@teamix-evo/ui 0.1.1 → 0.3.0
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 +184 -184
- package/manifest.json +680 -492
- package/package.json +20 -10
- package/src/components/accordion/accordion.meta.md +5 -4
- package/src/components/accordion/accordion.stories.tsx +14 -9
- package/src/components/accordion/accordion.tsx +104 -8
- package/src/components/affix/affix.meta.md +20 -2
- package/src/components/affix/affix.stories.tsx +102 -25
- package/src/components/affix/affix.tsx +79 -9
- package/src/components/alert/alert.meta.md +44 -13
- package/src/components/alert/alert.stories.tsx +66 -21
- package/src/components/alert/alert.tsx +81 -34
- package/src/components/alert-dialog/alert-dialog.meta.md +61 -16
- package/src/components/alert-dialog/alert-dialog.stories.tsx +145 -3
- package/src/components/alert-dialog/alert-dialog.tsx +60 -13
- package/src/components/anchor/anchor.meta.md +8 -3
- package/src/components/anchor/anchor.stories.tsx +3 -3
- package/src/components/anchor/anchor.tsx +2 -2
- package/src/components/app/app.meta.md +9 -4
- package/src/components/app/app.stories.tsx +9 -7
- package/src/components/aspect-ratio/aspect-ratio.meta.md +4 -3
- package/src/components/aspect-ratio/aspect-ratio.stories.tsx +3 -3
- package/src/components/auto-complete/auto-complete.meta.md +14 -6
- package/src/components/auto-complete/auto-complete.stories.tsx +47 -4
- package/src/components/auto-complete/auto-complete.tsx +119 -71
- package/src/components/avatar/avatar.meta.md +6 -7
- package/src/components/avatar/avatar.stories.tsx +21 -3
- package/src/components/avatar/avatar.tsx +24 -23
- package/src/components/badge/badge.meta.md +10 -9
- package/src/components/badge/badge.stories.tsx +2 -2
- package/src/components/badge/badge.tsx +9 -15
- package/src/components/breadcrumb/breadcrumb.meta.md +27 -7
- package/src/components/breadcrumb/breadcrumb.stories.tsx +127 -4
- package/src/components/breadcrumb/breadcrumb.tsx +22 -8
- package/src/components/button/button.meta.md +258 -21
- package/src/components/button/button.stories.tsx +549 -41
- package/src/components/button/button.tsx +335 -33
- package/src/components/button/demo/as-child.tsx +24 -0
- package/src/components/button/demo/basic.tsx +8 -0
- package/src/components/button/demo/block.tsx +16 -0
- package/src/components/button/demo/loading.tsx +19 -0
- package/src/components/button/demo/shapes.tsx +18 -0
- package/src/components/button/demo/sizes.tsx +19 -0
- package/src/components/button/demo/variants.tsx +19 -0
- package/src/components/button/demo/with-icon.tsx +20 -0
- package/src/components/calendar/calendar.meta.md +13 -3
- package/src/components/calendar/calendar.stories.tsx +6 -6
- package/src/components/calendar/calendar.tsx +73 -8
- package/src/components/card/card.meta.md +27 -5
- package/src/components/card/card.stories.tsx +42 -3
- package/src/components/card/card.tsx +146 -63
- package/src/components/carousel/carousel.meta.md +4 -3
- package/src/components/carousel/carousel.stories.tsx +11 -6
- package/src/components/cascader/cascader.meta.md +47 -17
- package/src/components/cascader/cascader.stories.tsx +22 -10
- package/src/components/cascader/cascader.tsx +428 -85
- package/src/components/checkbox/checkbox.meta.md +75 -7
- package/src/components/checkbox/checkbox.stories.tsx +161 -3
- package/src/components/checkbox/checkbox.tsx +77 -9
- package/src/components/collapsible/collapsible.meta.md +14 -6
- package/src/components/collapsible/collapsible.stories.tsx +10 -2
- package/src/components/collapsible/collapsible.tsx +93 -6
- package/src/components/color-picker/color-picker.meta.md +12 -7
- package/src/components/color-picker/color-picker.stories.tsx +86 -7
- package/src/components/color-picker/color-picker.tsx +20 -9
- package/src/components/command/command.meta.md +29 -13
- package/src/components/command/command.stories.tsx +4 -4
- package/src/components/command/command.tsx +19 -8
- package/src/components/context-menu/context-menu.meta.md +11 -8
- package/src/components/context-menu/context-menu.stories.tsx +11 -3
- package/src/components/context-menu/context-menu.tsx +21 -8
- package/src/components/data-table/data-table.meta.md +6 -5
- package/src/components/data-table/data-table.stories.tsx +13 -6
- package/src/components/data-table/data-table.tsx +2 -2
- package/src/components/date-picker/date-picker.meta.md +88 -19
- package/src/components/date-picker/date-picker.stories.tsx +55 -5
- package/src/components/date-picker/date-picker.tsx +1489 -91
- package/src/components/descriptions/descriptions.meta.md +10 -5
- package/src/components/descriptions/descriptions.stories.tsx +3 -3
- package/src/components/descriptions/descriptions.tsx +22 -14
- package/src/components/dialog/dialog.meta.md +76 -13
- package/src/components/dialog/dialog.stories.tsx +182 -20
- package/src/components/dialog/dialog.tsx +67 -15
- package/src/components/dialog/imperative.tsx +252 -0
- package/src/components/drawer/drawer.meta.md +33 -34
- package/src/components/drawer/drawer.stories.tsx +29 -12
- package/src/components/drawer/drawer.tsx +22 -113
- package/src/components/dropdown-menu/dropdown-menu.meta.md +78 -10
- package/src/components/dropdown-menu/dropdown-menu.stories.tsx +88 -2
- package/src/components/dropdown-menu/dropdown-menu.tsx +24 -10
- package/src/components/ellipsis/ellipsis.meta.md +87 -0
- package/src/components/ellipsis/ellipsis.stories.tsx +72 -0
- package/src/components/ellipsis/ellipsis.tsx +153 -0
- package/src/components/empty/empty.meta.md +9 -4
- package/src/components/empty/empty.stories.tsx +4 -4
- package/src/components/empty/empty.tsx +10 -3
- package/src/components/field/field.meta.md +47 -9
- package/src/components/field/field.stories.tsx +385 -5
- package/src/components/field/field.tsx +263 -35
- package/src/components/filter-bar/filter-bar.meta.md +92 -0
- package/src/components/filter-bar/filter-bar.stories.tsx +1083 -0
- package/src/components/filter-bar/filter-bar.tsx +568 -0
- package/src/components/flex/flex.meta.md +54 -6
- package/src/components/flex/flex.stories.tsx +107 -20
- package/src/components/flex/flex.tsx +27 -4
- package/src/components/float-button/float-button.meta.md +8 -3
- package/src/components/float-button/float-button.stories.tsx +9 -7
- package/src/components/float-button/float-button.tsx +1 -1
- package/src/components/form/form.meta.md +39 -17
- package/src/components/form/form.stories.tsx +350 -3
- package/src/components/form/form.tsx +101 -35
- package/src/components/grid/grid.meta.md +7 -2
- package/src/components/grid/grid.stories.tsx +6 -4
- package/src/components/hover-card/hover-card.meta.md +20 -9
- package/src/components/hover-card/hover-card.stories.tsx +34 -5
- package/src/components/hover-card/hover-card.tsx +51 -13
- package/src/components/icon/DEVELOPMENT.md +809 -0
- package/src/components/icon/icon.meta.md +170 -0
- package/src/components/icon/icon.stories.tsx +344 -0
- package/src/components/icon/icon.tsx +248 -0
- package/src/components/image/image.meta.md +9 -4
- package/src/components/image/image.stories.tsx +3 -3
- package/src/components/image/image.tsx +6 -4
- package/src/components/input/demo/basic.tsx +12 -0
- package/src/components/input/demo/clearable.tsx +21 -0
- package/src/components/input/demo/show-count.tsx +18 -0
- package/src/components/input/demo/sizes.tsx +15 -0
- package/src/components/input/input.meta.md +39 -33
- package/src/components/input/input.stories.tsx +62 -35
- package/src/components/input/input.tsx +97 -98
- package/src/components/input-group/input-group.meta.md +54 -22
- package/src/components/input-group/input-group.stories.tsx +49 -16
- package/src/components/input-group/input-group.tsx +44 -8
- package/src/components/input-number/input-number.meta.md +64 -7
- package/src/components/input-number/input-number.stories.tsx +46 -8
- package/src/components/input-number/input-number.tsx +99 -26
- package/src/components/input-otp/input-otp.meta.md +4 -3
- package/src/components/input-otp/input-otp.stories.tsx +3 -3
- package/src/components/input-otp/input-otp.tsx +1 -1
- package/src/components/item/item.meta.md +8 -3
- package/src/components/item/item.stories.tsx +8 -5
- package/src/components/item/item.tsx +7 -6
- package/src/components/kbd/kbd.meta.md +13 -4
- package/src/components/kbd/kbd.stories.tsx +4 -4
- package/src/components/kbd/kbd.tsx +10 -5
- package/src/components/label/label.meta.md +18 -10
- package/src/components/label/label.stories.tsx +64 -6
- package/src/components/label/label.tsx +91 -19
- package/src/components/masonry/masonry.meta.md +8 -3
- package/src/components/masonry/masonry.stories.tsx +7 -5
- package/src/components/masonry/masonry.tsx +1 -0
- package/src/components/mentions/mentions.meta.md +36 -6
- package/src/components/mentions/mentions.stories.tsx +120 -6
- package/src/components/mentions/mentions.tsx +11 -5
- package/src/components/menubar/menubar.meta.md +30 -12
- package/src/components/menubar/menubar.stories.tsx +62 -2
- package/src/components/menubar/menubar.tsx +9 -9
- package/src/components/native-select/native-select.meta.md +8 -3
- package/src/components/native-select/native-select.stories.tsx +8 -5
- package/src/components/native-select/native-select.tsx +1 -1
- package/src/components/navigation-menu/navigation-menu.meta.md +19 -9
- package/src/components/navigation-menu/navigation-menu.stories.tsx +112 -9
- package/src/components/navigation-menu/navigation-menu.tsx +8 -4
- package/src/components/notification/notification.meta.md +52 -10
- package/src/components/notification/notification.stories.tsx +11 -9
- package/src/components/notification/notification.tsx +36 -21
- package/src/components/page-header/DEVELOPMENT.md +842 -0
- package/src/components/page-header/page-header.meta.md +208 -0
- package/src/components/page-header/page-header.stories.tsx +421 -0
- package/src/components/page-header/page-header.tsx +281 -0
- package/src/components/pagination/pagination.meta.md +140 -37
- package/src/components/pagination/pagination.stories.tsx +232 -10
- package/src/components/pagination/pagination.tsx +355 -63
- package/src/components/popconfirm/popconfirm.meta.md +9 -4
- package/src/components/popconfirm/popconfirm.stories.tsx +3 -4
- package/src/components/popconfirm/popconfirm.tsx +2 -2
- package/src/components/popover/popover.meta.md +62 -5
- package/src/components/popover/popover.stories.tsx +83 -7
- package/src/components/popover/popover.tsx +77 -28
- package/src/components/progress/progress.meta.md +38 -6
- package/src/components/progress/progress.stories.tsx +3 -3
- package/src/components/progress/progress.tsx +24 -16
- package/src/components/radio-group/radio-group.meta.md +79 -7
- package/src/components/radio-group/radio-group.stories.tsx +39 -3
- package/src/components/radio-group/radio-group.tsx +149 -18
- package/src/components/rate/rate.meta.md +35 -4
- package/src/components/rate/rate.stories.tsx +13 -5
- package/src/components/rate/rate.tsx +37 -10
- package/src/components/resizable/resizable.meta.md +7 -4
- package/src/components/resizable/resizable.stories.tsx +6 -6
- package/src/components/resizable/resizable.tsx +1 -1
- package/src/components/result/result.meta.md +7 -2
- package/src/components/result/result.stories.tsx +4 -8
- package/src/components/result/result.tsx +24 -15
- package/src/components/scroll-area/scroll-area.meta.md +4 -3
- package/src/components/scroll-area/scroll-area.stories.tsx +12 -4
- package/src/components/scroll-area/scroll-area.tsx +3 -3
- package/src/components/segmented/segmented.meta.md +7 -4
- package/src/components/segmented/segmented.stories.tsx +37 -8
- package/src/components/segmented/segmented.tsx +15 -7
- package/src/components/select/select.meta.md +197 -52
- package/src/components/select/select.stories.tsx +238 -63
- package/src/components/select/select.tsx +718 -171
- package/src/components/separator/separator.meta.md +4 -3
- package/src/components/separator/separator.stories.tsx +3 -3
- package/src/components/separator/separator.tsx +3 -7
- package/src/components/sheet/sheet.meta.md +32 -16
- package/src/components/sheet/sheet.stories.tsx +116 -10
- package/src/components/sheet/sheet.tsx +116 -29
- package/src/components/sidebar/sidebar.meta.md +37 -18
- package/src/components/sidebar/sidebar.stories.tsx +701 -29
- package/src/components/sidebar/sidebar.tsx +615 -142
- package/src/components/skeleton/skeleton.meta.md +4 -5
- package/src/components/skeleton/skeleton.stories.tsx +4 -4
- package/src/components/skeleton/skeleton.tsx +7 -7
- package/src/components/slider/slider.meta.md +57 -5
- package/src/components/slider/slider.stories.tsx +58 -6
- package/src/components/slider/slider.tsx +154 -13
- package/src/components/sonner/sonner.meta.md +58 -7
- package/src/components/sonner/sonner.stories.tsx +78 -5
- package/src/components/sonner/sonner.tsx +137 -8
- package/src/components/spinner/spinner.meta.md +62 -13
- package/src/components/spinner/spinner.stories.tsx +66 -14
- package/src/components/spinner/spinner.tsx +111 -9
- package/src/components/statistic/statistic.meta.md +7 -2
- package/src/components/statistic/statistic.stories.tsx +3 -7
- package/src/components/statistic/statistic.tsx +5 -6
- package/src/components/steps/steps.meta.md +18 -4
- package/src/components/steps/steps.stories.tsx +43 -3
- package/src/components/steps/steps.tsx +15 -12
- package/src/components/switch/switch.meta.md +51 -5
- package/src/components/switch/switch.stories.tsx +6 -6
- package/src/components/switch/switch.tsx +109 -41
- package/src/components/table/table.meta.md +17 -6
- package/src/components/table/table.stories.tsx +10 -5
- package/src/components/table/table.tsx +4 -4
- package/src/components/tabs/tabs.meta.md +38 -25
- package/src/components/tabs/tabs.stories.tsx +111 -25
- package/src/components/tabs/tabs.tsx +125 -54
- package/src/components/tag/tag.meta.md +105 -40
- package/src/components/tag/tag.stories.tsx +189 -16
- package/src/components/tag/tag.tsx +222 -21
- package/src/components/textarea/textarea.meta.md +35 -19
- package/src/components/textarea/textarea.stories.tsx +32 -6
- package/src/components/textarea/textarea.tsx +33 -9
- package/src/components/time-picker/time-picker.meta.md +124 -32
- package/src/components/time-picker/time-picker.stories.tsx +85 -15
- package/src/components/time-picker/time-picker.tsx +913 -61
- package/src/components/timeline/timeline.meta.md +14 -6
- package/src/components/timeline/timeline.stories.tsx +37 -7
- package/src/components/timeline/timeline.tsx +35 -14
- package/src/components/toggle/toggle.meta.md +5 -4
- package/src/components/toggle/toggle.stories.tsx +4 -4
- package/src/components/toggle/toggle.tsx +4 -3
- package/src/components/toggle-group/toggle-group.meta.md +5 -4
- package/src/components/toggle-group/toggle-group.stories.tsx +3 -3
- package/src/components/toggle-group/toggle-group.tsx +2 -2
- package/src/components/tooltip/tooltip.meta.md +55 -5
- package/src/components/tooltip/tooltip.stories.tsx +42 -5
- package/src/components/tooltip/tooltip.tsx +81 -21
- package/src/components/tour/tour.meta.md +9 -4
- package/src/components/tour/tour.stories.tsx +3 -3
- package/src/components/tour/tour.tsx +4 -4
- package/src/components/transfer/transfer.meta.md +11 -6
- package/src/components/transfer/transfer.stories.tsx +4 -8
- package/src/components/transfer/transfer.tsx +28 -21
- package/src/components/tree/tree.meta.md +63 -5
- package/src/components/tree/tree.stories.tsx +31 -12
- package/src/components/tree/tree.tsx +9 -8
- package/src/components/tree-select/tree-select.meta.md +59 -8
- package/src/components/tree-select/tree-select.stories.tsx +3 -3
- package/src/components/tree-select/tree-select.tsx +42 -7
- package/src/components/typography/typography.meta.md +61 -14
- package/src/components/typography/typography.stories.tsx +12 -11
- package/src/components/typography/typography.tsx +43 -28
- package/src/components/upload/upload.meta.md +49 -4
- package/src/components/upload/upload.stories.tsx +72 -12
- package/src/components/upload/upload.tsx +170 -37
- package/src/components/watermark/watermark.meta.md +7 -2
- package/src/components/watermark/watermark.stories.tsx +101 -9
- package/src/components/watermark/watermark.tsx +1 -0
- package/src/hooks/use-breakpoint.ts +117 -0
- package/src/hooks/use-debounce-callback.ts +52 -0
- package/src/hooks/use-mobile.ts +23 -0
- package/src/stories/theme-tokens.stories.tsx +747 -0
- package/src/utils/trigger-input.ts +53 -0
- package/src/components/button-group/button-group.meta.md +0 -92
- package/src/components/button-group/button-group.stories.tsx +0 -90
- package/src/components/button-group/button-group.tsx +0 -75
- package/src/components/combobox/combobox.meta.md +0 -93
- package/src/components/combobox/combobox.stories.tsx +0 -55
- package/src/components/combobox/combobox.tsx +0 -130
- package/src/components/space/space.meta.md +0 -94
- package/src/components/space/space.stories.tsx +0 -94
- package/src/components/space/space.tsx +0 -106
|
@@ -1,14 +1,51 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
3
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
3
4
|
|
|
4
5
|
import { cn } from '@/utils/cn';
|
|
5
6
|
|
|
6
7
|
const TooltipProvider = TooltipPrimitive.Provider;
|
|
7
8
|
const TooltipRoot = TooltipPrimitive.Root;
|
|
8
|
-
const TooltipTrigger =
|
|
9
|
+
const TooltipTrigger = React.forwardRef<
|
|
10
|
+
React.ElementRef<typeof TooltipPrimitive.Trigger>,
|
|
11
|
+
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Trigger>
|
|
12
|
+
>(({ className, ...props }, ref) => (
|
|
13
|
+
<TooltipPrimitive.Trigger
|
|
14
|
+
ref={ref}
|
|
15
|
+
className={cn('cursor-pointer', className)}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
));
|
|
19
|
+
TooltipTrigger.displayName = TooltipPrimitive.Trigger.displayName;
|
|
20
|
+
|
|
21
|
+
const tooltipContentVariants = cva(
|
|
22
|
+
'z-50 overflow-hidden rounded-md px-3 py-1.5 text-xs animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
|
23
|
+
{
|
|
24
|
+
variants: {
|
|
25
|
+
variant: {
|
|
26
|
+
default: 'bg-primary text-primary-foreground shadow-md',
|
|
27
|
+
light:
|
|
28
|
+
'border border-border bg-popover text-popover-foreground shadow-md',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
defaultVariants: {
|
|
32
|
+
variant: 'default',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
/** 箭头填充色与变体一一对应。 */
|
|
38
|
+
const arrowFillByVariant: Record<
|
|
39
|
+
NonNullable<VariantProps<typeof tooltipContentVariants>['variant']>,
|
|
40
|
+
string
|
|
41
|
+
> = {
|
|
42
|
+
default: 'fill-primary',
|
|
43
|
+
light: 'fill-popover',
|
|
44
|
+
};
|
|
9
45
|
|
|
10
46
|
export interface TooltipContentProps
|
|
11
|
-
extends React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content
|
|
47
|
+
extends React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>,
|
|
48
|
+
VariantProps<typeof tooltipContentVariants> {
|
|
12
49
|
/**
|
|
13
50
|
* 是否显示三角形箭头(antd `arrow` 并集)。
|
|
14
51
|
* @default true
|
|
@@ -19,24 +56,37 @@ export interface TooltipContentProps
|
|
|
19
56
|
const TooltipContent = React.forwardRef<
|
|
20
57
|
React.ElementRef<typeof TooltipPrimitive.Content>,
|
|
21
58
|
TooltipContentProps
|
|
22
|
-
>(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
sideOffset=
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
59
|
+
>(
|
|
60
|
+
(
|
|
61
|
+
{
|
|
62
|
+
className,
|
|
63
|
+
sideOffset = 4,
|
|
64
|
+
arrow = true,
|
|
65
|
+
variant = 'default',
|
|
66
|
+
children,
|
|
67
|
+
...props
|
|
68
|
+
},
|
|
69
|
+
ref,
|
|
70
|
+
) => (
|
|
71
|
+
<TooltipPrimitive.Portal>
|
|
72
|
+
<TooltipPrimitive.Content
|
|
73
|
+
ref={ref}
|
|
74
|
+
sideOffset={sideOffset}
|
|
75
|
+
className={cn(tooltipContentVariants({ variant }), className)}
|
|
76
|
+
{...props}
|
|
77
|
+
>
|
|
78
|
+
{children}
|
|
79
|
+
{arrow ? (
|
|
80
|
+
<TooltipPrimitive.Arrow
|
|
81
|
+
className={arrowFillByVariant[variant ?? 'default']}
|
|
82
|
+
width={8}
|
|
83
|
+
height={4}
|
|
84
|
+
/>
|
|
85
|
+
) : null}
|
|
86
|
+
</TooltipPrimitive.Content>
|
|
87
|
+
</TooltipPrimitive.Portal>
|
|
88
|
+
),
|
|
89
|
+
);
|
|
40
90
|
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
|
41
91
|
|
|
42
92
|
// ─── Convenience wrapper(antd-style 一行调用)──────────────────────────────
|
|
@@ -52,6 +102,14 @@ export interface TooltipProps
|
|
|
52
102
|
title: React.ReactNode;
|
|
53
103
|
/** 弹出方向。 @default "top" */
|
|
54
104
|
side?: 'top' | 'right' | 'bottom' | 'left';
|
|
105
|
+
/**
|
|
106
|
+
* 视觉变体:
|
|
107
|
+
* - `default`:深色背景 + 浅色文字(信息密度高、对比强,适合图标按钮 / 列截断提示)
|
|
108
|
+
* - `light`:浅色背景 + 深色文字 + 边框 + 阴影(视觉更轻,贴近富内容卡片调性,
|
|
109
|
+
* 对齐 cloud-design Balloon `type="primary"`)
|
|
110
|
+
* @default "default"
|
|
111
|
+
*/
|
|
112
|
+
variant?: 'default' | 'light';
|
|
55
113
|
/** 是否显示三角形箭头。 @default true */
|
|
56
114
|
arrow?: boolean;
|
|
57
115
|
/** 显示延迟(ms),默认沿用 Provider 的 delayDuration。 */
|
|
@@ -64,6 +122,7 @@ const Tooltip: React.FC<TooltipProps> = ({
|
|
|
64
122
|
children,
|
|
65
123
|
title,
|
|
66
124
|
side = 'top',
|
|
125
|
+
variant = 'default',
|
|
67
126
|
arrow = true,
|
|
68
127
|
delayDuration,
|
|
69
128
|
withProvider = false,
|
|
@@ -72,7 +131,7 @@ const Tooltip: React.FC<TooltipProps> = ({
|
|
|
72
131
|
const inner = (
|
|
73
132
|
<TooltipRoot delayDuration={delayDuration} {...rootProps}>
|
|
74
133
|
<TooltipTrigger asChild>{children}</TooltipTrigger>
|
|
75
|
-
<TooltipContent side={side} arrow={arrow}>
|
|
134
|
+
<TooltipContent side={side} variant={variant} arrow={arrow}>
|
|
76
135
|
{title}
|
|
77
136
|
</TooltipContent>
|
|
78
137
|
</TooltipRoot>
|
|
@@ -90,4 +149,5 @@ export {
|
|
|
90
149
|
TooltipRoot,
|
|
91
150
|
TooltipTrigger,
|
|
92
151
|
TooltipContent,
|
|
152
|
+
tooltipContentVariants,
|
|
93
153
|
};
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
id: tour
|
|
3
3
|
name: Tour
|
|
4
4
|
type: component
|
|
5
|
-
category:
|
|
5
|
+
category: deprecated
|
|
6
6
|
since: 0.1.0
|
|
7
|
-
package:
|
|
7
|
+
package: '@teamix-evo/ui'
|
|
8
|
+
displayName: 新手引导
|
|
8
9
|
---
|
|
9
10
|
|
|
10
|
-
# Tour
|
|
11
|
+
# Tour 新手引导
|
|
11
12
|
|
|
12
13
|
新手引导 — antd 独有补足。**等价 antd `Tour`**(v5.0+)。多步骤引导(spotlight + 卡片 + 步进按钮 + 可关闭),帮助新用户首次进入页面时了解关键功能位置。
|
|
13
14
|
|
|
@@ -24,6 +25,8 @@ package: "@teamix-evo/ui"
|
|
|
24
25
|
- 表单字段说明 → `FieldDescription`
|
|
25
26
|
- 错误反馈 → `Alert` / `notification`
|
|
26
27
|
|
|
28
|
+
## Props
|
|
29
|
+
|
|
27
30
|
<!-- auto:props:begin -->
|
|
28
31
|
| 名称 | 类型 | 默认值 | 必填 | 说明 |
|
|
29
32
|
| --- | --- | --- | --- | --- |
|
|
@@ -38,6 +41,8 @@ package: "@teamix-evo/ui"
|
|
|
38
41
|
| `mask` | `boolean` | `true` | – | 是否显示遮罩(antd `mask` 并集)。 |
|
|
39
42
|
<!-- auto:props:end -->
|
|
40
43
|
|
|
44
|
+
## 依赖
|
|
45
|
+
|
|
41
46
|
<!-- auto:deps:begin -->
|
|
42
47
|
### 同库依赖
|
|
43
48
|
|
|
@@ -46,7 +51,7 @@ package: "@teamix-evo/ui"
|
|
|
46
51
|
| Entry | 类型 | 描述 |
|
|
47
52
|
| --- | --- | --- |
|
|
48
53
|
| `cn` | util | Tailwind className 合并工具(clsx + tailwind-merge) |
|
|
49
|
-
| `button` | component | 通用按钮 — shadcn 实现 +
|
|
54
|
+
| `button` | component | 通用按钮 — shadcn 实现 + cloud-design 能力并集(loading / icon / shape / block / dashed variant / color 语义双 prop / disabledTooltip)。同文件合一导出 ButtonGroup + ButtonGroupText(等价 antd Space.Compact + cd SplitButton)。 |
|
|
50
55
|
|
|
51
56
|
### npm 依赖
|
|
52
57
|
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
3
3
|
import { Tour } from './tour';
|
|
4
4
|
import { Button } from '@/components/button/button';
|
|
5
5
|
|
|
6
6
|
const meta: Meta<typeof Tour> = {
|
|
7
|
-
title: '
|
|
7
|
+
title: '废弃 · Deprecated/Tour',
|
|
8
8
|
component: Tour,
|
|
9
9
|
tags: ['autodocs'],
|
|
10
10
|
parameters: {
|
|
11
11
|
docs: {
|
|
12
12
|
description: {
|
|
13
13
|
component:
|
|
14
|
-
'新手引导 — 多步骤 spotlight + 卡片 + 步进按钮。帮助新用户首次进入页面时了解关键功能位置。等价 antd `Tour
|
|
14
|
+
'⚠️ **已废弃** — 仅 Storybook 留档,不通过 manifest 对外发布。\n\n新手引导 — 多步骤 spotlight + 卡片 + 步进按钮。帮助新用户首次进入页面时了解关键功能位置。等价 antd `Tour`(v5.0+)。业务侧自管“是否首次访问”。',
|
|
15
15
|
},
|
|
16
16
|
},
|
|
17
17
|
},
|
|
@@ -176,7 +176,7 @@ const Tour: React.FC<TourProps> = ({
|
|
|
176
176
|
<rect
|
|
177
177
|
width="100%"
|
|
178
178
|
height="100%"
|
|
179
|
-
fill="
|
|
179
|
+
fill="var(--overlay-scrim)"
|
|
180
180
|
mask="url(#tour-mask)"
|
|
181
181
|
/>
|
|
182
182
|
</svg>
|
|
@@ -188,7 +188,7 @@ const Tour: React.FC<TourProps> = ({
|
|
|
188
188
|
<div
|
|
189
189
|
role="dialog"
|
|
190
190
|
className={cn(
|
|
191
|
-
'absolute w-80 rounded-md border bg-popover p-4 text-popover-foreground shadow-xl',
|
|
191
|
+
'absolute w-80 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-xl',
|
|
192
192
|
)}
|
|
193
193
|
style={cardStyle}
|
|
194
194
|
>
|
|
@@ -198,13 +198,13 @@ const Tour: React.FC<TourProps> = ({
|
|
|
198
198
|
type="button"
|
|
199
199
|
aria-label="关闭"
|
|
200
200
|
onClick={close}
|
|
201
|
-
className="text-muted-foreground transition-colors hover:text-foreground"
|
|
201
|
+
className="cursor-pointer text-muted-foreground transition-colors hover:text-foreground"
|
|
202
202
|
>
|
|
203
203
|
<X className="size-4" />
|
|
204
204
|
</button>
|
|
205
205
|
</div>
|
|
206
206
|
{cur.description ? (
|
|
207
|
-
<div className="mt-2 text-
|
|
207
|
+
<div className="mt-2 text-xs text-muted-foreground">
|
|
208
208
|
{cur.description}
|
|
209
209
|
</div>
|
|
210
210
|
) : null}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: transfer
|
|
3
3
|
name: Transfer
|
|
4
|
+
displayName: 穿梭框
|
|
4
5
|
type: component
|
|
5
|
-
category: data-
|
|
6
|
+
category: data-entry
|
|
6
7
|
since: 0.1.0
|
|
7
|
-
package:
|
|
8
|
+
package: '@teamix-evo/ui'
|
|
8
9
|
---
|
|
9
10
|
|
|
10
|
-
# Transfer
|
|
11
|
+
# Transfer 穿梭框
|
|
11
12
|
|
|
12
13
|
穿梭框 — antd 独有补足。**双侧勾选 + 移动**的批量分配交互(权限分配、字段映射、收件人选择)。受控 `targetKeys` + `onChange` 单一真值,内置全选 / 半选 / 可选搜索 / 禁用项。
|
|
13
14
|
|
|
@@ -22,6 +23,8 @@ package: "@teamix-evo/ui"
|
|
|
22
23
|
- 单纯多选 → `Select multiple` / `CheckboxGroup`(轻量)
|
|
23
24
|
- 选项 > 500 — 本组件未做虚拟化,建议改用 `Table` + 行选 + bulk action 模式
|
|
24
25
|
|
|
26
|
+
## Props
|
|
27
|
+
|
|
25
28
|
<!-- auto:props:begin -->
|
|
26
29
|
| 名称 | 类型 | 默认值 | 必填 | 说明 |
|
|
27
30
|
| --- | --- | --- | --- | --- |
|
|
@@ -36,6 +39,8 @@ package: "@teamix-evo/ui"
|
|
|
36
39
|
| `className` | `string` | – | – | – |
|
|
37
40
|
<!-- auto:props:end -->
|
|
38
41
|
|
|
42
|
+
## 依赖
|
|
43
|
+
|
|
39
44
|
<!-- auto:deps:begin -->
|
|
40
45
|
### 同库依赖
|
|
41
46
|
|
|
@@ -44,9 +49,9 @@ package: "@teamix-evo/ui"
|
|
|
44
49
|
| Entry | 类型 | 描述 |
|
|
45
50
|
| --- | --- | --- |
|
|
46
51
|
| `cn` | util | Tailwind className 合并工具(clsx + tailwind-merge) |
|
|
47
|
-
| `button` | component | 通用按钮 — shadcn 实现 +
|
|
52
|
+
| `button` | component | 通用按钮 — shadcn 实现 + cloud-design 能力并集(loading / icon / shape / block / dashed variant / color 语义双 prop / disabledTooltip)。同文件合一导出 ButtonGroup + ButtonGroupText(等价 antd Space.Compact + cd SplitButton)。 |
|
|
48
53
|
| `checkbox` | component | 复选框 — Radix Checkbox(原生 indeterminate)+ antd Checkbox.Group(options 数组驱动) |
|
|
49
|
-
| `input` | component |
|
|
54
|
+
| `input` | component | 单行文本输入 — clearable / showCount / size(sm 24 / md 32 / lg 36,与 Button 同档)/ error 四档内建能力。前缀/后缀/addon 等复合形态已拆出独立 InputGroup;多行已拆出独立 Textarea |
|
|
50
55
|
|
|
51
56
|
### npm 依赖
|
|
52
57
|
|
|
@@ -86,5 +91,5 @@ const [target, setTarget] = React.useState<string[]>(['2', '4']);
|
|
|
86
91
|
onChange={setTarget}
|
|
87
92
|
titles={['全部成员', '已授权']}
|
|
88
93
|
showSearch
|
|
89
|
-
|
|
94
|
+
/>;
|
|
90
95
|
```
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
3
3
|
import { Transfer, type TransferItem } from './transfer';
|
|
4
4
|
|
|
5
5
|
const meta: Meta<typeof Transfer> = {
|
|
6
|
-
title: '
|
|
6
|
+
title: '数据录入 · Data Entry/Transfer',
|
|
7
7
|
component: Transfer,
|
|
8
8
|
tags: ['autodocs'],
|
|
9
9
|
parameters: {
|
|
10
10
|
docs: {
|
|
11
11
|
description: {
|
|
12
12
|
component:
|
|
13
|
-
'穿梭框 — 双侧勾选 +
|
|
13
|
+
'穿梭框 — 双侧勾选 + 移动的批量分配交互(权限分配、字段映射、收件人选择)。受控 targetKeys 单一真值,内置全选 / 半选 / 可选搜索 / 禁用项跳过。等价 antd `Transfer`。',
|
|
14
14
|
},
|
|
15
15
|
},
|
|
16
16
|
},
|
|
@@ -30,11 +30,7 @@ export const Playground: Story = {
|
|
|
30
30
|
render: () => {
|
|
31
31
|
const [target, setTarget] = React.useState<string[]>(['2', '4']);
|
|
32
32
|
return (
|
|
33
|
-
<Transfer
|
|
34
|
-
dataSource={data}
|
|
35
|
-
targetKeys={target}
|
|
36
|
-
onChange={setTarget}
|
|
37
|
-
/>
|
|
33
|
+
<Transfer dataSource={data} targetKeys={target} onChange={setTarget} />
|
|
38
34
|
);
|
|
39
35
|
},
|
|
40
36
|
};
|
|
@@ -120,33 +120,39 @@ const Transfer = React.forwardRef<HTMLDivElement, TransferProps>(
|
|
|
120
120
|
query: string,
|
|
121
121
|
setQuery: (v: string) => void,
|
|
122
122
|
) => {
|
|
123
|
-
const selectableKeys = visible
|
|
123
|
+
const selectableKeys = visible
|
|
124
|
+
.filter((i) => !i.disabled)
|
|
125
|
+
.map((i) => i.key);
|
|
124
126
|
const allChecked =
|
|
125
|
-
selectableKeys.length > 0 &&
|
|
127
|
+
selectableKeys.length > 0 &&
|
|
128
|
+
selectableKeys.every((k) => checked.includes(k));
|
|
126
129
|
const someChecked =
|
|
127
130
|
!allChecked && selectableKeys.some((k) => checked.includes(k));
|
|
128
131
|
const toggleAll = (value: boolean) => {
|
|
129
|
-
if (value)
|
|
132
|
+
if (value)
|
|
133
|
+
setChecked(Array.from(new Set([...checked, ...selectableKeys])));
|
|
130
134
|
else setChecked(checked.filter((k) => !selectableKeys.includes(k)));
|
|
131
135
|
};
|
|
132
136
|
|
|
133
137
|
return (
|
|
134
|
-
<div className="flex w-56 flex-col overflow-hidden rounded-md border bg-card text-
|
|
135
|
-
<div className="flex items-center justify-between gap-2 border-b px-3 py-2">
|
|
138
|
+
<div className="flex w-56 flex-col overflow-hidden rounded-md border border-border bg-card text-xs">
|
|
139
|
+
<div className="flex items-center justify-between gap-2 border-b border-b-border bg-muted/40 px-3 py-2">
|
|
136
140
|
<label className="flex items-center gap-2">
|
|
137
141
|
<Checkbox
|
|
138
|
-
checked={
|
|
142
|
+
checked={
|
|
143
|
+
allChecked ? true : someChecked ? 'indeterminate' : false
|
|
144
|
+
}
|
|
139
145
|
disabled={disabled || selectableKeys.length === 0}
|
|
140
146
|
onCheckedChange={(c) => toggleAll(c === true)}
|
|
141
147
|
/>
|
|
142
|
-
<span className="text-xs text-muted-foreground">
|
|
148
|
+
<span className="text-xs text-muted-foreground tabular-nums">
|
|
143
149
|
{checked.length}/{items.length}
|
|
144
150
|
</span>
|
|
145
151
|
</label>
|
|
146
|
-
<span className="text-xs font-medium">{title}</span>
|
|
152
|
+
<span className="text-xs font-medium text-foreground">{title}</span>
|
|
147
153
|
</div>
|
|
148
154
|
{showSearch ? (
|
|
149
|
-
<div className="border-b p-2">
|
|
155
|
+
<div className="border-b border-b-border p-2">
|
|
150
156
|
<div className="relative">
|
|
151
157
|
<Search className="absolute left-2 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" />
|
|
152
158
|
<Input
|
|
@@ -175,8 +181,9 @@ const Transfer = React.forwardRef<HTMLDivElement, TransferProps>(
|
|
|
175
181
|
<li key={item.key}>
|
|
176
182
|
<label
|
|
177
183
|
className={cn(
|
|
178
|
-
'flex items-center gap-2 px-3 py-1.5',
|
|
179
|
-
!itemDisabled && 'cursor-pointer hover:bg-accent',
|
|
184
|
+
'flex items-center gap-2 px-3 py-1.5 transition-colors',
|
|
185
|
+
!itemDisabled && 'cursor-pointer hover:bg-accent/50',
|
|
186
|
+
!itemDisabled && isChecked && 'bg-accent/40',
|
|
180
187
|
itemDisabled && 'cursor-not-allowed opacity-50',
|
|
181
188
|
)}
|
|
182
189
|
>
|
|
@@ -185,7 +192,8 @@ const Transfer = React.forwardRef<HTMLDivElement, TransferProps>(
|
|
|
185
192
|
disabled={itemDisabled}
|
|
186
193
|
onCheckedChange={(c) => {
|
|
187
194
|
if (c === true) setChecked([...checked, item.key]);
|
|
188
|
-
else
|
|
195
|
+
else
|
|
196
|
+
setChecked(checked.filter((k) => k !== item.key));
|
|
189
197
|
}}
|
|
190
198
|
/>
|
|
191
199
|
<span className="min-w-0 flex-1 truncate">
|
|
@@ -202,10 +210,7 @@ const Transfer = React.forwardRef<HTMLDivElement, TransferProps>(
|
|
|
202
210
|
};
|
|
203
211
|
|
|
204
212
|
return (
|
|
205
|
-
<div
|
|
206
|
-
ref={ref}
|
|
207
|
-
className={cn('flex items-center gap-3', className)}
|
|
208
|
-
>
|
|
213
|
+
<div ref={ref} className={cn('flex items-center gap-3', className)}>
|
|
209
214
|
{renderPane(
|
|
210
215
|
titles[0],
|
|
211
216
|
leftItems,
|
|
@@ -215,22 +220,24 @@ const Transfer = React.forwardRef<HTMLDivElement, TransferProps>(
|
|
|
215
220
|
leftQuery,
|
|
216
221
|
setLeftQuery,
|
|
217
222
|
)}
|
|
218
|
-
<div className="flex flex-col gap-
|
|
223
|
+
<div className="flex flex-col gap-1.5">
|
|
219
224
|
<Button
|
|
220
|
-
size="
|
|
225
|
+
size="sm"
|
|
221
226
|
variant="outline"
|
|
222
227
|
disabled={disabled || leftChecked.length === 0}
|
|
223
228
|
onClick={moveRight}
|
|
224
229
|
aria-label="移动到右侧"
|
|
225
|
-
|
|
230
|
+
className="size-7 p-0"
|
|
231
|
+
icon={<ChevronRight className="size-3.5" />}
|
|
226
232
|
/>
|
|
227
233
|
<Button
|
|
228
|
-
size="
|
|
234
|
+
size="sm"
|
|
229
235
|
variant="outline"
|
|
230
236
|
disabled={disabled || rightChecked.length === 0}
|
|
231
237
|
onClick={moveLeft}
|
|
232
238
|
aria-label="移动到左侧"
|
|
233
|
-
|
|
239
|
+
className="size-7 p-0"
|
|
240
|
+
icon={<ChevronLeft className="size-3.5" />}
|
|
234
241
|
/>
|
|
235
242
|
</div>
|
|
236
243
|
{renderPane(
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: tree
|
|
3
3
|
name: Tree
|
|
4
|
+
displayName: 树形控件
|
|
4
5
|
type: component
|
|
5
6
|
category: data-display
|
|
6
7
|
since: 0.1.0
|
|
7
|
-
package:
|
|
8
|
+
package: '@teamix-evo/ui'
|
|
8
9
|
---
|
|
9
10
|
|
|
10
|
-
# Tree
|
|
11
|
+
# Tree 树形控件
|
|
11
12
|
|
|
12
13
|
树形控件 — antd 独有补足。递归层级展示(组织架构、文件系统、分类目录),支持**可展开 / 可单选 / 可勾选(父子级联 + 半选)**,受控与非受控并存。Radix 未提供 tree primitive — 本组件自实现递归 + 受控逻辑。
|
|
13
14
|
|
|
@@ -23,6 +24,8 @@ package: "@teamix-evo/ui"
|
|
|
23
24
|
- 大数据量(> 1000 节点)— 本组件不做虚拟化,业务侧请自做分页 / 懒加载子节点
|
|
24
25
|
- 拖拽排序场景 → 需配合 `react-dnd` 等库自行扩展,本组件不内置
|
|
25
26
|
|
|
27
|
+
## Props
|
|
28
|
+
|
|
26
29
|
<!-- auto:props:begin -->
|
|
27
30
|
| 名称 | 类型 | 默认值 | 必填 | 说明 |
|
|
28
31
|
| --- | --- | --- | --- | --- |
|
|
@@ -41,6 +44,8 @@ package: "@teamix-evo/ui"
|
|
|
41
44
|
| `onExpand` | `(next: string[]) => void` | – | – | 展开变化回调。 |
|
|
42
45
|
<!-- auto:props:end -->
|
|
43
46
|
|
|
47
|
+
## 依赖
|
|
48
|
+
|
|
44
49
|
<!-- auto:deps:begin -->
|
|
45
50
|
### 同库依赖
|
|
46
51
|
|
|
@@ -66,6 +71,9 @@ pnpm add lucide-react@^0.460.0
|
|
|
66
71
|
- **`checkable` 默认级联**:勾选父节点会勾选所有后代,勾选所有后代会自动勾选父节点 — **不要**自己写额外的级联逻辑;`onCheck` 给的是叶子+完全选中的父节点集合(半选不在内)
|
|
67
72
|
- **半选(indeterminate)**自动计算,不需要消费方维护
|
|
68
73
|
- **`selectable` + `checkable` 可共存**,但 UI 上选中高亮与勾选是两套独立状态(对齐 antd)
|
|
74
|
+
- **选中 ≠ hover**:hover 是 `accent/50`(半透明),选中是 `accent` 实色 + `font-medium`,视觉上明显区分;**不要**手动改为其他调色板
|
|
75
|
+
- **节点缩进**:每层 20px刷类 shadcn/cloud-design teamix 规范,**不要**手动调 padding
|
|
76
|
+
- **展开图标**:`size-3` 的 `ChevronRight` 旋转 90°,默认为 `text-muted-foreground` hover 变 `text-foreground` — 不要换 chevron 尺寸
|
|
69
77
|
- **大数据量警告**:节点数 ≥ 500 时建议拆分为"按需加载子节点"(在 `onExpand` 中拉取),否则首次渲染卡顿
|
|
70
78
|
- **`disabled` 节点**:展开按钮亦禁用,但**仍参与级联计算** — 父被勾选时禁用子也会变为 checked
|
|
71
79
|
|
|
@@ -82,7 +90,11 @@ const data: TreeNode[] = [
|
|
|
82
90
|
title: 'src',
|
|
83
91
|
icon: <Folder className="size-3.5" />,
|
|
84
92
|
children: [
|
|
85
|
-
{
|
|
93
|
+
{
|
|
94
|
+
key: 'src/index.ts',
|
|
95
|
+
title: 'index.ts',
|
|
96
|
+
icon: <File className="size-3.5" />,
|
|
97
|
+
},
|
|
86
98
|
{
|
|
87
99
|
key: 'src/components',
|
|
88
100
|
title: 'components',
|
|
@@ -97,7 +109,7 @@ const data: TreeNode[] = [
|
|
|
97
109
|
];
|
|
98
110
|
|
|
99
111
|
// 默认展开 + 选择
|
|
100
|
-
<Tree data={data} defaultExpandAll
|
|
112
|
+
<Tree data={data} defaultExpandAll />;
|
|
101
113
|
|
|
102
114
|
// 可勾选(受控)
|
|
103
115
|
const [checked, setChecked] = React.useState<string[]>([]);
|
|
@@ -107,5 +119,51 @@ const [checked, setChecked] = React.useState<string[]>([]);
|
|
|
107
119
|
defaultExpandAll
|
|
108
120
|
checkedKeys={checked}
|
|
109
121
|
onCheck={setChecked}
|
|
110
|
-
|
|
122
|
+
/>;
|
|
111
123
|
```
|
|
124
|
+
|
|
125
|
+
## Tree 形态 — 旧库 API → 新库映射
|
|
126
|
+
|
|
127
|
+
> 旧库 `Tree / Tree.Node`(hybridcloud,JSX 子组件式) → 新库 `Tree`(纯数据驱动)。
|
|
128
|
+
> 新库放弃 JSX `<Tree.Node>` 子组件嵌套,改用 `data: TreeNode[]` 数组(对齐 antd 5+ 的 `treeData` 风格)— tree-shake 友好 / 序列化方便 / 异步加载更直观。
|
|
129
|
+
|
|
130
|
+
### 命名映射
|
|
131
|
+
|
|
132
|
+
| 旧库 API | 新库 API | 备注 |
|
|
133
|
+
| --- | --- | --- |
|
|
134
|
+
| `<Tree>` + `<Tree.Node>` 子组件嵌套 | `<Tree data={[{ key, title, children }]} />` | **Breaking** — 改为数据驱动 |
|
|
135
|
+
| `dataSource` | `data` | 字段命名简化 |
|
|
136
|
+
| `Tree.Node` 的 `key/label/children` | `TreeNode.key/title/children` | `label` → `title`(对齐 antd) |
|
|
137
|
+
| `checkedKeys` / `selectedKeys` / `expandedKeys` | 同名保留 | 受控集合 |
|
|
138
|
+
| `defaultCheckedKeys` / `defaultSelectedKeys` / `defaultExpandedKeys` | 同名保留 | uncontrolled 初值 |
|
|
139
|
+
| `defaultExpandAll` | 同名保留 | 仅 uncontrolled 模式 |
|
|
140
|
+
| `onCheck(keys, extra)` | `onCheck(keys)` | 单参数化(extra 信息可在 data 里查) |
|
|
141
|
+
| `onSelect(keys, extra)` | `onSelect(keys)` | 同上 |
|
|
142
|
+
| `isLeaf`(Node prop) | `TreeNode.isLeaf`(data field) | 数据字段化 |
|
|
143
|
+
| `disabled`(Node prop) | `TreeNode.disabled`(data field) | 同上 |
|
|
144
|
+
| `icon`(Node prop) | `TreeNode.icon`(data field) | 同上 |
|
|
145
|
+
|
|
146
|
+
### Breaking Changes(从旧库迁移时需改写)
|
|
147
|
+
|
|
148
|
+
1. **JSX `<Tree.Node>` 全部改写为 `data` 数组** — 这是最大改动,业务工程需要重构数据结构
|
|
149
|
+
2. `dataSource` → `data`
|
|
150
|
+
3. `label` → `title`(节点字段)
|
|
151
|
+
4. `onCheck(keys, extra)` → `onCheck(keys)`(extra 信息消失,业务侧自查 data)
|
|
152
|
+
|
|
153
|
+
### 不修复 / 后续工序清单(报告 §3 P1/P2)
|
|
154
|
+
|
|
155
|
+
> 以下功能在新库未实现,**业务真有需求时**优先做。多数依赖外部库或较复杂的 source 改造。
|
|
156
|
+
|
|
157
|
+
- **`draggable` 拖拽排序**(P1):需集成 `@dnd-kit/core` + `@dnd-kit/sortable`,本组件不内置;业务侧自接 dnd-kit
|
|
158
|
+
- **`loadData` 异步加载子节点**(P1):点击展开时触发 fetch,目前业务侧用受控 `expandedKeys` + `onExpand` 自管异步;后续工序加 prop
|
|
159
|
+
- **`checkStrictly` 父子不关联**(P1):checkable 模式下严格独立勾选,目前固定级联;后续 prop
|
|
160
|
+
- **`useVirtual` 虚拟滚动**(P1):大数据量(> 1000 节点)首次渲染卡顿,后续可集成 `react-window` 或 `@tanstack/react-virtual`
|
|
161
|
+
- **`editable` 节点编辑**(P2):双击节点变 Input;业务侧用 `title: <Input />` 自定义渲染替代
|
|
162
|
+
- **`filterTreeNode` 过滤高亮**(P2):配合 TreeSelect 的 showSearch 使用,需在 Tree 层先支持
|
|
163
|
+
|
|
164
|
+
### 不修复(报告 §5 已明确)
|
|
165
|
+
|
|
166
|
+
- **JSX `<Tree.Node>`**:数据驱动是显式优势,不回退
|
|
167
|
+
- **`labelRender` vs `label(ReactNode)`**:`title` 直接接 ReactNode,无需另设 render prop
|
|
168
|
+
- **展开动画**:CSS transition 已内置(对齐 antd 默认)
|
|
169
|
+
- **`focusedKey` / `autoFocus`**:Radix-style 内管,不暴露
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
3
3
|
import { File, Folder } from 'lucide-react';
|
|
4
4
|
import { Tree, type TreeNode } from './tree';
|
|
5
5
|
|
|
@@ -11,7 +11,7 @@ const meta: Meta<typeof Tree> = {
|
|
|
11
11
|
docs: {
|
|
12
12
|
description: {
|
|
13
13
|
component:
|
|
14
|
-
'树形控件 —
|
|
14
|
+
'树形控件 — 递归层级展示(目录、组织、分类)。支持展开 / 单选 / 父子级联勾选(自动半选),受控与非受控并存。Radix 未提供 tree primitive,本组件自实现递归与级联。等价 antd `Tree`。',
|
|
15
15
|
},
|
|
16
16
|
},
|
|
17
17
|
},
|
|
@@ -26,22 +26,45 @@ const fileTree: TreeNode[] = [
|
|
|
26
26
|
title: 'src',
|
|
27
27
|
icon: <Folder className="size-3.5" />,
|
|
28
28
|
children: [
|
|
29
|
-
{
|
|
29
|
+
{
|
|
30
|
+
key: 'src/index.ts',
|
|
31
|
+
title: 'index.ts',
|
|
32
|
+
icon: <File className="size-3.5" />,
|
|
33
|
+
},
|
|
30
34
|
{
|
|
31
35
|
key: 'src/components',
|
|
32
36
|
title: 'components',
|
|
33
37
|
icon: <Folder className="size-3.5" />,
|
|
34
38
|
children: [
|
|
35
|
-
{
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
{
|
|
40
|
+
key: 'src/components/Button.tsx',
|
|
41
|
+
title: 'Button.tsx',
|
|
42
|
+
icon: <File className="size-3.5" />,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
key: 'src/components/Input.tsx',
|
|
46
|
+
title: 'Input.tsx',
|
|
47
|
+
icon: <File className="size-3.5" />,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
key: 'src/components/Dialog.tsx',
|
|
51
|
+
title: 'Dialog.tsx',
|
|
52
|
+
icon: <File className="size-3.5" />,
|
|
53
|
+
disabled: true,
|
|
54
|
+
},
|
|
38
55
|
],
|
|
39
56
|
},
|
|
40
57
|
{
|
|
41
58
|
key: 'src/utils',
|
|
42
59
|
title: 'utils',
|
|
43
60
|
icon: <Folder className="size-3.5" />,
|
|
44
|
-
children: [
|
|
61
|
+
children: [
|
|
62
|
+
{
|
|
63
|
+
key: 'src/utils/cn.ts',
|
|
64
|
+
title: 'cn.ts',
|
|
65
|
+
icon: <File className="size-3.5" />,
|
|
66
|
+
},
|
|
67
|
+
],
|
|
45
68
|
},
|
|
46
69
|
],
|
|
47
70
|
},
|
|
@@ -99,11 +122,7 @@ export const ControlledExpand: Story = {
|
|
|
99
122
|
render: () => {
|
|
100
123
|
const [expanded, setExpanded] = React.useState<string[]>(['src']);
|
|
101
124
|
return (
|
|
102
|
-
<Tree
|
|
103
|
-
data={fileTree}
|
|
104
|
-
expandedKeys={expanded}
|
|
105
|
-
onExpand={setExpanded}
|
|
106
|
-
/>
|
|
125
|
+
<Tree data={fileTree} expandedKeys={expanded} onExpand={setExpanded} />
|
|
107
126
|
);
|
|
108
127
|
},
|
|
109
128
|
};
|