@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
@@ -1,12 +1,12 @@
1
- import React, { useEffect } from "react";
2
-
1
+ import React, { ChangeEvent, forwardRef, useCallback, useEffect, useState } from "react";
3
2
  import * as SelectPrimitive from "@radix-ui/react-select";
4
3
  import {
4
+ defaultBorderMixin,
5
5
  fieldBackgroundDisabledMixin,
6
6
  fieldBackgroundHoverMixin,
7
7
  fieldBackgroundInvisibleMixin,
8
8
  fieldBackgroundMixin,
9
- focusedMixin
9
+ focusedDisabled
10
10
  } from "../styles";
11
11
  import { CheckIcon, ExpandMoreIcon } from "../icons";
12
12
  import { cls } from "../util";
@@ -17,90 +17,75 @@ export type SelectProps = {
17
17
  name?: string,
18
18
  id?: string,
19
19
  onOpenChange?: (open: boolean) => void,
20
- value?: string | string[],
20
+ value?: string,
21
21
  className?: string,
22
22
  inputClassName?: string,
23
- onChange?: React.EventHandler<React.ChangeEvent<HTMLSelectElement>>,
23
+ onChange?: React.EventHandler<ChangeEvent<HTMLSelectElement>>,
24
24
  onValueChange?: (updatedValue: string) => void,
25
- onMultiValueChange?: (updatedValue: string[]) => void,
26
25
  placeholder?: React.ReactNode,
27
- renderValue?: (value: string, index: number) => React.ReactNode,
28
- renderValues?: (values: string[]) => React.ReactNode,
26
+ renderValue?: (value: string) => React.ReactNode,
29
27
  size?: "small" | "medium",
30
28
  label?: React.ReactNode | string,
31
29
  disabled?: boolean,
32
30
  error?: boolean,
33
31
  position?: "item-aligned" | "popper",
34
32
  endAdornment?: React.ReactNode,
35
- multiple?: boolean,
36
33
  inputRef?: React.RefObject<HTMLButtonElement>,
37
34
  padding?: boolean,
38
- includeFocusOutline?: boolean,
39
35
  invisible?: boolean,
40
- children?: React.ReactNode
36
+ children?: React.ReactNode;
41
37
  };
42
38
 
43
- export function Select({
44
- inputRef,
45
- open,
46
- name,
47
- id,
48
- onOpenChange,
49
- value,
50
- onChange,
51
- onValueChange,
52
- onMultiValueChange,
53
- className,
54
- inputClassName,
55
- placeholder,
56
- renderValue,
57
- renderValues,
58
- label,
59
- size = "medium",
60
- includeFocusOutline = true,
61
- error,
62
- disabled,
63
- padding = true,
64
- position = "item-aligned",
65
- endAdornment,
66
- multiple,
67
- invisible,
68
- children,
69
- ...props
70
- }: SelectProps) {
39
+ export const Select = forwardRef<HTMLDivElement, SelectProps>(({
40
+ inputRef,
41
+ open,
42
+ name,
43
+ id,
44
+ onOpenChange,
45
+ value,
46
+ onChange,
47
+ onValueChange,
48
+ className,
49
+ inputClassName,
50
+ placeholder,
51
+ renderValue,
52
+ label,
53
+ size = "medium",
54
+ error,
55
+ disabled,
56
+ padding = true,
57
+ position = "item-aligned",
58
+ endAdornment,
59
+ invisible,
60
+ children,
61
+ ...props
62
+ }, ref) => {
63
+
64
+ const [openInternal, setOpenInternal] = useState(open ?? false);
71
65
 
72
- const [openInternal, setOpenInternal] = React.useState(false);
73
66
  useEffect(() => {
74
67
  setOpenInternal(open ?? false);
75
68
  }, [open]);
76
69
 
77
- const onValueChangeInternal = React.useCallback((newValue: string) => {
78
- if (multiple) {
79
- if (Array.isArray(value) && value.includes(newValue)) {
80
- onMultiValueChange?.(value.filter(v => v !== newValue));
81
- } else {
82
- onMultiValueChange?.([...(value as string[] ?? []), newValue]);
83
- }
84
- } else {
85
- onValueChange?.(newValue);
86
- }
87
- if (!multiple && onChange) {
70
+ const onValueChangeInternal = useCallback((newValue: string) => {
71
+ onValueChange?.(newValue);
72
+ if (onChange) {
88
73
  const event = {
89
74
  target: {
90
75
  name,
91
76
  value: newValue
92
77
  }
93
- } as React.ChangeEvent<HTMLSelectElement>;
78
+ } as ChangeEvent<HTMLSelectElement>;
94
79
  onChange(event);
95
80
  }
96
- }, [multiple, onChange, value, onMultiValueChange, onValueChange]);
81
+ }, [onChange, value, onValueChange]);
97
82
 
98
83
  const hasValue = Array.isArray(value) ? value.length > 0 : value != null;
84
+
99
85
  return (
100
86
  <SelectPrimitive.Root
101
87
  name={name}
102
- value={Array.isArray(value) ? undefined : value}
103
- defaultOpen={open}
88
+ value={value}
104
89
  open={openInternal}
105
90
  disabled={disabled}
106
91
  onValueChange={onValueChangeInternal}
@@ -108,19 +93,18 @@ export function Select({
108
93
  onOpenChange?.(open);
109
94
  setOpenInternal(open);
110
95
  }}
111
- {...props}>
112
-
96
+ {...props}
97
+ >
113
98
  {typeof label === "string" ? <SelectInputLabel error={error}>{label}</SelectInputLabel> : label}
114
-
115
- <div
116
- className={cls(
117
- size === "small" ? "min-h-[42px]" : "min-h-[64px]",
118
- "select-none rounded-md text-sm",
119
- invisible ? fieldBackgroundInvisibleMixin : fieldBackgroundMixin,
120
- disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin,
121
- "relative flex items-center",
122
- className)}>
123
-
99
+ <div className={cls(
100
+ size === "small" ? "min-h-[42px]" : "min-h-[64px]",
101
+ "select-none rounded-md text-sm",
102
+ invisible ? fieldBackgroundInvisibleMixin : fieldBackgroundMixin,
103
+ disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin,
104
+ "relative flex items-center",
105
+ className
106
+ )}
107
+ >
124
108
  <SelectPrimitive.Trigger
125
109
  ref={inputRef}
126
110
  id={id}
@@ -134,65 +118,62 @@ export function Select({
134
118
  error ? "border border-red-500 dark:border-red-600" : "",
135
119
  disabled ? "text-slate-600 dark:text-slate-400" : "text-slate-800 dark:text-white",
136
120
  "relative flex items-center",
137
- includeFocusOutline ? focusedMixin : "",
138
121
  inputClassName
139
- )}>
140
-
141
- <div className={cls(
142
- "flex-grow w-full max-w-full flex flex-row gap-2 items-center",
143
- "overflow-visible",
144
- size === "small" ? "h-[42px]" : "h-[64px]"
145
- )}>
146
- <SelectPrimitive.Value placeholder={placeholder}>
147
- {renderValue &&
148
- (hasValue && Array.isArray(value)
149
- ? value.map((v, i) => (
150
- <div key={v} className={"flex items-center gap-1 max-w-full"}>
151
- {renderValue ? renderValue(v, i) : v}
152
- </div>))
153
- : (typeof value === "string" ? (renderValue ? renderValue(value, 0) : value) : placeholder))}
154
-
155
- {renderValues && (!hasValue || Array.isArray(value))
156
- ? renderValues(value as string[] ?? [])
157
- : null}
158
-
159
- {!renderValue && !renderValues && hasValue}
160
-
122
+ )}
123
+
124
+ onClick={(e) => {
125
+ e.preventDefault();
126
+ e.stopPropagation();
127
+ }}
128
+ >
129
+ <div
130
+ ref={ref}
131
+ className={cls(
132
+ "flex-grow w-full max-w-full flex flex-row gap-2 items-center",
133
+ "overflow-visible",
134
+ size === "small" ? "h-[42px]" : "h-[64px]"
135
+ )}
136
+ >
137
+ <SelectPrimitive.Value
138
+ onClick={(e) => {
139
+ e.preventDefault();
140
+ e.stopPropagation();
141
+ }}
142
+ placeholder={placeholder}
143
+ className={"w-full"}>
144
+ {hasValue && value && renderValue ? renderValue(value) : placeholder}
145
+ {hasValue && !renderValue && value}
161
146
  </SelectPrimitive.Value>
162
147
  </div>
163
-
164
- <SelectPrimitive.Icon className={cls(
165
- "px-2 h-full flex items-center",
166
- )}>
167
- <ExpandMoreIcon size={"small"}
168
- className={cls("transition", open ? "rotate-180" : "")}/>
148
+ <SelectPrimitive.Icon className={cls("px-2 h-full flex items-center")}>
149
+ <ExpandMoreIcon size={"small"} className={cls("transition", open ? "rotate-180" : "")}/>
169
150
  </SelectPrimitive.Icon>
170
-
171
151
  </SelectPrimitive.Trigger>
172
-
173
- {endAdornment && <div className={cls("absolute h-full flex items-center",
174
- size === "small" ? "right-10" : "right-14")}
175
- onClick={(e) => e.stopPropagation()}>
176
- {endAdornment}
177
- </div>}
178
-
152
+ {endAdornment && (
153
+ <div
154
+ className={cls("absolute h-full flex items-center", size === "small" ? "right-10" : "right-14")}
155
+ onClick={(e) => {
156
+ e.preventDefault();
157
+ e.stopPropagation();
158
+ }}>
159
+ {endAdornment}
160
+ </div>
161
+ )}
179
162
  </div>
180
163
  <SelectPrimitive.Portal>
181
- <SelectPrimitive.Content
182
- position={position}
183
- className="z-50 relative overflow-hidden border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-800 p-2 rounded-lg shadow-lg">
184
- <SelectPrimitive.Viewport
185
- className={"p-1"}
186
- style={{
187
- maxHeight: "var(--radix-select-content-available-height)"
188
- }}>
164
+ <SelectPrimitive.Content position={position}
165
+ className={cls(focusedDisabled, "z-50 relative overflow-hidden border bg-white dark:bg-gray-900 p-2 rounded-lg", defaultBorderMixin)}>
166
+ <SelectPrimitive.Viewport className={"p-1"}
167
+ style={{ maxHeight: "var(--radix-select-content-available-height)" }}>
189
168
  {children}
190
169
  </SelectPrimitive.Viewport>
191
170
  </SelectPrimitive.Content>
192
171
  </SelectPrimitive.Portal>
193
172
  </SelectPrimitive.Root>
194
173
  );
195
- }
174
+ });
175
+
176
+ Select.displayName = "Select";
196
177
 
197
178
  export type SelectItemProps = {
198
179
  value: string,
@@ -217,17 +198,15 @@ export function SelectItem({
217
198
  }}
218
199
  className={cls(
219
200
  "w-full",
220
- "relative relative flex items-center p-2 rounded-md text-sm text-slate-700 dark:text-slate-300",
221
- focusedMixin,
201
+ "relative flex items-center p-2 rounded-md text-sm text-slate-700 dark:text-slate-300",
222
202
  "focus:z-10",
223
- "data-[state=checked]:bg-slate-100 data-[state=checked]:dark:bg-slate-900 focus:bg-slate-100 dark:focus:bg-slate-950",
224
- "data-[state=checked]:focus:bg-slate-200 data-[state=checked]:dark:focus:bg-slate-950",
203
+ "data-[state=checked]:bg-slate-100 data-[state=checked]:dark:bg-slate-800 focus:bg-slate-100 dark:focus:bg-gray-950",
204
+ "data-[state=checked]:focus:bg-slate-200 data-[state=checked]:dark:focus:bg-gray-950",
225
205
  disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer",
226
206
  "[&>*]:w-full",
227
207
  "overflow-visible",
228
208
  className
229
- )}
230
- >
209
+ )}>
231
210
  <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
232
211
  <div
233
212
  className="absolute left-1 data-[state=checked]:block hidden">
@@ -1,20 +1,26 @@
1
1
  import * as SeparatorPrimitive from "@radix-ui/react-separator";
2
+ import { cls } from "../util";
2
3
 
3
- export function Separator({ orientation, decorative }: {
4
+ export function Separator({
5
+ orientation,
6
+ decorative,
7
+ className
8
+ }: {
4
9
  orientation: "horizontal" | "vertical",
5
- decorative?: boolean
10
+ decorative?: boolean,
11
+ className?: string
6
12
  }) {
7
13
  if (orientation === "horizontal")
8
14
  return (
9
15
  <SeparatorPrimitive.Root
10
16
  decorative={decorative}
11
17
  orientation="horizontal"
12
- className="dark:bg-opacity-50 bg-opacity-50 dark:bg-gray-600 bg-gray-300 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px my-[8px]"/>
18
+ className={cls("dark:bg-opacity-80 dark:bg-gray-800 bg-gray-100 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px my-4", className)}/>
13
19
  );
14
20
  else
15
21
  return (
16
22
  <SeparatorPrimitive.Root
17
- className="dark:bg-opacity-50 bg-opacity-50 dark:bg-gray-600 bg-gray-300 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px mx-[8px]"
23
+ className={cls("dark:bg-opacity-80 dark:bg-gray-800 bg-gray-100 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px mx-4", className)}
18
24
  decorative={decorative}
19
25
  orientation="vertical"
20
26
  />
@@ -1,37 +1,38 @@
1
- import React, { useEffect } from "react";
2
- import * as DialogPrimitive from "@radix-ui/react-dialog";
1
+ import React, { useEffect, useState } from "react";
3
2
  import { cls } from "../util";
3
+ import { defaultBorderMixin } from "../styles";
4
+ import * as DialogPrimitive from "@radix-ui/react-dialog";
4
5
 
5
6
  interface SheetProps {
6
7
  children: React.ReactNode;
7
8
  open: boolean;
9
+ title?: string;
8
10
  side?: "top" | "bottom" | "left" | "right";
11
+ darkBackground?: boolean;
9
12
  transparent?: boolean;
10
13
  onOpenChange?: (open: boolean) => void;
14
+ className?: string;
15
+ overlayClassName?: string;
11
16
  }
12
17
 
13
18
  export const Sheet: React.FC<SheetProps> = ({
14
19
  children,
15
20
  side = "right",
21
+ title,
16
22
  open,
17
23
  onOpenChange,
18
24
  transparent,
25
+ className,
26
+ overlayClassName,
19
27
  ...props
20
28
  }) => {
21
-
22
- const [displayed, setDisplayed] = React.useState(false);
29
+ const [displayed, setDisplayed] = useState(false);
23
30
 
24
31
  useEffect(() => {
25
- if (!open) {
26
- const timeout = setTimeout(() => {
27
- setDisplayed(false);
28
- }, 250);
29
- return () => clearTimeout(timeout);
30
- } else {
31
- setDisplayed(true);
32
- return () => {
33
- };
34
- }
32
+ const timeout = setTimeout(() => {
33
+ setDisplayed(open);
34
+ }, 1);
35
+ return () => clearTimeout(timeout);
35
36
  }, [open]);
36
37
 
37
38
  const transformValue: Record<string, string> = {
@@ -41,36 +42,52 @@ export const Sheet: React.FC<SheetProps> = ({
41
42
  right: "translate-x-full"
42
43
  };
43
44
 
44
- return (
45
+ const borderClass: Record<string, string> = {
46
+ top: "border-b",
47
+ bottom: "border-t",
48
+ left: "border-r",
49
+ right: "border-l"
50
+ };
45
51
 
52
+ return (
46
53
  <DialogPrimitive.Root open={displayed || open}
47
54
  onOpenChange={onOpenChange}>
48
55
  <DialogPrimitive.Portal>
56
+ <DialogPrimitive.Title autoFocus tabIndex={0}>
57
+ {title ?? "Sheet"}
58
+ </DialogPrimitive.Title>
49
59
  <DialogPrimitive.Overlay
50
60
  className={cls(
51
- "fixed inset-0 transition-opacity z-20 ease-in-out duration-200 backdrop-blur-sm",
61
+ "fixed inset-0 transition-opacity z-20 ease-in-out duration-100 backdrop-blur-sm",
52
62
  "bg-black bg-opacity-50",
53
63
  "dark:bg-gray-900 dark:bg-opacity-60",
54
- displayed && open ? "opacity-100" : "opacity-0"
64
+ displayed && open ? "opacity-100" : "opacity-0",
65
+ overlayClassName
55
66
  )}
56
67
  style={{
57
- pointerEvents: displayed ? "auto" : "none",
68
+ pointerEvents: displayed ? "auto" : "none"
58
69
  }}
70
+ onClick={() => onOpenChange && onOpenChange(false)}
59
71
  />
60
72
  <DialogPrimitive.Content
61
73
  {...props}
74
+ onFocusCapture={(event) => event.preventDefault()}
62
75
  className={cls(
76
+ borderClass[side],
77
+ defaultBorderMixin,
63
78
  "transform-gpu",
64
79
  "will-change-transform",
65
80
  "text-slate-900 dark:text-white",
66
- "fixed transform z-20 transition-all duration-[240ms] ease-in-out",
81
+ "fixed transform z-20 transition-all ease-in-out",
82
+ !displayed ? "duration-150" : "duration-100",
67
83
  "outline-none focus:outline-none",
68
84
  transparent ? "" : "shadow-md bg-white dark:bg-gray-950",
69
85
  side === "top" || side === "bottom" ? "w-full" : "h-full",
70
86
  side === "left" || side === "top" ? "left-0 top-0" : "right-0 bottom-0",
71
- displayed && open ? "opacity-100" : "opacity-0",
72
- !displayed || !open ? transformValue[side] : "")
73
- }
87
+ displayed && open ? "opacity-100" : "opacity-50",
88
+ !displayed || !open ? transformValue[side] : "",
89
+ className
90
+ )}
74
91
  >
75
92
  {children}
76
93
  </DialogPrimitive.Content>
@@ -20,7 +20,7 @@ export function Skeleton({
20
20
  className={
21
21
  cls(
22
22
  "block",
23
- "bg-slate-200 dark:bg-slate-800 rounded",
23
+ "bg-slate-200 dark:bg-slate-800 rounded-md",
24
24
  "animate-pulse",
25
25
  "max-w-full max-h-full",
26
26
  className)
@@ -6,16 +6,19 @@ export type TableProps = {
6
6
  children: React.ReactNode;
7
7
  className?: string;
8
8
  style?: React.CSSProperties;
9
- };
9
+ } & React.TableHTMLAttributes<HTMLTableElement>;
10
10
 
11
11
  export const Table = ({
12
12
  children,
13
13
  className,
14
- style
14
+ style,
15
+ ...rest
15
16
  }: TableProps) => (
16
- <table className={cls("w-full text-left text-gray-800 dark:text-white rounded-md overflow-x-auto",
17
- className)}
18
- style={style}>
17
+ <table
18
+ className={cls("text-left text-gray-800 dark:text-white rounded-md overflow-x-auto", className)}
19
+ style={style}
20
+ {...rest}
21
+ >
19
22
  {children}
20
23
  </table>
21
24
  );
@@ -23,13 +26,17 @@ export const Table = ({
23
26
  export type TableBodyProps = {
24
27
  children?: React.ReactNode;
25
28
  className?: string;
26
- };
29
+ } & React.HTMLAttributes<HTMLTableSectionElement>;
30
+
27
31
  export const TableBody = ({
28
32
  children,
29
- className
33
+ className,
34
+ ...rest
30
35
  }: TableBodyProps) => (
31
36
  <tbody
32
- className={cls("bg-white text-sm dark:bg-gray-800 divide-y divide-slate-200 dark:divide-gray-700", className)}>
37
+ className={cls("bg-white dark:bg-gray-950 text-sm divide-y divide-slate-200 dark:divide-gray-700", className)}
38
+ {...rest}
39
+ >
33
40
  {children}
34
41
  </tbody>
35
42
  );
@@ -37,17 +44,22 @@ export const TableBody = ({
37
44
  export type TableHeaderProps = {
38
45
  children?: React.ReactNode;
39
46
  className?: string;
40
- };
47
+ } & React.HTMLAttributes<HTMLTableSectionElement>;
41
48
 
42
49
  export const TableHeader = ({
43
50
  children,
44
- className
51
+ className,
52
+ ...rest
45
53
  }: TableHeaderProps) => (
46
- <thead>
47
- <tr className={cls(
48
- defaultBorderMixin,
49
- "text-sm font-medium text-gray-700 dark:text-slate-300",
50
- "bg-slate-50 border-b dark:bg-gray-900", className)}>
54
+ <thead {...rest}>
55
+ <tr
56
+ className={cls(
57
+ defaultBorderMixin,
58
+ "text-sm font-medium text-gray-700 dark:text-slate-300",
59
+ "bg-slate-50 border-b dark:bg-gray-900",
60
+ className
61
+ )}
62
+ >
51
63
  {children}
52
64
  </tr>
53
65
  </thead>
@@ -58,13 +70,14 @@ export type TableRowProps = {
58
70
  className?: string;
59
71
  onClick?: React.MouseEventHandler<any>;
60
72
  style?: React.CSSProperties;
61
- };
73
+ } & React.HTMLAttributes<HTMLTableRowElement>;
62
74
 
63
75
  export const TableRow = ({
64
76
  children,
65
77
  className,
66
78
  onClick,
67
- style
79
+ style,
80
+ ...rest
68
81
  }: TableRowProps) => (
69
82
  <tr
70
83
  onClick={onClick}
@@ -73,7 +86,9 @@ export const TableRow = ({
73
86
  "divide-slate-100 dark:divide-gray-800",
74
87
  "bg-white dark:bg-gray-950",
75
88
  onClick ? "hover:bg-slate-100 dark:hover:bg-gray-800 cursor-pointer" : "",
76
- className)}
89
+ className
90
+ )}
91
+ {...rest}
77
92
  >
78
93
  {children}
79
94
  </tr>
@@ -87,7 +102,7 @@ export type TableCellProps = {
87
102
  style?: React.CSSProperties;
88
103
  align?: "left" | "center" | "right";
89
104
  colspan?: number;
90
- };
105
+ } & React.HTMLAttributes<HTMLTableCellElement>;
91
106
 
92
107
  export const TableCell = ({
93
108
  children,
@@ -96,20 +111,24 @@ export const TableCell = ({
96
111
  align,
97
112
  className,
98
113
  style,
99
- colspan
114
+ colspan,
115
+ ...rest
100
116
  }: TableCellProps) => {
101
-
102
117
  const ref = useRef<HTMLTableCellElement>(null);
103
-
104
118
  const Tag = header || getParentName(ref.current) === "TableHeader" ? "th" : "td";
105
119
  return (
106
- <Tag scope={scope}
107
- colSpan={colspan}
108
- ref={ref}
109
- style={style}
110
- className={cls("px-4 py-3 text-clip ",
111
- align === "center" ? "text-center" : (align === "right" ? "text-right" : "text-left"),
112
- className)}>
120
+ <Tag
121
+ scope={scope}
122
+ colSpan={colspan}
123
+ ref={ref}
124
+ style={style}
125
+ className={cls(
126
+ "px-4 py-3 text-clip ",
127
+ align === "center" ? "text-center" : (align === "right" ? "text-right" : "text-left"),
128
+ className
129
+ )}
130
+ {...rest}
131
+ >
113
132
  {children}
114
133
  </Tag>
115
134
  );
@@ -124,7 +143,6 @@ function getParentName(element: HTMLElement | null): string | undefined {
124
143
  key.startsWith("__reactInternalInstance$")
125
144
  );
126
145
  });
127
-
128
146
  // @ts-ignore
129
147
  const domFiber = element[key];
130
148
  // @ts-ignore
@@ -1,6 +1,5 @@
1
1
  import React from "react";
2
2
  import * as TabsPrimitive from "@radix-ui/react-tabs";
3
- import { focusedMixin } from "../styles";
4
3
  import { cls } from "../util";
5
4
 
6
5
  export type TabsProps = {
@@ -42,7 +41,7 @@ export function Tab({
42
41
  }: TabProps) {
43
42
  return <TabsPrimitive.Trigger value={value}
44
43
  disabled={disabled}
45
- className={cls(focusedMixin,
44
+ className={cls(
46
45
  "border-b-2 border-transparent",
47
46
  "data-[state=active]:border-secondary",
48
47
  disabled
@@ -54,7 +53,7 @@ export function Tab({
54
53
  // "data-[state=active]:bg-slate-50 data-[state=active]:dark:bg-slate-800",
55
54
  className)}>
56
55
  <div className={cls("uppercase inline-block p-2 px-4 m-2 rounded",
57
- "hover:bg-slate-100 dark:hover:bg-slate-800")}>
56
+ "hover:bg-slate-200 hover:bg-opacity-75 dark:hover:bg-slate-800")}>
58
57
  {children}
59
58
  </div>
60
59
  </TabsPrimitive.Trigger>;