@qijenchen/design-system 0.1.0-beta.74 → 0.1.0-beta.76

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.
Files changed (203) hide show
  1. package/CLAUDE.md +1 -1
  2. package/dist/components/AppShell/app-shell.d.ts +2 -2
  3. package/dist/components/AppShell/app-shell.js.map +1 -1
  4. package/dist/components/Avatar/avatar.js.map +1 -1
  5. package/dist/components/BulkActionBar/bulk-action-bar.d.ts.map +1 -1
  6. package/dist/components/BulkActionBar/bulk-action-bar.js +1 -1
  7. package/dist/components/BulkActionBar/bulk-action-bar.js.map +1 -1
  8. package/dist/components/Button/button.d.ts.map +1 -1
  9. package/dist/components/Button/button.js.map +1 -1
  10. package/dist/components/Chart/chart.d.ts +1 -1
  11. package/dist/components/Chart/chart.js.map +1 -1
  12. package/dist/components/Checkbox/checkbox.d.ts +1 -1
  13. package/dist/components/Checkbox/checkbox.js +1 -1
  14. package/dist/components/Checkbox/checkbox.js.map +1 -1
  15. package/dist/components/Combobox/combobox.d.ts +1 -1
  16. package/dist/components/Combobox/combobox.d.ts.map +1 -1
  17. package/dist/components/Combobox/combobox.js +13 -10
  18. package/dist/components/Combobox/combobox.js.map +1 -1
  19. package/dist/components/Command/command.d.ts +1 -1
  20. package/dist/components/Command/command.js +3 -3
  21. package/dist/components/Command/command.js.map +1 -1
  22. package/dist/components/DataTable/cell-registry.d.ts.map +1 -1
  23. package/dist/components/DataTable/cell-registry.js +2 -2
  24. package/dist/components/DataTable/cell-registry.js.map +1 -1
  25. package/dist/components/DataTable/data-table.d.ts +27 -6
  26. package/dist/components/DataTable/data-table.d.ts.map +1 -1
  27. package/dist/components/DataTable/data-table.js +57 -34
  28. package/dist/components/DataTable/data-table.js.map +1 -1
  29. package/dist/components/DatePicker/date-picker.d.ts.map +1 -1
  30. package/dist/components/DatePicker/date-picker.js +2 -2
  31. package/dist/components/DatePicker/date-picker.js.map +1 -1
  32. package/dist/components/DescriptionList/description-list.d.ts +1 -1
  33. package/dist/components/DescriptionList/description-list.js +2 -2
  34. package/dist/components/DescriptionList/description-list.js.map +1 -1
  35. package/dist/components/Empty/empty.d.ts +2 -0
  36. package/dist/components/Empty/empty.d.ts.map +1 -1
  37. package/dist/components/Empty/empty.js.map +1 -1
  38. package/dist/components/Field/field-wrapper.js +4 -4
  39. package/dist/components/Field/field-wrapper.js.map +1 -1
  40. package/dist/components/OverflowIndicator/overflow-indicator.d.ts +1 -1
  41. package/dist/components/OverflowIndicator/overflow-indicator.js +2 -2
  42. package/dist/components/OverflowIndicator/overflow-indicator.js.map +1 -1
  43. package/dist/components/PeoplePicker/people-picker.js +2 -2
  44. package/dist/components/PeoplePicker/people-picker.js.map +1 -1
  45. package/dist/components/ProfileCard/profile-card.d.ts +1 -1
  46. package/dist/components/ProfileCard/profile-card.js +2 -1
  47. package/dist/components/ProfileCard/profile-card.js.map +1 -1
  48. package/dist/components/Rating/rating.js.map +1 -1
  49. package/dist/components/Select/select.js +4 -4
  50. package/dist/components/Select/select.js.map +1 -1
  51. package/dist/components/Textarea/textarea.d.ts +1 -1
  52. package/dist/components/Textarea/textarea.js +2 -2
  53. package/dist/components/Textarea/textarea.js.map +1 -1
  54. package/dist/components/TimePicker/time-picker.d.ts.map +1 -1
  55. package/dist/components/TimePicker/time-picker.js +14 -23
  56. package/dist/components/TimePicker/time-picker.js.map +1 -1
  57. package/dist/components/TreeView/tree-view.d.ts +1 -1
  58. package/dist/components/TreeView/tree-view.js +1 -1
  59. package/dist/components/TreeView/tree-view.js.map +1 -1
  60. package/ds-canonical/fork/governance.lock +1 -1
  61. package/ds-canonical/fork/preamble.md +2 -2
  62. package/ds-canonical/hooks/check_field_controls_contracts.sh +30 -3
  63. package/ds-canonical/hooks/check_story_invariants.sh +26 -0
  64. package/ds-canonical/hooks/tests/test_check_story_invariants.sh +30 -0
  65. package/ds-canonical/references/props-naming.md +15 -1
  66. package/ds-canonical/rules/ui-development.md +2 -2
  67. package/llms-full.txt +7 -2
  68. package/llms.txt +3 -3
  69. package/package.json +1 -1
  70. package/src/components/Accordion/accordion.principles.stories.tsx +3 -3
  71. package/src/components/Alert/alert.anatomy.stories.tsx +4 -4
  72. package/src/components/Alert/alert.principles.stories.tsx +5 -5
  73. package/src/components/AppShell/app-shell.principles.stories.tsx +6 -6
  74. package/src/components/AppShell/app-shell.spec.md +4 -4
  75. package/src/components/AppShell/app-shell.tsx +2 -2
  76. package/src/components/AspectRatio/aspect-ratio.principles.stories.tsx +1 -1
  77. package/src/components/Avatar/avatar.principles.stories.tsx +3 -3
  78. package/src/components/Avatar/avatar.tsx +1 -1
  79. package/src/components/Badge/badge.principles.stories.tsx +3 -3
  80. package/src/components/Breadcrumb/breadcrumb.principles.stories.tsx +3 -3
  81. package/src/components/Breadcrumb/breadcrumb.spec.md +11 -1
  82. package/src/components/BulkActionBar/bulk-action-bar.anatomy.stories.tsx +1 -1
  83. package/src/components/BulkActionBar/bulk-action-bar.principles.stories.tsx +3 -3
  84. package/src/components/BulkActionBar/bulk-action-bar.spec.md +4 -2
  85. package/src/components/BulkActionBar/bulk-action-bar.stories.tsx +2 -2
  86. package/src/components/BulkActionBar/bulk-action-bar.tsx +3 -2
  87. package/src/components/Button/button.principles.stories.tsx +3 -3
  88. package/src/components/Button/button.tsx +0 -10
  89. package/src/components/Calendar/calendar.anatomy.stories.tsx +1 -1
  90. package/src/components/Calendar/calendar.principles.stories.tsx +3 -3
  91. package/src/components/Carousel/carousel.principles.stories.tsx +2 -2
  92. package/src/components/Chart/chart.principles.stories.tsx +4 -4
  93. package/src/components/Chart/chart.tsx +1 -1
  94. package/src/components/Checkbox/checkbox.principles.stories.tsx +2 -2
  95. package/src/components/Checkbox/checkbox.tsx +1 -1
  96. package/src/components/Chip/chip.principles.stories.tsx +3 -3
  97. package/src/components/Coachmark/coachmark.anatomy.stories.tsx +1 -1
  98. package/src/components/Coachmark/coachmark.principles.stories.tsx +3 -3
  99. package/src/components/Coachmark/coachmark.spec.md +2 -2
  100. package/src/components/Combobox/combobox.anatomy.stories.tsx +14 -14
  101. package/src/components/Combobox/combobox.principles.stories.tsx +6 -6
  102. package/src/components/Combobox/combobox.spec.md +1 -1
  103. package/src/components/Combobox/combobox.tsx +25 -14
  104. package/src/components/Command/command.anatomy.stories.tsx +2 -0
  105. package/src/components/Command/command.principles.stories.tsx +7 -7
  106. package/src/components/Command/command.tsx +2 -2
  107. package/src/components/DataTable/cell-registry.tsx +6 -2
  108. package/src/components/DataTable/data-table-filter-panel.tsx +3 -3
  109. package/src/components/DataTable/data-table.anatomy.stories.tsx +1 -1
  110. package/src/components/DataTable/data-table.css +1 -1
  111. package/src/components/DataTable/data-table.principles.stories.tsx +3 -3
  112. package/src/components/DataTable/data-table.spec.md +25 -17
  113. package/src/components/DataTable/data-table.stories.tsx +29 -25
  114. package/src/components/DataTable/data-table.tsx +92 -44
  115. package/src/components/DateGrid/date-grid.anatomy.stories.tsx +1 -1
  116. package/src/components/DateGrid/date-grid.principles.stories.tsx +4 -4
  117. package/src/components/DateGrid/date-grid.spec.md +1 -1
  118. package/src/components/DatePicker/date-picker.anatomy.stories.tsx +15 -11
  119. package/src/components/DatePicker/date-picker.principles.stories.tsx +5 -5
  120. package/src/components/DatePicker/date-picker.spec.md +1 -1
  121. package/src/components/DatePicker/date-picker.tsx +9 -6
  122. package/src/components/DescriptionList/description-list.principles.stories.tsx +5 -5
  123. package/src/components/DescriptionList/description-list.tsx +1 -1
  124. package/src/components/Dialog/dialog.anatomy.stories.tsx +1 -1
  125. package/src/components/Dialog/dialog.principles.stories.tsx +4 -4
  126. package/src/components/DropdownMenu/dropdown-menu.anatomy.stories.tsx +1 -1
  127. package/src/components/DropdownMenu/dropdown-menu.principles.stories.tsx +5 -5
  128. package/src/components/DropdownMenu/dropdown-menu.spec.md +1 -1
  129. package/src/components/Empty/empty.principles.stories.tsx +2 -2
  130. package/src/components/Empty/empty.tsx +2 -0
  131. package/src/components/Field/field-controls.spec.md +9 -6
  132. package/src/components/Field/field-wrapper.tsx +4 -4
  133. package/src/components/Field/field.principles.stories.tsx +4 -4
  134. package/src/components/FileItem/file-item.principles.stories.tsx +6 -5
  135. package/src/components/FileUpload/file-upload.principles.stories.tsx +6 -6
  136. package/src/components/FileUpload/file-upload.spec.md +1 -1
  137. package/src/components/FileViewer/file-viewer.principles.stories.tsx +5 -5
  138. package/src/components/HoverCard/hover-card.principles.stories.tsx +6 -6
  139. package/src/components/Input/input.anatomy.stories.tsx +3 -3
  140. package/src/components/Input/input.principles.stories.tsx +4 -4
  141. package/src/components/LinkInput/link-input.anatomy.stories.tsx +3 -3
  142. package/src/components/LinkInput/link-input.principles.stories.tsx +5 -5
  143. package/src/components/Menu/menu-item.principles.stories.tsx +7 -7
  144. package/src/components/Notice/notice.anatomy.stories.tsx +1 -1
  145. package/src/components/Notice/notice.principles.stories.tsx +7 -7
  146. package/src/components/NumberInput/number-input.anatomy.stories.tsx +8 -7
  147. package/src/components/NumberInput/number-input.principles.stories.tsx +4 -4
  148. package/src/components/NumberInput/number-input.spec.md +1 -1
  149. package/src/components/OverflowIndicator/overflow-indicator.principles.stories.tsx +5 -5
  150. package/src/components/OverflowIndicator/overflow-indicator.tsx +1 -1
  151. package/src/components/PeoplePicker/people-picker.principles.stories.tsx +3 -3
  152. package/src/components/PeoplePicker/people-picker.spec.md +3 -3
  153. package/src/components/PeoplePicker/people-picker.tsx +6 -6
  154. package/src/components/Popover/popover.principles.stories.tsx +5 -5
  155. package/src/components/ProfileCard/profile-card.anatomy.stories.tsx +1 -1
  156. package/src/components/ProfileCard/profile-card.principles.stories.tsx +1 -1
  157. package/src/components/ProfileCard/profile-card.tsx +1 -1
  158. package/src/components/ProgressBar/progress-bar.principles.stories.tsx +2 -2
  159. package/src/components/ProgressBar/progress-bar.spec.md +1 -1
  160. package/src/components/RadioGroup/radio-group.principles.stories.tsx +2 -2
  161. package/src/components/Rating/rating.anatomy.stories.tsx +2 -2
  162. package/src/components/Rating/rating.principles.stories.tsx +3 -3
  163. package/src/components/Rating/rating.spec.md +1 -1
  164. package/src/components/Rating/rating.tsx +1 -1
  165. package/src/components/ScrollArea/scroll-area.principles.stories.tsx +4 -4
  166. package/src/components/Select/select.anatomy.stories.tsx +18 -18
  167. package/src/components/Select/select.principles.stories.tsx +5 -5
  168. package/src/components/Select/select.spec.md +1 -1
  169. package/src/components/Select/select.tsx +7 -7
  170. package/src/components/SelectMenu/select-menu.anatomy.stories.tsx +1 -1
  171. package/src/components/SelectMenu/select-menu.principles.stories.tsx +8 -8
  172. package/src/components/SelectionControl/selection-item.principles.stories.tsx +7 -7
  173. package/src/components/Separator/separator.principles.stories.tsx +4 -4
  174. package/src/components/Sheet/sheet.principles.stories.tsx +2 -2
  175. package/src/components/Sidebar/sidebar.principles.stories.tsx +4 -4
  176. package/src/components/Sidebar/sidebar.spec.md +2 -2
  177. package/src/components/Skeleton/skeleton.principles.stories.tsx +5 -5
  178. package/src/components/Slider/slider.anatomy.stories.tsx +1 -1
  179. package/src/components/Slider/slider.principles.stories.tsx +3 -3
  180. package/src/components/Steps/steps.principles.stories.tsx +4 -4
  181. package/src/components/Steps/steps.spec.md +2 -2
  182. package/src/components/Switch/switch.principles.stories.tsx +1 -1
  183. package/src/components/Tabs/tabs.principles.stories.tsx +3 -3
  184. package/src/components/Tabs/tabs.spec.md +1 -1
  185. package/src/components/Tag/tag.principles.stories.tsx +3 -3
  186. package/src/components/Textarea/textarea.principles.stories.tsx +2 -2
  187. package/src/components/Textarea/textarea.tsx +3 -3
  188. package/src/components/TimePicker/time-picker.principles.stories.tsx +5 -5
  189. package/src/components/TimePicker/time-picker.spec.md +1 -1
  190. package/src/components/TimePicker/time-picker.tsx +11 -12
  191. package/src/components/Toast/toast.principles.stories.tsx +2 -2
  192. package/src/components/Tooltip/tooltip.principles.stories.tsx +3 -3
  193. package/src/components/TreeView/tree-view.principles.stories.tsx +5 -5
  194. package/src/components/TreeView/tree-view.stories.tsx +1 -1
  195. package/src/components/TreeView/tree-view.tsx +1 -1
  196. package/src/patterns/element-anatomy/item-anatomy.spec.md +1 -1
  197. package/src/patterns/element-anatomy/item-anatomy.stories.tsx +1 -1
  198. package/src/patterns/overlay-surface/overlay-surface.spec.md +1 -0
  199. package/src/patterns/resize-handle/resize-handle.spec.md +1 -1
  200. package/src/tokens/color/color.spec.md +2 -0
  201. package/src/tokens/color/semantic.css +1 -1
  202. package/src/tokens/uiSize/uiSize.css +5 -0
  203. package/src/tokens/uiSize/uiSize.spec.md +17 -3
@@ -310,7 +310,7 @@ DatePicker 套 `React.forwardRef` + `displayName`;`DatePickerProps` extends `Omi
310
310
 
311
311
  ## 邊界案例
312
312
 
313
- - **Disabled**:Field SSOT own;resolvedMode='disabled' 走 readonly / disabled 純 wrapper 分支(無 Popover trigger、`aria-disabled`、不開 picker),文字與 Calendar icon 切 `text-fg-disabled`。顯式 `mode="display"` 永遠最優先(useResolvedFieldMode step 1,見 field-context.ts):display + disabled 同傳走 display 分支不套 disabled token;要 disabled chrome 傳 `disabled` 或 `mode="disabled"`。
313
+ - **Disabled**:Field SSOT own;resolvedMode='disabled' 走 readonly / disabled 純 wrapper 分支(無 Popover trigger、`aria-disabled`、不開 picker),文字與 Calendar icon 切 `text-fg-disabled`。readonly 不顯示 Calendar icon(類型身份 indicator 規則,SSOT field-controls.spec.md L227);disabled 保留並切 `fg-disabled`。顯式 `mode="display"` 永遠最優先(useResolvedFieldMode step 1,見 field-context.ts):display + disabled 同傳走 display 分支不套 disabled token;要 disabled chrome 傳 `disabled` 或 `mode="disabled"`。
314
314
  - **Loading(server-rendered grid)**:DatePicker 為 sync UI 不獨立 own loading。若 consumer 場景需 async date constraint fetch(如後端 disabled-dates list),consumer 應先 disable trigger 直到 fetch 完成,或在 popover 開啟後 body 切 `<Empty icon={<CircularProgress/>}/>`(對齊 panel-body loading SSOT)。本 spec scope 內不渲 loading state。
315
315
  - **Empty(no value)**:`value=null` → trigger 顯 placeholder(預設 `YYYY/MM/DD`,showTime 時 `YYYY/MM/DD HH:MM`;consumer 可傳 `placeholder` 覆寫)。無導覽目標時鍵盤焦點停留(react-day-picker v9 內建)。
316
316
  - **Invalid date input**:Field validation 處理 `aria-invalid="true"` + error border + 下方 error message;DatePicker 本身不 own validation 規則。
@@ -483,9 +483,9 @@ const DatePicker = React.forwardRef<HTMLDivElement, DatePickerProps>(
483
483
  : <span className="text-fg-muted">{EMPTY_DISPLAY}</span>
484
484
  }
485
485
  </span>
486
- {/* 2026-06-10 類型身份 indicator:readonly/disabled 保留(naked cell 依 showDisplayEndIcon=isEditable,
487
- 並修掉原「disabled cell 無視 gate 漏顯」之 2026-05-10 cell canonical 違反);disabled → fg-disabled(spec L213)*/}
488
- {(variant === 'naked' ? showDisplayEndIcon : true) && (
486
+ {/* 2026-06-26 類型身份 indicator:edit 顯示 / readonly 不顯示(純值、不可開) / disabled 保留(fg-disabled,對齊原生 <select disabled>);
487
+ naked cell showDisplayEndIcon=isEditable(維持 2026-05-10 cell canonical「非可編欄不顯」)*/}
488
+ {(variant === 'naked' ? showDisplayEndIcon : resolvedMode === 'disabled') && (
489
489
  <ItemSuffix className="pointer-events-none">
490
490
  <CalendarIcon size={iconSize} className={resolvedMode === 'disabled' ? 'text-fg-disabled' : 'text-fg-muted'} aria-hidden />
491
491
  </ItemSuffix>
@@ -897,9 +897,12 @@ const DatePickerRange = React.forwardRef<HTMLDivElement, DatePickerRangeProps>(
897
897
  <span className={cn('flex-1 min-w-0 truncate', !endIso && 'text-fg-muted', resolvedMode === 'disabled' && 'text-fg-disabled')}>
898
898
  {endIso ? formatDateOrDateTime(endIso, showTime, showSeconds, { formatOptions, locale }) : resolvedPlaceholder[1]}
899
899
  </span>
900
- <ItemSuffix className="pointer-events-none">
901
- <CalendarIcon size={iconSize} className={resolvedMode === 'disabled' ? 'text-fg-disabled' : 'text-fg-muted'} aria-hidden />
902
- </ItemSuffix>
900
+ {/* 2026-06-26 類型身份 indicator:readonly 不顯示 / disabled 保留(fg-disabled)— 對齊單一 DatePicker(:488)+ SSOT;Range 無 naked-cell 變體故 gate = resolvedMode==='disabled' */}
901
+ {resolvedMode === 'disabled' && (
902
+ <ItemSuffix className="pointer-events-none">
903
+ <CalendarIcon size={iconSize} className="text-fg-disabled" aria-hidden />
904
+ </ItemSuffix>
905
+ )}
903
906
  </div>
904
907
  )
905
908
  }
@@ -53,19 +53,19 @@ export const UsageGuidance: Story = {
53
53
  <p>適合 DescriptionList 的真實業務場景(點擊跳轉「展示」頁範例):</p>
54
54
  <ul className="space-y-1">
55
55
  <li>
56
- <LinkTo kind="Design System/Components/DescriptionList/展示" name="使用者個資"><span className="text-primary hover:underline font-medium cursor-pointer">使用者個資</span></LinkTo>
56
+ <LinkTo kind="Design System/Components/DescriptionList/展示" name="使用者個資"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">使用者個資</span></LinkTo>
57
57
  </li>
58
58
  <li>
59
- <LinkTo kind="Design System/Components/DescriptionList/展示" name="產品規格"><span className="text-primary hover:underline font-medium cursor-pointer">產品規格</span></LinkTo>
59
+ <LinkTo kind="Design System/Components/DescriptionList/展示" name="產品規格"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">產品規格</span></LinkTo>
60
60
  </li>
61
61
  <li>
62
- <LinkTo kind="Design System/Components/DescriptionList/展示" name="訂單明細"><span className="text-primary hover:underline font-medium cursor-pointer">訂單明細</span></LinkTo>
62
+ <LinkTo kind="Design System/Components/DescriptionList/展示" name="訂單明細"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">訂單明細</span></LinkTo>
63
63
  </li>
64
64
  <li>
65
- <LinkTo kind="Design System/Components/DescriptionList/展示" name="詳情面板"><span className="text-primary hover:underline font-medium cursor-pointer">詳情面板</span></LinkTo>
65
+ <LinkTo kind="Design System/Components/DescriptionList/展示" name="詳情面板"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">詳情面板</span></LinkTo>
66
66
  </li>
67
67
  <li>
68
- <LinkTo kind="Design System/Components/DescriptionList/展示" name="水平佈局"><span className="text-primary hover:underline font-medium cursor-pointer">水平佈局</span></LinkTo>
68
+ <LinkTo kind="Design System/Components/DescriptionList/展示" name="水平佈局"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">水平佈局</span></LinkTo>
69
69
  </li>
70
70
  </ul>
71
71
  <p className="text-fg-muted mt-3">判斷不確定時:對照 spec.md「何時用 / 何時不用」段;若仍不符,改用近親元件(見 <code>Vs*Rule</code> stories)。</p>
@@ -123,7 +123,7 @@ DescriptionItem.displayName = 'DescriptionItem'
123
123
  // Phase 2 fill needed: purpose descriptions + when rationale + world-class refs
124
124
  export const descriptionListMeta = {
125
125
  component: 'DescriptionList',
126
- family: null, // non-family composite / overlay / layout
126
+ family: 'composite', // 對齊 description-list.spec.md frontmatter family: composite(SSOT)
127
127
  variants: {
128
128
 
129
129
  },
@@ -417,7 +417,7 @@ export const ColorMatrix: Story = {
417
417
  <div className="flex flex-col gap-8">
418
418
  <div>
419
419
  <H3>Density</H3>
420
- <Desc>Dialog `data-layout-space="lg"`(只鎖版面間距 tier)+ ui-size 繼承 page `data-density`(控件不被撐大)modal 值得寬鬆呼吸 padding:body px-loose 24 / header py-tight 16 → header 56(宣告 lg tier)reinstate c3d3b736 decouple(只鎖 layout-space,非當年連 ui-size 一起鎖撐高 header density)。世界級:Material M3 / Atlassian modal padding 24。</Desc>
420
+ <Desc>Dialog **不自設任何 density attribute**,layout-space + ui-size 全繼承 page。md page body px-loose 16 / header py-tight 12 → header 48;lg page → 24 / 16 → header 56,隨 page tier。modal 寬鬆呼吸由 page tier 自動滿足(lg 24 = Material 級;md 16 = Polaris Modal 下限)。世界級:SAP Fiori / AWS Cloudscape 皆讓 modal page density dial 走,不釘固定 tier。</Desc>
421
421
  </div>
422
422
 
423
423
  <div>
@@ -52,16 +52,16 @@ export const UsageGuidance: Story = {
52
52
  <p>適合 Dialog 的真實業務場景(點擊跳轉「展示」頁範例):</p>
53
53
  <ul className="space-y-1">
54
54
  <li>
55
- <LinkTo kind="Design System/Components/Dialog/展示" name="表單"><span className="text-primary hover:underline font-medium cursor-pointer">表單</span></LinkTo>
55
+ <LinkTo kind="Design System/Components/Dialog/展示" name="表單"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">表單</span></LinkTo>
56
56
  </li>
57
57
  <li>
58
- <LinkTo kind="Design System/Components/Dialog/展示" name="長內容"><span className="text-primary hover:underline font-medium cursor-pointer">長內容</span></LinkTo>
58
+ <LinkTo kind="Design System/Components/Dialog/展示" name="長內容"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">長內容</span></LinkTo>
59
59
  </li>
60
60
  <li>
61
- <LinkTo kind="Design System/Components/Dialog/展示" name="危險操作"><span className="text-primary hover:underline font-medium cursor-pointer">危險操作</span></LinkTo>
61
+ <LinkTo kind="Design System/Components/Dialog/展示" name="危險操作"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">危險操作</span></LinkTo>
62
62
  </li>
63
63
  <li>
64
- <LinkTo kind="Design System/Components/Dialog/展示" name="主體放清單"><span className="text-primary hover:underline font-medium cursor-pointer">主體放清單</span></LinkTo>
64
+ <LinkTo kind="Design System/Components/Dialog/展示" name="主體放清單"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">主體放清單</span></LinkTo>
65
65
  </li>
66
66
  </ul>
67
67
  <p className="text-fg-muted mt-3">判斷不確定時:對照 spec.md「何時用 / 何時不用」段;若仍不符,改用近親元件(見 <code>Vs*Rule</code> stories)。</p>
@@ -963,7 +963,7 @@ export const Accessibility = {
963
963
  <div className="max-w-3xl text-body text-fg-secondary">
964
964
  <h3 className="text-h5 text-foreground mb-2">無障礙設計</h3>
965
965
  <p className="whitespace-pre-line">{"無障礙能力沿用 Radix 選單元件的內建支援,涵蓋語意角色、選單導覽與焦點管理,設計師與工程師不需額外設定。\n\n鍵盤操作:\n\n- Tab — 將焦點移到觸發按鈕\n- Enter / Space / 向下鍵 — 開啟選單\n- 向上鍵 / 向下鍵 — 在選項之間移動\n- Enter — 選擇目前的選項\n- Esc — 關閉整個選單(含子選單;逐層收合用左方向鍵)\n\n焦點管理:選單開啟時焦點會進入選單,關閉後自動回到原本的觸發按鈕;目前導覽到的選項會以明顯的 highlight 底色標示,鍵盤使用者隨時看得到自己在哪一項。\n\n驗證:鍵盤可完整操作(不需滑鼠),文字對比達 WCAG AA;在 Storybook 無障礙檢查面板上應為零項嚴重問題。"}</p>
966
- <p className="mt-4 text-fg-muted">完整 ARIA 細節參考 <a className="text-primary hover:underline" href="https://www.radix-ui.com/primitives/docs/components/dropdown-menu#accessibility" target="_blank" rel="noreferrer">Radix Accessibility 文件</a>。</p>
966
+ <p className="mt-4 text-fg-muted">完整 ARIA 細節參考 <a className="text-primary hover:text-primary-hover" href="https://www.radix-ui.com/primitives/docs/components/dropdown-menu#accessibility" target="_blank" rel="noreferrer">Radix Accessibility 文件</a>。</p>
967
967
  </div>
968
968
  ),
969
969
  }
@@ -58,19 +58,19 @@ export const UsageGuidance: Story = {
58
58
  <p>適合 DropdownMenu 的真實業務場景(點擊跳轉「展示」頁範例):</p>
59
59
  <ul className="space-y-1">
60
60
  <li>
61
- <LinkTo kind="Design System/Components/DropdownMenu/展示" name="群組"><span className="text-primary hover:underline font-medium cursor-pointer">群組 — 帳號選單(個人資料 / 設定 / 登出分組)</span></LinkTo>
61
+ <LinkTo kind="Design System/Components/DropdownMenu/展示" name="群組"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">群組 — 帳號選單(個人資料 / 設定 / 登出分組)</span></LinkTo>
62
62
  </li>
63
63
  <li>
64
- <LinkTo kind="Design System/Components/DropdownMenu/展示" name="後綴"><span className="text-primary hover:underline font-medium cursor-pointer">後綴 — 收件匣未讀數 badge、外開連結提示</span></LinkTo>
64
+ <LinkTo kind="Design System/Components/DropdownMenu/展示" name="後綴"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">後綴 — 收件匣未讀數 badge、外開連結提示</span></LinkTo>
65
65
  </li>
66
66
  <li>
67
- <LinkTo kind="Design System/Components/DropdownMenu/展示" name="子選單"><span className="text-primary hover:underline font-medium cursor-pointer">子選單 — 主題切換(淺色 / 深色 / 跟隨系統)</span></LinkTo>
67
+ <LinkTo kind="Design System/Components/DropdownMenu/展示" name="子選單"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">子選單 — 主題切換(淺色 / 深色 / 跟隨系統)</span></LinkTo>
68
68
  </li>
69
69
  <li>
70
- <LinkTo kind="Design System/Components/DropdownMenu/展示" name="勾選項"><span className="text-primary hover:underline font-medium cursor-pointer">勾選項 — 表格顯示欄位切換</span></LinkTo>
70
+ <LinkTo kind="Design System/Components/DropdownMenu/展示" name="勾選項"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">勾選項 — 表格顯示欄位切換</span></LinkTo>
71
71
  </li>
72
72
  <li>
73
- <LinkTo kind="Design System/Components/DropdownMenu/展示" name="單選"><span className="text-primary hover:underline font-medium cursor-pointer">單選 — 檔案清單排序方式</span></LinkTo>
73
+ <LinkTo kind="Design System/Components/DropdownMenu/展示" name="單選"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">單選 — 檔案清單排序方式</span></LinkTo>
74
74
  </li>
75
75
  </ul>
76
76
  <p className="text-fg-muted mt-3">判斷不確定時:先看「選完之後畫面是否需要保留選中狀態」——需要就改用 Select / SelectMenu。下方的「DropdownMenu vs 選值元件」與「群組 vs 分隔線」範例提供更完整的對照。</p>
@@ -217,7 +217,7 @@ Item-level default / hover / focused / selected / disabled **色彩**由 MenuIte
217
217
  - **Disabled item**:`<DropdownMenuItem disabled>`(Radix 內建支援),視覺繼承 MenuItem SSOT(`text-fg-disabled` + `aria-disabled=true` + 鍵盤導覽 skip + 不觸發 onSelect)。
218
218
  - **Loading(async submenu / async items)**:DropdownMenu primitive 不獨立 own loading prop。async submenu 場景應由 consumer 在 `<DropdownMenuSub>` 內條件性渲 `<DropdownMenuItem disabled>` + spinner label(如「載入中...」);或 fetch options 前先 disable 整個 menu trigger。完整 loading body 替換 pattern 屬 SelectMenu scope,不在 DropdownMenu scope。
219
219
  - **Empty(no items / async fetch result empty)**:consumer 應條件性渲 `<DropdownMenuItem disabled>` 顯示「無可用動作」字樣;不渲空 menu。
220
- - **Dark mode / density**:走 MenuItem + Popover SSOT 自動 adapt;density 預設 lock `md`(M3 portal subtree convention)
220
+ - **Dark mode / density**:走 MenuItem + Popover SSOT 自動 adapt;density 繼承 page(不鎖;DropdownMenu item 高度 = field-height-{size} 隨 page density 變,鎖 md 會釘死 md-scale 對不上 lg 觸發點),SSOT 見 `tokens/density/density.spec.md`。
221
221
 
222
222
  ---
223
223
 
@@ -59,10 +59,10 @@ export const UsageGuidance: Story = {
59
59
  <p>適合 Empty 的真實業務場景(點擊跳轉「展示」頁範例):</p>
60
60
  <ul className="space-y-1">
61
61
  <li>
62
- <LinkTo kind="Design System/Components/Empty/展示" name="搜尋無結果"><span className="text-primary hover:underline font-medium cursor-pointer">搜尋無結果</span></LinkTo>
62
+ <LinkTo kind="Design System/Components/Empty/展示" name="搜尋無結果"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">搜尋無結果</span></LinkTo>
63
63
  </li>
64
64
  <li>
65
- <LinkTo kind="Design System/Components/Empty/展示" name="空清單"><span className="text-primary hover:underline font-medium cursor-pointer">空清單</span></LinkTo>
65
+ <LinkTo kind="Design System/Components/Empty/展示" name="空清單"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">空清單</span></LinkTo>
66
66
  </li>
67
67
  </ul>
68
68
  <p className="text-fg-muted mt-3">判斷不確定時:對照 spec.md「何時用 / 何時不用」段;若仍不符,改用近親元件(見下方「vs 近親」)。</p>
@@ -15,6 +15,8 @@ import { useRowSize } from '@/design-system/patterns/element-anatomy/item-anatom
15
15
  * desc → action = mt-6(24px)
16
16
  * title → desc = `var(--item-gap-label-desc-reading-lg)`(reading-lg tier token,item-anatomy SSOT;bare `--item-gap-label-desc` 已 retire)
17
17
  *
18
+ * description 字級隨 RowSizeContext 變(sm/md → text-body 14px,lg → text-body-lg 16px)。
19
+ *
18
20
  * Outer padding 由 consumer 容器決定(py-12 / py-6 / py-16 等)。
19
21
  */
20
22
 
@@ -58,7 +58,9 @@ components/
58
58
 
59
59
  ---
60
60
 
61
- ## Mode — 三種模式
61
+ ## Mode — 表單三態 (display 見下方 Display 段)
62
+
63
+ 下表涵蓋 Form-context 三態(edit / readonly / disabled);完整 `FieldMode` 為四值(`'edit' | 'display' | 'readonly' | 'disabled'`),`display` 模式於下方 `## Display` 段記載。
62
64
 
63
65
  | Mode | 底色 | 邊框 | 文字色 | 用途 |
64
66
  |------|------|------|--------|------|
@@ -226,14 +228,15 @@ Field 內的具體套用:
226
228
 
227
229
  ## 下拉箭頭(Select / Combobox)與類型身份 indicator
228
230
 
229
- Select / Combobox 的 ChevronDown、DatePicker 的 Calendar、TimePicker 的 Clock = **類型身份 indicator**(「這是什麼欄位」),**「是欄位」的所有狀態都顯示**(2026-06-10 user 拍板;對齊原生 select / MUI #19833 / Carbon read-only「keep icon signifiers de-emphasized」/ Accordion M24 precedent):
231
+ Select / Combobox 的 ChevronDown、DatePicker 的 Calendar、TimePicker 的 Clock = **類型身份 indicator**(「這是什麼欄位」)。**edit 顯示(可互動)/ readonly 不顯示 / disabled 顯示(灰示)**(2026-06-26 user 拍板;readonly = 純值顯示、不可開下拉 → 箭頭會誤導故不顯;disabled 保留對齊原生 `<select disabled>` 灰示箭頭 + MUI #19833 / Carbon read-only「keep icon signifiers de-emphasized」/ Accordion M24 precedent):
230
232
 
231
- - edit / readonly:`fg-muted`;**disabled:`fg-disabled`**(對齊上方 Icon 色彩原則)
233
+ - edit:`fg-muted`;**readonly:不顯示 indicator**;**disabled:`fg-disabled`**(對齊上方 Icon 色彩原則)
232
234
  - 不可互動(`pointer-events-none`)——下拉由 select 元素本身觸發
233
235
  - **Cell(naked variant)例外**:indicator 依 `showDisplayEndIcon`(= cell 的 isEditable)——非可編欄不顯(2026-05-10 cell canonical「indicator = editable affordance」);**可編欄的 disabled cell 顯示 + fg-disabled**(同表單邏輯)
234
236
  - locked(readonly/disabled)wrapper 並設 `aria-disabled`(disabled 時)——styled-disabled 非原生元素需明告 AT inactive,亦使 axe 正確套用 WCAG 1.4.3 inactive-UI 豁免
235
237
  - clearable 有值時:clear X 在左,ChevronDown 在右
236
- - 右側元素(clear + chevron)水平間距對齊 Field container padding token(具體值見 `field-wrapper.tsx`),跟 Input 一致
238
+ - **右側元素(clear / chevron / calendar / clock)右緣水平內距 = `--field-px`(12px,SSOT `tokens/uiSize/uiSize.css`),edit / readonly / disabled / display 全 mode 一致**(跟 Input 一致)。**tag 模式特例**:左側 `tagPadding` 用對稱 px-calc(≈8px)貼齊 tags、會吃掉右緣,故 tag 容器(含 readonly/disabled)**必 re-assert `paddingRight: var(--field-px)`** 對齊 edit;漏接 = chevron 右緣偏移 bug(2026-06-27 修 Select:354 / Combobox ReadonlyMultiSelect)
239
+ - **多行(Combobox tag wrap)垂直對齊**:tags 換行、容器動態變高時,右側 chevron **鎖第一行 tag 中線**(非整體置中)——容器 `items-start` + `ItemSuffix self-start` + `style={{ height: tagHeight }}`(sm 20 / md+lg 24)。對齊 item-anatomy「suffix 永遠 `h-[1lh]` 對齊第一行」canonical;edit / readonly / disabled 全 mode 一致(2026-06-27 補 readonly/disabled wrap 漏接)
237
240
 
238
241
  ## Select 顯示模式
239
242
 
@@ -246,9 +249,9 @@ Select 支援兩種顯示模式(`display` prop):
246
249
 
247
250
  `plain` 模式可搭配 `startIcon`(代表 value 的圖示,如狀態 icon;2026-05-01 由 `text` 改名 `plain`,rationale 見 `select.spec.md`)。
248
251
 
249
- `tag` 模式的 edit 用 hidden select overlay(跟 Combobox 同模式),Tag 用 `pointer-events-none`,點擊穿透到 select。右側元素水平間距對齊 Field container padding token(見 `field-wrapper.tsx`)。
252
+ `tag` 模式的 edit 用 hidden select overlay(跟 Combobox 同模式),Tag 用 `pointer-events-none`,點擊穿透到 select。右側元素右緣 = `--field-px`(見上方「右側元素」canonical;tag 模式 readonly/disabled 必 re-assert)。
250
253
 
251
- tagPadding 只在有 Tag 時才套用。Placeholder/空值狀態使用 fieldWrapper 的標準 px-3 padding,確保文字與邊框有足夠間距。
254
+ tagPadding 只在有 Tag 時才套用。Placeholder/空值狀態使用 fieldWrapper 的標準 `--field-px`(`px-[var(--field-px)]`)padding,確保文字與邊框有足夠間距。
252
255
 
253
256
  ---
254
257
 
@@ -57,9 +57,9 @@ export const fieldWrapperStyles = cva(
57
57
  naked: '',
58
58
  },
59
59
  size: {
60
- sm: 'text-body h-field-sm px-3 gap-2',
61
- md: 'text-body h-field-md px-3 gap-2',
62
- lg: 'text-body-lg h-field-lg px-3 gap-2',
60
+ sm: 'text-body h-field-sm px-[var(--field-px)] gap-2',
61
+ md: 'text-body h-field-md px-[var(--field-px)] gap-2',
62
+ lg: 'text-body-lg h-field-lg px-[var(--field-px)] gap-2',
63
63
  },
64
64
  },
65
65
  // mode x variant 交叉:visual chrome 由 compoundVariants 決定
@@ -98,7 +98,7 @@ export const fieldWrapperStyles = cva(
98
98
  mode: 'display',
99
99
  variant: 'default',
100
100
  // 2026-05-13 Q3 Path Ⅰ(user 拍板 Path Ⅰ 全 zero chrome + codex V2 verdict + field-controls.spec.md (d)):
101
- // default display = zero chrome — !px-0 !py-0 override size token 的 px-3,跟 Select / Combobox
101
+ // default display = zero chrome — !px-0 !py-0 override size token 的 px-[var(--field-px)],跟 Select / Combobox
102
102
  // / DatePicker / TimePicker / LinkInput non-D-path bare-span idiom 一致(Carbon read-only / Stripe
103
103
  // display / Notion property / Polaris readonly TextField 全 zero chrome)。
104
104
  className: 'bg-transparent border border-transparent !px-0 !py-0',
@@ -49,10 +49,10 @@ export const UsageGuidance: Story = {
49
49
  <div className="prose prose-sm max-w-prose mb-8">
50
50
  <p>適合 Field 的真實業務場景(點擊跳轉「展示」頁範例):</p>
51
51
  <ul className="space-y-1">
52
- <li><LinkTo kind="Design System/Components/Field/展示" name="垂直"><span className="text-primary hover:underline font-medium cursor-pointer">註冊 / 建立專案表單 — 引導式逐欄輸入(垂直佈局)</span></LinkTo></li>
53
- <li><LinkTo kind="Design System/Components/Field/展示" name="水平"><span className="text-primary hover:underline font-medium cursor-pointer">帳號設定 / 偏好設定頁 — 修改已知屬性(水平佈局)</span></LinkTo></li>
54
- <li><LinkTo kind="Design System/Components/Field/展示" name="混合控制元件的高度對齊"><span className="text-primary hover:underline font-medium cursor-pointer">同一表單混用 Input / Select / DatePicker 等控制元件</span></LinkTo></li>
55
- <li><LinkTo kind="Design System/Components/Field/展示" name="SegmentedControl 作為 Field 控制元件"><span className="text-primary hover:underline font-medium cursor-pointer">少量互斥選項(計費週期、版面密度)用 SegmentedControl 當控制元件</span></LinkTo></li>
52
+ <li><LinkTo kind="Design System/Components/Field/展示" name="垂直"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">註冊 / 建立專案表單 — 引導式逐欄輸入(垂直佈局)</span></LinkTo></li>
53
+ <li><LinkTo kind="Design System/Components/Field/展示" name="水平"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">帳號設定 / 偏好設定頁 — 修改已知屬性(水平佈局)</span></LinkTo></li>
54
+ <li><LinkTo kind="Design System/Components/Field/展示" name="混合控制元件的高度對齊"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">同一表單混用 Input / Select / DatePicker 等控制元件</span></LinkTo></li>
55
+ <li><LinkTo kind="Design System/Components/Field/展示" name="SegmentedControl 作為 Field 控制元件"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">少量互斥選項(計費週期、版面密度)用 SegmentedControl 當控制元件</span></LinkTo></li>
56
56
  </ul>
57
57
  <p className="text-fg-muted mt-3">判斷不確定時:對照 spec.md「何時用 / 何時不用」段;若仍不符,改用近親元件(見下方 vs 近親 段)。</p>
58
58
  </div>
@@ -43,19 +43,19 @@ export const UsageGuidance: Story = {
43
43
  <p>適合 FileItem 的真實業務場景(點擊跳轉「展示」頁範例):</p>
44
44
  <ul className="space-y-1">
45
45
  <li>
46
- <LinkTo kind="Design System/Components/FileItem/展示" name="豐富樣式"><span className="text-primary hover:underline font-medium cursor-pointer">圖片 / 設計稿上傳 — 需要縮圖預覽(豐富樣式)</span></LinkTo>
46
+ <LinkTo kind="Design System/Components/FileItem/展示" name="豐富樣式"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">圖片 / 設計稿上傳 — 需要縮圖預覽(豐富樣式)</span></LinkTo>
47
47
  </li>
48
48
  <li>
49
- <LinkTo kind="Design System/Components/FileItem/展示" name="緊湊樣式"><span className="text-primary hover:underline font-medium cursor-pointer">CSV / JSON 批次匯入的密集清單(緊湊樣式)</span></LinkTo>
49
+ <LinkTo kind="Design System/Components/FileItem/展示" name="緊湊樣式"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">CSV / JSON 批次匯入的密集清單(緊湊樣式)</span></LinkTo>
50
50
  </li>
51
51
  <li>
52
- <LinkTo kind="Design System/Components/FileItem/展示" name="懸停替換"><span className="text-primary hover:underline font-medium cursor-pointer">上傳完成後滑入整列、狀態 icon 換成下載鈕(懸停替換)</span></LinkTo>
52
+ <LinkTo kind="Design System/Components/FileItem/展示" name="懸停替換"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">上傳完成後滑入整列、狀態 icon 換成下載鈕(懸停替換)</span></LinkTo>
53
53
  </li>
54
54
  <li>
55
- <LinkTo kind="Design System/Components/FileItem/展示" name="已上傳"><span className="text-primary hover:underline font-medium cursor-pointer">工單 / 訊息附件的已上傳靜態檔案</span></LinkTo>
55
+ <LinkTo kind="Design System/Components/FileItem/展示" name="已上傳"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">工單 / 訊息附件的已上傳靜態檔案</span></LinkTo>
56
56
  </li>
57
57
  <li>
58
- <LinkTo kind="Design System/Components/FileItem/展示" name="緊湊 混合"><span className="text-primary hover:underline font-medium cursor-pointer">同一批次混合上傳中 / 完成 / 失敗狀態的清單</span></LinkTo>
58
+ <LinkTo kind="Design System/Components/FileItem/展示" name="緊湊 混合"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">同一批次混合上傳中 / 完成 / 失敗狀態的清單</span></LinkTo>
59
59
  </li>
60
60
  </ul>
61
61
  <p className="text-fg-muted mt-3">判斷不確定時:對照 spec.md「何時用 / 何時不用」段;若仍不符,改用近親元件(見 <code>Vs*Rule</code> stories)。</p>
@@ -181,6 +181,7 @@ export const StatusProgressRule: Story = {
181
181
  name="users-export.csv"
182
182
  description="1.2 MB"
183
183
  status="completed"
184
+ surface="upload-manager"
184
185
  mode="rich"
185
186
  />
186
187
  </Rule>
@@ -64,16 +64,16 @@ export const UsageGuidance: Story = {
64
64
  <p>適合 FileUpload 的真實業務場景(點擊跳轉「展示」頁範例):</p>
65
65
  <ul className="space-y-1">
66
66
  <li>
67
- <LinkTo kind="Design System/Components/FileUpload/展示" name="單檔上傳"><span className="text-primary hover:underline font-medium cursor-pointer">履歷 / 大頭貼等單檔上傳</span></LinkTo>
67
+ <LinkTo kind="Design System/Components/FileUpload/展示" name="單檔上傳"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">履歷 / 大頭貼等單檔上傳</span></LinkTo>
68
68
  </li>
69
69
  <li>
70
- <LinkTo kind="Design System/Components/FileUpload/展示" name="批次上傳"><span className="text-primary hover:underline font-medium cursor-pointer">相簿照片 / 多檔附件批次上傳</span></LinkTo>
70
+ <LinkTo kind="Design System/Components/FileUpload/展示" name="批次上傳"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">相簿照片 / 多檔附件批次上傳</span></LinkTo>
71
71
  </li>
72
72
  <li>
73
- <LinkTo kind="Design System/Components/FileUpload/展示" name="內建 files 屬性"><span className="text-primary hover:underline font-medium cursor-pointer">上傳後直接顯示進度清單(內建 files 屬性)</span></LinkTo>
73
+ <LinkTo kind="Design System/Components/FileUpload/展示" name="內建 files 屬性"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">上傳後直接顯示進度清單(內建 files 屬性)</span></LinkTo>
74
74
  </li>
75
75
  <li>
76
- <LinkTo kind="Design System/Components/FileUpload/展示" name="自訂內容"><span className="text-primary hover:underline font-medium cursor-pointer">品牌化上傳區 — 自訂 dropzone 內容</span></LinkTo>
76
+ <LinkTo kind="Design System/Components/FileUpload/展示" name="自訂內容"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">品牌化上傳區 — 自訂 dropzone 內容</span></LinkTo>
77
77
  </li>
78
78
  </ul>
79
79
  <p className="text-fg-muted mt-3">判斷不確定時:對照 spec.md「何時用 / 何時不用」段;若仍不符,改用近親元件(見 <code>Vs*Rule</code> stories)。</p>
@@ -93,10 +93,10 @@ export const UsageGuidance: Story = {
93
93
  note="drag-over 只用邊框顏色(border-primary,底維持 surface 不變 bg)傳達狀態。加 scale 會讓區塊在拖放瞬間晃動、使用者滑鼠與 drop target 錯位;加 shadow 和元件 elevation 體系衝突。"
94
94
  >
95
95
  <div className="flex flex-col gap-2">
96
- <div className="border-2 border-dashed border-primary bg-surface rounded-md px-6 py-10 text-center text-caption text-fg-muted">
96
+ <div className="border-2 border-dashed border-primary bg-surface rounded-md p-[var(--layout-space-loose)] text-center text-caption text-fg-muted">
97
97
  ✓ 僅改邊框顏色(dashed primary,底維持 surface)
98
98
  </div>
99
- <div className="border-2 border-dashed border-primary bg-surface rounded-md px-6 py-10 text-center text-caption text-fg-muted scale-105 shadow-[var(--elevation-200)]">
99
+ <div className="border-2 border-dashed border-primary bg-surface rounded-md p-[var(--layout-space-loose)] text-center text-caption text-fg-muted scale-105 shadow-[var(--elevation-200)]">
100
100
  ✗ scale + shadow — 視覺噪音,與 elevation 系統衝突
101
101
  </div>
102
102
  </div>
@@ -140,7 +140,7 @@ FileUpload 是**拖放 / 點擊上傳區塊**——可拖曳檔案進入或點
140
140
 
141
141
  ## A11y 預設
142
142
 
143
- - `role="button"` + `tabIndex=0`(disabled 時 `-1`)
143
+ - `role="button"` + `tabIndex=0`(disabled 或 loading 時 `-1`)
144
144
  - Enter / Space 鍵觸發檔案選取浮窗(模擬 click)
145
145
  - `aria-disabled={true}` 當 disabled
146
146
  - `<input type="file">` 以 `className="hidden"`(`display:none`)隱藏 — 移出無障礙樹、不可聚焦;互動由外層 `role="button"` wrapper 承載。Accessible name 來自 wrapper 內 Empty 的 title + description 文字(name-from-content),非 input 本身
@@ -106,19 +106,19 @@ export const UsageGuidance: Story = {
106
106
  <p>適合 FileViewer 的真實業務場景(點擊跳轉「展示」頁範例):</p>
107
107
  <ul className="space-y-1">
108
108
  <li>
109
- <LinkTo kind="Design System/Components/FileViewer/展示" name="Jira — 附件多圖檢視"><span className="text-primary hover:underline font-medium cursor-pointer">Jira — 附件多圖檢視</span></LinkTo>
109
+ <LinkTo kind="Design System/Components/FileViewer/展示" name="Jira — 附件多圖檢視"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">Jira — 附件多圖檢視</span></LinkTo>
110
110
  </li>
111
111
  <li>
112
- <LinkTo kind="Design System/Components/FileViewer/展示" name="Notion — 頁內配圖相簿"><span className="text-primary hover:underline font-medium cursor-pointer">Notion — 頁面配圖相簿瀏覽</span></LinkTo>
112
+ <LinkTo kind="Design System/Components/FileViewer/展示" name="Notion — 頁內配圖相簿"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">Notion — 頁面配圖相簿瀏覽</span></LinkTo>
113
113
  </li>
114
114
  <li>
115
- <LinkTo kind="Design System/Components/FileViewer/展示" name="Figma — 單檔縮放聚焦"><span className="text-primary hover:underline font-medium cursor-pointer">Figma — 設計稿單檔縮放聚焦檢視</span></LinkTo>
115
+ <LinkTo kind="Design System/Components/FileViewer/展示" name="Figma — 單檔縮放聚焦"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">Figma — 設計稿單檔縮放聚焦檢視</span></LinkTo>
116
116
  </li>
117
117
  <li>
118
- <LinkTo kind="Design System/Components/FileViewer/展示" name="Gmail — 多附件預覽"><span className="text-primary hover:underline font-medium cursor-pointer">Gmail — 信件多附件快速預覽</span></LinkTo>
118
+ <LinkTo kind="Design System/Components/FileViewer/展示" name="Gmail — 多附件預覽"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">Gmail — 信件多附件快速預覽</span></LinkTo>
119
119
  </li>
120
120
  <li>
121
- <LinkTo kind="Design System/Components/FileViewer/展示" name="活動相集 — 縮圖膠卷展開"><span className="text-primary hover:underline font-medium cursor-pointer">活動相集 — 開啟縮圖膠卷瀏覽跳轉</span></LinkTo>
121
+ <LinkTo kind="Design System/Components/FileViewer/展示" name="活動相集 — 縮圖膠卷展開"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">活動相集 — 開啟縮圖膠卷瀏覽跳轉</span></LinkTo>
122
122
  </li>
123
123
  </ul>
124
124
  <p className="text-fg-muted mt-3">判斷不確定時:對照 spec.md「何時用 / 何時不用」段;若仍不符,改用近親元件(見 <code>Vs*Rule</code> stories)。</p>
@@ -50,19 +50,19 @@ export const UsageGuidance: Story = {
50
50
  <p>適合 HoverCard 的真實業務場景(點擊跳轉「展示」頁範例):</p>
51
51
  <ul className="space-y-1">
52
52
  <li>
53
- <LinkTo kind="Design System/Internal/HoverCard/展示" name="人員頭像 ProfileCard"><span className="text-primary hover:underline font-medium cursor-pointer">人員頭像 ProfileCard</span></LinkTo>
53
+ <LinkTo kind="Design System/Internal/HoverCard/展示" name="人員頭像 ProfileCard"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">人員頭像 ProfileCard</span></LinkTo>
54
54
  </li>
55
55
  <li>
56
- <LinkTo kind="Design System/Internal/HoverCard/展示" name="連結預覽卡"><span className="text-primary hover:underline font-medium cursor-pointer">連結預覽卡</span></LinkTo>
56
+ <LinkTo kind="Design System/Internal/HoverCard/展示" name="連結預覽卡"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">連結預覽卡</span></LinkTo>
57
57
  </li>
58
58
  <li>
59
- <LinkTo kind="Design System/Internal/HoverCard/展示" name="溢出清單"><span className="text-primary hover:underline font-medium cursor-pointer">溢出清單</span></LinkTo>
59
+ <LinkTo kind="Design System/Internal/HoverCard/展示" name="溢出清單"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">溢出清單</span></LinkTo>
60
60
  </li>
61
61
  <li>
62
- <LinkTo kind="Design System/Internal/HoverCard/展示" name="儲存庫資訊卡"><span className="text-primary hover:underline font-medium cursor-pointer">Repository 資訊卡</span></LinkTo>
62
+ <LinkTo kind="Design System/Internal/HoverCard/展示" name="儲存庫資訊卡"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">Repository 資訊卡</span></LinkTo>
63
63
  </li>
64
64
  <li>
65
- <LinkTo kind="Design System/Internal/HoverCard/展示" name="觸發點類型與延遲"><span className="text-primary hover:underline font-medium cursor-pointer">Trigger 類型與 delay</span></LinkTo>
65
+ <LinkTo kind="Design System/Internal/HoverCard/展示" name="觸發點類型與延遲"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">Trigger 類型與 delay</span></LinkTo>
66
66
  </li>
67
67
  </ul>
68
68
  <p className="text-fg-muted mt-3">判斷不確定時:對照 spec.md「何時用 / 何時不用」段;若仍不符,改用近親元件(見下方「vs 近親」)。</p>
@@ -193,7 +193,7 @@ export const PureBehaviorPrimitiveRule: Story = {
193
193
  <HoverCardTrigger asChild>
194
194
  <Button variant="tertiary" size="sm">深色 Tooltip 樣式</Button>
195
195
  </HoverCardTrigger>
196
- <HoverCardContent className="bg-tooltip text-inverse-fg rounded-md px-3 py-2" data-theme="dark">
196
+ <HoverCardContent className="bg-tooltip text-on-emphasis rounded-md px-3 py-2" data-theme="dark">
197
197
  <div className="w-48 text-caption">OverflowIndicator 風格:深底 + compact</div>
198
198
  </HoverCardContent>
199
199
  </HoverCard>
@@ -51,9 +51,9 @@ interface SizeSpec {
51
51
  }
52
52
 
53
53
  const SIZE_SPECS: Record<SizeKey, SizeSpec> = {
54
- sm: { heightToken: 'h-field-sm', height: '28px', pxToken: 'px-3', px: 12, gapToken: 'gap-2', gap: 8, fontToken: 'text-body', font: '14px', icon: 16, actionHover: 18 },
55
- md: { heightToken: 'h-field-md', height: '32px', pxToken: 'px-3', px: 12, gapToken: 'gap-2', gap: 8, fontToken: 'text-body', font: '14px', icon: 16, actionHover: 18 },
56
- lg: { heightToken: 'h-field-lg', height: '36px', pxToken: 'px-3', px: 12, gapToken: 'gap-2', gap: 8, fontToken: 'text-body-lg', font: '16px', icon: 20, actionHover: 22 },
54
+ sm: { heightToken: 'h-field-sm', height: '28px', pxToken: 'px-[var(--field-px)]', px: 12, gapToken: 'gap-2', gap: 8, fontToken: 'text-body', font: '14px', icon: 16, actionHover: 18 },
55
+ md: { heightToken: 'h-field-md', height: '32px', pxToken: 'px-[var(--field-px)]', px: 12, gapToken: 'gap-2', gap: 8, fontToken: 'text-body', font: '14px', icon: 16, actionHover: 18 },
56
+ lg: { heightToken: 'h-field-lg', height: '36px', pxToken: 'px-[var(--field-px)]', px: 12, gapToken: 'gap-2', gap: 8, fontToken: 'text-body-lg', font: '16px', icon: 20, actionHover: 22 },
57
57
  }
58
58
 
59
59
  const MODE_DESC: Record<ModeKey, string> = {
@@ -50,10 +50,10 @@ export const UsageGuidance: Story = {
50
50
  <div className="prose prose-sm max-w-prose mb-8">
51
51
  <p>適合 Input 的真實業務場景(點擊跳轉「展示」頁範例):</p>
52
52
  <ul className="space-y-1">
53
- <li><LinkTo kind="Design System/Components/Input/展示" name="四模式"><span className="text-primary hover:underline font-medium cursor-pointer">商品名稱欄位的編輯 / 純展示 / 唯讀 / 停用四模式</span></LinkTo></li>
54
- <li><LinkTo kind="Design System/Components/Input/展示" name="尺寸與 Button 對齊"><span className="text-primary hover:underline font-medium cursor-pointer">搜尋列 — 輸入框與按鈕並排等高</span></LinkTo></li>
55
- <li><LinkTo kind="Design System/Components/Input/展示" name="尾端操作"><span className="text-primary hover:underline font-medium cursor-pointer">密碼顯示切換 / 搜尋清除等尾端操作</span></LinkTo></li>
56
- <li><LinkTo kind="Design System/Components/Input/展示" name="錯誤狀態"><span className="text-primary hover:underline font-medium cursor-pointer">Email 格式錯誤的驗證回饋</span></LinkTo></li>
53
+ <li><LinkTo kind="Design System/Components/Input/展示" name="四模式"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">商品名稱欄位的編輯 / 純展示 / 唯讀 / 停用四模式</span></LinkTo></li>
54
+ <li><LinkTo kind="Design System/Components/Input/展示" name="尺寸與 Button 對齊"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">搜尋列 — 輸入框與按鈕並排等高</span></LinkTo></li>
55
+ <li><LinkTo kind="Design System/Components/Input/展示" name="尾端操作"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">密碼顯示切換 / 搜尋清除等尾端操作</span></LinkTo></li>
56
+ <li><LinkTo kind="Design System/Components/Input/展示" name="錯誤狀態"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">Email 格式錯誤的驗證回饋</span></LinkTo></li>
57
57
  </ul>
58
58
  <p className="text-fg-muted mt-3">判斷不確定時:對照 spec.md「何時用 / 何時不用」段;若仍不符,改用近親元件(見下方 vs 近親 段)。</p>
59
59
  </div>
@@ -92,9 +92,9 @@ interface SizeSpec {
92
92
  }
93
93
 
94
94
  const SIZE_SPECS: Record<SizeKey, SizeSpec> = {
95
- sm: { heightToken: 'h-field-sm', height: '28px', pxToken: 'px-3', px: 12, gapToken: 'gap-2', gap: 8, fontToken: 'text-body', font: '14px', icon: 16, actionHover: 18 },
96
- md: { heightToken: 'h-field-md', height: '32px', pxToken: 'px-3', px: 12, gapToken: 'gap-2', gap: 8, fontToken: 'text-body', font: '14px', icon: 16, actionHover: 18 },
97
- lg: { heightToken: 'h-field-lg', height: '36px', pxToken: 'px-3', px: 12, gapToken: 'gap-2', gap: 8, fontToken: 'text-body-lg', font: '16px', icon: 20, actionHover: 22 },
95
+ sm: { heightToken: 'h-field-sm', height: '28px', pxToken: 'px-[var(--field-px)]', px: 12, gapToken: 'gap-2', gap: 8, fontToken: 'text-body', font: '14px', icon: 16, actionHover: 18 },
96
+ md: { heightToken: 'h-field-md', height: '32px', pxToken: 'px-[var(--field-px)]', px: 12, gapToken: 'gap-2', gap: 8, fontToken: 'text-body', font: '14px', icon: 16, actionHover: 18 },
97
+ lg: { heightToken: 'h-field-lg', height: '36px', pxToken: 'px-[var(--field-px)]', px: 12, gapToken: 'gap-2', gap: 8, fontToken: 'text-body-lg', font: '16px', icon: 20, actionHover: 22 },
98
98
  }
99
99
 
100
100
  /* ═══════════════════════════════════════════════════════════════════════════
@@ -47,19 +47,19 @@ export const UsageGuidance: Story = {
47
47
  <p>適合 LinkInput 的真實業務場景(點擊跳轉「展示」頁範例):</p>
48
48
  <ul className="space-y-1">
49
49
  <li>
50
- <LinkTo kind="Design System/Components/LinkInput/展示" name="空值"><span className="text-primary hover:underline font-medium cursor-pointer">空值</span></LinkTo>
50
+ <LinkTo kind="Design System/Components/LinkInput/展示" name="空值"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">空值</span></LinkTo>
51
51
  </li>
52
52
  <li>
53
- <LinkTo kind="Design System/Components/LinkInput/展示" name="失焦驗證"><span className="text-primary hover:underline font-medium cursor-pointer">Blur 驗證</span></LinkTo>
53
+ <LinkTo kind="Design System/Components/LinkInput/展示" name="失焦驗證"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">Blur 驗證</span></LinkTo>
54
54
  </li>
55
55
  <li>
56
- <LinkTo kind="Design System/Components/LinkInput/展示" name="尺寸"><span className="text-primary hover:underline font-medium cursor-pointer">尺寸</span></LinkTo>
56
+ <LinkTo kind="Design System/Components/LinkInput/展示" name="尺寸"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">尺寸</span></LinkTo>
57
57
  </li>
58
58
  <li>
59
- <LinkTo kind="Design System/Components/LinkInput/展示" name="四模式"><span className="text-primary hover:underline font-medium cursor-pointer">四模式</span></LinkTo>
59
+ <LinkTo kind="Design System/Components/LinkInput/展示" name="四模式"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">四模式</span></LinkTo>
60
60
  </li>
61
61
  <li>
62
- <LinkTo kind="Design System/Components/LinkInput/展示" name="展示樣式"><span className="text-primary hover:underline font-medium cursor-pointer">展示樣式</span></LinkTo>
62
+ <LinkTo kind="Design System/Components/LinkInput/展示" name="展示樣式"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">展示樣式</span></LinkTo>
63
63
  </li>
64
64
  </ul>
65
65
  <p className="text-fg-muted mt-3">判斷不確定時:先確認這個值是不是「儲存後使用者會想直接點開的完整網址」。若不是(例如純字串代號、email、內部路徑),改用 Input。下方「vs 近親」段有正反對照範例。</p>
@@ -24,19 +24,19 @@ export const UsageGuidance: Story = {
24
24
  <p>適合 Menu 的真實業務場景(點擊跳轉「展示」頁範例):</p>
25
25
  <ul className="space-y-1">
26
26
  <li>
27
- <LinkTo kind="Design System/Internal/Menu/展示" name="基本"><span className="text-primary hover:underline font-medium cursor-pointer">信箱資料夾切換選單(收件匣 / 草稿 / 已傳送)— 純文字選項</span></LinkTo>
27
+ <LinkTo kind="Design System/Internal/Menu/展示" name="基本"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">信箱資料夾切換選單(收件匣 / 草稿 / 已傳送)— 純文字選項</span></LinkTo>
28
28
  </li>
29
29
  <li>
30
- <LinkTo kind="Design System/Internal/Menu/展示" name="前置圖示 + 說明文字"><span className="text-primary hover:underline font-medium cursor-pointer">通知偏好設定選單 — 前置圖示 + 說明文字</span></LinkTo>
30
+ <LinkTo kind="Design System/Internal/Menu/展示" name="前置圖示 + 說明文字"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">通知偏好設定選單 — 前置圖示 + 說明文字</span></LinkTo>
31
31
  </li>
32
32
  <li>
33
- <LinkTo kind="Design System/Internal/Menu/展示" name="頭像"><span className="text-primary hover:underline font-medium cursor-pointer">指派負責人選單 — 人員頭像列</span></LinkTo>
33
+ <LinkTo kind="Design System/Internal/Menu/展示" name="頭像"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">指派負責人選單 — 人員頭像列</span></LinkTo>
34
34
  </li>
35
35
  <li>
36
- <LinkTo kind="Design System/Internal/Menu/展示" name="頭像 + 說明文字"><span className="text-primary hover:underline font-medium cursor-pointer">跨部門選人 — 頭像 + 部門說明文字</span></LinkTo>
36
+ <LinkTo kind="Design System/Internal/Menu/展示" name="頭像 + 說明文字"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">跨部門選人 — 頭像 + 部門說明文字</span></LinkTo>
37
37
  </li>
38
38
  <li>
39
- <LinkTo kind="Design System/Internal/Menu/展示" name="多選"><span className="text-primary hover:underline font-medium cursor-pointer">通知管道多選(電子郵件 / 推播 / Slack)</span></LinkTo>
39
+ <LinkTo kind="Design System/Internal/Menu/展示" name="多選"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">通知管道多選(電子郵件 / 推播 / Slack)</span></LinkTo>
40
40
  </li>
41
41
  </ul>
42
42
  <p className="text-fg-muted mt-3">判斷不確定時:先確認情境是否屬於上面這些「在選單裡挑一個或多個選項」的場景;若不是(例如是可編輯的表單欄位、或需要大塊內容的列表行),改用對應的近親元件,下方「vs 近親元件」段有說明。</p>
@@ -66,10 +66,10 @@ export const CompositionRules: Story = {
66
66
  <p>MenuItem 是選單選項列的共用排版元件,由以下三類選單元件包起來使用,不會直接寫在產品頁面裡:</p>
67
67
 
68
68
  <h4>Pattern 1 — DropdownMenu + MenuItem(action menu)</h4>
69
- <p>使用者點擊觸發某個 action(複製 / 刪除 / 重新命名)→ <LinkTo kind="Design System/Components/DropdownMenu/展示" name="基本"><span className="text-primary hover:underline font-medium cursor-pointer">DropdownMenu</span></LinkTo>(Radix 控制 open / close + keyboard nav,MenuItem 提供 row layout)。</p>
69
+ <p>使用者點擊觸發某個 action(複製 / 刪除 / 重新命名)→ <LinkTo kind="Design System/Components/DropdownMenu/展示" name="基本"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">DropdownMenu</span></LinkTo>(Radix 控制 open / close + keyboard nav,MenuItem 提供 row layout)。</p>
70
70
 
71
71
  <h4>Pattern 2 — SelectMenu(Popover + Command + MenuItem)— form value 選擇</h4>
72
- <p>使用者選一個 / 多個值寫回 form → <LinkTo kind="Design System/Components/Select/展示" name="四模式"><span className="text-primary hover:underline font-medium cursor-pointer">Select</span></LinkTo> / <LinkTo kind="Design System/Components/Combobox/展示" name="四模式"><span className="text-primary hover:underline font-medium cursor-pointer">Combobox</span></LinkTo>(內部已組合 SelectMenu + cmdk + MenuItem)。</p>
72
+ <p>使用者選一個 / 多個值寫回 form → <LinkTo kind="Design System/Components/Select/展示" name="四模式"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">Select</span></LinkTo> / <LinkTo kind="Design System/Components/Combobox/展示" name="四模式"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">Combobox</span></LinkTo>(內部已組合 SelectMenu + cmdk + MenuItem)。</p>
73
73
 
74
74
  <h4>Pattern 3 — ContextMenu + MenuItem(右鍵選單,未來)</h4>
75
75
  <p>右鍵觸發 contextual action → 預留消費者(Radix ContextMenu + MenuItem 同 layout primitive)。</p>
@@ -448,7 +448,7 @@ export const VariantIconMap: Story = {
448
448
  <H3>Subtle 樣式視覺</H3>
449
449
  <Desc>
450
450
  Notice 本身不設 bg / border。此處 shell 為 Alert consumer 提供的 subtle container(
451
- <code className="font-mono text-footnote mx-1">bg-*-subtle + border {`{hue}-hover`}</code>
451
+ <code className="font-mono text-footnote mx-1">bg-*-subtle + border {`{hue}-text`}</code>
452
452
  ),展示 icon 色彩在 subtle surface 上的對比。Solid(dark bg + 白字 icon)對照請查
453
453
  <code className="font-mono text-footnote mx-1">alert.anatomy.stories.tsx</code>
454
454