@firecms/ui 3.0.0-canary.12 → 3.0.0-canary.120

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.
Files changed (101) hide show
  1. package/README.md +1 -1
  2. package/dist/components/Avatar.d.ts +1 -0
  3. package/dist/components/BooleanSwitch.d.ts +1 -1
  4. package/dist/components/CenteredView.d.ts +4 -2
  5. package/dist/components/Checkbox.d.ts +3 -2
  6. package/dist/components/Chip.d.ts +3 -2
  7. package/dist/components/DateTimeField.d.ts +3 -4
  8. package/dist/components/Dialog.d.ts +4 -1
  9. package/dist/components/InputLabel.d.ts +2 -2
  10. package/dist/components/Label.d.ts +4 -1
  11. package/dist/components/Markdown.d.ts +1 -0
  12. package/dist/components/Menu.d.ts +6 -2
  13. package/dist/components/Menubar.d.ts +79 -0
  14. package/dist/components/MultiSelect.d.ts +1 -4
  15. package/dist/components/NewMultiSelect.d.ts +60 -0
  16. package/dist/components/Popover.d.ts +2 -1
  17. package/dist/components/RadioGroup.d.ts +26 -3
  18. package/dist/components/Select.d.ts +4 -4
  19. package/dist/components/Sheet.d.ts +4 -0
  20. package/dist/components/Table.d.ts +10 -10
  21. package/dist/components/TextField.d.ts +1 -1
  22. package/dist/components/TextareaAutosize.d.ts +3 -34
  23. package/dist/components/Tooltip.d.ts +5 -2
  24. package/dist/components/index.d.ts +2 -1
  25. package/dist/hooks/index.d.ts +4 -0
  26. package/dist/hooks/useLocaleConfig.d.ts +1 -0
  27. package/dist/icons/Icon.d.ts +3 -3
  28. package/dist/index.css +77 -0
  29. package/dist/index.d.ts +1 -0
  30. package/dist/index.es.js +13290 -13511
  31. package/dist/index.es.js.map +1 -1
  32. package/dist/index.umd.js +19828 -49
  33. package/dist/index.umd.js.map +1 -1
  34. package/dist/styles.d.ts +7 -7
  35. package/dist/util/{cn.d.ts → cls.d.ts} +4 -0
  36. package/dist/util/index.d.ts +1 -3
  37. package/package.json +109 -118
  38. package/src/components/Alert.tsx +2 -2
  39. package/src/components/Autocomplete.tsx +4 -3
  40. package/src/components/Avatar.tsx +7 -6
  41. package/src/components/Badge.tsx +1 -1
  42. package/src/components/BooleanSwitch.tsx +15 -15
  43. package/src/components/BooleanSwitchWithLabel.tsx +8 -8
  44. package/src/components/Button.tsx +11 -13
  45. package/src/components/Card.tsx +3 -3
  46. package/src/components/CenteredView.tsx +25 -15
  47. package/src/components/Checkbox.tsx +11 -9
  48. package/src/components/Chip.tsx +8 -5
  49. package/src/components/CircularProgress.tsx +2 -2
  50. package/src/components/Collapse.tsx +3 -2
  51. package/src/components/Container.tsx +2 -2
  52. package/src/components/DateTimeField.tsx +38 -48
  53. package/src/components/Dialog.tsx +15 -6
  54. package/src/components/DialogActions.tsx +2 -2
  55. package/src/components/DialogContent.tsx +2 -2
  56. package/src/components/ExpandablePanel.tsx +10 -8
  57. package/src/components/FileUpload.tsx +6 -9
  58. package/src/components/IconButton.tsx +4 -6
  59. package/src/components/InfoLabel.tsx +2 -2
  60. package/src/components/InputLabel.tsx +12 -9
  61. package/src/components/Label.tsx +17 -4
  62. package/src/components/Markdown.tsx +14 -3
  63. package/src/components/Menu.tsx +49 -31
  64. package/src/components/Menubar.tsx +322 -0
  65. package/src/components/MultiSelect.tsx +12 -14
  66. package/src/components/NewMultiSelect.tsx +370 -0
  67. package/src/components/Paper.tsx +2 -2
  68. package/src/components/Popover.tsx +17 -14
  69. package/src/components/RadioGroup.tsx +41 -9
  70. package/src/components/SearchBar.tsx +7 -8
  71. package/src/components/Select.tsx +92 -104
  72. package/src/components/Sheet.tsx +45 -28
  73. package/src/components/Skeleton.tsx +9 -6
  74. package/src/components/Table.tsx +50 -32
  75. package/src/components/Tabs.tsx +6 -7
  76. package/src/components/TextField.tsx +10 -13
  77. package/src/components/TextareaAutosize.tsx +3 -3
  78. package/src/components/Tooltip.tsx +27 -13
  79. package/src/components/Typography.tsx +34 -19
  80. package/src/components/common/SelectInputLabel.tsx +2 -2
  81. package/src/components/index.tsx +2 -1
  82. package/src/hooks/index.ts +4 -0
  83. package/src/hooks/useLocaleConfig.tsx +18 -0
  84. package/src/icons/Icon.tsx +46 -43
  85. package/src/icons/icon_keys.ts +114 -1301
  86. package/src/index.css +77 -0
  87. package/src/index.ts +1 -0
  88. package/src/scripts/generateIconKeys.ts +20 -11
  89. package/src/styles.ts +7 -7
  90. package/src/util/cls.ts +14 -0
  91. package/src/util/index.ts +1 -3
  92. package/tailwind.config.js +5 -3
  93. package/dist/components/Spinner.d.ts +0 -1
  94. package/src/components/Spinner.tsx +0 -18
  95. package/src/util/cn.ts +0 -6
  96. /package/dist/{util → hooks}/useDebounceValue.d.ts +0 -0
  97. /package/dist/{util → hooks}/useInjectStyles.d.ts +0 -0
  98. /package/dist/{util → hooks}/useOutsideAlerter.d.ts +0 -0
  99. /package/src/{util → hooks}/useDebounceValue.tsx +0 -0
  100. /package/src/{util → hooks}/useInjectStyles.tsx +0 -0
  101. /package/src/{util → hooks}/useOutsideAlerter.tsx +0 -0
@@ -1,5 +1,7 @@
1
1
  import * as React from "react";
2
- import { cn } from "../util";
2
+ import { cls } from "../util";
3
+ import { Label } from "./Label";
4
+ import { defaultBorderMixin } from "../styles";
3
5
 
4
6
  export type InputLabelProps = {
5
7
  children?: React.ReactNode;
@@ -7,6 +9,12 @@ export type InputLabelProps = {
7
9
  shrink?: boolean;
8
10
  } & React.LabelHTMLAttributes<HTMLLabelElement>;
9
11
 
12
+ const defaultClasses = {
13
+ root: "origin-left transition-transform block whitespace-nowrap overflow-hidden text-overflow-ellipsis max-w-full",
14
+ shrink: "transform translate-y-[2px] scale-75 translate-x-[12px]",
15
+ expanded: "translate-x-[16px] top-0 transform translate-y-[16px] scale-100"
16
+ };
17
+
10
18
  export const InputLabel = React.forwardRef<HTMLLabelElement, InputLabelProps>(function InputLabel(inProps, ref) {
11
19
  const {
12
20
  shrink,
@@ -14,13 +22,7 @@ export const InputLabel = React.forwardRef<HTMLLabelElement, InputLabelProps>(fu
14
22
  ...other
15
23
  } = inProps;
16
24
 
17
- const defaultClasses = {
18
- root: "origin-left transition-transform block whitespace-nowrap overflow-hidden text-overflow-ellipsis max-w-full",
19
- shrink: "transform translate-y-[2px] scale-75 translate-x-[12px]",
20
- expanded: "translate-x-[16px] top-0 transform translate-y-[16px] scale-100"
21
- };
22
-
23
- const computedClassName = cn(defaultClasses.root,
25
+ const computedClassName = cls(defaultClasses.root,
24
26
  {
25
27
  [defaultClasses.shrink]: shrink,
26
28
  [defaultClasses.expanded]: !shrink
@@ -28,9 +30,10 @@ export const InputLabel = React.forwardRef<HTMLLabelElement, InputLabelProps>(fu
28
30
 
29
31
  return (
30
32
  <label
33
+ className={cls("text-sm font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
34
+ defaultBorderMixin, computedClassName)}
31
35
  data-shrink={shrink}
32
36
  ref={ref}
33
- className={computedClassName}
34
37
  {...other}
35
38
  />
36
39
  );
@@ -1,15 +1,28 @@
1
1
  import * as React from "react"
2
2
  import * as LabelPrimitive from "@radix-ui/react-label"
3
- import { cn } from "../util";
3
+ import { cls } from "../util";
4
4
  import { defaultBorderMixin } from "../styles";
5
5
 
6
+ type LabelProps = React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> & {
7
+ border?: boolean,
8
+ onClick?: React.MouseEventHandler<HTMLLabelElement>
9
+ };
6
10
  const Label = React.forwardRef<
7
11
  React.ElementRef<typeof LabelPrimitive.Root>,
8
- React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
9
- >(({ className, ...props }, ref) => (
12
+ LabelProps
13
+ >(({
14
+ className,
15
+ border,
16
+ onClick,
17
+ ...props
18
+ }, ref) => (
10
19
  <LabelPrimitive.Root
11
20
  ref={ref}
12
- className={cn("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70", defaultBorderMixin, className)}
21
+ onClick={onClick}
22
+ className={cls("text-sm font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
23
+ border && "border border-gray-300 dark:border-gray-700 rounded-md px-3 py-1.5",
24
+ onClick && "hover:cursor-pointer hover:bg-gray-200 dark:hover:bg-gray-800",
25
+ defaultBorderMixin, className)}
13
26
  {...props}
14
27
  />
15
28
  ))
@@ -3,26 +3,37 @@ import equal from "react-fast-compare"
3
3
 
4
4
  // @ts-ignore
5
5
  import MarkdownIt from "markdown-it";
6
+ import { cls } from "../util";
6
7
 
7
8
  export interface MarkdownProps {
8
9
  source: string,
10
+ size?: "small" | "medium" | "large" | "xl" | "2xl";
9
11
  className?: string
10
12
  }
11
13
 
12
- const md = new MarkdownIt({ html: true, });
14
+ const proseClasses = {
15
+ small: "prose-sm text-sm",
16
+ medium: "prose text-base",
17
+ large: "prose-lg",
18
+ xl: "prose-xl",
19
+ "2xl": "prose-2xl"
20
+ };
21
+
22
+ const md = new MarkdownIt({ html: true });
13
23
  /**
14
24
  * @group Preview components
15
25
  */
16
26
  export const Markdown = React.memo<MarkdownProps>(function Markdown({
17
27
  source,
18
- className
28
+ className,
29
+ size = "medium"
19
30
  }: MarkdownProps) {
20
31
  const html = useMemo(() => {
21
32
  return md.render(typeof source === "string" ? source : "");
22
33
  }, [source]);
23
34
 
24
35
  return <div
25
- className={className}
36
+ className={cls(proseClasses[size], "dark:prose-invert prose-headings:font-title", className)}
26
37
  dangerouslySetInnerHTML={{ __html: html }}
27
38
  />;
28
39
  }
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
3
- import { focusedMixin, paperMixin } from "../styles";
4
- import { cn } from "../util";
3
+ import { focusedDisabled, paperMixin } from "../styles";
4
+ import { cls } from "../util";
5
5
 
6
6
  export type MenuProps = {
7
7
  children: React.ReactNode;
@@ -12,49 +12,67 @@ export type MenuProps = {
12
12
  onOpenChange?(open: boolean): void;
13
13
 
14
14
  portalContainer?: HTMLElement | null;
15
+ side?: "top" | "right" | "bottom" | "left";
16
+ align?: "start" | "center" | "end";
15
17
  }
16
18
 
17
- export function Menu({
18
- children,
19
- trigger,
20
- open,
21
- defaultOpen,
22
- onOpenChange,
23
- portalContainer
24
- }: MenuProps) {
25
- return (
26
- <DropdownMenu.Root
27
- open={open}
28
- defaultOpen={defaultOpen}
29
- onOpenChange={onOpenChange}>
30
- <DropdownMenu.Trigger asChild>
31
- {trigger}
32
- </DropdownMenu.Trigger>
33
- <DropdownMenu.Portal container={portalContainer}>
34
- <DropdownMenu.Content className={cn(paperMixin, "shadow py-2 z-30")}>
35
- {children}
36
- </DropdownMenu.Content>
37
- </DropdownMenu.Portal>
38
- </DropdownMenu.Root>
39
- );
40
- }
19
+ const Menu = React.forwardRef<
20
+ React.ElementRef<typeof DropdownMenu.Trigger>,
21
+ MenuProps
22
+ >(({
23
+ children,
24
+ trigger,
25
+ open,
26
+ defaultOpen,
27
+ side,
28
+ align,
29
+ onOpenChange,
30
+ portalContainer
31
+ }, ref) => (
32
+ <DropdownMenu.Root
33
+ open={open}
34
+ defaultOpen={defaultOpen}
35
+ onOpenChange={onOpenChange}>
36
+ <DropdownMenu.Trigger
37
+ ref={ref}
38
+ asChild>
39
+ {trigger}
40
+ </DropdownMenu.Trigger>
41
+ <DropdownMenu.Portal container={portalContainer}>
42
+ <DropdownMenu.Content
43
+ side={side}
44
+ align={align}
45
+ className={cls(paperMixin, focusedDisabled, "shadow py-2 z-30")}>
46
+ {children}
47
+ </DropdownMenu.Content>
48
+ </DropdownMenu.Portal>
49
+ </DropdownMenu.Root>
50
+ ))
51
+ Menu.displayName = "Menu"
52
+
53
+ export { Menu }
41
54
 
42
55
  export type MenuItemProps = {
43
56
  children: React.ReactNode;
44
57
  dense?: boolean;
45
58
  onClick?: (event: React.MouseEvent) => void;
46
- }
59
+ };
47
60
 
48
61
  export function MenuItem({
49
62
  children,
50
- dense,
63
+ dense = false, // Default value is false if not provided
51
64
  onClick
52
65
  }: MenuItemProps) {
66
+ // Dynamically adjusting the class based on the "dense" prop
67
+ const classNames = cls(
68
+ onClick && "cursor-pointer",
69
+ "rounded-md text-sm font-medium text-slate-700 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-900 flex items-center gap-4",
70
+ dense ? "px-3 py-1.5" : "px-4 py-2"
71
+ );
72
+
53
73
  return (
54
74
  <DropdownMenu.Item
55
- className={cn(focusedMixin,
56
- onClick && "cursor-pointer",
57
- "rounded-md px-4 py-2 text-sm font-medium text-slate-700 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-900 flex items-center gap-4")}
75
+ className={classNames}
58
76
  onClick={onClick}>
59
77
  {children}
60
78
  </DropdownMenu.Item>
@@ -0,0 +1,322 @@
1
+ import * as React from "react";
2
+
3
+ import * as MenubarPrimitive from "@radix-ui/react-menubar";
4
+ import { cls } from "../util";
5
+ import { CheckIcon, ChevronRightIcon } from "../icons";
6
+
7
+ export function Menubar({
8
+ children,
9
+ onSelect,
10
+ className
11
+ }: {
12
+ children: React.ReactNode,
13
+ onSelect?: (event: React.SyntheticEvent) => void,
14
+ className?: string
15
+ }) {
16
+ return (
17
+ <MenubarPrimitive.Root
18
+ onSelect={onSelect}
19
+ className={cls("z-10 flex bg-white dark:bg-gray-950 p-[3px] rounded-sm shadow-sm", className)}>
20
+ {children}
21
+ </MenubarPrimitive.Root>
22
+ )
23
+ }
24
+
25
+ export function MenubarMenu({
26
+ children,
27
+ }: { children: React.ReactNode }) {
28
+ return (
29
+ <MenubarPrimitive.Menu>
30
+ {children}
31
+ </MenubarPrimitive.Menu>
32
+ )
33
+ }
34
+
35
+ export function MenubarTrigger({
36
+ children,
37
+ onSelect,
38
+ className
39
+ }: {
40
+ children: React.ReactNode,
41
+ onSelect?: (event: React.SyntheticEvent) => void,
42
+ className?: string
43
+ }) {
44
+ return (
45
+ <MenubarPrimitive.Trigger
46
+ onSelect={onSelect}
47
+ className={cls("py-2 px-3 outline-none select-none font-medium leading-none rounded text-text-primary dark:text-text-primary-dark text-[13px] flex items-center justify-between gap-[2px] data-[highlighted]:bg-slate-100 data-[highlighted]:dark:bg-gray-800 data-[state=open]:bg-slate-100 data-[state=open]:dark:bg-gray-800 hover:bg-slate-200 hover:bg-opacity-75 dark:hover:bg-gray-700 dark:hover:bg-opacity-50",
48
+ className)}>
49
+ {children}
50
+ </MenubarPrimitive.Trigger>
51
+ )
52
+ }
53
+
54
+ export function MenubarPortal({
55
+ children,
56
+ }: { children: React.ReactNode }) {
57
+ return (
58
+ <MenubarPrimitive.Portal>
59
+ {children}
60
+ </MenubarPrimitive.Portal>
61
+ )
62
+ }
63
+
64
+ export function MenubarContent({
65
+ children,
66
+ className,
67
+ align,
68
+ sideOffset,
69
+ alignOffset,
70
+ onSelect,
71
+ ...rest
72
+ }: {
73
+ children: React.ReactNode,
74
+ className?: string,
75
+ onSelect?: (event: React.SyntheticEvent) => void,
76
+ align?: "start" | "center" | "end",
77
+ sideOffset?: number,
78
+ alignOffset?: number
79
+ }) {
80
+ return (
81
+ <MenubarPrimitive.Content
82
+ onSelect={onSelect}
83
+ className={cls("min-w-[220px] bg-white dark:bg-gray-950 rounded-md p-[6px] shadow-[0px_10px_38px_-10px_rgba(22,_23,_24,_0.35),_0px_10px_20px_-15px_rgba(22,_23,_24,_0.2)] [animation-duration:_400ms] [animation-timing-function:_cubic-bezier(0.16,_1,_0.3,_1)] will-change-[transform,opacity]", className)}
84
+ align={align ?? "start"}
85
+ sideOffset={sideOffset ?? 5}
86
+ alignOffset={alignOffset ?? -3}
87
+ {...rest}
88
+ >
89
+ {children}
90
+ </MenubarPrimitive.Content>
91
+ )
92
+ }
93
+
94
+ export function MenubarItem({
95
+ children,
96
+ leftPadding,
97
+ className,
98
+ disabled,
99
+ onSelect,
100
+ ...rest
101
+ }: {
102
+ children: React.ReactNode,
103
+ onSelect?: (event: Event) => void;
104
+ leftPadding?: boolean,
105
+ className?: string,
106
+ disabled?: boolean
107
+ }) {
108
+ return (
109
+ <MenubarPrimitive.Item
110
+ onSelect={onSelect}
111
+ className={cls("group text-[13px] leading-none rounded flex items-center h-[32px] px-[10px] py-[2px] relative select-none outline-none data-[state=open]:bg-slate-100 data-[state=open]:dark:bg-gray-800 data-[state=open]:text-text-primary data-[state=open]:dark:text-text-primary-dark data-[highlighted]:bg-slate-100 data-[highlighted]:dark:bg-gray-800 data-[disabled]:text-text-disabled data-[disabled]:dark:text-text-disabled-dark data-[disabled]:pointer-events-none",
112
+ leftPadding ? "pl-5" : "",
113
+ disabled ? "pointer-events-none text-text-secondary dark:text-text-secondary-dark" : "text-text-primary dark:text-text-primary-dark",
114
+ className)}
115
+ disabled={disabled}
116
+ {...rest}
117
+ >
118
+ {children}
119
+ </MenubarPrimitive.Item>
120
+ )
121
+ }
122
+
123
+ export function MenubarSeparator({
124
+ children,
125
+ className,
126
+ ...rest
127
+ }: {
128
+ children?: React.ReactNode,
129
+ className?: string,
130
+ }) {
131
+ return (
132
+ <MenubarPrimitive.Separator
133
+ className={cls("h-[1px] bg-slate-100 dark:bg-gray-800 m-[5px]", className)}
134
+ {...rest}
135
+ >
136
+ {children}
137
+ </MenubarPrimitive.Separator>
138
+ )
139
+ }
140
+
141
+ export function MenubarSub({
142
+ children,
143
+ ...rest
144
+ }: {
145
+ children?: React.ReactNode,
146
+ }) {
147
+ return (
148
+ <MenubarPrimitive.Sub
149
+ {...rest}
150
+ >
151
+ {children}
152
+ </MenubarPrimitive.Sub>
153
+ )
154
+ }
155
+
156
+ export function MenubarSubTrigger({
157
+ children,
158
+ className,
159
+ onSelect,
160
+ ...rest
161
+ }: {
162
+ children?: React.ReactNode,
163
+ onSelect?: (event: React.SyntheticEvent) => void,
164
+ className?: string,
165
+ }) {
166
+ return (
167
+ <MenubarPrimitive.SubTrigger
168
+ onSelect={onSelect}
169
+ className={cls("group text-[13px] leading-none text-text-primary dark:text-text-primary-dark rounded flex items-center h-[32px] px-[10px] py-[2px] relative select-none outline-none data-[state=open]:bg-slate-100 data-[state=open]:dark:bg-gray-800 data-[state=open]:text-text-primary data-[state=open]:dark:text-text-primary-dark data-[highlighted]:bg-slate-100 data-[highlighted]:dark:bg-gray-800 data-[disabled]:text-text-disabled data-[disabled]:dark:text-text-disabled-dark data-[disabled]:pointer-events-none",
170
+ className)}
171
+ {...rest}
172
+ >
173
+ {children}
174
+ </MenubarPrimitive.SubTrigger>
175
+ )
176
+ }
177
+
178
+ export function MenubarSubContent({
179
+ children,
180
+ alignOffset,
181
+ className,
182
+ onSelect,
183
+ ...rest
184
+ }: {
185
+ children?: React.ReactNode,
186
+ onSelect?: (event: React.SyntheticEvent) => void,
187
+ alignOffset?: number,
188
+ className?: string,
189
+ }) {
190
+ return (
191
+ <MenubarPrimitive.SubContent
192
+ onSelect={onSelect}
193
+ alignOffset={alignOffset ?? -5}
194
+ className={cls("min-w-[220px] bg-white dark:bg-gray-950 rounded-md p-[6px] shadow-[0px_10px_38px_-10px_rgba(22,_23,_24,_0.35),_0px_10px_20px_-15px_rgba(22,_23,_24,_0.2)] [animation-duration:_400ms] [animation-timing-function:_cubic-bezier(0.16,_1,_0.3,_1)] will-change-[transform,opacity]",
195
+ className)}
196
+ {...rest}
197
+ >
198
+ {children}
199
+ </MenubarPrimitive.SubContent>
200
+ )
201
+ }
202
+
203
+ export function MenubarCheckboxItem({
204
+ children,
205
+ checked,
206
+ onCheckedChange,
207
+ className,
208
+ onSelect,
209
+ ...rest
210
+ }: {
211
+ children?: React.ReactNode,
212
+ onSelect?: (event: Event) => void;
213
+ checked?: boolean,
214
+ onCheckedChange?: () => void,
215
+ className?: string,
216
+ }) {
217
+ return (
218
+ <MenubarPrimitive.CheckboxItem
219
+ onSelect={onSelect}
220
+ className={cls("text-[13px] leading-none text-text-primary dark:text-text-primary-dark rounded flex items-center h-[32px] px-[10px] py-[2px] relative select-none pl-5 outline-none data-[highlighted]:bg-slate-100 data-[highlighted]:dark:bg-gray-800 data-[disabled]:text-text-disabled data-[disabled]:dark:text-text-disabled-dark data-[disabled]:pointer-events-none",
221
+ className)}
222
+ checked={checked}
223
+ onCheckedChange={onCheckedChange}
224
+ {...rest}
225
+ >
226
+ {children}
227
+ </MenubarPrimitive.CheckboxItem>
228
+ )
229
+ }
230
+
231
+ export function MenubarItemIndicator({
232
+ children,
233
+ className,
234
+ ...rest
235
+ }: {
236
+ children?: React.ReactNode,
237
+ className?: string,
238
+ }) {
239
+ return (
240
+ <MenubarPrimitive.ItemIndicator
241
+ className={cls("absolute left-0 w-4 inline-flex items-center justify-center", className)}
242
+ {...rest}>
243
+ {children ?? <CheckIcon size={"smallest"}/>}
244
+ </MenubarPrimitive.ItemIndicator>
245
+ )
246
+ }
247
+
248
+ export function MenubarRadioGroup({
249
+ children,
250
+ className,
251
+ value,
252
+ onValueChange,
253
+ onSelect,
254
+ ...rest
255
+ }: {
256
+ children?: React.ReactNode,
257
+ onSelect?: (event: React.SyntheticEvent) => void,
258
+ value?: string,
259
+ onValueChange?: (value: string) => void,
260
+ className?: string,
261
+ }) {
262
+ return (
263
+ <MenubarPrimitive.RadioGroup
264
+ className={cls(className)}
265
+ value={value}
266
+ onValueChange={onValueChange}
267
+ onSelect={onSelect}
268
+ {...rest}>
269
+ {children ?? <CheckIcon size={"small"}/>}
270
+ </MenubarPrimitive.RadioGroup>
271
+ )
272
+ }
273
+
274
+ export function MenubarRadioItem({
275
+ children,
276
+ className,
277
+ value,
278
+ onSelect,
279
+ ...rest
280
+ }: {
281
+ children?: React.ReactNode,
282
+ onSelect?: (event: Event) => void;
283
+ value: string,
284
+ className?: string,
285
+ }) {
286
+ return (
287
+ <MenubarPrimitive.RadioItem
288
+ onSelect={onSelect}
289
+ className={cls("text-[13px] leading-none text-text-primary dark:text-text-primary-dark rounded flex items-center h-[32px] px-[10px] py-[2px] relative select-none pl-5 outline-none data-[highlighted]:bg-slate-100 data-[highlighted]:dark:bg-gray-800 data-[disabled]:text-text-disabled data-[disabled]:dark:text-text-disabled-dark data-[disabled]:pointer-events-none",
290
+ className)}
291
+ value={value}
292
+ {...rest}>
293
+ {children ?? <CheckIcon size={"small"}/>}
294
+ </MenubarPrimitive.RadioItem>
295
+ )
296
+ }
297
+
298
+ export function MenubarShortcut({
299
+ children,
300
+ className,
301
+ ...rest
302
+ }: {
303
+ children?: React.ReactNode,
304
+ className?: string,
305
+ }) {
306
+ return (
307
+ <div
308
+ className={cls("ml-auto pl-5 group-data-[disabled]:text-text-disabled data-[disabled]:dark:text-text-disabled-dark",
309
+ className)}
310
+ {...rest}>
311
+ {children}
312
+ </div>
313
+ )
314
+ }
315
+
316
+ export function MenubarSubTriggerIndicator() {
317
+ return (
318
+ <div className="ml-auto pl-5 ">
319
+ <ChevronRightIcon size={"small"}/>
320
+ </div>
321
+ )
322
+ }
@@ -5,9 +5,10 @@ import * as Dialog from "@radix-ui/react-dialog";
5
5
  import { Command as CommandPrimitive } from "cmdk";
6
6
 
7
7
  import { ExpandMoreIcon } from "../icons";
8
- import { fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, fieldBackgroundMixin, focusedMixin } from "../styles";
9
- import { cn, useOutsideAlerter } from "../util";
8
+ import { fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, fieldBackgroundMixin, focusedDisabled } from "../styles";
9
+ import { cls } from "../util";
10
10
  import { SelectInputLabel } from "./common/SelectInputLabel";
11
+ import { useOutsideAlerter } from "../hooks";
11
12
 
12
13
  export type MultiSelectProps = {
13
14
  open?: boolean,
@@ -27,10 +28,7 @@ export type MultiSelectProps = {
27
28
  disabled?: boolean,
28
29
  error?: boolean,
29
30
  position?: "item-aligned" | "popper",
30
- endAdornment?: React.ReactNode,
31
31
  inputRef?: React.RefObject<HTMLButtonElement>,
32
- padding?: boolean,
33
- includeFocusOutline?: boolean,
34
32
  children?: React.ReactNode,
35
33
  };
36
34
 
@@ -51,7 +49,6 @@ export function MultiSelect({
51
49
  disabled,
52
50
  renderValue,
53
51
  renderValues,
54
- includeFocusOutline = true,
55
52
  containerClassName,
56
53
  className,
57
54
  children,
@@ -115,10 +112,10 @@ export function MultiSelect({
115
112
  inputRef.current?.focus();
116
113
  openDialog()
117
114
  }}
118
- className={cn("relative overflow-visible bg-transparent", containerClassName)}>
115
+ className={cls("relative overflow-visible bg-transparent", containerClassName)}>
119
116
  <div
120
117
  ref={containerRef}
121
- className={cn(
118
+ className={cls(
122
119
  "flex flex-row",
123
120
  size === "small" ? "min-h-[42px]" : "min-h-[64px]",
124
121
  "select-none rounded-md text-sm",
@@ -128,10 +125,9 @@ export function MultiSelect({
128
125
  "p-4",
129
126
  error ? "text-red-500 dark:text-red-600" : "focus:text-text-primary dark:focus:text-text-primary-dark",
130
127
  error ? "border border-red-500 dark:border-red-600" : "",
131
- includeFocusOutline ? focusedMixin : "",
132
128
  className)}
133
129
  >
134
- <div className={cn("flex-grow flex gap-1.5 flex-wrap items-center")}>
130
+ <div className={cls("flex-grow flex gap-1.5 flex-wrap items-center")}>
135
131
  {renderValue && (value ?? []).map((v, i) => renderValue(v, i))}
136
132
  {renderValues && renderValues(value ?? [])}
137
133
  <CommandPrimitive.Input
@@ -140,17 +136,19 @@ export function MultiSelect({
140
136
  onValueChange={setInputValue}
141
137
  // onBlur={() => setOpenInternal(false)}
142
138
  onFocus={openDialog}
143
- className="ml-2 bg-transparent outline-none flex-1 h-full w-full "
139
+ className={cls("ml-2 bg-transparent outline-none flex-1 h-full w-full ", focusedDisabled)}
144
140
  />
145
141
  </div>
146
142
  <div className={"px-2 h-full flex items-center"}>
147
143
  <ExpandMoreIcon size={"small"}
148
- className={cn("transition ", openInternal ? "rotate-180" : "")}/>
144
+ className={cls("transition ", openInternal ? "rotate-180" : "")}/>
149
145
  </div>
150
146
 
151
147
  </div>
152
148
 
153
- <Dialog.Root open={openInternal} onOpenChange={setOpenInternal}>
149
+ <Dialog.Root open={openInternal}
150
+ modal={true}
151
+ onOpenChange={setOpenInternal}>
154
152
  <Dialog.Portal>
155
153
  <MultiSelectContext.Provider
156
154
  value={{
@@ -209,7 +207,7 @@ export function MultiSelectItem({ children, value, className }: MultiSelectItemP
209
207
  setInputValue("");
210
208
  onValueChangeInternal(value);
211
209
  }}
212
- className={cn(
210
+ className={cls(
213
211
  (fieldValue ?? []).includes(value) ? "bg-slate-200 dark:bg-slate-950" : "",
214
212
  "cursor-pointer",
215
213
  "m-1",