@qijenchen/design-system 0.1.0-beta.95 → 0.1.0-beta.99
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 +1 -0
- package/dist/components/AccountMenu/account-menu.d.ts +86 -0
- package/dist/components/AccountMenu/account-menu.d.ts.map +1 -0
- package/dist/components/AccountMenu/account-menu.js +64 -0
- package/dist/components/AccountMenu/account-menu.js.map +1 -0
- package/dist/components/AccountMenu/index.d.ts +2 -0
- package/dist/components/AccountMenu/index.d.ts.map +1 -0
- package/dist/components/AccountMenu/index.js +6 -0
- package/dist/components/AccountMenu/index.js.map +1 -0
- package/dist/components/AppShell/_demo-helpers.d.ts.map +1 -1
- package/dist/components/AppShell/app-shell.d.ts.map +1 -1
- package/dist/components/AppShell/app-shell.js +2 -2
- package/dist/components/AppShell/app-shell.js.map +1 -1
- package/dist/components/Badge/badge.d.ts +1 -1
- package/dist/components/Button/button.d.ts +3 -3
- package/dist/components/Button/button.d.ts.map +1 -1
- package/dist/components/Button/button.js +3 -2
- package/dist/components/Button/button.js.map +1 -1
- package/dist/components/Calendar/calendar.d.ts +10 -21
- package/dist/components/Calendar/calendar.d.ts.map +1 -1
- package/dist/components/Calendar/calendar.js +52 -59
- package/dist/components/Calendar/calendar.js.map +1 -1
- package/dist/components/Combobox/combobox.d.ts.map +1 -1
- package/dist/components/Combobox/combobox.js +1 -0
- package/dist/components/Combobox/combobox.js.map +1 -1
- package/dist/components/Command/command.d.ts.map +1 -1
- package/dist/components/Command/command.js +3 -1
- package/dist/components/Command/command.js.map +1 -1
- package/dist/components/DataTable/cell-registry.d.ts.map +1 -1
- package/dist/components/DataTable/cell-registry.js +1 -5
- package/dist/components/DataTable/cell-registry.js.map +1 -1
- package/dist/components/DataTable/data-table-filter-group.d.ts +6 -2
- package/dist/components/DataTable/data-table-filter-group.d.ts.map +1 -1
- package/dist/components/DataTable/data-table-filter-group.js +32 -27
- package/dist/components/DataTable/data-table-filter-group.js.map +1 -1
- package/dist/components/DataTable/data-table-filter-labels.d.ts +44 -0
- package/dist/components/DataTable/data-table-filter-labels.d.ts.map +1 -0
- package/dist/components/DataTable/data-table-filter-labels.js +55 -0
- package/dist/components/DataTable/data-table-filter-labels.js.map +1 -0
- package/dist/components/DataTable/data-table-filter-panel.d.ts +11 -0
- package/dist/components/DataTable/data-table-filter-panel.d.ts.map +1 -1
- package/dist/components/DataTable/data-table-filter-panel.js +33 -10
- package/dist/components/DataTable/data-table-filter-panel.js.map +1 -1
- package/dist/components/DataTable/data-table-filter-value-picker.d.ts +4 -1
- package/dist/components/DataTable/data-table-filter-value-picker.d.ts.map +1 -1
- package/dist/components/DataTable/data-table-filter-value-picker.js +22 -8
- package/dist/components/DataTable/data-table-filter-value-picker.js.map +1 -1
- package/dist/components/DataTable/data-table.d.ts.map +1 -1
- package/dist/components/DataTable/data-table.js +5 -4
- package/dist/components/DataTable/data-table.js.map +1 -1
- package/dist/components/DataTable/index.js +2 -0
- package/dist/components/DataTable/index.js.map +1 -1
- package/dist/components/DatePicker/date-picker.d.ts.map +1 -1
- package/dist/components/DatePicker/date-picker.js +187 -156
- package/dist/components/DatePicker/date-picker.js.map +1 -1
- package/dist/components/Dialog/dialog.d.ts +1 -1
- package/dist/components/Dialog/dialog.d.ts.map +1 -1
- package/dist/components/Dialog/dialog.js +4 -2
- package/dist/components/Dialog/dialog.js.map +1 -1
- package/dist/components/DropdownMenu/dropdown-menu.d.ts +4 -1
- package/dist/components/DropdownMenu/dropdown-menu.d.ts.map +1 -1
- package/dist/components/DropdownMenu/dropdown-menu.js +46 -14
- package/dist/components/DropdownMenu/dropdown-menu.js.map +1 -1
- package/dist/components/Field/field-context.d.ts +12 -0
- package/dist/components/Field/field-context.d.ts.map +1 -1
- package/dist/components/Field/field-context.js +10 -1
- package/dist/components/Field/field-context.js.map +1 -1
- package/dist/components/Field/field-wrapper.d.ts.map +1 -1
- package/dist/components/Field/field-wrapper.js +7 -1
- package/dist/components/Field/field-wrapper.js.map +1 -1
- package/dist/components/Field/field.d.ts.map +1 -1
- package/dist/components/Field/field.js +11 -2
- package/dist/components/Field/field.js.map +1 -1
- package/dist/components/FieldControlGroup/field-control-group.d.ts +2 -5
- package/dist/components/FieldControlGroup/field-control-group.d.ts.map +1 -1
- package/dist/components/FieldControlGroup/field-control-group.js +2 -2
- package/dist/components/FieldControlGroup/field-control-group.js.map +1 -1
- package/dist/components/FileUpload/file-upload.js +1 -1
- package/dist/components/FileUpload/file-upload.js.map +1 -1
- package/dist/components/FileViewer/file-viewer.d.ts +1 -1
- package/dist/components/FileViewer/file-viewer.d.ts.map +1 -1
- package/dist/components/FileViewer/file-viewer.js +20 -3
- package/dist/components/FileViewer/file-viewer.js.map +1 -1
- package/dist/components/InlineEdit/inline-edit.d.ts +5 -0
- package/dist/components/InlineEdit/inline-edit.d.ts.map +1 -1
- package/dist/components/InlineEdit/inline-edit.js +65 -33
- package/dist/components/InlineEdit/inline-edit.js.map +1 -1
- package/dist/components/Input/input.d.ts.map +1 -1
- package/dist/components/Input/input.js +3 -2
- package/dist/components/Input/input.js.map +1 -1
- package/dist/components/LinkInput/link-input.d.ts.map +1 -1
- package/dist/components/LinkInput/link-input.js +2 -1
- package/dist/components/LinkInput/link-input.js.map +1 -1
- package/dist/components/Menu/menu-item.d.ts.map +1 -1
- package/dist/components/Menu/menu-item.js +4 -2
- package/dist/components/Menu/menu-item.js.map +1 -1
- package/dist/components/PeoplePicker/people-picker.d.ts +2 -0
- package/dist/components/PeoplePicker/people-picker.d.ts.map +1 -1
- package/dist/components/PeoplePicker/people-picker.js +4 -0
- package/dist/components/PeoplePicker/people-picker.js.map +1 -1
- package/dist/components/Popover/popover.d.ts.map +1 -1
- package/dist/components/Popover/popover.js +4 -2
- package/dist/components/Popover/popover.js.map +1 -1
- package/dist/components/ScrollArea/scroll-area.d.ts +4 -3
- package/dist/components/ScrollArea/scroll-area.d.ts.map +1 -1
- package/dist/components/ScrollArea/scroll-area.js +1 -1
- package/dist/components/ScrollArea/scroll-area.js.map +1 -1
- package/dist/components/Select/select.d.ts.map +1 -1
- package/dist/components/Select/select.js +59 -37
- package/dist/components/Select/select.js.map +1 -1
- package/dist/components/SelectMenu/select-menu.d.ts +2 -0
- package/dist/components/SelectMenu/select-menu.d.ts.map +1 -1
- package/dist/components/SelectMenu/select-menu.js +3 -1
- package/dist/components/SelectMenu/select-menu.js.map +1 -1
- package/dist/components/Sheet/sheet.d.ts +1 -1
- package/dist/components/Sidebar/sidebar.js +2 -2
- package/dist/components/Sidebar/sidebar.js.map +1 -1
- package/dist/components/Tabs/tabs.d.ts.map +1 -1
- package/dist/components/Tabs/tabs.js +3 -0
- package/dist/components/Tabs/tabs.js.map +1 -1
- package/dist/components/Tag/tag.d.ts +1 -1
- package/dist/components/Tag/tag.d.ts.map +1 -1
- package/dist/components/Tag/tag.js +4 -3
- package/dist/components/Tag/tag.js.map +1 -1
- package/dist/components/Textarea/textarea.d.ts +11 -0
- package/dist/components/Textarea/textarea.d.ts.map +1 -1
- package/dist/components/Textarea/textarea.js +22 -5
- package/dist/components/Textarea/textarea.js.map +1 -1
- package/dist/components/TimePicker/time-picker.d.ts.map +1 -1
- package/dist/components/TimePicker/time-picker.js +4 -3
- package/dist/components/TimePicker/time-picker.js.map +1 -1
- package/dist/components/Tooltip/tooltip.d.ts +1 -1
- package/dist/components/Tooltip/tooltip.d.ts.map +1 -1
- package/dist/components/Tooltip/tooltip.js +26 -1
- package/dist/components/Tooltip/tooltip.js.map +1 -1
- package/dist/components/TreeView/tree-view.d.ts +2 -0
- package/dist/components/TreeView/tree-view.d.ts.map +1 -1
- package/dist/components/TreeView/tree-view.js +3 -2
- package/dist/components/TreeView/tree-view.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/patterns/element-anatomy/item-anatomy.d.ts +10 -1
- package/dist/patterns/element-anatomy/item-anatomy.d.ts.map +1 -1
- package/dist/patterns/element-anatomy/item-anatomy.js +77 -29
- package/dist/patterns/element-anatomy/item-anatomy.js.map +1 -1
- package/dist/patterns/header-canonical/chrome-header.d.ts +11 -4
- package/dist/patterns/header-canonical/chrome-header.d.ts.map +1 -1
- package/dist/patterns/header-canonical/chrome-header.js +1 -1
- package/dist/patterns/header-canonical/chrome-header.js.map +1 -1
- package/dist/patterns/overlay-surface/overlay-surface.d.ts +4 -3
- package/dist/patterns/overlay-surface/overlay-surface.d.ts.map +1 -1
- package/dist/patterns/overlay-surface/overlay-surface.js +1 -0
- package/dist/patterns/overlay-surface/overlay-surface.js.map +1 -1
- package/dist/patterns/resize-handle/resize-handle.d.ts +9 -11
- package/dist/patterns/resize-handle/resize-handle.d.ts.map +1 -1
- package/dist/patterns/resize-handle/resize-handle.js +3 -6
- package/dist/patterns/resize-handle/resize-handle.js.map +1 -1
- package/ds-canonical/adapters/claude/agents/canonical-reviewer.md +1 -1
- package/ds-canonical/adapters/claude-root-instructions.md +1 -1
- package/ds-canonical/adapters/claude-settings-base.json +2 -5
- package/ds-canonical/fork/AGENTS.md +21 -10
- package/ds-canonical/fork/codex/hooks.json +1 -1
- package/ds-canonical/fork/common/instruction.md +21 -10
- package/ds-canonical/fork/consumer/governance-check.mjs +101 -13
- package/ds-canonical/fork/consumer/lock.json +14 -15
- package/ds-canonical/fork/consumer/managed-files/46f10bc55cdfdf834d0749eebff42ea0bb8576f361b36d2b6ba1851354c50150.blob +26 -3
- package/ds-canonical/fork/consumer/managed-files/63061e05969667005020166ea2ae7df3c96663f7a928e7dd3eebc1471022df56.blob +61 -5
- package/ds-canonical/fork/consumer/managed-files/93a89f16f6717d1e4e4e27ec20ef916e3355c7aa890ca74cd9b12db30d8a899f.blob +3 -10
- package/ds-canonical/fork/consumer/managed-files/bc44cabad181f766611dab6a8f52d81100afadd50ac59799015e8ba7bf46d9eb.blob +3 -2
- package/ds-canonical/fork/governance.lock +17 -33
- package/ds-canonical/fork/hooks/check_consumer_code_quality.sh +33 -0
- package/ds-canonical/fork/hooks/check_pattern_invariants.sh +39 -0
- package/ds-canonical/fork/hooks/check_sidebar_menu_button_implicit_wrap.sh +6 -4
- package/ds-canonical/fork/launchers/provider-hook-normalization.mjs +5 -11
- package/ds-canonical/fork/launchers/settings-hooks.json +2 -2
- package/ds-canonical/fork/manifest.json +11 -13
- package/ds-canonical/fork/providers/claude/hook-config.json +1 -7
- package/ds-canonical/fork/providers/codex/hook-config.json +1 -1
- package/ds-canonical/fork/references/story-baseline-registry.json +7 -1
- package/ds-canonical/hooks/check_consumer_code_quality.sh +33 -0
- package/ds-canonical/hooks/check_pattern_invariants.sh +39 -0
- package/ds-canonical/hooks/check_sidebar_menu_button_implicit_wrap.sh +6 -4
- package/ds-canonical/hooks/session_start_governance_check.sh +5 -6
- package/ds-canonical/hooks/tests/test_check_consumer_code_quality.sh +23 -1
- package/ds-canonical/hooks/tests/test_check_pattern_invariants.sh +36 -2
- package/ds-canonical/references/audit-coverage-vs-24-checklist.md +1 -1
- package/ds-canonical/references/failure-class-registry.json +151 -144
- package/ds-canonical/references/preflight-gate-baseline.json +16 -12
- package/ds-canonical/references/story-baseline-registry.json +7 -1
- package/ds-canonical/rules/meta-patterns.md +3 -3
- package/ds-canonical/skills/design-system-audit/SKILL.md +1 -1
- package/ds-canonical/skills/design-system-audit/references/audit-prompts.md +1 -1
- package/ds-canonical/templates/dashboard-app.tsx +31 -8
- package/llms-full.txt +6 -1
- package/llms.txt +2 -1
- package/package.json +1 -1
- package/src/components/Accordion/accordion.principles.stories.tsx +16 -26
- package/src/components/Accordion/accordion.stories.tsx +22 -40
- package/src/components/AccountMenu/account-menu.anatomy.stories.tsx +115 -0
- package/src/components/AccountMenu/account-menu.principles.stories.tsx +99 -0
- package/src/components/AccountMenu/account-menu.spec.md +101 -0
- package/src/components/AccountMenu/account-menu.stories.tsx +61 -0
- package/src/components/AccountMenu/account-menu.tsx +170 -0
- package/src/components/AccountMenu/index.ts +5 -0
- package/src/components/AppShell/_demo-helpers.tsx +53 -53
- package/src/components/AppShell/app-shell.spec.md +5 -1
- package/src/components/AppShell/app-shell.tsx +14 -12
- package/src/components/Avatar/avatar.principles.stories.tsx +4 -4
- package/src/components/Avatar/avatar.stories.tsx +20 -5
- package/src/components/Breadcrumb/breadcrumb.spec.md +1 -1
- package/src/components/Button/button.spec.md +1 -1
- package/src/components/Button/button.stories.tsx +21 -9
- package/src/components/Button/button.tsx +5 -4
- package/src/components/Calendar/calendar.anatomy.stories.tsx +19 -17
- package/src/components/Calendar/calendar.principles.stories.tsx +5 -6
- package/src/components/Calendar/calendar.spec.md +25 -29
- package/src/components/Calendar/calendar.stories.tsx +5 -7
- package/src/components/Calendar/calendar.tsx +75 -87
- package/src/components/Carousel/carousel.principles.stories.tsx +5 -1
- package/src/components/Chart/chart.spec.md +1 -1
- package/src/components/Checkbox/checkbox.anatomy.stories.tsx +14 -5
- package/src/components/Chip/chip.spec.md +1 -1
- package/src/components/CircularProgress/circular-progress.anatomy.stories.tsx +7 -6
- package/src/components/CircularProgress/circular-progress.principles.stories.tsx +8 -6
- package/src/components/CircularProgress/circular-progress.stories.tsx +3 -3
- package/src/components/Combobox/combobox.tsx +1 -0
- package/src/components/Command/command.spec.md +1 -0
- package/src/components/Command/command.tsx +4 -1
- package/src/components/DataTable/cell-registry.tsx +3 -7
- package/src/components/DataTable/data-table-filter-group.tsx +44 -27
- package/src/components/DataTable/data-table-filter-labels.ts +100 -0
- package/src/components/DataTable/data-table-filter-panel.tsx +48 -8
- package/src/components/DataTable/data-table-filter-value-picker.tsx +25 -8
- package/src/components/DataTable/data-table.spec.md +18 -1
- package/src/components/DataTable/data-table.stories.tsx +346 -33
- package/src/components/DataTable/data-table.tsx +11 -4
- package/src/components/DataTable/filter-operators.spec.md +2 -2
- package/src/components/DateGrid/date-grid.anatomy.stories.tsx +24 -20
- package/src/components/DateGrid/date-grid.principles.stories.tsx +27 -21
- package/src/components/DateGrid/date-grid.stories.tsx +22 -13
- package/src/components/DatePicker/date-picker.anatomy.stories.tsx +3 -3
- package/src/components/DatePicker/date-picker.spec.md +4 -4
- package/src/components/DatePicker/date-picker.stories.tsx +33 -9
- package/src/components/DatePicker/date-picker.tsx +210 -147
- package/src/components/Dialog/dialog.spec.md +1 -1
- package/src/components/Dialog/dialog.tsx +8 -2
- package/src/components/DropdownMenu/dropdown-menu.anatomy.stories.tsx +1 -1
- package/src/components/DropdownMenu/dropdown-menu.spec.md +5 -0
- package/src/components/DropdownMenu/dropdown-menu.stories.tsx +3 -17
- package/src/components/DropdownMenu/dropdown-menu.tsx +58 -16
- package/src/components/Field/field-context.ts +25 -1
- package/src/components/Field/field-wrapper.tsx +7 -1
- package/src/components/Field/field.spec.md +8 -1
- package/src/components/Field/field.tsx +14 -2
- package/src/components/FieldControlGroup/field-control-group.anatomy.stories.tsx +3 -3
- package/src/components/FieldControlGroup/field-control-group.spec.md +2 -3
- package/src/components/FieldControlGroup/field-control-group.stories.tsx +2 -1
- package/src/components/FieldControlGroup/field-control-group.tsx +6 -9
- package/src/components/FileItem/file-item.spec.md +1 -1
- package/src/components/FileItem/file-item.stories.tsx +1 -1
- package/src/components/FileUpload/file-upload.stories.tsx +32 -0
- package/src/components/FileUpload/file-upload.tsx +1 -1
- package/src/components/FileViewer/file-viewer.anatomy.stories.tsx +1 -1
- package/src/components/FileViewer/file-viewer.spec.md +1 -1
- package/src/components/FileViewer/file-viewer.stories.tsx +7 -0
- package/src/components/FileViewer/file-viewer.tsx +23 -5
- package/src/components/InlineEdit/inline-edit.spec.md +12 -0
- package/src/components/InlineEdit/inline-edit.stories.tsx +30 -19
- package/src/components/InlineEdit/inline-edit.tsx +94 -31
- package/src/components/Input/input.anatomy.stories.tsx +28 -12
- package/src/components/Input/input.principles.stories.tsx +23 -18
- package/src/components/Input/input.stories.tsx +9 -1
- package/src/components/Input/input.tsx +7 -2
- package/src/components/LinkInput/link-input.principles.stories.tsx +7 -7
- package/src/components/LinkInput/link-input.spec.md +1 -1
- package/src/components/LinkInput/link-input.tsx +5 -1
- package/src/components/Menu/menu-item.anatomy.stories.tsx +1 -1
- package/src/components/Menu/menu-item.tsx +9 -2
- package/src/components/NumberInput/number-input.anatomy.stories.tsx +44 -10
- package/src/components/NumberInput/number-input.principles.stories.tsx +20 -14
- package/src/components/NumberInput/number-input.spec.md +1 -1
- package/src/components/NumberInput/number-input.stories.tsx +12 -5
- package/src/components/PeoplePicker/people-picker.anatomy.stories.tsx +7 -0
- package/src/components/PeoplePicker/people-picker.spec.md +3 -1
- package/src/components/PeoplePicker/people-picker.tsx +5 -0
- package/src/components/Popover/popover.tsx +7 -2
- package/src/components/ProgressBar/progress-bar.principles.stories.tsx +14 -12
- package/src/components/RadioGroup/radio-group.anatomy.stories.tsx +5 -1
- package/src/components/RadioGroup/radio-group.spec.md +1 -1
- package/src/components/Rating/rating.principles.stories.tsx +2 -2
- package/src/components/ScrollArea/scroll-area.anatomy.stories.tsx +1 -1
- package/src/components/ScrollArea/scroll-area.spec.md +3 -3
- package/src/components/ScrollArea/scroll-area.tsx +5 -4
- package/src/components/Select/select.principles.stories.tsx +4 -3
- package/src/components/Select/select.stories.tsx +7 -6
- package/src/components/Select/select.tsx +61 -29
- package/src/components/SelectMenu/select-menu.spec.md +1 -1
- package/src/components/SelectMenu/select-menu.tsx +4 -1
- package/src/components/SelectionControl/selection-item.anatomy.stories.tsx +19 -8
- package/src/components/SelectionControl/selection-item.stories.tsx +7 -7
- package/src/components/Sheet/sheet.spec.md +1 -1
- package/src/components/Sidebar/sidebar.spec.md +3 -2
- package/src/components/Sidebar/sidebar.stories.tsx +67 -37
- package/src/components/Sidebar/sidebar.tsx +3 -3
- package/src/components/Slider/slider.principles.stories.tsx +9 -9
- package/src/components/Steps/steps.spec.md +1 -0
- package/src/components/Steps/steps.stories.tsx +18 -1
- package/src/components/Switch/switch.anatomy.stories.tsx +11 -11
- package/src/components/Switch/switch.principles.stories.tsx +11 -8
- package/src/components/Tabs/tabs.principles.stories.tsx +24 -0
- package/src/components/Tabs/tabs.spec.md +6 -4
- package/src/components/Tabs/tabs.tsx +11 -0
- package/src/components/Tag/tag.anatomy.stories.tsx +5 -2
- package/src/components/Tag/tag.spec.md +4 -3
- package/src/components/Tag/tag.stories.tsx +19 -0
- package/src/components/Tag/tag.tsx +14 -5
- package/src/components/Textarea/textarea.anatomy.stories.tsx +15 -9
- package/src/components/Textarea/textarea.principles.stories.tsx +21 -5
- package/src/components/Textarea/textarea.spec.md +10 -1
- package/src/components/Textarea/textarea.tsx +38 -5
- package/src/components/TimePicker/time-picker.tsx +11 -5
- package/src/components/Tooltip/tooltip.spec.md +10 -0
- package/src/components/Tooltip/tooltip.tsx +34 -3
- package/src/components/TreeView/tree-view.spec.md +3 -3
- package/src/components/TreeView/tree-view.stories.tsx +68 -9
- package/src/components/TreeView/tree-view.tsx +7 -2
- package/src/index.ts +9 -1
- package/src/patterns/element-anatomy/inline-action.spec.md +12 -8
- package/src/patterns/element-anatomy/item-anatomy.spec.md +8 -1
- package/src/patterns/element-anatomy/item-anatomy.stories.tsx +24 -5
- package/src/patterns/element-anatomy/item-anatomy.tsx +120 -35
- package/src/patterns/element-anatomy/truncated-text.spec.md +13 -2
- package/src/patterns/header-canonical/chrome-header.tsx +14 -5
- package/src/patterns/header-canonical/header-canonical.spec.md +10 -7
- package/src/patterns/header-canonical/header-canonical.stories.tsx +77 -0
- package/src/patterns/horizontal-overflow/horizontal-overflow.stories.tsx +2 -0
- package/src/patterns/overlay-surface/overlay-surface.spec.md +1 -0
- package/src/patterns/overlay-surface/overlay-surface.stories.tsx +17 -1
- package/src/patterns/overlay-surface/overlay-surface.tsx +8 -4
- package/src/patterns/resize-handle/resize-handle.spec.md +11 -13
- package/src/patterns/resize-handle/resize-handle.stories.tsx +1 -3
- package/src/patterns/resize-handle/resize-handle.tsx +13 -18
- package/src/tokens/color/semantic.css +3 -1
- package/src/tokens/layoutSpace/layoutSpace.stories.tsx +1 -1
- package/src/tokens/opacity/opacity.stories.tsx +1 -1
- package/src/tokens/radius/radius.stories.tsx +3 -3
- package/src/tokens/uiSize/uiSize.css +11 -0
- package/src/tokens/uiSize/uiSize.spec.md +1 -0
- package/ds-canonical/commands/gov-status.md +0 -9
- package/ds-canonical/fork/consumer/managed-files/77e06f62670dfee01e9b5e8b0f8dad085ce711d75538c1fb0679d9818acaca82.blob +0 -424
- package/ds-canonical/fork/preamble.md +0 -500
- package/ds-canonical/hooks/check_post_main_ssot_propagate.sh +0 -8
- package/ds-canonical/hooks/tests/test_check_post_main_ssot_propagate.sh +0 -37
|
@@ -120,6 +120,83 @@ export const WithTabs = () => (
|
|
|
120
120
|
)
|
|
121
121
|
WithTabs.storyName = '含分頁列'
|
|
122
122
|
|
|
123
|
+
/* 3-4. withTabs × overflow(scroll / menu)— header 分頁列在窄容器的溢出模式。
|
|
124
|
+
對標 Jira 專案設定頁:細分頁多到單行放不下(概覽/待辦清單/衝刺/看板/報表/版本/元件/權限/通知)。
|
|
125
|
+
Panel 限寬 420px + 9 個分頁強制觸發溢出;W2 契約(triggers 內縮 px-loose 對齊 header
|
|
126
|
+
content row)三種 overflow 模式同享,border 隨溢出內容延展(min-w-full,header-canonical.spec.md Rule W2)。
|
|
127
|
+
兩則共用同組分頁資料(同 tabs.stories.tsx OverflowScroll/OverflowMenu 精神),各教一種溢出機制。 */
|
|
128
|
+
const projectSettingsTabs = [
|
|
129
|
+
{ value: 'overview', label: '概覽', content: '負責人:張惟安 · 分類:客戶關係 · Scrum 流程已啟用' },
|
|
130
|
+
{ value: 'backlog', label: '待辦清單', content: 'Backlog 42 項:預設排序 = 優先級,顯示 story point 欄位' },
|
|
131
|
+
{ value: 'sprints', label: '衝刺', content: 'Sprint 18 進行中(04/14–04/28),完成 21 / 34 點' },
|
|
132
|
+
{ value: 'board', label: '看板', content: '欄位:待處理 / 進行中 / 審查中 / 完成;WIP 上限 5' },
|
|
133
|
+
{ value: 'reports', label: '報表', content: '燃盡圖 / 速度圖 / 累積流量圖,每週一自動寄送摘要' },
|
|
134
|
+
{ value: 'releases', label: '版本', content: 'v2.4.0 規劃中(05/30 發布)· v2.3.1 已發布' },
|
|
135
|
+
{ value: 'components', label: '元件', content: '前端 / API / 資料庫 / 通知服務,各自指派預設負責人' },
|
|
136
|
+
{ value: 'permissions', label: '權限', content: '管理員 3 人 · 成員 24 人;訪客僅能檢視看板' },
|
|
137
|
+
{ value: 'notifications', label: '通知', content: '議題指派與提及即時通知;摘要每日 09:00 寄送' },
|
|
138
|
+
] as const
|
|
139
|
+
|
|
140
|
+
/** 3. withTabs + overflow="scroll" — 窄 header 的分頁列單行橫向捲動(fade mask + 左右 arrow)。 */
|
|
141
|
+
export const WithTabsOverflowScroll = () => (
|
|
142
|
+
<div className="w-[420px]">
|
|
143
|
+
<Panel>
|
|
144
|
+
<Tabs defaultValue="overview">
|
|
145
|
+
<ChromeHeader
|
|
146
|
+
tabsSlot={
|
|
147
|
+
<TabsList overflow="scroll">
|
|
148
|
+
{projectSettingsTabs.map((t) => (
|
|
149
|
+
<TabsTrigger key={t.value} value={t.value}>{t.label}</TabsTrigger>
|
|
150
|
+
))}
|
|
151
|
+
</TabsList>
|
|
152
|
+
}
|
|
153
|
+
>
|
|
154
|
+
<h2 className="flex-1 truncate text-body-lg font-medium text-foreground">
|
|
155
|
+
CRM 平台 — 專案設定
|
|
156
|
+
</h2>
|
|
157
|
+
<Button iconOnly dismiss size="sm" startIcon={X} aria-label="關閉" />
|
|
158
|
+
</ChromeHeader>
|
|
159
|
+
{projectSettingsTabs.map((t) => (
|
|
160
|
+
<TabsContent key={t.value} value={t.value}>
|
|
161
|
+
<div className="p-6 text-body text-fg-secondary">{t.content}</div>
|
|
162
|
+
</TabsContent>
|
|
163
|
+
))}
|
|
164
|
+
</Tabs>
|
|
165
|
+
</Panel>
|
|
166
|
+
</div>
|
|
167
|
+
)
|
|
168
|
+
WithTabsOverflowScroll.storyName = '含分頁列 — 溢出水平捲動'
|
|
169
|
+
|
|
170
|
+
/** 4. withTabs + overflow="menu" — 窄 header 的分頁列 + 右側 ⌄ 導覽選單(show-all navigator)。 */
|
|
171
|
+
export const WithTabsOverflowMenu = () => (
|
|
172
|
+
<div className="w-[420px]">
|
|
173
|
+
<Panel>
|
|
174
|
+
<Tabs defaultValue="overview">
|
|
175
|
+
<ChromeHeader
|
|
176
|
+
tabsSlot={
|
|
177
|
+
<TabsList overflow="menu">
|
|
178
|
+
{projectSettingsTabs.map((t) => (
|
|
179
|
+
<TabsTrigger key={t.value} value={t.value}>{t.label}</TabsTrigger>
|
|
180
|
+
))}
|
|
181
|
+
</TabsList>
|
|
182
|
+
}
|
|
183
|
+
>
|
|
184
|
+
<h2 className="flex-1 truncate text-body-lg font-medium text-foreground">
|
|
185
|
+
CRM 平台 — 專案設定
|
|
186
|
+
</h2>
|
|
187
|
+
<Button iconOnly dismiss size="sm" startIcon={X} aria-label="關閉" />
|
|
188
|
+
</ChromeHeader>
|
|
189
|
+
{projectSettingsTabs.map((t) => (
|
|
190
|
+
<TabsContent key={t.value} value={t.value}>
|
|
191
|
+
<div className="p-6 text-body text-fg-secondary">{t.content}</div>
|
|
192
|
+
</TabsContent>
|
|
193
|
+
))}
|
|
194
|
+
</Tabs>
|
|
195
|
+
</Panel>
|
|
196
|
+
</div>
|
|
197
|
+
)
|
|
198
|
+
WithTabsOverflowMenu.storyName = '含分頁列 — 溢出 ⌄ 導覽選單'
|
|
199
|
+
|
|
123
200
|
/** Overview — header anatomy 兩型疊起來一次看完,每型上方標清「何時用 + 對標既有元件」。
|
|
124
201
|
* 注:ChromeHeader 另有 `leadingRail` slot,但它專為「跟 sidebar 收合 icon 對齊」而生(寬 = sidebar 收合寬),
|
|
125
202
|
* 只在有 sidebar 時有意義 → canonical demo 放 AppShell primary-header(leadingRail = <SidebarTrigger />),
|
|
@@ -65,6 +65,8 @@ function FilmstripScrollDemo() {
|
|
|
65
65
|
<div className="relative w-[480px]">
|
|
66
66
|
<div
|
|
67
67
|
ref={scrollRef}
|
|
68
|
+
tabIndex={0}
|
|
69
|
+
aria-label="簡報頁面縮圖"
|
|
68
70
|
className="overflow-x-auto overflow-y-hidden [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
|
|
69
71
|
style={{ maskImage, WebkitMaskImage: maskImage }}
|
|
70
72
|
>
|
|
@@ -32,6 +32,7 @@ Dialog 和 Popover 的**結構化 sub-components 共用 primitive**——提供
|
|
|
32
32
|
### SurfaceBody
|
|
33
33
|
- `px-[var(--layout-space-loose)] py-[var(--layout-space-tight)]`
|
|
34
34
|
- **永遠套 `flex-1 min-h-0 overflow-y-auto`**(viewport-aware scroll:視窗太小時 body 內捲動;非 flex-col parent 內 flex-1/min-h-0 為 no-op,backward compat)。2026-05-31 infra-audit 修:原寫「無額外 flex 屬性」與 code(overlay-surface.tsx:183 恆套)矛盾。consumer 依浮層類型:
|
|
35
|
+
- **Focus ownership**:SurfaceBody 不預設 `tabIndex`——短內容時它不是 scroll region,一律塞進 sequential focus order 會製造多餘 tab stop。當 bare SurfaceBody 在定高/viewport 壓縮下**實際 overflow**時,consumer 必須傳 `tabIndex={0}` + `role="region"` + 語意明確的 `aria-label`;SurfaceBody runtime 內建 inset DS focus ring。`BodyScroll` story 的 play assertion 機械驗證該具名節點確實 overflow 且可聚焦。Dialog / Sheet 正式 consumer 仍優先走下節 ScrollArea canonical。
|
|
35
36
|
- **Popover**:多數 bare consume,padding 即是總 padding
|
|
36
37
|
- **Dialog / Sheet**:consumer **不直接 wrap SurfaceBody**——走 ScrollArea canonical(下節),padding 搬到 ScrollArea viewport 內層 div
|
|
37
38
|
- **邊界**:空 children → 不渲染 placeholder、無最小高度(定高浮層內仍被 `flex-1` 撐滿剩餘空間);viewport 極小 → 見「Viewport-aware scroll chain invariant」節(body 內捲動);loading / error / empty 屬 consumer 內容層職責,非本 structural pattern(見 `dialog.spec.md`「狀態處理的職責邊界」)
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// DialogHeader / SheetHeader / PopoverHeader 等 wrapper,不直接 import;
|
|
6
6
|
// 本頁給 DS contributor 看「overlay 三段式結構 + padding / 分隔線契約」長什麼樣。
|
|
7
7
|
import type { Meta, StoryObj } from '@storybook/react'
|
|
8
|
+
import { expect, within } from '@storybook/test'
|
|
8
9
|
import type { ReactNode } from 'react'
|
|
9
10
|
import { X } from 'lucide-react'
|
|
10
11
|
import { cn } from '@/lib/utils'
|
|
@@ -91,7 +92,11 @@ export const BodyScroll: Story = {
|
|
|
91
92
|
<h2 className="flex-1 truncate text-body-lg font-medium text-foreground">服務條款更新</h2>
|
|
92
93
|
<Button iconOnly dismiss size="sm" startIcon={X} aria-label="關閉" />
|
|
93
94
|
</SurfaceHeader>
|
|
94
|
-
<SurfaceBody
|
|
95
|
+
<SurfaceBody
|
|
96
|
+
tabIndex={0}
|
|
97
|
+
role="region"
|
|
98
|
+
aria-label="服務條款更新內容"
|
|
99
|
+
>
|
|
95
100
|
<div className="flex flex-col gap-3 text-body text-foreground">
|
|
96
101
|
<p>1. 資料保存期限由 30 天調整為 90 天,到期後自動匿名化。</p>
|
|
97
102
|
<p>2. 新增歐盟區域資料中心選項,既有工作區可在設定頁遷移。</p>
|
|
@@ -113,4 +118,15 @@ export const BodyScroll: Story = {
|
|
|
113
118
|
</p>
|
|
114
119
|
</div>
|
|
115
120
|
),
|
|
121
|
+
play: async ({ canvasElement }) => {
|
|
122
|
+
const canvas = within(canvasElement)
|
|
123
|
+
const scrollRegion = canvas.getByRole('region', {
|
|
124
|
+
name: '服務條款更新內容',
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
await expect(scrollRegion.scrollHeight).toBeGreaterThan(scrollRegion.clientHeight)
|
|
128
|
+
await expect(scrollRegion).toHaveAttribute('tabindex', '0')
|
|
129
|
+
scrollRegion.focus()
|
|
130
|
+
await expect(scrollRegion).toHaveFocus()
|
|
131
|
+
},
|
|
116
132
|
}
|
|
@@ -90,9 +90,10 @@ export interface SurfaceHeaderProps
|
|
|
90
90
|
* Tabs row slot(2026-05-18 加 per header-canonical.spec.md W2/W4 真實能用 + user-mandated fix)。
|
|
91
91
|
* 提供時 SurfaceHeader 自動 column 結構:
|
|
92
92
|
* row 1 = children(title + actions/dismiss,px-loose py-tight)
|
|
93
|
-
* row 2 = tabsSlot 包在 `HEADER_TABS_SLOT_WRAPPER_CLASS` wrapper(
|
|
94
|
-
* 無 px / 無 border
|
|
95
|
-
*
|
|
93
|
+
* row 2 = tabsSlot 包在 `HEADER_TABS_SLOT_WRAPPER_CLASS` wrapper(v4:wrapper 自身
|
|
94
|
+
* 無 px / 無 border;`[&_[data-slot=tabs-list]]` 注入 px-loose,寬度 TabsList
|
|
95
|
+
* 各 overflow 模式自帶,border-b 延展全寬 — W1 視覺一條線。
|
|
96
|
+
* 詳 chrome-header.tsx HEADER_TABS_SLOT_WRAPPER_CLASS 註解)
|
|
96
97
|
*
|
|
97
98
|
* Consumer 傳:`tabsSlot={<TabsList>...</TabsList>}`,TabsContent 仍放 DialogBody 內。
|
|
98
99
|
* `<Tabs>` root 必須 wrap 整 DialogContent(Radix TabsList ↔ TabsContent 同 root 連動)。
|
|
@@ -133,8 +134,10 @@ export const SurfaceHeader = React.forwardRef<
|
|
|
133
134
|
- v1: wrapper border + TabsList border = 雙線(W1 違反)
|
|
134
135
|
- v2: wrapper px-loose + TabsList w-full inside = border 只跨 dialog - 2×px-loose
|
|
135
136
|
(不到 dialog 邊 user 抓「分隔線寬度應該要填滿整個 dialog」)
|
|
136
|
-
- v3
|
|
137
|
+
- v3:wrapper 不 inset,TabsList 自己 px-loose 內 padding inset triggers
|
|
137
138
|
→ TabsList border-b 延展全 dialog 寬,triggers 對齊 header content
|
|
139
|
+
- v4(2026-07-30):選取機制改 `data-slot="tabs-list"` attribute contract
|
|
140
|
+
(beta.86 overlay 包裹層破 direct-child;詳 chrome-header.tsx 註解)
|
|
138
141
|
對齊既有 `tabs.spec.md`「Underline 與 TabsList border 的視覺關係」段「selected 底線從
|
|
139
142
|
TabsList 的 gray border 位置長出來」(token = border-divider,tabs.tsx TABS_LIST_BASE)
|
|
140
143
|
+ GitHub Primer UnderlineNav / Ant Design line type / Mantine default 共識
|
|
@@ -181,6 +184,7 @@ export const SurfaceBody = React.forwardRef<
|
|
|
181
184
|
ref={ref}
|
|
182
185
|
className={cn(
|
|
183
186
|
'flex-1 min-h-0 overflow-y-auto',
|
|
187
|
+
'focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-ring',
|
|
184
188
|
'px-[var(--layout-space-loose)] py-[var(--layout-space-tight)]',
|
|
185
189
|
className,
|
|
186
190
|
)}
|
|
@@ -15,14 +15,14 @@ benchmark:
|
|
|
15
15
|
|
|
16
16
|
## 定位
|
|
17
17
|
|
|
18
|
-
**Drag-to-resize
|
|
18
|
+
**Drag-to-resize 視覺共同 primitive**——統一 column resize / sidebar drag-resize / row resize / panel resize 的命中區、cursor 與視覺 line。
|
|
19
19
|
|
|
20
20
|
**消費者(計畫)**:
|
|
21
21
|
- DataTable column resize(目前自畫 — Phase 2 migrate)
|
|
22
22
|
- Sidebar drag-resize(目前無 — Phase 3 enable)
|
|
23
23
|
- AppShell Aside drag-resize(目前無 — Phase 4 enable)
|
|
24
24
|
|
|
25
|
-
**不耦合 drag math** — consumer 自管 width state(TanStack `header.getResizeHandler()` / 手刻 pointer math / `useResizeObserver` 各種路徑)。本 primitive only ship 視覺 + cursor
|
|
25
|
+
**不耦合 drag math** — consumer 自管 width state(TanStack `header.getResizeHandler()` / 手刻 pointer math / `useResizeObserver` 各種路徑)。本 primitive only ship 視覺 + cursor,且固定 aria-hidden。
|
|
26
26
|
|
|
27
27
|
**Layout Family**:N/A(self-contained primitive,非 row-layout family member)。
|
|
28
28
|
|
|
@@ -38,7 +38,6 @@ benchmark:
|
|
|
38
38
|
position="end" // | "start"
|
|
39
39
|
isResizing?: boolean // consumer 自管 drag state
|
|
40
40
|
disabled?: boolean // consumer 自決 resizable opt-in
|
|
41
|
-
aria-label="拖曳調整欄寬" // 必傳
|
|
42
41
|
showLine?: boolean // default true,false = consumer paint own line
|
|
43
42
|
lineInsetStart?: string // line start inset(eg. var(--table-cell-py))
|
|
44
43
|
lineInsetEnd?: string // line end inset
|
|
@@ -46,11 +45,11 @@ benchmark:
|
|
|
46
45
|
/>
|
|
47
46
|
```
|
|
48
47
|
|
|
49
|
-
上方為自有(own)props。drag handler(`onPointerDownCapture` / `onPointerDown` / `onTouchStart` 等)**非本元件 bespoke typed prop**,而是經 `ResizeHandleProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'role'
|
|
48
|
+
上方為自有(own)props。drag handler(`onPointerDownCapture` / `onPointerDown` / `onTouchStart` 等)**非本元件 bespoke typed prop**,而是經 `ResizeHandleProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'role' | 'aria-label' | 'aria-orientation' | 'aria-hidden'>` 的 `...restProps` spread 透傳到底層 `<span>`(與 `onClick` / `onPointerMove` 等 generic DOM 事件同 status)。上述四個 ARIA props 由 primitive 固定為誠實的純 pointer decoration 契約,consumer 不可覆寫。consumer 接 drag math 即透過這些透傳事件,本 primitive 不耦合。
|
|
50
49
|
|
|
51
50
|
**direction**:
|
|
52
|
-
- `horizontal`(拖左右)→ `cursor: col-resize`
|
|
53
|
-
- `vertical`(拖上下)→ `cursor: row-resize`
|
|
51
|
+
- `horizontal`(拖左右)→ `cursor: col-resize`
|
|
52
|
+
- `vertical`(拖上下)→ `cursor: row-resize`
|
|
54
53
|
|
|
55
54
|
**position**:`end` 命中區在右(horizontal)/ 底(vertical)— column right edge / sidebar right edge 典型;`start` 左 / 上 — 罕用。
|
|
56
55
|
|
|
@@ -69,9 +68,8 @@ benchmark:
|
|
|
69
68
|
|
|
70
69
|
## a11y
|
|
71
70
|
|
|
72
|
-
-
|
|
73
|
-
-
|
|
74
|
-
- `disabled` 時不掛 role / orientation / label(語意正確 — disabled separator 不該為 a11y tree 入口)
|
|
71
|
+
- 固定 `aria-hidden="true"`:目前只有 pointer hit target / visual line,沒有 focus、`aria-valuenow/min/max`、`aria-controls` 或 Arrow-key 行為,不能冒充 WAI-ARIA separator/window-splitter widget。
|
|
72
|
+
- consumer 若把 resize 作為必要功能,必須另提供 keyboard-operable 等價控制;完整 splitter widget 需由新元件一次擁有 value、controls 與鍵盤 contract,不能在本 visual primitive 上零碎加 ARIA。
|
|
75
73
|
|
|
76
74
|
## 何時用 / 何時不用
|
|
77
75
|
|
|
@@ -84,10 +82,10 @@ benchmark:
|
|
|
84
82
|
|
|
85
83
|
## 邊界案例
|
|
86
84
|
|
|
87
|
-
- **Disabled**:仍渲染 1px line(`bg-divider`,無 hover affordance),但無 cursor、無 `select-none
|
|
85
|
+
- **Disabled**:仍渲染 1px line(`bg-divider`,無 hover affordance),但無 cursor、無 `select-none`;所有狀態皆固定從 accessibility tree 隱藏。
|
|
88
86
|
- **拖到 min / max 卡住**:primitive 不持 width state(不耦合 drag math),邊界 clamp 與卡住回饋由 consumer 的 resize handler 管;`isResizing` 期間 line 維持 `bg-primary` 不另示警。
|
|
89
87
|
- **同列多 handle 並存**(多欄 column resize):各 handle 為獨立 `<span>`,無互相協調;`-3px` outward offset 使相鄰欄命中區可能相接,先命中者(DOM 順序 / pointer target)收事件,衝突仲裁屬 consumer drag math。
|
|
90
|
-
- **RTL
|
|
88
|
+
- **RTL**:全域明定 LTR-only;本元件使用 physical `left/right` 定位,不提供 RTL 鏡像。
|
|
91
89
|
|
|
92
90
|
## Roadmap(用 user 既有的 v2 framing)
|
|
93
91
|
|
|
@@ -110,11 +108,11 @@ Phase 2-4 需獨立 RFC + 各別 user approval,本 spec 只 ship Phase 1 + 鎖
|
|
|
110
108
|
| **VS Code** | 8px(activity bar)| bg highlight on drag | col-resize | aria-label "Resize" |
|
|
111
109
|
| **Figma** | 8px | 1px line | col-resize | role separator |
|
|
112
110
|
|
|
113
|
-
|
|
111
|
+
視覺共識是 7-8px hit zone / 1px line / cursor 對應 direction;各產品 a11y contract 不一致。本 primitive 只收斂視覺,不把未實作的 splitter behavior 偽裝成 separator。
|
|
114
112
|
|
|
115
113
|
## 禁止事項
|
|
116
114
|
|
|
117
115
|
- ❌ 自畫 resize handle 視覺(`<div className="cursor-col-resize">`)— 必消費本 primitive
|
|
118
116
|
- ❌ 直接給 ResizeHandle 加 drag state hook(eg. `useColumnResize`)— drag math 是 consumer concern,不污染 primitive
|
|
119
117
|
- ❌ Phase 2/3/4 不走 RFC + user approval 自動 migrate — Audit-vs-execute 分權違反
|
|
120
|
-
- ❌
|
|
118
|
+
- ❌ 在本 pointer-only primitive 加 `role="separator"` / `aria-*value*`——完整 splitter 語意必須連同 keyboard/value/controls 一次實作
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @story-baseline: none — primitive 用 minimal scenario showcase visual + cursor
|
|
1
|
+
// @story-baseline: none — primitive 用 minimal scenario showcase visual + cursor
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react'
|
|
3
3
|
import * as React from 'react'
|
|
4
4
|
import { ResizeHandle } from './resize-handle'
|
|
@@ -21,7 +21,6 @@ const ColumnDemo: React.FC<{ isResizing?: boolean; disabled?: boolean }> = ({ is
|
|
|
21
21
|
position="end"
|
|
22
22
|
isResizing={isResizing}
|
|
23
23
|
disabled={disabled}
|
|
24
|
-
aria-label="拖曳調整欄寬"
|
|
25
24
|
/>
|
|
26
25
|
</div>
|
|
27
26
|
)
|
|
@@ -64,7 +63,6 @@ export const Vertical: Story = {
|
|
|
64
63
|
<ResizeHandle
|
|
65
64
|
direction="vertical"
|
|
66
65
|
position="end"
|
|
67
|
-
aria-label="拖曳調整面板高度"
|
|
68
66
|
/>
|
|
69
67
|
</div>
|
|
70
68
|
),
|
|
@@ -2,11 +2,11 @@ import * as React from 'react'
|
|
|
2
2
|
import { cn } from '@/lib/utils'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* ResizeHandle — pattern primitive for drag-to-resize visual
|
|
5
|
+
* ResizeHandle — pattern primitive for drag-to-resize visual hit target(2026-05-21 v1 ship per
|
|
6
6
|
* user「style 難道不用跟 data table column resize 維持 ssot」+「都照你建議做」approval)。
|
|
7
7
|
*
|
|
8
8
|
* ── 定位 ──
|
|
9
|
-
* 統一所有 drag-resize affordance 的視覺 / cursor /
|
|
9
|
+
* 統一所有 drag-resize affordance 的視覺 / cursor / 命中區。
|
|
10
10
|
* Consumer 自管 drag math(TanStack column resize / Sidebar drag-resize / Aside drag-resize
|
|
11
11
|
* 各有不同 width state pathway,本 primitive 不耦合)。
|
|
12
12
|
*
|
|
@@ -32,13 +32,16 @@ import { cn } from '@/lib/utils'
|
|
|
32
32
|
* - Figma left panel resize(8px hit zone + 1px line)
|
|
33
33
|
*
|
|
34
34
|
* 統一共識:hit zone ≥ 7px(fingertip-friendly)/ 1px visual line(non-intrusive)/
|
|
35
|
-
* hover affordance(stronger line) / drag feedback(primary highlight)
|
|
36
|
-
*
|
|
35
|
+
* hover affordance(stronger line) / drag feedback(primary highlight)。
|
|
36
|
+
*
|
|
37
|
+
* 本 primitive 目前只有 pointer drag visual/hit target,沒有 keyboard/value/controls contract;
|
|
38
|
+
* 因此固定從 accessibility tree 隱藏,不冒充 WAI-ARIA separator/window-splitter widget。
|
|
37
39
|
*/
|
|
38
|
-
export interface ResizeHandleProps
|
|
40
|
+
export interface ResizeHandleProps
|
|
41
|
+
extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'role' | 'aria-hidden' | 'aria-label' | 'aria-orientation'> {
|
|
39
42
|
/**
|
|
40
43
|
* Drag 方向。`horizontal` = 拖拉左右(column resize / sidebar width);
|
|
41
|
-
* `vertical` = 拖拉上下(row resize / panel height)。決定 cursor
|
|
44
|
+
* `vertical` = 拖拉上下(row resize / panel height)。決定 cursor。
|
|
42
45
|
*/
|
|
43
46
|
direction: 'horizontal' | 'vertical'
|
|
44
47
|
/**
|
|
@@ -53,11 +56,9 @@ export interface ResizeHandleProps extends Omit<React.HTMLAttributes<HTMLSpanEle
|
|
|
53
56
|
isResizing?: boolean
|
|
54
57
|
/**
|
|
55
58
|
* 是否禁用拖拉。consumer 透過 col / panel 的 resizable flag 決定。
|
|
56
|
-
* 禁用時不 render cursor
|
|
59
|
+
* 禁用時不 render cursor;元件所有狀態皆固定 aria-hidden。
|
|
57
60
|
*/
|
|
58
61
|
disabled?: boolean
|
|
59
|
-
/** a11y 描述性 label。consumer 必傳(eg. 「拖曳調整欄寬」/「拖曳調整側欄寬度」)。 */
|
|
60
|
-
'aria-label': string
|
|
61
62
|
/**
|
|
62
63
|
* 是否畫 visual line(1px divider)。`false` = consumer 已 paint(eg. DataTable panel
|
|
63
64
|
* boundary col by panel-r 接管,不重複)。Default `true`。
|
|
@@ -82,7 +83,6 @@ export interface ResizeHandleProps extends Omit<React.HTMLAttributes<HTMLSpanEle
|
|
|
82
83
|
* position="end"
|
|
83
84
|
* isResizing={header.column.getIsResizing?.()}
|
|
84
85
|
* disabled={!isResizable}
|
|
85
|
-
* aria-label="拖曳調整欄寬"
|
|
86
86
|
* onPointerDownCapture={(e) => {
|
|
87
87
|
* e.stopPropagation()
|
|
88
88
|
* header.getResizeHandler?.()(e.nativeEvent)
|
|
@@ -96,7 +96,6 @@ export interface ResizeHandleProps extends Omit<React.HTMLAttributes<HTMLSpanEle
|
|
|
96
96
|
* direction="horizontal"
|
|
97
97
|
* position="end"
|
|
98
98
|
* isResizing={isDragging}
|
|
99
|
-
* aria-label="拖曳調整側欄寬度"
|
|
100
99
|
* onPointerDown={startDrag}
|
|
101
100
|
* />
|
|
102
101
|
* ```
|
|
@@ -117,7 +116,6 @@ export const ResizeHandle = React.forwardRef<HTMLSpanElement, ResizeHandleProps>
|
|
|
117
116
|
ref,
|
|
118
117
|
) => {
|
|
119
118
|
const isHorizontal = direction === 'horizontal'
|
|
120
|
-
const ariaOrientation = isHorizontal ? 'vertical' : 'horizontal' // separator's axis is perpendicular to drag
|
|
121
119
|
|
|
122
120
|
// 命中區用 inline style 而非 Tailwind arbitrary values(避免 Tailwind v4 JIT 對新增 arbitrary
|
|
123
121
|
// class 在 dev mode 不更新 stylesheet 的 quirk;7px 是 primitive constant 非 token,inline 妥當)。
|
|
@@ -162,17 +160,14 @@ export const ResizeHandle = React.forwardRef<HTMLSpanElement, ResizeHandleProps>
|
|
|
162
160
|
...(position === 'end' ? { bottom: 3 } : { top: 3 }),
|
|
163
161
|
}
|
|
164
162
|
|
|
165
|
-
|
|
166
|
-
const { 'aria-label': ariaLabel, style: extraStyle, ...restProps } = props
|
|
163
|
+
const { style: extraStyle, ...restProps } = props
|
|
167
164
|
return (
|
|
168
165
|
<span
|
|
169
166
|
ref={ref}
|
|
170
|
-
|
|
171
|
-
aria-
|
|
172
|
-
aria-label={disabled ? undefined : ariaLabel}
|
|
167
|
+
{...restProps}
|
|
168
|
+
aria-hidden="true"
|
|
173
169
|
style={{ ...hitZoneStyle, ...extraStyle }}
|
|
174
170
|
className={cn('group/resize', !disabled && 'select-none', className)}
|
|
175
|
-
{...restProps}
|
|
176
171
|
>
|
|
177
172
|
{showLine && (
|
|
178
173
|
<span
|
|
@@ -50,7 +50,9 @@
|
|
|
50
50
|
│ --fg-disabled disabled 文字(neutral-6) │
|
|
51
51
|
│ │
|
|
52
52
|
│ 文字色一律使用 neutral alpha,透明度疊加在任何背景皆可維持對比 │
|
|
53
|
-
│ 弱化 icon hover 後變 fg-secondary(neutral-8
|
|
53
|
+
│ 弱化 icon hover 後變 fg-secondary(neutral-8)— 往前一階不跳階 │
|
|
54
|
+
│ rule owner 對偶:patterns/element-anatomy/inline-action.spec.md │
|
|
55
|
+
│ 「Icon 色彩」段;機械強制 check_pattern_invariants.sh C.5 │
|
|
54
56
|
└─────────────────────────────────────────────────────────────────────┘
|
|
55
57
|
|
|
56
58
|
┌─ 互動狀態(引用色盤 step)─────────────────────────────────────────────┐
|
|
@@ -40,7 +40,7 @@ function SpaceRow({ utility, mdValue, lgValue, usage }: {
|
|
|
40
40
|
<div className="text-caption font-mono text-fg-muted">lg: {lgValue}</div>
|
|
41
41
|
<div className="text-body text-foreground">{usage}</div>
|
|
42
42
|
<div className="flex items-center justify-end">
|
|
43
|
-
<div className="bg-primary h-6" style={{ width: mdValue }}
|
|
43
|
+
<div aria-hidden="true" className="bg-primary h-6" style={{ width: mdValue }} />
|
|
44
44
|
</div>
|
|
45
45
|
</div>
|
|
46
46
|
)
|
|
@@ -33,9 +33,9 @@ function OpacityRow({ utility, value, usage }: { utility: string; value: string;
|
|
|
33
33
|
<div className="text-body text-foreground">{usage}</div>
|
|
34
34
|
<div className="flex items-center gap-2">
|
|
35
35
|
<div
|
|
36
|
+
aria-hidden="true"
|
|
36
37
|
className="h-8 w-8 rounded bg-primary"
|
|
37
38
|
style={{ opacity: parseFloat(value) }}
|
|
38
|
-
aria-label={`${utility} preview`}
|
|
39
39
|
/>
|
|
40
40
|
<span className="text-caption text-fg-muted">preview</span>
|
|
41
41
|
</div>
|
|
@@ -33,9 +33,9 @@ export const Overview: Story = {
|
|
|
33
33
|
<span className="text-caption text-fg-muted">2px — 極小 indicator(≤ 10px)</span>
|
|
34
34
|
</div>
|
|
35
35
|
<div className="flex flex-wrap gap-3 items-center">
|
|
36
|
-
<div className="rounded-xs bg-primary h-2 w-2"
|
|
37
|
-
<div className="rounded-xs bg-success h-2 w-2" />
|
|
38
|
-
<div className="rounded-xs bg-error h-2 w-2" />
|
|
36
|
+
<div aria-hidden="true" className="rounded-xs bg-primary h-2 w-2" />
|
|
37
|
+
<div aria-hidden="true" className="rounded-xs bg-success h-2 w-2" />
|
|
38
|
+
<div aria-hidden="true" className="rounded-xs bg-error h-2 w-2" />
|
|
39
39
|
<span className="text-caption text-fg-muted ml-2">Chart legend swatch(8×8 色塊):md 4px 在 8×8 上接近 50% 圓,xs 2px 保留「色塊」而非「膠囊」語意</span>
|
|
40
40
|
</div>
|
|
41
41
|
</div>
|
|
@@ -24,6 +24,17 @@
|
|
|
24
24
|
--field-height-md: 2rem; /* 32px */
|
|
25
25
|
--field-height-lg: 2.25rem; /* 36px */
|
|
26
26
|
|
|
27
|
+
/* Field control vertical padding — 讓「單行的多行控件」與同 size 單行 Input 等高 SSOT。
|
|
28
|
+
公式 = (field-height − 1lh)/2 − 1px:`1lh` 在使用端解析成該元素自己的行高(text-body 21px /
|
|
29
|
+
text-body-lg 24px),`−1px` 補 border-box 內的上下各 1px 邊框——少了它三個 size 都會高 2px。
|
|
30
|
+
density 自動連動(引用 --field-height-*,lg density 覆寫後公式仍成立)。
|
|
31
|
+
消費者:Textarea edit base + fieldViewGeometry 多行 view(兩者相等 = InlineEdit 多行零跳契約,
|
|
32
|
+
由 scripts/inline-edit-view-geometry-invariant.mjs 機械鎖)。
|
|
33
|
+
DataTable cell 不消費此 token——cell 的 padding 載體無邊框,自有 --table-cell-py 公式。 */
|
|
34
|
+
--field-control-py-sm: calc((var(--field-height-sm) - 1lh) / 2 - 1px);
|
|
35
|
+
--field-control-py-md: calc((var(--field-height-md) - 1lh) / 2 - 1px);
|
|
36
|
+
--field-control-py-lg: calc((var(--field-height-lg) - 1lh) / 2 - 1px);
|
|
37
|
+
|
|
27
38
|
/* Field horizontal padding — 固定 12px(不隨 size/density);form-context field 左右內距 SSOT。
|
|
28
39
|
跟 --table-cell-px(cell-context)同 -px 慣例;Input/Select/Combobox/DatePicker/TimePicker/Textarea
|
|
29
40
|
+ tag 模式右緣 re-assert 全消費此 token(取代散落的 px-3 / inline 0.75rem,M17 SSOT 可傳播)。 */
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Retired command compatibility pointer
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# `/gov-status` retired
|
|
6
|
-
|
|
7
|
-
This one-time Genesis compatibility file has no executable workflow. Use the
|
|
8
|
-
provider-neutral `governance-status` skill. The distinct protected cleanup PR
|
|
9
|
-
removes this legacy command path after the A/M-only transition closes.
|