-
-
Notifications
You must be signed in to change notification settings - Fork 92
Expand file tree
/
Copy pathLabelSelector.tsx
More file actions
76 lines (66 loc) · 2.07 KB
/
LabelSelector.tsx
File metadata and controls
76 lines (66 loc) · 2.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import { t } from "@/i18n";
import { PluginContext } from "@/ui/context";
import type React from "react";
import { useMemo } from "react";
import { Button, DialogTrigger, ListBox, ListBoxItem, type Selection } from "react-aria-components";
import type { Label } from "../../api/domain/label";
import { ObsidianIcon } from "../components/obsidian-icon";
import { Popover } from "./Popover";
type Props = {
selected: Label[];
setSelected: (labels: Label[]) => void;
};
export const LabelSelector: React.FC<Props> = ({ selected, setSelected }) => {
const plugin = PluginContext.use();
const options = useMemo(() => {
return Array.from(plugin.services.todoist.data().labels.iter());
}, [plugin]);
const selectedKeys = selected.map((l) => l.id);
const onSelectionChange = (selection: Selection) => {
if (selection === "all") {
setSelected([...options]);
return;
}
setSelected(options.filter((l) => selection.has(l.id)));
};
const i18n = t().createTaskModal.labelSelector;
return (
<DialogTrigger>
<Button className="label-selector" aria-label={i18n.buttonLabel}>
<ObsidianIcon size="m" id="tag" />
<span>{i18n.buttonText(selected.length)}</span>
</Button>
<Popover>
<ListBox
aria-label={i18n.labelOptionsLabel}
selectionMode="multiple"
className="task-option-dialog task-label-menu"
selectedKeys={selectedKeys}
onSelectionChange={onSelectionChange}
>
{options.map((l) => (
<LabelItem key={l.id} label={l} isSelected={selectedKeys.contains(l.id)} />
))}
</ListBox>
</Popover>
</DialogTrigger>
);
};
type LabelItemProps = {
label: Label;
isSelected: boolean;
};
const LabelItem: React.FC<LabelItemProps> = ({ label, isSelected }) => {
return (
<ListBoxItem
id={label.id}
key={label.id}
className="label-option"
aria-label={label.name}
textValue={label.name}
>
{label.name}
{isSelected && <ObsidianIcon size="xs" id="check" />}
</ListBoxItem>
);
};