@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.
- package/README.md +1 -1
- package/dist/components/Avatar.d.ts +1 -0
- package/dist/components/BooleanSwitch.d.ts +1 -1
- package/dist/components/CenteredView.d.ts +4 -2
- package/dist/components/Checkbox.d.ts +3 -2
- package/dist/components/Chip.d.ts +3 -2
- package/dist/components/DateTimeField.d.ts +3 -4
- package/dist/components/Dialog.d.ts +4 -1
- package/dist/components/InputLabel.d.ts +2 -2
- package/dist/components/Label.d.ts +4 -1
- package/dist/components/Markdown.d.ts +1 -0
- package/dist/components/Menu.d.ts +6 -2
- package/dist/components/Menubar.d.ts +79 -0
- package/dist/components/MultiSelect.d.ts +1 -4
- package/dist/components/NewMultiSelect.d.ts +60 -0
- package/dist/components/Popover.d.ts +2 -1
- package/dist/components/RadioGroup.d.ts +26 -3
- package/dist/components/Select.d.ts +4 -4
- package/dist/components/Sheet.d.ts +4 -0
- package/dist/components/Table.d.ts +10 -10
- package/dist/components/TextField.d.ts +1 -1
- package/dist/components/TextareaAutosize.d.ts +3 -34
- package/dist/components/Tooltip.d.ts +5 -2
- package/dist/components/index.d.ts +2 -1
- package/dist/hooks/index.d.ts +4 -0
- package/dist/hooks/useLocaleConfig.d.ts +1 -0
- package/dist/icons/Icon.d.ts +3 -3
- package/dist/index.css +77 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +13290 -13511
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +19828 -49
- package/dist/index.umd.js.map +1 -1
- package/dist/styles.d.ts +7 -7
- package/dist/util/{cn.d.ts → cls.d.ts} +4 -0
- package/dist/util/index.d.ts +1 -3
- package/package.json +109 -118
- package/src/components/Alert.tsx +2 -2
- package/src/components/Autocomplete.tsx +4 -3
- package/src/components/Avatar.tsx +7 -6
- package/src/components/Badge.tsx +1 -1
- package/src/components/BooleanSwitch.tsx +15 -15
- package/src/components/BooleanSwitchWithLabel.tsx +8 -8
- package/src/components/Button.tsx +11 -13
- package/src/components/Card.tsx +3 -3
- package/src/components/CenteredView.tsx +25 -15
- package/src/components/Checkbox.tsx +11 -9
- package/src/components/Chip.tsx +8 -5
- package/src/components/CircularProgress.tsx +2 -2
- package/src/components/Collapse.tsx +3 -2
- package/src/components/Container.tsx +2 -2
- package/src/components/DateTimeField.tsx +38 -48
- package/src/components/Dialog.tsx +15 -6
- package/src/components/DialogActions.tsx +2 -2
- package/src/components/DialogContent.tsx +2 -2
- package/src/components/ExpandablePanel.tsx +10 -8
- package/src/components/FileUpload.tsx +6 -9
- package/src/components/IconButton.tsx +4 -6
- package/src/components/InfoLabel.tsx +2 -2
- package/src/components/InputLabel.tsx +12 -9
- package/src/components/Label.tsx +17 -4
- package/src/components/Markdown.tsx +14 -3
- package/src/components/Menu.tsx +49 -31
- package/src/components/Menubar.tsx +322 -0
- package/src/components/MultiSelect.tsx +12 -14
- package/src/components/NewMultiSelect.tsx +370 -0
- package/src/components/Paper.tsx +2 -2
- package/src/components/Popover.tsx +17 -14
- package/src/components/RadioGroup.tsx +41 -9
- package/src/components/SearchBar.tsx +7 -8
- package/src/components/Select.tsx +92 -104
- package/src/components/Sheet.tsx +45 -28
- package/src/components/Skeleton.tsx +9 -6
- package/src/components/Table.tsx +50 -32
- package/src/components/Tabs.tsx +6 -7
- package/src/components/TextField.tsx +10 -13
- package/src/components/TextareaAutosize.tsx +3 -3
- package/src/components/Tooltip.tsx +27 -13
- package/src/components/Typography.tsx +34 -19
- package/src/components/common/SelectInputLabel.tsx +2 -2
- package/src/components/index.tsx +2 -1
- package/src/hooks/index.ts +4 -0
- package/src/hooks/useLocaleConfig.tsx +18 -0
- package/src/icons/Icon.tsx +46 -43
- package/src/icons/icon_keys.ts +114 -1301
- package/src/index.css +77 -0
- package/src/index.ts +1 -0
- package/src/scripts/generateIconKeys.ts +20 -11
- package/src/styles.ts +7 -7
- package/src/util/cls.ts +14 -0
- package/src/util/index.ts +1 -3
- package/tailwind.config.js +5 -3
- package/dist/components/Spinner.d.ts +0 -1
- package/src/components/Spinner.tsx +0 -18
- package/src/util/cn.ts +0 -6
- /package/dist/{util → hooks}/useDebounceValue.d.ts +0 -0
- /package/dist/{util → hooks}/useInjectStyles.d.ts +0 -0
- /package/dist/{util → hooks}/useOutsideAlerter.d.ts +0 -0
- /package/src/{util → hooks}/useDebounceValue.tsx +0 -0
- /package/src/{util → hooks}/useInjectStyles.tsx +0 -0
- /package/src/{util → hooks}/useOutsideAlerter.tsx +0 -0
@@ -1,5 +1,7 @@
|
|
1
1
|
import * as React from "react";
|
2
|
-
import {
|
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
|
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
|
);
|
package/src/components/Label.tsx
CHANGED
@@ -1,15 +1,28 @@
|
|
1
1
|
import * as React from "react"
|
2
2
|
import * as LabelPrimitive from "@radix-ui/react-label"
|
3
|
-
import {
|
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
|
-
|
9
|
-
>(({
|
12
|
+
LabelProps
|
13
|
+
>(({
|
14
|
+
className,
|
15
|
+
border,
|
16
|
+
onClick,
|
17
|
+
...props
|
18
|
+
}, ref) => (
|
10
19
|
<LabelPrimitive.Root
|
11
20
|
ref={ref}
|
12
|
-
|
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
|
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
|
}
|
package/src/components/Menu.tsx
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import React from "react";
|
2
2
|
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
|
3
|
-
import {
|
4
|
-
import {
|
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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
</DropdownMenu.
|
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={
|
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,
|
9
|
-
import {
|
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={
|
115
|
+
className={cls("relative overflow-visible bg-transparent", containerClassName)}>
|
119
116
|
<div
|
120
117
|
ref={containerRef}
|
121
|
-
className={
|
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={
|
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={
|
144
|
+
className={cls("transition ", openInternal ? "rotate-180" : "")}/>
|
149
145
|
</div>
|
150
146
|
|
151
147
|
</div>
|
152
148
|
|
153
|
-
<Dialog.Root open={openInternal}
|
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={
|
210
|
+
className={cls(
|
213
211
|
(fieldValue ?? []).includes(value) ? "bg-slate-200 dark:bg-slate-950" : "",
|
214
212
|
"cursor-pointer",
|
215
213
|
"m-1",
|