@meta-1/design 0.0.199 → 0.0.201
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/package.json +3 -1
- package/src/assets/locales/en-us.ts +4 -0
- package/src/assets/locales/zh-cn.ts +4 -0
- package/src/assets/locales/zh-tw.ts +4 -0
- package/src/assets/style/theme.css +72 -21
- package/src/components/ui/button.tsx +28 -18
- package/src/components/uix/action/index.tsx +7 -5
- package/src/components/uix/action/style.css +21 -0
- package/src/components/uix/alert/index.tsx +5 -5
- package/src/components/uix/alert-dialog/index.tsx +56 -16
- package/src/components/uix/badge/index.tsx +8 -2
- package/src/components/uix/button/index.tsx +7 -5
- package/src/components/uix/card/index.tsx +7 -4
- package/src/components/uix/checkbox-group/index.tsx +3 -4
- package/src/components/uix/combo-select/index.tsx +99 -129
- package/src/components/uix/command/index.tsx +126 -0
- package/src/components/uix/data-grid/index.tsx +625 -0
- package/src/components/uix/data-grid/overlays.tsx +26 -0
- package/src/components/uix/data-grid/style.css +6 -0
- package/src/components/uix/data-table/index.tsx +10 -7
- package/src/components/uix/date-picker/index.tsx +55 -46
- package/src/components/uix/date-range-picker/index.tsx +116 -36
- package/src/components/uix/dialog/index.tsx +5 -5
- package/src/components/uix/dropdown/index.tsx +1 -1
- package/src/components/uix/input/index.tsx +23 -0
- package/src/components/uix/message/index.tsx +4 -4
- package/src/components/uix/pagination/index.tsx +17 -31
- package/src/components/uix/popover/index.tsx +30 -0
- package/src/components/uix/radio-group/index.tsx +2 -2
- package/src/components/uix/select/index.tsx +6 -2
- package/src/components/uix/sheet/index.tsx +76 -0
- package/src/components/uix/tabs/index.tsx +38 -0
- package/src/components/uix/tags-input/index.tsx +22 -3
- package/src/components/uix/textarea/index.tsx +23 -0
- package/src/components/uix/tooltip/index.tsx +5 -4
- package/src/components/uix/tree/style.css +1 -0
- package/src/components/uix/tree-select/index.tsx +59 -64
- package/src/components/uix/uploader/index.tsx +1 -1
- package/src/components/uix/value-formatter/index.tsx +40 -46
- package/src/index.ts +19 -36
- package/src/lib/utils.ts +50 -1
- package/src/components/uix/breadcrumbs/index.tsx +0 -38
- package/src/components/uix/space/index.tsx +0 -24
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
|
|
3
|
+
import { ScrollArea } from "@meta-1/design/components/ui/scroll-area";
|
|
4
|
+
import {
|
|
5
|
+
SheetClose,
|
|
6
|
+
SheetContent,
|
|
7
|
+
SheetDescription,
|
|
8
|
+
SheetFooter,
|
|
9
|
+
SheetHeader,
|
|
10
|
+
SheetTitle,
|
|
11
|
+
SheetTrigger,
|
|
12
|
+
Sheet as UISheet,
|
|
13
|
+
} from "@meta-1/design/components/ui/sheet";
|
|
14
|
+
import { cn } from "@meta-1/design/lib/utils";
|
|
15
|
+
|
|
16
|
+
export type SheetProps = {
|
|
17
|
+
open?: boolean;
|
|
18
|
+
onOpenChange?: (open: boolean) => void;
|
|
19
|
+
title?: React.ReactNode;
|
|
20
|
+
description?: React.ReactNode;
|
|
21
|
+
content?: React.ReactNode;
|
|
22
|
+
children?: React.ReactNode;
|
|
23
|
+
side?: "top" | "right" | "bottom" | "left";
|
|
24
|
+
className?: string;
|
|
25
|
+
closable?: boolean;
|
|
26
|
+
asChild?: boolean;
|
|
27
|
+
footer?: React.ReactNode;
|
|
28
|
+
maskClosable?: boolean;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const Sheet: FC<SheetProps> = (props) => {
|
|
32
|
+
const {
|
|
33
|
+
open,
|
|
34
|
+
onOpenChange,
|
|
35
|
+
title,
|
|
36
|
+
description,
|
|
37
|
+
content,
|
|
38
|
+
children,
|
|
39
|
+
side,
|
|
40
|
+
className,
|
|
41
|
+
closable,
|
|
42
|
+
asChild,
|
|
43
|
+
footer,
|
|
44
|
+
maskClosable = true,
|
|
45
|
+
} = props;
|
|
46
|
+
return (
|
|
47
|
+
<UISheet onOpenChange={onOpenChange} open={open}>
|
|
48
|
+
<SheetTrigger asChild={asChild}>{children}</SheetTrigger>
|
|
49
|
+
<SheetContent
|
|
50
|
+
className={cn(
|
|
51
|
+
"gap-sheet",
|
|
52
|
+
"[&>button:last-child]:flex [&>button:last-child]:items-center [&>button:last-child]:justify-center",
|
|
53
|
+
className,
|
|
54
|
+
closable === false && "[&>button:last-child]:hidden",
|
|
55
|
+
)}
|
|
56
|
+
onInteractOutside={(e) => {
|
|
57
|
+
if (!maskClosable) {
|
|
58
|
+
e.preventDefault();
|
|
59
|
+
}
|
|
60
|
+
}}
|
|
61
|
+
side={side}
|
|
62
|
+
>
|
|
63
|
+
<SheetHeader className={cn("p-sheet pb-0", !title && !description && "sr-only")}>
|
|
64
|
+
<SheetTitle className={cn(!title && "sr-only")}>{title || "Sheet"}</SheetTitle>
|
|
65
|
+
<SheetDescription className={cn(!description && "sr-only")}>
|
|
66
|
+
{description || "Sheet content"}
|
|
67
|
+
</SheetDescription>
|
|
68
|
+
</SheetHeader>
|
|
69
|
+
<ScrollArea className="flex-1">{content}</ScrollArea>
|
|
70
|
+
{footer != null && <SheetFooter className="p-sheet pt-0">{footer}</SheetFooter>}
|
|
71
|
+
</SheetContent>
|
|
72
|
+
</UISheet>
|
|
73
|
+
);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export { SheetClose };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
|
|
3
|
+
import { TabsContent, TabsList, TabsTrigger, Tabs as UITabs } from "../../ui/tabs";
|
|
4
|
+
|
|
5
|
+
export type TabsItem = {
|
|
6
|
+
label: string;
|
|
7
|
+
value: string;
|
|
8
|
+
content?: React.ReactNode;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type TabsProps = {
|
|
12
|
+
items: TabsItem[];
|
|
13
|
+
defaultValue?: string;
|
|
14
|
+
value?: string;
|
|
15
|
+
onChange?: (value: string) => void;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const Tabs: FC<TabsProps> = (props) => {
|
|
19
|
+
const { items, defaultValue, value, onChange } = props;
|
|
20
|
+
return (
|
|
21
|
+
<UITabs defaultValue={defaultValue} onValueChange={onChange} value={value}>
|
|
22
|
+
<TabsList className="h-tabs-title rounded-tabs-title">
|
|
23
|
+
{items.map((item) => (
|
|
24
|
+
<TabsTrigger className="rounded-tabs-title" key={item.value} value={item.value}>
|
|
25
|
+
{item.label}
|
|
26
|
+
</TabsTrigger>
|
|
27
|
+
))}
|
|
28
|
+
</TabsList>
|
|
29
|
+
{items.map((item) =>
|
|
30
|
+
item.content ? (
|
|
31
|
+
<TabsContent key={item.value} value={item.value}>
|
|
32
|
+
{item.content}
|
|
33
|
+
</TabsContent>
|
|
34
|
+
) : null,
|
|
35
|
+
)}
|
|
36
|
+
</UITabs>
|
|
37
|
+
);
|
|
38
|
+
};
|
|
@@ -17,6 +17,7 @@ export interface TagsInputProps {
|
|
|
17
17
|
separator?: string | RegExp;
|
|
18
18
|
validate?: (tag: string) => boolean;
|
|
19
19
|
disabled?: boolean;
|
|
20
|
+
allowClear?: boolean;
|
|
20
21
|
onTagAdd?: (tag: string) => void;
|
|
21
22
|
onTagRemove?: (tag: string) => void;
|
|
22
23
|
renderTag?: (tag: string, index: number, remove: () => void) => React.ReactNode;
|
|
@@ -37,6 +38,7 @@ export const TagsInput = forwardRef<HTMLDivElement, TagsInputProps>((props, ref)
|
|
|
37
38
|
separator = ",",
|
|
38
39
|
validate,
|
|
39
40
|
disabled = false,
|
|
41
|
+
allowClear = false,
|
|
40
42
|
onTagAdd,
|
|
41
43
|
onTagRemove,
|
|
42
44
|
renderTag,
|
|
@@ -147,10 +149,16 @@ export const TagsInput = forwardRef<HTMLDivElement, TagsInputProps>((props, ref)
|
|
|
147
149
|
inputRef.current?.focus();
|
|
148
150
|
};
|
|
149
151
|
|
|
152
|
+
const clearAll = (e: React.MouseEvent) => {
|
|
153
|
+
e.stopPropagation();
|
|
154
|
+
handleChange([]);
|
|
155
|
+
setInputValue("");
|
|
156
|
+
};
|
|
157
|
+
|
|
150
158
|
const defaultRenderTag = (tag: string, index: number, remove: () => void) => (
|
|
151
159
|
<div
|
|
152
160
|
className={cn(
|
|
153
|
-
"inline-flex items-center gap-
|
|
161
|
+
"inline-flex items-center gap-0.5 rounded-input bg-secondary px-1.5 py-0.5 text-xs transition-colors",
|
|
154
162
|
"hover:bg-secondary/80",
|
|
155
163
|
disabled && "pointer-events-none opacity-50",
|
|
156
164
|
tagClassName,
|
|
@@ -167,7 +175,7 @@ export const TagsInput = forwardRef<HTMLDivElement, TagsInputProps>((props, ref)
|
|
|
167
175
|
}}
|
|
168
176
|
type="button"
|
|
169
177
|
>
|
|
170
|
-
<XIcon className="
|
|
178
|
+
<XIcon className="size-4" />
|
|
171
179
|
</button>
|
|
172
180
|
)}
|
|
173
181
|
</div>
|
|
@@ -176,7 +184,8 @@ export const TagsInput = forwardRef<HTMLDivElement, TagsInputProps>((props, ref)
|
|
|
176
184
|
return (
|
|
177
185
|
<div
|
|
178
186
|
className={cn(
|
|
179
|
-
"flex min-h-
|
|
187
|
+
"group relative flex min-h-input w-full flex-wrap gap-0.5 rounded-input border border-input bg-transparent py-0.5 text-sm shadow-xs transition-[color,box-shadow]",
|
|
188
|
+
currentTags.length > 0 ? "px-0.5" : "px-input",
|
|
180
189
|
"focus-within:border-ring focus-within:ring-[3px] focus-within:ring-ring/50",
|
|
181
190
|
disabled && "pointer-events-none cursor-not-allowed opacity-50",
|
|
182
191
|
"dark:bg-input/30",
|
|
@@ -195,6 +204,7 @@ export const TagsInput = forwardRef<HTMLDivElement, TagsInputProps>((props, ref)
|
|
|
195
204
|
className={cn(
|
|
196
205
|
"min-w-[120px] flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground",
|
|
197
206
|
"disabled:pointer-events-none disabled:cursor-not-allowed",
|
|
207
|
+
allowClear && currentTags.length > 0 && "pr-6",
|
|
198
208
|
inputClassName,
|
|
199
209
|
)}
|
|
200
210
|
disabled={disabled || (maxTags !== undefined && currentTags.length >= maxTags)}
|
|
@@ -208,6 +218,15 @@ export const TagsInput = forwardRef<HTMLDivElement, TagsInputProps>((props, ref)
|
|
|
208
218
|
type="text"
|
|
209
219
|
value={inputValue}
|
|
210
220
|
/>
|
|
221
|
+
|
|
222
|
+
{allowClear && currentTags.length > 0 && !disabled && (
|
|
223
|
+
<div
|
|
224
|
+
className="absolute top-0 right-0 z-10 hidden h-full cursor-pointer items-center justify-center px-2 group-hover:flex"
|
|
225
|
+
onClick={clearAll}
|
|
226
|
+
>
|
|
227
|
+
<XIcon className="size-4 opacity-50" />
|
|
228
|
+
</div>
|
|
229
|
+
)}
|
|
211
230
|
</div>
|
|
212
231
|
);
|
|
213
232
|
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
|
|
3
|
+
import { Textarea as UITextarea } from "@meta-1/design/components/ui/textarea";
|
|
4
|
+
import { cn } from "@meta-1/design/lib/utils";
|
|
5
|
+
|
|
6
|
+
export interface TextareaProps extends Omit<React.ComponentProps<"textarea">, "onChange"> {
|
|
7
|
+
className?: string;
|
|
8
|
+
onChange?: (value: string) => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>((props, forwardedRef) => {
|
|
12
|
+
const { className, onChange, ...rest } = props;
|
|
13
|
+
const elementRef = forwardedRef;
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<UITextarea
|
|
17
|
+
className={cn("rounded-input p-input", className)}
|
|
18
|
+
onChange={(e) => onChange?.(e.target.value)}
|
|
19
|
+
{...rest}
|
|
20
|
+
ref={elementRef}
|
|
21
|
+
/>
|
|
22
|
+
);
|
|
23
|
+
});
|
|
@@ -4,8 +4,9 @@ import {
|
|
|
4
4
|
TooltipContent,
|
|
5
5
|
TooltipProvider,
|
|
6
6
|
TooltipTrigger,
|
|
7
|
-
Tooltip as
|
|
7
|
+
Tooltip as UITooltip,
|
|
8
8
|
} from "@meta-1/design/components/ui/tooltip";
|
|
9
|
+
import { cn } from "@meta-1/design/lib/utils";
|
|
9
10
|
|
|
10
11
|
type Side = "top" | "right" | "bottom" | "left";
|
|
11
12
|
|
|
@@ -21,12 +22,12 @@ export const Tooltip: FC<TooltipProps> = (props) => {
|
|
|
21
22
|
const { open, onOpenChange, className } = props;
|
|
22
23
|
return (
|
|
23
24
|
<TooltipProvider>
|
|
24
|
-
<
|
|
25
|
+
<UITooltip onOpenChange={onOpenChange} open={open}>
|
|
25
26
|
<TooltipTrigger asChild={true}>{props.children}</TooltipTrigger>
|
|
26
|
-
<TooltipContent className={className} side={props.side}>
|
|
27
|
+
<TooltipContent className={cn("rounded-tooltip p-tooltip", className)} side={props.side}>
|
|
27
28
|
{props.content}
|
|
28
29
|
</TooltipContent>
|
|
29
|
-
</
|
|
30
|
+
</UITooltip>
|
|
30
31
|
</TooltipProvider>
|
|
31
32
|
);
|
|
32
33
|
};
|
|
@@ -2,19 +2,7 @@ import { type FC, type ReactNode, useEffect, useMemo, useRef, useState } from "r
|
|
|
2
2
|
import { CaretSortIcon, Cross2Icon } from "@radix-ui/react-icons";
|
|
3
3
|
import classNames from "classnames";
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
cn,
|
|
7
|
-
Empty,
|
|
8
|
-
type EmptyProps,
|
|
9
|
-
Popover,
|
|
10
|
-
PopoverContent,
|
|
11
|
-
PopoverTrigger,
|
|
12
|
-
ScrollArea,
|
|
13
|
-
Spin,
|
|
14
|
-
Tree,
|
|
15
|
-
type TreeData,
|
|
16
|
-
useSize,
|
|
17
|
-
} from "@meta-1/design";
|
|
5
|
+
import { cn, Empty, type EmptyProps, Popover, ScrollArea, Spin, Tree, type TreeData, useSize } from "@meta-1/design";
|
|
18
6
|
import { Button } from "@meta-1/design/components/ui/button";
|
|
19
7
|
|
|
20
8
|
export type TreeSelectProps = {
|
|
@@ -80,60 +68,67 @@ export const TreeSelect: FC<TreeSelectProps> = (props) => {
|
|
|
80
68
|
}
|
|
81
69
|
}, [value]);
|
|
82
70
|
|
|
71
|
+
const content = (
|
|
72
|
+
<ScrollArea className={classNames("flex max-h-[30vh] flex-col", contentClassName)}>
|
|
73
|
+
{treeData?.length ? (
|
|
74
|
+
<Tree
|
|
75
|
+
expandedKeys={expandedKeys}
|
|
76
|
+
onExpand={(expandedKeys) => setExpandedKeys(expandedKeys as string[])}
|
|
77
|
+
onSelect={(selectedKeys, { selected }) => {
|
|
78
|
+
if (selected) {
|
|
79
|
+
onChange?.(selectedKeys[0] as string);
|
|
80
|
+
setSelectedKeys(selectedKeys as string[]);
|
|
81
|
+
}
|
|
82
|
+
setOpen(false);
|
|
83
|
+
}}
|
|
84
|
+
selectedKeys={selectedKeys}
|
|
85
|
+
treeData={treeData}
|
|
86
|
+
/>
|
|
87
|
+
) : (
|
|
88
|
+
<Empty {...(emptyProps ?? {})} />
|
|
89
|
+
)}
|
|
90
|
+
</ScrollArea>
|
|
91
|
+
);
|
|
92
|
+
|
|
83
93
|
return (
|
|
84
|
-
<Popover
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
onChange?.(undefined);
|
|
108
|
-
e.stopPropagation();
|
|
109
|
-
}}
|
|
110
|
-
/>
|
|
111
|
-
</div>
|
|
112
|
-
)}
|
|
113
|
-
</div>
|
|
114
|
-
</Button>
|
|
115
|
-
</PopoverTrigger>
|
|
116
|
-
<PopoverContent className="p-0" style={{ width: size.width }}>
|
|
117
|
-
<ScrollArea className={classNames("flex max-h-[30vh] flex-col", contentClassName)}>
|
|
118
|
-
{treeData?.length ? (
|
|
119
|
-
<Tree
|
|
120
|
-
expandedKeys={expandedKeys}
|
|
121
|
-
onExpand={(expandedKeys) => setExpandedKeys(expandedKeys as string[])}
|
|
122
|
-
onSelect={(selectedKeys, { selected }) => {
|
|
123
|
-
if (selected) {
|
|
124
|
-
onChange?.(selectedKeys[0] as string);
|
|
125
|
-
setSelectedKeys(selectedKeys as string[]);
|
|
126
|
-
}
|
|
127
|
-
setOpen(false);
|
|
128
|
-
}}
|
|
129
|
-
selectedKeys={selectedKeys}
|
|
130
|
-
treeData={treeData}
|
|
131
|
-
/>
|
|
94
|
+
<Popover
|
|
95
|
+
asChild
|
|
96
|
+
className="p-0"
|
|
97
|
+
content={content}
|
|
98
|
+
disabled={loading || disabled}
|
|
99
|
+
onOpenChange={setOpen}
|
|
100
|
+
open={open}
|
|
101
|
+
style={{ width: size.width }}
|
|
102
|
+
>
|
|
103
|
+
<Button
|
|
104
|
+
aria-expanded={open}
|
|
105
|
+
className={cn(
|
|
106
|
+
"group h-9 min-w-[150px] items-center justify-between px-2 py-1 align-middle hover:bg-secondary/40",
|
|
107
|
+
className,
|
|
108
|
+
)}
|
|
109
|
+
disabled={loading || disabled}
|
|
110
|
+
ref={containerRef}
|
|
111
|
+
variant="outline"
|
|
112
|
+
>
|
|
113
|
+
<div className="flex flex-1 items-center justify-center">
|
|
114
|
+
<div className="flex flex-1">{showValue}</div>
|
|
115
|
+
{loading ? (
|
|
116
|
+
<Spin />
|
|
132
117
|
) : (
|
|
133
|
-
<
|
|
118
|
+
<div className="flex items-center">
|
|
119
|
+
<CaretSortIcon className={cn("block h-4 w-4", showClear ? "group-hover:hidden" : "")} />
|
|
120
|
+
<Cross2Icon
|
|
121
|
+
className={cn("hidden h-4 w-4", showClear ? "group-hover:block" : "")}
|
|
122
|
+
onClick={(e) => {
|
|
123
|
+
setSelectedKeys([]);
|
|
124
|
+
onChange?.(undefined);
|
|
125
|
+
e.stopPropagation();
|
|
126
|
+
}}
|
|
127
|
+
/>
|
|
128
|
+
</div>
|
|
134
129
|
)}
|
|
135
|
-
</
|
|
136
|
-
</
|
|
130
|
+
</div>
|
|
131
|
+
</Button>
|
|
137
132
|
</Popover>
|
|
138
133
|
);
|
|
139
134
|
};
|
|
@@ -222,7 +222,7 @@ export const Uploader = forwardRef<HTMLDivElement, UploaderProps>((props, forwar
|
|
|
222
222
|
<div
|
|
223
223
|
className={cn(
|
|
224
224
|
"flex items-center justify-center p-6 text-card-foreground/50",
|
|
225
|
-
"rounded-
|
|
225
|
+
"rounded-input border-2 border-border border-dashed bg-card",
|
|
226
226
|
"cursor-default",
|
|
227
227
|
"focus:border-primary",
|
|
228
228
|
isMaxFilesReached && "cursor-not-allowed opacity-50",
|
|
@@ -1,59 +1,53 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { forwardRef, type PropsWithChildren } from "react";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// biome-ignore lint/suspicious/noExplicitAny: <formatter functions can accept any value type>
|
|
4
|
+
export type Formatter = (value: any) => any;
|
|
5
|
+
export type Formatters = Formatter[];
|
|
4
6
|
|
|
5
|
-
// biome-ignore lint/suspicious/noExplicitAny: <
|
|
6
|
-
export
|
|
7
|
-
// biome-ignore lint/suspicious/noExplicitAny: <functionMap>
|
|
8
|
-
export type FunctionMap = Record<string, (value: any, ...args: any[]) => any>;
|
|
9
|
-
|
|
10
|
-
const _handles: FunctionMap = {};
|
|
11
|
-
|
|
12
|
-
export const register = (handles: FunctionMap) => {
|
|
13
|
-
Object.assign(_handles, handles);
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
// biome-ignore lint/suspicious/noExplicitAny: <v>
|
|
17
|
-
export const formatValue = (v: any, formatters: Formatters, all?: FunctionMap) => {
|
|
18
|
-
// biome-ignore lint/suspicious/noExplicitAny: <merged>
|
|
19
|
-
const merged: any = { ...BUILT_IN, ..._handles, ...(all ?? {}) };
|
|
20
|
-
// biome-ignore lint/suspicious/noExplicitAny: <fallback>
|
|
21
|
-
const fallback = (v: any, ..._p: any[]) => v;
|
|
22
|
-
// biome-ignore lint/suspicious/noExplicitAny: <params>
|
|
23
|
-
let params: any[] = [];
|
|
7
|
+
// biome-ignore lint/suspicious/noExplicitAny: <formatter functions can accept any value type>
|
|
8
|
+
export const formatValue = (v: any, formatters: Formatters) => {
|
|
24
9
|
let result = v;
|
|
25
10
|
|
|
26
|
-
for (const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
call = merged[filter[0]] || fallback;
|
|
34
|
-
params = filter[1];
|
|
35
|
-
}
|
|
36
|
-
try {
|
|
37
|
-
result = call(result, ...params);
|
|
38
|
-
} catch {
|
|
39
|
-
console.log("formatter error", filter);
|
|
11
|
+
for (const formatter of formatters) {
|
|
12
|
+
if (typeof formatter === "function") {
|
|
13
|
+
try {
|
|
14
|
+
result = formatter(result);
|
|
15
|
+
} catch (error) {
|
|
16
|
+
console.warn("Formatter error:", error);
|
|
17
|
+
}
|
|
40
18
|
}
|
|
41
19
|
}
|
|
42
20
|
return result;
|
|
43
21
|
};
|
|
44
22
|
|
|
45
23
|
export interface ValueFormatterProps extends PropsWithChildren {
|
|
46
|
-
// biome-ignore lint/suspicious/noExplicitAny: <value>
|
|
24
|
+
// biome-ignore lint/suspicious/noExplicitAny: <formatters chain can transform value to any type>
|
|
47
25
|
value?: any;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
26
|
+
formatters?: Formatters;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function ValueFormatterInner(props: ValueFormatterProps, _ref: React.ForwardedRef<never>) {
|
|
30
|
+
const { formatters = [], value, children } = props;
|
|
31
|
+
const v = value === 0 ? value : value || children;
|
|
32
|
+
const formatted = formatValue(v, formatters);
|
|
33
|
+
return <>{formatted}</>;
|
|
51
34
|
}
|
|
52
35
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
36
|
+
ValueFormatterInner.displayName = "ValueFormatter";
|
|
37
|
+
|
|
38
|
+
export const ValueFormatter = forwardRef(ValueFormatterInner);
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* 类型辅助函数,用于为 formatters 提供类型信息
|
|
42
|
+
* 使用示例:
|
|
43
|
+
* ```tsx
|
|
44
|
+
* const formatters = createFormatters<string[]>([
|
|
45
|
+
* (v) => v.join("|"),
|
|
46
|
+
* (v) => v.toUpperCase(),
|
|
47
|
+
* ]);
|
|
48
|
+
* <ValueFormatter value={["a", "b"]} formatters={formatters} />
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export function createFormatters<TInput = any>(formatters: Array<(value: TInput) => any>): Formatters {
|
|
52
|
+
return formatters as Formatters;
|
|
53
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -17,16 +17,6 @@ export {
|
|
|
17
17
|
BreadcrumbSeparator,
|
|
18
18
|
} from "./components/ui/breadcrumb";
|
|
19
19
|
export { Calendar } from "./components/ui/calendar";
|
|
20
|
-
export {
|
|
21
|
-
Command,
|
|
22
|
-
CommandEmpty,
|
|
23
|
-
CommandGroup,
|
|
24
|
-
CommandInput,
|
|
25
|
-
CommandItem,
|
|
26
|
-
CommandList,
|
|
27
|
-
CommandSeparator,
|
|
28
|
-
CommandShortcut,
|
|
29
|
-
} from "./components/ui/command";
|
|
30
20
|
export {
|
|
31
21
|
ContextMenu,
|
|
32
22
|
ContextMenuCheckboxItem,
|
|
@@ -44,19 +34,12 @@ export {
|
|
|
44
34
|
ContextMenuSubTrigger,
|
|
45
35
|
ContextMenuTrigger,
|
|
46
36
|
} from "./components/ui/context-menu";
|
|
47
|
-
export * from "./components/ui/dropdown-menu";
|
|
48
37
|
export {
|
|
49
38
|
HoverCard,
|
|
50
39
|
HoverCardContent,
|
|
51
40
|
HoverCardTrigger,
|
|
52
41
|
} from "./components/ui/hover-card";
|
|
53
|
-
export { Input } from "./components/ui/input";
|
|
54
42
|
export * from "./components/ui/navigation-menu";
|
|
55
|
-
export {
|
|
56
|
-
Popover,
|
|
57
|
-
PopoverContent,
|
|
58
|
-
PopoverTrigger,
|
|
59
|
-
} from "./components/ui/popover";
|
|
60
43
|
export { Progress } from "./components/ui/progress";
|
|
61
44
|
export {
|
|
62
45
|
ResizableHandle,
|
|
@@ -65,16 +48,6 @@ export {
|
|
|
65
48
|
} from "./components/ui/resizable";
|
|
66
49
|
export { ScrollArea, ScrollBar } from "./components/ui/scroll-area";
|
|
67
50
|
export { Separator } from "./components/ui/separator";
|
|
68
|
-
export {
|
|
69
|
-
Sheet,
|
|
70
|
-
SheetClose,
|
|
71
|
-
SheetContent,
|
|
72
|
-
SheetDescription,
|
|
73
|
-
SheetFooter,
|
|
74
|
-
SheetHeader,
|
|
75
|
-
SheetTitle,
|
|
76
|
-
SheetTrigger,
|
|
77
|
-
} from "./components/ui/sheet";
|
|
78
51
|
export { Skeleton } from "./components/ui/skeleton";
|
|
79
52
|
export { Slider } from "./components/ui/slider";
|
|
80
53
|
// base
|
|
@@ -89,21 +62,17 @@ export {
|
|
|
89
62
|
TableHeader,
|
|
90
63
|
TableRow,
|
|
91
64
|
} from "./components/ui/table";
|
|
92
|
-
export { Tabs, TabsContent, TabsList, TabsTrigger } from "./components/ui/tabs";
|
|
93
|
-
export { Textarea } from "./components/ui/textarea";
|
|
94
65
|
// advanced components
|
|
95
66
|
export type { ActionProps } from "./components/uix/action";
|
|
96
67
|
export { Action } from "./components/uix/action";
|
|
97
68
|
export type { AlertProps } from "./components/uix/alert";
|
|
98
69
|
export { Alert } from "./components/uix/alert";
|
|
99
|
-
export type { ConfirmProps } from "./components/uix/alert-dialog";
|
|
70
|
+
export type { AlertDialogProps, ConfirmProps } from "./components/uix/alert-dialog";
|
|
100
71
|
export { useAlert } from "./components/uix/alert-dialog";
|
|
101
72
|
export type { AvatarProps } from "./components/uix/avatar";
|
|
102
73
|
export { Avatar } from "./components/uix/avatar";
|
|
103
74
|
export type { BadgeProps, BadgeVariant } from "./components/uix/badge";
|
|
104
75
|
export { Badge } from "./components/uix/badge";
|
|
105
|
-
export type { BreadcrumbsItemProps, BreadcrumbsProps } from "./components/uix/breadcrumbs";
|
|
106
|
-
export { Breadcrumbs, BreadcrumbsItem } from "./components/uix/breadcrumbs";
|
|
107
76
|
export type { BroadcastChannelProviderProps } from "./components/uix/broadcast-channel-context";
|
|
108
77
|
export { BroadcastChannelProvider, useBroadcastChannel } from "./components/uix/broadcast-channel-context";
|
|
109
78
|
export type { ButtonProps } from "./components/uix/button";
|
|
@@ -116,13 +85,17 @@ export type { CheckboxGroupOptionProps, CheckboxGroupProps } from "./components/
|
|
|
116
85
|
export { CheckboxGroup } from "./components/uix/checkbox-group";
|
|
117
86
|
export type { ComboSelectOptionProps, ComboSelectProps, ComboSelectValueType } from "./components/uix/combo-select";
|
|
118
87
|
export { ComboSelect } from "./components/uix/combo-select";
|
|
88
|
+
export type { CommandItemProps, CommandProps } from "./components/uix/command";
|
|
89
|
+
export { Command } from "./components/uix/command";
|
|
119
90
|
export type { ConfigProviderProps } from "./components/uix/config-provider";
|
|
120
91
|
export { ConfigProvider } from "./components/uix/config-provider";
|
|
92
|
+
export type { DataGridColumn, DataGridProps, StickyColumnProps } from "./components/uix/data-grid";
|
|
93
|
+
export { DataGrid } from "./components/uix/data-grid";
|
|
121
94
|
export type { DataTableColumn, DataTableProps } from "./components/uix/data-table";
|
|
122
95
|
export { DataTable } from "./components/uix/data-table";
|
|
123
96
|
export type { DatePickerProps } from "./components/uix/date-picker";
|
|
124
97
|
export { DatePicker } from "./components/uix/date-picker";
|
|
125
|
-
export type { DateRangePickerProps } from "./components/uix/date-range-picker";
|
|
98
|
+
export type { DateRange, DateRangePickerProps } from "./components/uix/date-range-picker";
|
|
126
99
|
export { DateRangePicker } from "./components/uix/date-range-picker";
|
|
127
100
|
export type { DialogProps } from "./components/uix/dialog";
|
|
128
101
|
export { Dialog } from "./components/uix/dialog";
|
|
@@ -138,26 +111,36 @@ export type { FieldItem, FormInstance, FormProps, RenderProps } from "./componen
|
|
|
138
111
|
export { Form, FormItem } from "./components/uix/form";
|
|
139
112
|
export type { ImageProps } from "./components/uix/image";
|
|
140
113
|
export { Image } from "./components/uix/image";
|
|
114
|
+
export { Input } from "./components/uix/input";
|
|
141
115
|
export type { LoadingProps } from "./components/uix/loading";
|
|
142
116
|
export { Loading } from "./components/uix/loading";
|
|
143
117
|
export { useMessage } from "./components/uix/message";
|
|
144
118
|
export type { PaginationProps } from "./components/uix/pagination";
|
|
145
119
|
export { Pagination } from "./components/uix/pagination";
|
|
120
|
+
export type { PopoverProps } from "./components/uix/popover";
|
|
121
|
+
export { Popover } from "./components/uix/popover";
|
|
146
122
|
export type { RadioGroupOptionProps, RadioGroupProps } from "./components/uix/radio-group";
|
|
147
123
|
export { RadioGroup } from "./components/uix/radio-group";
|
|
148
124
|
export type { ResultProps } from "./components/uix/result";
|
|
149
125
|
export { Result } from "./components/uix/result";
|
|
150
126
|
export type { SelectOptionProps, SelectProps } from "./components/uix/select";
|
|
151
127
|
export { Select } from "./components/uix/select";
|
|
152
|
-
export {
|
|
128
|
+
export type { SheetProps } from "./components/uix/sheet";
|
|
129
|
+
export {
|
|
130
|
+
Sheet,
|
|
131
|
+
SheetClose,
|
|
132
|
+
} from "./components/uix/sheet";
|
|
153
133
|
export type { SpinProps } from "./components/uix/spin";
|
|
154
134
|
export { Spin } from "./components/uix/spin";
|
|
155
135
|
export type { StepsItemProps, StepsProps } from "./components/uix/steps";
|
|
156
136
|
export { Steps, StepsItem } from "./components/uix/steps";
|
|
157
137
|
export type { SwitchProps } from "./components/uix/switch";
|
|
158
138
|
export { Switch } from "./components/uix/switch";
|
|
139
|
+
export type { TabsItem, TabsProps } from "./components/uix/tabs";
|
|
140
|
+
export { Tabs } from "./components/uix/tabs";
|
|
159
141
|
export type { TagsInputProps } from "./components/uix/tags-input";
|
|
160
142
|
export { TagsInput } from "./components/uix/tags-input";
|
|
143
|
+
export { Textarea } from "./components/uix/textarea";
|
|
161
144
|
export type { TooltipProps } from "./components/uix/tooltip";
|
|
162
145
|
export { Tooltip } from "./components/uix/tooltip";
|
|
163
146
|
export type { TreeData, TreeProps } from "./components/uix/tree";
|
|
@@ -169,8 +152,8 @@ export { TreeTable } from "./components/uix/tree-table";
|
|
|
169
152
|
export type { UploaderProps } from "./components/uix/uploader";
|
|
170
153
|
export { Uploader } from "./components/uix/uploader";
|
|
171
154
|
export type { HandleProps, UploadFile } from "./components/uix/uploader/type";
|
|
172
|
-
export type { ValueFormatterProps } from "./components/uix/value-formatter";
|
|
173
|
-
export {
|
|
155
|
+
export type { Formatters, ValueFormatterProps } from "./components/uix/value-formatter";
|
|
156
|
+
export { createFormatters, ValueFormatter } from "./components/uix/value-formatter";
|
|
174
157
|
// custom hooks
|
|
175
158
|
export * from "./hooks";
|
|
176
159
|
// utils
|