@teamix-evo/ui 0.7.0 → 0.7.2
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/manifest.json +16 -7
- package/package.json +4 -4
- package/src/_design-system/theme-tokens/stories.tsx +2 -2
- package/src/components/accordion/index.tsx +1 -1
- package/src/components/affix/meta.md +26 -0
- package/src/components/alert/index.tsx +2 -2
- package/src/components/alert-dialog/index.tsx +3 -3
- package/src/components/alert-dialog/meta.md +52 -0
- package/src/components/alert-dialog/stories.tsx +45 -48
- package/src/components/avatar/index.tsx +1 -1
- package/src/components/badge/index.tsx +2 -2
- package/src/components/badge/meta.md +48 -0
- package/src/components/button/index.tsx +2 -2
- package/src/components/button/meta.md +15 -0
- package/src/components/button/stories.tsx +1 -1
- package/src/components/calendar/index.tsx +2 -2
- package/src/components/card/index.tsx +1 -1
- package/src/components/carousel/index.tsx +2 -2
- package/src/components/carousel/meta.md +34 -2
- package/src/components/carousel/stories.tsx +2 -2
- package/src/components/cascader-select/index.tsx +2 -1
- package/src/components/cascader-select/meta.md +46 -0
- package/src/components/checkbox/meta.md +47 -0
- package/src/components/color-picker/index.tsx +3 -3
- package/src/components/color-picker/meta.md +80 -0
- package/src/components/combobox/index.tsx +2 -2
- package/src/components/combobox/meta.md +130 -0
- package/src/components/data-table/index.tsx +3 -3
- package/src/components/data-table/meta.md +419 -0
- package/src/components/data-table/stories.tsx +4 -4
- package/src/components/date-picker/meta.md +91 -0
- package/src/components/descriptions/index.tsx +1 -1
- package/src/components/descriptions/meta.md +245 -0
- package/src/components/dialog/index.tsx +4 -4
- package/src/components/dialog/meta.md +47 -1
- package/src/components/dialog/stories.tsx +38 -41
- package/src/components/dropdown-menu/index.tsx +5 -5
- package/src/components/empty/index.tsx +2 -2
- package/src/components/field/index.tsx +4 -4
- package/src/components/filter-bar/index.tsx +6 -6
- package/src/components/filter-bar/meta.md +323 -0
- package/src/components/float-button/index.tsx +2 -2
- package/src/components/form/index.tsx +1 -1
- package/src/components/form/meta.md +119 -0
- package/src/components/hover-card/index.tsx +1 -1
- package/src/components/hover-card/meta.md +21 -0
- package/src/components/input/meta.md +16 -0
- package/src/components/input-group/index.tsx +1 -1
- package/src/components/input-group/meta.md +118 -0
- package/src/components/input-group/stories.tsx +6 -6
- package/src/components/input-ip/index.tsx +2 -2
- package/src/components/input-ip/meta.md +30 -0
- package/src/components/input-ip/stories.tsx +2 -2
- package/src/components/input-number/index.tsx +3 -2
- package/src/components/input-number/meta.md +67 -0
- package/src/components/input-number/stories.tsx +2 -2
- package/src/components/item/index.tsx +4 -4
- package/src/components/label/meta.md +8 -0
- package/src/components/mentions/meta.md +15 -0
- package/src/components/menubar/index.tsx +4 -4
- package/src/components/navigation-menu/index.tsx +4 -4
- package/src/components/page-header/index.tsx +2 -2
- package/src/components/page-header/meta.md +145 -0
- package/src/components/page-shell/index.tsx +3 -3
- package/src/components/pagination/index.tsx +1 -1
- package/src/components/pagination/meta.md +203 -0
- package/src/components/popconfirm/meta.md +45 -0
- package/src/components/popover/index.tsx +2 -2
- package/src/components/popover/meta.md +47 -0
- package/src/components/progress/index.tsx +1 -1
- package/src/components/progress/meta.md +36 -0
- package/src/components/progress/stories.tsx +1 -1
- package/src/components/radio-group/meta.md +69 -0
- package/src/components/rate/index.tsx +1 -1
- package/src/components/rate/meta.md +50 -0
- package/src/components/resizable/index.tsx +1 -1
- package/src/components/select/index.tsx +2 -2
- package/src/components/select/meta.md +20 -0
- package/src/components/separator/index.tsx +1 -1
- package/src/components/sheet/index.tsx +13 -14
- package/src/components/sheet/meta.md +124 -0
- package/src/components/sheet/stories.tsx +110 -119
- package/src/components/sidebar/index.tsx +5 -5
- package/src/components/sidebar/meta.md +383 -0
- package/src/components/skeleton/meta.md +13 -0
- package/src/components/slider/index.tsx +2 -2
- package/src/components/sonner/meta.md +86 -0
- package/src/components/spinner/meta.md +46 -0
- package/src/components/spinner/stories.tsx +2 -2
- package/src/components/steps/meta.md +20 -0
- package/src/components/steps/stories.tsx +1 -1
- package/src/components/switch/index.tsx +2 -2
- package/src/components/switch/meta.md +33 -0
- package/src/components/table/index.tsx +4 -4
- package/src/components/table/meta.md +11 -0
- package/src/components/tabs/index.tsx +7 -7
- package/src/components/tabs/meta.md +52 -0
- package/src/components/tag/index.tsx +8 -8
- package/src/components/tag/meta.md +194 -0
- package/src/components/textarea/index.tsx +1 -1
- package/src/components/textarea/meta.md +27 -0
- package/src/components/textarea/stories.tsx +1 -1
- package/src/components/time-picker/index.tsx +3 -3
- package/src/components/time-picker/meta.md +76 -0
- package/src/components/timeline/index.tsx +1 -0
- package/src/components/toggle/index.tsx +1 -1
- package/src/components/toggle-group/index.tsx +1 -1
- package/src/components/tooltip/index.tsx +1 -1
- package/src/components/tooltip/meta.md +23 -0
- package/src/components/transfer/index.tsx +2 -2
- package/src/components/transfer/meta.md +97 -0
- package/src/components/tree/index.tsx +245 -15
- package/src/components/tree/meta.md +151 -0
- package/src/components/tree-select/index.tsx +16 -2
- package/src/components/tree-select/meta.md +150 -0
- package/src/components/typography/index.tsx +3 -3
- package/src/components/upload/index.tsx +3 -3
- package/src/components/upload/meta.md +82 -0
- package/src/components/tree/utils.ts +0 -269
- package/src/examples/built-in-assets/stories.tsx +0 -572
- package/src/examples/evaluators/stories.tsx +0 -502
|
@@ -76,7 +76,7 @@ function SheetOverlay({
|
|
|
76
76
|
<SheetPrimitive.Overlay
|
|
77
77
|
data-slot="sheet-overlay"
|
|
78
78
|
className={cn(
|
|
79
|
-
'fixed inset-0 z-50 bg-black/10 duration-100
|
|
79
|
+
'fixed inset-0 z-50 bg-black/10 duration-100 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0 supports-backdrop-filter:backdrop-blur-xs',
|
|
80
80
|
className,
|
|
81
81
|
)}
|
|
82
82
|
{...props}
|
|
@@ -131,26 +131,26 @@ function SheetContent({
|
|
|
131
131
|
className={cn(
|
|
132
132
|
// 基础布局:fixed 定位 + flex 列容器 + token 化阴影(抽屉与背景的边界由阴影表达,不画 border)
|
|
133
133
|
// eslint-disable-next-line teamix-evo/no-arbitrary-tw-value -- box-shadow 走 component-level token --drawer-shadow,按 ADR 0026 在源码内显式声明。
|
|
134
|
-
'fixed z-50 flex flex-col bg-popover text-xs text-popover-foreground shadow-[var(--drawer-shadow,0px_0px_24px_0px_rgba(0,0,0,0.1))] transition ease-in-out outline-none data-[state=
|
|
134
|
+
'fixed z-50 flex flex-col bg-popover text-xs text-popover-foreground shadow-[var(--drawer-shadow,0px_0px_24px_0px_rgba(0,0,0,0.1))] transition ease-in-out outline-none data-[state=closed]:animate-out data-[state=closed]:duration-200 data-[state=open]:animate-in data-[state=open]:duration-300',
|
|
135
135
|
// 4 向定位(不加 border)
|
|
136
|
-
'data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:
|
|
137
|
-
'data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:
|
|
136
|
+
'data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:size-full',
|
|
137
|
+
'data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:size-full',
|
|
138
138
|
'data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:w-full',
|
|
139
139
|
'data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:w-full',
|
|
140
140
|
// 4 向滑入滑出动画
|
|
141
|
-
'data-[side=right]:data-[state=
|
|
142
|
-
'data-[side=left]:data-[state=
|
|
143
|
-
'data-[side=top]:data-[state=
|
|
144
|
-
'data-[side=bottom]:data-[state=
|
|
141
|
+
'data-[side=right]:data-[state=closed]:slide-out-to-right data-[side=right]:data-[state=open]:slide-in-from-right',
|
|
142
|
+
'data-[side=left]:data-[state=closed]:slide-out-to-left data-[side=left]:data-[state=open]:slide-in-from-left',
|
|
143
|
+
'data-[side=top]:data-[state=closed]:slide-out-to-top data-[side=top]:data-[state=open]:slide-in-from-top',
|
|
144
|
+
'data-[side=bottom]:data-[state=closed]:slide-out-to-bottom data-[side=bottom]:data-[state=open]:slide-in-from-bottom',
|
|
145
145
|
// size 档位:left/right 控宽,top/bottom 控高(sm 断点以上生效,移动端默认贴边全屏)
|
|
146
146
|
// eslint-disable-next-line teamix-evo/no-arbitrary-tw-value -- 像素值对齐 cloud-design Drawer mini/small/medium/large 视觉档位 (400/600/800/1200);通过 component-level token 表达过于碎片化,按 ADR 0026 在源码内显式声明。
|
|
147
|
-
'data-[side=left]:data-[size=
|
|
147
|
+
'data-[side=left]:data-[size=lg]:sm:max-w-[800px] data-[side=left]:data-[size=md]:sm:max-w-[600px] data-[side=left]:data-[size=sm]:sm:max-w-[400px] data-[side=left]:data-[size=xl]:sm:max-w-[1200px]',
|
|
148
148
|
// eslint-disable-next-line teamix-evo/no-arbitrary-tw-value -- 同上,对齐 cloud-design Drawer 视觉档位。
|
|
149
|
-
'data-[side=right]:data-[size=
|
|
149
|
+
'data-[side=right]:data-[size=lg]:sm:max-w-[800px] data-[side=right]:data-[size=md]:sm:max-w-[600px] data-[side=right]:data-[size=sm]:sm:max-w-[400px] data-[side=right]:data-[size=xl]:sm:max-w-[1200px]',
|
|
150
150
|
// eslint-disable-next-line teamix-evo/no-arbitrary-tw-value -- top/bottom 方向 size 控高度,对齐视觉档位。
|
|
151
|
-
'data-[side=top]:data-[size=
|
|
151
|
+
'data-[side=top]:data-[size=lg]:max-h-[560px] data-[side=top]:data-[size=md]:max-h-[400px] data-[side=top]:data-[size=sm]:max-h-[280px] data-[side=top]:data-[size=xl]:max-h-[80vh]',
|
|
152
152
|
// eslint-disable-next-line teamix-evo/no-arbitrary-tw-value -- 同上。
|
|
153
|
-
'data-[side=bottom]:data-[size=
|
|
153
|
+
'data-[side=bottom]:data-[size=lg]:max-h-[560px] data-[side=bottom]:data-[size=md]:max-h-[400px] data-[side=bottom]:data-[size=sm]:max-h-[280px] data-[side=bottom]:data-[size=xl]:max-h-[80vh]',
|
|
154
154
|
className,
|
|
155
155
|
)}
|
|
156
156
|
{...props}
|
|
@@ -182,7 +182,7 @@ function SheetHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
|
|
182
182
|
<div
|
|
183
183
|
data-slot="sheet-header"
|
|
184
184
|
className={cn(
|
|
185
|
-
'flex flex-col gap-1.5 border-b border-border
|
|
185
|
+
'flex flex-col gap-1.5 border-b border-border px-5 py-3 has-data-[slot=sheet-header-extra]:grid has-data-[slot=sheet-header-extra]:grid-cols-[1fr_auto] has-data-[slot=sheet-header-extra]:items-start has-data-[slot=sheet-header-extra]:gap-x-3 has-data-[slot=sheet-header-extra]:pr-14',
|
|
186
186
|
className,
|
|
187
187
|
)}
|
|
188
188
|
{...props}
|
|
@@ -245,7 +245,6 @@ function SheetFooter({ className, ...props }: React.ComponentProps<'div'>) {
|
|
|
245
245
|
<div
|
|
246
246
|
data-slot="sheet-footer"
|
|
247
247
|
className={cn(
|
|
248
|
-
// eslint-disable-next-line teamix-evo/no-bare-border -- border-footer-separator 是 @theme 声明的语义 token,已加入 lint-core 白名单
|
|
249
248
|
'flex flex-col gap-2 border-t border-footer-separator px-4 py-2.5 sm:flex-row sm:justify-start',
|
|
250
249
|
className,
|
|
251
250
|
)}
|
|
@@ -66,6 +66,40 @@
|
|
|
66
66
|
</div>
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
+
### Placement
|
|
70
|
+
|
|
71
|
+
自定义弹出方向 — 4 向 side 切换。
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
<div className="flex flex-col gap-3">
|
|
75
|
+
<RadioGroup
|
|
76
|
+
value={side}
|
|
77
|
+
onValueChange={(v) => setSide(v as typeof side)}
|
|
78
|
+
className="flex flex-row gap-4"
|
|
79
|
+
>
|
|
80
|
+
{(['right', 'bottom', 'left', 'top'] as const).map((p) => (
|
|
81
|
+
<div key={p} className="flex items-center gap-1.5">
|
|
82
|
+
<RadioGroupItem value={p} id={`side-${p}`} />
|
|
83
|
+
<Label htmlFor={`side-${p}`}>{p}</Label>
|
|
84
|
+
</div>
|
|
85
|
+
))}
|
|
86
|
+
</RadioGroup>
|
|
87
|
+
<Sheet>
|
|
88
|
+
<SheetTrigger asChild>
|
|
89
|
+
<Button>打开 {side} 方向</Button>
|
|
90
|
+
</SheetTrigger>
|
|
91
|
+
<SheetContent side={side}>
|
|
92
|
+
<SheetHeader>
|
|
93
|
+
<SheetTitle>标题</SheetTitle>
|
|
94
|
+
</SheetHeader>
|
|
95
|
+
<SheetBody>
|
|
96
|
+
Start your business here by searching a popular product
|
|
97
|
+
</SheetBody>
|
|
98
|
+
</SheetContent>
|
|
99
|
+
</Sheet>
|
|
100
|
+
</div>
|
|
101
|
+
```
|
|
102
|
+
|
|
69
103
|
### WithExtra
|
|
70
104
|
|
|
71
105
|
Header 附加内容 — 通过 SheetHeaderExtra 放置帮助链接 / 次要操作。
|
|
@@ -199,6 +233,96 @@ Header 附加内容 — 通过 SheetHeaderExtra 放置帮助链接 / 次要操
|
|
|
199
233
|
</Sheet>
|
|
200
234
|
```
|
|
201
235
|
|
|
236
|
+
### Nested
|
|
237
|
+
|
|
238
|
+
双层抽屉 — 抽屉内打开新的抽屉,对应 cloud-design Drawer 的 double demo。
|
|
239
|
+
|
|
240
|
+
```tsx
|
|
241
|
+
<>
|
|
242
|
+
<Button onClick={() => setOuter(true)}>Open drawer</Button>
|
|
243
|
+
<Sheet open={outer} onOpenChange={setOuter}>
|
|
244
|
+
<SheetContent size="md">
|
|
245
|
+
<SheetHeader>
|
|
246
|
+
<SheetTitle>Multi-level drawer</SheetTitle>
|
|
247
|
+
</SheetHeader>
|
|
248
|
+
<SheetBody>
|
|
249
|
+
<Button onClick={() => setInner(true)}>Two-level drawer</Button>
|
|
250
|
+
<div className="mt-10 flex flex-col gap-2">
|
|
251
|
+
{Array.from({ length: 20 }).map((_, i) => (
|
|
252
|
+
<p key={i}>很长的内容 {i + 1}</p>
|
|
253
|
+
))}
|
|
254
|
+
<p>底部的内容</p>
|
|
255
|
+
</div>
|
|
256
|
+
</SheetBody>
|
|
257
|
+
<SheetFooter className="border-border">
|
|
258
|
+
<Button onClick={() => setOuter(false)}>Submit</Button>
|
|
259
|
+
<Button variant="outline" onClick={() => setOuter(false)}>
|
|
260
|
+
Cancel
|
|
261
|
+
</Button>
|
|
262
|
+
</SheetFooter>
|
|
263
|
+
<Sheet open={inner} onOpenChange={setInner}>
|
|
264
|
+
<SheetContent size="sm">
|
|
265
|
+
<SheetHeader>
|
|
266
|
+
<SheetTitle>Two-level Drawer</SheetTitle>
|
|
267
|
+
</SheetHeader>
|
|
268
|
+
<SheetBody>This is two-level drawer</SheetBody>
|
|
269
|
+
</SheetContent>
|
|
270
|
+
</Sheet>
|
|
271
|
+
</SheetContent>
|
|
272
|
+
</Sheet>
|
|
273
|
+
</>
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Controlled
|
|
277
|
+
|
|
278
|
+
受控异步关闭 — onOpenChange 在 loading 期间拦截关闭,按钮 loading 期间禁止外部交互。
|
|
279
|
+
|
|
280
|
+
```tsx
|
|
281
|
+
const [open, setOpen] = React.useState(false);
|
|
282
|
+
const [loading, setLoading] = React.useState(false);
|
|
283
|
+
const onConfirm = async () => {
|
|
284
|
+
setLoading(true);
|
|
285
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
286
|
+
setLoading(false);
|
|
287
|
+
setOpen(false);
|
|
288
|
+
};
|
|
289
|
+
return (
|
|
290
|
+
<Sheet
|
|
291
|
+
open={open}
|
|
292
|
+
onOpenChange={(next) => {
|
|
293
|
+
if (loading) return;
|
|
294
|
+
setOpen(next);
|
|
295
|
+
}}
|
|
296
|
+
>
|
|
297
|
+
<SheetTrigger asChild>
|
|
298
|
+
<Button>打开</Button>
|
|
299
|
+
</SheetTrigger>
|
|
300
|
+
<SheetContent
|
|
301
|
+
size="sm"
|
|
302
|
+
onPointerDownOutside={(e) => loading && e.preventDefault()}
|
|
303
|
+
onEscapeKeyDown={(e) => loading && e.preventDefault()}
|
|
304
|
+
>
|
|
305
|
+
<SheetHeader>
|
|
306
|
+
<SheetTitle>确认提交?</SheetTitle>
|
|
307
|
+
</SheetHeader>
|
|
308
|
+
<SheetBody>
|
|
309
|
+
<p>提交期间无法点击遮罩或按 ESC 关闭。</p>
|
|
310
|
+
</SheetBody>
|
|
311
|
+
<SheetFooter>
|
|
312
|
+
<Button loading={loading} onClick={onConfirm}>
|
|
313
|
+
确认
|
|
314
|
+
</Button>
|
|
315
|
+
<SheetClose asChild>
|
|
316
|
+
<Button variant="outline" disabled={loading}>
|
|
317
|
+
取消
|
|
318
|
+
</Button>
|
|
319
|
+
</SheetClose>
|
|
320
|
+
</SheetFooter>
|
|
321
|
+
</SheetContent>
|
|
322
|
+
</Sheet>
|
|
323
|
+
);
|
|
324
|
+
```
|
|
325
|
+
|
|
202
326
|
### NoCloseButton
|
|
203
327
|
|
|
204
328
|
隐藏关闭按钮 — 强制通过底部操作关闭,常用于流程类强引导。
|
|
@@ -107,41 +107,38 @@ export const Sizes: Story = {
|
|
|
107
107
|
export const Placement: Story = {
|
|
108
108
|
name: '弹出方向 side',
|
|
109
109
|
render: () => {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
<
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
{
|
|
122
|
-
<
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
<
|
|
129
|
-
<
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
<
|
|
133
|
-
<
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
);
|
|
143
|
-
}
|
|
144
|
-
return <Demo />;
|
|
110
|
+
const [side, setSide] = React.useState<
|
|
111
|
+
'top' | 'right' | 'bottom' | 'left'
|
|
112
|
+
>('right');
|
|
113
|
+
return (
|
|
114
|
+
<div className="flex flex-col gap-3">
|
|
115
|
+
<RadioGroup
|
|
116
|
+
value={side}
|
|
117
|
+
onValueChange={(v) => setSide(v as typeof side)}
|
|
118
|
+
className="flex flex-row gap-4"
|
|
119
|
+
>
|
|
120
|
+
{(['right', 'bottom', 'left', 'top'] as const).map((p) => (
|
|
121
|
+
<div key={p} className="flex items-center gap-1.5">
|
|
122
|
+
<RadioGroupItem value={p} id={`side-${p}`} />
|
|
123
|
+
<Label htmlFor={`side-${p}`}>{p}</Label>
|
|
124
|
+
</div>
|
|
125
|
+
))}
|
|
126
|
+
</RadioGroup>
|
|
127
|
+
<Sheet>
|
|
128
|
+
<SheetTrigger asChild>
|
|
129
|
+
<Button>打开 {side} 方向</Button>
|
|
130
|
+
</SheetTrigger>
|
|
131
|
+
<SheetContent side={side}>
|
|
132
|
+
<SheetHeader>
|
|
133
|
+
<SheetTitle>标题</SheetTitle>
|
|
134
|
+
</SheetHeader>
|
|
135
|
+
<SheetBody>
|
|
136
|
+
Start your business here by searching a popular product
|
|
137
|
+
</SheetBody>
|
|
138
|
+
</SheetContent>
|
|
139
|
+
</Sheet>
|
|
140
|
+
</div>
|
|
141
|
+
);
|
|
145
142
|
},
|
|
146
143
|
};
|
|
147
144
|
|
|
@@ -282,46 +279,43 @@ export const LargeContent: Story = {
|
|
|
282
279
|
export const Nested: Story = {
|
|
283
280
|
name: '双层抽屉',
|
|
284
281
|
render: () => {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
<
|
|
292
|
-
<
|
|
293
|
-
<
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
<
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
{
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
<
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
<
|
|
312
|
-
<
|
|
313
|
-
<
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
);
|
|
323
|
-
}
|
|
324
|
-
return <Demo />;
|
|
282
|
+
const [outer, setOuter] = React.useState(false);
|
|
283
|
+
const [inner, setInner] = React.useState(false);
|
|
284
|
+
return (
|
|
285
|
+
<>
|
|
286
|
+
<Button onClick={() => setOuter(true)}>Open drawer</Button>
|
|
287
|
+
<Sheet open={outer} onOpenChange={setOuter}>
|
|
288
|
+
<SheetContent size="md">
|
|
289
|
+
<SheetHeader>
|
|
290
|
+
<SheetTitle>Multi-level drawer</SheetTitle>
|
|
291
|
+
</SheetHeader>
|
|
292
|
+
<SheetBody>
|
|
293
|
+
<Button onClick={() => setInner(true)}>Two-level drawer</Button>
|
|
294
|
+
<div className="mt-10 flex flex-col gap-2">
|
|
295
|
+
{Array.from({ length: 20 }).map((_, i) => (
|
|
296
|
+
<p key={i}>很长的内容 {i + 1}</p>
|
|
297
|
+
))}
|
|
298
|
+
<p>底部的内容</p>
|
|
299
|
+
</div>
|
|
300
|
+
</SheetBody>
|
|
301
|
+
<SheetFooter className="border-border">
|
|
302
|
+
<Button onClick={() => setOuter(false)}>Submit</Button>
|
|
303
|
+
<Button variant="outline" onClick={() => setOuter(false)}>
|
|
304
|
+
Cancel
|
|
305
|
+
</Button>
|
|
306
|
+
</SheetFooter>
|
|
307
|
+
<Sheet open={inner} onOpenChange={setInner}>
|
|
308
|
+
<SheetContent size="sm">
|
|
309
|
+
<SheetHeader>
|
|
310
|
+
<SheetTitle>Two-level Drawer</SheetTitle>
|
|
311
|
+
</SheetHeader>
|
|
312
|
+
<SheetBody>This is two-level drawer</SheetBody>
|
|
313
|
+
</SheetContent>
|
|
314
|
+
</Sheet>
|
|
315
|
+
</SheetContent>
|
|
316
|
+
</Sheet>
|
|
317
|
+
</>
|
|
318
|
+
);
|
|
325
319
|
},
|
|
326
320
|
};
|
|
327
321
|
|
|
@@ -329,52 +323,49 @@ export const Nested: Story = {
|
|
|
329
323
|
export const Controlled: Story = {
|
|
330
324
|
name: '受控异步',
|
|
331
325
|
render: () => {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
326
|
+
const [open, setOpen] = React.useState(false);
|
|
327
|
+
const [loading, setLoading] = React.useState(false);
|
|
328
|
+
const onConfirm = async () => {
|
|
329
|
+
setLoading(true);
|
|
330
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
331
|
+
setLoading(false);
|
|
332
|
+
setOpen(false);
|
|
333
|
+
};
|
|
334
|
+
return (
|
|
335
|
+
<Sheet
|
|
336
|
+
open={open}
|
|
337
|
+
onOpenChange={(next) => {
|
|
338
|
+
if (loading) return;
|
|
339
|
+
setOpen(next);
|
|
340
|
+
}}
|
|
341
|
+
>
|
|
342
|
+
<SheetTrigger asChild>
|
|
343
|
+
<Button>打开</Button>
|
|
344
|
+
</SheetTrigger>
|
|
345
|
+
<SheetContent
|
|
346
|
+
size="sm"
|
|
347
|
+
onPointerDownOutside={(e) => loading && e.preventDefault()}
|
|
348
|
+
onEscapeKeyDown={(e) => loading && e.preventDefault()}
|
|
348
349
|
>
|
|
349
|
-
<
|
|
350
|
-
<
|
|
351
|
-
</
|
|
352
|
-
<
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
</SheetBody>
|
|
363
|
-
<SheetFooter>
|
|
364
|
-
<Button loading={loading} onClick={onConfirm}>
|
|
365
|
-
确认
|
|
350
|
+
<SheetHeader>
|
|
351
|
+
<SheetTitle>确认提交?</SheetTitle>
|
|
352
|
+
</SheetHeader>
|
|
353
|
+
<SheetBody>
|
|
354
|
+
<p>提交期间无法点击遮罩或按 ESC 关闭。</p>
|
|
355
|
+
</SheetBody>
|
|
356
|
+
<SheetFooter>
|
|
357
|
+
<Button loading={loading} onClick={onConfirm}>
|
|
358
|
+
确认
|
|
359
|
+
</Button>
|
|
360
|
+
<SheetClose asChild>
|
|
361
|
+
<Button variant="outline" disabled={loading}>
|
|
362
|
+
取消
|
|
366
363
|
</Button>
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
</SheetFooter>
|
|
373
|
-
</SheetContent>
|
|
374
|
-
</Sheet>
|
|
375
|
-
);
|
|
376
|
-
}
|
|
377
|
-
return <Demo />;
|
|
364
|
+
</SheetClose>
|
|
365
|
+
</SheetFooter>
|
|
366
|
+
</SheetContent>
|
|
367
|
+
</Sheet>
|
|
368
|
+
);
|
|
378
369
|
},
|
|
379
370
|
};
|
|
380
371
|
|
|
@@ -211,7 +211,7 @@ function Sidebar({
|
|
|
211
211
|
<SheetTitle>Sidebar</SheetTitle>
|
|
212
212
|
<SheetDescription>Displays the mobile sidebar.</SheetDescription>
|
|
213
213
|
</SheetHeader>
|
|
214
|
-
<div className="flex
|
|
214
|
+
<div className="flex size-full flex-col">{children}</div>
|
|
215
215
|
</SheetContent>
|
|
216
216
|
</Sheet>
|
|
217
217
|
);
|
|
@@ -246,7 +246,7 @@ function Sidebar({
|
|
|
246
246
|
// Adjust the padding for floating and inset variants.
|
|
247
247
|
variant === 'floating' || variant === 'inset'
|
|
248
248
|
? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]'
|
|
249
|
-
: 'group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l
|
|
249
|
+
: 'border-sidebar-border group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l',
|
|
250
250
|
className,
|
|
251
251
|
)}
|
|
252
252
|
{...props}
|
|
@@ -479,7 +479,7 @@ function SidebarMenuItem({ className, ...props }: React.ComponentProps<'li'>) {
|
|
|
479
479
|
}
|
|
480
480
|
|
|
481
481
|
const sidebarMenuButtonVariants = cva(
|
|
482
|
-
'peer/menu-button group/menu-button flex w-full cursor-pointer items-center gap-2 overflow-hidden rounded-md p-2 text-left text-xs ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:cursor-not-allowed aria-disabled:opacity-50 data-[
|
|
482
|
+
'peer/menu-button group/menu-button flex w-full cursor-pointer items-center gap-2 overflow-hidden rounded-md p-2 text-left text-xs ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:cursor-not-allowed aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate',
|
|
483
483
|
{
|
|
484
484
|
variants: {
|
|
485
485
|
variant: {
|
|
@@ -585,7 +585,7 @@ function SidebarMenuBadge({
|
|
|
585
585
|
data-slot="sidebar-menu-badge"
|
|
586
586
|
data-sidebar="menu-badge"
|
|
587
587
|
className={cn(
|
|
588
|
-
'pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium text-sidebar-foreground tabular-nums select-none group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[
|
|
588
|
+
'pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium text-sidebar-foreground tabular-nums select-none group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1',
|
|
589
589
|
className,
|
|
590
590
|
)}
|
|
591
591
|
{...props}
|
|
@@ -637,7 +637,7 @@ function SidebarMenuSub({ className, ...props }: React.ComponentProps<'ul'>) {
|
|
|
637
637
|
data-slot="sidebar-menu-sub"
|
|
638
638
|
data-sidebar="menu-sub"
|
|
639
639
|
className={cn(
|
|
640
|
-
'ml-4 flex min-w-0 flex-col gap-1
|
|
640
|
+
'ml-4 flex min-w-0 flex-col gap-1 py-0.5 pl-4 group-data-[collapsible=icon]:hidden',
|
|
641
641
|
className,
|
|
642
642
|
)}
|
|
643
643
|
{...props}
|