@qijenchen/design-system 0.1.0-beta.84 → 0.1.0-beta.86
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/AGENTS.md +210 -0
- package/CLAUDE.md +17 -191
- package/cli-init.mjs +30 -2
- package/dist/components/Accordion/accordion.d.ts +2 -2
- package/dist/components/Accordion/accordion.d.ts.map +1 -1
- package/dist/components/Accordion/accordion.js.map +1 -1
- package/dist/components/Avatar/avatar.js +1 -1
- package/dist/components/Avatar/avatar.js.map +1 -1
- package/dist/components/BulkActionBar/bulk-action-bar.d.ts +1 -1
- package/dist/components/BulkActionBar/bulk-action-bar.d.ts.map +1 -1
- package/dist/components/BulkActionBar/bulk-action-bar.js +3 -3
- package/dist/components/BulkActionBar/bulk-action-bar.js.map +1 -1
- package/dist/components/Button/button-group.d.ts +2 -2
- package/dist/components/Button/button-group.d.ts.map +1 -1
- package/dist/components/Button/button-group.js +2 -2
- package/dist/components/Button/button-group.js.map +1 -1
- package/dist/components/Button/button.d.ts +2 -1
- package/dist/components/Button/button.d.ts.map +1 -1
- package/dist/components/Button/button.js +1 -1
- package/dist/components/Button/button.js.map +1 -1
- package/dist/components/Carousel/carousel.d.ts +14 -8
- package/dist/components/Carousel/carousel.d.ts.map +1 -1
- package/dist/components/Carousel/carousel.js +64 -37
- package/dist/components/Carousel/carousel.js.map +1 -1
- package/dist/components/Checkbox/checkbox-group.d.ts.map +1 -1
- package/dist/components/Checkbox/checkbox-group.js +21 -14
- package/dist/components/Checkbox/checkbox-group.js.map +1 -1
- package/dist/components/Checkbox/checkbox.d.ts +2 -2
- package/dist/components/Checkbox/checkbox.d.ts.map +1 -1
- package/dist/components/Checkbox/checkbox.js +49 -10
- package/dist/components/Checkbox/checkbox.js.map +1 -1
- package/dist/components/Combobox/combobox.d.ts +15 -6
- package/dist/components/Combobox/combobox.d.ts.map +1 -1
- package/dist/components/Combobox/combobox.js +13 -7
- 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 +11 -2
- package/dist/components/Command/command.js.map +1 -1
- package/dist/components/DataTable/cell-registry.d.ts +5 -5
- package/dist/components/DataTable/cell-registry.d.ts.map +1 -1
- package/dist/components/DataTable/cell-registry.js +41 -38
- package/dist/components/DataTable/cell-registry.js.map +1 -1
- package/dist/components/DataTable/column-types.d.ts +1 -17
- package/dist/components/DataTable/column-types.d.ts.map +1 -1
- package/dist/components/DataTable/column-types.js.map +1 -1
- package/dist/components/DataTable/data-table-column-visibility-panel.d.ts.map +1 -1
- package/dist/components/DataTable/data-table-column-visibility-panel.js +71 -64
- package/dist/components/DataTable/data-table-column-visibility-panel.js.map +1 -1
- package/dist/components/DataTable/data-table-filter-group.d.ts +47 -0
- package/dist/components/DataTable/data-table-filter-group.d.ts.map +1 -0
- package/dist/components/DataTable/data-table-filter-group.js +154 -0
- package/dist/components/DataTable/data-table-filter-group.js.map +1 -0
- package/dist/components/DataTable/data-table-filter-panel.d.ts +0 -2
- package/dist/components/DataTable/data-table-filter-panel.d.ts.map +1 -1
- package/dist/components/DataTable/data-table-filter-panel.js +5 -328
- package/dist/components/DataTable/data-table-filter-panel.js.map +1 -1
- package/dist/components/DataTable/data-table-filter-value-picker.d.ts +29 -0
- package/dist/components/DataTable/data-table-filter-value-picker.d.ts.map +1 -0
- package/dist/components/DataTable/data-table-filter-value-picker.js +187 -0
- package/dist/components/DataTable/data-table-filter-value-picker.js.map +1 -0
- package/dist/components/DataTable/data-table-interaction-layer.d.ts +2 -2
- package/dist/components/DataTable/data-table-interaction-layer.js.map +1 -1
- package/dist/components/DataTable/data-table-sort-manager.js +2 -2
- package/dist/components/DataTable/data-table-sort-manager.js.map +1 -1
- package/dist/components/DataTable/data-table.d.ts +1 -1
- package/dist/components/DataTable/data-table.d.ts.map +1 -1
- package/dist/components/DataTable/data-table.js +44 -32
- package/dist/components/DataTable/data-table.js.map +1 -1
- package/dist/components/DatePicker/date-picker.d.ts +3 -3
- package/dist/components/DatePicker/date-picker.js +4 -4
- package/dist/components/DatePicker/date-picker.js.map +1 -1
- package/dist/components/DescriptionList/description-list.d.ts +3 -3
- package/dist/components/DescriptionList/description-list.d.ts.map +1 -1
- package/dist/components/DescriptionList/description-list.js +6 -6
- package/dist/components/DescriptionList/description-list.js.map +1 -1
- package/dist/components/Dialog/dialog.d.ts +2 -2
- package/dist/components/Dialog/dialog.d.ts.map +1 -1
- package/dist/components/Dialog/dialog.js.map +1 -1
- package/dist/components/DropdownMenu/dropdown-menu.d.ts +8 -3
- package/dist/components/DropdownMenu/dropdown-menu.d.ts.map +1 -1
- package/dist/components/DropdownMenu/dropdown-menu.js +7 -7
- package/dist/components/DropdownMenu/dropdown-menu.js.map +1 -1
- package/dist/components/Field/field-context.d.ts +16 -10
- package/dist/components/Field/field-context.d.ts.map +1 -1
- package/dist/components/Field/field-context.js.map +1 -1
- package/dist/components/Field/field-types.d.ts +2 -2
- package/dist/components/Field/field-types.d.ts.map +1 -1
- package/dist/components/Field/field-types.js.map +1 -1
- package/dist/components/Field/field-wrapper.d.ts +20 -4
- package/dist/components/Field/field-wrapper.d.ts.map +1 -1
- package/dist/components/Field/field-wrapper.js +30 -31
- package/dist/components/Field/field-wrapper.js.map +1 -1
- package/dist/components/Field/field.d.ts +1 -1
- package/dist/components/Field/field.d.ts.map +1 -1
- package/dist/components/Field/field.js +25 -3
- package/dist/components/Field/field.js.map +1 -1
- package/dist/components/Field/index.d.ts +1 -0
- package/dist/components/Field/index.d.ts.map +1 -1
- package/dist/components/Field/index.js +2 -0
- package/dist/components/Field/index.js.map +1 -1
- package/dist/components/Field/use-form-validation.d.ts +1 -1
- package/dist/components/Field/use-form-validation.js.map +1 -1
- package/dist/components/FileItem/file-item.d.ts.map +1 -1
- package/dist/components/FileItem/file-item.js +2 -5
- package/dist/components/FileItem/file-item.js.map +1 -1
- package/dist/components/FileUpload/file-upload.d.ts.map +1 -1
- package/dist/components/FileUpload/file-upload.js +5 -1
- package/dist/components/FileUpload/file-upload.js.map +1 -1
- package/dist/components/FileViewer/file-viewer.d.ts.map +1 -1
- package/dist/components/FileViewer/file-viewer.js +2 -1
- package/dist/components/FileViewer/file-viewer.js.map +1 -1
- package/dist/components/HoverCard/hover-card.d.ts +2 -2
- package/dist/components/HoverCard/hover-card.d.ts.map +1 -1
- package/dist/components/HoverCard/hover-card.js +4 -2
- package/dist/components/HoverCard/hover-card.js.map +1 -1
- package/dist/components/InlineEdit/inline-edit.d.ts +23 -16
- package/dist/components/InlineEdit/inline-edit.d.ts.map +1 -1
- package/dist/components/InlineEdit/inline-edit.js +104 -62
- package/dist/components/InlineEdit/inline-edit.js.map +1 -1
- package/dist/components/Input/input.d.ts +1 -1
- package/dist/components/Input/input.d.ts.map +1 -1
- package/dist/components/Input/input.js +6 -6
- package/dist/components/Input/input.js.map +1 -1
- package/dist/components/LinkInput/link-input.d.ts +5 -5
- package/dist/components/LinkInput/link-input.d.ts.map +1 -1
- package/dist/components/LinkInput/link-input.js +3 -3
- package/dist/components/LinkInput/link-input.js.map +1 -1
- package/dist/components/Notice/notice.d.ts +17 -1
- package/dist/components/Notice/notice.d.ts.map +1 -1
- package/dist/components/Notice/notice.js +7 -1
- package/dist/components/Notice/notice.js.map +1 -1
- package/dist/components/NumberInput/number-input.d.ts +1 -1
- package/dist/components/NumberInput/number-input.d.ts.map +1 -1
- package/dist/components/NumberInput/number-input.js +12 -1
- package/dist/components/NumberInput/number-input.js.map +1 -1
- package/dist/components/PeoplePicker/avatar-stack-overflow.d.ts +1 -1
- package/dist/components/PeoplePicker/avatar-stack-overflow.js.map +1 -1
- package/dist/components/PeoplePicker/people-picker.d.ts +5 -5
- package/dist/components/PeoplePicker/people-picker.d.ts.map +1 -1
- package/dist/components/PeoplePicker/people-picker.js +7 -5
- package/dist/components/PeoplePicker/people-picker.js.map +1 -1
- package/dist/components/PeoplePicker/person-display.d.ts +1 -1
- package/dist/components/PeoplePicker/person-display.js.map +1 -1
- package/dist/components/ProfileCard/profile-card.d.ts +1 -1
- package/dist/components/ProfileCard/profile-card.js.map +1 -1
- package/dist/components/RadioGroup/radio-group.d.ts +3 -3
- package/dist/components/RadioGroup/radio-group.d.ts.map +1 -1
- package/dist/components/RadioGroup/radio-group.js +1 -1
- package/dist/components/RadioGroup/radio-group.js.map +1 -1
- package/dist/components/Rating/rating.d.ts.map +1 -1
- package/dist/components/Rating/rating.js +4 -0
- package/dist/components/Rating/rating.js.map +1 -1
- package/dist/components/ScrollArea/scroll-area.d.ts +3 -2
- package/dist/components/ScrollArea/scroll-area.d.ts.map +1 -1
- package/dist/components/ScrollArea/scroll-area.js.map +1 -1
- package/dist/components/SegmentedControl/segmented-control.d.ts +4 -3
- package/dist/components/SegmentedControl/segmented-control.d.ts.map +1 -1
- package/dist/components/SegmentedControl/segmented-control.js.map +1 -1
- package/dist/components/Select/select.d.ts +16 -6
- package/dist/components/Select/select.d.ts.map +1 -1
- package/dist/components/Select/select.js +17 -5
- package/dist/components/Select/select.js.map +1 -1
- package/dist/components/SelectMenu/select-menu.d.ts +17 -1
- package/dist/components/SelectMenu/select-menu.d.ts.map +1 -1
- package/dist/components/SelectMenu/select-menu.js +17 -3
- package/dist/components/SelectMenu/select-menu.js.map +1 -1
- package/dist/components/SelectionControl/boolean-value.d.ts +1 -1
- package/dist/components/SelectionControl/boolean-value.js.map +1 -1
- package/dist/components/Sheet/sheet.d.ts +2 -2
- package/dist/components/Sheet/sheet.d.ts.map +1 -1
- package/dist/components/Sheet/sheet.js.map +1 -1
- package/dist/components/Sidebar/sidebar.d.ts +1 -1
- package/dist/components/Sidebar/sidebar.js +2 -2
- package/dist/components/Sidebar/sidebar.js.map +1 -1
- package/dist/components/Slider/slider.d.ts.map +1 -1
- package/dist/components/Slider/slider.js +6 -3
- package/dist/components/Slider/slider.js.map +1 -1
- package/dist/components/Steps/steps.d.ts +6 -4
- package/dist/components/Steps/steps.d.ts.map +1 -1
- package/dist/components/Steps/steps.js +19 -5
- package/dist/components/Steps/steps.js.map +1 -1
- package/dist/components/Switch/switch.d.ts +4 -4
- package/dist/components/Switch/switch.d.ts.map +1 -1
- package/dist/components/Switch/switch.js +3 -1
- package/dist/components/Switch/switch.js.map +1 -1
- package/dist/components/Tabs/tabs.d.ts +1 -1
- package/dist/components/Tabs/tabs.d.ts.map +1 -1
- package/dist/components/Tabs/tabs.js +73 -23
- package/dist/components/Tabs/tabs.js.map +1 -1
- package/dist/components/Tag/tag.d.ts +3 -1
- package/dist/components/Tag/tag.d.ts.map +1 -1
- package/dist/components/Tag/tag.js +2 -2
- package/dist/components/Tag/tag.js.map +1 -1
- package/dist/components/Textarea/textarea.d.ts +4 -4
- package/dist/components/Textarea/textarea.d.ts.map +1 -1
- package/dist/components/Textarea/textarea.js +15 -15
- package/dist/components/Textarea/textarea.js.map +1 -1
- package/dist/components/TimePicker/time-picker.d.ts +4 -4
- package/dist/components/TimePicker/time-picker.d.ts.map +1 -1
- package/dist/components/TimePicker/time-picker.js +8 -5
- package/dist/components/TimePicker/time-picker.js.map +1 -1
- package/dist/components/Tooltip/tooltip.d.ts.map +1 -1
- package/dist/components/Tooltip/tooltip.js +27 -23
- package/dist/components/Tooltip/tooltip.js.map +1 -1
- package/dist/components/TreeView/tree-view.d.ts.map +1 -1
- package/dist/components/TreeView/tree-view.js +16 -0
- package/dist/components/TreeView/tree-view.js.map +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -11
- package/dist/lib/drag-visual.d.ts +2 -2
- package/dist/lib/drag-visual.js.map +1 -1
- package/dist/lib/utils.d.ts +1 -0
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +21 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/patterns/element-anatomy/item-anatomy.d.ts +2 -0
- package/dist/patterns/element-anatomy/item-anatomy.d.ts.map +1 -1
- package/dist/patterns/element-anatomy/item-anatomy.js +2 -2
- package/dist/patterns/element-anatomy/item-anatomy.js.map +1 -1
- package/dist/tokens/categorical-color.d.ts +3 -3
- package/dist/tokens/categorical-color.d.ts.map +1 -1
- package/dist/tokens/categorical-color.js +2 -2
- package/dist/tokens/categorical-color.js.map +1 -1
- package/ds-canonical/fork/AGENTS.md +213 -0
- package/ds-canonical/fork/codex/agents/skills/independent-review/SKILL.md +33 -0
- package/ds-canonical/fork/codex/hooks.json +16 -0
- package/ds-canonical/fork/governance.lock +22 -7
- package/ds-canonical/fork/hooks/check_ds_anchor_preflight.sh +22 -1
- package/ds-canonical/fork/hooks/inject_deploy_url_after_push.sh +14 -2
- package/ds-canonical/fork/manifest.json +10 -1
- package/ds-canonical/fork/preamble.md +3 -2
- package/ds-canonical/fork/skills/product-ui-audit/SKILL.md +7 -7
- package/ds-canonical/fork/skills/ux-audit/SKILL.md +1 -1
- package/ds-canonical/fork/skills/visual-audit/SKILL.md +0 -1
- package/ds-canonical/hooks/check_codex_brief_invariants.sh +9 -3
- package/ds-canonical/hooks/check_datatable_invariants.sh +6 -3
- package/ds-canonical/hooks/check_ds_anchor_preflight.sh +22 -1
- package/ds-canonical/hooks/check_overlay_open_focus_escape_probe.sh +11 -2
- package/ds-canonical/hooks/check_plugin_fork_health.sh +17 -1
- package/ds-canonical/hooks/check_post_main_ssot_propagate.sh +21 -4
- package/ds-canonical/hooks/inject_deploy_url_after_push.sh +14 -2
- package/ds-canonical/hooks/session_start_governance_check.sh +10 -2
- package/ds-canonical/references/certified-surfaces.md +20 -0
- package/ds-canonical/references/preflight-gate-baseline.json +5 -0
- package/ds-canonical/references/principle-dim-map.json +20 -2
- package/ds-canonical/references/props-naming.md +2 -1
- package/ds-canonical/references/ssot-index.md +2 -2
- package/ds-canonical/references/story-baseline-registry.json +2 -2
- package/ds-canonical/rules/story-rules.md +1 -1
- package/ds-canonical/rules/ui-development.md +2 -1
- package/ds-canonical/skills/codex-collab/SKILL.md +7 -7
- package/ds-canonical/skills/codex-collab/references/brief-template.md +5 -1
- package/ds-canonical/skills/component-quality-gate/SKILL.md +1 -1
- package/ds-canonical/skills/deep-audit-cross-codex/SKILL.md +5 -5
- package/ds-canonical/skills/design-system-audit/SKILL.md +5 -5
- package/ds-canonical/skills/product-ui-audit/SKILL.md +7 -7
- package/ds-canonical/skills/ux-audit/SKILL.md +1 -1
- package/ds-canonical/skills/visual-audit/SKILL.md +0 -1
- package/ds-story-manifest.json +21 -21
- package/llms-full.txt +3 -3
- package/llms.txt +1 -1
- package/package.json +2 -1
- package/src/components/Accordion/accordion.anatomy.stories.tsx +11 -11
- package/src/components/Accordion/accordion.principles.stories.tsx +21 -6
- package/src/components/Accordion/accordion.spec.md +10 -1
- package/src/components/Accordion/accordion.stories.tsx +10 -5
- package/src/components/Accordion/accordion.tsx +7 -2
- package/src/components/Alert/alert.principles.stories.tsx +2 -8
- package/src/components/AppShell/app-shell.anatomy.stories.tsx +19 -13
- package/src/components/AppShell/app-shell.principles.stories.tsx +21 -21
- package/src/components/AppShell/app-shell.spec.md +4 -0
- package/src/components/AppShell/app-shell.stories.tsx +4 -5
- package/src/components/Avatar/avatar.tsx +1 -1
- package/src/components/Badge/badge.spec.md +2 -2
- package/src/components/Breadcrumb/breadcrumb.anatomy.stories.tsx +7 -3
- package/src/components/Breadcrumb/breadcrumb.principles.stories.tsx +4 -1
- package/src/components/Breadcrumb/breadcrumb.stories.tsx +1 -1
- package/src/components/BulkActionBar/bulk-action-bar.anatomy.stories.tsx +6 -6
- package/src/components/BulkActionBar/bulk-action-bar.principles.stories.tsx +18 -6
- package/src/components/BulkActionBar/bulk-action-bar.spec.md +15 -5
- package/src/components/BulkActionBar/bulk-action-bar.stories.tsx +8 -24
- package/src/components/BulkActionBar/bulk-action-bar.tsx +4 -4
- package/src/components/Button/button-group.tsx +4 -4
- package/src/components/Button/button.anatomy.stories.tsx +26 -7
- package/src/components/Button/button.principles.stories.tsx +1 -1
- package/src/components/Button/button.spec.md +2 -2
- package/src/components/Button/button.stories.tsx +22 -28
- package/src/components/Button/button.tsx +2 -1
- package/src/components/Calendar/calendar.anatomy.stories.tsx +1 -1
- package/src/components/Calendar/calendar.spec.md +1 -1
- package/src/components/Carousel/carousel.spec.md +17 -1
- package/src/components/Carousel/carousel.tsx +93 -42
- package/src/components/Checkbox/checkbox-group.tsx +26 -15
- package/src/components/Checkbox/checkbox.anatomy.stories.tsx +3 -3
- package/src/components/Checkbox/checkbox.spec.md +14 -3
- package/src/components/Checkbox/checkbox.stories.tsx +4 -4
- package/src/components/Checkbox/checkbox.tsx +79 -19
- package/src/components/Coachmark/coachmark.anatomy.stories.tsx +5 -5
- package/src/components/Coachmark/coachmark.principles.stories.tsx +1 -1
- package/src/components/Combobox/combobox.anatomy.stories.tsx +11 -4
- package/src/components/Combobox/combobox.principles.stories.tsx +10 -11
- package/src/components/Combobox/combobox.spec.md +6 -2
- package/src/components/Combobox/combobox.stories.tsx +9 -36
- package/src/components/Combobox/combobox.tsx +42 -27
- package/src/components/Command/command.spec.md +3 -3
- package/src/components/Command/command.tsx +9 -2
- package/src/components/DataTable/cell-registry.tsx +75 -76
- package/src/components/DataTable/column-types.ts +4 -17
- package/src/components/DataTable/data-table-column-visibility-panel.tsx +20 -7
- package/src/components/DataTable/data-table-filter-group.tsx +231 -0
- package/src/components/DataTable/data-table-filter-panel.tsx +19 -436
- package/src/components/DataTable/data-table-filter-value-picker.tsx +237 -0
- package/src/components/DataTable/data-table-interaction-layer.tsx +3 -3
- package/src/components/DataTable/data-table-sort-manager.tsx +2 -2
- package/src/components/DataTable/data-table.anatomy.stories.tsx +25 -24
- package/src/components/DataTable/data-table.css +2 -3
- package/src/components/DataTable/data-table.principles.stories.tsx +17 -11
- package/src/components/DataTable/data-table.spec.md +8 -8
- package/src/components/DataTable/data-table.stories.tsx +39 -29
- package/src/components/DataTable/data-table.tsx +94 -68
- package/src/components/DataTable/filter-operators.spec.md +5 -3
- package/src/components/DateGrid/date-grid.spec.md +1 -1
- package/src/components/DatePicker/date-picker.anatomy.stories.tsx +9 -9
- package/src/components/DatePicker/date-picker.principles.stories.tsx +4 -4
- package/src/components/DatePicker/date-picker.spec.md +9 -9
- package/src/components/DatePicker/date-picker.stories.tsx +9 -9
- package/src/components/DatePicker/date-picker.tsx +13 -13
- package/src/components/DescriptionList/description-list.anatomy.stories.tsx +5 -5
- package/src/components/DescriptionList/description-list.principles.stories.tsx +2 -2
- package/src/components/DescriptionList/description-list.spec.md +12 -12
- package/src/components/DescriptionList/description-list.stories.tsx +3 -3
- package/src/components/DescriptionList/description-list.tsx +10 -10
- package/src/components/Dialog/dialog.tsx +4 -1
- package/src/components/DropdownMenu/dropdown-menu.tsx +27 -14
- package/src/components/Field/field-context.ts +17 -11
- package/src/components/Field/field-controls.spec.md +44 -37
- package/src/components/Field/field-types.ts +14 -12
- package/src/components/Field/field-wrapper.tsx +59 -43
- package/src/components/Field/field.anatomy.stories.tsx +6 -6
- package/src/components/Field/field.principles.stories.tsx +5 -28
- package/src/components/Field/field.spec.md +4 -4
- package/src/components/Field/field.stories.tsx +103 -72
- package/src/components/Field/field.tsx +36 -4
- package/src/components/Field/form-validation.spec.md +2 -0
- package/src/components/Field/index.ts +1 -0
- package/src/components/Field/use-form-validation.ts +1 -1
- package/src/components/FieldControlGroup/field-control-group.principles.stories.tsx +3 -3
- package/src/components/FieldControlGroup/field-control-group.spec.md +3 -3
- package/src/components/FileItem/file-item.tsx +10 -8
- package/src/components/FileUpload/file-upload.principles.stories.tsx +7 -7
- package/src/components/FileUpload/file-upload.spec.md +3 -2
- package/src/components/FileUpload/file-upload.tsx +5 -1
- package/src/components/FileViewer/file-viewer.anatomy.stories.tsx +1 -1
- package/src/components/FileViewer/file-viewer.principles.stories.tsx +1 -1
- package/src/components/FileViewer/file-viewer.spec.md +1 -1
- package/src/components/FileViewer/file-viewer.stories.tsx +1 -1
- package/src/components/FileViewer/file-viewer.tsx +3 -2
- package/src/components/HoverCard/hover-card.anatomy.stories.tsx +6 -4
- package/src/components/HoverCard/hover-card.principles.stories.tsx +6 -1
- package/src/components/HoverCard/hover-card.spec.md +2 -2
- package/src/components/HoverCard/hover-card.tsx +4 -2
- package/src/components/InlineEdit/inline-edit.anatomy.stories.tsx +184 -0
- package/src/components/InlineEdit/inline-edit.principles.stories.tsx +142 -0
- package/src/components/InlineEdit/inline-edit.spec.md +71 -46
- package/src/components/InlineEdit/inline-edit.stories.tsx +20 -19
- package/src/components/InlineEdit/inline-edit.tsx +211 -125
- package/src/components/Input/input.anatomy.stories.tsx +15 -15
- package/src/components/Input/input.principles.stories.tsx +3 -3
- package/src/components/Input/input.spec.md +4 -4
- package/src/components/Input/input.stories.tsx +3 -3
- package/src/components/Input/input.tsx +13 -13
- package/src/components/LinkInput/link-input.anatomy.stories.tsx +2 -2
- package/src/components/LinkInput/link-input.principles.stories.tsx +1 -1
- package/src/components/LinkInput/link-input.spec.md +6 -2
- package/src/components/LinkInput/link-input.stories.tsx +8 -8
- package/src/components/LinkInput/link-input.tsx +21 -19
- package/src/components/Notice/notice.principles.stories.tsx +1 -1
- package/src/components/Notice/notice.tsx +8 -2
- package/src/components/NumberInput/number-input.anatomy.stories.tsx +6 -6
- package/src/components/NumberInput/number-input.principles.stories.tsx +4 -4
- package/src/components/NumberInput/number-input.spec.md +6 -6
- package/src/components/NumberInput/number-input.stories.tsx +4 -4
- package/src/components/NumberInput/number-input.tsx +17 -5
- package/src/components/OverflowIndicator/overflow-indicator.anatomy.stories.tsx +8 -4
- package/src/components/OverflowIndicator/overflow-indicator.principles.stories.tsx +6 -7
- package/src/components/OverflowIndicator/overflow-indicator.spec.md +1 -1
- package/src/components/OverflowIndicator/overflow-indicator.stories.tsx +6 -30
- package/src/components/PeoplePicker/avatar-stack-overflow.ts +1 -1
- package/src/components/PeoplePicker/people-picker.anatomy.stories.tsx +13 -10
- package/src/components/PeoplePicker/people-picker.principles.stories.tsx +5 -1
- package/src/components/PeoplePicker/people-picker.stories.tsx +5 -5
- package/src/components/PeoplePicker/people-picker.tsx +39 -20
- package/src/components/PeoplePicker/person-display.tsx +3 -3
- package/src/components/Popover/popover.anatomy.stories.tsx +10 -7
- package/src/components/Popover/popover.principles.stories.tsx +49 -28
- package/src/components/Popover/popover.spec.md +4 -2
- package/src/components/ProfileCard/profile-card.anatomy.stories.tsx +1 -1
- package/src/components/ProfileCard/profile-card.tsx +1 -1
- package/src/components/ProgressBar/progress-bar.anatomy.stories.tsx +14 -13
- package/src/components/ProgressBar/progress-bar.principles.stories.tsx +8 -23
- package/src/components/ProgressBar/progress-bar.stories.tsx +8 -2
- package/src/components/README.md +1 -0
- package/src/components/RadioGroup/radio-group.anatomy.stories.tsx +8 -3
- package/src/components/RadioGroup/radio-group.stories.tsx +3 -3
- package/src/components/RadioGroup/radio-group.tsx +19 -14
- package/src/components/Rating/rating.anatomy.stories.tsx +1 -1
- package/src/components/Rating/rating.principles.stories.tsx +3 -3
- package/src/components/Rating/rating.spec.md +2 -2
- package/src/components/Rating/rating.stories.tsx +4 -18
- package/src/components/Rating/rating.tsx +5 -1
- package/src/components/ScrollArea/scroll-area.principles.stories.tsx +1 -1
- package/src/components/ScrollArea/scroll-area.spec.md +1 -1
- package/src/components/ScrollArea/scroll-area.tsx +5 -2
- package/src/components/SegmentedControl/segmented-control.principles.stories.tsx +4 -1
- package/src/components/SegmentedControl/segmented-control.spec.md +5 -10
- package/src/components/SegmentedControl/segmented-control.tsx +6 -3
- package/src/components/Select/select.anatomy.stories.tsx +13 -7
- package/src/components/Select/select.principles.stories.tsx +3 -3
- package/src/components/Select/select.spec.md +11 -1
- package/src/components/Select/select.stories.tsx +41 -27
- package/src/components/Select/select.tsx +44 -26
- package/src/components/SelectMenu/select-menu.anatomy.stories.tsx +44 -26
- package/src/components/SelectMenu/select-menu.principles.stories.tsx +0 -1
- package/src/components/SelectMenu/select-menu.stories.tsx +7 -19
- package/src/components/SelectMenu/select-menu.tsx +38 -5
- package/src/components/SelectionControl/boolean-value.tsx +2 -2
- package/src/components/SelectionControl/selection-item.anatomy.stories.tsx +1 -1
- package/src/components/SelectionControl/selection-item.principles.stories.tsx +4 -4
- package/src/components/Separator/separator.principles.stories.tsx +1 -1
- package/src/components/Sheet/sheet.principles.stories.tsx +5 -3
- package/src/components/Sheet/sheet.tsx +4 -1
- package/src/components/Sidebar/sidebar.tsx +1 -1
- package/src/components/Slider/slider.anatomy.stories.tsx +5 -4
- package/src/components/Slider/slider.principles.stories.tsx +6 -6
- package/src/components/Slider/slider.spec.md +13 -1
- package/src/components/Slider/slider.stories.tsx +44 -32
- package/src/components/Slider/slider.tsx +13 -4
- package/src/components/Steps/steps.anatomy.stories.tsx +7 -7
- package/src/components/Steps/steps.principles.stories.tsx +1 -1
- package/src/components/Steps/steps.spec.md +4 -2
- package/src/components/Steps/steps.stories.tsx +4 -56
- package/src/components/Steps/steps.tsx +31 -7
- package/src/components/Switch/switch.anatomy.stories.tsx +3 -3
- package/src/components/Switch/switch.principles.stories.tsx +1 -1
- package/src/components/Switch/switch.spec.md +4 -4
- package/src/components/Switch/switch.stories.tsx +3 -3
- package/src/components/Switch/switch.tsx +16 -10
- package/src/components/Tabs/tabs.anatomy.stories.tsx +6 -0
- package/src/components/Tabs/tabs.principles.stories.tsx +10 -2
- package/src/components/Tabs/tabs.spec.md +5 -2
- package/src/components/Tabs/tabs.stories.tsx +36 -44
- package/src/components/Tabs/tabs.tsx +101 -36
- package/src/components/Tag/tag.anatomy.stories.tsx +2 -2
- package/src/components/Tag/tag.principles.stories.tsx +4 -4
- package/src/components/Tag/tag.spec.md +3 -1
- package/src/components/Tag/tag.tsx +5 -3
- package/src/components/Textarea/textarea.anatomy.stories.tsx +6 -6
- package/src/components/Textarea/textarea.spec.md +5 -5
- package/src/components/Textarea/textarea.tsx +24 -24
- package/src/components/TimePicker/time-picker.anatomy.stories.tsx +12 -11
- package/src/components/TimePicker/time-picker.principles.stories.tsx +37 -44
- package/src/components/TimePicker/time-picker.spec.md +6 -5
- package/src/components/TimePicker/time-picker.stories.tsx +3 -3
- package/src/components/TimePicker/time-picker.tsx +24 -14
- package/src/components/Toast/toast.principles.stories.tsx +1 -1
- package/src/components/Toast/toast.stories.tsx +1 -1
- package/src/components/Tooltip/tooltip.anatomy.stories.tsx +15 -6
- package/src/components/Tooltip/tooltip.principles.stories.tsx +4 -4
- package/src/components/Tooltip/tooltip.spec.md +9 -3
- package/src/components/Tooltip/tooltip.stories.tsx +1 -1
- package/src/components/Tooltip/tooltip.tsx +12 -2
- package/src/components/TreeView/tree-view.anatomy.stories.tsx +16 -14
- package/src/components/TreeView/tree-view.principles.stories.tsx +44 -11
- package/src/components/TreeView/tree-view.spec.md +8 -6
- package/src/components/TreeView/tree-view.stories.tsx +9 -43
- package/src/components/TreeView/tree-view.tsx +36 -0
- package/src/index.ts +16 -9
- package/src/lib/drag-visual.ts +2 -2
- package/src/lib/utils.ts +19 -0
- package/src/patterns/element-anatomy/inline-action.spec.md +1 -1
- package/src/patterns/element-anatomy/item-anatomy.tsx +4 -2
- package/src/patterns/header-canonical/header-canonical.spec.md +9 -0
- package/src/patterns/header-canonical/header-canonical.stories.tsx +31 -5
- package/src/tokens/categorical-color.ts +5 -5
- package/src/tokens/color/color.spec.md +5 -5
- package/src/tokens/color/primitives.css +9 -2
- package/src/tokens/opacity/opacity.spec.md +1 -1
- package/src/tokens/orphan-tokens.spec.md +1 -1
- package/src/tokens/typography/typography.spec.md +2 -0
- package/src/tokens/uiSize/uiSize.css +6 -1
- package/src/tokens/uiSize/uiSize.spec.md +1 -1
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { jsxs,
|
|
1
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { RotateCcw, X, Search, Lock, GripVertical, Eye, EyeOff } from "lucide-react";
|
|
4
4
|
import { Button } from "../Button/button.js";
|
|
5
5
|
import { ButtonDivider } from "../Button/button-group.js";
|
|
6
6
|
import { Input } from "../Input/input.js";
|
|
7
|
-
import {
|
|
8
|
-
import { PopoverHeader, PopoverTitle, PopoverClose, PopoverFooter } from "../Popover/popover.js";
|
|
7
|
+
import { PopoverHeader, PopoverTitle, PopoverClose, PopoverBody, PopoverFooter } from "../Popover/popover.js";
|
|
9
8
|
import { ItemPrefix, ItemInlineActionButton, ItemLabel, ROW_PADDING_BY_SIZE } from "../../patterns/element-anatomy/item-anatomy.js";
|
|
10
9
|
import { cn } from "../../lib/utils.js";
|
|
11
10
|
import { DndContext, closestCenter } from "@dnd-kit/core";
|
|
@@ -67,67 +66,75 @@ function DataTableColumnVisibilityPanel({
|
|
|
67
66
|
next.splice(newIdx, 0, m);
|
|
68
67
|
onColumnOrderChange(next);
|
|
69
68
|
};
|
|
70
|
-
return
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
69
|
+
return (
|
|
70
|
+
// 決策16 定案(2026-07-18,SSOT consistency 稽核後):對齊 sibling FilterPanel/SortManager 的
|
|
71
|
+
// overlay-surface canonical shape —— root `<div flex flex-col h-full min-h-0>`(M25 viewport-aware
|
|
72
|
+
// scroll chain)+ viewport-adaptive `PopoverBody`(取代原 fixed `ScrollArea max-h-72`)。三個
|
|
73
|
+
// DataTable state-panel 收斂成同一形狀,body 隨視窗高度自適應(高螢幕多欄不再硬卡 288px)。
|
|
74
|
+
// 寬度仍由 consumer 的 `<PopoverContent w-72>` 提供(panel root w-full 撐滿)。
|
|
75
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full min-h-0 w-full", children: [
|
|
76
|
+
/* @__PURE__ */ jsx(PopoverHeader, { hideClose: true, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 w-full min-w-0", children: [
|
|
77
|
+
/* @__PURE__ */ jsx(PopoverTitle, { className: "flex-1", children: "欄位顯示" }),
|
|
78
|
+
resettable && anyHidden && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
79
|
+
/* @__PURE__ */ jsx(
|
|
80
|
+
Button,
|
|
81
|
+
{
|
|
82
|
+
variant: "text",
|
|
83
|
+
size: "sm",
|
|
84
|
+
iconOnly: true,
|
|
85
|
+
startIcon: RotateCcw,
|
|
86
|
+
"aria-label": "恢復預設",
|
|
87
|
+
onClick: handleReset
|
|
88
|
+
}
|
|
89
|
+
),
|
|
90
|
+
/* @__PURE__ */ jsx(ButtonDivider, {})
|
|
91
|
+
] }),
|
|
92
|
+
/* @__PURE__ */ jsx(PopoverClose, { asChild: true, children: /* @__PURE__ */ jsx(Button, { "data-dismiss": true, iconOnly: true, dismiss: true, size: "sm", startIcon: X, "aria-label": "關閉" }) })
|
|
93
|
+
] }) }),
|
|
94
|
+
searchable && /* @__PURE__ */ jsx("div", { className: "shrink-0 px-[var(--layout-space-loose)] pt-[var(--layout-space-tight)]", children: /* @__PURE__ */ jsx(
|
|
95
|
+
Input,
|
|
96
|
+
{
|
|
97
|
+
size: "md",
|
|
98
|
+
placeholder: "搜尋欄位…",
|
|
99
|
+
"aria-label": "搜尋欄位",
|
|
100
|
+
value: search,
|
|
101
|
+
onChange: (e) => setSearch(e.target.value),
|
|
102
|
+
startIcon: Search
|
|
103
|
+
}
|
|
104
|
+
) }),
|
|
105
|
+
/* @__PURE__ */ jsx(PopoverBody, { className: "!px-0 !py-0", children: /* @__PURE__ */ jsx("div", { className: "py-2 flex flex-col", style: { "--item-prefix-slot": "16px" }, children: dndEnabled ? /* @__PURE__ */ jsx(DndContext, { collisionDetection: closestCenter, onDragEnd: handleDragEnd, children: /* @__PURE__ */ jsx(
|
|
106
|
+
SortableContext,
|
|
107
|
+
{
|
|
108
|
+
items: filteredEntries.map((e) => e.id).filter((id) => !lockedSet.has(id)),
|
|
109
|
+
strategy: verticalListSortingStrategy,
|
|
110
|
+
children: filteredEntries.map(({ id, label }) => /* @__PURE__ */ jsx(
|
|
111
|
+
VisibilityRow,
|
|
112
|
+
{
|
|
113
|
+
id,
|
|
114
|
+
label,
|
|
115
|
+
visible: visibility[id] !== false,
|
|
116
|
+
locked: lockedSet.has(id),
|
|
117
|
+
draggable: true,
|
|
118
|
+
onToggle: () => handleToggle(id)
|
|
119
|
+
},
|
|
120
|
+
id
|
|
121
|
+
))
|
|
122
|
+
}
|
|
123
|
+
) }) : filteredEntries.map(({ id, label }) => /* @__PURE__ */ jsx(
|
|
124
|
+
VisibilityRow,
|
|
125
|
+
{
|
|
126
|
+
id,
|
|
127
|
+
label,
|
|
128
|
+
visible: visibility[id] !== false,
|
|
129
|
+
locked: lockedSet.has(id),
|
|
130
|
+
draggable: false,
|
|
131
|
+
onToggle: () => handleToggle(id)
|
|
132
|
+
},
|
|
133
|
+
id
|
|
134
|
+
)) }) }),
|
|
135
|
+
/* @__PURE__ */ jsx(PopoverFooter, { className: "justify-start", children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "sm", onClick: handleBulkToggle, children: allVisible ? "全部隱藏" : "顯示全部" }) })
|
|
136
|
+
] })
|
|
137
|
+
);
|
|
131
138
|
}
|
|
132
139
|
function VisibilityRow({
|
|
133
140
|
id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-column-visibility-panel.js","sources":["../../../src/components/DataTable/data-table-column-visibility-panel.tsx"],"sourcesContent":["// @benchmark-unverified-blanket: file-level retraction per M22 (d) — claims herein not individually URL-cited; treat as unverified visual/usage rumor unless retrofit per-claim. Hook escape preserved.\n/**\n * DataTableColumnVisibilityPanel — Issue 3 primitive(2026-05-10)。\n *\n * 從 WithBulkActions story L868+(149 lines)+ RoadmapAllInOne(L1796+,53 lines)抽出 SSOT\n * primitive。Roadmap demo 跟 WithBulkActions 都用此 panel 開啟「欄位顯示」popover。\n *\n * **Feature SSOT**(對齊 Linear / Airtable / Notion / Material X-DataGrid 的 columnVisibility panel idiom):\n * - 列出所有 togglable 欄位 + Eye / EyeOff 切換\n * - Locked 欄位(`lockedIds`)— 顯 Lock icon,不可 toggle / 不可 drag\n * - 可選 search filter(`searchable`,跨欄位 label match)\n * - 可選 column drag reorder(`onColumnOrderChange` 傳 → 啟 DnD)\n * - 可選 reset 按鈕(`resettable: boolean` opt-in,header 區 RotateCcw;點擊 `onVisibilityChange({})` 還原全顯示,無獨立 onReset prop)\n * - Bidirectional bulk toggle(footer button:全可見 → 全部隱藏 / 任一隱藏 → 顯示全部)\n *\n * **Why 抽 primitive**(per Issue 3 Rule-of-3):RoadmapAllInOne + WithBulkActions + 未來 product\n * UI 至少 3 處消費同 panel。重複 hand-craft → 設計語言 drift(已抓到:Roadmap 版無 search /\n * 無 drag / 無 reset,WithBulkActions 版有,語意不一致)。Primitive 把所有 feature 集中,\n * consumer opt-in via props 確保 SSOT。\n *\n * **對齊**:Linear column-visibility-panel pattern / Material X-DataGrid `<GridColumnsPanel>`\n * / Airtable Field-config drawer。\n */\n\nimport * as React from 'react'\nimport { Eye, EyeOff, Lock, GripVertical, Search, RotateCcw, X as XIcon } from 'lucide-react'\nimport { Button } from '@/design-system/components/Button/button'\nimport { ButtonDivider } from '@/design-system/components/Button/button-group'\nimport { Input } from '@/design-system/components/Input/input'\nimport { ScrollArea } from '@/design-system/components/ScrollArea/scroll-area'\nimport { PopoverHeader, PopoverFooter, PopoverTitle, PopoverClose } from '@/design-system/components/Popover/popover'\nimport { ItemPrefix, ItemLabel, ItemInlineActionButton, ROW_PADDING_BY_SIZE } from '@/design-system/patterns/element-anatomy/item-anatomy'\nimport { cn } from '@/lib/utils'\nimport { DndContext, closestCenter, type DragEndEvent } from '@dnd-kit/core'\nimport { SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable'\nimport { CSS } from '@dnd-kit/utilities'\nimport { dragSourceStyle } from '@/design-system/lib/drag-visual'\n\ninterface ColumnVisibilityPanelColumn {\n /** Column id(stable identifier;對齊 DataTable column.id / accessorKey)*/\n id: string\n /** Column header label(human-readable)*/\n label: string\n}\n\nexport interface DataTableColumnVisibilityPanelProps {\n /** 全部可 toggle 欄位(consumer 已過濾掉 system cols 如 __select__)*/\n columns: ColumnVisibilityPanelColumn[]\n /** 受控 visibility map(`true` / undefined = visible / `false` = hidden)*/\n visibility: Record<string, boolean>\n /** Visibility 變更 callback */\n onVisibilityChange: (next: Record<string, boolean>) => void\n /** 受控 column order(若提供啟 DnD reorder) */\n columnOrder?: string[]\n /** Order 變更 callback;若提供 → 啟用 drag handle / DnD reorder */\n onColumnOrderChange?: (next: string[]) => void\n /** Locked column ids(顯 Lock icon,不可 toggle / 不可 drag)*/\n lockedIds?: string[]\n /** 是否啟搜尋 input(預設 false)*/\n searchable?: boolean\n /** 是否顯 reset button(任一欄隱藏才顯,onClick 清空 visibility map)*/\n resettable?: boolean\n // Issue 3 post-codex audit(2026-05-10):`onClose` prop retired — Radix `PopoverClose asChild`\n // 已自帶 popover dismiss,沒 concrete consumer 需 callback。Future 若需要再加。\n}\n\nexport function DataTableColumnVisibilityPanel({\n columns,\n visibility,\n onVisibilityChange,\n columnOrder,\n onColumnOrderChange,\n lockedIds = [],\n searchable = false,\n resettable = false,\n}: DataTableColumnVisibilityPanelProps) {\n const [search, setSearch] = React.useState('')\n const lockedSet = React.useMemo(() => new Set(lockedIds), [lockedIds])\n const dndEnabled = !!(columnOrder && onColumnOrderChange)\n\n // 計算 visible order:用 columnOrder 排,fallback columns 順序。\n const orderedIds = React.useMemo(() => {\n if (columnOrder && columnOrder.length > 0) {\n const colSet = new Set(columns.map((c) => c.id))\n return columnOrder.filter((id) => colSet.has(id))\n }\n return columns.map((c) => c.id)\n }, [columnOrder, columns])\n\n const filteredEntries = React.useMemo(() => {\n return orderedIds\n .map((id) => columns.find((c) => c.id === id))\n .filter((c): c is ColumnVisibilityPanelColumn => c != null)\n .filter((c) => (search ? c.label.toLowerCase().includes(search.toLowerCase()) : true))\n }, [orderedIds, columns, search])\n\n const togglableIds = columns.map((c) => c.id).filter((id) => !lockedSet.has(id))\n const allVisible = togglableIds.every((id) => visibility[id] !== false)\n const anyHidden = togglableIds.some((id) => visibility[id] === false)\n\n const handleToggle = (id: string) => {\n const visible = visibility[id] !== false\n onVisibilityChange({ ...visibility, [id]: !visible })\n }\n\n const handleReset = () => onVisibilityChange({})\n\n const handleBulkToggle = () => {\n if (allVisible) {\n const next: Record<string, boolean> = {}\n togglableIds.forEach((id) => { next[id] = false })\n onVisibilityChange(next)\n } else {\n onVisibilityChange({})\n }\n }\n\n const handleDragEnd = (e: DragEndEvent) => {\n if (!dndEnabled) return\n const { active, over } = e\n if (!over || active.id === over.id) return\n const oldIdx = columnOrder!.indexOf(active.id as string)\n const newIdx = columnOrder!.indexOf(over.id as string)\n if (oldIdx < 0 || newIdx < 0) return\n // Locked id 不可被 reorder 動到\n if (lockedSet.has(columnOrder![oldIdx]) || lockedSet.has(columnOrder![newIdx])) return\n const next = [...columnOrder!]\n const [m] = next.splice(oldIdx, 1)\n next.splice(newIdx, 0, m)\n onColumnOrderChange!(next)\n }\n\n return (\n <>\n <PopoverHeader hideClose>\n <div className=\"flex items-center gap-1 w-full min-w-0\">\n <PopoverTitle className=\"flex-1\">欄位顯示</PopoverTitle>\n {resettable && anyHidden && (\n <>\n <Button\n variant=\"text\" size=\"sm\" iconOnly startIcon={RotateCcw}\n aria-label=\"恢復預設\"\n onClick={handleReset}\n />\n <ButtonDivider />\n </>\n )}\n <PopoverClose asChild>\n <Button data-dismiss iconOnly dismiss size=\"sm\" startIcon={XIcon} aria-label=\"關閉\" />\n </PopoverClose>\n </div>\n </PopoverHeader>\n {searchable && (\n <div className=\"px-[var(--layout-space-loose)] pt-[var(--layout-space-tight)]\">\n <Input\n size=\"md\"\n placeholder=\"搜尋欄位…\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n startIcon={Search}\n />\n </div>\n )}\n <ScrollArea className=\"max-h-72\">\n <div className=\"py-2 flex flex-col\" style={{ '--item-prefix-slot': '16px' } as React.CSSProperties}>\n {dndEnabled ? (\n <DndContext collisionDetection={closestCenter} onDragEnd={handleDragEnd}>\n <SortableContext\n items={filteredEntries.map((e) => e.id).filter((id) => !lockedSet.has(id))}\n strategy={verticalListSortingStrategy}\n >\n {filteredEntries.map(({ id, label }) => (\n <VisibilityRow\n key={id}\n id={id}\n label={label}\n visible={visibility[id] !== false}\n locked={lockedSet.has(id)}\n draggable\n onToggle={() => handleToggle(id)}\n />\n ))}\n </SortableContext>\n </DndContext>\n ) : (\n filteredEntries.map(({ id, label }) => (\n <VisibilityRow\n key={id}\n id={id}\n label={label}\n visible={visibility[id] !== false}\n locked={lockedSet.has(id)}\n draggable={false}\n onToggle={() => handleToggle(id)}\n />\n ))\n )}\n </div>\n </ScrollArea>\n <PopoverFooter className=\"justify-start\">\n <Button variant=\"tertiary\" size=\"sm\" onClick={handleBulkToggle}>\n {allVisible ? '全部隱藏' : '顯示全部'}\n </Button>\n </PopoverFooter>\n </>\n )\n}\n\n// VisibilityRow:single column row。Draggable mode → GripVertical handle / static mode → 無 handle。\nfunction VisibilityRow({\n id, label, visible, locked, draggable, onToggle,\n}: {\n id: string\n label: string\n visible: boolean\n locked: boolean\n draggable: boolean\n onToggle: () => void\n}) {\n // Conditional hooks 不行 — 永遠呼 useSortable,只是 disabled 時 listeners no-op\n const sortable = useSortable({ id, disabled: locked || !draggable })\n const { attributes, listeners, setNodeRef, transform, transition, isDragging } = sortable\n const style: React.CSSProperties = draggable\n ? { transform: CSS.Transform.toString(transform), transition, ...dragSourceStyle(isDragging) }\n : {}\n return (\n <div\n ref={draggable ? setNodeRef : undefined}\n style={style}\n className={cn(\n 'flex items-start gap-2 w-full px-[var(--layout-space-loose)]',\n ROW_PADDING_BY_SIZE.md,\n )}\n >\n <ItemPrefix>\n {/* 2026-05-18 改 per user「做完」approval:14 → 16 對齊 uiSize.spec.md Icon Tier */}\n {locked ? (\n <Lock size={16} className=\"text-fg-muted\" aria-hidden />\n ) : draggable ? (\n <ItemInlineActionButton\n icon={GripVertical}\n size=\"md\"\n aria-label=\"拖曳重排\"\n className=\"cursor-grab active:cursor-grabbing\"\n {...attributes}\n {...listeners}\n />\n ) : null}\n </ItemPrefix>\n <ItemLabel className={locked ? 'text-fg-disabled' : undefined}>{label}</ItemLabel>\n <ItemInlineActionButton\n icon={visible ? Eye : EyeOff}\n size=\"md\"\n aria-label={visible ? '隱藏此欄' : '顯示此欄'}\n disabled={locked}\n onClick={onToggle}\n className={locked ? 'cursor-not-allowed text-fg-disabled' : ''}\n />\n </div>\n )\n}\n"],"names":["XIcon"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"data-table-column-visibility-panel.js","sources":["../../../src/components/DataTable/data-table-column-visibility-panel.tsx"],"sourcesContent":["// @benchmark-unverified-blanket: file-level retraction per M22 (d) — claims herein not individually URL-cited; treat as unverified visual/usage rumor unless retrofit per-claim. Hook escape preserved.\n/**\n * DataTableColumnVisibilityPanel — Issue 3 primitive(2026-05-10)。\n *\n * 從 WithBulkActions story L868+(149 lines)+ RoadmapAllInOne(L1796+,53 lines)抽出 SSOT\n * primitive。Roadmap demo 跟 WithBulkActions 都用此 panel 開啟「欄位顯示」popover。\n *\n * **Feature SSOT**(對齊 Linear / Airtable / Notion / Material X-DataGrid 的 columnVisibility panel idiom):\n * - 列出所有 togglable 欄位 + Eye / EyeOff 切換\n * - Locked 欄位(`lockedIds`)— 顯 Lock icon,不可 toggle / 不可 drag\n * - 可選 search filter(`searchable`,跨欄位 label match)\n * - 可選 column drag reorder(`onColumnOrderChange` 傳 → 啟 DnD)\n * - 可選 reset 按鈕(`resettable: boolean` opt-in,header 區 RotateCcw;點擊 `onVisibilityChange({})` 還原全顯示,無獨立 onReset prop)\n * - Bidirectional bulk toggle(footer button:全可見 → 全部隱藏 / 任一隱藏 → 顯示全部)\n *\n * **Why 抽 primitive**(per Issue 3 Rule-of-3):RoadmapAllInOne + WithBulkActions + 未來 product\n * UI 至少 3 處消費同 panel。重複 hand-craft → 設計語言 drift(已抓到:Roadmap 版無 search /\n * 無 drag / 無 reset,WithBulkActions 版有,語意不一致)。Primitive 把所有 feature 集中,\n * consumer opt-in via props 確保 SSOT。\n *\n * **對齊**:Linear column-visibility-panel pattern / Material X-DataGrid `<GridColumnsPanel>`\n * / Airtable Field-config drawer。\n */\n\nimport * as React from 'react'\nimport { Eye, EyeOff, Lock, GripVertical, Search, RotateCcw, X as XIcon } from 'lucide-react'\nimport { Button } from '@/design-system/components/Button/button'\nimport { ButtonDivider } from '@/design-system/components/Button/button-group'\nimport { Input } from '@/design-system/components/Input/input'\nimport { PopoverHeader, PopoverBody, PopoverFooter, PopoverTitle, PopoverClose } from '@/design-system/components/Popover/popover'\nimport { ItemPrefix, ItemLabel, ItemInlineActionButton, ROW_PADDING_BY_SIZE } from '@/design-system/patterns/element-anatomy/item-anatomy'\nimport { cn } from '@/lib/utils'\nimport { DndContext, closestCenter, type DragEndEvent } from '@dnd-kit/core'\nimport { SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable'\nimport { CSS } from '@dnd-kit/utilities'\nimport { dragSourceStyle } from '@/design-system/lib/drag-visual'\n\ninterface ColumnVisibilityPanelColumn {\n /** Column id(stable identifier;對齊 DataTable column.id / accessorKey)*/\n id: string\n /** Column header label(human-readable)*/\n label: string\n}\n\nexport interface DataTableColumnVisibilityPanelProps {\n /** 全部可 toggle 欄位(consumer 已過濾掉 system cols 如 __select__)*/\n columns: ColumnVisibilityPanelColumn[]\n /** 受控 visibility map(`true` / undefined = visible / `false` = hidden)*/\n visibility: Record<string, boolean>\n /** Visibility 變更 callback */\n onVisibilityChange: (next: Record<string, boolean>) => void\n /** 受控 column order(若提供啟 DnD reorder) */\n columnOrder?: string[]\n /** Order 變更 callback;若提供 → 啟用 drag handle / DnD reorder */\n onColumnOrderChange?: (next: string[]) => void\n /** Locked column ids(顯 Lock icon,不可 toggle / 不可 drag)*/\n lockedIds?: string[]\n /** 是否啟搜尋 input(預設 false)*/\n searchable?: boolean\n /** 是否顯 reset button(任一欄隱藏才顯,onClick 清空 visibility map)*/\n resettable?: boolean\n // Issue 3 post-codex audit(2026-05-10):`onClose` prop retired — Radix `PopoverClose asChild`\n // 已自帶 popover dismiss,沒 concrete consumer 需 callback。Future 若需要再加。\n}\n\nexport function DataTableColumnVisibilityPanel({\n columns,\n visibility,\n onVisibilityChange,\n columnOrder,\n onColumnOrderChange,\n lockedIds = [],\n searchable = false,\n resettable = false,\n}: DataTableColumnVisibilityPanelProps) {\n const [search, setSearch] = React.useState('')\n const lockedSet = React.useMemo(() => new Set(lockedIds), [lockedIds])\n const dndEnabled = !!(columnOrder && onColumnOrderChange)\n\n // 計算 visible order:用 columnOrder 排,fallback columns 順序。\n const orderedIds = React.useMemo(() => {\n if (columnOrder && columnOrder.length > 0) {\n const colSet = new Set(columns.map((c) => c.id))\n return columnOrder.filter((id) => colSet.has(id))\n }\n return columns.map((c) => c.id)\n }, [columnOrder, columns])\n\n const filteredEntries = React.useMemo(() => {\n return orderedIds\n .map((id) => columns.find((c) => c.id === id))\n .filter((c): c is ColumnVisibilityPanelColumn => c != null)\n .filter((c) => (search ? c.label.toLowerCase().includes(search.toLowerCase()) : true))\n }, [orderedIds, columns, search])\n\n const togglableIds = columns.map((c) => c.id).filter((id) => !lockedSet.has(id))\n const allVisible = togglableIds.every((id) => visibility[id] !== false)\n const anyHidden = togglableIds.some((id) => visibility[id] === false)\n\n const handleToggle = (id: string) => {\n const visible = visibility[id] !== false\n onVisibilityChange({ ...visibility, [id]: !visible })\n }\n\n const handleReset = () => onVisibilityChange({})\n\n const handleBulkToggle = () => {\n if (allVisible) {\n const next: Record<string, boolean> = {}\n togglableIds.forEach((id) => { next[id] = false })\n onVisibilityChange(next)\n } else {\n onVisibilityChange({})\n }\n }\n\n const handleDragEnd = (e: DragEndEvent) => {\n if (!dndEnabled) return\n const { active, over } = e\n if (!over || active.id === over.id) return\n const oldIdx = columnOrder!.indexOf(active.id as string)\n const newIdx = columnOrder!.indexOf(over.id as string)\n if (oldIdx < 0 || newIdx < 0) return\n // Locked id 不可被 reorder 動到\n if (lockedSet.has(columnOrder![oldIdx]) || lockedSet.has(columnOrder![newIdx])) return\n const next = [...columnOrder!]\n const [m] = next.splice(oldIdx, 1)\n next.splice(newIdx, 0, m)\n onColumnOrderChange!(next)\n }\n\n // 2026-07-18 決策16 錯誤史(明記以免再犯):原本這個 panel 是 Fragment + fixed `ScrollArea max-h-72`,\n // 與 sibling FilterPanel/SortManager(root-div + viewport-aware SurfaceBody)不一致。我給過**兩個都錯**\n // 的辯護理由 —— (1)「PopoverHeader 用 -mx 負邊距、包 root 會破壞」= 錯(SurfaceHeader 用正 px-loose+border-b,\n // 無 -mx);(2)「sibling 自刻 header 不用 primitive」= 錯(三 panel 皆消費 SurfaceHeader/PopoverHeader primitive)。\n // 真正差異只是 body/scroll 策略。multi-agent SSOT consistency 稽核定案:**是 drift,該統一**(fixed 288px cap\n // 在高螢幕多欄下劣於 sibling 的 viewport-adaptive;且是唯一不能當 template 複製的 panel)。故下方已改成 canonical shape。\n return (\n // 決策16 定案(2026-07-18,SSOT consistency 稽核後):對齊 sibling FilterPanel/SortManager 的\n // overlay-surface canonical shape —— root `<div flex flex-col h-full min-h-0>`(M25 viewport-aware\n // scroll chain)+ viewport-adaptive `PopoverBody`(取代原 fixed `ScrollArea max-h-72`)。三個\n // DataTable state-panel 收斂成同一形狀,body 隨視窗高度自適應(高螢幕多欄不再硬卡 288px)。\n // 寬度仍由 consumer 的 `<PopoverContent w-72>` 提供(panel root w-full 撐滿)。\n <div className=\"flex flex-col h-full min-h-0 w-full\">\n <PopoverHeader hideClose>\n <div className=\"flex items-center gap-1 w-full min-w-0\">\n <PopoverTitle className=\"flex-1\">欄位顯示</PopoverTitle>\n {resettable && anyHidden && (\n <>\n <Button\n variant=\"text\" size=\"sm\" iconOnly startIcon={RotateCcw}\n aria-label=\"恢復預設\"\n onClick={handleReset}\n />\n <ButtonDivider />\n </>\n )}\n <PopoverClose asChild>\n <Button data-dismiss iconOnly dismiss size=\"sm\" startIcon={XIcon} aria-label=\"關閉\" />\n </PopoverClose>\n </div>\n </PopoverHeader>\n {searchable && (\n <div className=\"shrink-0 px-[var(--layout-space-loose)] pt-[var(--layout-space-tight)]\">\n <Input\n size=\"md\"\n placeholder=\"搜尋欄位…\"\n aria-label=\"搜尋欄位\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n startIcon={Search}\n />\n </div>\n )}\n {/* viewport-adaptive body(List-as-region idiom:PopoverBody !px-0 !py-0 撤 chrome padding,\n 內層 py-2 給垂直呼吸、row 自帶 px-loose 水平 padding)。取代原 fixed ScrollArea max-h-72。 */}\n <PopoverBody className=\"!px-0 !py-0\">\n <div className=\"py-2 flex flex-col\" style={{ '--item-prefix-slot': '16px' } as React.CSSProperties}>\n {dndEnabled ? (\n <DndContext collisionDetection={closestCenter} onDragEnd={handleDragEnd}>\n <SortableContext\n items={filteredEntries.map((e) => e.id).filter((id) => !lockedSet.has(id))}\n strategy={verticalListSortingStrategy}\n >\n {filteredEntries.map(({ id, label }) => (\n <VisibilityRow\n key={id}\n id={id}\n label={label}\n visible={visibility[id] !== false}\n locked={lockedSet.has(id)}\n draggable\n onToggle={() => handleToggle(id)}\n />\n ))}\n </SortableContext>\n </DndContext>\n ) : (\n filteredEntries.map(({ id, label }) => (\n <VisibilityRow\n key={id}\n id={id}\n label={label}\n visible={visibility[id] !== false}\n locked={lockedSet.has(id)}\n draggable={false}\n onToggle={() => handleToggle(id)}\n />\n ))\n )}\n </div>\n </PopoverBody>\n <PopoverFooter className=\"justify-start\">\n <Button variant=\"tertiary\" size=\"sm\" onClick={handleBulkToggle}>\n {allVisible ? '全部隱藏' : '顯示全部'}\n </Button>\n </PopoverFooter>\n </div>\n )\n}\n\n// VisibilityRow:single column row。Draggable mode → GripVertical handle / static mode → 無 handle。\nfunction VisibilityRow({\n id, label, visible, locked, draggable, onToggle,\n}: {\n id: string\n label: string\n visible: boolean\n locked: boolean\n draggable: boolean\n onToggle: () => void\n}) {\n // Conditional hooks 不行 — 永遠呼 useSortable,只是 disabled 時 listeners no-op\n const sortable = useSortable({ id, disabled: locked || !draggable })\n const { attributes, listeners, setNodeRef, transform, transition, isDragging } = sortable\n const style: React.CSSProperties = draggable\n ? { transform: CSS.Transform.toString(transform), transition, ...dragSourceStyle(isDragging) }\n : {}\n return (\n <div\n ref={draggable ? setNodeRef : undefined}\n style={style}\n className={cn(\n 'flex items-start gap-2 w-full px-[var(--layout-space-loose)]',\n ROW_PADDING_BY_SIZE.md,\n )}\n >\n <ItemPrefix>\n {/* 2026-05-18 改 per user「做完」approval:14 → 16 對齊 uiSize.spec.md Icon Tier */}\n {locked ? (\n <Lock size={16} className=\"text-fg-muted\" aria-hidden />\n ) : draggable ? (\n <ItemInlineActionButton\n icon={GripVertical}\n size=\"md\"\n aria-label=\"拖曳重排\"\n className=\"cursor-grab active:cursor-grabbing\"\n {...attributes}\n {...listeners}\n />\n ) : null}\n </ItemPrefix>\n <ItemLabel className={locked ? 'text-fg-disabled' : undefined}>{label}</ItemLabel>\n <ItemInlineActionButton\n icon={visible ? Eye : EyeOff}\n size=\"md\"\n aria-label={visible ? '隱藏此欄' : '顯示此欄'}\n disabled={locked}\n onClick={onToggle}\n className={locked ? 'cursor-not-allowed text-fg-disabled' : ''}\n />\n </div>\n )\n}\n"],"names":["XIcon"],"mappings":";;;;;;;;;;;;;AAiEO,SAAS,+BAA+B;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY,CAAA;AAAA,EACZ,aAAa;AAAA,EACb,aAAa;AACf,GAAwC;AACtC,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAS,EAAE;AAC7C,QAAM,YAAY,MAAM,QAAQ,MAAM,IAAI,IAAI,SAAS,GAAG,CAAC,SAAS,CAAC;AACrE,QAAM,aAAa,CAAC,EAAE,eAAe;AAGrC,QAAM,aAAa,MAAM,QAAQ,MAAM;AACrC,QAAI,eAAe,YAAY,SAAS,GAAG;AACzC,YAAM,SAAS,IAAI,IAAI,QAAQ,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAC/C,aAAO,YAAY,OAAO,CAAC,OAAO,OAAO,IAAI,EAAE,CAAC;AAAA,IAClD;AACA,WAAO,QAAQ,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,EAChC,GAAG,CAAC,aAAa,OAAO,CAAC;AAEzB,QAAM,kBAAkB,MAAM,QAAQ,MAAM;AAC1C,WAAO,WACJ,IAAI,CAAC,OAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,EAC5C,OAAO,CAAC,MAAwC,KAAK,IAAI,EACzD,OAAO,CAAC,MAAO,SAAS,EAAE,MAAM,YAAA,EAAc,SAAS,OAAO,YAAA,CAAa,IAAI,IAAK;AAAA,EACzF,GAAG,CAAC,YAAY,SAAS,MAAM,CAAC;AAEhC,QAAM,eAAe,QAAQ,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC;AAC/E,QAAM,aAAa,aAAa,MAAM,CAAC,OAAO,WAAW,EAAE,MAAM,KAAK;AACtE,QAAM,YAAY,aAAa,KAAK,CAAC,OAAO,WAAW,EAAE,MAAM,KAAK;AAEpE,QAAM,eAAe,CAAC,OAAe;AACnC,UAAM,UAAU,WAAW,EAAE,MAAM;AACnC,uBAAmB,EAAE,GAAG,YAAY,CAAC,EAAE,GAAG,CAAC,SAAS;AAAA,EACtD;AAEA,QAAM,cAAc,MAAM,mBAAmB,EAAE;AAE/C,QAAM,mBAAmB,MAAM;AAC7B,QAAI,YAAY;AACd,YAAM,OAAgC,CAAA;AACtC,mBAAa,QAAQ,CAAC,OAAO;AAAE,aAAK,EAAE,IAAI;AAAA,MAAM,CAAC;AACjD,yBAAmB,IAAI;AAAA,IACzB,OAAO;AACL,yBAAmB,CAAA,CAAE;AAAA,IACvB;AAAA,EACF;AAEA,QAAM,gBAAgB,CAAC,MAAoB;AACzC,QAAI,CAAC,WAAY;AACjB,UAAM,EAAE,QAAQ,KAAA,IAAS;AACzB,QAAI,CAAC,QAAQ,OAAO,OAAO,KAAK,GAAI;AACpC,UAAM,SAAS,YAAa,QAAQ,OAAO,EAAY;AACvD,UAAM,SAAS,YAAa,QAAQ,KAAK,EAAY;AACrD,QAAI,SAAS,KAAK,SAAS,EAAG;AAE9B,QAAI,UAAU,IAAI,YAAa,MAAM,CAAC,KAAK,UAAU,IAAI,YAAa,MAAM,CAAC,EAAG;AAChF,UAAM,OAAO,CAAC,GAAG,WAAY;AAC7B,UAAM,CAAC,CAAC,IAAI,KAAK,OAAO,QAAQ,CAAC;AACjC,SAAK,OAAO,QAAQ,GAAG,CAAC;AACxB,wBAAqB,IAAI;AAAA,EAC3B;AAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAME,qBAAC,OAAA,EAAI,WAAU,uCACb,UAAA;AAAA,MAAA,oBAAC,iBAAc,WAAS,MACtB,UAAA,qBAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,QAAA,oBAAC,cAAA,EAAa,WAAU,UAAS,UAAA,QAAI;AAAA,QACpC,cAAc,aACb,qBAAA,UAAA,EACE,UAAA;AAAA,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cAAO,MAAK;AAAA,cAAK,UAAQ;AAAA,cAAC,WAAW;AAAA,cAC7C,cAAW;AAAA,cACX,SAAS;AAAA,YAAA;AAAA,UAAA;AAAA,8BAEV,eAAA,CAAA,CAAc;AAAA,QAAA,GACjB;AAAA,4BAED,cAAA,EAAa,SAAO,MACnB,UAAA,oBAAC,QAAA,EAAO,gBAAY,MAAC,UAAQ,MAAC,SAAO,MAAC,MAAK,MAAK,WAAWA,GAAO,cAAW,MAAK,EAAA,CACpF;AAAA,MAAA,EAAA,CACF,EAAA,CACF;AAAA,MACC,cACC,oBAAC,OAAA,EAAI,WAAU,0EACb,UAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,aAAY;AAAA,UACZ,cAAW;AAAA,UACX,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,UAAU,EAAE,OAAO,KAAK;AAAA,UACzC,WAAW;AAAA,QAAA;AAAA,MAAA,GAEf;AAAA,0BAID,aAAA,EAAY,WAAU,eACrB,UAAA,oBAAC,OAAA,EAAI,WAAU,sBAAqB,OAAO,EAAE,sBAAsB,UAChE,UAAA,aACC,oBAAC,cAAW,oBAAoB,eAAe,WAAW,eACxD,UAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAO,gBAAgB,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC;AAAA,UACzE,UAAU;AAAA,UAET,0BAAgB,IAAI,CAAC,EAAE,IAAI,YAC1B;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC;AAAA,cACA;AAAA,cACA,SAAS,WAAW,EAAE,MAAM;AAAA,cAC5B,QAAQ,UAAU,IAAI,EAAE;AAAA,cACxB,WAAS;AAAA,cACT,UAAU,MAAM,aAAa,EAAE;AAAA,YAAA;AAAA,YAN1B;AAAA,UAAA,CAQR;AAAA,QAAA;AAAA,MAAA,EACH,CACF,IAEA,gBAAgB,IAAI,CAAC,EAAE,IAAI,YACzB;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC;AAAA,UACA;AAAA,UACA,SAAS,WAAW,EAAE,MAAM;AAAA,UAC5B,QAAQ,UAAU,IAAI,EAAE;AAAA,UACxB,WAAW;AAAA,UACX,UAAU,MAAM,aAAa,EAAE;AAAA,QAAA;AAAA,QAN1B;AAAA,MAAA,CAQR,GAEL,EAAA,CACF;AAAA,MACA,oBAAC,eAAA,EAAc,WAAU,iBACvB,8BAAC,QAAA,EAAO,SAAQ,YAAW,MAAK,MAAK,SAAS,kBAC3C,UAAA,aAAa,SAAS,QACzB,EAAA,CACF;AAAA,IAAA,EAAA,CACF;AAAA;AAEJ;AAGA,SAAS,cAAc;AAAA,EACrB;AAAA,EAAI;AAAA,EAAO;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAW;AACzC,GAOG;AAED,QAAM,WAAW,YAAY,EAAE,IAAI,UAAU,UAAU,CAAC,WAAW;AACnE,QAAM,EAAE,YAAY,WAAW,YAAY,WAAW,YAAY,eAAe;AACjF,QAAM,QAA6B,YAC/B,EAAE,WAAW,IAAI,UAAU,SAAS,SAAS,GAAG,YAAY,GAAG,gBAAgB,UAAU,EAAA,IACzF,CAAA;AACJ,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK,YAAY,aAAa;AAAA,MAC9B;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA,oBAAoB;AAAA,MAAA;AAAA,MAGtB,UAAA;AAAA,QAAA,oBAAC,YAAA,EAEE,UAAA,SACC,oBAAC,MAAA,EAAK,MAAM,IAAI,WAAU,iBAAgB,eAAW,KAAA,CAAC,IACpD,YACF;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAM;AAAA,YACN,MAAK;AAAA,YACL,cAAW;AAAA,YACX,WAAU;AAAA,YACT,GAAG;AAAA,YACH,GAAG;AAAA,UAAA;AAAA,QAAA,IAEJ,KAAA,CACN;AAAA,4BACC,WAAA,EAAU,WAAW,SAAS,qBAAqB,QAAY,UAAA,OAAM;AAAA,QACtE;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAM,UAAU,MAAM;AAAA,YACtB,MAAK;AAAA,YACL,cAAY,UAAU,SAAS;AAAA,YAC/B,UAAU;AAAA,YACV,SAAS;AAAA,YACT,WAAW,SAAS,wCAAwC;AAAA,UAAA;AAAA,QAAA;AAAA,MAC9D;AAAA,IAAA;AAAA,EAAA;AAGN;"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type SelectOption } from '../../components/Select/select';
|
|
2
|
+
import type { ColumnType } from './column-types';
|
|
3
|
+
import type { Conjunction, FilterCondition, FilterGroup } from './filter-tree';
|
|
4
|
+
export interface FilterColumn {
|
|
5
|
+
id: string;
|
|
6
|
+
label: string;
|
|
7
|
+
type: ColumnType;
|
|
8
|
+
options?: Array<{
|
|
9
|
+
value: string;
|
|
10
|
+
label: string;
|
|
11
|
+
}>;
|
|
12
|
+
/** People pool for person/multiPerson filter picker(對齊 cell-registry meta.people SSOT)*/
|
|
13
|
+
people?: Array<{
|
|
14
|
+
name: string;
|
|
15
|
+
avatarUrl?: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
}>;
|
|
18
|
+
includeTime?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare function getDefaultOperator(type?: ColumnType): string;
|
|
21
|
+
export declare const datePrecisionOf: (col: FilterColumn | undefined) => "day" | "ms" | undefined;
|
|
22
|
+
export declare function FilterRow({ index, condition, conjunction, filterableColumns, fieldOptions, onChangeConjunction, onChangeField, onChangeOp, onChangeValue, onRemove, }: {
|
|
23
|
+
index: number;
|
|
24
|
+
condition: FilterCondition;
|
|
25
|
+
conjunction: Conjunction;
|
|
26
|
+
filterableColumns: FilterColumn[];
|
|
27
|
+
fieldOptions: SelectOption[];
|
|
28
|
+
onChangeConjunction: (c: Conjunction) => void;
|
|
29
|
+
onChangeField: (v: string) => void;
|
|
30
|
+
onChangeOp: (v: string) => void;
|
|
31
|
+
onChangeValue: (v: unknown) => void;
|
|
32
|
+
onRemove: () => void;
|
|
33
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
export declare function GroupBlock({ index, group, rootConjunction, filterableColumns, fieldOptions, onChangeRootConjunction, onChangeGroupConjunction, onChangeCondition, onRemoveCondition, onAddCondition, onRemoveGroup, }: {
|
|
35
|
+
index: number;
|
|
36
|
+
group: FilterGroup;
|
|
37
|
+
rootConjunction: Conjunction;
|
|
38
|
+
filterableColumns: FilterColumn[];
|
|
39
|
+
fieldOptions: SelectOption[];
|
|
40
|
+
onChangeRootConjunction: (c: Conjunction) => void;
|
|
41
|
+
onChangeGroupConjunction: (c: Conjunction) => void;
|
|
42
|
+
onChangeCondition: (condId: string, patch: Partial<FilterCondition>) => void;
|
|
43
|
+
onRemoveCondition: (condId: string) => void;
|
|
44
|
+
onAddCondition: () => void;
|
|
45
|
+
onRemoveGroup: () => void;
|
|
46
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
47
|
+
//# sourceMappingURL=data-table-filter-group.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-table-filter-group.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/data-table-filter-group.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAAU,KAAK,YAAY,EAAE,MAAM,0CAA0C,CAAA;AAEpF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAQhD,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAK9E,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,UAAU,CAAA;IAChB,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACjD,yFAAyF;IACzF,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC1E,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAOD,wBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,CAE5D;AAID,eAAO,MAAM,eAAe,GAAI,KAAK,YAAY,GAAG,SAAS,KAAG,KAAK,GAAG,IAAI,GAAG,SACV,CAAA;AA0CrE,wBAAgB,SAAS,CAAC,EACxB,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,iBAAiB,EAAE,YAAY,EAC9D,mBAAmB,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,QAAQ,GACxE,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,eAAe,CAAA;IAC1B,WAAW,EAAE,WAAW,CAAA;IACxB,iBAAiB,EAAE,YAAY,EAAE,CAAA;IACjC,YAAY,EAAE,YAAY,EAAE,CAAA;IAC5B,mBAAmB,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI,CAAA;IAC7C,aAAa,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/B,aAAa,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IACnC,QAAQ,EAAE,MAAM,IAAI,CAAA;CACrB,2CAgEA;AAID,wBAAgB,UAAU,CAAC,EACzB,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,YAAY,EAC9D,uBAAuB,EAAE,wBAAwB,EACjD,iBAAiB,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,GACpE,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,WAAW,CAAA;IAClB,eAAe,EAAE,WAAW,CAAA;IAC5B,iBAAiB,EAAE,YAAY,EAAE,CAAA;IACjC,YAAY,EAAE,YAAY,EAAE,CAAA;IAC5B,uBAAuB,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI,CAAA;IACjD,wBAAwB,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI,CAAA;IAClD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,eAAe,CAAC,KAAK,IAAI,CAAA;IAC5E,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3C,cAAc,EAAE,MAAM,IAAI,CAAA;IAC1B,aAAa,EAAE,MAAM,IAAI,CAAA;CAC1B,2CAoCA"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Trash2, Plus } from "lucide-react";
|
|
3
|
+
import { Button } from "../Button/button.js";
|
|
4
|
+
import { Select } from "../Select/select.js";
|
|
5
|
+
import { FieldControlGroup } from "../FieldControlGroup/field-control-group.js";
|
|
6
|
+
import { DEFAULT_OPERATOR, getOperatorSpec, getValueShape, OPERATOR_REGISTRY } from "./filter-operators.js";
|
|
7
|
+
import { FilterValuePicker } from "./data-table-filter-value-picker.js";
|
|
8
|
+
function getOperatorOptions(type) {
|
|
9
|
+
const registry = type && OPERATOR_REGISTRY[type] ? OPERATOR_REGISTRY[type] : OPERATOR_REGISTRY.string;
|
|
10
|
+
return registry.map((op) => ({ value: op.op, label: op.label }));
|
|
11
|
+
}
|
|
12
|
+
function getDefaultOperator(type) {
|
|
13
|
+
return type && DEFAULT_OPERATOR[type] || DEFAULT_OPERATOR.string;
|
|
14
|
+
}
|
|
15
|
+
const datePrecisionOf = (col) => (col == null ? void 0 : col.type) === "date" ? col.includeTime ? "ms" : "day" : void 0;
|
|
16
|
+
const CONJ_OPTIONS = [
|
|
17
|
+
{ value: "and", label: "And" },
|
|
18
|
+
{ value: "or", label: "Or" }
|
|
19
|
+
];
|
|
20
|
+
function ConjunctionLabel({
|
|
21
|
+
index,
|
|
22
|
+
conjunction,
|
|
23
|
+
onChange
|
|
24
|
+
}) {
|
|
25
|
+
if (index === 0) {
|
|
26
|
+
return /* @__PURE__ */ jsx("div", { className: "w-20 shrink-0 text-body text-fg-muted px-[var(--field-px)] self-center", children: "Where" });
|
|
27
|
+
}
|
|
28
|
+
if (index >= 2) {
|
|
29
|
+
const label = conjunction === "and" ? "And" : "Or";
|
|
30
|
+
return /* @__PURE__ */ jsx("div", { className: "w-20 shrink-0 text-body text-fg-muted px-[var(--field-px)] self-center", children: label });
|
|
31
|
+
}
|
|
32
|
+
return /* @__PURE__ */ jsx("div", { className: "w-20 shrink-0", children: /* @__PURE__ */ jsx(
|
|
33
|
+
Select,
|
|
34
|
+
{
|
|
35
|
+
size: "sm",
|
|
36
|
+
options: CONJ_OPTIONS,
|
|
37
|
+
value: conjunction,
|
|
38
|
+
onChange: (v) => onChange(v),
|
|
39
|
+
minRows: 2,
|
|
40
|
+
"aria-label": "連接詞 — 同 group 共用"
|
|
41
|
+
}
|
|
42
|
+
) });
|
|
43
|
+
}
|
|
44
|
+
function FilterRow({
|
|
45
|
+
index,
|
|
46
|
+
condition,
|
|
47
|
+
conjunction,
|
|
48
|
+
filterableColumns,
|
|
49
|
+
fieldOptions,
|
|
50
|
+
onChangeConjunction,
|
|
51
|
+
onChangeField,
|
|
52
|
+
onChangeOp,
|
|
53
|
+
onChangeValue,
|
|
54
|
+
onRemove
|
|
55
|
+
}) {
|
|
56
|
+
const colInfo = filterableColumns.find((c) => c.id === condition.field);
|
|
57
|
+
const operatorOptions = getOperatorOptions(colInfo == null ? void 0 : colInfo.type);
|
|
58
|
+
const hasField = !!condition.field;
|
|
59
|
+
const opSpec = colInfo ? getOperatorSpec(colInfo.type, condition.op) : null;
|
|
60
|
+
const valueShape = colInfo && opSpec ? getValueShape(opSpec, colInfo.type, colInfo.includeTime) : null;
|
|
61
|
+
const hasValueCell = valueShape !== "none";
|
|
62
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
63
|
+
/* @__PURE__ */ jsx(ConjunctionLabel, { index, conjunction, onChange: onChangeConjunction }),
|
|
64
|
+
/* @__PURE__ */ jsxs(FieldControlGroup, { block: true, className: "flex-1 min-w-0", children: [
|
|
65
|
+
/* @__PURE__ */ jsx(
|
|
66
|
+
Select,
|
|
67
|
+
{
|
|
68
|
+
className: "!w-[var(--data-table-filter-field-width)] flex-shrink-0",
|
|
69
|
+
size: "sm",
|
|
70
|
+
options: fieldOptions,
|
|
71
|
+
value: condition.field,
|
|
72
|
+
onChange: onChangeField,
|
|
73
|
+
placeholder: "選擇欄位",
|
|
74
|
+
"aria-label": "篩選欄位"
|
|
75
|
+
}
|
|
76
|
+
),
|
|
77
|
+
/* @__PURE__ */ jsx(
|
|
78
|
+
Select,
|
|
79
|
+
{
|
|
80
|
+
className: hasValueCell ? "!w-[var(--data-table-filter-op-width)] flex-shrink-0" : "!flex-1 !min-w-0",
|
|
81
|
+
size: "sm",
|
|
82
|
+
options: operatorOptions,
|
|
83
|
+
value: condition.op,
|
|
84
|
+
onChange: onChangeOp,
|
|
85
|
+
disabled: !hasField,
|
|
86
|
+
placeholder: "運算子",
|
|
87
|
+
"aria-label": "篩選運算子"
|
|
88
|
+
}
|
|
89
|
+
),
|
|
90
|
+
hasValueCell && /* @__PURE__ */ jsx(
|
|
91
|
+
FilterValuePicker,
|
|
92
|
+
{
|
|
93
|
+
shape: valueShape,
|
|
94
|
+
value: condition.value,
|
|
95
|
+
onChange: onChangeValue,
|
|
96
|
+
colInfo,
|
|
97
|
+
disabled: !hasField,
|
|
98
|
+
ariaLabel: colInfo ? `${colInfo.label} 篩選值` : "篩選值",
|
|
99
|
+
className: "!flex-1 !min-w-0"
|
|
100
|
+
}
|
|
101
|
+
)
|
|
102
|
+
] }),
|
|
103
|
+
/* @__PURE__ */ jsx(Button, { variant: "text", size: "sm", iconOnly: true, startIcon: Trash2, "aria-label": "刪除", onClick: onRemove })
|
|
104
|
+
] });
|
|
105
|
+
}
|
|
106
|
+
function GroupBlock({
|
|
107
|
+
index,
|
|
108
|
+
group,
|
|
109
|
+
rootConjunction,
|
|
110
|
+
filterableColumns,
|
|
111
|
+
fieldOptions,
|
|
112
|
+
onChangeRootConjunction,
|
|
113
|
+
onChangeGroupConjunction,
|
|
114
|
+
onChangeCondition,
|
|
115
|
+
onRemoveCondition,
|
|
116
|
+
onAddCondition,
|
|
117
|
+
onRemoveGroup
|
|
118
|
+
}) {
|
|
119
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
|
|
120
|
+
/* @__PURE__ */ jsx("div", { className: "pt-2", children: /* @__PURE__ */ jsx(ConjunctionLabel, { index, conjunction: rootConjunction, onChange: onChangeRootConjunction }) }),
|
|
121
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0 rounded-md bg-muted p-2 flex flex-col gap-2", children: [
|
|
122
|
+
group.children.map((cond, cIdx) => /* @__PURE__ */ jsx(
|
|
123
|
+
FilterRow,
|
|
124
|
+
{
|
|
125
|
+
index: cIdx,
|
|
126
|
+
condition: cond,
|
|
127
|
+
conjunction: group.conjunction,
|
|
128
|
+
filterableColumns,
|
|
129
|
+
fieldOptions,
|
|
130
|
+
onChangeConjunction: onChangeGroupConjunction,
|
|
131
|
+
onChangeField: (v) => {
|
|
132
|
+
const newCol = filterableColumns.find((c) => c.id === v);
|
|
133
|
+
onChangeCondition(cond.id, { field: v, op: getDefaultOperator(newCol == null ? void 0 : newCol.type), value: "", datePrecision: datePrecisionOf(newCol) });
|
|
134
|
+
},
|
|
135
|
+
onChangeOp: (v) => onChangeCondition(cond.id, { op: v, value: "" }),
|
|
136
|
+
onChangeValue: (v) => onChangeCondition(cond.id, { value: v }),
|
|
137
|
+
onRemove: () => onRemoveCondition(cond.id)
|
|
138
|
+
},
|
|
139
|
+
cond.id
|
|
140
|
+
)),
|
|
141
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
142
|
+
/* @__PURE__ */ jsx(Button, { variant: "text", size: "sm", startIcon: Plus, onClick: onAddCondition, children: "加入巢狀篩選" }),
|
|
143
|
+
group.children.length === 0 && /* @__PURE__ */ jsx(Button, { variant: "text", size: "sm", startIcon: Trash2, danger: true, onClick: onRemoveGroup, children: "移除空群組" })
|
|
144
|
+
] })
|
|
145
|
+
] })
|
|
146
|
+
] });
|
|
147
|
+
}
|
|
148
|
+
export {
|
|
149
|
+
FilterRow,
|
|
150
|
+
GroupBlock,
|
|
151
|
+
datePrecisionOf,
|
|
152
|
+
getDefaultOperator
|
|
153
|
+
};
|
|
154
|
+
//# sourceMappingURL=data-table-filter-group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-table-filter-group.js","sources":["../../../src/components/DataTable/data-table-filter-group.tsx"],"sourcesContent":["// @benchmark-unverified-blanket: file-level retraction per M22 (d) — claims herein not individually URL-cited; treat as unverified visual/usage rumor unless retrofit per-claim. Hook escape preserved(2026-07-14 自 data-table-filter-panel.tsx 拆檔搬移,原檔級 escape 隨段落帶入)。\n// @internal — DS-internal 單元(filter row / nested-group renderer + 共用 column/operator\n// helpers;GroupBlock 為 nested-group renderer,FilterRow / ConjunctionLabel 為其 row 構件、\n// flat mode 共用。只被 data-table-filter-panel.tsx 消費);不隨 index.ts re-export 進 npm public surface。\n// ────────────────────────────── 消費的 SSOT ──────────────────────────────\n// - FieldControlGroup:field + op + value border-collapse 接合(field-control-group.spec.md;\n// FilterValuePicker 為 direct child,className forward 不開 wrapper div — 2026-05-04 #2 fix)\n// - Button(variant=\"text\" iconOnly)row meta trash / Select(size=\"sm\")conjunction・field・op\n// (data-table.spec.md「四、UI canonical」:trash = form-control row text Button;A6 conjunction)\n// - Width tokens:--data-table-filter-field-width / --data-table-filter-op-width(uiSize.css SSOT,\n// 2026-05-23 Phase A.4 Decision 2)\n// - Operator SSOT:./filter-operators.ts OPERATOR_REGISTRY(禁 hardcode op 字串)\n// - Group container 灰底 bg-muted:color.spec.md L651-654 靜態低重要 surface semantic(2026-05-09 Q3 A)\n// 設計規則:./filter-operators.spec.md + ./data-table.spec.md「進階篩選」段\n\nimport { Plus, Trash2 } from 'lucide-react'\nimport { Button } from '@/design-system/components/Button/button'\nimport { Select, type SelectOption } from '@/design-system/components/Select/select'\nimport { FieldControlGroup } from '@/design-system/components/FieldControlGroup/field-control-group'\nimport type { ColumnType } from './column-types'\nimport {\n OPERATOR_REGISTRY,\n DEFAULT_OPERATOR,\n getOperatorSpec,\n getValueShape,\n type ValueShape,\n} from './filter-operators'\nimport type { Conjunction, FilterCondition, FilterGroup } from './filter-tree'\nimport { FilterValuePicker } from './data-table-filter-value-picker'\n\n// ── Shared internal types + operator helpers(panel orchestration 也消費)────\n\nexport interface FilterColumn {\n id: string\n label: string\n type: ColumnType\n options?: Array<{ value: string; label: string }>\n /** People pool for person/multiPerson filter picker(對齊 cell-registry meta.people SSOT)*/\n people?: Array<{ name: string; avatarUrl?: string; description?: string }>\n includeTime?: boolean\n}\n\nfunction getOperatorOptions(type?: ColumnType): SelectOption[] {\n const registry = type && OPERATOR_REGISTRY[type] ? OPERATOR_REGISTRY[type] : OPERATOR_REGISTRY.string\n return registry.map((op) => ({ value: op.op, label: op.label }))\n}\n\nexport function getDefaultOperator(type?: ColumnType): string {\n return (type && DEFAULT_OPERATOR[type]) || DEFAULT_OPERATOR.string\n}\n\n// Q6(2026-07-04):date 欄位把比對精度寫進 condition(includeTime=true → ms,否則 day)。\n// 'time' 欄暫不寫(值非完整日期,truncate 語意不成立;見 filter-operators.spec v3 time 註)。\nexport const datePrecisionOf = (col: FilterColumn | undefined): 'day' | 'ms' | undefined =>\n col?.type === 'date' ? (col.includeTime ? 'ms' : 'day') : undefined\n\n// ── ConjunctionLabel ───────────────────────────────────────────────────\n\nconst CONJ_OPTIONS: SelectOption[] = [\n { value: 'and', label: 'And' },\n { value: 'or', label: 'Or' },\n]\n\nfunction ConjunctionLabel({\n index, conjunction, onChange,\n}: { index: number; conjunction: Conjunction; onChange: (c: Conjunction) => void }) {\n // index === 0:首 row 顯示靜態「Where」label\n // index === 1:**唯一可改**的 AND/OR Select(連動整 group conjunction)\n // index ≥ 2:被連動的 row,read-only 顯示當前 conjunction 文字(同 Where 視覺,A6 canonical)\n // 對齊 Airtable / Notion / Linear 共識 @benchmark-unverified(non-OSS)\n // px-[var(--field-px)] 對齊 Field 內部 padding 12px(Q13)\n if (index === 0) {\n return <div className=\"w-20 shrink-0 text-body text-fg-muted px-[var(--field-px)] self-center\">Where</div>\n }\n if (index >= 2) {\n const label = conjunction === 'and' ? 'And' : 'Or'\n return <div className=\"w-20 shrink-0 text-body text-fg-muted px-[var(--field-px)] self-center\">{label}</div>\n }\n // index === 1:可切換的 AND/OR Select\n // minRows={2} — And/Or 2 選項,顯式縮 menu 高度避免 reserve 3 row 空白(Q5)\n return (\n <div className=\"w-20 shrink-0\">\n <Select\n size=\"sm\"\n options={CONJ_OPTIONS}\n value={conjunction}\n onChange={(v) => onChange(v as Conjunction)}\n minRows={2}\n aria-label=\"連接詞 — 同 group 共用\"\n />\n </div>\n )\n}\n\n// ── FilterRow(flat 用 + group 內共用) ──────────────────────────────\n\nexport function FilterRow({\n index, condition, conjunction, filterableColumns, fieldOptions,\n onChangeConjunction, onChangeField, onChangeOp, onChangeValue, onRemove,\n}: {\n index: number\n condition: FilterCondition\n conjunction: Conjunction\n filterableColumns: FilterColumn[]\n fieldOptions: SelectOption[]\n onChangeConjunction: (c: Conjunction) => void\n onChangeField: (v: string) => void\n onChangeOp: (v: string) => void\n onChangeValue: (v: unknown) => void\n onRemove: () => void\n}) {\n const colInfo = filterableColumns.find((c) => c.id === condition.field)\n const operatorOptions = getOperatorOptions(colInfo?.type)\n const hasField = !!condition.field\n const opSpec = colInfo ? getOperatorSpec(colInfo.type, condition.op) : null\n const valueShape: ValueShape | null = colInfo && opSpec\n ? getValueShape(opSpec, colInfo.type, colInfo.includeTime)\n : null\n // op 'is_set' / 'is_not_set' 等 shape='none' → 無 value cell,op 自動 expand 填剩餘寬\n // 對齊 Notion / Airtable / Linear filter row 行為\n // 注意:valueShape=null(初始無 field 選)時仍 render value cell(disabled placeholder)— 只 'none' 才 fold\n const hasValueCell = valueShape !== 'none'\n\n // FieldControlGroup 接合 field + op + value 視覺(2026-05-04 E refactor + 多輪 fix):\n // - border collapse 取代 3 顆獨立 Select 並排,對齊 Airtable / Linear / Notion filter row idiom\n // - ConjunctionLabel + Trash 在 group 外層(meta actions,不屬 control 一體)\n // - **#5 fix**:row 內水平 gap = `gap-2` (8px),layoutSpace 規則 5 緊密相關\n // - **#9 fix**:cell 用 `min-w-[]`(field 160 / op 120),value flex-1 min-w-0,讓 long label 可撐寬\n // - **#2 fix**:FilterValuePicker 直接是 FieldControlGroup direct child(無 wrapper div),CSS variants 命中正確\n return (\n <div className=\"flex items-center gap-2\">\n <ConjunctionLabel index={index} conjunction={conjunction} onChange={onChangeConjunction} />\n {/* **#9 fix(2026-05-04 v4)**:Field controls trigger `w-full` override 外 className,改用 Tailwind `!`\n important 強制 override(`!w-[160px]` / `!w-[120px]`),value 用 `!flex-1 !min-w-0`。\n Select 元件本身沒 destructure `style` prop 所以 inline style flex-basis 行不通,只能用 className。 */}\n <FieldControlGroup block className=\"flex-1 min-w-0\">\n {/* 2026-05-23 Phase A.4 Decision 2:`!w-[160px]` / `!w-[120px]` → tokens\n `--data-table-filter-field-width` / `--data-table-filter-op-width`(SSOT in uiSize.css)\n Behavior preserved 完好如初:flat + nested 同 width(token 是 design constant) */}\n <Select\n className=\"!w-[var(--data-table-filter-field-width)] flex-shrink-0\"\n size=\"sm\"\n options={fieldOptions}\n value={condition.field}\n onChange={onChangeField}\n placeholder=\"選擇欄位\"\n aria-label=\"篩選欄位\"\n />\n <Select\n className={hasValueCell ? '!w-[var(--data-table-filter-op-width)] flex-shrink-0' : '!flex-1 !min-w-0'}\n size=\"sm\"\n options={operatorOptions}\n value={condition.op}\n onChange={onChangeOp}\n disabled={!hasField}\n placeholder=\"運算子\"\n aria-label=\"篩選運算子\"\n />\n {hasValueCell && (\n <FilterValuePicker\n shape={valueShape}\n value={condition.value}\n onChange={onChangeValue}\n colInfo={colInfo}\n disabled={!hasField}\n ariaLabel={colInfo ? `${colInfo.label} 篩選值` : '篩選值'}\n className=\"!flex-1 !min-w-0\"\n />\n )}\n </FieldControlGroup>\n {/* Trash 用 text Button — filter row 是 form-control row,Field 同高對齊(28 md) */}\n <Button variant=\"text\" size=\"sm\" iconOnly startIcon={Trash2} aria-label=\"刪除\" onClick={onRemove} />\n </div>\n )\n}\n\n// ── GroupBlock(nested 用) ────────────────────────────────────────────\n\nexport function GroupBlock({\n index, group, rootConjunction, filterableColumns, fieldOptions,\n onChangeRootConjunction, onChangeGroupConjunction,\n onChangeCondition, onRemoveCondition, onAddCondition, onRemoveGroup,\n}: {\n index: number\n group: FilterGroup\n rootConjunction: Conjunction\n filterableColumns: FilterColumn[]\n fieldOptions: SelectOption[]\n onChangeRootConjunction: (c: Conjunction) => void\n onChangeGroupConjunction: (c: Conjunction) => void\n onChangeCondition: (condId: string, patch: Partial<FilterCondition>) => void\n onRemoveCondition: (condId: string) => void\n onAddCondition: () => void\n onRemoveGroup: () => void\n}) {\n return (\n <div className=\"flex items-start gap-2\">\n <div className=\"pt-2\">\n <ConjunctionLabel index={index} conjunction={rootConjunction} onChange={onChangeRootConjunction} />\n </div>\n {/* Group container 灰底 — `bg-muted`(`--muted` neutral-2,user 2026-05-09 拍板 Q3 A)。對齊 color.spec.md L651-654 「table header / tab / code block / skeleton」靜態低重要 surface semantic */}\n <div className=\"flex-1 min-w-0 rounded-md bg-muted p-2 flex flex-col gap-2\">\n {group.children.map((cond, cIdx) => (\n <FilterRow\n key={cond.id}\n index={cIdx}\n condition={cond}\n conjunction={group.conjunction}\n filterableColumns={filterableColumns}\n fieldOptions={fieldOptions}\n onChangeConjunction={onChangeGroupConjunction}\n onChangeField={(v) => {\n const newCol = filterableColumns.find((c) => c.id === v)\n onChangeCondition(cond.id, { field: v, op: getDefaultOperator(newCol?.type), value: '', datePrecision: datePrecisionOf(newCol) })\n }}\n onChangeOp={(v) => onChangeCondition(cond.id, { op: v, value: '' })}\n onChangeValue={(v) => onChangeCondition(cond.id, { value: v })}\n onRemove={() => onRemoveCondition(cond.id)}\n />\n ))}\n {/* Q9 — text variant 對齊 inline 派 + 視覺輕量 */}\n <div className=\"flex items-center justify-between\">\n <Button variant=\"text\" size=\"sm\" startIcon={Plus} onClick={onAddCondition}>加入巢狀篩選</Button>\n {group.children.length === 0 && (\n <Button variant=\"text\" size=\"sm\" startIcon={Trash2} danger onClick={onRemoveGroup}>移除空群組</Button>\n )}\n </div>\n </div>\n </div>\n )\n}\n"],"names":[],"mappings":";;;;;;;AA0CA,SAAS,mBAAmB,MAAmC;AAC7D,QAAM,WAAW,QAAQ,kBAAkB,IAAI,IAAI,kBAAkB,IAAI,IAAI,kBAAkB;AAC/F,SAAO,SAAS,IAAI,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,OAAO,GAAG,MAAA,EAAQ;AACjE;AAEO,SAAS,mBAAmB,MAA2B;AAC5D,SAAQ,QAAQ,iBAAiB,IAAI,KAAM,iBAAiB;AAC9D;AAIO,MAAM,kBAAkB,CAAC,SAC9B,2BAAK,UAAS,SAAU,IAAI,cAAc,OAAO,QAAS;AAI5D,MAAM,eAA+B;AAAA,EACnC,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,EACvB,EAAE,OAAO,MAAM,OAAO,KAAA;AACxB;AAEA,SAAS,iBAAiB;AAAA,EACxB;AAAA,EAAO;AAAA,EAAa;AACtB,GAAoF;AAMlF,MAAI,UAAU,GAAG;AACf,WAAO,oBAAC,OAAA,EAAI,WAAU,0EAAyE,UAAA,SAAK;AAAA,EACtG;AACA,MAAI,SAAS,GAAG;AACd,UAAM,QAAQ,gBAAgB,QAAQ,QAAQ;AAC9C,WAAO,oBAAC,OAAA,EAAI,WAAU,0EAA0E,UAAA,OAAM;AAAA,EACxG;AAGA,SACE,oBAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,MACP,UAAU,CAAC,MAAM,SAAS,CAAgB;AAAA,MAC1C,SAAS;AAAA,MACT,cAAW;AAAA,IAAA;AAAA,EAAA,GAEf;AAEJ;AAIO,SAAS,UAAU;AAAA,EACxB;AAAA,EAAO;AAAA,EAAW;AAAA,EAAa;AAAA,EAAmB;AAAA,EAClD;AAAA,EAAqB;AAAA,EAAe;AAAA,EAAY;AAAA,EAAe;AACjE,GAWG;AACD,QAAM,UAAU,kBAAkB,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU,KAAK;AACtE,QAAM,kBAAkB,mBAAmB,mCAAS,IAAI;AACxD,QAAM,WAAW,CAAC,CAAC,UAAU;AAC7B,QAAM,SAAS,UAAU,gBAAgB,QAAQ,MAAM,UAAU,EAAE,IAAI;AACvE,QAAM,aAAgC,WAAW,SAC7C,cAAc,QAAQ,QAAQ,MAAM,QAAQ,WAAW,IACvD;AAIJ,QAAM,eAAe,eAAe;AAQpC,SACE,qBAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,IAAA,oBAAC,kBAAA,EAAiB,OAAc,aAA0B,UAAU,qBAAqB;AAAA,IAIzF,qBAAC,mBAAA,EAAkB,OAAK,MAAC,WAAU,kBAIjC,UAAA;AAAA,MAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,MAAK;AAAA,UACL,SAAS;AAAA,UACT,OAAO,UAAU;AAAA,UACjB,UAAU;AAAA,UACV,aAAY;AAAA,UACZ,cAAW;AAAA,QAAA;AAAA,MAAA;AAAA,MAEb;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAW,eAAe,yDAAyD;AAAA,UACnF,MAAK;AAAA,UACL,SAAS;AAAA,UACT,OAAO,UAAU;AAAA,UACjB,UAAU;AAAA,UACV,UAAU,CAAC;AAAA,UACX,aAAY;AAAA,UACZ,cAAW;AAAA,QAAA;AAAA,MAAA;AAAA,MAEZ,gBACC;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAO;AAAA,UACP,OAAO,UAAU;AAAA,UACjB,UAAU;AAAA,UACV;AAAA,UACA,UAAU,CAAC;AAAA,UACX,WAAW,UAAU,GAAG,QAAQ,KAAK,SAAS;AAAA,UAC9C,WAAU;AAAA,QAAA;AAAA,MAAA;AAAA,IACZ,GAEJ;AAAA,IAEA,oBAAC,QAAA,EAAO,SAAQ,QAAO,MAAK,MAAK,UAAQ,MAAC,WAAW,QAAQ,cAAW,MAAK,SAAS,SAAA,CAAU;AAAA,EAAA,GAClG;AAEJ;AAIO,SAAS,WAAW;AAAA,EACzB;AAAA,EAAO;AAAA,EAAO;AAAA,EAAiB;AAAA,EAAmB;AAAA,EAClD;AAAA,EAAyB;AAAA,EACzB;AAAA,EAAmB;AAAA,EAAmB;AAAA,EAAgB;AACxD,GAYG;AACD,SACE,qBAAC,OAAA,EAAI,WAAU,0BACb,UAAA;AAAA,IAAA,oBAAC,OAAA,EAAI,WAAU,QACb,UAAA,oBAAC,kBAAA,EAAiB,OAAc,aAAa,iBAAiB,UAAU,wBAAA,CAAyB,EAAA,CACnG;AAAA,IAEA,qBAAC,OAAA,EAAI,WAAU,8DACZ,UAAA;AAAA,MAAA,MAAM,SAAS,IAAI,CAAC,MAAM,SACzB;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,OAAO;AAAA,UACP,WAAW;AAAA,UACX,aAAa,MAAM;AAAA,UACnB;AAAA,UACA;AAAA,UACA,qBAAqB;AAAA,UACrB,eAAe,CAAC,MAAM;AACpB,kBAAM,SAAS,kBAAkB,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC;AACvD,8BAAkB,KAAK,IAAI,EAAE,OAAO,GAAG,IAAI,mBAAmB,iCAAQ,IAAI,GAAG,OAAO,IAAI,eAAe,gBAAgB,MAAM,GAAG;AAAA,UAClI;AAAA,UACA,YAAY,CAAC,MAAM,kBAAkB,KAAK,IAAI,EAAE,IAAI,GAAG,OAAO,IAAI;AAAA,UAClE,eAAe,CAAC,MAAM,kBAAkB,KAAK,IAAI,EAAE,OAAO,GAAG;AAAA,UAC7D,UAAU,MAAM,kBAAkB,KAAK,EAAE;AAAA,QAAA;AAAA,QAbpC,KAAK;AAAA,MAAA,CAeb;AAAA,MAED,qBAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,QAAA,oBAAC,QAAA,EAAO,SAAQ,QAAO,MAAK,MAAK,WAAW,MAAM,SAAS,gBAAgB,UAAA,SAAA,CAAM;AAAA,QAChF,MAAM,SAAS,WAAW,KACzB,oBAAC,UAAO,SAAQ,QAAO,MAAK,MAAK,WAAW,QAAQ,QAAM,MAAC,SAAS,eAAe,UAAA,QAAA,CAAK;AAAA,MAAA,EAAA,CAE5F;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;"}
|
|
@@ -4,8 +4,6 @@ import { createEmptyFilterTree, isFilterTreeActive, evaluateTree, dataTableFilte
|
|
|
4
4
|
export { createEmptyFilterTree, isFilterTreeActive, evaluateTree, dataTableFilterMatch, };
|
|
5
5
|
export type { Conjunction, FilterCondition, FilterGroup, FilterTree, FilterTreeFlat, FilterTreeNested };
|
|
6
6
|
export interface DataTableFilterPanelProps<TData> {
|
|
7
|
-
/** flat(無 group)or nested(1-level group)— consumer 拍板 */
|
|
8
|
-
mode: 'flat' | 'nested';
|
|
9
7
|
/** 可被 filter 的 columns */
|
|
10
8
|
columns: ColumnDef<TData, any>[];
|
|
11
9
|
/** 當前 FilterTree(controlled) */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-filter-panel.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/data-table-filter-panel.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"data-table-filter-panel.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/data-table-filter-panel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAgBtD,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAElB,YAAY,EACZ,oBAAoB,EACpB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACtB,MAAM,eAAe,CAAA;AAGtB,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,YAAY,EACZ,oBAAoB,GACrB,CAAA;AACD,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,gBAAgB,EAAE,CAAA;AAsFvG,MAAM,WAAW,yBAAyB,CAAC,KAAK;IAI9C,0BAA0B;IAC1B,OAAO,EAAE,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAA;IAChC,gCAAgC;IAChC,KAAK,EAAE,UAAU,CAAA;IACjB,wBAAwB;IACxB,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAA;IACpC;;;;OAIG;IACH,YAAY,CAAC,EAAE,UAAU,CAAA;IACzB,oEAAoE;IACpE,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAA;IAC9B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AA6PD,eAAO,MAAM,oBAAoB,EAAkD,CAAC,KAAK,EACvF,KAAK,EAAE,yBAAyB,CAAC,KAAK,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC,CAAA;CAAE,KACnF,KAAK,CAAC,YAAY,CACtB"}
|