@firecms/ui 3.0.0-beta.8 → 3.0.0-beta.9

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 (59) hide show
  1. package/dist/components/BooleanSwitch.d.ts +1 -1
  2. package/dist/components/Checkbox.d.ts +1 -1
  3. package/dist/components/Chip.d.ts +3 -2
  4. package/dist/components/DateTimeField.d.ts +2 -3
  5. package/dist/components/Dialog.d.ts +4 -1
  6. package/dist/components/Menu.d.ts +4 -1
  7. package/dist/components/Menubar.d.ts +19 -9
  8. package/dist/components/MultiSelect.d.ts +31 -16
  9. package/dist/components/Popover.d.ts +2 -1
  10. package/dist/components/RadioGroup.d.ts +1 -0
  11. package/dist/components/Select.d.ts +5 -9
  12. package/dist/components/Separator.d.ts +2 -1
  13. package/dist/components/Sheet.d.ts +4 -0
  14. package/dist/components/Table.d.ts +10 -10
  15. package/dist/components/Tooltip.d.ts +6 -2
  16. package/dist/components/_MultiSelect.d.ts +0 -0
  17. package/dist/icons/Icon.d.ts +1 -1
  18. package/dist/index.css +77 -0
  19. package/dist/index.es.js +13036 -13690
  20. package/dist/index.es.js.map +1 -1
  21. package/dist/index.umd.js +19684 -49
  22. package/dist/index.umd.js.map +1 -1
  23. package/dist/styles.d.ts +3 -3
  24. package/package.json +109 -106
  25. package/src/components/Avatar.tsx +0 -2
  26. package/src/components/BooleanSwitch.tsx +11 -11
  27. package/src/components/BooleanSwitchWithLabel.tsx +4 -4
  28. package/src/components/Button.tsx +6 -8
  29. package/src/components/Card.tsx +2 -2
  30. package/src/components/Checkbox.tsx +5 -5
  31. package/src/components/Chip.tsx +7 -4
  32. package/src/components/DateTimeField.tsx +30 -41
  33. package/src/components/Dialog.tsx +11 -2
  34. package/src/components/ExpandablePanel.tsx +3 -3
  35. package/src/components/FileUpload.tsx +1 -2
  36. package/src/components/IconButton.tsx +1 -3
  37. package/src/components/InputLabel.tsx +4 -2
  38. package/src/components/Menu.tsx +38 -26
  39. package/src/components/Menubar.tsx +42 -7
  40. package/src/components/MultiSelect.tsx +333 -164
  41. package/src/components/Popover.tsx +15 -13
  42. package/src/components/RadioGroup.tsx +1 -0
  43. package/src/components/SearchBar.tsx +1 -2
  44. package/src/components/Select.tsx +98 -119
  45. package/src/components/Separator.tsx +10 -4
  46. package/src/components/Sheet.tsx +39 -22
  47. package/src/components/Skeleton.tsx +1 -1
  48. package/src/components/Table.tsx +48 -30
  49. package/src/components/Tabs.tsx +2 -3
  50. package/src/components/TextField.tsx +2 -6
  51. package/src/components/Tooltip.tsx +26 -11
  52. package/src/components/Typography.tsx +14 -16
  53. package/src/components/_MultiSelect.tsx +222 -0
  54. package/src/icons/Icon.tsx +2 -2
  55. package/src/icons/icon_keys.ts +114 -1301
  56. package/src/index.css +77 -0
  57. package/src/scripts/generateIconKeys.ts +20 -10
  58. package/src/styles.ts +3 -3
  59. package/tailwind.config.js +3 -3
@@ -15,6 +15,9 @@ export type DialogProps = {
15
15
  maxWidth?: keyof typeof widthClasses;
16
16
  modal?: boolean;
17
17
  onOpenAutoFocus?: (e: Event) => void;
18
+ onEscapeKeyDown?: (e: KeyboardEvent) => void;
19
+ onPointerDownOutside?: (e: Event) => void;
20
+ onInteractOutside?: (e: Event) => void;
18
21
  };
19
22
 
20
23
  const widthClasses = {
@@ -43,7 +46,10 @@ export const Dialog = ({
43
46
  scrollable = true,
44
47
  maxWidth = "lg",
45
48
  modal = true,
46
- onOpenAutoFocus
49
+ onOpenAutoFocus,
50
+ onEscapeKeyDown,
51
+ onPointerDownOutside,
52
+ onInteractOutside
47
53
  }: DialogProps) => {
48
54
  const [displayed, setDisplayed] = useState(false);
49
55
 
@@ -51,7 +57,7 @@ export const Dialog = ({
51
57
  if (!open) {
52
58
  const timeout = setTimeout(() => {
53
59
  setDisplayed(false);
54
- }, 250);
60
+ }, 150);
55
61
  return () => clearTimeout(timeout);
56
62
  } else {
57
63
  setDisplayed(true);
@@ -79,7 +85,10 @@ export const Dialog = ({
79
85
  />
80
86
 
81
87
  <DialogPrimitive.Content
88
+ onEscapeKeyDown={onEscapeKeyDown}
82
89
  onOpenAutoFocus={onOpenAutoFocus}
90
+ onPointerDownOutside={onPointerDownOutside}
91
+ onInteractOutside={onInteractOutside}
83
92
  className={cls("h-full outline-none flex justify-center items-center z-40 opacity-100 transition-all duration-200 ease-in-out")}
84
93
  >
85
94
  <div
@@ -1,7 +1,7 @@
1
1
  import React, { PropsWithChildren, useEffect, useState } from "react";
2
2
 
3
3
  import * as Collapsible from "@radix-ui/react-collapsible";
4
- import { defaultBorderMixin, fieldBackgroundMixin, focusedMixin } from "../styles";
4
+ import { defaultBorderMixin, fieldBackgroundMixin } from "../styles";
5
5
  import { ExpandMoreIcon } from "../icons";
6
6
  import { cls } from "../util";
7
7
  import { useInjectStyles } from "../hooks";
@@ -88,9 +88,9 @@ export function ExpandablePanel({
88
88
  }}>
89
89
 
90
90
  <Collapsible.Trigger
91
- className={cls(focusedMixin,
91
+ className={cls(
92
92
  "rounded flex items-center justify-between w-full min-h-[52px]",
93
- "hover:bg-slate-50 dark:hover:bg-gray-800 dark:hover:bg-opacity-10",
93
+ "hover:bg-slate-50 dark:hover:bg-gray-800 dark:hover:bg-opacity-20",
94
94
  invisible ? "border-b px-2" : "p-4",
95
95
  invisible && defaultBorderMixin,
96
96
  asField && fieldBackgroundMixin,
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { useDropzone } from "react-dropzone";
3
- import { fieldBackgroundHoverMixin, fieldBackgroundMixin, focusedMixin } from "../styles";
3
+ import { fieldBackgroundHoverMixin, fieldBackgroundMixin } from "../styles";
4
4
  import { cls } from "../util";
5
5
  import { Typography } from "./Typography";
6
6
 
@@ -65,7 +65,6 @@ export function FileUpload({
65
65
  {...getRootProps()}
66
66
  className={cls(
67
67
  fieldBackgroundMixin,
68
- focusedMixin,
69
68
  "flex gap-2",
70
69
  "p-4 box-border relative items-center border-2 border-solid border-transparent outline-none rounded-md duration-200 ease-[cubic-bezier(0.4,0,0.2,1)] focus:border-primary-solid",
71
70
  {
@@ -1,5 +1,4 @@
1
1
  import React from "react";
2
- import { focusedMixin } from "../styles";
3
2
  import { cls } from "../util";
4
3
 
5
4
  export type IconButtonProps<C extends React.ElementType> =
@@ -15,7 +14,7 @@ export type IconButtonProps<C extends React.ElementType> =
15
14
  }
16
15
 
17
16
  const buttonClasses =
18
- "hover:bg-slate-200 hover:bg-opacity-75 dark:hover:bg-gray-700 dark:hover:bg-opacity-50";
17
+ "hover:bg-slate-200 hover:bg-opacity-75 dark:hover:bg-slate-800";
19
18
  const baseClasses =
20
19
  "inline-flex items-center justify-center p-2 text-sm font-medium focus:outline-none transition-colors ease-in-out duration-150";
21
20
  const colorClasses = "text-slate-600 visited:text-slate-600 dark:text-slate-300 dark:visited:text-gray-300";
@@ -50,7 +49,6 @@ const IconButtonInner = <C extends React.ElementType = "button">({
50
49
  ref={ref}
51
50
  {...props}
52
51
  className={cls(
53
- focusedMixin,
54
52
  disabled ? "opacity-50 pointer-events-none" : "cursor-pointer",
55
53
  toggled ? "outline outline-2 outline-primary" : "",
56
54
  colorClasses,
@@ -1,6 +1,7 @@
1
1
  import * as React from "react";
2
2
  import { cls } from "../util";
3
3
  import { Label } from "./Label";
4
+ import { defaultBorderMixin } from "../styles";
4
5
 
5
6
  export type InputLabelProps = {
6
7
  children?: React.ReactNode;
@@ -28,10 +29,11 @@ export const InputLabel = React.forwardRef<HTMLLabelElement, InputLabelProps>(fu
28
29
  }, className);
29
30
 
30
31
  return (
31
- <Label
32
+ <label
33
+ className={cls("text-sm font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
34
+ defaultBorderMixin, computedClassName)}
32
35
  data-shrink={shrink}
33
36
  ref={ref}
34
- className={computedClassName}
35
37
  {...other}
36
38
  />
37
39
  );
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
3
- import { focusedMixin, paperMixin } from "../styles";
3
+ import { focusedDisabled, paperMixin } from "../styles";
4
4
  import { cls } from "../util";
5
5
 
6
6
  export type MenuProps = {
@@ -12,32 +12,45 @@ 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={cls(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;
@@ -52,7 +65,6 @@ export function MenuItem({
52
65
  }: MenuItemProps) {
53
66
  // Dynamically adjusting the class based on the "dense" prop
54
67
  const classNames = cls(
55
- focusedMixin,
56
68
  onClick && "cursor-pointer",
57
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",
58
70
  dense ? "px-3 py-1.5" : "px-4 py-2"
@@ -1,13 +1,21 @@
1
+ import * as React from "react";
2
+
1
3
  import * as MenubarPrimitive from "@radix-ui/react-menubar";
2
4
  import { cls } from "../util";
3
5
  import { CheckIcon, ChevronRightIcon } from "../icons";
4
6
 
5
7
  export function Menubar({
6
8
  children,
9
+ onSelect,
7
10
  className
8
- }: { children: React.ReactNode, className?: string }) {
11
+ }: {
12
+ children: React.ReactNode,
13
+ onSelect?: (event: React.SyntheticEvent) => void,
14
+ className?: string
15
+ }) {
9
16
  return (
10
17
  <MenubarPrimitive.Root
18
+ onSelect={onSelect}
11
19
  className={cls("z-10 flex bg-white dark:bg-gray-950 p-[3px] rounded-sm shadow-sm", className)}>
12
20
  {children}
13
21
  </MenubarPrimitive.Root>
@@ -26,10 +34,16 @@ export function MenubarMenu({
26
34
 
27
35
  export function MenubarTrigger({
28
36
  children,
37
+ onSelect,
29
38
  className
30
- }: { children: React.ReactNode, className?: string }) {
39
+ }: {
40
+ children: React.ReactNode,
41
+ onSelect?: (event: React.SyntheticEvent) => void,
42
+ className?: string
43
+ }) {
31
44
  return (
32
45
  <MenubarPrimitive.Trigger
46
+ onSelect={onSelect}
33
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",
34
48
  className)}>
35
49
  {children}
@@ -53,16 +67,19 @@ export function MenubarContent({
53
67
  align,
54
68
  sideOffset,
55
69
  alignOffset,
70
+ onSelect,
56
71
  ...rest
57
72
  }: {
58
73
  children: React.ReactNode,
59
74
  className?: string,
75
+ onSelect?: (event: React.SyntheticEvent) => void,
60
76
  align?: "start" | "center" | "end",
61
77
  sideOffset?: number,
62
78
  alignOffset?: number
63
79
  }) {
64
80
  return (
65
81
  <MenubarPrimitive.Content
82
+ onSelect={onSelect}
66
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)}
67
84
  align={align ?? "start"}
68
85
  sideOffset={sideOffset ?? 5}
@@ -79,16 +96,19 @@ export function MenubarItem({
79
96
  leftPadding,
80
97
  className,
81
98
  disabled,
99
+ onSelect,
82
100
  ...rest
83
101
  }: {
84
102
  children: React.ReactNode,
103
+ onSelect?: (event: Event) => void;
85
104
  leftPadding?: boolean,
86
105
  className?: string,
87
106
  disabled?: boolean
88
107
  }) {
89
108
  return (
90
109
  <MenubarPrimitive.Item
91
- 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-disabled data-[disabled]:dark:text-disabled-dark data-[disabled]:pointer-events-none",
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",
92
112
  leftPadding ? "pl-5" : "",
93
113
  disabled ? "pointer-events-none text-text-secondary dark:text-text-secondary-dark" : "text-text-primary dark:text-text-primary-dark",
94
114
  className)}
@@ -136,14 +156,17 @@ export function MenubarSub({
136
156
  export function MenubarSubTrigger({
137
157
  children,
138
158
  className,
159
+ onSelect,
139
160
  ...rest
140
161
  }: {
141
162
  children?: React.ReactNode,
163
+ onSelect?: (event: React.SyntheticEvent) => void,
142
164
  className?: string,
143
165
  }) {
144
166
  return (
145
167
  <MenubarPrimitive.SubTrigger
146
- 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-disabled data-[disabled]:dark:text-disabled-dark data-[disabled]:pointer-events-none",
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",
147
170
  className)}
148
171
  {...rest}
149
172
  >
@@ -156,14 +179,17 @@ export function MenubarSubContent({
156
179
  children,
157
180
  alignOffset,
158
181
  className,
182
+ onSelect,
159
183
  ...rest
160
184
  }: {
161
185
  children?: React.ReactNode,
186
+ onSelect?: (event: React.SyntheticEvent) => void,
162
187
  alignOffset?: number,
163
188
  className?: string,
164
189
  }) {
165
190
  return (
166
191
  <MenubarPrimitive.SubContent
192
+ onSelect={onSelect}
167
193
  alignOffset={alignOffset ?? -5}
168
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]",
169
195
  className)}
@@ -179,16 +205,19 @@ export function MenubarCheckboxItem({
179
205
  checked,
180
206
  onCheckedChange,
181
207
  className,
208
+ onSelect,
182
209
  ...rest
183
210
  }: {
184
211
  children?: React.ReactNode,
212
+ onSelect?: (event: Event) => void;
185
213
  checked?: boolean,
186
214
  onCheckedChange?: () => void,
187
215
  className?: string,
188
216
  }) {
189
217
  return (
190
218
  <MenubarPrimitive.CheckboxItem
191
- 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-disabled data-[disabled]:dark:text-disabled-dark data-[disabled]:pointer-events-none",
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",
192
221
  className)}
193
222
  checked={checked}
194
223
  onCheckedChange={onCheckedChange}
@@ -221,9 +250,11 @@ export function MenubarRadioGroup({
221
250
  className,
222
251
  value,
223
252
  onValueChange,
253
+ onSelect,
224
254
  ...rest
225
255
  }: {
226
256
  children?: React.ReactNode,
257
+ onSelect?: (event: React.SyntheticEvent) => void,
227
258
  value?: string,
228
259
  onValueChange?: (value: string) => void,
229
260
  className?: string,
@@ -233,6 +264,7 @@ export function MenubarRadioGroup({
233
264
  className={cls(className)}
234
265
  value={value}
235
266
  onValueChange={onValueChange}
267
+ onSelect={onSelect}
236
268
  {...rest}>
237
269
  {children ?? <CheckIcon size={"small"}/>}
238
270
  </MenubarPrimitive.RadioGroup>
@@ -243,15 +275,18 @@ export function MenubarRadioItem({
243
275
  children,
244
276
  className,
245
277
  value,
278
+ onSelect,
246
279
  ...rest
247
280
  }: {
248
281
  children?: React.ReactNode,
282
+ onSelect?: (event: Event) => void;
249
283
  value: string,
250
284
  className?: string,
251
285
  }) {
252
286
  return (
253
287
  <MenubarPrimitive.RadioItem
254
- 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-disabled data-[disabled]:dark:text-disabled-dark data-[disabled]:pointer-events-none",
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",
255
290
  className)}
256
291
  value={value}
257
292
  {...rest}>
@@ -270,7 +305,7 @@ export function MenubarShortcut({
270
305
  }) {
271
306
  return (
272
307
  <div
273
- className={cls("ml-auto pl-5 group-data-[disabled]:text-disabled data-[disabled]:dark:text-disabled-dark",
308
+ className={cls("ml-auto pl-5 group-data-[disabled]:text-text-disabled data-[disabled]:dark:text-text-disabled-dark",
274
309
  className)}
275
310
  {...rest}>
276
311
  {children}