@teamix-evo/ui 0.2.0 → 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 +15 -9
- package/src/components/accordion/accordion.meta.md +5 -9
- package/src/components/accordion/accordion.stories.tsx +3 -3
- package/src/components/accordion/accordion.tsx +104 -8
- package/src/components/affix/affix.meta.md +21 -12
- package/src/components/affix/affix.stories.tsx +101 -26
- package/src/components/affix/affix.tsx +79 -9
- package/src/components/alert/alert.meta.md +52 -26
- 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 +48 -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 +10 -14
- package/src/components/anchor/anchor.stories.tsx +3 -3
- package/src/components/anchor/anchor.tsx +2 -2
- package/src/components/app/app.meta.md +10 -14
- package/src/components/app/app.stories.tsx +6 -6
- package/src/components/aspect-ratio/aspect-ratio.meta.md +4 -8
- package/src/components/aspect-ratio/aspect-ratio.stories.tsx +3 -3
- package/src/components/auto-complete/auto-complete.meta.md +19 -20
- package/src/components/auto-complete/auto-complete.stories.tsx +44 -3
- package/src/components/auto-complete/auto-complete.tsx +119 -71
- package/src/components/avatar/avatar.meta.md +9 -22
- package/src/components/avatar/avatar.stories.tsx +21 -3
- package/src/components/avatar/avatar.tsx +24 -23
- package/src/components/badge/badge.meta.md +14 -18
- package/src/components/badge/badge.stories.tsx +2 -2
- package/src/components/badge/badge.tsx +2 -2
- package/src/components/breadcrumb/breadcrumb.meta.md +29 -20
- package/src/components/breadcrumb/breadcrumb.stories.tsx +120 -5
- package/src/components/breadcrumb/breadcrumb.tsx +22 -8
- package/src/components/button/button.meta.md +261 -29
- package/src/components/button/button.stories.tsx +549 -41
- package/src/components/button/button.tsx +335 -33
- package/src/components/calendar/calendar.meta.md +19 -14
- package/src/components/calendar/calendar.stories.tsx +5 -5
- package/src/components/calendar/calendar.tsx +73 -8
- package/src/components/card/card.meta.md +31 -34
- package/src/components/card/card.stories.tsx +34 -3
- package/src/components/card/card.tsx +146 -63
- package/src/components/carousel/carousel.meta.md +10 -14
- package/src/components/carousel/carousel.stories.tsx +1 -1
- package/src/components/cascader/cascader.meta.md +43 -22
- package/src/components/cascader/cascader.stories.tsx +13 -2
- package/src/components/cascader/cascader.tsx +427 -84
- package/src/components/checkbox/checkbox.meta.md +74 -24
- package/src/components/checkbox/checkbox.stories.tsx +160 -2
- package/src/components/checkbox/checkbox.tsx +77 -9
- package/src/components/collapsible/collapsible.meta.md +7 -6
- package/src/components/collapsible/collapsible.stories.tsx +2 -2
- package/src/components/collapsible/collapsible.tsx +93 -6
- package/src/components/color-picker/color-picker.meta.md +16 -20
- package/src/components/color-picker/color-picker.stories.tsx +86 -7
- package/src/components/color-picker/color-picker.tsx +19 -9
- package/src/components/command/command.meta.md +7 -11
- package/src/components/command/command.stories.tsx +4 -4
- package/src/components/command/command.tsx +18 -7
- package/src/components/context-menu/context-menu.meta.md +5 -25
- package/src/components/context-menu/context-menu.stories.tsx +4 -4
- package/src/components/context-menu/context-menu.tsx +21 -8
- package/src/components/data-table/data-table.meta.md +14 -18
- package/src/components/data-table/data-table.stories.tsx +1 -1
- package/src/components/data-table/data-table.tsx +2 -2
- package/src/components/date-picker/date-picker.meta.md +90 -41
- 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 +12 -16
- package/src/components/descriptions/descriptions.stories.tsx +2 -2
- package/src/components/descriptions/descriptions.tsx +22 -14
- package/src/components/dialog/dialog.meta.md +67 -17
- 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 +27 -39
- package/src/components/drawer/drawer.stories.tsx +29 -12
- package/src/components/drawer/drawer.tsx +22 -114
- package/src/components/dropdown-menu/dropdown-menu.meta.md +64 -24
- package/src/components/dropdown-menu/dropdown-menu.stories.tsx +81 -3
- 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 +10 -14
- package/src/components/empty/empty.stories.tsx +3 -3
- package/src/components/empty/empty.tsx +10 -3
- package/src/components/field/field.meta.md +46 -25
- package/src/components/field/field.stories.tsx +380 -3
- 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 +59 -20
- package/src/components/flex/flex.stories.tsx +65 -10
- package/src/components/flex/flex.tsx +27 -4
- package/src/components/float-button/float-button.meta.md +10 -29
- package/src/components/float-button/float-button.stories.tsx +6 -6
- package/src/components/form/form.meta.md +31 -52
- package/src/components/form/form.stories.tsx +350 -3
- package/src/components/form/form.tsx +101 -35
- package/src/components/grid/grid.meta.md +4 -24
- package/src/components/grid/grid.stories.tsx +2 -2
- package/src/components/hover-card/hover-card.meta.md +9 -10
- package/src/components/hover-card/hover-card.stories.tsx +29 -4
- 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 +14 -18
- package/src/components/image/image.stories.tsx +3 -3
- package/src/components/image/image.tsx +2 -0
- package/src/components/input/demo/sizes.tsx +2 -2
- package/src/components/input/input.meta.md +44 -43
- package/src/components/input/input.stories.tsx +62 -35
- package/src/components/input/input.tsx +96 -101
- package/src/components/input-group/input-group.meta.md +53 -39
- package/src/components/input-group/input-group.stories.tsx +49 -16
- package/src/components/input-group/input-group.tsx +43 -8
- package/src/components/input-number/input-number.meta.md +68 -20
- package/src/components/input-number/input-number.stories.tsx +33 -6
- package/src/components/input-number/input-number.tsx +79 -20
- package/src/components/input-otp/input-otp.meta.md +8 -20
- 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 -26
- package/src/components/item/item.stories.tsx +3 -3
- package/src/components/item/item.tsx +7 -6
- package/src/components/kbd/kbd.meta.md +7 -19
- package/src/components/kbd/kbd.stories.tsx +4 -4
- package/src/components/kbd/kbd.tsx +8 -4
- package/src/components/label/label.meta.md +21 -18
- 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 -12
- package/src/components/masonry/masonry.stories.tsx +4 -4
- package/src/components/mentions/mentions.meta.md +42 -21
- package/src/components/mentions/mentions.stories.tsx +120 -6
- package/src/components/mentions/mentions.tsx +10 -5
- package/src/components/menubar/menubar.meta.md +4 -8
- package/src/components/menubar/menubar.stories.tsx +55 -3
- package/src/components/menubar/menubar.tsx +9 -9
- package/src/components/native-select/native-select.meta.md +7 -11
- package/src/components/native-select/native-select.stories.tsx +4 -4
- package/src/components/native-select/native-select.tsx +1 -1
- package/src/components/navigation-menu/navigation-menu.meta.md +4 -8
- package/src/components/navigation-menu/navigation-menu.stories.tsx +106 -3
- package/src/components/navigation-menu/navigation-menu.tsx +6 -3
- package/src/components/notification/notification.meta.md +41 -8
- package/src/components/notification/notification.stories.tsx +9 -9
- package/src/components/notification/notification.tsx +34 -19
- 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 +122 -50
- package/src/components/pagination/pagination.stories.tsx +227 -11
- package/src/components/pagination/pagination.tsx +355 -63
- package/src/components/popconfirm/popconfirm.meta.md +19 -23
- package/src/components/popconfirm/popconfirm.stories.tsx +2 -2
- package/src/components/popconfirm/popconfirm.tsx +1 -1
- package/src/components/popover/popover.meta.md +64 -12
- package/src/components/popover/popover.stories.tsx +83 -7
- package/src/components/popover/popover.tsx +77 -28
- package/src/components/progress/progress.meta.md +43 -26
- package/src/components/progress/progress.stories.tsx +2 -2
- package/src/components/progress/progress.tsx +19 -11
- package/src/components/radio-group/radio-group.meta.md +78 -11
- package/src/components/radio-group/radio-group.stories.tsx +38 -2
- package/src/components/radio-group/radio-group.tsx +149 -18
- package/src/components/rate/rate.meta.md +41 -19
- package/src/components/rate/rate.stories.tsx +2 -2
- package/src/components/rate/rate.tsx +37 -10
- package/src/components/resizable/resizable.meta.md +4 -12
- package/src/components/resizable/resizable.stories.tsx +5 -5
- package/src/components/resizable/resizable.tsx +1 -1
- package/src/components/result/result.meta.md +10 -14
- package/src/components/result/result.stories.tsx +2 -2
- package/src/components/result/result.tsx +21 -12
- package/src/components/scroll-area/scroll-area.meta.md +4 -8
- package/src/components/scroll-area/scroll-area.stories.tsx +5 -5
- package/src/components/segmented/segmented.meta.md +15 -17
- package/src/components/segmented/segmented.stories.tsx +3 -3
- package/src/components/segmented/segmented.tsx +15 -7
- package/src/components/select/select.meta.md +199 -67
- package/src/components/select/select.stories.tsx +238 -63
- package/src/components/select/select.tsx +718 -171
- package/src/components/separator/separator.meta.md +10 -14
- package/src/components/separator/separator.stories.tsx +2 -2
- package/src/components/separator/separator.tsx +3 -7
- package/src/components/sheet/sheet.meta.md +26 -21
- package/src/components/sheet/sheet.stories.tsx +116 -10
- package/src/components/sheet/sheet.tsx +116 -29
- package/src/components/sidebar/sidebar.meta.md +28 -38
- package/src/components/sidebar/sidebar.stories.tsx +696 -29
- package/src/components/sidebar/sidebar.tsx +615 -142
- package/src/components/skeleton/skeleton.meta.md +7 -31
- package/src/components/skeleton/skeleton.stories.tsx +3 -3
- package/src/components/skeleton/skeleton.tsx +7 -7
- package/src/components/slider/slider.meta.md +60 -13
- package/src/components/slider/slider.stories.tsx +58 -6
- package/src/components/slider/slider.tsx +154 -13
- package/src/components/sonner/sonner.meta.md +54 -8
- package/src/components/sonner/sonner.stories.tsx +79 -11
- package/src/components/sonner/sonner.tsx +137 -8
- package/src/components/spinner/spinner.meta.md +57 -21
- package/src/components/spinner/spinner.stories.tsx +66 -14
- package/src/components/spinner/spinner.tsx +111 -9
- package/src/components/statistic/statistic.meta.md +14 -30
- package/src/components/statistic/statistic.stories.tsx +1 -1
- package/src/components/statistic/statistic.tsx +4 -5
- package/src/components/steps/steps.meta.md +20 -15
- package/src/components/steps/steps.stories.tsx +37 -2
- package/src/components/steps/steps.tsx +15 -12
- package/src/components/switch/switch.meta.md +56 -15
- package/src/components/switch/switch.stories.tsx +5 -5
- package/src/components/switch/switch.tsx +59 -13
- package/src/components/table/table.meta.md +3 -7
- package/src/components/table/table.stories.tsx +1 -1
- package/src/components/table/table.tsx +4 -4
- package/src/components/tabs/tabs.meta.md +40 -32
- package/src/components/tabs/tabs.stories.tsx +104 -26
- package/src/components/tabs/tabs.tsx +125 -54
- package/src/components/tag/tag.meta.md +104 -68
- package/src/components/tag/tag.stories.tsx +183 -15
- package/src/components/tag/tag.tsx +222 -21
- package/src/components/textarea/textarea.meta.md +42 -31
- package/src/components/textarea/textarea.stories.tsx +32 -6
- package/src/components/textarea/textarea.tsx +32 -8
- package/src/components/time-picker/time-picker.meta.md +119 -50
- package/src/components/time-picker/time-picker.stories.tsx +65 -33
- package/src/components/time-picker/time-picker.tsx +889 -101
- package/src/components/timeline/timeline.meta.md +16 -17
- package/src/components/timeline/timeline.stories.tsx +24 -4
- package/src/components/timeline/timeline.tsx +32 -12
- package/src/components/toggle/toggle.meta.md +8 -12
- 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 +10 -14
- 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 +63 -18
- package/src/components/tooltip/tooltip.stories.tsx +42 -5
- package/src/components/tooltip/tooltip.tsx +81 -21
- package/src/components/tour/tour.meta.md +16 -20
- package/src/components/tour/tour.stories.tsx +3 -3
- package/src/components/tour/tour.tsx +3 -3
- package/src/components/transfer/transfer.meta.md +18 -22
- package/src/components/transfer/transfer.stories.tsx +2 -2
- package/src/components/transfer/transfer.tsx +28 -21
- package/src/components/tree/tree.meta.md +67 -22
- package/src/components/tree/tree.stories.tsx +1 -1
- package/src/components/tree/tree.tsx +9 -8
- package/src/components/tree-select/tree-select.meta.md +59 -23
- package/src/components/tree-select/tree-select.stories.tsx +2 -2
- package/src/components/tree-select/tree-select.tsx +42 -7
- package/src/components/typography/typography.meta.md +61 -39
- package/src/components/typography/typography.stories.tsx +14 -9
- package/src/components/typography/typography.tsx +38 -25
- package/src/components/upload/upload.meta.md +61 -25
- package/src/components/upload/upload.stories.tsx +69 -3
- package/src/components/upload/upload.tsx +170 -37
- package/src/components/watermark/watermark.meta.md +15 -19
- package/src/components/watermark/watermark.stories.tsx +98 -8
- 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 -101
- package/src/components/button-group/button-group.stories.tsx +0 -93
- package/src/components/button-group/button-group.tsx +0 -75
- package/src/components/combobox/combobox.meta.md +0 -102
- package/src/components/combobox/combobox.stories.tsx +0 -55
- package/src/components/combobox/combobox.tsx +0 -130
- package/src/components/input/demo/addon.tsx +0 -15
- package/src/components/input/demo/with-prefix-suffix.tsx +0 -19
- package/src/components/space/space.meta.md +0 -103
- package/src/components/space/space.stories.tsx +0 -108
- package/src/components/space/space.tsx +0 -106
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import * as LabelPrimitive from '@radix-ui/react-label';
|
|
3
3
|
import { cva, type VariantProps } from 'class-variance-authority';
|
|
4
|
+
import { Info } from 'lucide-react';
|
|
4
5
|
|
|
5
6
|
import { cn } from '@/utils/cn';
|
|
7
|
+
import {
|
|
8
|
+
TooltipContent,
|
|
9
|
+
TooltipProvider,
|
|
10
|
+
TooltipRoot,
|
|
11
|
+
TooltipTrigger,
|
|
12
|
+
} from '@/components/tooltip/tooltip';
|
|
6
13
|
|
|
7
14
|
const labelVariants = cva(
|
|
8
|
-
'text-
|
|
15
|
+
'text-xs font-medium leading-8 peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
|
|
9
16
|
{
|
|
10
17
|
variants: {
|
|
11
18
|
disabled: {
|
|
@@ -29,11 +36,33 @@ export interface LabelProps
|
|
|
29
36
|
*/
|
|
30
37
|
disabled?: boolean;
|
|
31
38
|
/**
|
|
32
|
-
* 必填标记。`true` 时在 children
|
|
39
|
+
* 必填标记。`true` 时在 children 与 info icon **后**追加红色 `*`
|
|
40
|
+
* (语义来自 design destructive token);顺序为 `文字 ⓘ *`,三者间距 4px。
|
|
33
41
|
* 配合 `aria-required` 在 input 上一起使用以保证可访问性。
|
|
34
42
|
* @default false
|
|
35
43
|
*/
|
|
36
44
|
required?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* 辅助说明文本 — 有值时在 label 文字后渲染 info icon + hover tooltip
|
|
47
|
+
* (对齐 antd `Form.Item.tooltip` 习惯)。
|
|
48
|
+
*/
|
|
49
|
+
tooltip?: string;
|
|
50
|
+
/**
|
|
51
|
+
* Tooltip 弹出方向。
|
|
52
|
+
* @default 'top'
|
|
53
|
+
*/
|
|
54
|
+
tooltipSide?: 'top' | 'right' | 'bottom' | 'left';
|
|
55
|
+
/**
|
|
56
|
+
* 最大宽度 — 超出时截断省略号。数字单位为 px,字符串直接用作 CSS 值。
|
|
57
|
+
* 适合长字段名在固定宽度表单中防止换行影响布局。
|
|
58
|
+
* @default undefined
|
|
59
|
+
*/
|
|
60
|
+
maxWidth?: number | string;
|
|
61
|
+
/**
|
|
62
|
+
* 最小宽度(px) — 防止过度压缩,在响应式布局中保留可读宽度下限。
|
|
63
|
+
* @default undefined
|
|
64
|
+
*/
|
|
65
|
+
minWidth?: number;
|
|
37
66
|
}
|
|
38
67
|
|
|
39
68
|
const Label = React.forwardRef<
|
|
@@ -41,25 +70,68 @@ const Label = React.forwardRef<
|
|
|
41
70
|
LabelProps
|
|
42
71
|
>(
|
|
43
72
|
(
|
|
44
|
-
{
|
|
73
|
+
{
|
|
74
|
+
className,
|
|
75
|
+
style,
|
|
76
|
+
disabled = false,
|
|
77
|
+
required = false,
|
|
78
|
+
tooltip,
|
|
79
|
+
tooltipSide = 'top',
|
|
80
|
+
maxWidth,
|
|
81
|
+
minWidth,
|
|
82
|
+
children,
|
|
83
|
+
...props
|
|
84
|
+
},
|
|
45
85
|
ref,
|
|
46
|
-
) =>
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
{
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
86
|
+
) => {
|
|
87
|
+
const mergedStyle: React.CSSProperties = {
|
|
88
|
+
...style,
|
|
89
|
+
...(maxWidth !== undefined && {
|
|
90
|
+
maxWidth: typeof maxWidth === 'number' ? `${maxWidth}px` : maxWidth,
|
|
91
|
+
}),
|
|
92
|
+
...(minWidth !== undefined && { minWidth: `${minWidth}px` }),
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<LabelPrimitive.Root
|
|
97
|
+
ref={ref}
|
|
98
|
+
data-required={required ? '' : undefined}
|
|
99
|
+
style={mergedStyle}
|
|
100
|
+
className={cn(
|
|
101
|
+
labelVariants({ disabled }),
|
|
102
|
+
maxWidth !== undefined && 'truncate',
|
|
103
|
+
className,
|
|
104
|
+
)}
|
|
105
|
+
{...props}
|
|
106
|
+
>
|
|
107
|
+
<span className="inline-flex items-center gap-1 align-middle">
|
|
108
|
+
<span className={cn(maxWidth !== undefined && 'truncate')}>
|
|
109
|
+
{children}
|
|
110
|
+
</span>
|
|
111
|
+
{tooltip ? (
|
|
112
|
+
<TooltipProvider delayDuration={200}>
|
|
113
|
+
<TooltipRoot>
|
|
114
|
+
<TooltipTrigger asChild>
|
|
115
|
+
<Info
|
|
116
|
+
className="size-3.5 shrink-0 cursor-help text-muted-foreground transition-colors hover:text-foreground"
|
|
117
|
+
aria-hidden="true"
|
|
118
|
+
/>
|
|
119
|
+
</TooltipTrigger>
|
|
120
|
+
<TooltipContent side={tooltipSide}>
|
|
121
|
+
<p className="max-w-xs text-xs">{tooltip}</p>
|
|
122
|
+
</TooltipContent>
|
|
123
|
+
</TooltipRoot>
|
|
124
|
+
</TooltipProvider>
|
|
125
|
+
) : null}
|
|
126
|
+
{required ? (
|
|
127
|
+
<span className="shrink-0 text-destructive" aria-hidden="true">
|
|
128
|
+
*
|
|
129
|
+
</span>
|
|
130
|
+
) : null}
|
|
59
131
|
</span>
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
132
|
+
</LabelPrimitive.Root>
|
|
133
|
+
);
|
|
134
|
+
},
|
|
63
135
|
);
|
|
64
136
|
Label.displayName = 'Label';
|
|
65
137
|
|
|
@@ -3,7 +3,7 @@ id: masonry
|
|
|
3
3
|
name: Masonry
|
|
4
4
|
displayName: 瀑布流
|
|
5
5
|
type: component
|
|
6
|
-
category:
|
|
6
|
+
category: deprecated
|
|
7
7
|
since: 0.1.0
|
|
8
8
|
package: '@teamix-evo/ui'
|
|
9
9
|
---
|
|
@@ -27,30 +27,26 @@ package: '@teamix-evo/ui'
|
|
|
27
27
|
## Props
|
|
28
28
|
|
|
29
29
|
<!-- auto:props:begin -->
|
|
30
|
-
|
|
31
|
-
|
|
|
32
|
-
|
|
|
33
|
-
| `
|
|
34
|
-
| `gap` | `number` | `16` | – | 列间距(像素)。 |
|
|
35
|
-
|
|
30
|
+
| 名称 | 类型 | 默认值 | 必填 | 说明 |
|
|
31
|
+
| --- | --- | --- | --- | --- |
|
|
32
|
+
| `columns` | `number` | `3` | – | 列数(antd `columns` 并集) — 固定值或响应式断点配置 `{ default, sm, md, lg, xl }`。 **响应式注意**:本组件用 CSS `column-count`,断点匹配靠 Tailwind `@container` 不便, 简化为 fixed 列数。响应式建议直接在外层包 className(如 `md:columns-3 columns-2`)+ `columns={undefined}`。 |
|
|
33
|
+
| `gap` | `number` | `16` | – | 列间距(像素)。 |
|
|
36
34
|
<!-- auto:props:end -->
|
|
37
35
|
|
|
38
36
|
## 依赖
|
|
39
37
|
|
|
40
38
|
<!-- auto:deps:begin -->
|
|
41
|
-
|
|
42
39
|
### 同库依赖
|
|
43
40
|
|
|
44
41
|
> `teamix-evo ui add masonry` 时,以下 entry 会被自动连带安装(无需手动 add)。
|
|
45
42
|
|
|
46
|
-
| Entry | 类型 | 描述
|
|
47
|
-
|
|
|
48
|
-
| `cn`
|
|
43
|
+
| Entry | 类型 | 描述 |
|
|
44
|
+
| --- | --- | --- |
|
|
45
|
+
| `cn` | util | Tailwind className 合并工具(clsx + tailwind-merge) |
|
|
49
46
|
|
|
50
47
|
### npm 依赖
|
|
51
48
|
|
|
52
49
|
_无 — 本组件不依赖任何 npm 包。_
|
|
53
|
-
|
|
54
50
|
<!-- auto:deps:end -->
|
|
55
51
|
|
|
56
52
|
## AI 生成纪律
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
2
|
import { Masonry } from './masonry';
|
|
3
3
|
|
|
4
4
|
const meta: Meta<typeof Masonry> = {
|
|
5
|
-
title: '
|
|
5
|
+
title: '废弃 · Deprecated/Masonry',
|
|
6
6
|
component: Masonry,
|
|
7
7
|
tags: ['autodocs'],
|
|
8
8
|
parameters: {
|
|
9
9
|
docs: {
|
|
10
10
|
description: {
|
|
11
11
|
component:
|
|
12
|
-
'瀑布流 — CSS column-count + break-inside: avoid 的 0 JS 实现(图片墙 / 资讯卡片流 / Dashboard 卡片墙)。等价 antd `Masonry`(v6.0 新)。响应式建议外层 className 控制。',
|
|
12
|
+
'⚠️ **已废弃** — 仅 Storybook 留档,不通过 manifest 对外发布。\n\n瀑布流 — CSS column-count + break-inside: avoid 的 0 JS 实现(图片墙 / 资讯卡片流 / Dashboard 卡片墙)。等价 antd `Masonry`(v6.0 新)。响应式建议外层 className 控制。',
|
|
13
13
|
},
|
|
14
14
|
},
|
|
15
15
|
},
|
|
@@ -35,7 +35,7 @@ export const Playground: Story = {
|
|
|
35
35
|
{cards.map((c) => (
|
|
36
36
|
<div
|
|
37
37
|
key={c.id}
|
|
38
|
-
className="flex items-center justify-center rounded-md border bg-card text-sm"
|
|
38
|
+
className="flex items-center justify-center rounded-md border border-border bg-card text-sm"
|
|
39
39
|
style={{ height: c.h }}
|
|
40
40
|
>
|
|
41
41
|
{c.text}({c.h}px)
|
|
@@ -3,7 +3,7 @@ id: mentions
|
|
|
3
3
|
name: Mentions
|
|
4
4
|
displayName: 提及
|
|
5
5
|
type: component
|
|
6
|
-
category:
|
|
6
|
+
category: deprecated
|
|
7
7
|
since: 0.1.0
|
|
8
8
|
package: '@teamix-evo/ui'
|
|
9
9
|
---
|
|
@@ -25,39 +25,35 @@ package: '@teamix-evo/ui'
|
|
|
25
25
|
## Props
|
|
26
26
|
|
|
27
27
|
<!-- auto:props:begin -->
|
|
28
|
-
|
|
29
|
-
|
|
|
30
|
-
|
|
|
31
|
-
| `
|
|
32
|
-
| `
|
|
33
|
-
| `
|
|
34
|
-
| `
|
|
35
|
-
| `
|
|
36
|
-
| `
|
|
37
|
-
| `
|
|
38
|
-
| `
|
|
39
|
-
| `
|
|
40
|
-
| `disabled` | `boolean` | – | – | 禁用。 |
|
|
41
|
-
|
|
28
|
+
| 名称 | 类型 | 默认值 | 必填 | 说明 |
|
|
29
|
+
| --- | --- | --- | --- | --- |
|
|
30
|
+
| `options` | `MentionsOption[]` | – | ✓ | 候选项(antd `options` 并集)。 |
|
|
31
|
+
| `value` | `string` | – | – | 受控值。 |
|
|
32
|
+
| `defaultValue` | `string` | – | – | uncontrolled 初值。 |
|
|
33
|
+
| `onChange` | `(value: string) => void` | – | – | 文本变化回调。 |
|
|
34
|
+
| `prefix` | `string` | `"@"` | – | 触发符(antd `prefix` 并集) — 通常是 `@` 或 `#`。 |
|
|
35
|
+
| `split` | `string` | `" "` | – | 选中候选项后插入文本的尾随分隔(对齐 antd `split` 默认空格)。 |
|
|
36
|
+
| `onSearch` | `(query: string, prefix: string) => void` | – | – | 用户在 prefix 后输入时的搜索回调,用于业务侧异步刷新 `options`。 |
|
|
37
|
+
| `onSelect` | `(option: MentionsOption, prefix: string) => void` | – | – | 选中候选项时回调。 |
|
|
38
|
+
| `rows` | `number` | `3` | – | 文本框尺寸传透传 Textarea(行数)。 |
|
|
39
|
+
| `disabled` | `boolean` | – | – | 禁用。 |
|
|
42
40
|
<!-- auto:props:end -->
|
|
43
41
|
|
|
44
42
|
## 依赖
|
|
45
43
|
|
|
46
44
|
<!-- auto:deps:begin -->
|
|
47
|
-
|
|
48
45
|
### 同库依赖
|
|
49
46
|
|
|
50
47
|
> `teamix-evo ui add mentions` 时,以下 entry 会被自动连带安装(无需手动 add)。
|
|
51
48
|
|
|
52
|
-
| Entry
|
|
53
|
-
|
|
|
54
|
-
| `cn`
|
|
55
|
-
| `
|
|
49
|
+
| Entry | 类型 | 描述 |
|
|
50
|
+
| --- | --- | --- |
|
|
51
|
+
| `cn` | util | Tailwind className 合并工具(clsx + tailwind-merge) |
|
|
52
|
+
| `input` | component | 文本输入合集 — Input(单行 + prefix/suffix/clearable/showCount/addonBefore/addonAfter/size)+ Textarea(多行 + autoSize)+ InputGroup 系列(InputGroupAddon / InputGroupInput / InputGroupTextarea)三件合一,size 与 Button 同档(sm 24 / md 32 / lg 36) |
|
|
56
53
|
|
|
57
54
|
### npm 依赖
|
|
58
55
|
|
|
59
56
|
_无 — 本组件不依赖任何 npm 包。_
|
|
60
|
-
|
|
61
57
|
<!-- auto:deps:end -->
|
|
62
58
|
|
|
63
59
|
## AI 生成纪律
|
|
@@ -96,3 +92,28 @@ const [opts, setOpts] = React.useState(users);
|
|
|
96
92
|
|
|
97
93
|
// 双触发符:@ + # — 当前组件支持单 prefix,如需多触发请实例化两个 Mentions
|
|
98
94
|
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Mentions 形态 — 旧库无此组件
|
|
99
|
+
|
|
100
|
+
> 旧库(hybridcloud)不含 Mentions;本组件为**新库独有**,对齐 antd `Mentions` API 形态。
|
|
101
|
+
> 基于内置 Textarea + 自绘候选列表(无 portal);用 `prefix` 触发、`onSearch` 异步刷新、`onSelect` 埋点。
|
|
102
|
+
|
|
103
|
+
### antd Mentions 对齐表
|
|
104
|
+
|
|
105
|
+
| antd prop | 新库 prop | 备注 |
|
|
106
|
+
| ------------------- | ------------------ | --------------------------------------- |
|
|
107
|
+
| `options` | `options` | 结构一致 `{ value, label?, disabled? }` |
|
|
108
|
+
| `prefix` | `prefix` | 触发符,单字符 |
|
|
109
|
+
| `split` | `split` | 选中后尾随分隔,默认空格 |
|
|
110
|
+
| `onSearch` | `onSearch` | 异步刷新回调 |
|
|
111
|
+
| `onSelect` | `onSelect` | 选中回调 |
|
|
112
|
+
| `value / onChange` | `value / onChange` | 受控模式 |
|
|
113
|
+
| `defaultValue` | `defaultValue` | 非受控初值 |
|
|
114
|
+
| `disabled` | `disabled` | 整组禁用 |
|
|
115
|
+
| `rows` | `rows` | Textarea 行数(默认 3) |
|
|
116
|
+
| `placement` | 不支持 | 固定 bottom-left(级联层级场景不需调整) |
|
|
117
|
+
| `getPopupContainer` | 不支持 | 无 portal,列表就在组件内 relative 定位 |
|
|
118
|
+
| `filterOption` | 内置 includes | 如需自定义过滤逻辑,请在 onSearch 中做 |
|
|
119
|
+
| `validateSearch` | 不支持 | 低频 |
|
|
@@ -1,22 +1,24 @@
|
|
|
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 { Mentions } from './mentions';
|
|
4
4
|
|
|
5
5
|
const meta: Meta<typeof Mentions> = {
|
|
6
|
-
title: '
|
|
6
|
+
title: '废弃 · Deprecated/Mentions',
|
|
7
7
|
component: Mentions,
|
|
8
8
|
tags: ['autodocs'],
|
|
9
9
|
parameters: {
|
|
10
10
|
docs: {
|
|
11
11
|
description: {
|
|
12
12
|
component:
|
|
13
|
-
'
|
|
13
|
+
'⚠️ **已废弃** — 仅 Storybook 留档,不通过 manifest 对外发布。\n\n提及输入 —— 在多行文本中输入触发符(`@` / `#` / `/` 等)即弹出候选下拉,选中后插入 `@name<split>`,用于评论 @ 同事、# 话题、/ 命令等场景。基于 `Textarea` + 自定义 portal-less 候选层,等价 antd `Mentions`:`options` 候选、`prefix` 触发符、`split` 分隔、`onSearch` 异步刷新、`onSelect` 选中回调。键盘 ↑↓ 切换、Enter / Tab 选中、Esc 关闭;email 类 `a@b` 不会误触(触发符前必须为空白或行首)。视觉走 OpenTrek semantic tokens,所有样式来自 `@teamix-evo/tokens`,无 mock。',
|
|
14
14
|
},
|
|
15
15
|
},
|
|
16
16
|
},
|
|
17
17
|
argTypes: {
|
|
18
18
|
prefix: { control: 'text' },
|
|
19
19
|
placeholder: { control: 'text' },
|
|
20
|
+
rows: { control: { type: 'number', min: 1, max: 10 } },
|
|
21
|
+
disabled: { control: 'boolean' },
|
|
20
22
|
},
|
|
21
23
|
};
|
|
22
24
|
|
|
@@ -31,11 +33,27 @@ const users = [
|
|
|
31
33
|
];
|
|
32
34
|
|
|
33
35
|
export const Playground: Story = {
|
|
34
|
-
args: { placeholder: '输入 @ 提及同事...', options: users },
|
|
36
|
+
args: { placeholder: '输入 @ 提及同事...', options: users, rows: 3 },
|
|
37
|
+
parameters: {
|
|
38
|
+
docs: {
|
|
39
|
+
description: {
|
|
40
|
+
story:
|
|
41
|
+
'基础 @提及 —— 输入 `@` 触发,候选从 `options` 中按 query 过滤;键盘 ↑↓ + Enter 选中,Esc 关闭。',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
35
45
|
};
|
|
36
46
|
|
|
37
47
|
export const HashtagPrefix: Story = {
|
|
38
|
-
parameters: {
|
|
48
|
+
parameters: {
|
|
49
|
+
controls: { disable: true },
|
|
50
|
+
docs: {
|
|
51
|
+
description: {
|
|
52
|
+
story:
|
|
53
|
+
'自定义前缀 —— `prefix="#"` 用于话题标签场景。`prefix` 必须是单字符,多字符会与正文混淆。',
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
39
57
|
render: () => (
|
|
40
58
|
<Mentions
|
|
41
59
|
options={[
|
|
@@ -49,8 +67,35 @@ export const HashtagPrefix: Story = {
|
|
|
49
67
|
),
|
|
50
68
|
};
|
|
51
69
|
|
|
70
|
+
export const Multiline: Story = {
|
|
71
|
+
parameters: {
|
|
72
|
+
controls: { disable: true },
|
|
73
|
+
docs: {
|
|
74
|
+
description: {
|
|
75
|
+
story:
|
|
76
|
+
'多行场景 —— `rows={6}` 给到更长的输入区域。Enter 在候选打开时被消费(选中候选);候选关闭时回归原生换行 —— 这是预期行为。',
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
render: () => (
|
|
81
|
+
<Mentions
|
|
82
|
+
options={users}
|
|
83
|
+
rows={6}
|
|
84
|
+
placeholder={'多行评论:\n第一行...\n第二行 @ 提及同事...\n回车在候选打开时是"选中",关闭时是"换行"。'}
|
|
85
|
+
/>
|
|
86
|
+
),
|
|
87
|
+
};
|
|
88
|
+
|
|
52
89
|
export const AsyncSearch: Story = {
|
|
53
|
-
parameters: {
|
|
90
|
+
parameters: {
|
|
91
|
+
controls: { disable: true },
|
|
92
|
+
docs: {
|
|
93
|
+
description: {
|
|
94
|
+
story:
|
|
95
|
+
'异步候选 —— `onSearch(query, prefix)` 由消费侧拉接口刷新 `options`(组件不内置网络层)。下方实时显示当前候选数。',
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
},
|
|
54
99
|
render: () => {
|
|
55
100
|
const [opts, setOpts] = React.useState(users);
|
|
56
101
|
return (
|
|
@@ -73,3 +118,72 @@ export const AsyncSearch: Story = {
|
|
|
73
118
|
);
|
|
74
119
|
},
|
|
75
120
|
};
|
|
121
|
+
|
|
122
|
+
export const WithOnSelect: Story = {
|
|
123
|
+
parameters: {
|
|
124
|
+
controls: { disable: true },
|
|
125
|
+
docs: {
|
|
126
|
+
description: {
|
|
127
|
+
story:
|
|
128
|
+
'onSelect 回调 —— 在选中候选时记录最后一次选择。注意:`onSelect` 与 `onChange` 互不替代 —— 文本写入由 `onChange` 已经处理,`onSelect` 仅做埋点 / 业务联动。',
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
render: () => {
|
|
133
|
+
const [picked, setPicked] = React.useState<string | null>(null);
|
|
134
|
+
return (
|
|
135
|
+
<div className="flex flex-col gap-2">
|
|
136
|
+
<Mentions
|
|
137
|
+
options={users}
|
|
138
|
+
placeholder="选一个 @ 试试..."
|
|
139
|
+
onSelect={(opt, prefix) => setPicked(`${prefix}${opt.value}`)}
|
|
140
|
+
/>
|
|
141
|
+
<div className="text-xs text-muted-foreground">
|
|
142
|
+
上次选中:{' '}
|
|
143
|
+
<code className="rounded bg-muted px-1">{picked ?? '(无)'}</code>
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
);
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
export const DisabledOption: Story = {
|
|
151
|
+
parameters: {
|
|
152
|
+
controls: { disable: true },
|
|
153
|
+
docs: {
|
|
154
|
+
description: {
|
|
155
|
+
story:
|
|
156
|
+
'禁用候选项 —— 单个 option 的 `disabled` 会让它在下拉中变灰且不可选中(键盘跳过、点击无效)。',
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
render: () => (
|
|
161
|
+
<Mentions
|
|
162
|
+
options={[
|
|
163
|
+
{ value: 'alice', label: 'Alice (在线)' },
|
|
164
|
+
{ value: 'bob', label: 'Bob (离线)', disabled: true },
|
|
165
|
+
{ value: 'carol', label: 'Carol (在线)' },
|
|
166
|
+
]}
|
|
167
|
+
placeholder="@ 试试,Bob 不可选..."
|
|
168
|
+
/>
|
|
169
|
+
),
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
export const Disabled: Story = {
|
|
173
|
+
parameters: {
|
|
174
|
+
controls: { disable: true },
|
|
175
|
+
docs: {
|
|
176
|
+
description: {
|
|
177
|
+
story:
|
|
178
|
+
'整组禁用 —— `disabled` 透传 Textarea,既不可输入也不弹出候选。',
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
render: () => (
|
|
183
|
+
<Mentions
|
|
184
|
+
options={users}
|
|
185
|
+
defaultValue="@alice 这个评论已经被锁定..."
|
|
186
|
+
disabled
|
|
187
|
+
/>
|
|
188
|
+
),
|
|
189
|
+
};
|
|
@@ -72,7 +72,7 @@ function getTriggerContext(
|
|
|
72
72
|
if (ch === prefix) {
|
|
73
73
|
// The char immediately before prefix must be start-of-string / whitespace / newline,
|
|
74
74
|
// otherwise we'd trigger on emails like a@b.
|
|
75
|
-
const prev = i === 0 ? '' :
|
|
75
|
+
const prev = i === 0 ? '' : value[i - 1] ?? '';
|
|
76
76
|
if (prev === '' || /\s/.test(prev)) {
|
|
77
77
|
return { start: i, query: value.slice(i + 1, caret) };
|
|
78
78
|
}
|
|
@@ -107,7 +107,10 @@ const Mentions = React.forwardRef<HTMLTextAreaElement, MentionsProps>(
|
|
|
107
107
|
const current = isControlled ? value! : internal;
|
|
108
108
|
|
|
109
109
|
const innerRef = React.useRef<HTMLTextAreaElement | null>(null);
|
|
110
|
-
React.useImperativeHandle(
|
|
110
|
+
React.useImperativeHandle(
|
|
111
|
+
ref,
|
|
112
|
+
() => innerRef.current as HTMLTextAreaElement,
|
|
113
|
+
);
|
|
111
114
|
|
|
112
115
|
const [ctx, setCtx] = React.useState<TriggerCtx | null>(null);
|
|
113
116
|
const [activeIdx, setActiveIdx] = React.useState(0);
|
|
@@ -143,7 +146,7 @@ const Mentions = React.forwardRef<HTMLTextAreaElement, MentionsProps>(
|
|
|
143
146
|
const el = innerRef.current;
|
|
144
147
|
const before = current.slice(0, ctx.start);
|
|
145
148
|
const after = current.slice(
|
|
146
|
-
|
|
149
|
+
el?.selectionStart ?? ctx.start + 1 + ctx.query.length,
|
|
147
150
|
);
|
|
148
151
|
const inserted = `${prefix}${opt.value}${split}`;
|
|
149
152
|
const next = `${before}${inserted}${after}`;
|
|
@@ -206,7 +209,7 @@ const Mentions = React.forwardRef<HTMLTextAreaElement, MentionsProps>(
|
|
|
206
209
|
{ctx && filtered.length > 0 ? (
|
|
207
210
|
<ul
|
|
208
211
|
role="listbox"
|
|
209
|
-
className="absolute left-0 top-full z-50 mt-1 max-h-60 w-56 overflow-auto rounded-md border bg-popover p-1 text-
|
|
212
|
+
className="absolute left-0 top-full z-50 mt-1 max-h-60 w-56 overflow-auto rounded-md border border-border bg-popover p-1 text-xs text-popover-foreground shadow-md"
|
|
210
213
|
>
|
|
211
214
|
{filtered.map((opt, i) => (
|
|
212
215
|
<li
|
|
@@ -220,7 +223,9 @@ const Mentions = React.forwardRef<HTMLTextAreaElement, MentionsProps>(
|
|
|
220
223
|
onMouseEnter={() => setActiveIdx(i)}
|
|
221
224
|
className={cn(
|
|
222
225
|
'cursor-pointer rounded-sm px-2 py-1.5',
|
|
223
|
-
i === activeIdx &&
|
|
226
|
+
i === activeIdx &&
|
|
227
|
+
!opt.disabled &&
|
|
228
|
+
'bg-accent text-accent-foreground',
|
|
224
229
|
opt.disabled && 'cursor-not-allowed opacity-50',
|
|
225
230
|
)}
|
|
226
231
|
>
|
|
@@ -3,7 +3,7 @@ id: menubar
|
|
|
3
3
|
name: Menubar
|
|
4
4
|
displayName: 菜单栏
|
|
5
5
|
type: component
|
|
6
|
-
category:
|
|
6
|
+
category: deprecated
|
|
7
7
|
since: 0.1.0
|
|
8
8
|
package: '@teamix-evo/ui'
|
|
9
9
|
---
|
|
@@ -29,9 +29,7 @@ package: '@teamix-evo/ui'
|
|
|
29
29
|
> 以下表格由 `pnpm --filter @teamix-evo/ui gen:meta` 自动生成。下表是 `Menubar`(Root) 的 props。
|
|
30
30
|
|
|
31
31
|
<!-- auto:props:begin -->
|
|
32
|
-
|
|
33
32
|
_(组件无 `<Name>Props` interface — props 详见 [`menubar.tsx`](./menubar.tsx))_
|
|
34
|
-
|
|
35
33
|
<!-- auto:props:end -->
|
|
36
34
|
|
|
37
35
|
## 依赖
|
|
@@ -39,14 +37,13 @@ _(组件无 `<Name>Props` interface — props 详见 [`menubar.tsx`](./menubar.t
|
|
|
39
37
|
> 以下表格由 `pnpm --filter @teamix-evo/ui gen:meta` 自动生成,数据源是 [`manifest.json`](../../../manifest.json)。**手工编辑 marker 之间的内容会在下次生成时被覆盖**。
|
|
40
38
|
|
|
41
39
|
<!-- auto:deps:begin -->
|
|
42
|
-
|
|
43
40
|
### 同库依赖
|
|
44
41
|
|
|
45
42
|
> `teamix-evo ui add menubar` 时,以下 entry 会被自动连带安装(无需手动 add)。
|
|
46
43
|
|
|
47
|
-
| Entry | 类型 | 描述
|
|
48
|
-
|
|
|
49
|
-
| `cn`
|
|
44
|
+
| Entry | 类型 | 描述 |
|
|
45
|
+
| --- | --- | --- |
|
|
46
|
+
| `cn` | util | Tailwind className 合并工具(clsx + tailwind-merge) |
|
|
50
47
|
|
|
51
48
|
### npm 依赖
|
|
52
49
|
|
|
@@ -55,7 +52,6 @@ _(组件无 `<Name>Props` interface — props 详见 [`menubar.tsx`](./menubar.t
|
|
|
55
52
|
```bash
|
|
56
53
|
pnpm add @radix-ui/react-menubar@^1.1.0 lucide-react@^0.460.0
|
|
57
54
|
```
|
|
58
|
-
|
|
59
55
|
<!-- auto:deps:end -->
|
|
60
56
|
|
|
61
57
|
> 完整子组件:`Menubar` / `MenubarMenu` / `MenubarTrigger` / `MenubarContent` / `MenubarItem` / `MenubarCheckboxItem` / `MenubarRadioItem` / `MenubarLabel` / `MenubarSeparator` / `MenubarShortcut` / `MenubarSub` / `MenubarSubTrigger` / `MenubarSubContent` / `MenubarGroup` / `MenubarRadioGroup` / `MenubarPortal`。
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
3
|
import {
|
|
3
4
|
Menubar,
|
|
4
5
|
MenubarMenu,
|
|
@@ -10,17 +11,20 @@ import {
|
|
|
10
11
|
MenubarSub,
|
|
11
12
|
MenubarSubTrigger,
|
|
12
13
|
MenubarSubContent,
|
|
14
|
+
MenubarCheckboxItem,
|
|
15
|
+
MenubarRadioGroup,
|
|
16
|
+
MenubarRadioItem,
|
|
13
17
|
} from './menubar';
|
|
14
18
|
|
|
15
19
|
const meta: Meta<typeof Menubar> = {
|
|
16
|
-
title: '
|
|
20
|
+
title: '废弃 · Deprecated/Menubar',
|
|
17
21
|
component: Menubar,
|
|
18
22
|
tags: ['autodocs'],
|
|
19
23
|
parameters: {
|
|
20
24
|
docs: {
|
|
21
25
|
description: {
|
|
22
26
|
component:
|
|
23
|
-
'
|
|
27
|
+
'⚠️ **已废弃** — 仅 Storybook 留档,不通过 manifest 对外发布。\n\nMenubar 菜单栏 —— 在桌面应用或编辑器顶部带出 macOS 风格的“文件 / 编辑 / 视图 / 帮助”多一级菜单。Radix `Menubar` 内核 + shadcn 原子,**shadcn 专有、antd 未提供对应原子**,对齐 shadcn 的 `MenubarMenu` / `MenubarTrigger` / `MenubarContent` / `MenubarShortcut` / `MenubarSub` / `MenubarCheckboxItem` / `MenubarRadioItem`。视觉走 OpenTrek semantic tokens,所有样式来自 `@teamix-evo/tokens`,无 mock。',
|
|
24
28
|
},
|
|
25
29
|
},
|
|
26
30
|
},
|
|
@@ -87,3 +91,51 @@ export const Default: Story = {
|
|
|
87
91
|
</Menubar>
|
|
88
92
|
),
|
|
89
93
|
};
|
|
94
|
+
|
|
95
|
+
export const WithCheckboxAndRadio: Story = {
|
|
96
|
+
parameters: { controls: { disable: true } },
|
|
97
|
+
render: () => {
|
|
98
|
+
const [showStatus, setShowStatus] = React.useState(true);
|
|
99
|
+
const [showActivity, setShowActivity] = React.useState(false);
|
|
100
|
+
const [profile, setProfile] = React.useState('benoit');
|
|
101
|
+
return (
|
|
102
|
+
<Menubar>
|
|
103
|
+
<MenubarMenu>
|
|
104
|
+
<MenubarTrigger>视图</MenubarTrigger>
|
|
105
|
+
<MenubarContent>
|
|
106
|
+
<MenubarCheckboxItem checked={showStatus} onCheckedChange={setShowStatus}>
|
|
107
|
+
状态栏
|
|
108
|
+
</MenubarCheckboxItem>
|
|
109
|
+
<MenubarCheckboxItem checked={showActivity} onCheckedChange={setShowActivity}>
|
|
110
|
+
活动栏
|
|
111
|
+
</MenubarCheckboxItem>
|
|
112
|
+
<MenubarSeparator />
|
|
113
|
+
<MenubarRadioGroup value={profile} onValueChange={setProfile}>
|
|
114
|
+
<MenubarRadioItem value="benoit">Benoit</MenubarRadioItem>
|
|
115
|
+
<MenubarRadioItem value="colm">Colm</MenubarRadioItem>
|
|
116
|
+
<MenubarRadioItem value="hubert">Hubert</MenubarRadioItem>
|
|
117
|
+
</MenubarRadioGroup>
|
|
118
|
+
</MenubarContent>
|
|
119
|
+
</MenubarMenu>
|
|
120
|
+
</Menubar>
|
|
121
|
+
);
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export const DisabledItems: Story = {
|
|
126
|
+
parameters: { controls: { disable: true } },
|
|
127
|
+
render: () => (
|
|
128
|
+
<Menubar>
|
|
129
|
+
<MenubarMenu>
|
|
130
|
+
<MenubarTrigger>文件</MenubarTrigger>
|
|
131
|
+
<MenubarContent>
|
|
132
|
+
<MenubarItem>新建</MenubarItem>
|
|
133
|
+
<MenubarItem disabled>从模板新建(即将上线)</MenubarItem>
|
|
134
|
+
<MenubarSeparator />
|
|
135
|
+
<MenubarItem>保存</MenubarItem>
|
|
136
|
+
<MenubarItem disabled>发布到云端(未设置)</MenubarItem>
|
|
137
|
+
</MenubarContent>
|
|
138
|
+
</MenubarMenu>
|
|
139
|
+
</Menubar>
|
|
140
|
+
),
|
|
141
|
+
};
|