Skip to content

Commit 98ebe88

Browse files
authored
[WEB-1501] dev: multiple select core components (#4667)
* dev: multiple select core components * chore: added export statement
1 parent c8c86a3 commit 98ebe88

File tree

10 files changed

+691
-0
lines changed

10 files changed

+691
-0
lines changed

web/components/core/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export * from "./filters";
22
export * from "./modals";
3+
export * from "./multiple-select";
34
export * from "./sidebar";
45
export * from "./activity";
56
export * from "./favorite-star";
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// ui
2+
import { Checkbox } from "@plane/ui";
3+
// helpers
4+
import { cn } from "@/helpers/common.helper";
5+
// hooks
6+
import { TSelectionHelper } from "@/hooks/use-multiple-select";
7+
8+
type Props = {
9+
className?: string;
10+
disabled?: boolean;
11+
groupId: string;
12+
id: string;
13+
selectionHelpers: TSelectionHelper;
14+
};
15+
16+
export const MultipleSelectEntityAction: React.FC<Props> = (props) => {
17+
const { className, disabled = false, groupId, id, selectionHelpers } = props;
18+
// derived values
19+
const isSelected = selectionHelpers.getIsEntitySelected(id);
20+
21+
return (
22+
<Checkbox
23+
className={cn("!outline-none size-3.5", className)}
24+
iconClassName="size-3"
25+
onClick={(e) => {
26+
e.stopPropagation();
27+
selectionHelpers.handleEntityClick(e, id, groupId);
28+
}}
29+
checked={isSelected}
30+
data-entity-group-id={groupId}
31+
data-entity-id={id}
32+
disabled={disabled}
33+
readOnly
34+
/>
35+
);
36+
};
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// ui
2+
import { Checkbox } from "@plane/ui";
3+
// helpers
4+
import { cn } from "@/helpers/common.helper";
5+
// hooks
6+
import { TSelectionHelper } from "@/hooks/use-multiple-select";
7+
8+
type Props = {
9+
className?: string;
10+
disabled?: boolean;
11+
groupID: string;
12+
selectionHelpers: TSelectionHelper;
13+
};
14+
15+
export const MultipleSelectGroupAction: React.FC<Props> = (props) => {
16+
const { className, disabled = false, groupID, selectionHelpers } = props;
17+
// derived values
18+
const groupSelectionStatus = selectionHelpers.isGroupSelected(groupID);
19+
20+
return (
21+
<Checkbox
22+
className={cn("size-3.5 !outline-none", className)}
23+
iconClassName="size-3"
24+
onClick={() => selectionHelpers.handleGroupClick(groupID)}
25+
checked={groupSelectionStatus === "complete"}
26+
indeterminate={groupSelectionStatus === "partial"}
27+
disabled={disabled}
28+
/>
29+
);
30+
};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from "./entity-select-action";
2+
export * from "./group-select-action";
3+
export * from "./select-group";
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { observer } from "mobx-react";
2+
// hooks
3+
import { TSelectionHelper, useMultipleSelect } from "@/hooks/use-multiple-select";
4+
5+
type Props = {
6+
children: (helpers: TSelectionHelper) => React.ReactNode;
7+
containerRef: React.MutableRefObject<HTMLElement | null>;
8+
entities: Record<string, string[]>; // { groupID: entityIds[] }
9+
};
10+
11+
export const MultipleSelectGroup: React.FC<Props> = observer((props) => {
12+
const { children, containerRef, entities } = props;
13+
14+
const helpers = useMultipleSelect({
15+
containerRef,
16+
entities,
17+
});
18+
19+
return <>{children(helpers)}</>;
20+
});
21+
22+
MultipleSelectGroup.displayName = "MultipleSelectGroup";

web/hooks/store/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export * from "./use-label";
99
export * from "./use-member";
1010
export * from "./use-mention";
1111
export * from "./use-module";
12+
export * from "./use-multiple-select-store";
1213

1314
export * from "./pages/use-project-page";
1415
export * from "./pages/use-page";
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { useContext } from "react";
2+
// store
3+
import { StoreContext } from "@/lib/store-context";
4+
5+
export const useMultipleSelectStore = () => {
6+
const context = useContext(StoreContext);
7+
if (context === undefined) throw new Error("useMultipleSelectStore must be used within StoreProvider");
8+
return context.multipleSelect;
9+
};

0 commit comments

Comments
 (0)