@qijenchen/design-system 0.1.0-beta.8 → 0.1.0-beta.80
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/CLAUDE.md +200 -0
- package/README.md +10 -9
- package/cli-init.mjs +90 -0
- package/dist/components/Accordion/accordion.d.ts +1 -1
- package/dist/components/Accordion/accordion.d.ts.map +1 -1
- package/dist/components/Accordion/accordion.js +4 -1
- package/dist/components/Accordion/accordion.js.map +1 -1
- package/dist/components/Accordion/index.d.ts +2 -0
- package/dist/components/Accordion/index.d.ts.map +1 -0
- package/dist/components/Accordion/index.js +9 -0
- package/dist/components/Accordion/index.js.map +1 -0
- package/dist/components/Alert/alert.d.ts +2 -2
- package/dist/components/Alert/alert.d.ts.map +1 -1
- package/dist/components/Alert/alert.js +8 -7
- package/dist/components/Alert/alert.js.map +1 -1
- package/dist/components/Alert/index.d.ts +2 -0
- package/dist/components/Alert/index.d.ts.map +1 -0
- package/dist/components/Alert/index.js +7 -0
- package/dist/components/Alert/index.js.map +1 -0
- package/dist/components/AppShell/_demo-helpers.d.ts +3 -1
- package/dist/components/AppShell/_demo-helpers.d.ts.map +1 -1
- package/dist/components/AppShell/app-shell.d.ts +2 -2
- package/dist/components/AppShell/app-shell.d.ts.map +1 -1
- package/dist/components/AppShell/app-shell.js +9 -8
- package/dist/components/AppShell/app-shell.js.map +1 -1
- package/dist/components/AppShell/index.d.ts +2 -0
- package/dist/components/AppShell/index.d.ts.map +1 -0
- package/dist/components/AppShell/index.js +7 -0
- package/dist/components/AppShell/index.js.map +1 -0
- package/dist/components/AspectRatio/aspect-ratio.d.ts +1 -1
- package/dist/components/AspectRatio/aspect-ratio.d.ts.map +1 -1
- package/dist/components/AspectRatio/aspect-ratio.js +4 -2
- package/dist/components/AspectRatio/aspect-ratio.js.map +1 -1
- package/dist/components/AspectRatio/index.d.ts +2 -0
- package/dist/components/AspectRatio/index.d.ts.map +1 -0
- package/dist/components/AspectRatio/index.js +6 -0
- package/dist/components/AspectRatio/index.js.map +1 -0
- package/dist/components/Avatar/avatar.d.ts +12 -6
- package/dist/components/Avatar/avatar.d.ts.map +1 -1
- package/dist/components/Avatar/avatar.js +12 -23
- package/dist/components/Avatar/avatar.js.map +1 -1
- package/dist/components/Avatar/index.d.ts +2 -0
- package/dist/components/Avatar/index.d.ts.map +1 -0
- package/dist/components/Avatar/index.js +6 -0
- package/dist/components/Avatar/index.js.map +1 -0
- package/dist/components/Badge/badge.d.ts +20 -8
- package/dist/components/Badge/badge.d.ts.map +1 -1
- package/dist/components/Badge/badge.js +7 -5
- package/dist/components/Badge/badge.js.map +1 -1
- package/dist/components/Badge/index.d.ts +2 -0
- package/dist/components/Badge/index.d.ts.map +1 -0
- package/dist/components/Badge/index.js +7 -0
- package/dist/components/Badge/index.js.map +1 -0
- package/dist/components/Breadcrumb/breadcrumb.d.ts +1 -1
- package/dist/components/Breadcrumb/breadcrumb.js.map +1 -1
- package/dist/components/Breadcrumb/index.d.ts +2 -0
- package/dist/components/Breadcrumb/index.d.ts.map +1 -0
- package/dist/components/Breadcrumb/index.js +12 -0
- package/dist/components/Breadcrumb/index.js.map +1 -0
- package/dist/components/BulkActionBar/bulk-action-bar.d.ts +2 -2
- 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/BulkActionBar/index.d.ts +2 -0
- package/dist/components/BulkActionBar/index.d.ts.map +1 -0
- package/dist/components/BulkActionBar/index.js +7 -0
- package/dist/components/BulkActionBar/index.js.map +1 -0
- package/dist/components/Button/button.d.ts +7 -7
- package/dist/components/Button/button.d.ts.map +1 -1
- package/dist/components/Button/button.js +13 -10
- package/dist/components/Button/button.js.map +1 -1
- package/dist/components/Button/index.d.ts +2 -0
- package/dist/components/Button/index.d.ts.map +1 -0
- package/dist/components/Button/index.js +8 -0
- package/dist/components/Button/index.js.map +1 -0
- package/dist/components/Calendar/calendar.d.ts +9 -5
- package/dist/components/Calendar/calendar.d.ts.map +1 -1
- package/dist/components/Calendar/calendar.js +88 -76
- package/dist/components/Calendar/calendar.js.map +1 -1
- package/dist/components/Calendar/index.d.ts +2 -0
- package/dist/components/Calendar/index.d.ts.map +1 -0
- package/dist/components/Calendar/index.js +6 -0
- package/dist/components/Calendar/index.js.map +1 -0
- package/dist/components/Carousel/carousel.d.ts.map +1 -1
- package/dist/components/Carousel/carousel.js +11 -6
- package/dist/components/Carousel/carousel.js.map +1 -1
- package/dist/components/Carousel/index.d.ts +2 -0
- package/dist/components/Carousel/index.d.ts.map +1 -0
- package/dist/components/Carousel/index.js +11 -0
- package/dist/components/Carousel/index.js.map +1 -0
- package/dist/components/Chart/chart.d.ts +2 -2
- package/dist/components/Chart/chart.d.ts.map +1 -1
- package/dist/components/Chart/chart.js +3 -1
- package/dist/components/Chart/chart.js.map +1 -1
- package/dist/components/Chart/index.d.ts +2 -0
- package/dist/components/Chart/index.d.ts.map +1 -0
- package/dist/components/Chart/index.js +11 -0
- package/dist/components/Chart/index.js.map +1 -0
- package/dist/components/Checkbox/checkbox-group.d.ts +2 -1
- package/dist/components/Checkbox/checkbox-group.d.ts.map +1 -1
- package/dist/components/Checkbox/checkbox-group.js.map +1 -1
- package/dist/components/Checkbox/checkbox.d.ts +13 -7
- package/dist/components/Checkbox/checkbox.d.ts.map +1 -1
- package/dist/components/Checkbox/checkbox.js +49 -15
- package/dist/components/Checkbox/checkbox.js.map +1 -1
- package/dist/components/Checkbox/index.d.ts +2 -0
- package/dist/components/Checkbox/index.d.ts.map +1 -0
- package/dist/components/Checkbox/index.js +7 -0
- package/dist/components/Checkbox/index.js.map +1 -0
- package/dist/components/Chip/chip.d.ts +6 -6
- package/dist/components/Chip/chip.js +4 -3
- package/dist/components/Chip/chip.js.map +1 -1
- package/dist/components/Chip/index.d.ts +2 -0
- package/dist/components/Chip/index.d.ts.map +1 -0
- package/dist/components/Chip/index.js +8 -0
- package/dist/components/Chip/index.js.map +1 -0
- package/dist/components/CircularProgress/circular-progress.d.ts +2 -3
- package/dist/components/CircularProgress/circular-progress.d.ts.map +1 -1
- package/dist/components/CircularProgress/circular-progress.js +4 -3
- package/dist/components/CircularProgress/circular-progress.js.map +1 -1
- package/dist/components/CircularProgress/index.d.ts +2 -0
- package/dist/components/CircularProgress/index.d.ts.map +1 -0
- package/dist/components/CircularProgress/index.js +6 -0
- package/dist/components/CircularProgress/index.js.map +1 -0
- package/dist/components/Coachmark/coachmark-story-helpers.d.ts +22 -0
- package/dist/components/Coachmark/coachmark-story-helpers.d.ts.map +1 -0
- package/dist/components/Coachmark/coachmark.d.ts +4 -4
- package/dist/components/Coachmark/coachmark.d.ts.map +1 -1
- package/dist/components/Coachmark/coachmark.js +9 -4
- package/dist/components/Coachmark/coachmark.js.map +1 -1
- package/dist/components/Coachmark/index.d.ts +2 -0
- package/dist/components/Coachmark/index.d.ts.map +1 -0
- package/dist/components/Coachmark/index.js +6 -0
- package/dist/components/Coachmark/index.js.map +1 -0
- package/dist/components/Combobox/combobox.d.ts +16 -7
- package/dist/components/Combobox/combobox.d.ts.map +1 -1
- package/dist/components/Combobox/combobox.js +74 -39
- package/dist/components/Combobox/combobox.js.map +1 -1
- package/dist/components/Combobox/index.d.ts +2 -0
- package/dist/components/Combobox/index.d.ts.map +1 -0
- package/dist/components/Combobox/index.js +6 -0
- package/dist/components/Combobox/index.js.map +1 -0
- package/dist/components/Command/command.d.ts +5 -1
- package/dist/components/Command/command.d.ts.map +1 -1
- package/dist/components/Command/command.js +6 -6
- package/dist/components/Command/command.js.map +1 -1
- package/dist/components/Command/index.d.ts +2 -0
- package/dist/components/Command/index.d.ts.map +1 -0
- package/dist/components/Command/index.js +14 -0
- package/dist/components/Command/index.js.map +1 -0
- package/dist/components/DataTable/cell-registry.d.ts.map +1 -1
- package/dist/components/DataTable/cell-registry.js +6 -5
- package/dist/components/DataTable/cell-registry.js.map +1 -1
- package/dist/components/DataTable/data-table.d.ts +29 -8
- package/dist/components/DataTable/data-table.d.ts.map +1 -1
- package/dist/components/DataTable/data-table.js +69 -39
- package/dist/components/DataTable/data-table.js.map +1 -1
- package/dist/components/DataTable/filter-operators.d.ts +1 -1
- package/dist/components/DataTable/filter-tree.d.ts +1 -1
- package/dist/components/DataTable/index.d.ts +2 -0
- package/dist/components/DataTable/index.d.ts.map +1 -0
- package/dist/components/DataTable/index.js +8 -0
- package/dist/components/DataTable/index.js.map +1 -0
- package/dist/components/DateGrid/date-grid.d.ts +21 -17
- package/dist/components/DateGrid/date-grid.d.ts.map +1 -1
- package/dist/components/DateGrid/date-grid.js +2 -2
- package/dist/components/DateGrid/date-grid.js.map +1 -1
- package/dist/components/DateGrid/index.d.ts +2 -0
- package/dist/components/DateGrid/index.d.ts.map +1 -0
- package/dist/components/DateGrid/index.js +6 -0
- package/dist/components/DateGrid/index.js.map +1 -0
- package/dist/components/DatePicker/date-picker.d.ts.map +1 -1
- package/dist/components/DatePicker/date-picker.js +29 -18
- package/dist/components/DatePicker/date-picker.js.map +1 -1
- package/dist/components/DatePicker/index.d.ts +2 -0
- package/dist/components/DatePicker/index.d.ts.map +1 -0
- package/dist/components/DatePicker/index.js +8 -0
- package/dist/components/DatePicker/index.js.map +1 -0
- package/dist/components/DescriptionList/description-list.d.ts +3 -3
- package/dist/components/DescriptionList/description-list.js +4 -3
- package/dist/components/DescriptionList/description-list.js.map +1 -1
- package/dist/components/DescriptionList/index.d.ts +2 -0
- package/dist/components/DescriptionList/index.d.ts.map +1 -0
- package/dist/components/DescriptionList/index.js +7 -0
- package/dist/components/DescriptionList/index.js.map +1 -0
- package/dist/components/Dialog/dialog.d.ts.map +1 -1
- package/dist/components/Dialog/dialog.js.map +1 -1
- package/dist/components/Dialog/index.d.ts +2 -0
- package/dist/components/Dialog/index.d.ts.map +1 -0
- package/dist/components/Dialog/index.js +16 -0
- package/dist/components/Dialog/index.js.map +1 -0
- package/dist/components/DropdownMenu/dropdown-menu.d.ts +3 -2
- package/dist/components/DropdownMenu/dropdown-menu.d.ts.map +1 -1
- package/dist/components/DropdownMenu/dropdown-menu.js +3 -4
- package/dist/components/DropdownMenu/dropdown-menu.js.map +1 -1
- package/dist/components/DropdownMenu/index.d.ts +2 -0
- package/dist/components/DropdownMenu/index.d.ts.map +1 -0
- package/dist/components/DropdownMenu/index.js +21 -0
- package/dist/components/DropdownMenu/index.js.map +1 -0
- package/dist/components/Empty/empty.d.ts +11 -3
- package/dist/components/Empty/empty.d.ts.map +1 -1
- package/dist/components/Empty/empty.js +6 -6
- package/dist/components/Empty/empty.js.map +1 -1
- package/dist/components/Empty/index.d.ts +2 -0
- package/dist/components/Empty/index.d.ts.map +1 -0
- package/dist/components/Empty/index.js +6 -0
- package/dist/components/Empty/index.js.map +1 -0
- package/dist/components/Field/field-context.d.ts +49 -0
- package/dist/components/Field/field-context.d.ts.map +1 -1
- package/dist/components/Field/field-context.js +42 -0
- package/dist/components/Field/field-context.js.map +1 -1
- package/dist/components/Field/field-types.js.map +1 -1
- package/dist/components/Field/field-wrapper.js +5 -5
- package/dist/components/Field/field-wrapper.js.map +1 -1
- package/dist/components/Field/field.d.ts +4 -2
- package/dist/components/Field/field.d.ts.map +1 -1
- package/dist/components/Field/field.js +1 -0
- package/dist/components/Field/field.js.map +1 -1
- package/dist/components/Field/index.d.ts +2 -0
- package/dist/components/Field/index.d.ts.map +1 -0
- package/dist/components/Field/index.js +12 -0
- package/dist/components/Field/index.js.map +1 -0
- package/dist/components/Field/use-form-validation.d.ts +88 -0
- package/dist/components/Field/use-form-validation.d.ts.map +1 -0
- package/dist/components/Field/use-form-validation.js +127 -0
- package/dist/components/Field/use-form-validation.js.map +1 -0
- package/dist/components/FieldControlGroup/field-control-group.d.ts +5 -5
- package/dist/components/FieldControlGroup/field-control-group.d.ts.map +1 -1
- package/dist/components/FieldControlGroup/field-control-group.js +1 -1
- package/dist/components/FieldControlGroup/field-control-group.js.map +1 -1
- package/dist/components/FieldControlGroup/index.d.ts +2 -0
- package/dist/components/FieldControlGroup/index.d.ts.map +1 -0
- package/dist/components/FieldControlGroup/index.js +6 -0
- package/dist/components/FieldControlGroup/index.js.map +1 -0
- package/dist/components/FileItem/file-item.d.ts +12 -2
- package/dist/components/FileItem/file-item.d.ts.map +1 -1
- package/dist/components/FileItem/file-item.js +20 -6
- package/dist/components/FileItem/file-item.js.map +1 -1
- package/dist/components/FileItem/index.d.ts +2 -0
- package/dist/components/FileItem/index.d.ts.map +1 -0
- package/dist/components/FileItem/index.js +6 -0
- package/dist/components/FileItem/index.js.map +1 -0
- package/dist/components/FileUpload/file-upload.d.ts +32 -13
- package/dist/components/FileUpload/file-upload.d.ts.map +1 -1
- package/dist/components/FileUpload/file-upload.js +62 -18
- package/dist/components/FileUpload/file-upload.js.map +1 -1
- package/dist/components/FileUpload/index.d.ts +2 -0
- package/dist/components/FileUpload/index.d.ts.map +1 -0
- package/dist/components/FileUpload/index.js +6 -0
- package/dist/components/FileUpload/index.js.map +1 -0
- package/dist/components/FileViewer/file-viewer.d.ts +2 -2
- package/dist/components/FileViewer/file-viewer.d.ts.map +1 -1
- package/dist/components/FileViewer/file-viewer.js +28 -19
- package/dist/components/FileViewer/file-viewer.js.map +1 -1
- package/dist/components/FileViewer/index.d.ts +2 -0
- package/dist/components/FileViewer/index.d.ts.map +1 -0
- package/dist/components/FileViewer/index.js +7 -0
- package/dist/components/FileViewer/index.js.map +1 -0
- package/dist/components/HoverCard/hover-card.d.ts +7 -3
- package/dist/components/HoverCard/hover-card.d.ts.map +1 -1
- package/dist/components/HoverCard/hover-card.js +4 -3
- package/dist/components/HoverCard/hover-card.js.map +1 -1
- package/dist/components/HoverCard/index.d.ts +2 -0
- package/dist/components/HoverCard/index.d.ts.map +1 -0
- package/dist/components/HoverCard/index.js +8 -0
- package/dist/components/HoverCard/index.js.map +1 -0
- package/dist/components/Input/index.d.ts +2 -0
- package/dist/components/Input/index.d.ts.map +1 -0
- package/dist/components/Input/index.js +6 -0
- package/dist/components/Input/index.js.map +1 -0
- package/dist/components/Input/input.d.ts +5 -2
- package/dist/components/Input/input.d.ts.map +1 -1
- package/dist/components/Input/input.js +10 -8
- package/dist/components/Input/input.js.map +1 -1
- package/dist/components/LinkInput/index.d.ts +2 -0
- package/dist/components/LinkInput/index.d.ts.map +1 -0
- package/dist/components/LinkInput/index.js +6 -0
- package/dist/components/LinkInput/index.js.map +1 -0
- package/dist/components/LinkInput/link-input.d.ts.map +1 -1
- package/dist/components/LinkInput/link-input.js +8 -8
- package/dist/components/LinkInput/link-input.js.map +1 -1
- package/dist/components/Menu/index.d.ts +2 -0
- package/dist/components/Menu/index.d.ts.map +1 -0
- package/dist/components/Menu/index.js +9 -0
- package/dist/components/Menu/index.js.map +1 -0
- package/dist/components/Menu/menu-item.d.ts +6 -2
- package/dist/components/Menu/menu-item.d.ts.map +1 -1
- package/dist/components/Menu/menu-item.js +2 -1
- package/dist/components/Menu/menu-item.js.map +1 -1
- package/dist/components/Notice/index.d.ts +2 -0
- package/dist/components/Notice/index.d.ts.map +1 -0
- package/dist/components/Notice/index.js +8 -0
- package/dist/components/Notice/index.js.map +1 -0
- package/dist/components/Notice/notice.d.ts +13 -6
- package/dist/components/Notice/notice.d.ts.map +1 -1
- package/dist/components/Notice/notice.js +16 -6
- package/dist/components/Notice/notice.js.map +1 -1
- package/dist/components/NumberInput/index.d.ts +2 -0
- package/dist/components/NumberInput/index.d.ts.map +1 -0
- package/dist/components/NumberInput/index.js +7 -0
- package/dist/components/NumberInput/index.js.map +1 -0
- package/dist/components/NumberInput/number-input.d.ts.map +1 -1
- package/dist/components/NumberInput/number-input.js +8 -7
- package/dist/components/NumberInput/number-input.js.map +1 -1
- package/dist/components/OverflowIndicator/index.d.ts +2 -0
- package/dist/components/OverflowIndicator/index.d.ts.map +1 -0
- package/dist/components/OverflowIndicator/index.js +6 -0
- package/dist/components/OverflowIndicator/index.js.map +1 -0
- package/dist/components/OverflowIndicator/overflow-indicator.d.ts +5 -1
- package/dist/components/OverflowIndicator/overflow-indicator.d.ts.map +1 -1
- package/dist/components/OverflowIndicator/overflow-indicator.js +13 -6
- package/dist/components/OverflowIndicator/overflow-indicator.js.map +1 -1
- package/dist/components/PeoplePicker/index.d.ts +2 -0
- package/dist/components/PeoplePicker/index.d.ts.map +1 -0
- package/dist/components/PeoplePicker/index.js +9 -0
- package/dist/components/PeoplePicker/index.js.map +1 -0
- package/dist/components/PeoplePicker/people-picker-helpers.d.ts.map +1 -1
- package/dist/components/PeoplePicker/people-picker-helpers.js +2 -2
- package/dist/components/PeoplePicker/people-picker-helpers.js.map +1 -1
- package/dist/components/PeoplePicker/people-picker.d.ts.map +1 -1
- package/dist/components/PeoplePicker/people-picker.js +21 -17
- package/dist/components/PeoplePicker/people-picker.js.map +1 -1
- package/dist/components/PeoplePicker/person-display.d.ts +7 -7
- package/dist/components/PeoplePicker/person-display.d.ts.map +1 -1
- package/dist/components/PeoplePicker/person-display.js +9 -9
- package/dist/components/PeoplePicker/person-display.js.map +1 -1
- package/dist/components/Popover/index.d.ts +2 -0
- package/dist/components/Popover/index.d.ts.map +1 -0
- package/dist/components/Popover/index.js +14 -0
- package/dist/components/Popover/index.js.map +1 -0
- package/dist/components/Popover/popover.d.ts +2 -2
- package/dist/components/Popover/popover.d.ts.map +1 -1
- package/dist/components/Popover/popover.js +12 -12
- package/dist/components/Popover/popover.js.map +1 -1
- package/dist/components/ProfileCard/index.d.ts +2 -0
- package/dist/components/ProfileCard/index.d.ts.map +1 -0
- package/dist/components/ProfileCard/index.js +8 -0
- package/dist/components/ProfileCard/index.js.map +1 -0
- package/dist/components/{NameCard/name-card.d.ts → ProfileCard/profile-card.d.ts} +26 -20
- package/dist/components/ProfileCard/profile-card.d.ts.map +1 -0
- package/dist/components/{NameCard/name-card.js → ProfileCard/profile-card.js} +11 -10
- package/dist/components/ProfileCard/profile-card.js.map +1 -0
- package/dist/components/ProgressBar/index.d.ts +2 -0
- package/dist/components/ProgressBar/index.d.ts.map +1 -0
- package/dist/components/ProgressBar/index.js +6 -0
- package/dist/components/ProgressBar/index.js.map +1 -0
- package/dist/components/ProgressBar/progress-bar.d.ts +2 -2
- package/dist/components/ProgressBar/progress-bar.js +3 -3
- package/dist/components/ProgressBar/progress-bar.js.map +1 -1
- package/dist/components/RadioGroup/index.d.ts +2 -0
- package/dist/components/RadioGroup/index.d.ts.map +1 -0
- package/dist/components/RadioGroup/index.js +8 -0
- package/dist/components/RadioGroup/index.js.map +1 -0
- package/dist/components/RadioGroup/radio-group.d.ts +15 -9
- package/dist/components/RadioGroup/radio-group.d.ts.map +1 -1
- package/dist/components/RadioGroup/radio-group.js +71 -33
- package/dist/components/RadioGroup/radio-group.js.map +1 -1
- package/dist/components/Rating/index.d.ts +2 -0
- package/dist/components/Rating/index.d.ts.map +1 -0
- package/dist/components/Rating/index.js +6 -0
- package/dist/components/Rating/index.js.map +1 -0
- package/dist/components/Rating/rating.d.ts +6 -2
- package/dist/components/Rating/rating.d.ts.map +1 -1
- package/dist/components/Rating/rating.js +10 -7
- package/dist/components/Rating/rating.js.map +1 -1
- package/dist/components/ScrollArea/index.d.ts +2 -0
- package/dist/components/ScrollArea/index.d.ts.map +1 -0
- package/dist/components/ScrollArea/index.js +7 -0
- package/dist/components/ScrollArea/index.js.map +1 -0
- package/dist/components/ScrollArea/scroll-area.d.ts +1 -1
- package/dist/components/ScrollArea/scroll-area.js +2 -2
- package/dist/components/ScrollArea/scroll-area.js.map +1 -1
- package/dist/components/SegmentedControl/index.d.ts +2 -0
- package/dist/components/SegmentedControl/index.d.ts.map +1 -0
- package/dist/components/SegmentedControl/index.js +9 -0
- package/dist/components/SegmentedControl/index.js.map +1 -0
- package/dist/components/SegmentedControl/segmented-control.d.ts +2 -2
- package/dist/components/SegmentedControl/segmented-control.d.ts.map +1 -1
- package/dist/components/SegmentedControl/segmented-control.js +8 -10
- package/dist/components/SegmentedControl/segmented-control.js.map +1 -1
- package/dist/components/Select/index.d.ts +2 -0
- package/dist/components/Select/index.d.ts.map +1 -0
- package/dist/components/Select/index.js +6 -0
- package/dist/components/Select/index.js.map +1 -0
- package/dist/components/Select/select.d.ts.map +1 -1
- package/dist/components/Select/select.js +30 -18
- package/dist/components/Select/select.js.map +1 -1
- package/dist/components/SelectMenu/index.d.ts +2 -0
- package/dist/components/SelectMenu/index.d.ts.map +1 -0
- package/dist/components/SelectMenu/index.js +6 -0
- package/dist/components/SelectMenu/index.js.map +1 -0
- package/dist/components/SelectMenu/select-menu.d.ts +10 -5
- package/dist/components/SelectMenu/select-menu.d.ts.map +1 -1
- package/dist/components/SelectMenu/select-menu.js +12 -4
- package/dist/components/SelectMenu/select-menu.js.map +1 -1
- package/dist/components/SelectionControl/index.d.ts +2 -0
- package/dist/components/SelectionControl/index.d.ts.map +1 -0
- package/dist/components/SelectionControl/index.js +7 -0
- package/dist/components/SelectionControl/index.js.map +1 -0
- package/dist/components/SelectionControl/selection-item.d.ts +5 -1
- package/dist/components/SelectionControl/selection-item.d.ts.map +1 -1
- package/dist/components/SelectionControl/selection-item.js +3 -1
- package/dist/components/SelectionControl/selection-item.js.map +1 -1
- package/dist/components/Separator/index.d.ts +2 -0
- package/dist/components/Separator/index.d.ts.map +1 -0
- package/dist/components/Separator/index.js +6 -0
- package/dist/components/Separator/index.js.map +1 -0
- package/dist/components/Separator/separator.d.ts +2 -2
- package/dist/components/Separator/separator.js +4 -3
- package/dist/components/Separator/separator.js.map +1 -1
- package/dist/components/Sheet/index.d.ts +2 -0
- package/dist/components/Sheet/index.d.ts.map +1 -0
- package/dist/components/Sheet/index.js +17 -0
- package/dist/components/Sheet/index.js.map +1 -0
- package/dist/components/Sheet/sheet.d.ts +6 -5
- package/dist/components/Sheet/sheet.d.ts.map +1 -1
- package/dist/components/Sheet/sheet.js +1 -1
- package/dist/components/Sheet/sheet.js.map +1 -1
- package/dist/components/Sidebar/index.d.ts +2 -0
- package/dist/components/Sidebar/index.d.ts.map +1 -0
- package/dist/components/Sidebar/index.js +24 -0
- package/dist/components/Sidebar/index.js.map +1 -0
- package/dist/components/Sidebar/sidebar.d.ts +2 -2
- package/dist/components/Sidebar/sidebar.d.ts.map +1 -1
- package/dist/components/Sidebar/sidebar.js +9 -5
- package/dist/components/Sidebar/sidebar.js.map +1 -1
- package/dist/components/Skeleton/index.d.ts +2 -0
- package/dist/components/Skeleton/index.d.ts.map +1 -0
- package/dist/components/Skeleton/index.js +6 -0
- package/dist/components/Skeleton/index.js.map +1 -0
- package/dist/components/Skeleton/skeleton.d.ts +1 -1
- package/dist/components/Skeleton/skeleton.js +2 -1
- package/dist/components/Skeleton/skeleton.js.map +1 -1
- package/dist/components/Slider/index.d.ts +2 -0
- package/dist/components/Slider/index.d.ts.map +1 -0
- package/dist/components/Slider/index.js +7 -0
- package/dist/components/Slider/index.js.map +1 -0
- package/dist/components/Slider/slider.d.ts +6 -6
- package/dist/components/Slider/slider.d.ts.map +1 -1
- package/dist/components/Slider/slider.js +25 -10
- package/dist/components/Slider/slider.js.map +1 -1
- package/dist/components/Steps/index.d.ts +2 -0
- package/dist/components/Steps/index.d.ts.map +1 -0
- package/dist/components/Steps/index.js +12 -0
- package/dist/components/Steps/index.js.map +1 -0
- package/dist/components/Steps/steps.d.ts +2 -2
- package/dist/components/Steps/steps.d.ts.map +1 -1
- package/dist/components/Steps/steps.js +48 -23
- package/dist/components/Steps/steps.js.map +1 -1
- package/dist/components/Switch/index.d.ts +2 -0
- package/dist/components/Switch/index.d.ts.map +1 -0
- package/dist/components/Switch/index.js +7 -0
- package/dist/components/Switch/index.js.map +1 -0
- package/dist/components/Switch/switch.d.ts +16 -14
- package/dist/components/Switch/switch.d.ts.map +1 -1
- package/dist/components/Switch/switch.js +46 -17
- package/dist/components/Switch/switch.js.map +1 -1
- package/dist/components/Tabs/index.d.ts +2 -0
- package/dist/components/Tabs/index.d.ts.map +1 -0
- package/dist/components/Tabs/index.js +10 -0
- package/dist/components/Tabs/index.js.map +1 -0
- package/dist/components/Tabs/tabs.d.ts +5 -5
- package/dist/components/Tabs/tabs.d.ts.map +1 -1
- package/dist/components/Tabs/tabs.js +14 -7
- package/dist/components/Tabs/tabs.js.map +1 -1
- package/dist/components/Tag/index.d.ts +2 -0
- package/dist/components/Tag/index.d.ts.map +1 -0
- package/dist/components/Tag/index.js +7 -0
- package/dist/components/Tag/index.js.map +1 -0
- package/dist/components/Tag/tag.d.ts +37 -23
- package/dist/components/Tag/tag.d.ts.map +1 -1
- package/dist/components/Tag/tag.js +39 -44
- package/dist/components/Tag/tag.js.map +1 -1
- package/dist/components/Textarea/index.d.ts +2 -0
- package/dist/components/Textarea/index.d.ts.map +1 -0
- package/dist/components/Textarea/index.js +7 -0
- package/dist/components/Textarea/index.js.map +1 -0
- package/dist/components/Textarea/textarea.d.ts +5 -10
- package/dist/components/Textarea/textarea.d.ts.map +1 -1
- package/dist/components/Textarea/textarea.js +14 -12
- package/dist/components/Textarea/textarea.js.map +1 -1
- package/dist/components/TimePicker/index.d.ts +2 -0
- package/dist/components/TimePicker/index.d.ts.map +1 -0
- package/dist/components/TimePicker/index.js +6 -0
- package/dist/components/TimePicker/index.js.map +1 -0
- package/dist/components/TimePicker/time-columns.d.ts.map +1 -1
- package/dist/components/TimePicker/time-columns.js +4 -1
- package/dist/components/TimePicker/time-columns.js.map +1 -1
- package/dist/components/TimePicker/time-picker.d.ts +2 -1
- package/dist/components/TimePicker/time-picker.d.ts.map +1 -1
- package/dist/components/TimePicker/time-picker.js +33 -32
- package/dist/components/TimePicker/time-picker.js.map +1 -1
- package/dist/components/Toast/index.d.ts +2 -0
- package/dist/components/Toast/index.d.ts.map +1 -0
- package/dist/components/Toast/index.js +7 -0
- package/dist/components/Toast/index.js.map +1 -0
- package/dist/components/Toast/toast.d.ts +1 -1
- package/dist/components/Toast/toast.js +2 -2
- package/dist/components/Toast/toast.js.map +1 -1
- package/dist/components/Tooltip/index.d.ts +2 -0
- package/dist/components/Tooltip/index.d.ts.map +1 -0
- package/dist/components/Tooltip/index.js +9 -0
- package/dist/components/Tooltip/index.js.map +1 -0
- 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 +2 -1
- package/dist/components/Tooltip/tooltip.js.map +1 -1
- package/dist/components/TreeView/index.d.ts +2 -0
- package/dist/components/TreeView/index.d.ts.map +1 -0
- package/dist/components/TreeView/index.js +8 -0
- package/dist/components/TreeView/index.js.map +1 -0
- package/dist/components/TreeView/tree-view.d.ts +11 -11
- package/dist/components/TreeView/tree-view.d.ts.map +1 -1
- package/dist/components/TreeView/tree-view.js +36 -9
- package/dist/components/TreeView/tree-view.js.map +1 -1
- package/dist/hooks/use-overflow-items.d.ts +10 -6
- package/dist/hooks/use-overflow-items.d.ts.map +1 -1
- package/dist/hooks/use-overflow-items.js.map +1 -1
- package/dist/index.d.ts +57 -67
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -59
- package/dist/index.js.map +1 -1
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +3 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/node_modules/react-hook-form/dist/index.esm.js +1950 -0
- package/dist/node_modules/react-hook-form/dist/index.esm.js.map +1 -0
- package/dist/patterns/element-anatomy/index.d.ts +2 -0
- package/dist/patterns/element-anatomy/index.d.ts.map +1 -0
- package/dist/patterns/element-anatomy/index.js +20 -0
- package/dist/patterns/element-anatomy/index.js.map +1 -0
- package/dist/patterns/element-anatomy/item-anatomy.d.ts +9 -5
- package/dist/patterns/element-anatomy/item-anatomy.d.ts.map +1 -1
- package/dist/patterns/element-anatomy/item-anatomy.js +1 -1
- package/dist/patterns/element-anatomy/item-anatomy.js.map +1 -1
- package/dist/patterns/header-canonical/chrome-header.d.ts +13 -4
- package/dist/patterns/header-canonical/chrome-header.d.ts.map +1 -1
- package/dist/patterns/header-canonical/chrome-header.js +4 -2
- package/dist/patterns/header-canonical/chrome-header.js.map +1 -1
- package/dist/patterns/header-canonical/index.d.ts +2 -0
- package/dist/patterns/header-canonical/index.d.ts.map +1 -0
- package/dist/patterns/header-canonical/index.js +6 -0
- package/dist/patterns/header-canonical/index.js.map +1 -0
- package/dist/patterns/horizontal-overflow/index.d.ts +2 -0
- package/dist/patterns/horizontal-overflow/index.d.ts.map +1 -0
- package/dist/patterns/horizontal-overflow/index.js +14 -0
- package/dist/patterns/horizontal-overflow/index.js.map +1 -0
- package/dist/patterns/overlay-surface/index.d.ts +2 -0
- package/dist/patterns/overlay-surface/index.d.ts.map +1 -0
- package/dist/patterns/overlay-surface/index.js +8 -0
- package/dist/patterns/overlay-surface/index.js.map +1 -0
- package/dist/patterns/overlay-surface/overlay-surface.d.ts +11 -2
- package/dist/patterns/overlay-surface/overlay-surface.d.ts.map +1 -1
- package/dist/patterns/overlay-surface/overlay-surface.js +5 -2
- package/dist/patterns/overlay-surface/overlay-surface.js.map +1 -1
- package/dist/patterns/resize-handle/index.d.ts +2 -0
- package/dist/patterns/resize-handle/index.d.ts.map +1 -0
- package/dist/patterns/resize-handle/index.js +5 -0
- package/dist/patterns/resize-handle/index.js.map +1 -0
- package/dist/story-governance/category-matrix.d.ts +35 -0
- package/dist/story-governance/category-matrix.d.ts.map +1 -0
- package/dist/tokens/categorical-color.d.ts +60 -0
- package/dist/tokens/categorical-color.d.ts.map +1 -0
- package/dist/tokens/categorical-color.js +110 -0
- package/dist/tokens/categorical-color.js.map +1 -0
- package/dist/tokens/motion/motion.d.ts +1 -1
- package/dist/tokens/motion/motion.d.ts.map +1 -1
- package/dist/tokens/motion/motion.js.map +1 -1
- package/dist/tokens/uiSize/icon-size.d.ts +1 -2
- package/dist/tokens/uiSize/icon-size.d.ts.map +1 -1
- package/ds-canonical/commands/README.md +26 -0
- package/ds-canonical/commands/gov-status.md +79 -0
- package/ds-canonical/fork/governance.lock +222 -0
- package/ds-canonical/fork/hooks/block_prototype_imports.py +111 -0
- package/ds-canonical/fork/hooks/check_chrome_header_avatar_canonical.sh +95 -0
- package/ds-canonical/fork/hooks/check_consumer_app_invariants.sh +349 -0
- package/ds-canonical/fork/hooks/check_ds_anchor_preflight.sh +132 -0
- package/ds-canonical/fork/hooks/check_escape_marker_abuse.sh +140 -0
- package/ds-canonical/fork/hooks/check_field_family_invariants.sh +250 -0
- package/ds-canonical/fork/hooks/check_fork_product_quality.sh +36 -0
- package/ds-canonical/fork/hooks/check_item_list_gap.sh +54 -0
- package/ds-canonical/fork/hooks/check_layout_space_magic_numbers.sh +96 -0
- package/ds-canonical/fork/hooks/check_opacity_token_usage.sh +149 -0
- package/ds-canonical/fork/hooks/check_pattern_invariants.sh +196 -0
- package/ds-canonical/fork/hooks/check_sidebar_menu_button_implicit_wrap.sh +86 -0
- package/ds-canonical/fork/hooks/check_tabs_content_chrome_body_double_gap.sh +183 -0
- package/ds-canonical/fork/hooks/check_tailwind_wildcard_in_docs.sh +79 -0
- package/ds-canonical/fork/hooks/inject_deploy_url_after_push.sh +238 -0
- package/ds-canonical/fork/launchers/fork-governance-dispatcher.sh +44 -0
- package/ds-canonical/fork/launchers/inject_fork_governance_preamble.sh +54 -0
- package/ds-canonical/fork/launchers/settings-hooks.json +58 -0
- package/ds-canonical/fork/manifest.json +98 -0
- package/ds-canonical/fork/preamble.md +495 -0
- package/ds-canonical/fork/skills/bug-fix-rhythm/SKILL.md +183 -0
- package/ds-canonical/fork/skills/code-quality-audit/SKILL.md +65 -0
- package/ds-canonical/fork/skills/delivery-handoff/SKILL.md +229 -0
- package/ds-canonical/fork/skills/delivery-handoff/references/flow-diagram.md +180 -0
- package/ds-canonical/fork/skills/delivery-handoff/references/handoff-template.md +177 -0
- package/ds-canonical/fork/skills/delivery-handoff/references/inventory-checklist.md +196 -0
- package/ds-canonical/fork/skills/performance-audit/SKILL.md +107 -0
- package/ds-canonical/fork/skills/product-ui-audit/SKILL.md +232 -0
- package/ds-canonical/fork/skills/product-ui-audit/references/audit-checks.md +246 -0
- package/ds-canonical/fork/skills/product-ui-audit/references/common-misuses.md +329 -0
- package/ds-canonical/fork/skills/product-ui-audit/references/report-template.md +159 -0
- package/ds-canonical/fork/skills/propose-options/SKILL.md +177 -0
- package/ds-canonical/fork/skills/prototype/SKILL.md +244 -0
- package/ds-canonical/fork/skills/prototype/references/audit-checks.md +38 -0
- package/ds-canonical/fork/skills/prototype/references/benchmark-sources.md +94 -0
- package/ds-canonical/fork/skills/prototype/references/checkpoints.md +191 -0
- package/ds-canonical/fork/skills/prototype/references/evaluation-matrix.md +141 -0
- package/ds-canonical/fork/skills/prototype/references/ooux-template.md +198 -0
- package/ds-canonical/fork/skills/prototype/references/proposal-template.md +229 -0
- package/ds-canonical/fork/skills/scan-similar-bugs/SKILL.md +200 -0
- package/ds-canonical/fork/skills/ux-audit/SKILL.md +130 -0
- package/ds-canonical/fork/skills/visual-audit/SKILL.md +247 -0
- package/ds-canonical/fork/skills/visual-audit/output/.gitkeep +0 -0
- package/ds-canonical/fork/skills/visual-audit/references/audit-architecture.md +101 -0
- package/ds-canonical/fork/skills/visual-audit/references/visual-checklist.md +297 -0
- package/ds-canonical/fork/skills/visual-audit/references/world-class-benchmarks.md +198 -0
- package/ds-canonical/hooks/README.md +145 -0
- package/ds-canonical/hooks/_log-fire.sh +46 -0
- package/ds-canonical/hooks/auto_regen_ds_barrel.sh +58 -0
- package/ds-canonical/hooks/block_prototype_imports.py +111 -0
- package/ds-canonical/hooks/check_audit_post_report_validator.sh +156 -0
- package/ds-canonical/hooks/check_audit_sample_escape.sh +76 -0
- package/ds-canonical/hooks/check_benchmark_citation.sh +106 -0
- package/ds-canonical/hooks/check_canonical_propagation.sh +189 -0
- package/ds-canonical/hooks/check_chrome_header_avatar_canonical.sh +95 -0
- package/ds-canonical/hooks/check_codex_brief_invariants.sh +115 -0
- package/ds-canonical/hooks/check_codex_collab_5step.sh +108 -0
- package/ds-canonical/hooks/check_consumer_app_invariants.sh +349 -0
- package/ds-canonical/hooks/check_datatable_invariants.sh +180 -0
- package/ds-canonical/hooks/check_dim_count_drift.sh +72 -0
- package/ds-canonical/hooks/check_ds_anchor_preflight.sh +132 -0
- package/ds-canonical/hooks/check_escape_marker_abuse.sh +140 -0
- package/ds-canonical/hooks/check_field_controls_contracts.sh +137 -0
- package/ds-canonical/hooks/check_field_family_invariants.sh +250 -0
- package/ds-canonical/hooks/check_file_size_budget.sh +60 -0
- package/ds-canonical/hooks/check_full_story_visual_interaction_sweep.sh +71 -0
- package/ds-canonical/hooks/check_item_list_gap.sh +54 -0
- package/ds-canonical/hooks/check_layout_space_magic_numbers.sh +96 -0
- package/ds-canonical/hooks/check_main_branch_workbench.sh +93 -0
- package/ds-canonical/hooks/check_naming_and_abstraction.sh +165 -0
- package/ds-canonical/hooks/check_opacity_token_usage.sh +149 -0
- package/ds-canonical/hooks/check_orphan_ds_css.sh +66 -0
- package/ds-canonical/hooks/check_overlay_open_focus_escape_probe.sh +75 -0
- package/ds-canonical/hooks/check_pattern_invariants.sh +196 -0
- package/ds-canonical/hooks/check_peoplepicker_ssot_drift.sh +56 -0
- package/ds-canonical/hooks/check_pixel_quantified_audit.sh +53 -0
- package/ds-canonical/hooks/check_plugin_fork_health.sh +137 -0
- package/ds-canonical/hooks/check_post_main_ssot_propagate.sh +90 -0
- package/ds-canonical/hooks/check_propose_discipline.sh +147 -0
- package/ds-canonical/hooks/check_propose_pre_grep_verify.sh +70 -0
- package/ds-canonical/hooks/check_propose_without_benchmark.sh +63 -0
- package/ds-canonical/hooks/check_select_all_canonical.sh +58 -0
- package/ds-canonical/hooks/check_sidebar_menu_button_implicit_wrap.sh +86 -0
- package/ds-canonical/hooks/check_solo_workflow.sh +317 -0
- package/ds-canonical/hooks/check_spec_class_drift.sh +88 -0
- package/ds-canonical/hooks/check_story_invariants.sh +748 -0
- package/ds-canonical/hooks/check_storybook_addon_packaging.sh +151 -0
- package/ds-canonical/hooks/check_substantive_edit_approval_preflight.sh +110 -0
- package/ds-canonical/hooks/check_tabs_content_chrome_body_double_gap.sh +183 -0
- package/ds-canonical/hooks/check_tailwind_wildcard_in_docs.sh +79 -0
- package/ds-canonical/hooks/check_wrapper_primitive_schema_drift.sh +104 -0
- package/ds-canonical/hooks/chrome_header_dispatcher.sh +56 -0
- package/ds-canonical/hooks/enforce_home_charter.sh +44 -0
- package/ds-canonical/hooks/inject_deploy_url_after_push.sh +238 -0
- package/ds-canonical/hooks/inject_pending_self_audit.sh +248 -0
- package/ds-canonical/hooks/lib/_app_shell_primary_header_consistency.sh +100 -0
- package/ds-canonical/hooks/lib/_approval_re.sh +33 -0
- package/ds-canonical/hooks/lib/_chrome_header_handcraft.sh +75 -0
- package/ds-canonical/hooks/lib/_code_quality.sh +73 -0
- package/ds-canonical/hooks/lib/_cva_default_sync.sh +69 -0
- package/ds-canonical/hooks/lib/_governance_coverage_check.sh +49 -0
- package/ds-canonical/hooks/lib/_hardcoded_strings.sh +163 -0
- package/ds-canonical/hooks/lib/_header_with_tabs_border.sh +87 -0
- package/ds-canonical/hooks/lib/_layout_space_canonical.sh +56 -0
- package/ds-canonical/hooks/lib/_overlay_handcraft.sh +162 -0
- package/ds-canonical/hooks/lib/_person_data_richness.sh +42 -0
- package/ds-canonical/hooks/lib/_story_compile_drift.sh +48 -0
- package/ds-canonical/hooks/lib/_tab_lg_chrome_header_equal.sh +70 -0
- package/ds-canonical/hooks/lib/_token_hygiene.sh +104 -0
- package/ds-canonical/hooks/log_governance_fires.sh +50 -0
- package/ds-canonical/hooks/log_skill_invokes.sh +41 -0
- package/ds-canonical/hooks/post_edit_dispatcher.sh +62 -0
- package/ds-canonical/hooks/retired/2026-06-11-prune-merge/check_addon_subdir_ship.sh +76 -0
- package/ds-canonical/hooks/retired/2026-06-11-prune-merge/check_consumer_app_story_title.sh +81 -0
- package/ds-canonical/hooks/retired/2026-06-11-prune-merge/check_consumer_ds_primitive_misuse.sh +120 -0
- package/ds-canonical/hooks/retired/2026-06-11-prune-merge/check_consumer_no_ds_catalog.sh +101 -0
- package/ds-canonical/hooks/retired/2026-06-11-prune-merge/check_consumer_story_baseline.sh +76 -0
- package/ds-canonical/hooks/retired/2026-06-11-prune-merge/check_data_table_size_num_to_meta_width.sh +68 -0
- package/ds-canonical/hooks/retired/2026-06-11-prune-merge/check_fork_user_plugin_install.sh +79 -0
- package/ds-canonical/hooks/retired/2026-06-11-prune-merge/check_plugin_freshness.sh +68 -0
- package/ds-canonical/hooks/retired/2026-06-11-prune-merge/check_propose_cite_required.sh +88 -0
- package/ds-canonical/hooks/retired/2026-06-11-prune-merge/check_propose_plain_chinese.sh +74 -0
- package/ds-canonical/hooks/retired/2026-06-11-prune-merge/check_storybook_addon_preset_cjs.sh +87 -0
- package/ds-canonical/hooks/retired/check_anatomy_section_numbering.sh +106 -0
- package/ds-canonical/hooks/retired/check_avatar_hovercard.sh +90 -0
- package/ds-canonical/hooks/retired/check_button_icon_literal.sh.retired-2026-04-28 +38 -0
- package/ds-canonical/hooks/retired/check_container_breathing.sh +142 -0
- package/ds-canonical/hooks/retired/check_governance_compliance.sh +61 -0
- package/ds-canonical/hooks/retired/check_icon_only_padding_formula.sh +104 -0
- package/ds-canonical/hooks/retired/check_item_content_primitive.sh +150 -0
- package/ds-canonical/hooks/retired/check_item_list_gap.sh +153 -0
- package/ds-canonical/hooks/retired/check_sideoffset_canonical.sh +65 -0
- package/ds-canonical/hooks/retired/check_spec_iteration_tag.sh +87 -0
- package/ds-canonical/hooks/retired/check_ssot_consultation.sh +88 -0
- package/ds-canonical/hooks/retired/check_sync_update.sh +20 -0
- package/ds-canonical/hooks/retired/check_third_party_dom_verified.sh +95 -0
- package/ds-canonical/hooks/retired/enforce_home_charter.sh +125 -0
- package/ds-canonical/hooks/retired/post_edit_canonical_interrogate.sh +109 -0
- package/ds-canonical/hooks/retired/pre_edit_spec_check.sh +68 -0
- package/ds-canonical/hooks/retired/pre_new_component_spec.sh +39 -0
- package/ds-canonical/hooks/retired/pre_write_subsumption_check.sh +112 -0
- package/ds-canonical/hooks/retired/stop_meta_self_audit.sh.retired-2026-05-13 +76 -0
- package/ds-canonical/hooks/retired/tests/test_check_anatomy_section_numbering.sh +14 -0
- package/ds-canonical/hooks/retired/tests/test_check_avatar_hovercard.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_container_breathing.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_governance_compliance.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_icon_only_padding_formula.sh +79 -0
- package/ds-canonical/hooks/retired/tests/test_check_item_content_primitive.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_item_list_gap.sh +163 -0
- package/ds-canonical/hooks/retired/tests/test_check_sideoffset_canonical.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_spec_iteration_tag.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_ssot_consultation.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_sync_update.sh +14 -0
- package/ds-canonical/hooks/retired/tests/test_check_third_party_dom_verified.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_enforce_home_charter.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_pre_edit_spec_check.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_pre_new_component_spec.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_pre_write_subsumption_check.sh +63 -0
- package/ds-canonical/hooks/session_start_governance_check.sh +310 -0
- package/ds-canonical/hooks/stop_passive_logging.sh +322 -0
- package/ds-canonical/hooks/stop_self_audit.sh +516 -0
- package/ds-canonical/hooks/tests/KNOWN-BROKEN.md +15 -0
- package/ds-canonical/hooks/tests/run-all.sh +76 -0
- package/ds-canonical/hooks/tests/test_auto_regen_ds_barrel.sh +180 -0
- package/ds-canonical/hooks/tests/test_block_prototype_imports.sh +143 -0
- package/ds-canonical/hooks/tests/test_check_addon_subdir_ship.sh +171 -0
- package/ds-canonical/hooks/tests/test_check_app_shell_primary_header_consistency.sh +196 -0
- package/ds-canonical/hooks/tests/test_check_audit_post_report_validator.sh +127 -0
- package/ds-canonical/hooks/tests/test_check_audit_sample_escape.sh +93 -0
- package/ds-canonical/hooks/tests/test_check_benchmark_citation.sh +115 -0
- package/ds-canonical/hooks/tests/test_check_canonical_propagation.sh +133 -0
- package/ds-canonical/hooks/tests/test_check_chrome_header_avatar_canonical.sh +198 -0
- package/ds-canonical/hooks/tests/test_check_chrome_header_handcraft.sh +146 -0
- package/ds-canonical/hooks/tests/test_check_code_quality.sh +15 -0
- package/ds-canonical/hooks/tests/test_check_codex_brief_invariants.sh +208 -0
- package/ds-canonical/hooks/tests/test_check_codex_collab_5step.sh +96 -0
- package/ds-canonical/hooks/tests/test_check_consumer_app_invariants.sh +12 -0
- package/ds-canonical/hooks/tests/test_check_consumer_app_story_title.sh +164 -0
- package/ds-canonical/hooks/tests/test_check_consumer_ds_primitive_misuse.sh +240 -0
- package/ds-canonical/hooks/tests/test_check_consumer_no_ds_catalog.sh +214 -0
- package/ds-canonical/hooks/tests/test_check_consumer_story_baseline.sh +202 -0
- package/ds-canonical/hooks/tests/test_check_cva_default_sync.sh +15 -0
- package/ds-canonical/hooks/tests/test_check_data_table_size_num_to_meta_width.sh +53 -0
- package/ds-canonical/hooks/tests/test_check_datatable_invariants.sh +122 -0
- package/ds-canonical/hooks/tests/test_check_dim_count_drift.sh +98 -0
- package/ds-canonical/hooks/tests/test_check_ds_anchor_preflight.sh +104 -0
- package/ds-canonical/hooks/tests/test_check_escape_marker_abuse.sh +192 -0
- package/ds-canonical/hooks/tests/test_check_field_controls_contracts.sh +126 -0
- package/ds-canonical/hooks/tests/test_check_field_family_invariants.sh +203 -0
- package/ds-canonical/hooks/tests/test_check_file_size_budget.sh +32 -0
- package/ds-canonical/hooks/tests/test_check_fork_user_plugin_install.sh +46 -0
- package/ds-canonical/hooks/tests/test_check_full_story_visual_interaction_sweep.sh +190 -0
- package/ds-canonical/hooks/tests/test_check_hardcoded_strings.sh +14 -0
- package/ds-canonical/hooks/tests/test_check_header_with_tabs_border.sh +110 -0
- package/ds-canonical/hooks/tests/test_check_item_list_gap.sh +44 -0
- package/ds-canonical/hooks/tests/test_check_layout_space_canonical.sh +73 -0
- package/ds-canonical/hooks/tests/test_check_layout_space_magic_numbers.sh +206 -0
- package/ds-canonical/hooks/tests/test_check_main_branch_workbench.sh +147 -0
- package/ds-canonical/hooks/tests/test_check_naming_and_abstraction.sh +136 -0
- package/ds-canonical/hooks/tests/test_check_opacity_token_usage.sh +110 -0
- package/ds-canonical/hooks/tests/test_check_orphan_ds_css.sh +212 -0
- package/ds-canonical/hooks/tests/test_check_overlay_handcraft.sh +126 -0
- package/ds-canonical/hooks/tests/test_check_overlay_open_focus_escape_probe.sh +191 -0
- package/ds-canonical/hooks/tests/test_check_pattern_invariants.sh +148 -0
- package/ds-canonical/hooks/tests/test_check_peoplepicker_ssot_drift.sh +108 -0
- package/ds-canonical/hooks/tests/test_check_person_data_richness.sh +58 -0
- package/ds-canonical/hooks/tests/test_check_pixel_quantified_audit.sh +142 -0
- package/ds-canonical/hooks/tests/test_check_plugin_fork_health.sh +9 -0
- package/ds-canonical/hooks/tests/test_check_propose_cite_required.sh +181 -0
- package/ds-canonical/hooks/tests/test_check_propose_discipline.sh +10 -0
- package/ds-canonical/hooks/tests/test_check_propose_plain_chinese.sh +127 -0
- package/ds-canonical/hooks/tests/test_check_propose_pre_grep_verify.sh +117 -0
- package/ds-canonical/hooks/tests/test_check_propose_without_benchmark.sh +55 -0
- package/ds-canonical/hooks/tests/test_check_select_all_canonical.sh +125 -0
- package/ds-canonical/hooks/tests/test_check_sidebar_menu_button_implicit_wrap.sh +224 -0
- package/ds-canonical/hooks/tests/test_check_solo_workflow.sh +201 -0
- package/ds-canonical/hooks/tests/test_check_spec_class_drift.sh +135 -0
- package/ds-canonical/hooks/tests/test_check_story_anatomy.sh.broken +197 -0
- package/ds-canonical/hooks/tests/test_check_story_category.sh.broken +187 -0
- package/ds-canonical/hooks/tests/test_check_story_compile_drift.sh +15 -0
- package/ds-canonical/hooks/tests/test_check_story_invariants.sh +384 -0
- package/ds-canonical/hooks/tests/test_check_story_name_jargon.sh.broken +53 -0
- package/ds-canonical/hooks/tests/test_check_story_slot_split.sh +156 -0
- package/ds-canonical/hooks/tests/test_check_storybook_addon_packaging.sh +10 -0
- package/ds-canonical/hooks/tests/test_check_storybook_addon_preset_cjs.sh +200 -0
- package/ds-canonical/hooks/tests/test_check_substantive_edit_approval_preflight.sh +176 -0
- package/ds-canonical/hooks/tests/test_check_tab_lg_chrome_header_equal.sh +141 -0
- package/ds-canonical/hooks/tests/test_check_tailwind_wildcard_in_docs.sh +182 -0
- package/ds-canonical/hooks/tests/test_check_token_hygiene.sh +21 -0
- package/ds-canonical/hooks/tests/test_check_wrapper_primitive_schema_drift.sh +169 -0
- package/ds-canonical/hooks/tests/test_enforce_home_charter.sh +77 -0
- package/ds-canonical/hooks/tests/test_inject_deploy_url_after_push.sh +193 -0
- package/ds-canonical/hooks/tests/test_inject_pending_self_audit.sh +125 -0
- package/ds-canonical/hooks/tests/test_log_governance_fires.sh +10 -0
- package/ds-canonical/hooks/tests/test_log_skill_invokes.sh +7 -0
- package/ds-canonical/hooks/tests/test_post_edit_dispatcher.sh +108 -0
- package/ds-canonical/hooks/tests/test_session_start_governance_check.sh +154 -0
- package/ds-canonical/hooks/tests/test_stop_capture_metrics.sh +95 -0
- package/ds-canonical/hooks/tests/test_stop_governance_drift_check.sh.broken +125 -0
- package/ds-canonical/hooks/tests/test_stop_harvest_corrections.sh +10 -0
- package/ds-canonical/hooks/tests/test_stop_passive_logging.sh +100 -0
- package/ds-canonical/hooks/tests/test_stop_self_audit.sh +98 -0
- package/ds-canonical/hooks/tests/test_stop_tsc_sanity.sh +10 -0
- package/ds-canonical/references/README.md +46 -0
- package/ds-canonical/references/audit-coverage-vs-24-checklist.md +74 -0
- package/ds-canonical/references/build-ui-canonicals.md +72 -0
- package/ds-canonical/references/composition-fidelity.md +47 -0
- package/ds-canonical/references/cva-patterns.md +41 -0
- package/ds-canonical/references/drag-canonical.md +331 -0
- package/ds-canonical/references/item-anatomy-recipe.md +225 -0
- package/ds-canonical/references/naming-conventions.md +57 -0
- package/ds-canonical/references/principle-dim-map.json +513 -0
- package/ds-canonical/references/props-naming.md +59 -0
- package/ds-canonical/references/scenario-definition.md +146 -0
- package/ds-canonical/references/spec-rules.md +58 -0
- package/ds-canonical/references/ssot-consultation.md +63 -0
- package/ds-canonical/references/ssot-index.md +40 -0
- package/ds-canonical/references/story-baseline-registry.json +107 -0
- package/ds-canonical/references/structural-token-retention.md +42 -0
- package/ds-canonical/references/tailwind-gotchas.md +87 -0
- package/ds-canonical/references/ui-dev-rules.md +81 -0
- package/ds-canonical/rules/README.md +34 -0
- package/ds-canonical/rules/meta-patterns.md +87 -0
- package/ds-canonical/rules/self-verify.md +56 -0
- package/ds-canonical/rules/spec-rules.md +25 -0
- package/ds-canonical/rules/story-rules.md +67 -0
- package/ds-canonical/rules/ui-development.md +92 -0
- package/ds-canonical/skills/README.md +88 -0
- package/ds-canonical/skills/bug-fix-rhythm/SKILL.md +181 -0
- package/ds-canonical/skills/code-quality-audit/SKILL.md +63 -0
- package/ds-canonical/skills/codex-collab/SKILL.md +249 -0
- package/ds-canonical/skills/codex-collab/references/brief-template.md +48 -0
- package/ds-canonical/skills/codex-collab/references/transport.md +58 -0
- package/ds-canonical/skills/codify-corrections/SKILL.md +184 -0
- package/ds-canonical/skills/codify-principle/SKILL.md +151 -0
- package/ds-canonical/skills/component-quality-gate/SKILL.md +102 -0
- package/ds-canonical/skills/component-quality-gate/references/checklist.md +79 -0
- package/ds-canonical/skills/deep-audit-cross-codex/SKILL.md +254 -0
- package/ds-canonical/skills/deep-audit-cross-codex/references/phase-a-workflow.md +123 -0
- package/ds-canonical/skills/deep-audit-cross-codex/references/phase-b-codex-brief.md +186 -0
- package/ds-canonical/skills/deep-audit-cross-codex/references/skill-relationships-antipatterns-benchmarks.md +30 -0
- package/ds-canonical/skills/deep-audit-cross-codex/references/triage-rubric.md +69 -0
- package/ds-canonical/skills/deep-audit-cross-codex/references/upstream-directives-r-mapping.md +33 -0
- package/ds-canonical/skills/delivery-handoff/SKILL.md +229 -0
- package/ds-canonical/skills/delivery-handoff/references/flow-diagram.md +180 -0
- package/ds-canonical/skills/delivery-handoff/references/handoff-template.md +177 -0
- package/ds-canonical/skills/delivery-handoff/references/inventory-checklist.md +196 -0
- package/ds-canonical/skills/design-system-audit/SKILL.md +386 -0
- package/ds-canonical/skills/design-system-audit/references/audit-prompts.md +1325 -0
- package/ds-canonical/skills/design-system-audit/references/checkpoints.md +240 -0
- package/ds-canonical/skills/design-system-audit/references/historical-bugs.md +240 -0
- package/ds-canonical/skills/design-system-audit/references/principle-audit-protocol.md +378 -0
- package/ds-canonical/skills/design-system-audit/references/rule-placement.md +175 -0
- package/ds-canonical/skills/ensure-canonical/SKILL.md +196 -0
- package/ds-canonical/skills/governance-health/SKILL.md +147 -0
- package/ds-canonical/skills/knowledge-prune/SKILL.md +250 -0
- package/ds-canonical/skills/knowledge-prune/references/phase-z-cross-repo-ssot-propagation.md +11 -0
- package/ds-canonical/skills/knowledge-prune/references/prune-dimensions-d5-d10.md +55 -0
- package/ds-canonical/skills/knowledge-prune/references/world-class-prune-alignment.md +7 -0
- package/ds-canonical/skills/new-component/SKILL.md +170 -0
- package/ds-canonical/skills/new-component/references/new-component-checklist.md +85 -0
- package/ds-canonical/skills/performance-audit/SKILL.md +107 -0
- package/ds-canonical/skills/product-ui-audit/SKILL.md +230 -0
- package/ds-canonical/skills/product-ui-audit/references/audit-checks.md +246 -0
- package/ds-canonical/skills/product-ui-audit/references/common-misuses.md +329 -0
- package/ds-canonical/skills/product-ui-audit/references/report-template.md +159 -0
- package/ds-canonical/skills/propose-options/SKILL.md +177 -0
- package/ds-canonical/skills/prototype/SKILL.md +244 -0
- package/ds-canonical/skills/prototype/references/audit-checks.md +37 -0
- package/ds-canonical/skills/prototype/references/benchmark-sources.md +94 -0
- package/ds-canonical/skills/prototype/references/checkpoints.md +191 -0
- package/ds-canonical/skills/prototype/references/evaluation-matrix.md +141 -0
- package/ds-canonical/skills/prototype/references/ooux-template.md +198 -0
- package/ds-canonical/skills/prototype/references/proposal-template.md +229 -0
- package/ds-canonical/skills/scan-similar-bugs/SKILL.md +198 -0
- package/ds-canonical/skills/story-auto-compile-migrate/SKILL.md +159 -0
- package/ds-canonical/skills/story-writing/SKILL.md +122 -0
- package/ds-canonical/skills/story-writing/references/anatomy-standard.md +217 -0
- package/ds-canonical/skills/story-writing/references/category-templates.md +174 -0
- package/ds-canonical/skills/story-writing/references/example-selection.md +70 -0
- package/ds-canonical/skills/story-writing/references/self-check.md +20 -0
- package/ds-canonical/skills/ux-audit/SKILL.md +130 -0
- package/ds-canonical/skills/visual-audit/SKILL.md +245 -0
- package/ds-canonical/skills/visual-audit/output/.gitkeep +0 -0
- package/ds-canonical/skills/visual-audit/references/audit-architecture.md +100 -0
- package/ds-canonical/skills/visual-audit/references/visual-checklist.md +297 -0
- package/ds-canonical/skills/visual-audit/references/world-class-benchmarks.md +198 -0
- package/ds-canonical/templates/_README.md +23 -0
- package/ds-canonical/templates/dashboard-app.tsx +161 -0
- package/ds-story-manifest.json +1684 -0
- package/llms-full.txt +414 -0
- package/llms.txt +70 -0
- package/package.json +31 -8
- package/src/components/Accordion/accordion.anatomy.stories.tsx +496 -0
- package/src/components/Accordion/accordion.principles.stories.tsx +360 -0
- package/src/components/Accordion/accordion.spec.md +131 -0
- package/src/components/Accordion/accordion.stories.tsx +190 -0
- package/src/components/Accordion/accordion.tsx +4 -1
- package/src/components/Accordion/index.ts +5 -0
- package/src/components/Alert/alert.anatomy.stories.tsx +238 -0
- package/src/components/Alert/alert.principles.stories.tsx +220 -0
- package/src/components/Alert/alert.spec.md +202 -0
- package/src/components/Alert/alert.stories.tsx +139 -0
- package/src/components/Alert/alert.tsx +9 -6
- package/src/components/Alert/index.ts +5 -0
- package/src/components/AppShell/_demo-helpers.tsx +87 -11
- package/src/components/AppShell/app-shell.anatomy.stories.tsx +176 -0
- package/src/components/AppShell/app-shell.principles.stories.tsx +140 -0
- package/src/components/AppShell/app-shell.spec.md +357 -0
- package/src/components/AppShell/app-shell.stories.tsx +442 -0
- package/src/components/AppShell/app-shell.tsx +15 -9
- package/src/components/AppShell/index.ts +5 -0
- package/src/components/AspectRatio/aspect-ratio.anatomy.stories.tsx +208 -0
- package/src/components/AspectRatio/aspect-ratio.principles.stories.tsx +303 -0
- package/src/components/AspectRatio/aspect-ratio.spec.md +148 -0
- package/src/components/AspectRatio/aspect-ratio.stories.tsx +170 -0
- package/src/components/AspectRatio/aspect-ratio.tsx +4 -2
- package/src/components/AspectRatio/index.ts +5 -0
- package/src/components/Avatar/avatar.anatomy.stories.tsx +701 -0
- package/src/components/Avatar/avatar.principles.stories.tsx +245 -0
- package/src/components/Avatar/avatar.spec.md +312 -0
- package/src/components/Avatar/avatar.stories.tsx +135 -0
- package/src/components/Avatar/avatar.tsx +45 -46
- package/src/components/Avatar/index.ts +5 -0
- package/src/components/Badge/badge.anatomy.stories.tsx +591 -0
- package/src/components/Badge/badge.principles.stories.tsx +391 -0
- package/src/components/Badge/badge.spec.md +398 -0
- package/src/components/Badge/badge.stories.tsx +80 -0
- package/src/components/Badge/badge.tsx +34 -13
- package/src/components/Badge/index.ts +5 -0
- package/src/components/Breadcrumb/breadcrumb.anatomy.stories.tsx +458 -0
- package/src/components/Breadcrumb/breadcrumb.principles.stories.tsx +343 -0
- package/src/components/Breadcrumb/breadcrumb.spec.md +268 -0
- package/src/components/Breadcrumb/breadcrumb.stories.tsx +307 -0
- package/src/components/Breadcrumb/breadcrumb.tsx +2 -2
- package/src/components/Breadcrumb/index.ts +5 -0
- package/src/components/BulkActionBar/bulk-action-bar.anatomy.stories.tsx +224 -0
- package/src/components/BulkActionBar/bulk-action-bar.principles.stories.tsx +242 -0
- package/src/components/BulkActionBar/bulk-action-bar.spec.md +226 -0
- package/src/components/BulkActionBar/bulk-action-bar.stories.tsx +136 -0
- package/src/components/BulkActionBar/bulk-action-bar.tsx +13 -11
- package/src/components/BulkActionBar/index.ts +5 -0
- package/src/components/Button/button.anatomy.stories.tsx +710 -0
- package/src/components/Button/button.principles.stories.tsx +370 -0
- package/src/components/Button/button.spec.md +463 -0
- package/src/components/Button/button.stories.tsx +362 -0
- package/src/components/Button/button.tsx +25 -28
- package/src/components/Button/index.ts +5 -0
- package/src/components/Calendar/calendar.anatomy.stories.tsx +218 -0
- package/src/components/Calendar/calendar.principles.stories.tsx +143 -0
- package/src/components/Calendar/calendar.spec.md +264 -0
- package/src/components/Calendar/calendar.stories.tsx +88 -0
- package/src/components/Calendar/calendar.tsx +54 -40
- package/src/components/Calendar/index.ts +5 -0
- package/src/components/Carousel/carousel.anatomy.stories.tsx +516 -0
- package/src/components/Carousel/carousel.principles.stories.tsx +330 -0
- package/src/components/Carousel/carousel.spec.md +273 -0
- package/src/components/Carousel/carousel.stories.tsx +121 -0
- package/src/components/Carousel/carousel.tsx +26 -7
- package/src/components/Carousel/index.ts +5 -0
- package/src/components/Chart/chart.anatomy.stories.tsx +307 -0
- package/src/components/Chart/chart.principles.stories.tsx +436 -0
- package/src/components/Chart/chart.spec.md +174 -0
- package/src/components/Chart/chart.stories.tsx +268 -0
- package/src/components/Chart/chart.tsx +5 -2
- package/src/components/Chart/index.ts +5 -0
- package/src/components/Checkbox/checkbox-group.tsx +2 -1
- package/src/components/Checkbox/checkbox.anatomy.stories.tsx +626 -0
- package/src/components/Checkbox/checkbox.principles.stories.tsx +216 -0
- package/src/components/Checkbox/checkbox.spec.md +372 -0
- package/src/components/Checkbox/checkbox.stories.tsx +114 -0
- package/src/components/Checkbox/checkbox.tsx +80 -22
- package/src/components/Checkbox/index.ts +5 -0
- package/src/components/Chip/chip.anatomy.stories.tsx +422 -0
- package/src/components/Chip/chip.principles.stories.tsx +228 -0
- package/src/components/Chip/chip.spec.md +237 -0
- package/src/components/Chip/chip.stories.tsx +88 -0
- package/src/components/Chip/chip.tsx +6 -6
- package/src/components/Chip/index.ts +5 -0
- package/src/components/CircularProgress/circular-progress.anatomy.stories.tsx +176 -0
- package/src/components/CircularProgress/circular-progress.principles.stories.tsx +258 -0
- package/src/components/CircularProgress/circular-progress.spec.md +267 -0
- package/src/components/CircularProgress/circular-progress.stories.tsx +153 -0
- package/src/components/CircularProgress/circular-progress.tsx +4 -5
- package/src/components/CircularProgress/index.ts +5 -0
- package/src/components/Coachmark/coachmark-story-helpers.tsx +39 -0
- package/src/components/Coachmark/coachmark.anatomy.stories.tsx +356 -0
- package/src/components/Coachmark/coachmark.principles.stories.tsx +355 -0
- package/src/components/Coachmark/coachmark.spec.md +238 -0
- package/src/components/Coachmark/coachmark.stories.tsx +214 -0
- package/src/components/Coachmark/coachmark.tsx +16 -7
- package/src/components/Coachmark/index.ts +5 -0
- package/src/components/Combobox/combobox.anatomy.stories.tsx +919 -0
- package/src/components/Combobox/combobox.principles.stories.tsx +239 -0
- package/src/components/Combobox/combobox.spec.md +202 -0
- package/src/components/Combobox/combobox.stories.tsx +184 -0
- package/src/components/Combobox/combobox.tsx +86 -39
- package/src/components/Combobox/index.ts +5 -0
- package/src/components/Command/command.anatomy.stories.tsx +107 -0
- package/src/components/Command/command.principles.stories.tsx +88 -0
- package/src/components/Command/command.spec.md +181 -0
- package/src/components/Command/command.stories.tsx +280 -0
- package/src/components/Command/command.tsx +13 -8
- package/src/components/Command/index.ts +5 -0
- package/src/components/DataTable/cell-registry.tsx +19 -6
- package/src/components/DataTable/data-table-filter-panel.tsx +8 -8
- package/src/components/DataTable/data-table-sort-manager.tsx +4 -4
- package/src/components/DataTable/data-table.anatomy.stories.tsx +519 -0
- package/src/components/DataTable/data-table.css +1 -1
- package/src/components/DataTable/data-table.principles.stories.tsx +265 -0
- package/src/components/DataTable/data-table.spec.md +540 -0
- package/src/components/DataTable/data-table.stories.tsx +1941 -0
- package/src/components/DataTable/data-table.tsx +121 -53
- package/src/components/DataTable/filter-operators.spec.md +267 -0
- package/src/components/DataTable/filter-operators.ts +1 -1
- package/src/components/DataTable/filter-tree.ts +2 -2
- package/src/components/DataTable/index.ts +5 -0
- package/src/components/DateGrid/date-grid.anatomy.stories.tsx +583 -0
- package/src/components/DateGrid/date-grid.principles.stories.tsx +338 -0
- package/src/components/DateGrid/date-grid.spec.md +218 -0
- package/src/components/DateGrid/date-grid.stories.tsx +195 -0
- package/src/components/DateGrid/date-grid.tsx +22 -18
- package/src/components/DateGrid/index.ts +5 -0
- package/src/components/DatePicker/date-picker.anatomy.stories.tsx +952 -0
- package/src/components/DatePicker/date-picker.principles.stories.tsx +205 -0
- package/src/components/DatePicker/date-picker.spec.md +337 -0
- package/src/components/DatePicker/date-picker.stories.tsx +323 -0
- package/src/components/DatePicker/date-picker.tsx +46 -22
- package/src/components/DatePicker/index.ts +5 -0
- package/src/components/DescriptionList/description-list.anatomy.stories.tsx +252 -0
- package/src/components/DescriptionList/description-list.principles.stories.tsx +309 -0
- package/src/components/DescriptionList/description-list.spec.md +220 -0
- package/src/components/DescriptionList/description-list.stories.tsx +112 -0
- package/src/components/DescriptionList/description-list.tsx +3 -3
- package/src/components/DescriptionList/index.ts +5 -0
- package/src/components/Dialog/dialog.anatomy.stories.tsx +484 -0
- package/src/components/Dialog/dialog.principles.stories.tsx +313 -0
- package/src/components/Dialog/dialog.spec.md +216 -0
- package/src/components/Dialog/dialog.stories.tsx +483 -0
- package/src/components/Dialog/dialog.tsx +9 -9
- package/src/components/Dialog/index.ts +5 -0
- package/src/components/DropdownMenu/dropdown-menu.anatomy.stories.tsx +969 -0
- package/src/components/DropdownMenu/dropdown-menu.principles.stories.tsx +339 -0
- package/src/components/DropdownMenu/dropdown-menu.spec.md +260 -0
- package/src/components/DropdownMenu/dropdown-menu.stories.tsx +286 -0
- package/src/components/DropdownMenu/dropdown-menu.tsx +29 -7
- package/src/components/DropdownMenu/index.ts +5 -0
- package/src/components/Empty/empty.anatomy.stories.tsx +275 -0
- package/src/components/Empty/empty.principles.stories.tsx +314 -0
- package/src/components/Empty/empty.spec.md +216 -0
- package/src/components/Empty/empty.stories.tsx +80 -0
- package/src/components/Empty/empty.tsx +16 -7
- package/src/components/Empty/index.ts +5 -0
- package/src/components/Field/field-context.ts +98 -0
- package/src/components/Field/field-controls.spec.md +382 -0
- package/src/components/Field/field-types.ts +1 -1
- package/src/components/Field/field-wrapper.tsx +6 -6
- package/src/components/Field/field.anatomy.stories.tsx +544 -0
- package/src/components/Field/field.principles.stories.tsx +278 -0
- package/src/components/Field/field.spec.md +460 -0
- package/src/components/Field/field.stories.tsx +716 -0
- package/src/components/Field/field.tsx +12 -5
- package/src/components/Field/form-validation.spec.md +172 -0
- package/src/components/Field/index.ts +5 -0
- package/src/components/Field/use-form-validation.ts +242 -0
- package/src/components/FieldControlGroup/field-control-group.anatomy.stories.tsx +118 -0
- package/src/components/FieldControlGroup/field-control-group.principles.stories.tsx +121 -0
- package/src/components/FieldControlGroup/field-control-group.spec.md +195 -0
- package/src/components/FieldControlGroup/field-control-group.stories.tsx +161 -0
- package/src/components/FieldControlGroup/field-control-group.tsx +9 -8
- package/src/components/FieldControlGroup/index.ts +5 -0
- package/src/components/FileItem/file-item.anatomy.stories.tsx +344 -0
- package/src/components/FileItem/file-item.principles.stories.tsx +276 -0
- package/src/components/FileItem/file-item.spec.md +491 -0
- package/src/components/FileItem/file-item.stories.tsx +265 -0
- package/src/components/FileItem/file-item.tsx +37 -13
- package/src/components/FileItem/index.ts +5 -0
- package/src/components/FileUpload/file-upload.anatomy.stories.tsx +446 -0
- package/src/components/FileUpload/file-upload.principles.stories.tsx +312 -0
- package/src/components/FileUpload/file-upload.spec.md +163 -0
- package/src/components/FileUpload/file-upload.stories.tsx +167 -0
- package/src/components/FileUpload/file-upload.tsx +78 -27
- package/src/components/FileUpload/index.ts +5 -0
- package/src/components/FileViewer/file-viewer.anatomy.stories.tsx +1127 -0
- package/src/components/FileViewer/file-viewer.principles.stories.tsx +636 -0
- package/src/components/FileViewer/file-viewer.spec.md +368 -0
- package/src/components/FileViewer/file-viewer.stories.tsx +407 -0
- package/src/components/FileViewer/file-viewer.tsx +58 -28
- package/src/components/FileViewer/index.ts +5 -0
- package/src/components/HoverCard/hover-card.anatomy.stories.tsx +145 -0
- package/src/components/HoverCard/hover-card.principles.stories.tsx +222 -0
- package/src/components/HoverCard/hover-card.spec.md +167 -0
- package/src/components/HoverCard/hover-card.stories.tsx +304 -0
- package/src/components/HoverCard/hover-card.tsx +15 -4
- package/src/components/HoverCard/index.ts +5 -0
- package/src/components/Input/index.ts +5 -0
- package/src/components/Input/input.anatomy.stories.tsx +763 -0
- package/src/components/Input/input.principles.stories.tsx +265 -0
- package/src/components/Input/input.spec.md +207 -0
- package/src/components/Input/input.stories.tsx +133 -0
- package/src/components/Input/input.tsx +17 -14
- package/src/components/LinkInput/index.ts +5 -0
- package/src/components/LinkInput/link-input.anatomy.stories.tsx +746 -0
- package/src/components/LinkInput/link-input.principles.stories.tsx +182 -0
- package/src/components/LinkInput/link-input.spec.md +144 -0
- package/src/components/LinkInput/link-input.stories.tsx +132 -0
- package/src/components/LinkInput/link-input.tsx +9 -8
- package/src/components/Menu/index.ts +5 -0
- package/src/components/Menu/menu-item.anatomy.stories.tsx +780 -0
- package/src/components/Menu/menu-item.principles.stories.tsx +81 -0
- package/src/components/Menu/menu-item.spec.md +304 -0
- package/src/components/Menu/menu-item.stories.tsx +214 -0
- package/src/components/Menu/menu-item.tsx +8 -3
- package/src/components/Notice/index.ts +5 -0
- package/src/components/Notice/notice.anatomy.stories.tsx +610 -0
- package/src/components/Notice/notice.principles.stories.tsx +102 -0
- package/src/components/Notice/notice.spec.md +158 -0
- package/src/components/Notice/notice.stories.tsx +257 -0
- package/src/components/Notice/notice.tsx +26 -10
- package/src/components/NumberInput/index.ts +5 -0
- package/src/components/NumberInput/number-input.anatomy.stories.tsx +787 -0
- package/src/components/NumberInput/number-input.principles.stories.tsx +199 -0
- package/src/components/NumberInput/number-input.spec.md +144 -0
- package/src/components/NumberInput/number-input.stories.tsx +142 -0
- package/src/components/NumberInput/number-input.tsx +9 -10
- package/src/components/OverflowIndicator/index.ts +5 -0
- package/src/components/OverflowIndicator/overflow-indicator.anatomy.stories.tsx +549 -0
- package/src/components/OverflowIndicator/overflow-indicator.principles.stories.tsx +77 -0
- package/src/components/OverflowIndicator/overflow-indicator.spec.md +127 -0
- package/src/components/OverflowIndicator/overflow-indicator.stories.tsx +238 -0
- package/src/components/OverflowIndicator/overflow-indicator.tsx +19 -6
- package/src/components/PeoplePicker/index.ts +5 -0
- package/src/components/PeoplePicker/people-picker-helpers.ts +5 -5
- package/src/components/PeoplePicker/people-picker.anatomy.stories.tsx +427 -0
- package/src/components/PeoplePicker/people-picker.principles.stories.tsx +192 -0
- package/src/components/PeoplePicker/people-picker.spec.md +292 -0
- package/src/components/PeoplePicker/people-picker.stories.tsx +162 -0
- package/src/components/PeoplePicker/people-picker.tsx +31 -22
- package/src/components/PeoplePicker/person-display.tsx +30 -29
- package/src/components/Popover/index.ts +5 -0
- package/src/components/Popover/popover.anatomy.stories.tsx +279 -0
- package/src/components/Popover/popover.principles.stories.tsx +295 -0
- package/src/components/Popover/popover.spec.md +209 -0
- package/src/components/Popover/popover.stories.tsx +116 -0
- package/src/components/Popover/popover.tsx +17 -14
- package/src/components/ProfileCard/index.ts +5 -0
- package/src/components/ProfileCard/profile-card.anatomy.stories.tsx +504 -0
- package/src/components/ProfileCard/profile-card.principles.stories.tsx +225 -0
- package/src/components/ProfileCard/profile-card.spec.md +191 -0
- package/src/components/ProfileCard/profile-card.stories.tsx +53 -0
- package/src/components/{NameCard/name-card.tsx → ProfileCard/profile-card.tsx} +36 -30
- package/src/components/ProgressBar/index.ts +5 -0
- package/src/components/ProgressBar/progress-bar.anatomy.stories.tsx +438 -0
- package/src/components/ProgressBar/progress-bar.principles.stories.tsx +339 -0
- package/src/components/ProgressBar/progress-bar.spec.md +240 -0
- package/src/components/ProgressBar/progress-bar.stories.tsx +119 -0
- package/src/components/ProgressBar/progress-bar.tsx +4 -4
- package/src/components/RadioGroup/index.ts +5 -0
- package/src/components/RadioGroup/radio-group.anatomy.stories.tsx +681 -0
- package/src/components/RadioGroup/radio-group.principles.stories.tsx +163 -0
- package/src/components/RadioGroup/radio-group.spec.md +149 -0
- package/src/components/RadioGroup/radio-group.stories.tsx +101 -0
- package/src/components/RadioGroup/radio-group.tsx +114 -57
- package/src/components/Rating/index.ts +5 -0
- package/src/components/Rating/rating.anatomy.stories.tsx +495 -0
- package/src/components/Rating/rating.principles.stories.tsx +296 -0
- package/src/components/Rating/rating.spec.md +214 -0
- package/src/components/Rating/rating.stories.tsx +133 -0
- package/src/components/Rating/rating.tsx +29 -14
- package/src/components/ScrollArea/index.ts +5 -0
- package/src/components/ScrollArea/scroll-area.anatomy.stories.tsx +451 -0
- package/src/components/ScrollArea/scroll-area.principles.stories.tsx +331 -0
- package/src/components/ScrollArea/scroll-area.spec.md +143 -0
- package/src/components/ScrollArea/scroll-area.stories.tsx +243 -0
- package/src/components/ScrollArea/scroll-area.tsx +2 -2
- package/src/components/SegmentedControl/index.ts +5 -0
- package/src/components/SegmentedControl/segmented-control.anatomy.stories.tsx +295 -0
- package/src/components/SegmentedControl/segmented-control.principles.stories.tsx +281 -0
- package/src/components/SegmentedControl/segmented-control.spec.md +297 -0
- package/src/components/SegmentedControl/segmented-control.stories.tsx +33 -0
- package/src/components/SegmentedControl/segmented-control.tsx +9 -10
- package/src/components/Select/index.ts +5 -0
- package/src/components/Select/select.anatomy.stories.tsx +828 -0
- package/src/components/Select/select.principles.stories.tsx +311 -0
- package/src/components/Select/select.spec.md +337 -0
- package/src/components/Select/select.stories.tsx +198 -0
- package/src/components/Select/select.tsx +37 -16
- package/src/components/SelectMenu/index.ts +5 -0
- package/src/components/SelectMenu/select-menu.anatomy.stories.tsx +812 -0
- package/src/components/SelectMenu/select-menu.principles.stories.tsx +107 -0
- package/src/components/SelectMenu/select-menu.spec.md +229 -0
- package/src/components/SelectMenu/select-menu.stories.tsx +155 -0
- package/src/components/SelectMenu/select-menu.tsx +34 -9
- package/src/components/SelectionControl/index.ts +5 -0
- package/src/components/SelectionControl/selection-item.anatomy.stories.tsx +571 -0
- package/src/components/SelectionControl/selection-item.principles.stories.tsx +77 -0
- package/src/components/SelectionControl/selection-item.spec.md +141 -0
- package/src/components/SelectionControl/selection-item.stories.tsx +137 -0
- package/src/components/SelectionControl/selection-item.tsx +8 -2
- package/src/components/Separator/index.ts +5 -0
- package/src/components/Separator/separator.anatomy.stories.tsx +125 -0
- package/src/components/Separator/separator.principles.stories.tsx +141 -0
- package/src/components/Separator/separator.spec.md +115 -0
- package/src/components/Separator/separator.stories.tsx +127 -0
- package/src/components/Separator/separator.tsx +2 -2
- package/src/components/Sheet/index.ts +5 -0
- package/src/components/Sheet/sheet.anatomy.stories.tsx +269 -0
- package/src/components/Sheet/sheet.principles.stories.tsx +351 -0
- package/src/components/Sheet/sheet.spec.md +146 -0
- package/src/components/Sheet/sheet.stories.tsx +168 -0
- package/src/components/Sheet/sheet.tsx +7 -6
- package/src/components/Sidebar/index.ts +5 -0
- package/src/components/Sidebar/sidebar.anatomy.stories.tsx +772 -0
- package/src/components/Sidebar/sidebar.principles.stories.tsx +505 -0
- package/src/components/Sidebar/sidebar.spec.md +724 -0
- package/src/components/Sidebar/sidebar.stories.tsx +498 -0
- package/src/components/Sidebar/sidebar.tsx +20 -9
- package/src/components/Skeleton/index.ts +5 -0
- package/src/components/Skeleton/skeleton.anatomy.stories.tsx +145 -0
- package/src/components/Skeleton/skeleton.principles.stories.tsx +234 -0
- package/src/components/Skeleton/skeleton.spec.md +106 -0
- package/src/components/Skeleton/skeleton.stories.tsx +137 -0
- package/src/components/Skeleton/skeleton.tsx +1 -1
- package/src/components/Slider/index.ts +5 -0
- package/src/components/Slider/slider.anatomy.stories.tsx +236 -0
- package/src/components/Slider/slider.principles.stories.tsx +250 -0
- package/src/components/Slider/slider.spec.md +358 -0
- package/src/components/Slider/slider.stories.tsx +99 -0
- package/src/components/Slider/slider.tsx +54 -16
- package/src/components/Steps/index.ts +5 -0
- package/src/components/Steps/steps.anatomy.stories.tsx +448 -0
- package/src/components/Steps/steps.principles.stories.tsx +300 -0
- package/src/components/Steps/steps.spec.md +479 -0
- package/src/components/Steps/steps.stories.tsx +335 -0
- package/src/components/Steps/steps.tsx +56 -26
- package/src/components/Switch/index.ts +5 -0
- package/src/components/Switch/switch.anatomy.stories.tsx +227 -0
- package/src/components/Switch/switch.principles.stories.tsx +174 -0
- package/src/components/Switch/switch.spec.md +238 -0
- package/src/components/Switch/switch.stories.tsx +107 -0
- package/src/components/Switch/switch.tsx +69 -32
- package/src/components/Tabs/index.ts +5 -0
- package/src/components/Tabs/tabs.anatomy.stories.tsx +414 -0
- package/src/components/Tabs/tabs.principles.stories.tsx +257 -0
- package/src/components/Tabs/tabs.spec.md +331 -0
- package/src/components/Tabs/tabs.stories.tsx +155 -0
- package/src/components/Tabs/tabs.tsx +17 -10
- package/src/components/Tag/index.ts +5 -0
- package/src/components/Tag/tag.anatomy.stories.tsx +664 -0
- package/src/components/Tag/tag.principles.stories.tsx +270 -0
- package/src/components/Tag/tag.spec.md +324 -0
- package/src/components/Tag/tag.stories.tsx +69 -0
- package/src/components/Tag/tag.tsx +55 -57
- package/src/components/Textarea/index.ts +5 -0
- package/src/components/Textarea/textarea.anatomy.stories.tsx +304 -0
- package/src/components/Textarea/textarea.principles.stories.tsx +175 -0
- package/src/components/Textarea/textarea.spec.md +162 -0
- package/src/components/Textarea/textarea.stories.tsx +53 -0
- package/src/components/Textarea/textarea.tsx +20 -18
- package/src/components/TimePicker/index.ts +5 -0
- package/src/components/TimePicker/time-columns.tsx +8 -1
- package/src/components/TimePicker/time-picker.anatomy.stories.tsx +281 -0
- package/src/components/TimePicker/time-picker.principles.stories.tsx +140 -0
- package/src/components/TimePicker/time-picker.spec.md +290 -0
- package/src/components/TimePicker/time-picker.stories.tsx +193 -0
- package/src/components/TimePicker/time-picker.tsx +41 -23
- package/src/components/Toast/index.ts +5 -0
- package/src/components/Toast/toast.anatomy.stories.tsx +324 -0
- package/src/components/Toast/toast.principles.stories.tsx +217 -0
- package/src/components/Toast/toast.spec.md +181 -0
- package/src/components/Toast/toast.stories.tsx +125 -0
- package/src/components/Toast/toast.tsx +2 -2
- package/src/components/Tooltip/index.ts +5 -0
- package/src/components/Tooltip/tooltip.anatomy.stories.tsx +413 -0
- package/src/components/Tooltip/tooltip.principles.stories.tsx +204 -0
- package/src/components/Tooltip/tooltip.spec.md +142 -0
- package/src/components/Tooltip/tooltip.stories.tsx +116 -0
- package/src/components/Tooltip/tooltip.tsx +4 -1
- package/src/components/TreeView/index.ts +5 -0
- package/src/components/TreeView/tree-view.anatomy.stories.tsx +426 -0
- package/src/components/TreeView/tree-view.principles.stories.tsx +190 -0
- package/src/components/TreeView/tree-view.spec.md +390 -0
- package/src/components/TreeView/tree-view.stories.tsx +299 -0
- package/src/components/TreeView/tree-view.tsx +63 -26
- package/src/hooks/use-overflow-items.ts +10 -6
- package/src/index.ts +73 -69
- package/src/lib/utils.ts +2 -1
- package/src/patterns/README.md +15 -11
- package/src/patterns/action-bar/action-bar.spec.md +465 -0
- package/src/patterns/action-bar/action-bar.stories.tsx +612 -0
- package/src/patterns/element-anatomy/element-anatomy.spec.md +217 -0
- package/src/patterns/element-anatomy/index.ts +5 -0
- package/src/patterns/element-anatomy/inline-action.spec.md +320 -0
- package/src/patterns/element-anatomy/item-anatomy.spec.md +1051 -0
- package/src/patterns/element-anatomy/item-anatomy.stories.tsx +1622 -0
- package/src/patterns/element-anatomy/item-anatomy.tsx +9 -5
- package/src/patterns/header-canonical/chrome-header.tsx +16 -5
- package/src/patterns/header-canonical/header-canonical.css +2 -2
- package/src/patterns/header-canonical/header-canonical.spec.md +326 -0
- package/src/patterns/header-canonical/header-canonical.stories.tsx +150 -0
- package/src/patterns/header-canonical/index.ts +5 -0
- package/src/patterns/horizontal-overflow/horizontal-overflow.spec.md +211 -0
- package/src/patterns/horizontal-overflow/index.ts +5 -0
- package/src/patterns/overlay-surface/index.ts +5 -0
- package/src/patterns/overlay-surface/overlay-surface.spec.md +442 -0
- package/src/patterns/overlay-surface/overlay-surface.tsx +26 -11
- package/src/patterns/resize-handle/index.ts +5 -0
- package/src/patterns/resize-handle/resize-handle.spec.md +120 -0
- package/src/patterns/resize-handle/resize-handle.stories.tsx +71 -0
- package/src/story-governance/category-matrix.json +132 -0
- package/src/story-governance/category-matrix.ts +55 -0
- package/src/styles/base.css +92 -0
- package/src/styles/tokens.css +11 -0
- package/src/tokens/README.md +7 -2
- package/src/tokens/categorical-color.ts +164 -0
- package/src/tokens/color/color.spec.md +801 -0
- package/src/tokens/color/color.stories.tsx +363 -0
- package/src/tokens/color/primitives.css +7 -0
- package/src/tokens/color/semantic.css +28 -13
- package/src/tokens/density/density.spec.md +128 -0
- package/src/tokens/density/density.stories.tsx +240 -0
- package/src/tokens/elevation/elevation.spec.md +78 -0
- package/src/tokens/elevation/elevation.stories.tsx +98 -0
- package/src/tokens/layoutSpace/layoutSpace.css +1 -1
- package/src/tokens/layoutSpace/layoutSpace.spec.md +324 -0
- package/src/tokens/layoutSpace/layoutSpace.stories.tsx +75 -0
- package/src/tokens/motion/motion.css +2 -2
- package/src/tokens/motion/motion.spec.md +105 -0
- package/src/tokens/motion/motion.ts +1 -1
- package/src/tokens/opacity/opacity.spec.md +73 -0
- package/src/tokens/opacity/opacity.stories.tsx +69 -0
- package/src/tokens/orphan-tokens.spec.md +128 -0
- package/src/tokens/radius/radius.spec.md +126 -0
- package/src/tokens/radius/radius.stories.tsx +86 -0
- package/src/tokens/token-system.spec.md +240 -0
- package/src/tokens/typography/typography.spec.md +204 -0
- package/src/tokens/typography/typography.stories.tsx +133 -0
- package/src/tokens/uiSize/icon-size.ts +1 -2
- package/src/tokens/uiSize/uiSize.css +21 -0
- package/src/tokens/uiSize/uiSize.spec.md +465 -0
- package/src/tokens/utility-registry.json +124 -0
- package/dist/components/NameCard/name-card.d.ts.map +0 -1
- package/dist/components/NameCard/name-card.js.map +0 -1
|
@@ -3,7 +3,7 @@ import * as React from "react";
|
|
|
3
3
|
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
|
|
4
4
|
import { cva } from "class-variance-authority";
|
|
5
5
|
import { cn } from "../../lib/utils.js";
|
|
6
|
-
import {
|
|
6
|
+
import { useResolvedFieldSize, useResolvedFieldDisabled } from "../Field/field-context.js";
|
|
7
7
|
import { Tooltip, TooltipTrigger, TooltipContent } from "../Tooltip/tooltip.js";
|
|
8
8
|
import { ICON_SIZE } from "../../patterns/element-anatomy/item-anatomy.js";
|
|
9
9
|
const SegmentedControlContext = React.createContext({
|
|
@@ -32,17 +32,15 @@ const SegmentedControl = React.forwardRef(
|
|
|
32
32
|
size: sizeProp,
|
|
33
33
|
fullWidth = false,
|
|
34
34
|
iconOnly = false,
|
|
35
|
-
disabled
|
|
35
|
+
disabled,
|
|
36
36
|
children,
|
|
37
37
|
value,
|
|
38
38
|
defaultValue,
|
|
39
39
|
onValueChange,
|
|
40
40
|
...props
|
|
41
41
|
}, ref) => {
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
const resolvedSize = sizeProp ?? (fieldCtx == null ? void 0 : fieldCtx.size) ?? "md";
|
|
45
|
-
const resolvedDisabled = disabled || !!(fieldCtx == null ? void 0 : fieldCtx.disabled);
|
|
42
|
+
const resolvedSize = useResolvedFieldSize(sizeProp, "md");
|
|
43
|
+
const resolvedDisabled = useResolvedFieldDisabled(disabled);
|
|
46
44
|
const ctxValue = React.useMemo(
|
|
47
45
|
() => ({ size: resolvedSize, fullWidth, iconOnly, disabled: resolvedDisabled }),
|
|
48
46
|
[resolvedSize, fullWidth, iconOnly, resolvedDisabled]
|
|
@@ -112,7 +110,7 @@ const itemVariants = cva(
|
|
|
112
110
|
);
|
|
113
111
|
const SegmentedControlItem = React.forwardRef(({ className, startIcon: StartIcon, badge, children, "aria-label": ariaLabel, ...restProps }, ref) => {
|
|
114
112
|
const { size, fullWidth, iconOnly: groupIconOnly } = React.useContext(SegmentedControlContext);
|
|
115
|
-
const iconSize = ICON_SIZE[size];
|
|
113
|
+
const iconSize = size === "xs" ? ICON_SIZE.sm : ICON_SIZE[size];
|
|
116
114
|
const hasSuffix = badge != null;
|
|
117
115
|
const effectiveIconOnly = groupIconOnly;
|
|
118
116
|
const itemEl = /* @__PURE__ */ jsxs(
|
|
@@ -144,11 +142,11 @@ const SegmentedControlItem = React.forwardRef(({ className, startIcon: StartIcon
|
|
|
144
142
|
SegmentedControlItem.displayName = "SegmentedControlItem";
|
|
145
143
|
const segmentedControlMeta = {
|
|
146
144
|
component: "SegmentedControl",
|
|
147
|
-
family:
|
|
148
|
-
//
|
|
145
|
+
family: 3,
|
|
146
|
+
// Family 3(Pill Layout)— 對齊 spec frontmatter family:3 + body L42
|
|
149
147
|
variants: {},
|
|
150
148
|
sizes: {
|
|
151
|
-
xs: { fieldHeight: 24, typography: "caption", iconSize:
|
|
149
|
+
xs: { fieldHeight: 24, typography: "caption", iconSize: 16, purpose: "row-embedded inline action / DataTable inline filter" },
|
|
152
150
|
sm: { fieldHeight: 28, typography: "body", iconSize: 16, purpose: "compact chrome bar / dense toolbar" },
|
|
153
151
|
md: { fieldHeight: 32, typography: "body", iconSize: 16, purpose: "預設 — form field 對齊" },
|
|
154
152
|
lg: { fieldHeight: 36, typography: "body-lg", iconSize: 20, purpose: "touch / prominent CTA" }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"segmented-control.js","sources":["../../../src/components/SegmentedControl/segmented-control.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.\nimport * as React from 'react'\nimport * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group'\nimport { cva } from 'class-variance-authority'\nimport type { LucideIcon } from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport { useFieldContext } from '@/design-system/components/Field/field-context'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/design-system/components/Tooltip/tooltip'\nimport { ICON_SIZE } from '@/design-system/tokens/uiSize/icon-size'\n\n/**\n * SegmentedControl — 互斥多選一的 value 選擇器\n *\n * 基於 Radix ToggleGroup(寫死 type=\"single\"),橋接設計系統 token。\n * 內部 item 結構鏡射 Button,但兩者型別獨立。\n *\n * ── 定位 ──\n * 切 value(不是切 view)。塞得進 Field,Tabs 不行。\n * 切 view → Tabs;單一 on/off → Button pressed;>5 個選項 → Select。\n *\n * ── Size(對齊 field-height / Button 系列)──\n * xs h-field-xs(24 固定)\n * sm h-field-sm(28/32)\n * md h-field-md(32/36)★ 預設(跟 Button / Input / 所有 field-height 系列一致)\n * lg h-field-lg(36/40)\n *\n * ── fullWidth ──\n * false ★ 預設,item 寬度由內容決定(hug content)\n * true SegmentedControl 撐滿父容器寬度,所有 item 等分\n *\n * ── Item 結構 ──\n * [startIcon?] [<span px-1>label</span>] [<span gap-1>suffix?</span>]\n * suffix 目前只支援 badge;endIcon 為保留 slot、未開放\n *\n * ── iconOnly(group-level)──\n * 整組同時 icon-only 或全帶 label,不可混搭。\n */\n\ntype SegmentedControlSize = 'xs' | 'sm' | 'md' | 'lg'\n\ninterface SegmentedControlContextValue {\n size: SegmentedControlSize\n fullWidth: boolean\n iconOnly: boolean\n disabled: boolean\n}\n\nconst SegmentedControlContext = React.createContext<SegmentedControlContextValue>({\n size: 'md',\n fullWidth: false,\n iconOnly: false,\n disabled: false,\n})\n\n// ── Root ──\nconst segmentedControlVariants = cva(\n 'flex items-stretch rounded-md',\n {\n variants: {\n fullWidth: {\n true: 'w-full',\n false: 'w-fit',\n },\n },\n defaultVariants: {\n fullWidth: false,\n },\n }\n)\n\nexport interface SegmentedControlProps\n extends Omit<\n React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root>,\n 'type' | 'defaultValue' | 'value' | 'onValueChange'\n > {\n size?: SegmentedControlSize\n /** 撐滿父容器寬度,所有 item 等分。預設 false(hug content) */\n fullWidth?: boolean\n iconOnly?: boolean\n value?: string\n defaultValue?: string\n onValueChange?: (value: string) => void\n}\n\nconst SegmentedControl = React.forwardRef<\n React.ElementRef<typeof ToggleGroupPrimitive.Root>,\n SegmentedControlProps\n>(\n (\n {\n className,\n size: sizeProp,\n fullWidth = false,\n iconOnly = false,\n disabled = false,\n children,\n value,\n defaultValue,\n onValueChange,\n ...props\n },\n ref\n ) => {\n // Field 內自動讀 size,跟 Button 同機制\n const fieldCtx = useFieldContext?.()\n const resolvedSize: SegmentedControlSize =\n sizeProp ?? (fieldCtx?.size as SegmentedControlSize) ?? 'md'\n const resolvedDisabled = disabled || !!fieldCtx?.disabled\n\n // Memoize provider value(2026-04-22 D3 perf audit):避免每次父 render 重建 4-field object\n // 讓 children SegmentedControlItem 不必要 re-render\n const ctxValue = React.useMemo(\n () => ({ size: resolvedSize, fullWidth, iconOnly, disabled: resolvedDisabled }),\n [resolvedSize, fullWidth, iconOnly, resolvedDisabled],\n )\n\n return (\n <SegmentedControlContext.Provider value={ctxValue}>\n <ToggleGroupPrimitive.Root\n ref={ref}\n type=\"single\"\n value={value}\n defaultValue={defaultValue}\n onValueChange={(v) => {\n // Radix 的 single ToggleGroup 允許 deselect(返回空字串)\n // SegmentedControl 是 radio 語意,不允許空值——忽略 deselect\n if (v) onValueChange?.(v)\n }}\n disabled={resolvedDisabled}\n className={cn(segmentedControlVariants({ fullWidth }), className)}\n {...props}\n >\n {children}\n </ToggleGroupPrimitive.Root>\n </SegmentedControlContext.Provider>\n )\n }\n)\nSegmentedControl.displayName = 'SegmentedControl'\n\n// ── Item ──\n\n/**\n * Icon-only base — Polaris/Atlassian idiom:`aspect-square + p-0 + flex-center`。\n * 0 magic-number、0 公式、0 border-deduction;flex centering(已在 itemVariants base)\n * 自動將 SVG 視覺置中,任何 size / icon 都自然正方形。\n *\n * 對齊 `Button.tsx` 的 `ICON_ONLY_BASE`(2026-04-25 從 padding-formula 派改 padding-free)。\n * Rule-of-3:目前 2 處 consumer(Button + SegmentedControl),尚未抽 utility/token;\n * 第 3 個 host 加入時抽到 `packages/design-system/src/utils/`。\n *\n * 舊公式 `(field-height - icon)/2` 沒扣 border 2px,造成 SegmentedControl item 從\n * 設計 spec「自然正方形」漂移為 34×32 長方形(2026-04-25 audit 發現)。\n */\nconst ICON_ONLY_BASE = 'aspect-square p-0 min-w-0 gap-0'\n\nconst itemVariants = cva(\n [\n 'relative inline-flex items-center justify-center',\n 'whitespace-nowrap font-medium',\n 'border border-border bg-surface text-fg-secondary',\n 'transition-colors duration-150',\n 'cursor-pointer select-none',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:z-20',\n // disabled:cursor-not-allowed + 鎖住 hover 色(不用 pointer-events-none,否則 cursor 無法變)\n // button[disabled] 本身擋 click,不需靠 pointer-events: none\n 'disabled:cursor-not-allowed disabled:text-fg-disabled',\n 'disabled:hover:text-fg-disabled disabled:hover:border-border',\n // hover(未選):border 加深一階 + 文字轉深,對齊 Input / Chip hover\n 'hover:text-foreground hover:border-border-hover hover:z-[5]',\n // selected: 文字 + 邊框都用 primary-hover,底色維持 bg-surface 不變 (跟 Chip 一致)\n // ── 這是 pill 風格元件 (Chip / SegmentedControl) 的 canonical 選中規則:\n // primary-hover 同時染文字和線條;底色不改 (不用 primary-subtle)。\n // Tabs 是 underline 風格,規則不同 (文字 foreground + 底線 primary-hover)。\n // z-10 讓 border 浮在相鄰 item 之上\n 'data-[state=on]:text-primary-hover data-[state=on]:border-primary-hover data-[state=on]:z-10',\n // item 連體:除第一個外,-ml-px 讓相鄰 border 重疊\n 'first:rounded-l-md last:rounded-r-md',\n '[&:not(:first-child)]:-ml-px',\n ],\n {\n variants: {\n size: {\n xs: 'h-field-xs px-2 text-caption leading-compact gap-0',\n sm: 'h-field-sm px-3 text-body leading-compact gap-1',\n md: 'h-field-md px-3 text-body leading-compact gap-1',\n lg: 'h-field-lg px-3 text-body-lg leading-compact gap-1',\n },\n fullWidth: {\n true: 'flex-1 min-w-0',\n false: '',\n },\n },\n defaultVariants: {\n size: 'md',\n fullWidth: false,\n },\n }\n)\n\n// iconOnly 是 group-level 決策(由 <SegmentedControl iconOnly> 控制),\n// 不是 per-item 決策,所以 Item 型別不用 discriminated union 強制 iconOnly。\n// 但當 group iconOnly = true 時,每個 item 必須提供 startIcon + aria-label——\n// 這是語意契約,在 render 階段檢查並在 dev mode 發出警告(TS 層做不到這層檢查)。\nexport interface SegmentedControlItemProps\n extends React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item> {\n /** 左側 icon(LucideIcon)。group iconOnly = true 時必填。 */\n startIcon?: LucideIcon\n /** 右側 suffix badge(通常是計數指示器)。group iconOnly = true 時會被忽略。 */\n badge?: React.ReactNode\n /**\n * 無障礙名稱。帶 label 時可選(label 已傳達語意),\n * 但 group iconOnly = true 時必填——同時驅動 screen reader 和自動 tooltip。\n */\n 'aria-label'?: string\n children?: React.ReactNode\n}\n\nconst SegmentedControlItem = React.forwardRef<\n React.ElementRef<typeof ToggleGroupPrimitive.Item>,\n SegmentedControlItemProps\n>(({ className, startIcon: StartIcon, badge, children, 'aria-label': ariaLabel, ...restProps }, ref) => {\n const { size, fullWidth, iconOnly: groupIconOnly } = React.useContext(SegmentedControlContext)\n // 2026-05-18 改 per user 拍板「沒機械化導致偏移」+「做完」approval(對齊 Button xs / uiSize Icon Tier):\n // 原 xs=14 跟 Button xs=16 不一致,xs/sm/md 統一 16 對齊 uiSize.spec.md(xs/sm/md→16, lg→20)。\n // 2026-05-18 改 import ICON_SIZE SSOT(per user『做完』approval,消除 M17 違反 7+ 重複 ternary)\n const iconSize = ICON_SIZE[size as 'sm' | 'md' | 'lg']\n const hasSuffix = badge != null\n\n // Dev-mode 語意契約檢查:group iconOnly = true 時,item 必須有 startIcon + aria-label\n if (import.meta.env?.DEV && groupIconOnly) {\n if (!StartIcon) {\n console.warn(\n '[SegmentedControl] iconOnly 群組內的 item 必須提供 startIcon。'\n )\n }\n if (!ariaLabel) {\n console.warn(\n '[SegmentedControl] iconOnly 群組內的 item 必須提供 aria-label(作為無障礙名稱與自動 tooltip 來源)。'\n )\n }\n }\n\n const effectiveIconOnly = groupIconOnly\n\n const itemEl = (\n <ToggleGroupPrimitive.Item\n ref={ref}\n className={cn(\n itemVariants({ size, fullWidth }),\n effectiveIconOnly && ICON_ONLY_BASE,\n className,\n )}\n aria-label={ariaLabel}\n {...restProps}\n >\n {StartIcon && <StartIcon size={iconSize} aria-hidden />}\n {!effectiveIconOnly && children != null && <span className=\"px-1\">{children}</span>}\n {/* suffix wrapper:即使目前只有 badge,wrapper 從第一天就存在,\n 未來若開放 endIcon,直接加入此 span 內 gap-1 自動生效 */}\n {hasSuffix && !effectiveIconOnly && (\n <span className=\"inline-flex items-center gap-1\">{badge}</span>\n )}\n </ToggleGroupPrimitive.Item>\n )\n\n // icon-only 自動包 Tooltip(與 Button icon-only 一致)\n if (effectiveIconOnly && typeof ariaLabel === 'string') {\n return (\n <Tooltip>\n <TooltipTrigger asChild>{itemEl}</TooltipTrigger>\n <TooltipContent>{ariaLabel}</TooltipContent>\n </Tooltip>\n )\n }\n\n return itemEl\n})\nSegmentedControlItem.displayName = 'SegmentedControlItem'\n\n// Story auto-compile metadata — Phase 2 fill(2026-05-15)\n// Sizes 真實 cva keys = xs/sm/md/lg(itemVariants.size),映射 field-height-* token tier\n// SegmentedControl 無語意 variant(選中 vs 未選 是 state 不是 variant)— 與 Button.variant 刻意不同(spec「與 Button 的血緣」段)\nexport const segmentedControlMeta = {\n component: 'SegmentedControl',\n family: null, // non-family composite / overlay / layout\n variants: {},\n sizes: {\n xs: { fieldHeight: 24, typography: 'caption', iconSize: 14, purpose: 'row-embedded inline action / DataTable inline filter' },\n sm: { fieldHeight: 28, typography: 'body', iconSize: 16, purpose: 'compact chrome bar / dense toolbar' },\n md: { fieldHeight: 32, typography: 'body', iconSize: 16, purpose: '預設 — form field 對齊' },\n lg: { fieldHeight: 36, typography: 'body-lg', iconSize: 20, purpose: 'touch / prominent CTA' },\n },\n states: ['default', 'hover', 'active', 'focus-visible', 'disabled'],\n tokens: {\n bg: ['bg-surface'],\n fg: ['text-fg-disabled', 'text-fg-secondary', 'text-foreground'],\n ring: ['ring-ring'],\n },\n defaultSize: 'md',\n} as const\n\nexport { SegmentedControl, SegmentedControlItem, segmentedControlVariants, itemVariants as segmentedControlItemVariants }\nexport type { SegmentedControlSize }\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"segmented-control.js","sources":["../../../src/components/SegmentedControl/segmented-control.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.\nimport * as React from 'react'\nimport * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group'\nimport { cva } from 'class-variance-authority'\nimport type { LucideIcon } from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport { useResolvedFieldSize, useResolvedFieldDisabled } from '@/design-system/components/Field/field-context'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/design-system/components/Tooltip/tooltip'\nimport { ICON_SIZE } from '@/design-system/tokens/uiSize/icon-size'\n\n/**\n * SegmentedControl — 互斥多選一的 value 選擇器\n *\n * 基於 Radix ToggleGroup(寫死 type=\"single\"),橋接設計系統 token。\n * 內部 item 結構鏡射 Button,但兩者型別獨立。\n *\n * ── 定位 ──\n * 切 value(不是切 view)。塞得進 Field,Tabs 不行。\n * 切 view → Tabs;單一 on/off → Button pressed;>5 個選項 → Select。\n *\n * ── Size(對齊 field-height / Button 系列)──\n * xs h-field-xs(24 固定)\n * sm h-field-sm(28/32)\n * md h-field-md(32/36)★ 預設(跟 Button / Input / 所有 field-height 系列一致)\n * lg h-field-lg(36/40)\n *\n * ── fullWidth ──\n * false ★ 預設,item 寬度由內容決定(hug content)\n * true SegmentedControl 撐滿父容器寬度,所有 item 等分\n *\n * ── Item 結構 ──\n * [startIcon?] [<span px-1>label</span>] [<span gap-1>suffix?</span>]\n * suffix 目前只支援 badge;endIcon 為保留 slot、未開放\n *\n * ── iconOnly(group-level)──\n * 整組同時 icon-only 或全帶 label,不可混搭。\n */\n\ntype SegmentedControlSize = 'xs' | 'sm' | 'md' | 'lg'\n\ninterface SegmentedControlContextValue {\n size: SegmentedControlSize\n fullWidth: boolean\n iconOnly: boolean\n disabled: boolean\n}\n\nconst SegmentedControlContext = React.createContext<SegmentedControlContextValue>({\n size: 'md',\n fullWidth: false,\n iconOnly: false,\n disabled: false,\n})\n\n// ── Root ──\nconst segmentedControlVariants = cva(\n 'flex items-stretch rounded-md',\n {\n variants: {\n fullWidth: {\n true: 'w-full',\n false: 'w-fit',\n },\n },\n defaultVariants: {\n fullWidth: false,\n },\n }\n)\n\nexport interface SegmentedControlProps\n extends Omit<\n React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root>,\n 'type' | 'defaultValue' | 'value' | 'onValueChange'\n > {\n size?: SegmentedControlSize\n /** 撐滿父容器寬度,所有 item 等分。預設 false(hug content) */\n fullWidth?: boolean\n iconOnly?: boolean\n value?: string\n defaultValue?: string\n onValueChange?: (value: string) => void\n}\n\nconst SegmentedControl = React.forwardRef<\n React.ElementRef<typeof ToggleGroupPrimitive.Root>,\n SegmentedControlProps\n>(\n (\n {\n className,\n size: sizeProp,\n fullWidth = false,\n iconOnly = false,\n disabled,\n children,\n value,\n defaultValue,\n onValueChange,\n ...props\n },\n ref\n ) => {\n // Field 內自動讀 size + disabled,跟 Button 同機制(SSOT resolver hook)\n const resolvedSize = useResolvedFieldSize<SegmentedControlSize>(sizeProp, 'md') // SSOT:統一 size resolution(原散落 ?? fieldCtx?.size ?? 'md')\n const resolvedDisabled = useResolvedFieldDisabled(disabled)\n\n // Memoize provider value(2026-04-22 D3 perf audit):避免每次父 render 重建 4-field object\n // 讓 children SegmentedControlItem 不必要 re-render\n const ctxValue = React.useMemo(\n () => ({ size: resolvedSize, fullWidth, iconOnly, disabled: resolvedDisabled }),\n [resolvedSize, fullWidth, iconOnly, resolvedDisabled],\n )\n\n return (\n <SegmentedControlContext.Provider value={ctxValue}>\n <ToggleGroupPrimitive.Root\n ref={ref}\n type=\"single\"\n value={value}\n defaultValue={defaultValue}\n onValueChange={(v) => {\n // Radix 的 single ToggleGroup 允許 deselect(返回空字串)\n // SegmentedControl 是 radio 語意,不允許空值——忽略 deselect\n if (v) onValueChange?.(v)\n }}\n disabled={resolvedDisabled}\n className={cn(segmentedControlVariants({ fullWidth }), className)}\n {...props}\n >\n {children}\n </ToggleGroupPrimitive.Root>\n </SegmentedControlContext.Provider>\n )\n }\n)\nSegmentedControl.displayName = 'SegmentedControl'\n\n// ── Item ──\n\n/**\n * Icon-only base — Polaris/Atlassian idiom:`aspect-square + p-0 + flex-center`。\n * 0 magic-number、0 公式、0 border-deduction;flex centering(已在 itemVariants base)\n * 自動將 SVG 視覺置中,任何 size / icon 都自然正方形。\n *\n * 對齊 `Button.tsx` 的 `ICON_ONLY_BASE`(2026-04-25 從 padding-formula 派改 padding-free)。\n * Rule-of-3:目前 2 處 consumer(Button + SegmentedControl),尚未抽 utility/token;\n * 第 3 個 host 加入時抽到 `packages/design-system/src/utils/`。\n *\n * 舊公式 `(field-height - icon)/2` 沒扣 border 2px,造成 SegmentedControl item 從\n * 設計 spec「自然正方形」漂移為 34×32 長方形(2026-04-25 audit 發現)。\n */\nconst ICON_ONLY_BASE = 'aspect-square p-0 min-w-0 gap-0'\n\nconst itemVariants = cva(\n [\n 'relative inline-flex items-center justify-center',\n 'whitespace-nowrap font-medium',\n 'border border-border bg-surface text-fg-secondary',\n 'transition-colors duration-150',\n 'cursor-pointer select-none',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:z-20',\n // disabled:cursor-not-allowed + 鎖住 hover 色(不用 pointer-events-none,否則 cursor 無法變)\n // button[disabled] 本身擋 click,不需靠 pointer-events: none\n 'disabled:cursor-not-allowed disabled:text-fg-disabled',\n 'disabled:hover:text-fg-disabled disabled:hover:border-border',\n // hover(未選):border 加深一階 + 文字轉深,對齊 Input / Chip hover\n 'hover:text-foreground hover:border-border-hover hover:z-[5]',\n // selected: 文字 + 邊框都用 primary-hover,底色維持 bg-surface 不變 (跟 Chip 一致)\n // ── 這是 pill 風格元件 (Chip / SegmentedControl) 的 canonical 選中規則:\n // primary-hover 同時染文字和線條;底色不改 (不用 primary-subtle)。\n // Tabs 是 underline 風格,規則不同 (文字 foreground + 底線 primary-hover)。\n // z-10 讓 border 浮在相鄰 item 之上\n 'data-[state=on]:text-primary-hover data-[state=on]:border-primary-hover data-[state=on]:z-10',\n // item 連體:除第一個外,-ml-px 讓相鄰 border 重疊\n 'first:rounded-l-md last:rounded-r-md',\n '[&:not(:first-child)]:-ml-px',\n ],\n {\n variants: {\n size: {\n xs: 'h-field-xs px-2 text-caption leading-compact gap-0',\n sm: 'h-field-sm px-3 text-body leading-compact gap-1',\n md: 'h-field-md px-3 text-body leading-compact gap-1',\n lg: 'h-field-lg px-3 text-body-lg leading-compact gap-1',\n },\n fullWidth: {\n true: 'flex-1 min-w-0',\n false: '',\n },\n },\n defaultVariants: {\n size: 'md',\n fullWidth: false,\n },\n }\n)\n\n// iconOnly 是 group-level 決策(由 <SegmentedControl iconOnly> 控制),\n// 不是 per-item 決策,所以 Item 型別不用 discriminated union 強制 iconOnly。\n// 但當 group iconOnly = true 時,每個 item 必須提供 startIcon + aria-label——\n// 這是語意契約,在 render 階段檢查並在 dev mode 發出警告(TS 層做不到這層檢查)。\nexport interface SegmentedControlItemProps\n extends React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item> {\n /** 左側 icon(LucideIcon)。group iconOnly = true 時必填。 */\n startIcon?: LucideIcon\n /** 右側 suffix badge(通常是計數指示器)。group iconOnly = true 時會被忽略。 */\n badge?: React.ReactNode\n /**\n * 無障礙名稱。帶 label 時可選(label 已傳達語意),\n * 但 group iconOnly = true 時必填——同時驅動 screen reader 和自動 tooltip。\n */\n 'aria-label'?: string\n children?: React.ReactNode\n}\n\nconst SegmentedControlItem = React.forwardRef<\n React.ElementRef<typeof ToggleGroupPrimitive.Item>,\n SegmentedControlItemProps\n>(({ className, startIcon: StartIcon, badge, children, 'aria-label': ariaLabel, ...restProps }, ref) => {\n const { size, fullWidth, iconOnly: groupIconOnly } = React.useContext(SegmentedControlContext)\n // 2026-05-18 改 per user 拍板「沒機械化導致偏移」+「做完」approval(對齊 Button xs / uiSize Icon Tier):\n // 原 xs=14 跟 Button xs=16 不一致,xs/sm/md 統一 16 對齊 uiSize.spec.md(xs/sm/md→16, lg→20)。\n // 2026-05-18 改 import ICON_SIZE SSOT(per user『做完』approval,消除 M17 違反 7+ 重複 ternary)\n // 2026-05-31 #14:ICON_SIZE 只有 sm/md/lg key,size='xs' 會落 undefined → 對齊上方註解「xs/sm/md 統一 16」讓 xs 取 sm(16px)。\n const iconSize = size === 'xs' ? ICON_SIZE.sm : ICON_SIZE[size as 'sm' | 'md' | 'lg']\n const hasSuffix = badge != null\n\n // Dev-mode 語意契約檢查:group iconOnly = true 時,item 必須有 startIcon + aria-label\n if (import.meta.env?.DEV && groupIconOnly) {\n if (!StartIcon) {\n console.warn(\n '[SegmentedControl] iconOnly 群組內的 item 必須提供 startIcon。'\n )\n }\n if (!ariaLabel) {\n console.warn(\n '[SegmentedControl] iconOnly 群組內的 item 必須提供 aria-label(作為無障礙名稱與自動 tooltip 來源)。'\n )\n }\n }\n\n const effectiveIconOnly = groupIconOnly\n\n const itemEl = (\n <ToggleGroupPrimitive.Item\n ref={ref}\n className={cn(\n itemVariants({ size, fullWidth }),\n effectiveIconOnly && ICON_ONLY_BASE,\n className,\n )}\n aria-label={ariaLabel}\n {...restProps}\n >\n {StartIcon && <StartIcon size={iconSize} aria-hidden />}\n {!effectiveIconOnly && children != null && <span className=\"px-1\">{children}</span>}\n {/* suffix wrapper:即使目前只有 badge,wrapper 從第一天就存在,\n 未來若開放 endIcon,直接加入此 span 內 gap-1 自動生效 */}\n {hasSuffix && !effectiveIconOnly && (\n <span className=\"inline-flex items-center gap-1\">{badge}</span>\n )}\n </ToggleGroupPrimitive.Item>\n )\n\n // icon-only 自動包 Tooltip(與 Button icon-only 一致)\n if (effectiveIconOnly && typeof ariaLabel === 'string') {\n return (\n <Tooltip>\n <TooltipTrigger asChild>{itemEl}</TooltipTrigger>\n <TooltipContent>{ariaLabel}</TooltipContent>\n </Tooltip>\n )\n }\n\n return itemEl\n})\nSegmentedControlItem.displayName = 'SegmentedControlItem'\n\n// Story auto-compile metadata — Phase 2 fill(2026-05-15)\n// Sizes 真實 cva keys = xs/sm/md/lg(itemVariants.size),映射 field-height-* token tier\n// SegmentedControl 無語意 variant(選中 vs 未選 是 state 不是 variant)— 與 Button.variant 刻意不同(spec「與 Button 的血緣」段)\nexport const segmentedControlMeta = {\n component: 'SegmentedControl',\n family: 3, // Family 3(Pill Layout)— 對齊 spec frontmatter family:3 + body L42\n variants: {},\n sizes: {\n xs: { fieldHeight: 24, typography: 'caption', iconSize: 16, purpose: 'row-embedded inline action / DataTable inline filter' },\n sm: { fieldHeight: 28, typography: 'body', iconSize: 16, purpose: 'compact chrome bar / dense toolbar' },\n md: { fieldHeight: 32, typography: 'body', iconSize: 16, purpose: '預設 — form field 對齊' },\n lg: { fieldHeight: 36, typography: 'body-lg', iconSize: 20, purpose: 'touch / prominent CTA' },\n },\n states: ['default', 'hover', 'active', 'focus-visible', 'disabled'],\n tokens: {\n bg: ['bg-surface'],\n fg: ['text-fg-disabled', 'text-fg-secondary', 'text-foreground'],\n ring: ['ring-ring'],\n },\n defaultSize: 'md',\n} as const\n\nexport { SegmentedControl, SegmentedControlItem, segmentedControlVariants, itemVariants as segmentedControlItemVariants }\nexport type { SegmentedControlSize }\n"],"names":[],"mappings":";;;;;;;;AA+CA,MAAM,0BAA0B,MAAM,cAA4C;AAAA,EAChF,MAAM;AAAA,EACN,WAAW;AAAA,EACX,UAAU;AAAA,EACV,UAAU;AACZ,CAAC;AAGD,MAAM,2BAA2B;AAAA,EAC/B;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,WAAW;AAAA,QACT,MAAM;AAAA,QACN,OAAO;AAAA,MAAA;AAAA,IACT;AAAA,IAEF,iBAAiB;AAAA,MACf,WAAW;AAAA,IAAA;AAAA,EACb;AAEJ;AAgBA,MAAM,mBAAmB,MAAM;AAAA,EAI7B,CACE;AAAA,IACE;AAAA,IACA,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AAEH,UAAM,eAAe,qBAA2C,UAAU,IAAI;AAC9E,UAAM,mBAAmB,yBAAyB,QAAQ;AAI1D,UAAM,WAAW,MAAM;AAAA,MACrB,OAAO,EAAE,MAAM,cAAc,WAAW,UAAU,UAAU;MAC5D,CAAC,cAAc,WAAW,UAAU,gBAAgB;AAAA,IAAA;AAGtD,+BACG,wBAAwB,UAAxB,EAAiC,OAAO,UACvC,UAAA;AAAA,MAAC,qBAAqB;AAAA,MAArB;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA,eAAe,CAAC,MAAM;AAGpB,cAAI,kDAAmB;AAAA,QACzB;AAAA,QACA,UAAU;AAAA,QACV,WAAW,GAAG,yBAAyB,EAAE,UAAA,CAAW,GAAG,SAAS;AAAA,QAC/D,GAAG;AAAA,QAEH;AAAA,MAAA;AAAA,IAAA,GAEL;AAAA,EAEJ;AACF;AACA,iBAAiB,cAAc;AAgB/B,MAAM,iBAAiB;AAEvB,MAAM,eAAe;AAAA,EACnB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,EAAA;AAAA,EAEF;AAAA,IACE,UAAU;AAAA,MACR,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MAAA;AAAA,MAEN,WAAW;AAAA,QACT,MAAM;AAAA,QACN,OAAO;AAAA,MAAA;AAAA,IACT;AAAA,IAEF,iBAAiB;AAAA,MACf,MAAM;AAAA,MACN,WAAW;AAAA,IAAA;AAAA,EACb;AAEJ;AAoBA,MAAM,uBAAuB,MAAM,WAGjC,CAAC,EAAE,WAAW,WAAW,WAAW,OAAO,UAAU,cAAc,WAAW,GAAG,UAAA,GAAa,QAAQ;AACtG,QAAM,EAAE,MAAM,WAAW,UAAU,kBAAkB,MAAM,WAAW,uBAAuB;AAK7F,QAAM,WAAW,SAAS,OAAO,UAAU,KAAK,UAAU,IAA0B;AACpF,QAAM,YAAY,SAAS;AAgB3B,QAAM,oBAAoB;AAE1B,QAAM,SACJ;AAAA,IAAC,qBAAqB;AAAA,IAArB;AAAA,MACC;AAAA,MACA,WAAW;AAAA,QACT,aAAa,EAAE,MAAM,WAAW;AAAA,QAChC,qBAAqB;AAAA,QACrB;AAAA,MAAA;AAAA,MAEF,cAAY;AAAA,MACX,GAAG;AAAA,MAEH,UAAA;AAAA,QAAA,iCAAc,WAAA,EAAU,MAAM,UAAU,eAAW,MAAC;AAAA,QACpD,CAAC,qBAAqB,YAAY,4BAAS,QAAA,EAAK,WAAU,QAAQ,UAAS;AAAA,QAG3E,aAAa,CAAC,yCACZ,QAAA,EAAK,WAAU,kCAAkC,UAAA,MAAA,CAAM;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAM9D,MAAI,qBAAqB,OAAO,cAAc,UAAU;AACtD,gCACG,SAAA,EACC,UAAA;AAAA,0BAAC,gBAAA,EAAe,SAAO,MAAE,UAAA,QAAO;AAAA,MAChC,oBAAC,kBAAgB,UAAA,WAAU;AAAA,IAAA,GAC7B;AAAA,EAEJ;AAEA,SAAO;AACT,CAAC;AACD,qBAAqB,cAAc;AAK5B,MAAM,uBAAuB;AAAA,EAClC,WAAW;AAAA,EACX,QAAQ;AAAA;AAAA,EACR,UAAU,CAAA;AAAA,EACV,OAAO;AAAA,IACL,IAAI,EAAE,aAAa,IAAI,YAAY,WAAW,UAAU,IAAI,SAAS,uDAAA;AAAA,IACrE,IAAI,EAAE,aAAa,IAAI,YAAY,QAAQ,UAAU,IAAI,SAAS,qCAAA;AAAA,IAClE,IAAI,EAAE,aAAa,IAAI,YAAY,QAAQ,UAAU,IAAI,SAAS,qBAAA;AAAA,IAClE,IAAI,EAAE,aAAa,IAAI,YAAY,WAAW,UAAU,IAAI,SAAS,wBAAA;AAAA,EAAwB;AAAA,EAE/F,QAAQ,CAAC,WAAW,SAAS,UAAU,iBAAiB,UAAU;AAAA,EAClE,QAAQ;AAAA,IACN,IAAI,CAAC,YAAY;AAAA,IACjB,IAAI,CAAC,oBAAoB,qBAAqB,iBAAiB;AAAA,IAC/D,MAAM,CAAC,WAAW;AAAA,EAAA;AAAA,EAEpB,aAAa;AACf;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Select/index.ts"],"names":[],"mappings":"AAIA,cAAc,UAAU,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../src/components/Select/select.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAE9C,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,8CAA8C,CAAA;AAK3F,OAAO,EAAc,KAAK,gBAAgB,EAAE,MAAM,mDAAmD,CAAA;AAcrG;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,YAAa,SAAQ,gBAAgB;IACpD,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,2CAA2C;AAC3C,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;CACd;AAID,MAAM,WAAW,WACf,SAAQ,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,cAAc,GAAG,UAAU,CAAC;IAC3G,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,uFAAuF;IACvF,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IACzB,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,mEAAmE;IACnE,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAA;IAC5B,qFAAqF;IACrF,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB;;;;kGAI8F;IAC9F,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,GAAG,KAAK,CAAA;IACzB,SAAS,CAAC,EAAE,UAAU,CAAA;IACtB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;+HAE2H;IAC3H,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;0EAEsE;IACtE,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;yFACqF;IACrF,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACtC;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B;;;;;;;;OAQG;IACH,oBAAoB,CAAC,EAAE,CAAC,WAAW,EAAE,YAAY,KAAK,KAAK,CAAC,SAAS,CAAA;CACtE;
|
|
1
|
+
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../src/components/Select/select.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAE9C,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,8CAA8C,CAAA;AAK3F,OAAO,EAAc,KAAK,gBAAgB,EAAE,MAAM,mDAAmD,CAAA;AAcrG;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,YAAa,SAAQ,gBAAgB;IACpD,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,2CAA2C;AAC3C,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;CACd;AAID,MAAM,WAAW,WACf,SAAQ,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,cAAc,GAAG,UAAU,CAAC;IAC3G,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,uFAAuF;IACvF,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IACzB,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,mEAAmE;IACnE,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAA;IAC5B,qFAAqF;IACrF,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB;;;;kGAI8F;IAC9F,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,GAAG,KAAK,CAAA;IACzB,SAAS,CAAC,EAAE,UAAU,CAAA;IACtB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;+HAE2H;IAC3H,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;0EAEsE;IACtE,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;yFACqF;IACrF,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACtC;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B;;;;;;;;OAQG;IACH,oBAAoB,CAAC,EAAE,CAAC,WAAW,EAAE,YAAY,KAAK,KAAK,CAAC,SAAS,CAAA;CACtE;AAohBD,QAAA,MAAM,MAAM,wGAUX,CAAA;AAKD,eAAO,MAAM,UAAU;;;;;;;;;;;CAeb,CAAA;AAEV,OAAO,EAAE,MAAM,EAAE,CAAA"}
|
|
@@ -4,8 +4,8 @@ import { ChevronDown, X } from "lucide-react";
|
|
|
4
4
|
import { cn } from "../../lib/utils.js";
|
|
5
5
|
import { bareInputStyles, fieldWrapperStyles, EMPTY_DISPLAY, fieldDisplayTextClass, nakedCellRowModeAlign } from "../Field/field-wrapper.js";
|
|
6
6
|
import { Tag } from "../Tag/tag.js";
|
|
7
|
-
import { ItemPrefix, ItemSuffix,
|
|
8
|
-
import { useFieldContext } from "../Field/field-context.js";
|
|
7
|
+
import { ItemPrefix, ItemSuffix, ICON_SIZE, ItemInlineAction } from "../../patterns/element-anatomy/item-anatomy.js";
|
|
8
|
+
import { useFieldContext, useResolvedFieldInvalid, useResolvedFieldDisabled, useResolvedFieldSize, useResolvedFieldMode, useResolvedFieldVariant } from "../Field/field-context.js";
|
|
9
9
|
import { SelectMenu } from "../SelectMenu/select-menu.js";
|
|
10
10
|
import { useIsTouchDevice } from "../../hooks/use-is-touch-device.js";
|
|
11
11
|
import { useControllable } from "../../hooks/use-controllable.js";
|
|
@@ -149,23 +149,30 @@ function ReadonlyDisplay({
|
|
|
149
149
|
}
|
|
150
150
|
);
|
|
151
151
|
}
|
|
152
|
+
const showIndicator = variant === "naked" ? !!showDisplayEndIcon : resolvedMode === "disabled";
|
|
153
|
+
const ariaDisabled = resolvedMode === "disabled" ? true : void 0;
|
|
152
154
|
if (isTextDisplay) {
|
|
153
|
-
return /* @__PURE__ */ jsxs("div", { className: cn(fieldWrapperStyles({ mode: resolvedMode, variant, size: sz }), className), "data-field-mode": resolvedMode, children: [
|
|
155
|
+
return /* @__PURE__ */ jsxs("div", { className: cn(fieldWrapperStyles({ mode: resolvedMode, variant, size: sz }), className), "data-field-mode": resolvedMode, "aria-disabled": ariaDisabled, children: [
|
|
154
156
|
StartIcon && /* @__PURE__ */ jsx(ItemPrefix, { children: /* @__PURE__ */ jsx(StartIcon, { size: iconSize, className: cn("pointer-events-none", iconColor), "aria-hidden": true }) }),
|
|
155
|
-
/* @__PURE__ */ jsx("span", { className: cn("flex-1 min-w-0 truncate", resolvedMode === "disabled" && "text-fg-disabled"), children: value ? label : /* @__PURE__ */ jsx("span", { className: emptyColorCls, children: emptyText }) })
|
|
157
|
+
/* @__PURE__ */ jsx("span", { className: cn("flex-1 min-w-0 truncate", resolvedMode === "disabled" && "text-fg-disabled"), children: value ? label : /* @__PURE__ */ jsx("span", { className: emptyColorCls, children: emptyText }) }),
|
|
158
|
+
showIndicator && /* @__PURE__ */ jsx(ItemSuffix, { className: "pointer-events-none", children: /* @__PURE__ */ jsx(ChevronDown, { size: iconSize, className: cn("shrink-0", iconColor), "aria-hidden": true }) })
|
|
156
159
|
] });
|
|
157
160
|
}
|
|
158
161
|
const selectedOpt = options == null ? void 0 : options.find((o) => o.value === value);
|
|
159
162
|
const tagVariant = selectedOpt == null ? void 0 : selectedOpt.tagVariant;
|
|
160
|
-
return /* @__PURE__ */
|
|
163
|
+
return /* @__PURE__ */ jsxs("div", { className: cn(fieldWrapperStyles({ mode: resolvedMode, variant, size: sz }), value && tagPadding[sz], className), style: { paddingRight: "var(--field-px)" }, "data-field-mode": resolvedMode, "aria-disabled": ariaDisabled, children: [
|
|
164
|
+
value ? /* @__PURE__ */ jsx(Tag, { size: sz, color: tagVariant, children: label }) : /* @__PURE__ */ jsx("span", { className: emptyColorCls, children: emptyText }),
|
|
165
|
+
showIndicator && /* @__PURE__ */ jsx(ItemSuffix, { className: "pointer-events-none", children: /* @__PURE__ */ jsx(ChevronDown, { size: iconSize, className: cn("shrink-0", iconColor), "aria-hidden": true }) })
|
|
166
|
+
] });
|
|
161
167
|
}
|
|
162
168
|
const NativeSelect = React.forwardRef(
|
|
163
|
-
({ mode
|
|
169
|
+
({ mode, variant: variantProp, error: errorProp = false, size: sizeProp, options, value: valueProp, defaultValue, onChange, placeholder, className, disabled: disabledProp, clearable = false, display = "plain", startIcon: StartIcon, showDisplayEndIcon, id: idProp, "aria-describedby": ariaDescribedByProp, "aria-errormessage": ariaErrorMessageProp, ...props }, ref) => {
|
|
164
170
|
const fieldCtx = useFieldContext();
|
|
165
|
-
const error = errorProp
|
|
166
|
-
const disabled = disabledProp
|
|
167
|
-
const
|
|
168
|
-
const
|
|
171
|
+
const error = useResolvedFieldInvalid(errorProp);
|
|
172
|
+
const disabled = useResolvedFieldDisabled(disabledProp);
|
|
173
|
+
const size = useResolvedFieldSize(sizeProp);
|
|
174
|
+
const resolvedMode = useResolvedFieldMode({ mode, disabled });
|
|
175
|
+
const variant = useResolvedFieldVariant(variantProp);
|
|
169
176
|
const iconSize = getIconSize(size);
|
|
170
177
|
const [value, setValue] = useControllable({
|
|
171
178
|
value: valueProp,
|
|
@@ -221,7 +228,7 @@ const NativeSelect = React.forwardRef(
|
|
|
221
228
|
error && ["border-error hover:border-error-hover", "focus-within:border-error focus-within:hover:border-error"],
|
|
222
229
|
className
|
|
223
230
|
),
|
|
224
|
-
style: { paddingRight: "
|
|
231
|
+
style: { paddingRight: "var(--field-px)" },
|
|
225
232
|
"data-field-mode": "edit",
|
|
226
233
|
"data-error": error ? "" : void 0,
|
|
227
234
|
children: [
|
|
@@ -257,12 +264,13 @@ const NativeSelect = React.forwardRef(
|
|
|
257
264
|
);
|
|
258
265
|
NativeSelect.displayName = "NativeSelect";
|
|
259
266
|
const CustomSelect = React.forwardRef(
|
|
260
|
-
({ mode
|
|
267
|
+
({ mode, variant: variantProp, error: errorProp = false, size: sizeProp, options, groups, value: valueProp, defaultValue, onChange, placeholder, className, disabled: disabledProp, clearable = false, display = "plain", startIcon: StartIcon, searchable = false, loading, minRows, defaultOpen = false, onOpenChange, selectedItemRenderer, showDisplayEndIcon, id: idProp, "aria-describedby": ariaDescribedByProp, "aria-errormessage": ariaErrorMessageProp, "aria-label": ariaLabel }, ref) => {
|
|
261
268
|
const fieldCtx = useFieldContext();
|
|
262
|
-
const error = errorProp
|
|
263
|
-
const disabled = disabledProp
|
|
264
|
-
const
|
|
265
|
-
const
|
|
269
|
+
const error = useResolvedFieldInvalid(errorProp);
|
|
270
|
+
const disabled = useResolvedFieldDisabled(disabledProp);
|
|
271
|
+
const size = useResolvedFieldSize(sizeProp);
|
|
272
|
+
const resolvedMode = useResolvedFieldMode({ mode, disabled });
|
|
273
|
+
const variant = useResolvedFieldVariant(variantProp);
|
|
266
274
|
const iconSize = getIconSize(size);
|
|
267
275
|
const [value, setValue] = useControllable({
|
|
268
276
|
value: valueProp,
|
|
@@ -359,16 +367,20 @@ const CustomSelect = React.forwardRef(
|
|
|
359
367
|
"cursor-pointer",
|
|
360
368
|
className
|
|
361
369
|
),
|
|
362
|
-
style: !isTextDisplay ? { paddingRight: "
|
|
370
|
+
style: !isTextDisplay ? { paddingRight: "var(--field-px)" } : void 0,
|
|
363
371
|
"data-field-mode": "edit",
|
|
364
372
|
"data-error": error ? "" : void 0,
|
|
365
373
|
onKeyDown: (e) => {
|
|
366
374
|
if (e.key === "Enter" || e.key === " ") {
|
|
367
|
-
if (!
|
|
375
|
+
if (!open) {
|
|
368
376
|
e.preventDefault();
|
|
369
377
|
setOpen(true);
|
|
370
378
|
}
|
|
371
379
|
}
|
|
380
|
+
if (e.key === "ArrowDown" && !open) {
|
|
381
|
+
e.preventDefault();
|
|
382
|
+
setOpen(true);
|
|
383
|
+
}
|
|
372
384
|
if (e.key === "Escape") setOpen(false);
|
|
373
385
|
},
|
|
374
386
|
children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.js","sources":["../../../src/components/Select/select.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// code-quality-allow: file-size — Select 含 3 子元件(NativeSelect/CustomSelect/ReadonlyDisplay)+ helpers + 4-mode renderer + Field SSOT consumption,split-into-files 會破壞 file-local helper closure\n// @renderer-symmetry-allow: pre-existing Select architecture(2026-05-08 D-path)— selectedItemRenderer 由 CustomSelectTriggerContent 消費(edit + trigger 模式),ReadonlyDisplay 走 separate bare-span path(no D-path)。display→edit unify deferred 下 cycle per spec contract (a) note。本 turn 只加 `nakedCellRowModeAlign` import,no behavior change to renderer symmetry contract。\nimport * as React from 'react'\nimport { X, ChevronDown } from 'lucide-react'\nimport type { LucideIcon } from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport type { FieldMode, FieldVariant } from '@/design-system/components/Field/field-types'\nimport { fieldWrapperStyles, bareInputStyles, EMPTY_DISPLAY, nakedCellRowModeAlign, fieldDisplayTextClass } from '@/design-system/components/Field/field-wrapper'\nimport { Tag } from '@/design-system/components/Tag/tag'\nimport { ItemInlineAction, ItemPrefix, ItemSuffix } from '@/design-system/patterns/element-anatomy/item-anatomy'\nimport { useFieldContext } from '@/design-system/components/Field/field-context'\nimport { SelectMenu, type SelectMenuOption } from '@/design-system/components/SelectMenu/select-menu'\nimport { useIsTouchDevice } from '@/design-system/hooks/use-is-touch-device'\nimport { useControllable } from '@/design-system/hooks/use-controllable'\nimport { ICON_SIZE } from '@/design-system/tokens/uiSize/icon-size'\n\n// ── Tag padding per size ────────────────────────────────────────────────────\nconst tagPadding: Record<string, string> = {\n sm: 'px-[calc((var(--field-height-sm)_-_1.25rem)_/_2)]',\n md: 'px-[calc((var(--field-height-md)_-_1.5rem)_/_2)]',\n lg: 'px-[calc((var(--field-height-lg)_-_1.5rem)_/_2)]',\n}\n\n// ── Display ─────────────────────────────────────────────────────────────────\n\n/**\n * Select 用的 option schema(2026-05-10 Issue 4 + post-prune unify):**explicit extends\n * SelectMenuOption(primitive SSOT)** — 任何 SelectMenuOption 加 field 都自動繼承,不會 drift。\n *\n * Why `extends SelectMenuOption`(per user 「全盤檢查避免下次又改壞或是偏移」要求):\n * - **schema SSOT 機械強制**:TypeScript inheritance 跟著 primitive 走,wrapper consumer 永遠\n * 拿得到 primitive 所有 surface field\n * - **Hook lint**(M30 `check_wrapper_primitive_schema_drift.sh`):grep `interface .*Option`\n * 未 `extends` SelectMenuOption / 同名重複 declare 直接 BLOCK\n *\n * Wrapper-only field(`tagVariant`)— Select 獨有 `display='tag'` 用,SelectMenu primitive 不該知道\n * 此 wrapper-only concern,所以 wrapper 層 extend 加上,不污染 primitive。\n *\n * 對齊 Polaris ChoiceList / Material Autocomplete / Carbon Dropdown 的 wrapper-vs-primitive\n * schema-extension idiom。\n */\nexport interface SelectOption extends SelectMenuOption {\n /** Tag 模式的顏色。只在 display='tag' 時生效,對應 Tag 的 variant。Wrapper-only。 */\n tagVariant?: string\n}\n\n/** 分組設定 — 對齊 SelectMenuGroupConfig SSOT */\nexport interface SelectGroupConfig {\n key: string\n label: string\n}\n\n// ── Types ───────────────────────────────────────────────────────────────────\n\nexport interface SelectProps\n extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'size' | 'value' | 'defaultValue' | 'onChange'> {\n mode?: FieldMode\n /** Field chrome variant. Default = context.variant ?? 'default'. Per-prop override. */\n variant?: FieldVariant\n error?: boolean\n size?: 'sm' | 'md' | 'lg'\n options: SelectOption[]\n /** 分組顯示(對齊 SelectMenu groups SSOT)。option.group 對應 groups[].key */\n groups?: SelectGroupConfig[]\n /** Controlled value(consumer 自管 state)。傳 `value` + `onChange` 表示 controlled mode。 */\n value?: string | null\n /** Uncontrolled 初始值(2026-05-21 D3 audit add per user verbatim「決策三照妳建議」+「都給我做到好」)。\n * 不傳 `value` 時 Select 自管 internal state,以 `defaultValue` 為初始值,選變更時 fire `onChange`\n * callback 通知 consumer(但 state 仍歸 Select)。對齊 Radix Select(`defaultValue`)+ shadcn Input\n * (`defaultValue`)+ React `<input>` dual-mode canonical。\n * 互斥規則:同時傳 `value` + `defaultValue` 走 controlled(value 勝),`defaultValue` 僅 first-mount 用。 */\n defaultValue?: string | null\n onChange?: (value: string) => void\n placeholder?: string\n clearable?: boolean\n display?: 'plain' | 'tag'\n startIcon?: LucideIcon\n /** 啟用搜尋(desktop 時 field 變 input,打字即篩選) */\n searchable?: boolean\n /** Loading state(2026-05-15 audit B fix per user verbatim「dropdown 隨時可開,讀取在 panel 中間 CircularProgress」)。\n * Forward 給 SelectMenu primitive SSOT;dropdown 開啟時取代 options 顯 CircularProgress + loadingText。\n * Trigger 不變(chevron 保留 user 隨時可點開)。對齊 Field family loading SSOT + Empty 元件 `<Empty icon={CircularProgress}/>` compose。*/\n loading?: boolean\n\n /** Menu list 最小列數(空狀態 / 選項少時的視覺一致 reserve)。預設 3 — 選項 < 3 時顯式縮(如 And/Or 兩選項) */\n minRows?: number\n /** Initial open state(uncontrolled)。對齊 Radix Popover defaultOpen canonical;DataTable cell-as-input\n * click → 1 step open menu(Airtable / Notion canonical),consumer pass `defaultOpen` 達成。\n * Note:Native Select(mobile)無 popover 概念,此 prop 僅 Custom path 生效。 */\n defaultOpen?: boolean\n /** open state 變更 callback(對齊 Radix Popover onOpenChange canonical)。\n * DataTable cell-as-input 用:open=false 時 cell 自動 exit edit mode(避免 dismiss 後卡住)。 */\n onOpenChange?: (open: boolean) => void\n /**\n * Display mode 顯 picker intrinsic end icon(2026-05-08 D path Phase 1)。\n * 預設 false:`mode=\"display\"` 純展示 bare span(向後相容)。\n * `variant=\"naked\" && mode=\"display\"` 場景(DataTable cell)opt-in 設 true → wrap 進\n * Field naked-display + 渲 ChevronDown ItemSuffix。**只 display mode 生效**;readonly /\n * disabled / edit 已有 Field wrapper + suffix(不受此 prop 影響)。\n * Authority:`data-table.spec.md:204` + `inline-action.spec.md:157`「Field family endAction(自動繼承)」。\n * @default false\n */\n showDisplayEndIcon?: boolean\n /**\n * Trigger 內「已選項目」客製 render(2026-05-07 v15.5)。\n *\n * 設了 → trigger 不走純文字 / Tag 預設 path,改用 consumer 提供的 ReactNode(收 selectedOpt)。\n * Searchable+open 仍走 input(搜尋優先)。Empty value(no selection)仍走 placeholder。\n *\n * 用例:PeoplePicker 用此 slot 把 single 選中的 person render 成 PersonDisplay\n * (avatar + name)而非純文字 label。對齊 PeoplePicker = Select wrapper SSOT。\n */\n selectedItemRenderer?: (selectedOpt: SelectOption) => React.ReactNode\n}\n\n// ── Icon / size helpers ─────────────────────────────────────────────────────\n// 2026-05-18 改 import ICON_SIZE SSOT(per user『做完』approval,消除 M17 違反)\nconst getIconSize = (size: string) => ICON_SIZE[size as 'sm' | 'md' | 'lg']\n\n// ── Shared sub-components ───────────────────────────────────────────────────\n\n/**\n * Inline clear button for Select trigger.\n * 共用 SSOT — Native + Custom 兩變體統一消費。差別僅 onClick 內是否 stopPropagation\n * (Custom trigger 是 combobox `<div>`,點 clear 不可冒泡到打開 menu;Native `<select>` 自有原生\n * 行為,不需 stopPropagation)。\n *\n * 消費的 SSOT:\n * - patterns/element-anatomy/item-anatomy.spec.md → ItemInlineAction(canonical row inline action)\n */\nfunction SelectClearButton({\n size,\n onClear,\n stopPropagation = false,\n}: {\n size: 'sm' | 'md' | 'lg'\n onClear: () => void\n stopPropagation?: boolean\n}) {\n return (\n <span className=\"relative z-10\">\n <ItemInlineAction\n size={size}\n action={{\n icon: X,\n label: '清除選取', // i18n-allow: DS default inline-action label\n onClick: stopPropagation ? (e) => { e?.stopPropagation(); onClear() } : () => onClear(),\n }}\n />\n </span>\n )\n}\nSelectClearButton.displayName = 'SelectClearButton'\n\n/**\n * Trigger content for CustomSelect — 三種顯示模式分支(searchable+open / text / tag)\n * 抽出降低 `CustomSelect` forwardRef body 長度;邏輯本質是純展示分流,無 hook / ref。\n */\nfunction CustomSelectTriggerContent({\n searchable,\n open,\n isTextDisplay,\n size,\n value,\n selectedLabel,\n selectedOpt,\n SelectedIcon,\n StartIcon,\n iconSize,\n placeholder,\n search,\n setSearch,\n inputRef,\n selectedItemRenderer,\n}: {\n searchable: boolean\n open: boolean\n isTextDisplay: boolean\n size: 'sm' | 'md' | 'lg'\n value?: string | null\n selectedLabel: string\n selectedOpt?: SelectOption\n SelectedIcon?: LucideIcon\n StartIcon?: LucideIcon\n iconSize: number\n placeholder?: string\n search: string\n setSearch: (v: string) => void\n inputRef: React.RefObject<HTMLInputElement | null>\n selectedItemRenderer?: (selectedOpt: SelectOption) => React.ReactNode\n}): React.ReactNode {\n // Searchable + open: 顯示搜尋 input\n // 2026-05-15 Bug 2 fix(Claude+Codex Step 5 比稿 consensus,user verbatim「就 A」):\n // 撤掉 native `<input placeholder=selectedLabel>` 不可靠 ellipsis renderer(browser-specific\n // placeholder painting,user 抓「placeholder 直接被截掉沒 ellipsis」)。改 span overlay:\n // - input native placeholder 限「搜尋…」/「請選擇人員」trigger empty hint(無 selectedLabel)\n // - sibling `<span aria-hidden pointer-events-none absolute inset-0 truncate>` 在 search='' 且\n // 有 selectedLabel 時 overlay 顯該人名(memory aid,truncate-with-ellipsis 可控)\n // 對齊 spec.md §B row 4「open + inline-search + 選 1 人 → input cursor + placeholder = 該人名 + ellipsis」。\n // a11y guard(per codex Q2 reply):input aria-label / accessible name 來自 field/label/aria-label,\n // **不**依賴 placeholder 當 label;overlay span aria-hidden + pointer-events-none。\n if (searchable && open) {\n const triggerEmptyPlaceholder = placeholder || '搜尋…' // i18n-allow: DS fallback\n const showSelectedOverlay = !search && selectedLabel\n return (\n <span className=\"relative flex-1 min-w-0 inline-flex items-center\">\n {StartIcon && <ItemPrefix><StartIcon size={iconSize} className=\"text-fg-muted pointer-events-none\" aria-hidden /></ItemPrefix>}\n <input\n ref={inputRef as React.RefObject<HTMLInputElement>}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n // Native placeholder 限 trigger empty hint(無 selectedLabel 時);若已 selected,留空交給 overlay span\n placeholder={showSelectedOverlay ? '' : triggerEmptyPlaceholder}\n className={cn(bareInputStyles, 'cursor-text')}\n autoFocus\n />\n {showSelectedOverlay && (\n // 2026-05-16 Bug B 真 root cause fix(Claude+Codex M31 Step 5 比稿 consensus,user verbatim\n // 「修了一百次還沒好」+ codex cite W3C CSS Overflow / MDN / Mozilla Bug 972664#c1):\n // 原 `inline-flex items-center truncate` 套同一 span,text 變 anonymous flex item →\n // `text-overflow:ellipsis` 對 anonymous item 不 styleable → ellipsis dots 不可見(text 純 clip)。\n // 對齊 `person-display.tsx:148` 既有 DS canonical:outer flex container + inner truncate 真實 box。\n // DS-wide grep 29 個 truncate 都遵此 pattern,只本處違反 — 修齊。\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-0 flex items-center text-fg-muted\"\n >\n <span className=\"min-w-0 flex-1 truncate\">{selectedLabel}</span>\n </span>\n )}\n </span>\n )\n }\n // **selectedItemRenderer slot**(2026-05-07 v15.5):consumer 客製 selected display(e.g.\n // PeoplePicker 接 PersonDisplay)。優先於 isTextDisplay / Tag 預設 path,但 empty value\n // 仍走 placeholder。對齊 PeoplePicker = Select wrapper SSOT。\n if (selectedItemRenderer && value && selectedOpt) {\n return (\n <>\n {StartIcon && <ItemPrefix><StartIcon size={iconSize} className=\"text-fg-muted pointer-events-none\" aria-hidden /></ItemPrefix>}\n {/* 2026-05-14 item-anatomy SSOT fix(per codex H2 propagation 斷點):加 nakedCellRowModeAlign\n → autoRowHeight cell 內 selected renderer 也對齊 first-line,不再 vertical-center 整 row。 */}\n <span className={cn(\"flex-1 min-w-0 inline-flex items-center\", nakedCellRowModeAlign)}>{selectedItemRenderer(selectedOpt)}</span>\n </>\n )\n }\n // Text display: 純文字 + optional value icon\n if (isTextDisplay) {\n return (\n <>\n {StartIcon && <ItemPrefix><StartIcon size={iconSize} className=\"text-fg-muted pointer-events-none\" aria-hidden /></ItemPrefix>}\n {!StartIcon && SelectedIcon && value && <ItemPrefix><SelectedIcon size={iconSize} className=\"pointer-events-none\" aria-hidden /></ItemPrefix>}\n <span className={cn('flex-1 min-w-0 truncate', !value && 'text-fg-muted')}>\n {value ? selectedLabel : (placeholder ?? '選擇…')}\n </span>\n </>\n )\n }\n // Tag display: 用 option 的 tagVariant\n return (\n <>\n {value && selectedOpt?.tagVariant\n ? <Tag size={size} color={selectedOpt.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral'} className=\"shrink-0 pointer-events-none\">{selectedLabel}</Tag>\n : value\n ? <Tag size={size} className=\"shrink-0 pointer-events-none\">{selectedLabel}</Tag>\n : <span className=\"text-fg-muted\">{placeholder ?? '選擇…'}</span>\n }\n <span className=\"flex-1\" />\n </>\n )\n}\nCustomSelectTriggerContent.displayName = 'CustomSelectTriggerContent'\n\n// ── Shared readonly/disabled/display render ─────────────────────────────────\nfunction ReadonlyDisplay({\n mode, variant: variantProp, size, options, value, display, startIcon: StartIcon, className, placeholder, showDisplayEndIcon,\n}: Pick<SelectProps, 'mode' | 'variant' | 'size' | 'options' | 'value' | 'display' | 'startIcon' | 'className' | 'placeholder' | 'showDisplayEndIcon'>) {\n const resolvedMode = mode ?? 'readonly'\n const variant = variantProp ?? 'default'\n const sz = size ?? 'md'\n const iconSize = getIconSize(sz)\n const label = options?.find(o => o.value === value)?.label ?? value\n const iconColor = resolvedMode === 'disabled' ? 'text-fg-disabled' : 'text-fg-muted'\n const isTextDisplay = display !== 'tag'\n // K10+K14 fix(2026-05-04):disabled mode placeholder/empty 顯示色 → fg-disabled(neutral-6),非 fg-muted(neutral-7)\n // user canonical:disabled 顯著性優於 muted。同時 plain mode 必須 respect placeholder prop(之前忽略 = bug)\n const emptyColorCls = resolvedMode === 'disabled' ? 'text-fg-disabled' : 'text-fg-muted'\n const emptyText = placeholder ?? EMPTY_DISPLAY\n\n // mode='display':2 path(2026-05-08 D path Phase 1 Select canary)\n // ❌ 預設(無 showDisplayEndIcon):純內容輸出 bare span/Tag(原行為,backward compat)\n // 對齊原 SelectDisplay sub-component(retired)。readonly / disabled 仍走下方 fieldWrapperStyles。\n // ✅ showDisplayEndIcon=true(DataTable cell opt-in):Field naked-display wrapper +\n // ChevronDown ItemSuffix。SSOT canonical 跟 readonly/edit/disabled mode 同 DOM 結構。\n // Authority: data-table.spec.md:204 + inline-action.spec.md:157「Field family endAction」\n if (resolvedMode === 'display') {\n if (!showDisplayEndIcon) {\n // 2026-05-14 I2 fix(spec contract (e) display typography canonical):bare span 必套\n // `fieldDisplayTextClass(sz)`(sm/md→text-body,lg→text-body-lg)— 對齊跨 Field\n // family display 視覺尺寸統一。\n if (!value) return <span className={cn(fieldDisplayTextClass(sz), 'text-fg-muted', className)}>{emptyText}</span>\n if (isTextDisplay) return <span className={cn(fieldDisplayTextClass(sz), 'truncate', className)}>{label}</span>\n const selOpt = options?.find(o => o.value === value)\n const tVariant = selOpt?.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral' | undefined\n return <Tag size={sz} color={tVariant} className={className}>{label}</Tag>\n }\n // D path opt-in: Field naked-display wrapper + ItemSuffix ChevronDown\n const selOpt = options?.find(o => o.value === value)\n const tVariant = selOpt?.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral' | undefined\n return (\n <div\n className={cn(fieldWrapperStyles({ mode: 'display', variant, size: sz }), value && !isTextDisplay && tagPadding[sz], className)}\n data-field-mode=\"display\"\n >\n {isTextDisplay ? (\n <span className={cn(bareInputStyles, 'flex-1 min-w-0 truncate', !value && emptyColorCls)}>\n {value ? label : emptyText}\n </span>\n ) : value ? (\n <Tag size={sz} color={tVariant}>{label}</Tag>\n ) : (\n <span className={cn('flex-1 min-w-0', emptyColorCls)}>{emptyText}</span>\n )}\n <ItemSuffix><ChevronDown size={iconSize} className=\"text-fg-muted pointer-events-none\" aria-hidden /></ItemSuffix>\n </div>\n )\n }\n\n if (isTextDisplay) {\n return (\n <div className={cn(fieldWrapperStyles({ mode: resolvedMode, variant, size: sz }), className)} data-field-mode={resolvedMode}>\n {StartIcon && <ItemPrefix><StartIcon size={iconSize} className={cn('pointer-events-none', iconColor)} aria-hidden /></ItemPrefix>}\n <span className={cn('flex-1 min-w-0 truncate', resolvedMode === 'disabled' && 'text-fg-disabled')}>\n {value ? label : <span className={emptyColorCls}>{emptyText}</span>}\n </span>\n </div>\n )\n }\n\n const selectedOpt = options?.find(o => o.value === value)\n const tagVariant = selectedOpt?.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral' | undefined\n\n return (\n <div className={cn(fieldWrapperStyles({ mode: resolvedMode, variant, size: sz }), value && tagPadding[sz], className)} data-field-mode={resolvedMode}>\n {value ? <Tag size={sz} color={tagVariant}>{label}</Tag> : <span className={emptyColorCls}>{emptyText}</span>}\n </div>\n )\n}\n\n// ── Native Select (mobile) ─────────────────────────────────────────────\n\n// code-quality-allow: long-function — foundational composite main body — 拆 sub-fn 會複雜化 local state / ref / context binding\nconst NativeSelect = React.forwardRef<HTMLSelectElement, SelectProps>(\n ({ mode = 'edit', variant: variantProp, error: errorProp = false, size = 'md', options, value: valueProp, defaultValue, onChange, placeholder, className, disabled: disabledProp, clearable = false, display = 'plain', startIcon: StartIcon, showDisplayEndIcon, id: idProp, 'aria-describedby': ariaDescribedByProp, 'aria-errormessage': ariaErrorMessageProp, ...props }, ref) => {\n const fieldCtx = useFieldContext()\n const error = errorProp || (fieldCtx?.invalid ?? false)\n const disabled = disabledProp ?? fieldCtx?.disabled\n const resolvedMode = disabled ? 'disabled' : mode\n const variant: FieldVariant = variantProp ?? fieldCtx?.variant ?? 'default'\n const iconSize = getIconSize(size)\n // 2026-05-21 D3 audit:Controlled / Uncontrolled dual-mode via 既有 SSOT hook(同 CustomSelect)\n const [value, setValue] = useControllable<string | null>({\n value: valueProp,\n defaultValue: defaultValue ?? null,\n onChange: onChange ? (next) => onChange(next ?? '') : undefined,\n })\n const handleNativeChange = (v: string) => setValue(v)\n const showClear = clearable && value && resolvedMode === 'edit'\n const isTextDisplay = display === 'plain'\n const selectRef = React.useRef<HTMLSelectElement | null>(null)\n const setSelectRef = React.useCallback((el: HTMLSelectElement | null) => {\n selectRef.current = el\n if (typeof ref === 'function') ref(el)\n else if (ref) (ref as React.MutableRefObject<HTMLSelectElement | null>).current = el\n }, [ref])\n\n if (resolvedMode !== 'edit') {\n return <ReadonlyDisplay mode={resolvedMode} variant={variant} size={size} options={options} value={value} display={display} startIcon={StartIcon} className={className} placeholder={placeholder} showDisplayEndIcon={showDisplayEndIcon} />\n }\n\n const selectEl = (\n <select\n ref={setSelectRef}\n id={idProp ?? fieldCtx?.id}\n value={value ?? ''}\n onChange={(e) => handleNativeChange(e.target.value)}\n disabled={disabled}\n aria-invalid={error || undefined}\n aria-required={fieldCtx?.required || undefined}\n aria-describedby={ariaDescribedByProp ?? fieldCtx?.descriptionId}\n aria-errormessage={ariaErrorMessageProp ?? (error ? fieldCtx?.errorId : undefined)}\n className={cn(bareInputStyles, 'cursor-pointer appearance-none', !value && 'text-fg-muted', !isTextDisplay && value && 'absolute inset-0 w-full h-full opacity-0 z-0')}\n {...props}\n >\n {placeholder && <option value=\"\" disabled>{placeholder}</option>}\n {options.map(opt => <option key={opt.value} value={opt.value}>{opt.label}</option>)}\n </select>\n )\n\n const clearEl = showClear ? (\n <SelectClearButton size={size ?? 'md'} onClear={() => handleNativeChange('')} />\n ) : null\n\n const chevronEl = (\n <ItemSuffix className=\"relative z-10 pointer-events-none\">\n <ChevronDown size={iconSize} className=\"text-fg-muted\" aria-hidden />\n </ItemSuffix>\n )\n const selectedOpt = options?.find(o => o.value === value)\n const label = selectedOpt?.label ?? value\n const nativeTagVariant = selectedOpt?.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral' | undefined\n const SelectedOptIcon = selectedOpt?.icon\n\n if (!isTextDisplay) {\n return (\n <div className={cn(fieldWrapperStyles({ mode: 'edit', variant: variant, size }), value && tagPadding[size], 'relative',\n error && ['border-error hover:border-error-hover', 'focus-within:border-error focus-within:hover:border-error'], className)}\n style={{ paddingRight: '0.75rem' }} data-field-mode=\"edit\" data-error={error ? '' : undefined}>\n {value ? <Tag size={size} color={nativeTagVariant} className=\"shrink-0 relative z-10 pointer-events-none\">{label}</Tag> : <span className=\"text-fg-muted\">{placeholder ?? '選擇...'}</span>}\n {selectEl}\n <span className=\"flex-1\" />\n {clearEl}\n {chevronEl}\n </div>\n )\n }\n\n return (\n <div className={cn(fieldWrapperStyles({ mode: 'edit', variant: variant, size }),\n error && ['border-error hover:border-error-hover', 'focus-within:border-error focus-within:hover:border-error'], className)}\n data-field-mode=\"edit\" data-error={error ? '' : undefined}>\n {StartIcon && <ItemPrefix><StartIcon size={iconSize} className=\"text-fg-muted pointer-events-none\" aria-hidden /></ItemPrefix>}\n {!StartIcon && SelectedOptIcon && value && <ItemPrefix><SelectedOptIcon size={iconSize} className=\"pointer-events-none\" aria-hidden /></ItemPrefix>}\n {selectEl}\n {clearEl}\n {chevronEl}\n </div>\n )\n }\n)\nNativeSelect.displayName = 'NativeSelect'\n\n// ── Custom Select (desktop — consumes SelectMenu) ────────────────────────\n\n// code-quality-allow: long-function — foundational composite main body — 拆 sub-fn 會複雜化 local state / ref / context binding\nconst CustomSelect = React.forwardRef<HTMLDivElement, SelectProps>(\n ({ mode = 'edit', variant: variantProp, error: errorProp = false, size = 'md', options, groups, value: valueProp, defaultValue, onChange, placeholder, className, disabled: disabledProp, clearable = false, display = 'plain', startIcon: StartIcon, searchable = false, loading, minRows, defaultOpen = false, onOpenChange, selectedItemRenderer, showDisplayEndIcon, id: idProp, 'aria-describedby': ariaDescribedByProp, 'aria-errormessage': ariaErrorMessageProp, 'aria-label': ariaLabel }, ref) => {\n const fieldCtx = useFieldContext()\n const error = errorProp || (fieldCtx?.invalid ?? false)\n const disabled = disabledProp ?? fieldCtx?.disabled\n const resolvedMode = disabled ? 'disabled' : mode\n const variant: FieldVariant = variantProp ?? fieldCtx?.variant ?? 'default'\n const iconSize = getIconSize(size)\n // 2026-05-21 D3 audit:Controlled / Uncontrolled dual-mode via 既有 SSOT hook(M17 對齊,取代自刻 isControlled pattern)。\n // Phase B codex 抓:之前 Custom clear 走 `onChange?.('')` 沒 setInternalValue → uncontrolled clear 失效。useControllable 統一 setter 修。\n // onChange forward coerce null → ''(consumer 簽名 `(value: string) => void`,null 是 internal empty signal)。\n const [value, setValue] = useControllable<string | null>({\n value: valueProp,\n defaultValue: defaultValue ?? null,\n onChange: onChange ? (next) => onChange(next ?? '') : undefined,\n })\n const showClear = clearable && value && resolvedMode === 'edit'\n const isTextDisplay = display === 'plain'\n\n const [open, setOpen] = React.useState(defaultOpen)\n const [search, setSearch] = React.useState('')\n const inputRef = React.useRef<HTMLInputElement>(null)\n\n // 關閉時清搜尋\n React.useEffect(() => { if (!open) setSearch('') }, [open])\n\n // **React #310 fix(2026-05-04)**:所有 hooks 必在任何 early return 前 call,\n // 否則 disabled→edit 切換時 hook count 變動 → React 死亡。\n // 原本 useMemo(L280, L291) 在 early return 之後 = latent bug,K13 觸發(filter Op 從 disabled\n // 變 edit 當 user 選欄位)。修法:把所有 useMemo 提到 early return 之前。\n const selectedOpt = options?.find(o => o.value === value)\n // 2026-05-06 v9.1:value 不在 options 也要顯示原值(不沉默丟失)。原 fallback `''` 致\n // SelectCell 開 edit 時若 cell value 不在當前 options(e.g. 上游資料漂移 / options async\n // 後到 / 跨 dataset),trigger 顯示空白 — user 報「value 不見」。對齊 ReadonlyDisplay 同\n // 級 fallback `?? value`。\n const selectedLabel = selectedOpt?.label ?? value ?? ''\n const SelectedIcon = selectedOpt?.icon\n // ── 過濾選項 ──\n const filteredOptions = searchable && search\n ? options.filter(o => o.label.toLowerCase().includes(search.toLowerCase()))\n : options\n // ── 轉換 SelectOption → SelectMenuOption(必在 early return 前) ──\n // Issue 4(2026-05-10):forward avatar / description / disabled SSOT(per SelectMenuOption schema)。\n const menuOptions: SelectMenuOption[] = React.useMemo(\n () => filteredOptions.map(opt => ({\n value: opt.value,\n label: opt.label,\n icon: isTextDisplay ? opt.icon : undefined,\n avatar: opt.avatar,\n description: opt.description,\n disabled: opt.disabled,\n group: opt.group,\n })),\n [filteredOptions, isTextDisplay]\n )\n // ── Tag display 自訂 label 渲染(必在 early return 前) ──\n const renderLabel = React.useMemo(() => {\n if (isTextDisplay) return undefined\n return (menuOpt: SelectMenuOption) => {\n const srcOpt = options.find(o => o.value === menuOpt.value)\n if (srcOpt?.tagVariant) {\n return <Tag size={size} color={srcOpt.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral'}>{menuOpt.label}</Tag>\n }\n return menuOpt.label\n }\n }, [isTextDisplay, options, size])\n\n // **React #310 fix v2(2026-05-04)**:`handleValueChange` useCallback 也必在 early return 前\n // 原本 L306(early return 後)→ disabled→edit 切換時 hook count 仍變 → #310 持續\n // 2026-05-21 D3:`useControllable` 統一 controlled / uncontrolled state + onChange forward,不再手動 if-branch。\n const handleValueChange = React.useCallback(\n (newValue: string | string[]) => {\n setValue(Array.isArray(newValue) ? newValue[0] : newValue)\n },\n [setValue]\n )\n\n // Early return AFTER all hooks(disabled / readonly / display mode 走 ReadonlyDisplay)\n if (resolvedMode !== 'edit') {\n return <ReadonlyDisplay mode={resolvedMode} variant={variant} size={size} options={options} value={value} display={display} startIcon={StartIcon} className={className} placeholder={placeholder} showDisplayEndIcon={showDisplayEndIcon} />\n }\n\n // 2026-05-21 D3 Phase B codex 抓:Custom clear 用 setValue 不直接 onChange,uncontrolled clear 才能真清 internal state。\n const clearEl = showClear ? (\n <SelectClearButton size={size ?? 'md'} onClear={() => setValue('')} stopPropagation />\n ) : null\n\n const chevronEl = (\n <ItemSuffix>\n <ChevronDown size={iconSize} className={cn('text-fg-muted transition-transform', open && 'rotate-180')} aria-hidden />\n </ItemSuffix>\n )\n\n const triggerContent = (\n <CustomSelectTriggerContent\n searchable={searchable}\n open={open}\n isTextDisplay={isTextDisplay}\n size={size}\n value={value}\n selectedLabel={selectedLabel}\n selectedOpt={selectedOpt}\n SelectedIcon={SelectedIcon}\n StartIcon={StartIcon}\n iconSize={iconSize}\n placeholder={placeholder}\n search={search}\n setSearch={setSearch}\n inputRef={inputRef}\n selectedItemRenderer={selectedItemRenderer}\n />\n )\n\n // hooks(filteredOptions / menuOptions / renderLabel / handleValueChange)已全 hoist(React #310 fix v2)\n\n const trigger = (\n <div\n ref={ref}\n id={idProp ?? fieldCtx?.id}\n role=\"combobox\"\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-label={ariaLabel}\n aria-invalid={error || undefined}\n aria-required={fieldCtx?.required || undefined}\n aria-describedby={ariaDescribedByProp ?? fieldCtx?.descriptionId}\n aria-errormessage={ariaErrorMessageProp ?? (error ? fieldCtx?.errorId : undefined)}\n tabIndex={0}\n className={cn(\n fieldWrapperStyles({ mode: 'edit', variant: variant, size }),\n !isTextDisplay && value && !searchable && tagPadding[size],\n // 2026-05-06 v13.3 SSOT retire:per-control `open && 'border-primary'` 移除。Field default\n // state machine `data-[state=open]:border-border-hover`(灰深)處理 open;若 trigger focused\n // (Radix focus on open),focus-within:!border-primary 強制勝出顯藍。focus dominates everything\n // 全 DS 一致(Material/Polaris/Ant 共識),改 Field default 一處全 control 自動跟動。\n error && ['border-error hover:border-error-hover', 'focus-within:border-error focus-within:hover:border-error'],\n 'cursor-pointer',\n className,\n )}\n style={!isTextDisplay ? { paddingRight: '0.75rem' } : undefined}\n data-field-mode=\"edit\"\n data-error={error ? '' : undefined}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n if (!searchable) { e.preventDefault(); setOpen(true) }\n }\n if (e.key === 'Escape') setOpen(false)\n }}\n >\n {triggerContent}\n {clearEl}\n {chevronEl}\n </div>\n )\n\n return (\n <SelectMenu\n options={menuOptions}\n groups={groups}\n value={value ?? null}\n onValueChange={handleValueChange}\n searchable={false}\n loading={loading}\n size={size}\n minRows={minRows}\n open={open}\n onOpenChange={(o) => { setOpen(o); onOpenChange?.(o) }}\n renderLabel={renderLabel}\n onOpenAutoFocus={searchable ? (e) => { e.preventDefault(); inputRef.current?.focus() } : undefined}\n >\n {trigger}\n </SelectMenu>\n )\n }\n)\nCustomSelect.displayName = 'CustomSelect'\n\n// ── Public component(自動偵測 mobile / desktop)──────────────────────────────\n\nconst Select = React.forwardRef<HTMLSelectElement | HTMLDivElement, SelectProps>(\n (props, ref) => {\n const isMobile = useIsTouchDevice()\n\n if (isMobile) {\n return <NativeSelect ref={ref as React.Ref<HTMLSelectElement>} {...props} />\n }\n\n return <CustomSelect ref={ref as React.Ref<HTMLDivElement>} {...props} />\n }\n)\nSelect.displayName = 'Select'\n\n// Story auto-compile metadata — Phase 1 mechanical migration(2026-04-24)\n// Phase 2 fill needed: purpose descriptions + when rationale + world-class refs\nexport const selectMeta = {\n component: 'Select',\n family: 4,\n variants: {\n\n },\n sizes: {\n\n },\n states: ['default', 'hover', 'active', 'focus-visible', 'disabled'],\n tokens: {\n bg: [],\n fg: ['text-fg-disabled', 'text-fg-muted'],\n ring: [],\n },\n} as const\n\nexport { Select }\n"],"names":["selOpt","tVariant"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"select.js","sources":["../../../src/components/Select/select.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// code-quality-allow: file-size — Select 含 3 子元件(NativeSelect/CustomSelect/ReadonlyDisplay)+ helpers + 4-mode renderer + Field SSOT consumption,split-into-files 會破壞 file-local helper closure\n// @renderer-symmetry-allow: pre-existing Select architecture(2026-05-08 D-path)— selectedItemRenderer 由 CustomSelectTriggerContent 消費(edit + trigger 模式),ReadonlyDisplay 走 separate bare-span path(no D-path)。display→edit unify deferred 下 cycle per spec contract (a) note。本 turn 只加 `nakedCellRowModeAlign` import,no behavior change to renderer symmetry contract。\nimport * as React from 'react'\nimport { X, ChevronDown } from 'lucide-react'\nimport type { LucideIcon } from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport type { FieldMode, FieldVariant } from '@/design-system/components/Field/field-types'\nimport { fieldWrapperStyles, bareInputStyles, EMPTY_DISPLAY, nakedCellRowModeAlign, fieldDisplayTextClass } from '@/design-system/components/Field/field-wrapper'\nimport { Tag } from '@/design-system/components/Tag/tag'\nimport { ItemInlineAction, ItemPrefix, ItemSuffix } from '@/design-system/patterns/element-anatomy/item-anatomy'\nimport { useFieldContext, useResolvedFieldSize, useResolvedFieldDisabled, useResolvedFieldMode, useResolvedFieldVariant, useResolvedFieldInvalid } from '@/design-system/components/Field/field-context'\nimport { SelectMenu, type SelectMenuOption } from '@/design-system/components/SelectMenu/select-menu'\nimport { useIsTouchDevice } from '@/design-system/hooks/use-is-touch-device'\nimport { useControllable } from '@/design-system/hooks/use-controllable'\nimport { ICON_SIZE } from '@/design-system/tokens/uiSize/icon-size'\n\n// ── Tag padding per size ────────────────────────────────────────────────────\nconst tagPadding: Record<string, string> = {\n sm: 'px-[calc((var(--field-height-sm)_-_1.25rem)_/_2)]',\n md: 'px-[calc((var(--field-height-md)_-_1.5rem)_/_2)]',\n lg: 'px-[calc((var(--field-height-lg)_-_1.5rem)_/_2)]',\n}\n\n// ── Display ─────────────────────────────────────────────────────────────────\n\n/**\n * Select 用的 option schema(2026-05-10 Issue 4 + post-prune unify):**explicit extends\n * SelectMenuOption(primitive SSOT)** — 任何 SelectMenuOption 加 field 都自動繼承,不會 drift。\n *\n * Why `extends SelectMenuOption`(per user 「全盤檢查避免下次又改壞或是偏移」要求):\n * - **schema SSOT 機械強制**:TypeScript inheritance 跟著 primitive 走,wrapper consumer 永遠\n * 拿得到 primitive 所有 surface field\n * - **Hook lint**(M30 `check_wrapper_primitive_schema_drift.sh`):grep `interface .*Option`\n * 未 `extends` SelectMenuOption / 同名重複 declare 直接 BLOCK\n *\n * Wrapper-only field(`tagVariant`)— Select 獨有 `display='tag'` 用,SelectMenu primitive 不該知道\n * 此 wrapper-only concern,所以 wrapper 層 extend 加上,不污染 primitive。\n *\n * 對齊 Polaris ChoiceList / Material Autocomplete / Carbon Dropdown 的 wrapper-vs-primitive\n * schema-extension idiom。\n */\nexport interface SelectOption extends SelectMenuOption {\n /** Tag 模式的顏色。只在 display='tag' 時生效,對應 Tag 的 variant。Wrapper-only。 */\n tagVariant?: string\n}\n\n/** 分組設定 — 對齊 SelectMenuGroupConfig SSOT */\nexport interface SelectGroupConfig {\n key: string\n label: string\n}\n\n// ── Types ───────────────────────────────────────────────────────────────────\n\nexport interface SelectProps\n extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'size' | 'value' | 'defaultValue' | 'onChange'> {\n mode?: FieldMode\n /** Field chrome variant. Default = context.variant ?? 'default'. Per-prop override. */\n variant?: FieldVariant\n error?: boolean\n size?: 'sm' | 'md' | 'lg'\n options: SelectOption[]\n /** 分組顯示(對齊 SelectMenu groups SSOT)。option.group 對應 groups[].key */\n groups?: SelectGroupConfig[]\n /** Controlled value(consumer 自管 state)。傳 `value` + `onChange` 表示 controlled mode。 */\n value?: string | null\n /** Uncontrolled 初始值(2026-05-21 D3 audit add per user verbatim「決策三照妳建議」+「都給我做到好」)。\n * 不傳 `value` 時 Select 自管 internal state,以 `defaultValue` 為初始值,選變更時 fire `onChange`\n * callback 通知 consumer(但 state 仍歸 Select)。對齊 Radix Select(`defaultValue`)+ shadcn Input\n * (`defaultValue`)+ React `<input>` dual-mode canonical。\n * 互斥規則:同時傳 `value` + `defaultValue` 走 controlled(value 勝),`defaultValue` 僅 first-mount 用。 */\n defaultValue?: string | null\n onChange?: (value: string) => void\n placeholder?: string\n clearable?: boolean\n display?: 'plain' | 'tag'\n startIcon?: LucideIcon\n /** 啟用搜尋(desktop 時 field 變 input,打字即篩選) */\n searchable?: boolean\n /** Loading state(2026-05-15 audit B fix per user verbatim「dropdown 隨時可開,讀取在 panel 中間 CircularProgress」)。\n * Forward 給 SelectMenu primitive SSOT;dropdown 開啟時取代 options 顯 CircularProgress + loadingText。\n * Trigger 不變(chevron 保留 user 隨時可點開)。對齊 Field family loading SSOT + Empty 元件 `<Empty icon={CircularProgress}/>` compose。*/\n loading?: boolean\n\n /** Menu list 最小列數(空狀態 / 選項少時的視覺一致 reserve)。預設 3 — 選項 < 3 時顯式縮(如 And/Or 兩選項) */\n minRows?: number\n /** Initial open state(uncontrolled)。對齊 Radix Popover defaultOpen canonical;DataTable cell-as-input\n * click → 1 step open menu(Airtable / Notion canonical),consumer pass `defaultOpen` 達成。\n * Note:Native Select(mobile)無 popover 概念,此 prop 僅 Custom path 生效。 */\n defaultOpen?: boolean\n /** open state 變更 callback(對齊 Radix Popover onOpenChange canonical)。\n * DataTable cell-as-input 用:open=false 時 cell 自動 exit edit mode(避免 dismiss 後卡住)。 */\n onOpenChange?: (open: boolean) => void\n /**\n * Display mode 顯 picker intrinsic end icon(2026-05-08 D path Phase 1)。\n * 預設 false:`mode=\"display\"` 純展示 bare span(向後相容)。\n * `variant=\"naked\" && mode=\"display\"` 場景(DataTable cell)opt-in 設 true → wrap 進\n * Field naked-display + 渲 ChevronDown ItemSuffix。**只 display mode 生效**;readonly /\n * disabled / edit 已有 Field wrapper + suffix(不受此 prop 影響)。\n * Authority:`data-table.spec.md:204` + `inline-action.spec.md:157`「Field family endAction(自動繼承)」。\n * @default false\n */\n showDisplayEndIcon?: boolean\n /**\n * Trigger 內「已選項目」客製 render(2026-05-07 v15.5)。\n *\n * 設了 → trigger 不走純文字 / Tag 預設 path,改用 consumer 提供的 ReactNode(收 selectedOpt)。\n * Searchable+open 仍走 input(搜尋優先)。Empty value(no selection)仍走 placeholder。\n *\n * 用例:PeoplePicker 用此 slot 把 single 選中的 person render 成 PersonDisplay\n * (avatar + name)而非純文字 label。對齊 PeoplePicker = Select wrapper SSOT。\n */\n selectedItemRenderer?: (selectedOpt: SelectOption) => React.ReactNode\n}\n\n// ── Icon / size helpers ─────────────────────────────────────────────────────\n// 2026-05-18 改 import ICON_SIZE SSOT(per user『做完』approval,消除 M17 違反)\nconst getIconSize = (size: string) => ICON_SIZE[size as 'sm' | 'md' | 'lg']\n\n// ── Shared sub-components ───────────────────────────────────────────────────\n\n/**\n * Inline clear button for Select trigger.\n * 共用 SSOT — Native + Custom 兩變體統一消費。差別僅 onClick 內是否 stopPropagation\n * (Custom trigger 是 combobox `<div>`,點 clear 不可冒泡到打開 menu;Native `<select>` 自有原生\n * 行為,不需 stopPropagation)。\n *\n * 消費的 SSOT:\n * - patterns/element-anatomy/item-anatomy.spec.md → ItemInlineAction(canonical row inline action)\n */\nfunction SelectClearButton({\n size,\n onClear,\n stopPropagation = false,\n}: {\n size: 'sm' | 'md' | 'lg'\n onClear: () => void\n stopPropagation?: boolean\n}) {\n return (\n <span className=\"relative z-10\">\n <ItemInlineAction\n size={size}\n action={{\n icon: X,\n label: '清除選取', // i18n-allow: DS default inline-action label\n onClick: stopPropagation ? (e) => { e?.stopPropagation(); onClear() } : () => onClear(),\n }}\n />\n </span>\n )\n}\nSelectClearButton.displayName = 'SelectClearButton'\n\n/**\n * Trigger content for CustomSelect — 三種顯示模式分支(searchable+open / text / tag)\n * 抽出降低 `CustomSelect` forwardRef body 長度;邏輯本質是純展示分流,無 hook / ref。\n */\nfunction CustomSelectTriggerContent({\n searchable,\n open,\n isTextDisplay,\n size,\n value,\n selectedLabel,\n selectedOpt,\n SelectedIcon,\n StartIcon,\n iconSize,\n placeholder,\n search,\n setSearch,\n inputRef,\n selectedItemRenderer,\n}: {\n searchable: boolean\n open: boolean\n isTextDisplay: boolean\n size: 'sm' | 'md' | 'lg'\n value?: string | null\n selectedLabel: string\n selectedOpt?: SelectOption\n SelectedIcon?: LucideIcon\n StartIcon?: LucideIcon\n iconSize: number\n placeholder?: string\n search: string\n setSearch: (v: string) => void\n inputRef: React.RefObject<HTMLInputElement | null>\n selectedItemRenderer?: (selectedOpt: SelectOption) => React.ReactNode\n}): React.ReactNode {\n // Searchable + open: 顯示搜尋 input\n // 2026-05-15 Bug 2 fix(Claude+Codex Step 5 比稿 consensus,user verbatim「就 A」):\n // 撤掉 native `<input placeholder=selectedLabel>` 不可靠 ellipsis renderer(browser-specific\n // placeholder painting,user 抓「placeholder 直接被截掉沒 ellipsis」)。改 span overlay:\n // - input native placeholder 限「搜尋…」/「請選擇人員」trigger empty hint(無 selectedLabel)\n // - sibling `<span aria-hidden pointer-events-none absolute inset-0 truncate>` 在 search='' 且\n // 有 selectedLabel 時 overlay 顯該人名(memory aid,truncate-with-ellipsis 可控)\n // 對齊 spec.md §B row 4「open + inline-search + 選 1 人 → input cursor + placeholder = 該人名 + ellipsis」。\n // a11y guard(per codex Q2 reply):input aria-label / accessible name 來自 field/label/aria-label,\n // **不**依賴 placeholder 當 label;overlay span aria-hidden + pointer-events-none。\n if (searchable && open) {\n const triggerEmptyPlaceholder = placeholder || '搜尋…' // i18n-allow: DS fallback\n const showSelectedOverlay = !search && selectedLabel\n return (\n <span className=\"relative flex-1 min-w-0 inline-flex items-center\">\n {StartIcon && <ItemPrefix><StartIcon size={iconSize} className=\"text-fg-muted pointer-events-none\" aria-hidden /></ItemPrefix>}\n <input\n ref={inputRef as React.RefObject<HTMLInputElement>}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n // Native placeholder 限 trigger empty hint(無 selectedLabel 時);若已 selected,留空交給 overlay span\n placeholder={showSelectedOverlay ? '' : triggerEmptyPlaceholder}\n className={cn(bareInputStyles, 'cursor-text')}\n autoFocus\n />\n {showSelectedOverlay && (\n // 2026-05-16 Bug B 真 root cause fix(Claude+Codex M31 Step 5 比稿 consensus,user verbatim\n // 「修了一百次還沒好」+ codex cite W3C CSS Overflow / MDN / Mozilla Bug 972664#c1):\n // 原 `inline-flex items-center truncate` 套同一 span,text 變 anonymous flex item →\n // `text-overflow:ellipsis` 對 anonymous item 不 styleable → ellipsis dots 不可見(text 純 clip)。\n // 對齊 `person-display.tsx:148` 既有 DS canonical:outer flex container + inner truncate 真實 box。\n // DS-wide grep 29 個 truncate 都遵此 pattern,只本處違反 — 修齊。\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-0 flex items-center text-fg-muted\"\n >\n <span className=\"min-w-0 flex-1 truncate\">{selectedLabel}</span>\n </span>\n )}\n </span>\n )\n }\n // **selectedItemRenderer slot**(2026-05-07 v15.5):consumer 客製 selected display(e.g.\n // PeoplePicker 接 PersonDisplay)。優先於 isTextDisplay / Tag 預設 path,但 empty value\n // 仍走 placeholder。對齊 PeoplePicker = Select wrapper SSOT。\n if (selectedItemRenderer && value && selectedOpt) {\n return (\n <>\n {StartIcon && <ItemPrefix><StartIcon size={iconSize} className=\"text-fg-muted pointer-events-none\" aria-hidden /></ItemPrefix>}\n {/* 2026-05-14 item-anatomy SSOT fix(per codex H2 propagation 斷點):加 nakedCellRowModeAlign\n → autoRowHeight cell 內 selected renderer 也對齊 first-line,不再 vertical-center 整 row。 */}\n <span className={cn(\"flex-1 min-w-0 inline-flex items-center\", nakedCellRowModeAlign)}>{selectedItemRenderer(selectedOpt)}</span>\n </>\n )\n }\n // Text display: 純文字 + optional value icon\n if (isTextDisplay) {\n return (\n <>\n {StartIcon && <ItemPrefix><StartIcon size={iconSize} className=\"text-fg-muted pointer-events-none\" aria-hidden /></ItemPrefix>}\n {!StartIcon && SelectedIcon && value && <ItemPrefix><SelectedIcon size={iconSize} className=\"pointer-events-none\" aria-hidden /></ItemPrefix>}\n <span className={cn('flex-1 min-w-0 truncate', !value && 'text-fg-muted')}>\n {value ? selectedLabel : (placeholder ?? '選擇…')}\n </span>\n </>\n )\n }\n // Tag display: 用 option 的 tagVariant\n return (\n <>\n {value && selectedOpt?.tagVariant\n ? <Tag size={size} color={selectedOpt.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral'} className=\"shrink-0 pointer-events-none\">{selectedLabel}</Tag>\n : value\n ? <Tag size={size} className=\"shrink-0 pointer-events-none\">{selectedLabel}</Tag>\n : <span className=\"text-fg-muted\">{placeholder ?? '選擇…'}</span>\n }\n <span className=\"flex-1\" />\n </>\n )\n}\nCustomSelectTriggerContent.displayName = 'CustomSelectTriggerContent'\n\n// ── Shared readonly/disabled/display render ─────────────────────────────────\nfunction ReadonlyDisplay({\n mode, variant: variantProp, size, options, value, display, startIcon: StartIcon, className, placeholder, showDisplayEndIcon,\n}: Pick<SelectProps, 'mode' | 'variant' | 'size' | 'options' | 'value' | 'display' | 'startIcon' | 'className' | 'placeholder' | 'showDisplayEndIcon'>) {\n const resolvedMode = mode ?? 'readonly'\n const variant = variantProp ?? 'default'\n const sz = size ?? 'md'\n const iconSize = getIconSize(sz)\n const label = options?.find(o => o.value === value)?.label ?? value\n const iconColor = resolvedMode === 'disabled' ? 'text-fg-disabled' : 'text-fg-muted'\n const isTextDisplay = display !== 'tag'\n // K10+K14 fix(2026-05-04):disabled mode placeholder/empty 顯示色 → fg-disabled(neutral-6),非 fg-muted(neutral-7)\n // user canonical:disabled 顯著性優於 muted。同時 plain mode 必須 respect placeholder prop(之前忽略 = bug)\n const emptyColorCls = resolvedMode === 'disabled' ? 'text-fg-disabled' : 'text-fg-muted'\n const emptyText = placeholder ?? EMPTY_DISPLAY\n\n // mode='display':2 path(2026-05-08 D path Phase 1 Select canary)\n // ❌ 預設(無 showDisplayEndIcon):純內容輸出 bare span/Tag(原行為,backward compat)\n // 對齊原 SelectDisplay sub-component(retired)。readonly / disabled 仍走下方 fieldWrapperStyles。\n // ✅ showDisplayEndIcon=true(DataTable cell opt-in):Field naked-display wrapper +\n // ChevronDown ItemSuffix。SSOT canonical 跟 readonly/edit/disabled mode 同 DOM 結構。\n // Authority: data-table.spec.md:204 + inline-action.spec.md:157「Field family endAction」\n if (resolvedMode === 'display') {\n if (!showDisplayEndIcon) {\n // 2026-05-14 I2 fix(spec contract (e) display typography canonical):bare span 必套\n // `fieldDisplayTextClass(sz)`(sm/md→text-body,lg→text-body-lg)— 對齊跨 Field\n // family display 視覺尺寸統一。\n if (!value) return <span className={cn(fieldDisplayTextClass(sz), 'text-fg-muted', className)}>{emptyText}</span>\n if (isTextDisplay) return <span className={cn(fieldDisplayTextClass(sz), 'truncate', className)}>{label}</span>\n const selOpt = options?.find(o => o.value === value)\n const tVariant = selOpt?.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral' | undefined\n return <Tag size={sz} color={tVariant} className={className}>{label}</Tag>\n }\n // D path opt-in: Field naked-display wrapper + ItemSuffix ChevronDown\n const selOpt = options?.find(o => o.value === value)\n const tVariant = selOpt?.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral' | undefined\n return (\n <div\n className={cn(fieldWrapperStyles({ mode: 'display', variant, size: sz }), value && !isTextDisplay && tagPadding[sz], className)}\n data-field-mode=\"display\"\n >\n {isTextDisplay ? (\n <span className={cn(bareInputStyles, 'flex-1 min-w-0 truncate', !value && emptyColorCls)}>\n {value ? label : emptyText}\n </span>\n ) : value ? (\n <Tag size={sz} color={tVariant}>{label}</Tag>\n ) : (\n <span className={cn('flex-1 min-w-0', emptyColorCls)}>{emptyText}</span>\n )}\n <ItemSuffix><ChevronDown size={iconSize} className=\"text-fg-muted pointer-events-none\" aria-hidden /></ItemSuffix>\n </div>\n )\n }\n\n // 2026-06-26 類型身份 indicator 規則:edit 顯示 / readonly 不顯示(純值、不可開下拉,箭頭會誤導) /\n // disabled 保留(fg-disabled,對齊原生 <select disabled> 灰示箭頭 + Accordion M24 precedent)。\n // naked cell 情境依 showDisplayEndIcon = isEditable,維持 2026-05-10 cell canonical「非可編欄不顯」。\n // aria-disabled:styled-disabled(非 native disabled 元素)需明告 AT「inactive」,同時讓 axe 正確\n // 豁免 disabled 文字的 color-contrast(WCAG 1.4.3 inactive UI 例外)。\n const showIndicator = variant === 'naked' ? !!showDisplayEndIcon : resolvedMode === 'disabled'\n const ariaDisabled = resolvedMode === 'disabled' ? true : undefined\n\n if (isTextDisplay) {\n return (\n <div className={cn(fieldWrapperStyles({ mode: resolvedMode, variant, size: sz }), className)} data-field-mode={resolvedMode} aria-disabled={ariaDisabled}>\n {StartIcon && <ItemPrefix><StartIcon size={iconSize} className={cn('pointer-events-none', iconColor)} aria-hidden /></ItemPrefix>}\n <span className={cn('flex-1 min-w-0 truncate', resolvedMode === 'disabled' && 'text-fg-disabled')}>\n {value ? label : <span className={emptyColorCls}>{emptyText}</span>}\n </span>\n {showIndicator && <ItemSuffix className=\"pointer-events-none\"><ChevronDown size={iconSize} className={cn('shrink-0', iconColor)} aria-hidden /></ItemSuffix>}\n </div>\n )\n }\n\n const selectedOpt = options?.find(o => o.value === value)\n const tagVariant = selectedOpt?.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral' | undefined\n\n return (\n <div className={cn(fieldWrapperStyles({ mode: resolvedMode, variant, size: sz }), value && tagPadding[sz], className)} style={{ paddingRight: 'var(--field-px)' }} data-field-mode={resolvedMode} aria-disabled={ariaDisabled}>\n {value ? <Tag size={sz} color={tagVariant}>{label}</Tag> : <span className={emptyColorCls}>{emptyText}</span>}\n {showIndicator && <ItemSuffix className=\"pointer-events-none\"><ChevronDown size={iconSize} className={cn('shrink-0', iconColor)} aria-hidden /></ItemSuffix>}\n </div>\n )\n}\n\n// ── Native Select (mobile) ─────────────────────────────────────────────\n\n// code-quality-allow: long-function — foundational composite main body — 拆 sub-fn 會複雜化 local state / ref / context binding\nconst NativeSelect = React.forwardRef<HTMLSelectElement, SelectProps>(\n ({ mode, variant: variantProp, error: errorProp = false, size: sizeProp, options, value: valueProp, defaultValue, onChange, placeholder, className, disabled: disabledProp, clearable = false, display = 'plain', startIcon: StartIcon, showDisplayEndIcon, id: idProp, 'aria-describedby': ariaDescribedByProp, 'aria-errormessage': ariaErrorMessageProp, ...props }, ref) => {\n const fieldCtx = useFieldContext()\n const error = useResolvedFieldInvalid(errorProp)\n const disabled = useResolvedFieldDisabled(disabledProp)\n // 2026-05-31 #11:size 從 Field context cascade(對齊 Input/NumberInput + MUI FormControl)\n const size = useResolvedFieldSize(sizeProp)\n // 2026-06-08 SSOT:mode 經 useResolvedFieldMode(prop > 有效 disabled > fieldCtx.mode > 'edit');修 <Field mode=\"display\"> 漏 cascade\n const resolvedMode = useResolvedFieldMode({ mode, disabled })\n const variant: FieldVariant = useResolvedFieldVariant(variantProp)\n const iconSize = getIconSize(size)\n // 2026-05-21 D3 audit:Controlled / Uncontrolled dual-mode via 既有 SSOT hook(同 CustomSelect)\n const [value, setValue] = useControllable<string | null>({\n value: valueProp,\n defaultValue: defaultValue ?? null,\n onChange: onChange ? (next) => onChange(next ?? '') : undefined,\n })\n const handleNativeChange = (v: string) => setValue(v)\n const showClear = clearable && value && resolvedMode === 'edit'\n const isTextDisplay = display === 'plain'\n const selectRef = React.useRef<HTMLSelectElement | null>(null)\n const setSelectRef = React.useCallback((el: HTMLSelectElement | null) => {\n selectRef.current = el\n if (typeof ref === 'function') ref(el)\n else if (ref) (ref as React.MutableRefObject<HTMLSelectElement | null>).current = el\n }, [ref])\n\n if (resolvedMode !== 'edit') {\n return <ReadonlyDisplay mode={resolvedMode} variant={variant} size={size} options={options} value={value} display={display} startIcon={StartIcon} className={className} placeholder={placeholder} showDisplayEndIcon={showDisplayEndIcon} />\n }\n\n const selectEl = (\n <select\n ref={setSelectRef}\n id={idProp ?? fieldCtx?.id}\n value={value ?? ''}\n onChange={(e) => handleNativeChange(e.target.value)}\n disabled={disabled}\n aria-invalid={error || undefined}\n aria-required={fieldCtx?.required || undefined}\n aria-describedby={ariaDescribedByProp ?? fieldCtx?.descriptionId}\n aria-errormessage={ariaErrorMessageProp ?? (error ? fieldCtx?.errorId : undefined)}\n className={cn(bareInputStyles, 'cursor-pointer appearance-none', !value && 'text-fg-muted', !isTextDisplay && value && 'absolute inset-0 w-full h-full opacity-0 z-0')}\n {...props}\n >\n {placeholder && <option value=\"\" disabled>{placeholder}</option>}\n {options.map(opt => <option key={opt.value} value={opt.value}>{opt.label}</option>)}\n </select>\n )\n\n const clearEl = showClear ? (\n <SelectClearButton size={size ?? 'md'} onClear={() => handleNativeChange('')} />\n ) : null\n\n const chevronEl = (\n <ItemSuffix className=\"relative z-10 pointer-events-none\">\n <ChevronDown size={iconSize} className=\"text-fg-muted\" aria-hidden />\n </ItemSuffix>\n )\n const selectedOpt = options?.find(o => o.value === value)\n const label = selectedOpt?.label ?? value\n const nativeTagVariant = selectedOpt?.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral' | undefined\n const SelectedOptIcon = selectedOpt?.icon\n\n if (!isTextDisplay) {\n return (\n <div className={cn(fieldWrapperStyles({ mode: 'edit', variant: variant, size }), value && tagPadding[size], 'relative',\n error && ['border-error hover:border-error-hover', 'focus-within:border-error focus-within:hover:border-error'], className)}\n style={{ paddingRight: 'var(--field-px)' }} data-field-mode=\"edit\" data-error={error ? '' : undefined}>\n {value ? <Tag size={size} color={nativeTagVariant} className=\"shrink-0 relative z-10 pointer-events-none\">{label}</Tag> : <span className=\"text-fg-muted\">{placeholder ?? '選擇...'}</span>}\n {selectEl}\n <span className=\"flex-1\" />\n {clearEl}\n {chevronEl}\n </div>\n )\n }\n\n return (\n <div className={cn(fieldWrapperStyles({ mode: 'edit', variant: variant, size }),\n error && ['border-error hover:border-error-hover', 'focus-within:border-error focus-within:hover:border-error'], className)}\n data-field-mode=\"edit\" data-error={error ? '' : undefined}>\n {StartIcon && <ItemPrefix><StartIcon size={iconSize} className=\"text-fg-muted pointer-events-none\" aria-hidden /></ItemPrefix>}\n {!StartIcon && SelectedOptIcon && value && <ItemPrefix><SelectedOptIcon size={iconSize} className=\"pointer-events-none\" aria-hidden /></ItemPrefix>}\n {selectEl}\n {clearEl}\n {chevronEl}\n </div>\n )\n }\n)\nNativeSelect.displayName = 'NativeSelect'\n\n// ── Custom Select (desktop — consumes SelectMenu) ────────────────────────\n\n// code-quality-allow: long-function — foundational composite main body — 拆 sub-fn 會複雜化 local state / ref / context binding\nconst CustomSelect = React.forwardRef<HTMLDivElement, SelectProps>(\n ({ mode, variant: variantProp, error: errorProp = false, size: sizeProp, options, groups, value: valueProp, defaultValue, onChange, placeholder, className, disabled: disabledProp, clearable = false, display = 'plain', startIcon: StartIcon, searchable = false, loading, minRows, defaultOpen = false, onOpenChange, selectedItemRenderer, showDisplayEndIcon, id: idProp, 'aria-describedby': ariaDescribedByProp, 'aria-errormessage': ariaErrorMessageProp, 'aria-label': ariaLabel }, ref) => {\n const fieldCtx = useFieldContext()\n const error = useResolvedFieldInvalid(errorProp)\n const disabled = useResolvedFieldDisabled(disabledProp)\n // 2026-05-31 #11:size 從 Field context cascade(對齊 Input/NumberInput + MUI FormControl)\n const size = useResolvedFieldSize(sizeProp)\n // 2026-06-08 SSOT:mode 經 useResolvedFieldMode(prop > 有效 disabled > fieldCtx.mode > 'edit');修 <Field mode=\"display\"> 漏 cascade\n const resolvedMode = useResolvedFieldMode({ mode, disabled })\n const variant: FieldVariant = useResolvedFieldVariant(variantProp)\n const iconSize = getIconSize(size)\n // 2026-05-21 D3 audit:Controlled / Uncontrolled dual-mode via 既有 SSOT hook(M17 對齊,取代自刻 isControlled pattern)。\n // Phase B codex 抓:之前 Custom clear 走 `onChange?.('')` 沒 setInternalValue → uncontrolled clear 失效。useControllable 統一 setter 修。\n // onChange forward coerce null → ''(consumer 簽名 `(value: string) => void`,null 是 internal empty signal)。\n const [value, setValue] = useControllable<string | null>({\n value: valueProp,\n defaultValue: defaultValue ?? null,\n onChange: onChange ? (next) => onChange(next ?? '') : undefined,\n })\n const showClear = clearable && value && resolvedMode === 'edit'\n const isTextDisplay = display === 'plain'\n\n const [open, setOpen] = React.useState(defaultOpen)\n const [search, setSearch] = React.useState('')\n const inputRef = React.useRef<HTMLInputElement>(null)\n\n // 關閉時清搜尋\n React.useEffect(() => { if (!open) setSearch('') }, [open])\n\n // **React #310 fix(2026-05-04)**:所有 hooks 必在任何 early return 前 call,\n // 否則 disabled→edit 切換時 hook count 變動 → React 死亡。\n // 原本 useMemo(L280, L291) 在 early return 之後 = latent bug,K13 觸發(filter Op 從 disabled\n // 變 edit 當 user 選欄位)。修法:把所有 useMemo 提到 early return 之前。\n const selectedOpt = options?.find(o => o.value === value)\n // 2026-05-06 v9.1:value 不在 options 也要顯示原值(不沉默丟失)。原 fallback `''` 致\n // SelectCell 開 edit 時若 cell value 不在當前 options(e.g. 上游資料漂移 / options async\n // 後到 / 跨 dataset),trigger 顯示空白 — user 報「value 不見」。對齊 ReadonlyDisplay 同\n // 級 fallback `?? value`。\n const selectedLabel = selectedOpt?.label ?? value ?? ''\n const SelectedIcon = selectedOpt?.icon\n // ── 過濾選項 ──\n const filteredOptions = searchable && search\n ? options.filter(o => o.label.toLowerCase().includes(search.toLowerCase()))\n : options\n // ── 轉換 SelectOption → SelectMenuOption(必在 early return 前) ──\n // Issue 4(2026-05-10):forward avatar / description / disabled SSOT(per SelectMenuOption schema)。\n const menuOptions: SelectMenuOption[] = React.useMemo(\n () => filteredOptions.map(opt => ({\n value: opt.value,\n label: opt.label,\n icon: isTextDisplay ? opt.icon : undefined,\n avatar: opt.avatar,\n description: opt.description,\n disabled: opt.disabled,\n group: opt.group,\n })),\n [filteredOptions, isTextDisplay]\n )\n // ── Tag display 自訂 label 渲染(必在 early return 前) ──\n const renderLabel = React.useMemo(() => {\n if (isTextDisplay) return undefined\n return (menuOpt: SelectMenuOption) => {\n const srcOpt = options.find(o => o.value === menuOpt.value)\n if (srcOpt?.tagVariant) {\n return <Tag size={size} color={srcOpt.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral'}>{menuOpt.label}</Tag>\n }\n return menuOpt.label\n }\n }, [isTextDisplay, options, size])\n\n // **React #310 fix v2(2026-05-04)**:`handleValueChange` useCallback 也必在 early return 前\n // 原本 L306(early return 後)→ disabled→edit 切換時 hook count 仍變 → #310 持續\n // 2026-05-21 D3:`useControllable` 統一 controlled / uncontrolled state + onChange forward,不再手動 if-branch。\n const handleValueChange = React.useCallback(\n (newValue: string | string[]) => {\n setValue(Array.isArray(newValue) ? newValue[0] : newValue)\n },\n [setValue]\n )\n\n // Early return AFTER all hooks(disabled / readonly / display mode 走 ReadonlyDisplay)\n if (resolvedMode !== 'edit') {\n return <ReadonlyDisplay mode={resolvedMode} variant={variant} size={size} options={options} value={value} display={display} startIcon={StartIcon} className={className} placeholder={placeholder} showDisplayEndIcon={showDisplayEndIcon} />\n }\n\n // 2026-05-21 D3 Phase B codex 抓:Custom clear 用 setValue 不直接 onChange,uncontrolled clear 才能真清 internal state。\n const clearEl = showClear ? (\n <SelectClearButton size={size ?? 'md'} onClear={() => setValue('')} stopPropagation />\n ) : null\n\n const chevronEl = (\n <ItemSuffix>\n <ChevronDown size={iconSize} className={cn('text-fg-muted transition-transform', open && 'rotate-180')} aria-hidden />\n </ItemSuffix>\n )\n\n const triggerContent = (\n <CustomSelectTriggerContent\n searchable={searchable}\n open={open}\n isTextDisplay={isTextDisplay}\n size={size}\n value={value}\n selectedLabel={selectedLabel}\n selectedOpt={selectedOpt}\n SelectedIcon={SelectedIcon}\n StartIcon={StartIcon}\n iconSize={iconSize}\n placeholder={placeholder}\n search={search}\n setSearch={setSearch}\n inputRef={inputRef}\n selectedItemRenderer={selectedItemRenderer}\n />\n )\n\n // hooks(filteredOptions / menuOptions / renderLabel / handleValueChange)已全 hoist(React #310 fix v2)\n\n const trigger = (\n <div\n ref={ref}\n id={idProp ?? fieldCtx?.id}\n role=\"combobox\"\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-label={ariaLabel}\n aria-invalid={error || undefined}\n aria-required={fieldCtx?.required || undefined}\n aria-describedby={ariaDescribedByProp ?? fieldCtx?.descriptionId}\n aria-errormessage={ariaErrorMessageProp ?? (error ? fieldCtx?.errorId : undefined)}\n tabIndex={0}\n className={cn(\n fieldWrapperStyles({ mode: 'edit', variant: variant, size }),\n !isTextDisplay && value && !searchable && tagPadding[size],\n // 2026-05-06 v13.3 SSOT retire:per-control `open && 'border-primary'` 移除。Field default\n // state machine `data-[state=open]:border-border-hover`(灰深)處理 open;若 trigger focused\n // (Radix focus on open),focus-within:!border-primary 強制勝出顯藍。focus dominates everything\n // 全 DS 一致(Material/Polaris/Ant 共識),改 Field default 一處全 control 自動跟動。\n error && ['border-error hover:border-error-hover', 'focus-within:border-error focus-within:hover:border-error'],\n 'cursor-pointer',\n className,\n )}\n style={!isTextDisplay ? { paddingRight: 'var(--field-px)' } : undefined}\n data-field-mode=\"edit\"\n data-error={error ? '' : undefined}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n // 2026-06-11 P0 a11y(R2 deep-audit):原 guard `!searchable` 連「關閉時的鍵盤開啟」一起擋\n // → searchable Select / PeoplePicker single 鍵盤打不開(WCAG 2.1.1)。原意只是開啟後\n // 別吃掉搜尋框的 Space/Enter → 正確 guard = !open(關閉才攔;開啟後不干擾 input 輸入)。\n if (!open) { e.preventDefault(); setOpen(true) }\n }\n // APG combobox 展開鍵:ArrowDown 也可開(對齊 combobox.tsx 同 pattern;open 後不攔讓方向鍵導覽選單)\n if (e.key === 'ArrowDown' && !open) { e.preventDefault(); setOpen(true) }\n if (e.key === 'Escape') setOpen(false)\n }}\n >\n {triggerContent}\n {clearEl}\n {chevronEl}\n </div>\n )\n\n return (\n <SelectMenu\n options={menuOptions}\n groups={groups}\n value={value ?? null}\n onValueChange={handleValueChange}\n searchable={false}\n loading={loading}\n size={size}\n minRows={minRows}\n open={open}\n onOpenChange={(o) => { setOpen(o); onOpenChange?.(o) }}\n renderLabel={renderLabel}\n onOpenAutoFocus={searchable ? (e) => { e.preventDefault(); inputRef.current?.focus() } : undefined}\n >\n {trigger}\n </SelectMenu>\n )\n }\n)\nCustomSelect.displayName = 'CustomSelect'\n\n// ── Public component(自動偵測 mobile / desktop)──────────────────────────────\n\nconst Select = React.forwardRef<HTMLSelectElement | HTMLDivElement, SelectProps>(\n (props, ref) => {\n const isMobile = useIsTouchDevice()\n\n if (isMobile) {\n return <NativeSelect ref={ref as React.Ref<HTMLSelectElement>} {...props} />\n }\n\n return <CustomSelect ref={ref as React.Ref<HTMLDivElement>} {...props} />\n }\n)\nSelect.displayName = 'Select'\n\n// Story auto-compile metadata — Phase 1 mechanical migration(2026-04-24)\n// Phase 2 fill needed: purpose descriptions + when rationale + world-class refs\nexport const selectMeta = {\n component: 'Select',\n family: 4,\n variants: {\n\n },\n sizes: {\n\n },\n states: ['default', 'hover', 'active', 'focus-visible', 'disabled'],\n tokens: {\n bg: [],\n fg: ['text-fg-disabled', 'text-fg-muted'],\n ring: [],\n },\n} as const\n\nexport { Select }\n"],"names":["selOpt","tVariant"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SelectMenu/index.ts"],"names":[],"mappings":"AAIA,cAAc,eAAe,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal — DS-internal 單元(per `.claude/rules/ui-development.md` Public vs Internal canonical;spec frontmatter `isInternal`)。
|
|
3
|
+
* 不進 root barrel front-door;由 Select / Combobox wrap 消費,end-user app 請用 wrapper 元件。
|
|
4
|
+
*/
|
|
1
5
|
import * as React from 'react';
|
|
2
6
|
import type { LucideIcon } from 'lucide-react';
|
|
3
7
|
import type { AvatarData } from '../../components/Avatar/avatar';
|
|
@@ -56,9 +60,9 @@ export interface SelectMenuProps {
|
|
|
56
60
|
/** 空選項提示 */
|
|
57
61
|
emptyText?: string;
|
|
58
62
|
/** Loading 狀態(2026-05-15 audit B fix per user verbatim「dropdown 隨時可開,讀取在 panel 中間 CircularProgress」)
|
|
59
|
-
* true → render `<Empty icon={<CircularProgress size={48}/>}
|
|
60
|
-
* trigger 不變,user 隨時可開 dropdown。對齊 MUI Autocomplete
|
|
61
|
-
* loading idiom + DS 既有 `empty.spec.md:
|
|
63
|
+
* true → render `<Empty icon={<CircularProgress size={48}/>} className="py-6" />` 取代 options(純 spinner,無 description);
|
|
64
|
+
* trigger 不變,user 隨時可開 dropdown。對齊 MUI Autocomplete loading dropdown-body + Ant Select
|
|
65
|
+
* loading idiom + DS 既有 `empty.spec.md:191` 「全頁 loading = Empty + CircularProgress compose」SSOT。
|
|
62
66
|
*/
|
|
63
67
|
loading?: boolean;
|
|
64
68
|
/** 尺寸 */
|
|
@@ -80,8 +84,9 @@ export interface SelectMenuProps {
|
|
|
80
84
|
/** 攔截 PopoverContent 的 onOpenAutoFocus(如 Select searchable 需阻止 focus 搶走) */
|
|
81
85
|
onOpenAutoFocus?: (e: Event) => void;
|
|
82
86
|
/**
|
|
83
|
-
* Popover 內容容器的 DOM id
|
|
84
|
-
*
|
|
87
|
+
* Popover 內容容器的 DOM id(set 在 PopoverContent 外層 div,**非** cmdk 內層 `role="listbox"` 本身)。
|
|
88
|
+
* Combobox / 自定 trigger 用 `aria-controls` 指向此 id 時,指向的是 **popover 容器(listbox 的 ancestor)**——
|
|
89
|
+
* AT 經此容器可定位到內部 cmdk listbox(cmdk List 自帶 auto-generated `role="listbox"` id)。
|
|
85
90
|
*/
|
|
86
91
|
contentId?: string;
|
|
87
92
|
className?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select-menu.d.ts","sourceRoot":"","sources":["../../../src/components/SelectMenu/select-menu.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"select-menu.d.ts","sourceRoot":"","sources":["../../../src/components/SelectMenu/select-menu.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAG9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAA;AAa1E;;;;;;;;;;;;;;GAcG;AAIH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;CACd;AAED,KAAK,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAIjC,MAAM,WAAW,eAAe;IAC9B,WAAW;IACX,OAAO,EAAE,gBAAgB,EAAE,CAAA;IAC3B,gCAAgC;IAChC,MAAM,CAAC,EAAE,qBAAqB,EAAE,CAAA;IAEhC,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAA;IAChC,mBAAmB;IACnB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,IAAI,CAAA;IAElD,WAAW;IACX,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,YAAY;IACZ,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,aAAa;IACb,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,qBAAqB;IACrB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,8CAA8C;IAC9C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IAEvC,oBAAoB;IACpB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,sBAAsB;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,YAAY;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB,SAAS;IACT,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,WAAW;IACX,KAAK,CAAC,EAAE,OAAO,GAAG,KAAK,CAAA;IACvB,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB,iBAAiB;IACjB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,sGAAsG;IACtG,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,yBAAyB;IACzB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IAEtC,2CAA2C;IAC3C,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAA;IAC3D,4EAA4E;IAC5E,eAAe,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAA;IAEpC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAMD,QAAA,MAAM,UAAU,qFA6Sd,CAAA;AAMF,eAAO,MAAM,cAAc;;;;;;;;;;;CAejB,CAAA;AAEV,OAAO,EAAE,UAAU,EAAE,CAAA"}
|