@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,13 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: calendar
|
|
3
3
|
name: Calendar
|
|
4
|
+
displayName: 日历
|
|
4
5
|
type: component
|
|
5
|
-
category:
|
|
6
|
+
category: data-display
|
|
6
7
|
since: 0.1.0
|
|
7
8
|
package: '@teamix-evo/ui'
|
|
8
9
|
---
|
|
9
10
|
|
|
10
|
-
# Calendar
|
|
11
|
+
# Calendar 日历
|
|
11
12
|
|
|
12
13
|
日期选择面板 — 基于 [`react-day-picker`](https://react-day-picker.js.org/),与 design tokens 对齐。
|
|
13
14
|
**两种用法**:
|
|
@@ -37,6 +38,15 @@ package: '@teamix-evo/ui'
|
|
|
37
38
|
| `className` | `string` | – | – | 容器 className。组件内部默认带 `p-3`,会与传入值自动 merge。 |
|
|
38
39
|
| `classNames` | `DayPickerProps['classNames']` | – | – | 覆盖底层 react-day-picker 的 classNames slots(深度自定义日格 / 表头 / 导航等)。 |
|
|
39
40
|
| `showOutsideDays` | `boolean` | `true` | – | 是否显示当月范围外的日期(灰色填充,占位补齐周表格)。 |
|
|
41
|
+
| `mode` | `DayPickerProps['mode']` | `"single"` | – | 选择模式 — `'single'` 单选(`selected: Date`)/ `'multiple'` 多选(`selected: Date[]`) / `'range'` 范围(`selected: DateRange`)。 |
|
|
42
|
+
| `numberOfMonths` | `number` | `1` | – | 受控已选值 — 类型随 `mode` 变化: - `single` → `Date \| undefined` - `multiple` → `Date[]` - `range` → `{ from?: Date; to?: Date } \| undefined` 详细类型由底层 react-day-picker 判别联合保证;此处仅展示业务侧期望形态。 同时显示几个月历(对齐 antd `numberOfMonths`)。 |
|
|
43
|
+
| `disabled` | `DayPickerProps['disabled']` | – | – | 不可选日期匹配器 — 支持 `Date` / `Date[]` / `DateRange` / 函数 `(date) => boolean` / 复合数组。 |
|
|
44
|
+
| `defaultMonth` | `Date` | – | – | 默认显示的月份(uncontrolled — 仅初始生效)。 不传时使用 `selected` 的月份,均无则当前月。 |
|
|
45
|
+
| `month` | `Date` | – | – | 受控当前显示的月份(配 `onMonthChange` 使用)。 |
|
|
46
|
+
| `onMonthChange` | `(month: Date) => void` | – | – | 月份切换回调。 |
|
|
47
|
+
| `weekStartsOn` | `DayPickerProps['weekStartsOn']` | `0` | – | 一周起始日 — `0` 周日 / `1` 周一 / ... / `6` 周六(对齐 ISO 8601 / antd `firstDayOfWeek`)。 |
|
|
48
|
+
| `captionLayout` | `DayPickerProps['captionLayout']` | – | – | 标题布局 — 控制是否显示年 / 月下拉: - `'label'`(默认)— 仅标签文字 - `'dropdown'` — 月 + 年下拉 - `'dropdown-months'` — 仅月份下拉 - `'dropdown-years'` — 仅年份下拉 |
|
|
49
|
+
| `locale` | `DayPickerProps['locale']` | – | – | date-fns Locale 对象,用于本地化星期 / 月份名 / RTL 等(默认 en-US)。 |
|
|
40
50
|
<!-- auto:props:end -->
|
|
41
51
|
|
|
42
52
|
## 依赖
|
|
@@ -51,7 +61,7 @@ package: '@teamix-evo/ui'
|
|
|
51
61
|
| Entry | 类型 | 描述 |
|
|
52
62
|
| --- | --- | --- |
|
|
53
63
|
| `cn` | util | Tailwind className 合并工具(clsx + tailwind-merge) |
|
|
54
|
-
| `button` | component | 通用按钮 — shadcn 实现 +
|
|
64
|
+
| `button` | component | 通用按钮 — shadcn 实现 + cloud-design 能力并集(loading / icon / shape / block / dashed variant / color 语义双 prop / disabledTooltip)。同文件合一导出 ButtonGroup + ButtonGroupText(等价 antd Space.Compact + cd SplitButton)。 |
|
|
55
65
|
|
|
56
66
|
### npm 依赖
|
|
57
67
|
|
|
@@ -1,10 +1,10 @@
|
|
|
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 type { DateRange } from 'react-day-picker';
|
|
4
4
|
import { Calendar } from './calendar';
|
|
5
5
|
|
|
6
6
|
const meta: Meta<typeof Calendar> = {
|
|
7
|
-
title: '
|
|
7
|
+
title: '数据展示 · Data Display/Calendar',
|
|
8
8
|
component: Calendar,
|
|
9
9
|
tags: ['autodocs'],
|
|
10
10
|
parameters: {
|
|
@@ -12,7 +12,7 @@ const meta: Meta<typeof Calendar> = {
|
|
|
12
12
|
docs: {
|
|
13
13
|
description: {
|
|
14
14
|
component:
|
|
15
|
-
'日历 — 内联日期选择面板。基于
|
|
15
|
+
'日历 — 内联日期选择面板。基于 react-day-picker@9 + design tokens,支持 `mode="single" | "multiple" | "range"` 三种选择模式、年份 / 月份导航、`disabled` 函数式禁用、`numberOfMonths` 多月并排;通常配 `Popover` 包装为 `DatePicker`。',
|
|
16
16
|
},
|
|
17
17
|
},
|
|
18
18
|
},
|
|
@@ -29,7 +29,7 @@ export const Single: Story = {
|
|
|
29
29
|
mode="single"
|
|
30
30
|
selected={date}
|
|
31
31
|
onSelect={setDate}
|
|
32
|
-
className="rounded-md border"
|
|
32
|
+
className="rounded-md border border-border"
|
|
33
33
|
/>
|
|
34
34
|
);
|
|
35
35
|
},
|
|
@@ -43,7 +43,7 @@ export const Multiple: Story = {
|
|
|
43
43
|
mode="multiple"
|
|
44
44
|
selected={days}
|
|
45
45
|
onSelect={setDays}
|
|
46
|
-
className="rounded-md border"
|
|
46
|
+
className="rounded-md border border-border"
|
|
47
47
|
/>
|
|
48
48
|
);
|
|
49
49
|
},
|
|
@@ -61,7 +61,7 @@ export const Range: Story = {
|
|
|
61
61
|
selected={range}
|
|
62
62
|
onSelect={setRange}
|
|
63
63
|
numberOfMonths={2}
|
|
64
|
-
className="rounded-md border"
|
|
64
|
+
className="rounded-md border border-border"
|
|
65
65
|
/>
|
|
66
66
|
);
|
|
67
67
|
},
|
|
@@ -11,9 +11,9 @@ import { cn } from '@/utils/cn';
|
|
|
11
11
|
import { buttonVariants } from '@/components/button/button';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* Calendar 自身的可定制属性(ui 层包装)
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* Calendar 自身的可定制属性(ui 层包装)。底层完整 props 透传至
|
|
15
|
+
* [`DayPicker`](https://daypicker.dev/) — 下表列出业务侧最常用的核心 props,
|
|
16
|
+
* 其余 DayPicker prop(`initialFocus` / `pagedNavigation` 等)走 `...rest` 透传。
|
|
17
17
|
*/
|
|
18
18
|
export interface CalendarProps {
|
|
19
19
|
/**
|
|
@@ -29,6 +29,62 @@ export interface CalendarProps {
|
|
|
29
29
|
* @default true
|
|
30
30
|
*/
|
|
31
31
|
showOutsideDays?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* 选择模式 — `'single'` 单选(`selected: Date`)/ `'multiple'` 多选(`selected: Date[]`)
|
|
34
|
+
* / `'range'` 范围(`selected: DateRange`)。
|
|
35
|
+
* @default "single"
|
|
36
|
+
*/
|
|
37
|
+
mode?: DayPickerProps['mode'];
|
|
38
|
+
/**
|
|
39
|
+
* 受控已选值 — 类型随 `mode` 变化:
|
|
40
|
+
* - `single` → `Date | undefined`
|
|
41
|
+
* - `multiple` → `Date[]`
|
|
42
|
+
* - `range` → `{ from?: Date; to?: Date } | undefined`
|
|
43
|
+
*
|
|
44
|
+
* 详细类型由底层 react-day-picker 判别联合保证;此处仅展示业务侧期望形态。
|
|
45
|
+
*/
|
|
46
|
+
// selected / onSelect 由 DayPickerProps 通过 `& DayPickerProps` 透传保证类型正确;
|
|
47
|
+
// 此处声明仅为 meta 文档展示,不参与运行时类型推导。
|
|
48
|
+
// 业务侧调用:`<Calendar mode="single" selected={date} onSelect={(d) => ...} />`
|
|
49
|
+
/**
|
|
50
|
+
* 同时显示几个月历(对齐 antd `numberOfMonths`)。
|
|
51
|
+
* @default 1
|
|
52
|
+
*/
|
|
53
|
+
numberOfMonths?: number;
|
|
54
|
+
/**
|
|
55
|
+
* 不可选日期匹配器 — 支持 `Date` / `Date[]` / `DateRange` / 函数 `(date) => boolean`
|
|
56
|
+
* / 复合数组。
|
|
57
|
+
*/
|
|
58
|
+
disabled?: DayPickerProps['disabled'];
|
|
59
|
+
/**
|
|
60
|
+
* 默认显示的月份(uncontrolled — 仅初始生效)。
|
|
61
|
+
* 不传时使用 `selected` 的月份,均无则当前月。
|
|
62
|
+
*/
|
|
63
|
+
defaultMonth?: Date;
|
|
64
|
+
/** 受控当前显示的月份(配 `onMonthChange` 使用)。 */
|
|
65
|
+
month?: Date;
|
|
66
|
+
/** 月份切换回调。 */
|
|
67
|
+
onMonthChange?: (month: Date) => void;
|
|
68
|
+
/**
|
|
69
|
+
* 一周起始日 — `0` 周日 / `1` 周一 / ... / `6` 周六(对齐 ISO 8601 / antd `firstDayOfWeek`)。
|
|
70
|
+
* @default 0
|
|
71
|
+
*/
|
|
72
|
+
weekStartsOn?: DayPickerProps['weekStartsOn'];
|
|
73
|
+
/**
|
|
74
|
+
* 标题布局 — 控制是否显示年 / 月下拉:
|
|
75
|
+
* - `'label'`(默认)— 仅标签文字
|
|
76
|
+
* - `'dropdown'` — 月 + 年下拉
|
|
77
|
+
* - `'dropdown-months'` — 仅月份下拉
|
|
78
|
+
* - `'dropdown-years'` — 仅年份下拉
|
|
79
|
+
*/
|
|
80
|
+
captionLayout?: DayPickerProps['captionLayout'];
|
|
81
|
+
/**
|
|
82
|
+
* date-fns Locale 对象,用于本地化星期 / 月份名 / RTL 等(默认 en-US)。
|
|
83
|
+
* @example
|
|
84
|
+
* import { zhCN } from 'date-fns/locale';
|
|
85
|
+
* <Calendar locale={zhCN} />
|
|
86
|
+
*/
|
|
87
|
+
locale?: DayPickerProps['locale'];
|
|
32
88
|
}
|
|
33
89
|
|
|
34
90
|
function Calendar({
|
|
@@ -46,7 +102,7 @@ function Calendar({
|
|
|
46
102
|
months: 'flex flex-col sm:flex-row gap-4 relative',
|
|
47
103
|
month: 'flex flex-col gap-4',
|
|
48
104
|
month_caption: 'flex justify-center pt-1 items-center h-7 w-full',
|
|
49
|
-
caption_label: 'text-
|
|
105
|
+
caption_label: 'text-xs font-medium',
|
|
50
106
|
nav: 'absolute inset-x-1 top-1 z-10 flex items-center justify-between',
|
|
51
107
|
button_previous: cn(
|
|
52
108
|
buttonVariants({ variant: 'outline', size: 'icon' }),
|
|
@@ -58,19 +114,28 @@ function Calendar({
|
|
|
58
114
|
),
|
|
59
115
|
month_grid: 'w-full border-collapse',
|
|
60
116
|
weekdays: 'flex',
|
|
61
|
-
weekday:
|
|
62
|
-
'text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]',
|
|
117
|
+
weekday: 'text-muted-foreground rounded-md w-8 font-normal text-xs-cal',
|
|
63
118
|
week: 'flex w-full mt-2',
|
|
64
119
|
day: cn(
|
|
65
|
-
'relative p-0 text-center text-
|
|
120
|
+
'relative p-0 text-center text-xs focus-within:relative focus-within:z-20',
|
|
66
121
|
'[&:has([data-selected])]:bg-accent',
|
|
67
122
|
'[&:has([data-selected])]:first:rounded-l-md [&:has([data-selected])]:last:rounded-r-md',
|
|
68
123
|
'[&:has([data-range-start])]:rounded-l-md [&:has([data-range-end])]:rounded-r-md',
|
|
69
124
|
'[&:not(:has([data-range-middle]))]:[&:has([data-selected])]:rounded-md',
|
|
125
|
+
// 预留 1px transparent dashed border 全 4 边占位 —— DateRangePicker preview 虚线
|
|
126
|
+
// 切换时不触发 cell 宽度 / 高度跳变(仅切换 border-color)。
|
|
127
|
+
// dashed border 跨 cell 时 pattern 节奏不可避免有微小偏差(CSS 固有限制),
|
|
128
|
+
// 但 cell 间 0 gap,视觉上无明显断点。
|
|
129
|
+
'border border-transparent border-dashed',
|
|
70
130
|
),
|
|
71
131
|
day_button: cn(
|
|
72
132
|
buttonVariants({ variant: 'ghost' }),
|
|
73
|
-
'size-8 p-0 font-normal aria-selected:opacity-100',
|
|
133
|
+
'size-8 rounded-md p-0 font-normal aria-selected:opacity-100',
|
|
134
|
+
'focus-visible:ring-offset-0',
|
|
135
|
+
// 父 day cell(td)有 aria-selected 时,button hover 保持 primary 蓝,
|
|
136
|
+
// 不被 ghost variant 的 hover:bg-accent 覆盖。react-day-picker v9 的
|
|
137
|
+
// aria-selected 加在 cell 上而非 button 上,所以走 ancestor selector。
|
|
138
|
+
'[[aria-selected]_&]:hover:bg-primary [[aria-selected]_&]:hover:text-primary-foreground',
|
|
74
139
|
),
|
|
75
140
|
range_start: 'day-range-start',
|
|
76
141
|
range_end: 'day-range-end',
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: card
|
|
3
3
|
name: Card
|
|
4
|
+
displayName: 卡片
|
|
4
5
|
type: component
|
|
5
|
-
category:
|
|
6
|
+
category: data-display
|
|
6
7
|
since: 0.1.0
|
|
7
|
-
package:
|
|
8
|
+
package: '@teamix-evo/ui'
|
|
8
9
|
---
|
|
9
10
|
|
|
10
|
-
# Card
|
|
11
|
+
# Card 卡片
|
|
11
12
|
|
|
12
13
|
卡片容器 — shadcn 组合式(`Card / Header / Title / Description / Content / Footer`)+ antd 并集(`hoverable / loading / Cover / Actions / Meta / extra`)。
|
|
13
14
|
**单卡覆盖列表项 / 详情卡 / 资源卡 / 媒体卡多种形态**。
|
|
@@ -34,6 +35,7 @@ package: "@teamix-evo/ui"
|
|
|
34
35
|
| --- | --- | --- | --- | --- |
|
|
35
36
|
| `hoverable` | `boolean` | `false` | – | 鼠标 hover 时的视觉反馈(antd `hoverable` 并集) — 阴影升级 + 微交互。 |
|
|
36
37
|
| `loading` | `boolean` | `false` | – | 加载态(antd `loading` 并集) — 整卡渲染为骨架屏占位,不展示 children。 |
|
|
38
|
+
| `size` | `CardSize` | `"default"` | – | 卡片尺寸(antd `size` 并集,并与 cloud-design spec 对齐) — - `sm`: 16px padding + sm 标题 (16px) - `default`: 24px padding + base 标题 (16px) - `lg`: 32px padding + lg 标题 (18px) 会通过 context 传递给其子组件(Header / Content / Footer)。 |
|
|
37
39
|
<!-- auto:props:end -->
|
|
38
40
|
|
|
39
41
|
## 依赖
|
|
@@ -55,8 +57,6 @@ package: "@teamix-evo/ui"
|
|
|
55
57
|
_无 — 本组件不依赖任何 npm 包。_
|
|
56
58
|
<!-- auto:deps:end -->
|
|
57
59
|
|
|
58
|
-
> 子组件:`Card`(主容器)/ `CardHeader`(支持 `extra`)/ `CardTitle` / `CardDescription` / `CardContent` / `CardFooter` / `CardCover`(顶部封面)/ `CardActions`(底部分隔操作栏)/ `CardMeta`(avatar + title + description 行)。
|
|
59
|
-
|
|
60
60
|
## AI 生成纪律
|
|
61
61
|
|
|
62
62
|
- **`hoverable` 仅用于可点击卡**:配 `onClick` 或包 `<Link>`,不能 hover 起视觉但点了无反应
|
|
@@ -65,6 +65,28 @@ _无 — 本组件不依赖任何 npm 包。_
|
|
|
65
65
|
- **`<CardCover>` 顶部对齐**:必须是 Card 的第一个子元素(避免上方圆角穿帮)
|
|
66
66
|
- **`<CardActions items>` 数组用法**:item 可以是文本 / 图标按钮;数组长度不超过 4
|
|
67
67
|
|
|
68
|
+
## Card 形态 — 旧库 API → 新库映射
|
|
69
|
+
|
|
70
|
+
旧库(Teamix 1.0 / `@alifd/next.Card` / `Card.Content` / `Card.Media` / `Card.Actions`)走数据驱动 + free 模式;新库走**纯组合**。下表给出旧库 API 到新库写法的逐项映射。
|
|
71
|
+
|
|
72
|
+
| 旧库 API | 新库写法 | 备注 |
|
|
73
|
+
| --- | --- | --- |
|
|
74
|
+
| `<Card title="..." subTitle="...">` | `<CardHeader><CardTitle>...</CardTitle><CardDescription>...</CardDescription></CardHeader>` | 组合式更利于多语言换行 / 自定义节点 |
|
|
75
|
+
| `<Card extra={...}>` | `<CardHeader extra={...}>...</CardHeader>` | API 一致;放刷新 / 更多 / 切换等轻量按钮 |
|
|
76
|
+
| `<Card.Media>` | `<CardCover>` | 圆角自动只渲顶部(`rounded-t-lg`) |
|
|
77
|
+
| `<Card.Actions>` | `<CardActions items={[...]} />` | 自动均分等宽 + 中间分隔线 |
|
|
78
|
+
| `<Card.Divider />` | `<Separator />` | 用 `@/components/ui/separator` |
|
|
79
|
+
| `loading` 骨架屏 | `loading` (P0 已实现) | 整卡渲染为 3 行骨架占位 |
|
|
80
|
+
| `hoverable` 鼠标反馈 | `hoverable` (P0 已实现) | 阴影升级 + 微交互 |
|
|
81
|
+
| `size="small/medium/large"` | `size="sm/default/lg"` | 重命名 — `sm` 16px / `default` 24px / `lg` 32px padding |
|
|
82
|
+
| `showTitleBullet` 左侧竖线 | 不修复 — 业务自加 `<CardTitle className="border-l-2 border-primary pl-2">` | className 自实现 |
|
|
83
|
+
| `showHeadDivider` 标题分割线 | 不修复 — 用 `<Separator />` 或 `border-b` | — |
|
|
84
|
+
| `contentHeight` 内容固定高 | 不修复 — `<CardContent className="h-[N]">` | — |
|
|
85
|
+
| `free` 自由组合模式 | 不修复 — 新库始终组合式 | 默认即 free |
|
|
86
|
+
| `hasBorder={false}` | 不修复 — `className="border-0 shadow-none"` | — |
|
|
87
|
+
| `Card.CollapseContent` | 组合 `<Collapsible>` 在 `<CardContent>` 内 | 用 `@/components/ui/collapsible` |
|
|
88
|
+
| `Card.DropDownActions` | 组合 `<CardAction>` + `<DropdownMenu>` | shadcn 2026-04 新增 `<CardAction>` 子组件 |
|
|
89
|
+
|
|
68
90
|
## Examples
|
|
69
91
|
|
|
70
92
|
```tsx
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
2
|
import { Heart, MessageSquare, MoreHorizontal, Share } from 'lucide-react';
|
|
3
3
|
import {
|
|
4
4
|
Card,
|
|
@@ -19,14 +19,23 @@ import {
|
|
|
19
19
|
} from '@/components/avatar/avatar';
|
|
20
20
|
|
|
21
21
|
const meta: Meta<typeof Card> = {
|
|
22
|
-
title: '
|
|
22
|
+
title: '数据展示 · Data Display/Card',
|
|
23
23
|
component: Card,
|
|
24
24
|
tags: ['autodocs'],
|
|
25
|
+
parameters: {
|
|
26
|
+
docs: {
|
|
27
|
+
description: {
|
|
28
|
+
component:
|
|
29
|
+
'卡片容器 — shadcn 组合式(Card / Header / Title / Description / Content / Footer) + antd 并集(hoverable / loading / Cover / Actions / Meta / extra)。单卡覆盖列表项 / 详情卡 / 资源卡 / 媒体卡多种形态。',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
25
33
|
argTypes: {
|
|
26
34
|
hoverable: { control: 'boolean' },
|
|
27
35
|
loading: { control: 'boolean' },
|
|
36
|
+
size: { control: 'inline-radio', options: ['sm', 'default', 'lg'] },
|
|
28
37
|
},
|
|
29
|
-
args: { hoverable: false, loading: false },
|
|
38
|
+
args: { hoverable: false, loading: false, size: 'default' },
|
|
30
39
|
};
|
|
31
40
|
|
|
32
41
|
export default meta;
|
|
@@ -110,3 +119,33 @@ export const Media: Story = {
|
|
|
110
119
|
</Card>
|
|
111
120
|
),
|
|
112
121
|
};
|
|
122
|
+
|
|
123
|
+
export const Sizes: Story = {
|
|
124
|
+
name: 'Sizes · sm / default / lg',
|
|
125
|
+
parameters: { controls: { disable: true } },
|
|
126
|
+
render: () => (
|
|
127
|
+
<div className="flex flex-col gap-4">
|
|
128
|
+
{(['sm', 'default', 'lg'] as const).map((s) => (
|
|
129
|
+
<Card key={s} size={s} className="w-80">
|
|
130
|
+
<CardHeader>
|
|
131
|
+
<CardTitle>size = {s}</CardTitle>
|
|
132
|
+
<CardDescription>
|
|
133
|
+
padding 与标题级随 size 变化: sm → 16px / default → 24px / lg → 32px
|
|
134
|
+
</CardDescription>
|
|
135
|
+
</CardHeader>
|
|
136
|
+
<CardContent>
|
|
137
|
+
<p className="text-sm text-muted-foreground">
|
|
138
|
+
内容区 padding 同步从 head 继承,顶部 pt-0 跟 header 默认 gap 对齐。
|
|
139
|
+
</p>
|
|
140
|
+
</CardContent>
|
|
141
|
+
<CardFooter className="justify-end gap-2">
|
|
142
|
+
<Button size={s === 'lg' ? 'lg' : s === 'sm' ? 'sm' : 'default'} variant="outline">
|
|
143
|
+
取消
|
|
144
|
+
</Button>
|
|
145
|
+
<Button size={s === 'lg' ? 'lg' : s === 'sm' ? 'sm' : 'default'}>确认</Button>
|
|
146
|
+
</CardFooter>
|
|
147
|
+
</Card>
|
|
148
|
+
))}
|
|
149
|
+
</div>
|
|
150
|
+
),
|
|
151
|
+
};
|
|
@@ -3,6 +3,42 @@ import * as React from 'react';
|
|
|
3
3
|
import { cn } from '@/utils/cn';
|
|
4
4
|
import { Skeleton } from '@/components/skeleton/skeleton';
|
|
5
5
|
|
|
6
|
+
type CardSize = 'sm' | 'md' | 'default' | 'lg';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 内部驱动 Header / Content / Footer padding 的 context。
|
|
10
|
+
* 不对外暴露 — 子组件仅依据它返回对应的 Tailwind padding 类名,
|
|
11
|
+
* 保证 `<Card size="sm">` 包裹的子组件查表一致。
|
|
12
|
+
*/
|
|
13
|
+
const CardSizeContext = React.createContext<CardSize>('md');
|
|
14
|
+
|
|
15
|
+
const SIZE_TOKENS = {
|
|
16
|
+
sm: {
|
|
17
|
+
headerFooter: 'p-4',
|
|
18
|
+
content: 'p-4 pt-0',
|
|
19
|
+
footer: 'p-4 pt-0',
|
|
20
|
+
title: 'text-sm',
|
|
21
|
+
},
|
|
22
|
+
md: {
|
|
23
|
+
headerFooter: 'p-6',
|
|
24
|
+
content: 'p-6 pt-0',
|
|
25
|
+
footer: 'p-6 pt-0',
|
|
26
|
+
title: 'text-base',
|
|
27
|
+
},
|
|
28
|
+
default: {
|
|
29
|
+
headerFooter: 'p-6',
|
|
30
|
+
content: 'p-6 pt-0',
|
|
31
|
+
footer: 'p-6 pt-0',
|
|
32
|
+
title: 'text-base',
|
|
33
|
+
},
|
|
34
|
+
lg: {
|
|
35
|
+
headerFooter: 'p-8',
|
|
36
|
+
content: 'p-8 pt-0',
|
|
37
|
+
footer: 'p-8 pt-0',
|
|
38
|
+
title: 'text-lg',
|
|
39
|
+
},
|
|
40
|
+
} as const;
|
|
41
|
+
|
|
6
42
|
export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
7
43
|
/**
|
|
8
44
|
* 鼠标 hover 时的视觉反馈(antd `hoverable` 并集) — 阴影升级 + 微交互。
|
|
@@ -14,29 +50,56 @@ export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
14
50
|
* @default false
|
|
15
51
|
*/
|
|
16
52
|
loading?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* 卡片尺寸(antd `size` 并集,并与 cloud-design spec 对齐) —
|
|
55
|
+
* - `sm`: 16px padding + sm 标题 (16px)
|
|
56
|
+
* - `default`: 24px padding + base 标题 (16px)
|
|
57
|
+
* - `lg`: 32px padding + lg 标题 (18px)
|
|
58
|
+
* 会通过 context 传递给其子组件(Header / Content / Footer)。
|
|
59
|
+
* @default "default"
|
|
60
|
+
*/
|
|
61
|
+
size?: CardSize;
|
|
17
62
|
}
|
|
18
63
|
|
|
19
64
|
const Card = React.forwardRef<HTMLDivElement, CardProps>(
|
|
20
|
-
(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
65
|
+
(
|
|
66
|
+
{
|
|
67
|
+
className,
|
|
68
|
+
hoverable = false,
|
|
69
|
+
loading = false,
|
|
70
|
+
size = 'md',
|
|
71
|
+
children,
|
|
72
|
+
...props
|
|
73
|
+
},
|
|
74
|
+
ref,
|
|
75
|
+
) => (
|
|
76
|
+
<CardSizeContext.Provider value={size}>
|
|
77
|
+
<div
|
|
78
|
+
ref={ref}
|
|
79
|
+
data-size={size}
|
|
80
|
+
className={cn(
|
|
81
|
+
'rounded-lg border border-border bg-card text-card-foreground shadow-sm transition-shadow',
|
|
82
|
+
hoverable && 'cursor-pointer hover:shadow-md',
|
|
83
|
+
className,
|
|
84
|
+
)}
|
|
85
|
+
{...props}
|
|
86
|
+
>
|
|
87
|
+
{loading ? (
|
|
88
|
+
<div
|
|
89
|
+
className={cn(
|
|
90
|
+
'flex flex-col gap-3',
|
|
91
|
+
SIZE_TOKENS[size].headerFooter,
|
|
92
|
+
)}
|
|
93
|
+
>
|
|
94
|
+
<Skeleton shape="line" className="w-2/5" />
|
|
95
|
+
<Skeleton shape="line" />
|
|
96
|
+
<Skeleton shape="line" className="w-4/5" />
|
|
97
|
+
</div>
|
|
98
|
+
) : (
|
|
99
|
+
children
|
|
100
|
+
)}
|
|
101
|
+
</div>
|
|
102
|
+
</CardSizeContext.Provider>
|
|
40
103
|
),
|
|
41
104
|
);
|
|
42
105
|
Card.displayName = 'Card';
|
|
@@ -50,22 +113,29 @@ export interface CardHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
50
113
|
}
|
|
51
114
|
|
|
52
115
|
const CardHeader = React.forwardRef<HTMLDivElement, CardHeaderProps>(
|
|
53
|
-
({ className, extra, children, ...props }, ref) =>
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
116
|
+
({ className, extra, children, ...props }, ref) => {
|
|
117
|
+
const size = React.useContext(CardSizeContext);
|
|
118
|
+
return (
|
|
119
|
+
<div
|
|
120
|
+
ref={ref}
|
|
121
|
+
className={cn(
|
|
122
|
+
'flex flex-col gap-1.5',
|
|
123
|
+
SIZE_TOKENS[size].headerFooter,
|
|
124
|
+
className,
|
|
125
|
+
)}
|
|
126
|
+
{...props}
|
|
127
|
+
>
|
|
128
|
+
{extra ? (
|
|
129
|
+
<div className="flex items-start justify-between gap-3">
|
|
130
|
+
<div className="flex flex-1 flex-col gap-1.5">{children}</div>
|
|
131
|
+
<div className="shrink-0">{extra}</div>
|
|
132
|
+
</div>
|
|
133
|
+
) : (
|
|
134
|
+
children
|
|
135
|
+
)}
|
|
136
|
+
</div>
|
|
137
|
+
);
|
|
138
|
+
},
|
|
69
139
|
);
|
|
70
140
|
CardHeader.displayName = 'CardHeader';
|
|
71
141
|
|
|
@@ -87,16 +157,20 @@ CardAction.displayName = 'CardAction';
|
|
|
87
157
|
const CardTitle = React.forwardRef<
|
|
88
158
|
HTMLHeadingElement,
|
|
89
159
|
React.HTMLAttributes<HTMLHeadingElement>
|
|
90
|
-
>(({ className, ...props }, ref) =>
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
className
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
)
|
|
160
|
+
>(({ className, ...props }, ref) => {
|
|
161
|
+
const size = React.useContext(CardSizeContext);
|
|
162
|
+
return (
|
|
163
|
+
<h3
|
|
164
|
+
ref={ref}
|
|
165
|
+
className={cn(
|
|
166
|
+
'font-semibold leading-none tracking-tight',
|
|
167
|
+
SIZE_TOKENS[size].title,
|
|
168
|
+
className,
|
|
169
|
+
)}
|
|
170
|
+
{...props}
|
|
171
|
+
/>
|
|
172
|
+
);
|
|
173
|
+
});
|
|
100
174
|
CardTitle.displayName = 'CardTitle';
|
|
101
175
|
|
|
102
176
|
const CardDescription = React.forwardRef<
|
|
@@ -105,7 +179,7 @@ const CardDescription = React.forwardRef<
|
|
|
105
179
|
>(({ className, ...props }, ref) => (
|
|
106
180
|
<p
|
|
107
181
|
ref={ref}
|
|
108
|
-
className={cn('text-
|
|
182
|
+
className={cn('text-xs text-muted-foreground', className)}
|
|
109
183
|
{...props}
|
|
110
184
|
/>
|
|
111
185
|
));
|
|
@@ -114,21 +188,31 @@ CardDescription.displayName = 'CardDescription';
|
|
|
114
188
|
const CardContent = React.forwardRef<
|
|
115
189
|
HTMLDivElement,
|
|
116
190
|
React.HTMLAttributes<HTMLDivElement>
|
|
117
|
-
>(({ className, ...props }, ref) =>
|
|
118
|
-
|
|
119
|
-
|
|
191
|
+
>(({ className, ...props }, ref) => {
|
|
192
|
+
const size = React.useContext(CardSizeContext);
|
|
193
|
+
return (
|
|
194
|
+
<div
|
|
195
|
+
ref={ref}
|
|
196
|
+
className={cn(SIZE_TOKENS[size].content, className)}
|
|
197
|
+
{...props}
|
|
198
|
+
/>
|
|
199
|
+
);
|
|
200
|
+
});
|
|
120
201
|
CardContent.displayName = 'CardContent';
|
|
121
202
|
|
|
122
203
|
const CardFooter = React.forwardRef<
|
|
123
204
|
HTMLDivElement,
|
|
124
205
|
React.HTMLAttributes<HTMLDivElement>
|
|
125
|
-
>(({ className, ...props }, ref) =>
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
206
|
+
>(({ className, ...props }, ref) => {
|
|
207
|
+
const size = React.useContext(CardSizeContext);
|
|
208
|
+
return (
|
|
209
|
+
<div
|
|
210
|
+
ref={ref}
|
|
211
|
+
className={cn('flex items-center', SIZE_TOKENS[size].footer, className)}
|
|
212
|
+
{...props}
|
|
213
|
+
/>
|
|
214
|
+
);
|
|
215
|
+
});
|
|
132
216
|
CardFooter.displayName = 'CardFooter';
|
|
133
217
|
|
|
134
218
|
// ─── antd 风格 sub-components(并集)──────────────────────────────────────
|
|
@@ -139,7 +223,7 @@ const CardCover = React.forwardRef<HTMLDivElement, CardCoverProps>(
|
|
|
139
223
|
<div
|
|
140
224
|
ref={ref}
|
|
141
225
|
className={cn(
|
|
142
|
-
'overflow-hidden rounded-t-lg border-b [&>img]:w-full [&>img]:object-cover',
|
|
226
|
+
'overflow-hidden rounded-t-lg border-b border-border [&>img]:w-full [&>img]:object-cover',
|
|
143
227
|
className,
|
|
144
228
|
)}
|
|
145
229
|
{...props}
|
|
@@ -150,8 +234,7 @@ const CardCover = React.forwardRef<HTMLDivElement, CardCoverProps>(
|
|
|
150
234
|
);
|
|
151
235
|
CardCover.displayName = 'CardCover';
|
|
152
236
|
|
|
153
|
-
export interface CardActionsProps
|
|
154
|
-
extends React.HTMLAttributes<HTMLDivElement> {
|
|
237
|
+
export interface CardActionsProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
155
238
|
/** 操作项数组(antd `actions` 并集) — 自动均分等宽,中间分隔线。 */
|
|
156
239
|
items: React.ReactNode[];
|
|
157
240
|
}
|
|
@@ -160,7 +243,7 @@ const CardActions = React.forwardRef<HTMLDivElement, CardActionsProps>(
|
|
|
160
243
|
<div
|
|
161
244
|
ref={ref}
|
|
162
245
|
className={cn(
|
|
163
|
-
'flex items-stretch divide-x divide-border border-t',
|
|
246
|
+
'flex items-stretch divide-x divide-border border-t border-border',
|
|
164
247
|
className,
|
|
165
248
|
)}
|
|
166
249
|
{...props}
|
|
@@ -168,7 +251,7 @@ const CardActions = React.forwardRef<HTMLDivElement, CardActionsProps>(
|
|
|
168
251
|
{items.map((item, i) => (
|
|
169
252
|
<div
|
|
170
253
|
key={i}
|
|
171
|
-
className="flex flex-1 items-center justify-center py-3 text-
|
|
254
|
+
className="flex flex-1 items-center justify-center py-3 text-xs text-muted-foreground transition-colors hover:bg-accent"
|
|
172
255
|
>
|
|
173
256
|
{item}
|
|
174
257
|
</div>
|
|
@@ -200,7 +283,7 @@ const CardMeta = React.forwardRef<HTMLDivElement, CardMetaProps>(
|
|
|
200
283
|
<div className="text-sm font-semibold leading-none">{title}</div>
|
|
201
284
|
) : null}
|
|
202
285
|
{description ? (
|
|
203
|
-
<div className="text-
|
|
286
|
+
<div className="text-xs text-muted-foreground">{description}</div>
|
|
204
287
|
) : null}
|
|
205
288
|
</div>
|
|
206
289
|
</div>
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: carousel
|
|
3
3
|
name: Carousel
|
|
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
|
-
# Carousel
|
|
11
|
+
# Carousel 走马灯
|
|
11
12
|
|
|
12
13
|
走马灯 — 基于 [`embla-carousel-react`](https://www.embla-carousel.com/),性能与可访问性出色。
|
|
13
14
|
对应 antd `Carousel` 的核心场景。
|
|
@@ -50,7 +51,7 @@ package: "@teamix-evo/ui"
|
|
|
50
51
|
| Entry | 类型 | 描述 |
|
|
51
52
|
| --- | --- | --- |
|
|
52
53
|
| `cn` | util | Tailwind className 合并工具(clsx + tailwind-merge) |
|
|
53
|
-
| `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)。 |
|
|
54
55
|
|
|
55
56
|
### npm 依赖
|
|
56
57
|
|