@dxos/react-ui-pickers 0.10.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/assets/react-ui-pickers-IqrPkWEC.css +10 -0
- package/dist/lib/index.mjs +248 -0
- package/dist/lib/index.mjs.map +1 -0
- package/dist/types/src/components/HuePicker/HuePicker.d.ts.map +1 -1
- package/dist/types/src/components/IconPicker/IconPicker.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +11 -18
- package/src/components/HuePicker/HuePicker.tsx +2 -1
- package/src/components/IconPicker/IconPicker.tsx +1 -1
- package/dist/lib/browser/chunk-D3UYVI3X.mjs +0 -64
- package/dist/lib/browser/chunk-D3UYVI3X.mjs.map +0 -7
- package/dist/lib/browser/components/IconPicker/icons.mjs +0 -9
- package/dist/lib/browser/components/IconPicker/icons.mjs.map +0 -7
- package/dist/lib/browser/index.css +0 -7
- package/dist/lib/browser/index.css.map +0 -7
- package/dist/lib/browser/index.mjs +0 -237
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/node-esm/chunk-N4YXLEKA.mjs +0 -66
- package/dist/lib/node-esm/chunk-N4YXLEKA.mjs.map +0 -7
- package/dist/lib/node-esm/components/IconPicker/icons.mjs +0 -10
- package/dist/lib/node-esm/components/IconPicker/icons.mjs.map +0 -7
- package/dist/lib/node-esm/index.css +0 -7
- package/dist/lib/node-esm/index.css.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -238
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/types/src/components/IconPicker/icons.d.ts +0 -7
- package/dist/types/src/components/IconPicker/icons.d.ts.map +0 -1
- package/src/components/IconPicker/icons.ts +0 -66
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* https://github.com/missive/emoji-mart/blob/main/packages/emoji-mart-website/example-custom-styles.html
|
|
3
|
+
*/
|
|
4
|
+
[data-theme='dark'] em-emoji-picker {
|
|
5
|
+
/* TODO(burdon): Use tailwind tokens. */
|
|
6
|
+
--background-rgb: #3b3b3f;
|
|
7
|
+
--rgb-background: #3b3b3f;
|
|
8
|
+
--font-family: 'Inter Variable', ui-sans-serif;
|
|
9
|
+
}
|
|
10
|
+
/*$vite$:1*/
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import emojiData from "@emoji-mart/data";
|
|
2
|
+
import EmojiMart from "@emoji-mart/react";
|
|
3
|
+
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
4
|
+
import { useEffect, useState } from "react";
|
|
5
|
+
import { Button, ButtonGroup, DropdownMenu, Icon, IconButton, Popover, Toolbar, Tooltip, useMediaQuery, useThemeContext, useTranslation } from "@dxos/react-ui";
|
|
6
|
+
import { getSize, osTranslations } from "@dxos/ui-theme";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { hues, iconValues } from "@dxos/ui-types";
|
|
9
|
+
//#region src/components/EmojiPicker/EmojiPicker.tsx
|
|
10
|
+
/**
|
|
11
|
+
* A toolbar button for picking an emoji. Use only in `role=toolbar` elements. Unable to unset the value.
|
|
12
|
+
*/
|
|
13
|
+
var EmojiPickerToolbarButton = ({ classNames, emoji, disabled, defaultEmoji, onChangeEmoji }) => {
|
|
14
|
+
const { t } = useTranslation(osTranslations);
|
|
15
|
+
const { themeMode } = useThemeContext();
|
|
16
|
+
const [_emojiValue, setEmojiValue] = useControllableState({
|
|
17
|
+
prop: emoji,
|
|
18
|
+
onChange: onChangeEmoji,
|
|
19
|
+
defaultProp: defaultEmoji
|
|
20
|
+
});
|
|
21
|
+
const [emojiPickerOpen, setEmojiPickerOpen] = useState(false);
|
|
22
|
+
return /* @__PURE__ */ jsxs(Popover.Root, {
|
|
23
|
+
open: emojiPickerOpen,
|
|
24
|
+
onOpenChange: (nextOpen) => {
|
|
25
|
+
setEmojiPickerOpen(nextOpen);
|
|
26
|
+
},
|
|
27
|
+
children: [/* @__PURE__ */ jsx(Popover.Trigger, {
|
|
28
|
+
asChild: true,
|
|
29
|
+
children: /* @__PURE__ */ jsx(Toolbar.IconButton, {
|
|
30
|
+
icon: "ph--user-circle--regular",
|
|
31
|
+
label: t("select-emoji.label"),
|
|
32
|
+
iconOnly: true,
|
|
33
|
+
tooltipSide: "bottom",
|
|
34
|
+
disabled
|
|
35
|
+
})
|
|
36
|
+
}), /* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsxs(Popover.Content, {
|
|
37
|
+
side: "bottom",
|
|
38
|
+
onKeyDownCapture: (event) => {
|
|
39
|
+
if (event.key === "Escape") {
|
|
40
|
+
event.stopPropagation();
|
|
41
|
+
setEmojiPickerOpen(false);
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
children: [/* @__PURE__ */ jsx(EmojiMart, {
|
|
45
|
+
data: emojiData,
|
|
46
|
+
onEmojiSelect: ({ native }) => {
|
|
47
|
+
if (native) {
|
|
48
|
+
setEmojiValue(native);
|
|
49
|
+
setEmojiPickerOpen(false);
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
autoFocus: true,
|
|
53
|
+
maxFrequentRows: 0,
|
|
54
|
+
noCountryFlags: true,
|
|
55
|
+
theme: themeMode
|
|
56
|
+
}), /* @__PURE__ */ jsx(Popover.Arrow, {})]
|
|
57
|
+
}) })]
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* A button for picking an emoji alongside a button for unsetting it.
|
|
62
|
+
*/
|
|
63
|
+
var EmojiPickerBlock = ({ disabled, defaultEmoji, emoji, onChangeEmoji, onClickClear, triggerVariant = "ghost", classNames }) => {
|
|
64
|
+
const { t } = useTranslation(osTranslations);
|
|
65
|
+
const [isMd] = useMediaQuery("md");
|
|
66
|
+
const [emojiValue, setEmojiValue] = useControllableState({
|
|
67
|
+
prop: emoji,
|
|
68
|
+
onChange: onChangeEmoji,
|
|
69
|
+
defaultProp: defaultEmoji
|
|
70
|
+
});
|
|
71
|
+
const [emojiPickerOpen, setEmojiPickerOpen] = useState(false);
|
|
72
|
+
return /* @__PURE__ */ jsxs(ButtonGroup, {
|
|
73
|
+
classNames,
|
|
74
|
+
children: [/* @__PURE__ */ jsxs(Popover.Root, {
|
|
75
|
+
open: emojiPickerOpen,
|
|
76
|
+
onOpenChange: setEmojiPickerOpen,
|
|
77
|
+
children: [/* @__PURE__ */ jsx(Popover.Trigger, {
|
|
78
|
+
asChild: true,
|
|
79
|
+
children: /* @__PURE__ */ jsxs(Button, {
|
|
80
|
+
variant: triggerVariant,
|
|
81
|
+
classNames: "grow gap-2 text-2xl py-1",
|
|
82
|
+
disabled,
|
|
83
|
+
children: [
|
|
84
|
+
/* @__PURE__ */ jsx("span", {
|
|
85
|
+
className: "sr-only",
|
|
86
|
+
children: t("select-emoji.label")
|
|
87
|
+
}),
|
|
88
|
+
/* @__PURE__ */ jsx("span", { children: emojiValue }),
|
|
89
|
+
/* @__PURE__ */ jsx(Icon, {
|
|
90
|
+
icon: "ph--caret-down--bold",
|
|
91
|
+
size: 3
|
|
92
|
+
})
|
|
93
|
+
]
|
|
94
|
+
})
|
|
95
|
+
}), /* @__PURE__ */ jsxs(Popover.Content, {
|
|
96
|
+
side: "right",
|
|
97
|
+
sideOffset: isMd ? 0 : -310,
|
|
98
|
+
onKeyDownCapture: (event) => {
|
|
99
|
+
if (event.key === "Escape") {
|
|
100
|
+
event.stopPropagation();
|
|
101
|
+
setEmojiPickerOpen(false);
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
children: [/* @__PURE__ */ jsx(EmojiMart, {
|
|
105
|
+
data: emojiData,
|
|
106
|
+
onEmojiSelect: ({ native }) => {
|
|
107
|
+
if (native) {
|
|
108
|
+
setEmojiValue(native);
|
|
109
|
+
setEmojiPickerOpen(false);
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
autoFocus: true,
|
|
113
|
+
maxFrequentRows: 0,
|
|
114
|
+
noCountryFlags: true
|
|
115
|
+
}), /* @__PURE__ */ jsx(Popover.Arrow, {})]
|
|
116
|
+
})]
|
|
117
|
+
}), /* @__PURE__ */ jsx(IconButton, {
|
|
118
|
+
icon: "ph--arrow-counter-clockwise--regular",
|
|
119
|
+
iconOnly: true,
|
|
120
|
+
label: t("clear.label"),
|
|
121
|
+
tooltipSide: "right",
|
|
122
|
+
variant: triggerVariant,
|
|
123
|
+
onClick: onClickClear,
|
|
124
|
+
disabled
|
|
125
|
+
})]
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
//#endregion
|
|
129
|
+
//#region src/components/PickerButton/PickerButton.tsx
|
|
130
|
+
var PickerButton = ({ Component, disabled, classNames, defaultValue: defaultValueProp, value: valueProp, values, label, icon, onChange, onReset, rootVariant = "button", iconSize = 5 }) => {
|
|
131
|
+
const [value, setValue] = useControllableState({
|
|
132
|
+
prop: valueProp,
|
|
133
|
+
defaultProp: defaultValueProp,
|
|
134
|
+
onChange
|
|
135
|
+
});
|
|
136
|
+
useEffect(() => setValue(valueProp), [valueProp]);
|
|
137
|
+
const [open, setOpen] = useState(false);
|
|
138
|
+
const TriggerRoot = rootVariant === "toolbar-button" ? Toolbar.Button : Button;
|
|
139
|
+
return /* @__PURE__ */ jsxs(DropdownMenu.Root, {
|
|
140
|
+
modal: false,
|
|
141
|
+
open,
|
|
142
|
+
onOpenChange: setOpen,
|
|
143
|
+
children: [/* @__PURE__ */ jsx(Tooltip.Trigger, {
|
|
144
|
+
asChild: true,
|
|
145
|
+
content: label,
|
|
146
|
+
side: "bottom",
|
|
147
|
+
children: /* @__PURE__ */ jsx(DropdownMenu.Trigger, {
|
|
148
|
+
asChild: true,
|
|
149
|
+
children: /* @__PURE__ */ jsxs(TriggerRoot, {
|
|
150
|
+
classNames: ["gap-2 py-1", classNames],
|
|
151
|
+
disabled,
|
|
152
|
+
children: [
|
|
153
|
+
/* @__PURE__ */ jsx("span", {
|
|
154
|
+
className: "sr-only",
|
|
155
|
+
children: label
|
|
156
|
+
}),
|
|
157
|
+
value && /* @__PURE__ */ jsx(Component, {
|
|
158
|
+
value,
|
|
159
|
+
size: iconSize
|
|
160
|
+
}) || /* @__PURE__ */ jsx(Icon, {
|
|
161
|
+
icon,
|
|
162
|
+
size: iconSize
|
|
163
|
+
}),
|
|
164
|
+
/* @__PURE__ */ jsx(Icon, {
|
|
165
|
+
icon: "ph--caret-down--bold",
|
|
166
|
+
size: 3
|
|
167
|
+
})
|
|
168
|
+
]
|
|
169
|
+
})
|
|
170
|
+
})
|
|
171
|
+
}), /* @__PURE__ */ jsx(DropdownMenu.Portal, { children: /* @__PURE__ */ jsxs(DropdownMenu.Content, {
|
|
172
|
+
side: "bottom",
|
|
173
|
+
classNames: "!w-min",
|
|
174
|
+
children: [/* @__PURE__ */ jsxs(DropdownMenu.Viewport, {
|
|
175
|
+
classNames: "grid grid-cols-[repeat(6,min-content)]",
|
|
176
|
+
children: [values.map((_value) => {
|
|
177
|
+
return /* @__PURE__ */ jsx(DropdownMenu.CheckboxItem, {
|
|
178
|
+
checked: _value === value,
|
|
179
|
+
onCheckedChange: () => setValue(_value),
|
|
180
|
+
classNames: "p-1 items-center justify-center aspect-square",
|
|
181
|
+
children: /* @__PURE__ */ jsx(Component, {
|
|
182
|
+
value: _value,
|
|
183
|
+
size: iconSize
|
|
184
|
+
})
|
|
185
|
+
}, _value);
|
|
186
|
+
}), onReset && /* @__PURE__ */ jsx(DropdownMenu.CheckboxItem, {
|
|
187
|
+
onCheckedChange: () => onReset(),
|
|
188
|
+
classNames: "p-1 items-center justify-center aspect-square",
|
|
189
|
+
children: /* @__PURE__ */ jsx(Icon, {
|
|
190
|
+
icon: "ph--x--regular",
|
|
191
|
+
size: iconSize
|
|
192
|
+
})
|
|
193
|
+
})]
|
|
194
|
+
}), /* @__PURE__ */ jsx(DropdownMenu.Arrow, {})]
|
|
195
|
+
}) })]
|
|
196
|
+
});
|
|
197
|
+
};
|
|
198
|
+
//#endregion
|
|
199
|
+
//#region src/components/HuePicker/HuePicker.tsx
|
|
200
|
+
var HuePicker = (props) => {
|
|
201
|
+
const { t } = useTranslation(osTranslations);
|
|
202
|
+
return /* @__PURE__ */ jsx(PickerButton, {
|
|
203
|
+
Component: HuePreview,
|
|
204
|
+
label: t("select-hue.label"),
|
|
205
|
+
icon: "ph--palette--regular",
|
|
206
|
+
values: hues,
|
|
207
|
+
...props
|
|
208
|
+
});
|
|
209
|
+
};
|
|
210
|
+
var HuePreview = ({ value, size = 5 }) => {
|
|
211
|
+
return /* @__PURE__ */ jsx("div", {
|
|
212
|
+
className: "flex justify-center items-center",
|
|
213
|
+
children: /* @__PURE__ */ jsx("svg", {
|
|
214
|
+
viewBox: `0 0 ${size} ${size}`,
|
|
215
|
+
className: getSize(size),
|
|
216
|
+
children: /* @__PURE__ */ jsx("rect", {
|
|
217
|
+
x: 0,
|
|
218
|
+
y: 0,
|
|
219
|
+
width: size,
|
|
220
|
+
height: size,
|
|
221
|
+
fill: `var(--color-${value}-surface)`,
|
|
222
|
+
strokeWidth: 4
|
|
223
|
+
})
|
|
224
|
+
})
|
|
225
|
+
});
|
|
226
|
+
};
|
|
227
|
+
//#endregion
|
|
228
|
+
//#region src/components/IconPicker/IconPicker.tsx
|
|
229
|
+
var IconPicker = ({ ...props }) => {
|
|
230
|
+
const { t } = useTranslation(osTranslations);
|
|
231
|
+
return /* @__PURE__ */ jsx(PickerButton, {
|
|
232
|
+
Component: IconPreview,
|
|
233
|
+
label: t("select-icon.label"),
|
|
234
|
+
icon: "ph--selection--regular",
|
|
235
|
+
values: iconValues,
|
|
236
|
+
...props
|
|
237
|
+
});
|
|
238
|
+
};
|
|
239
|
+
var IconPreview = ({ value, size }) => {
|
|
240
|
+
return /* @__PURE__ */ jsx(Icon, {
|
|
241
|
+
icon: `ph--${value}--regular`,
|
|
242
|
+
size
|
|
243
|
+
});
|
|
244
|
+
};
|
|
245
|
+
//#endregion
|
|
246
|
+
export { EmojiPickerBlock, EmojiPickerToolbarButton, HuePicker, IconPicker, PickerButton };
|
|
247
|
+
|
|
248
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/components/EmojiPicker/EmojiPicker.tsx","../../src/components/PickerButton/PickerButton.tsx","../../src/components/HuePicker/HuePicker.tsx","../../src/components/IconPicker/IconPicker.tsx"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport './emoji.css';\n\nimport emojiData from '@emoji-mart/data';\nimport EmojiMart from '@emoji-mart/react';\nimport { useControllableState } from '@radix-ui/react-use-controllable-state';\nimport React, { useState } from 'react';\n\nimport {\n Button,\n ButtonGroup,\n type ButtonProps,\n Icon,\n IconButton,\n Popover,\n type ThemedClassName,\n Toolbar,\n useMediaQuery,\n useThemeContext,\n useTranslation,\n} from '@dxos/react-ui';\nimport { osTranslations } from '@dxos/ui-theme';\n\nexport type EmojiPickerProps = ThemedClassName<{\n disabled?: boolean;\n defaultEmoji?: string;\n emoji?: string;\n onChangeEmoji?: (nextEmoji: string) => void;\n onClickClear?: ButtonProps['onClick'];\n triggerVariant?: ButtonProps['variant'];\n}>;\n\n/**\n * A toolbar button for picking an emoji. Use only in `role=toolbar` elements. Unable to unset the value.\n */\nexport const EmojiPickerToolbarButton = ({\n classNames,\n emoji,\n disabled,\n defaultEmoji,\n onChangeEmoji,\n}: Omit<EmojiPickerProps, 'onClickClear'>) => {\n const { t } = useTranslation(osTranslations);\n const { themeMode } = useThemeContext();\n\n const [_emojiValue, setEmojiValue] = useControllableState<string>({\n prop: emoji,\n onChange: onChangeEmoji,\n defaultProp: defaultEmoji,\n });\n\n const [emojiPickerOpen, setEmojiPickerOpen] = useState<boolean>(false);\n\n return (\n <Popover.Root\n open={emojiPickerOpen}\n onOpenChange={(nextOpen) => {\n setEmojiPickerOpen(nextOpen);\n }}\n >\n <Popover.Trigger asChild>\n <Toolbar.IconButton\n icon='ph--user-circle--regular'\n label={t('select-emoji.label')}\n iconOnly\n tooltipSide='bottom'\n disabled={disabled}\n />\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Content\n side='bottom'\n onKeyDownCapture={(event) => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n setEmojiPickerOpen(false);\n }\n }}\n >\n {/* https://github.com/missive/emoji-mart?tab=readme-ov-file#options--props */}\n <EmojiMart\n data={emojiData}\n onEmojiSelect={({ native }: { native?: string }) => {\n if (native) {\n setEmojiValue(native);\n setEmojiPickerOpen(false);\n }\n }}\n autoFocus={true}\n maxFrequentRows={0}\n noCountryFlags={true}\n theme={themeMode}\n />\n <Popover.Arrow />\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n );\n};\n\n/**\n * A button for picking an emoji alongside a button for unsetting it.\n */\nexport const EmojiPickerBlock = ({\n disabled,\n defaultEmoji,\n emoji,\n onChangeEmoji,\n onClickClear,\n triggerVariant = 'ghost',\n classNames,\n}: EmojiPickerProps) => {\n const { t } = useTranslation(osTranslations);\n const [isMd] = useMediaQuery('md');\n\n const [emojiValue, setEmojiValue] = useControllableState<string>({\n prop: emoji,\n onChange: onChangeEmoji,\n defaultProp: defaultEmoji,\n });\n\n const [emojiPickerOpen, setEmojiPickerOpen] = useState<boolean>(false);\n\n return (\n <ButtonGroup classNames={classNames}>\n <Popover.Root open={emojiPickerOpen} onOpenChange={setEmojiPickerOpen}>\n <Popover.Trigger asChild>\n <Button variant={triggerVariant} classNames='grow gap-2 text-2xl py-1' disabled={disabled}>\n <span className='sr-only'>{t('select-emoji.label')}</span>\n <span>{emojiValue}</span>\n <Icon icon='ph--caret-down--bold' size={3} />\n </Button>\n </Popover.Trigger>\n <Popover.Content\n side='right'\n sideOffset={isMd ? 0 : -310}\n onKeyDownCapture={(event) => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n setEmojiPickerOpen(false);\n }\n }}\n >\n <EmojiMart\n data={emojiData}\n onEmojiSelect={({ native }: { native?: string }) => {\n if (native) {\n setEmojiValue(native);\n setEmojiPickerOpen(false);\n }\n }}\n autoFocus={true}\n maxFrequentRows={0}\n noCountryFlags={true}\n />\n <Popover.Arrow />\n </Popover.Content>\n </Popover.Root>\n <IconButton\n icon='ph--arrow-counter-clockwise--regular'\n iconOnly\n label={t('clear.label')}\n tooltipSide='right'\n variant={triggerVariant}\n onClick={onClickClear}\n disabled={disabled}\n />\n </ButtonGroup>\n );\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { useControllableState } from '@radix-ui/react-use-controllable-state';\nimport React, { type FC, useEffect, useState } from 'react';\n\nimport { Button, DropdownMenu, Icon, type IconProps, type ThemedClassName, Toolbar, Tooltip } from '@dxos/react-ui';\n\nexport type PickerButtonProps = ThemedClassName<{\n Component: FC<{ value: string; size?: IconProps['size'] }>;\n label: string;\n icon: string;\n values: readonly string[];\n disabled?: boolean;\n defaultValue?: string;\n value?: string;\n onChange?: (value: string) => void;\n onReset?: () => void;\n rootVariant?: 'button' | 'toolbar-button';\n iconSize?: IconProps['size'];\n}>;\n\nexport const PickerButton = ({\n Component,\n disabled,\n classNames,\n defaultValue: defaultValueProp,\n value: valueProp,\n values,\n label,\n icon,\n onChange,\n onReset,\n rootVariant = 'button',\n iconSize = 5,\n}: PickerButtonProps) => {\n const [value, setValue] = useControllableState<string>({\n prop: valueProp,\n defaultProp: defaultValueProp,\n onChange,\n });\n // TODO(burdon): useControllableState doesn't update the prop when the value is changed. Replace it.\n useEffect(() => setValue(valueProp), [valueProp]);\n\n const [open, setOpen] = useState<boolean>(false);\n const TriggerRoot = rootVariant === 'toolbar-button' ? Toolbar.Button : Button;\n\n return (\n <DropdownMenu.Root modal={false} open={open} onOpenChange={setOpen}>\n <Tooltip.Trigger asChild content={label} side='bottom'>\n <DropdownMenu.Trigger asChild>\n <TriggerRoot classNames={['gap-2 py-1', classNames]} disabled={disabled}>\n <span className='sr-only'>{label}</span>\n {(value && <Component value={value} size={iconSize} />) || <Icon icon={icon} size={iconSize} />}\n <Icon icon='ph--caret-down--bold' size={3} />\n </TriggerRoot>\n </DropdownMenu.Trigger>\n </Tooltip.Trigger>\n <DropdownMenu.Portal>\n <DropdownMenu.Content side='bottom' classNames='!w-min'>\n <DropdownMenu.Viewport classNames='grid grid-cols-[repeat(6,min-content)]'>\n {values.map((_value) => {\n return (\n <DropdownMenu.CheckboxItem\n key={_value}\n checked={_value === value}\n onCheckedChange={() => setValue(_value)}\n classNames={'p-1 items-center justify-center aspect-square'}\n >\n <Component value={_value} size={iconSize} />\n </DropdownMenu.CheckboxItem>\n );\n })}\n {onReset && (\n <DropdownMenu.CheckboxItem\n onCheckedChange={() => onReset()}\n classNames={'p-1 items-center justify-center aspect-square'}\n >\n <Icon icon='ph--x--regular' size={iconSize} />\n </DropdownMenu.CheckboxItem>\n )}\n </DropdownMenu.Viewport>\n <DropdownMenu.Arrow />\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n </DropdownMenu.Root>\n );\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport React from 'react';\n\nimport { type ButtonProps, type IconProps, type ThemedClassName, useTranslation } from '@dxos/react-ui';\nimport { getSize, osTranslations } from '@dxos/ui-theme';\nimport { hues } from '@dxos/ui-types';\n\nimport { PickerButton, type PickerButtonProps } from '../PickerButton';\n\nexport type HuePickerProps = {\n disabled?: boolean;\n defaultValue?: string;\n value?: string;\n onChange?: (nextHue: string) => void;\n onReset?: ButtonProps['onClick'];\n} & Pick<PickerButtonProps, 'disabled' | 'defaultValue' | 'value' | 'onChange' | 'onReset' | 'rootVariant'>;\n\nexport const HuePicker = (props: ThemedClassName<HuePickerProps>) => {\n const { t } = useTranslation(osTranslations);\n\n return (\n <PickerButton\n Component={HuePreview}\n label={t('select-hue.label')}\n icon='ph--palette--regular'\n values={hues}\n {...props}\n />\n );\n};\n\nconst HuePreview = ({ value, size = 5 }: { value: string; size?: IconProps['size'] }) => {\n return (\n <div className='flex justify-center items-center'>\n <svg viewBox={`0 0 ${size} ${size}`} className={getSize(size)}>\n <rect x={0} y={0} width={size} height={size} fill={`var(--color-${value}-surface)`} strokeWidth={4} />\n </svg>\n </div>\n );\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport React from 'react';\n\nimport { type ButtonProps, Icon, type IconProps, type ThemedClassName, useTranslation } from '@dxos/react-ui';\nimport { osTranslations } from '@dxos/ui-theme';\nimport { iconValues } from '@dxos/ui-types';\n\nimport { PickerButton, type PickerButtonProps } from '../PickerButton';\n\nexport type IconPickerProps = {\n disabled?: boolean;\n defaultValue?: string;\n value?: string;\n onChange?: (nextHue: string) => void;\n onReset?: ButtonProps['onClick'];\n} & Pick<\n PickerButtonProps,\n 'disabled' | 'rootVariant' | 'iconSize' | 'defaultValue' | 'value' | 'onChange' | 'onReset'\n>;\n\nexport const IconPicker = ({ ...props }: ThemedClassName<IconPickerProps>) => {\n const { t } = useTranslation(osTranslations);\n\n return (\n <PickerButton\n Component={IconPreview}\n label={t('select-icon.label')}\n icon='ph--selection--regular'\n values={iconValues}\n {...props}\n />\n );\n};\n\nconst IconPreview = ({ value, size }: { value: string; size?: IconProps['size'] }) => {\n return <Icon icon={`ph--${value}--regular`} size={size} />;\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HuePicker.d.ts","sourceRoot":"","sources":["../../../../../src/components/HuePicker/HuePicker.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,KAAK,WAAW,EAAkB,KAAK,eAAe,EAAkB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"HuePicker.d.ts","sourceRoot":"","sources":["../../../../../src/components/HuePicker/HuePicker.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,KAAK,WAAW,EAAkB,KAAK,eAAe,EAAkB,MAAM,gBAAgB,CAAC;AAIxG,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEvE,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,OAAO,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;CAClC,GAAG,IAAI,CAAC,iBAAiB,EAAE,UAAU,GAAG,cAAc,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,aAAa,CAAC,CAAC;AAE5G,eAAO,MAAM,SAAS,UAAW,eAAe,CAAC,cAAc,CAAC,sBAY/D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IconPicker.d.ts","sourceRoot":"","sources":["../../../../../src/components/IconPicker/IconPicker.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,KAAK,WAAW,EAAwB,KAAK,eAAe,EAAkB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"IconPicker.d.ts","sourceRoot":"","sources":["../../../../../src/components/IconPicker/IconPicker.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,KAAK,WAAW,EAAwB,KAAK,eAAe,EAAkB,MAAM,gBAAgB,CAAC;AAI9G,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEvE,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,OAAO,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;CAClC,GAAG,IAAI,CACN,iBAAiB,EACjB,UAAU,GAAG,aAAa,GAAG,UAAU,GAAG,cAAc,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAC5F,CAAC;AAEF,eAAO,MAAM,UAAU,iBAAkB,eAAe,CAAC,eAAe,CAAC,sBAYxE,CAAC"}
|