@hjmds/design-contracts 0.8.2

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 (353) hide show
  1. package/README.md +208 -0
  2. package/dist/alert-dialog.d.ts +102 -0
  3. package/dist/alert-dialog.d.ts.map +1 -0
  4. package/dist/alert-dialog.js +136 -0
  5. package/dist/alert-dialog.js.map +1 -0
  6. package/dist/base-recipes.d.ts +184 -0
  7. package/dist/base-recipes.d.ts.map +1 -0
  8. package/dist/base-recipes.js +129 -0
  9. package/dist/base-recipes.js.map +1 -0
  10. package/dist/behaviors.d.ts +1254 -0
  11. package/dist/behaviors.d.ts.map +1 -0
  12. package/dist/behaviors.js +972 -0
  13. package/dist/behaviors.js.map +1 -0
  14. package/dist/bottom-navigation-defaults.d.ts +13 -0
  15. package/dist/bottom-navigation-defaults.d.ts.map +1 -0
  16. package/dist/bottom-navigation-defaults.js +10 -0
  17. package/dist/bottom-navigation-defaults.js.map +1 -0
  18. package/dist/bottom-navigation.d.ts +114 -0
  19. package/dist/bottom-navigation.d.ts.map +1 -0
  20. package/dist/bottom-navigation.js +223 -0
  21. package/dist/bottom-navigation.js.map +1 -0
  22. package/dist/breadcrumb.d.ts +97 -0
  23. package/dist/breadcrumb.d.ts.map +1 -0
  24. package/dist/breadcrumb.js +99 -0
  25. package/dist/breadcrumb.js.map +1 -0
  26. package/dist/calendar.d.ts +285 -0
  27. package/dist/calendar.d.ts.map +1 -0
  28. package/dist/calendar.js +297 -0
  29. package/dist/calendar.js.map +1 -0
  30. package/dist/card.d.ts +39 -0
  31. package/dist/card.d.ts.map +1 -0
  32. package/dist/card.js +50 -0
  33. package/dist/card.js.map +1 -0
  34. package/dist/carousel.d.ts +180 -0
  35. package/dist/carousel.d.ts.map +1 -0
  36. package/dist/carousel.js +172 -0
  37. package/dist/carousel.js.map +1 -0
  38. package/dist/catalog.d.ts +7158 -0
  39. package/dist/catalog.d.ts.map +1 -0
  40. package/dist/catalog.js +220 -0
  41. package/dist/catalog.js.map +1 -0
  42. package/dist/collection.d.ts +123 -0
  43. package/dist/collection.d.ts.map +1 -0
  44. package/dist/collection.js +211 -0
  45. package/dist/collection.js.map +1 -0
  46. package/dist/color-references.d.ts +46 -0
  47. package/dist/color-references.d.ts.map +1 -0
  48. package/dist/color-references.js +39 -0
  49. package/dist/color-references.js.map +1 -0
  50. package/dist/colors.d.ts +56 -0
  51. package/dist/colors.d.ts.map +1 -0
  52. package/dist/colors.js +90 -0
  53. package/dist/colors.js.map +1 -0
  54. package/dist/command-palette.d.ts +240 -0
  55. package/dist/command-palette.d.ts.map +1 -0
  56. package/dist/command-palette.js +97 -0
  57. package/dist/command-palette.js.map +1 -0
  58. package/dist/component-contracts.d.ts +137 -0
  59. package/dist/component-contracts.d.ts.map +1 -0
  60. package/dist/component-contracts.js +53 -0
  61. package/dist/component-contracts.js.map +1 -0
  62. package/dist/component-definitions.d.ts +135 -0
  63. package/dist/component-definitions.d.ts.map +1 -0
  64. package/dist/component-definitions.js +142 -0
  65. package/dist/component-definitions.js.map +1 -0
  66. package/dist/component-recipes.d.ts +3583 -0
  67. package/dist/component-recipes.d.ts.map +1 -0
  68. package/dist/component-recipes.js +1503 -0
  69. package/dist/component-recipes.js.map +1 -0
  70. package/dist/component-references.d.ts +416 -0
  71. package/dist/component-references.d.ts.map +1 -0
  72. package/dist/component-references.js +140 -0
  73. package/dist/component-references.js.map +1 -0
  74. package/dist/content-state.d.ts +104 -0
  75. package/dist/content-state.d.ts.map +1 -0
  76. package/dist/content-state.js +116 -0
  77. package/dist/content-state.js.map +1 -0
  78. package/dist/counter-badge-recipe.d.ts +80 -0
  79. package/dist/counter-badge-recipe.d.ts.map +1 -0
  80. package/dist/counter-badge-recipe.js +44 -0
  81. package/dist/counter-badge-recipe.js.map +1 -0
  82. package/dist/counter-badge.d.ts +12 -0
  83. package/dist/counter-badge.d.ts.map +1 -0
  84. package/dist/counter-badge.js +21 -0
  85. package/dist/counter-badge.js.map +1 -0
  86. package/dist/data-table.d.ts +203 -0
  87. package/dist/data-table.d.ts.map +1 -0
  88. package/dist/data-table.js +182 -0
  89. package/dist/data-table.js.map +1 -0
  90. package/dist/date-picker.d.ts +268 -0
  91. package/dist/date-picker.d.ts.map +1 -0
  92. package/dist/date-picker.js +168 -0
  93. package/dist/date-picker.js.map +1 -0
  94. package/dist/description-list.d.ts +68 -0
  95. package/dist/description-list.d.ts.map +1 -0
  96. package/dist/description-list.js +85 -0
  97. package/dist/description-list.js.map +1 -0
  98. package/dist/design-system-provider.d.ts +80 -0
  99. package/dist/design-system-provider.d.ts.map +1 -0
  100. package/dist/design-system-provider.js +147 -0
  101. package/dist/design-system-provider.js.map +1 -0
  102. package/dist/evidence.d.ts +49 -0
  103. package/dist/evidence.d.ts.map +1 -0
  104. package/dist/evidence.js +133 -0
  105. package/dist/evidence.js.map +1 -0
  106. package/dist/file-picker.d.ts +183 -0
  107. package/dist/file-picker.d.ts.map +1 -0
  108. package/dist/file-picker.js +224 -0
  109. package/dist/file-picker.js.map +1 -0
  110. package/dist/floating-action-button.d.ts +143 -0
  111. package/dist/floating-action-button.d.ts.map +1 -0
  112. package/dist/floating-action-button.js +149 -0
  113. package/dist/floating-action-button.js.map +1 -0
  114. package/dist/form.d.ts +143 -0
  115. package/dist/form.d.ts.map +1 -0
  116. package/dist/form.js +206 -0
  117. package/dist/form.js.map +1 -0
  118. package/dist/foundations.d.ts +300 -0
  119. package/dist/foundations.d.ts.map +1 -0
  120. package/dist/foundations.js +238 -0
  121. package/dist/foundations.js.map +1 -0
  122. package/dist/grid.d.ts +75 -0
  123. package/dist/grid.d.ts.map +1 -0
  124. package/dist/grid.js +133 -0
  125. package/dist/grid.js.map +1 -0
  126. package/dist/icon-button-recipe.d.ts +99 -0
  127. package/dist/icon-button-recipe.d.ts.map +1 -0
  128. package/dist/icon-button-recipe.js +53 -0
  129. package/dist/icon-button-recipe.js.map +1 -0
  130. package/dist/icon.d.ts +41 -0
  131. package/dist/icon.d.ts.map +1 -0
  132. package/dist/icon.js +147 -0
  133. package/dist/icon.js.map +1 -0
  134. package/dist/image.d.ts +82 -0
  135. package/dist/image.d.ts.map +1 -0
  136. package/dist/image.js +100 -0
  137. package/dist/image.js.map +1 -0
  138. package/dist/index.d.ts +58 -0
  139. package/dist/index.d.ts.map +1 -0
  140. package/dist/index.js +66 -0
  141. package/dist/index.js.map +1 -0
  142. package/dist/layout.d.ts +118 -0
  143. package/dist/layout.d.ts.map +1 -0
  144. package/dist/layout.js +118 -0
  145. package/dist/layout.js.map +1 -0
  146. package/dist/link.d.ts +57 -0
  147. package/dist/link.d.ts.map +1 -0
  148. package/dist/link.js +142 -0
  149. package/dist/link.js.map +1 -0
  150. package/dist/load-more.d.ts +64 -0
  151. package/dist/load-more.d.ts.map +1 -0
  152. package/dist/load-more.js +124 -0
  153. package/dist/load-more.js.map +1 -0
  154. package/dist/mentions.d.ts +67 -0
  155. package/dist/mentions.d.ts.map +1 -0
  156. package/dist/mentions.js +107 -0
  157. package/dist/mentions.js.map +1 -0
  158. package/dist/number-field.d.ts +208 -0
  159. package/dist/number-field.d.ts.map +1 -0
  160. package/dist/number-field.js +247 -0
  161. package/dist/number-field.js.map +1 -0
  162. package/dist/otp-field.d.ts +152 -0
  163. package/dist/otp-field.d.ts.map +1 -0
  164. package/dist/otp-field.js +117 -0
  165. package/dist/otp-field.js.map +1 -0
  166. package/dist/pagination.d.ts +181 -0
  167. package/dist/pagination.d.ts.map +1 -0
  168. package/dist/pagination.js +226 -0
  169. package/dist/pagination.js.map +1 -0
  170. package/dist/password-field.d.ts +187 -0
  171. package/dist/password-field.d.ts.map +1 -0
  172. package/dist/password-field.js +120 -0
  173. package/dist/password-field.js.map +1 -0
  174. package/dist/popover.d.ts +152 -0
  175. package/dist/popover.d.ts.map +1 -0
  176. package/dist/popover.js +137 -0
  177. package/dist/popover.js.map +1 -0
  178. package/dist/progress-recipe.d.ts +43 -0
  179. package/dist/progress-recipe.d.ts.map +1 -0
  180. package/dist/progress-recipe.js +16 -0
  181. package/dist/progress-recipe.js.map +1 -0
  182. package/dist/recipes.d.ts +31 -0
  183. package/dist/recipes.d.ts.map +1 -0
  184. package/dist/recipes.js +46 -0
  185. package/dist/recipes.js.map +1 -0
  186. package/dist/responsive.d.ts +27 -0
  187. package/dist/responsive.d.ts.map +1 -0
  188. package/dist/responsive.js +66 -0
  189. package/dist/responsive.js.map +1 -0
  190. package/dist/result.d.ts +111 -0
  191. package/dist/result.d.ts.map +1 -0
  192. package/dist/result.js +97 -0
  193. package/dist/result.js.map +1 -0
  194. package/dist/selection-helpers.d.ts +16 -0
  195. package/dist/selection-helpers.d.ts.map +1 -0
  196. package/dist/selection-helpers.js +52 -0
  197. package/dist/selection-helpers.js.map +1 -0
  198. package/dist/semantic-colors.d.ts +275 -0
  199. package/dist/semantic-colors.d.ts.map +1 -0
  200. package/dist/semantic-colors.js +84 -0
  201. package/dist/semantic-colors.js.map +1 -0
  202. package/dist/sheet.d.ts +51 -0
  203. package/dist/sheet.d.ts.map +1 -0
  204. package/dist/sheet.js +69 -0
  205. package/dist/sheet.js.map +1 -0
  206. package/dist/showcase.d.ts +153 -0
  207. package/dist/showcase.d.ts.map +1 -0
  208. package/dist/showcase.js +210 -0
  209. package/dist/showcase.js.map +1 -0
  210. package/dist/side-panel.d.ts +199 -0
  211. package/dist/side-panel.d.ts.map +1 -0
  212. package/dist/side-panel.js +111 -0
  213. package/dist/side-panel.js.map +1 -0
  214. package/dist/slider.d.ts +138 -0
  215. package/dist/slider.d.ts.map +1 -0
  216. package/dist/slider.js +150 -0
  217. package/dist/slider.js.map +1 -0
  218. package/dist/splitter.d.ts +113 -0
  219. package/dist/splitter.d.ts.map +1 -0
  220. package/dist/splitter.js +99 -0
  221. package/dist/splitter.js.map +1 -0
  222. package/dist/statistic.d.ts +41 -0
  223. package/dist/statistic.d.ts.map +1 -0
  224. package/dist/statistic.js +76 -0
  225. package/dist/statistic.js.map +1 -0
  226. package/dist/steps.d.ts +196 -0
  227. package/dist/steps.d.ts.map +1 -0
  228. package/dist/steps.js +160 -0
  229. package/dist/steps.js.map +1 -0
  230. package/dist/tag.d.ts +128 -0
  231. package/dist/tag.d.ts.map +1 -0
  232. package/dist/tag.js +93 -0
  233. package/dist/tag.js.map +1 -0
  234. package/dist/timeline.d.ts +147 -0
  235. package/dist/timeline.d.ts.map +1 -0
  236. package/dist/timeline.js +127 -0
  237. package/dist/timeline.js.map +1 -0
  238. package/dist/toast.d.ts +164 -0
  239. package/dist/toast.d.ts.map +1 -0
  240. package/dist/toast.js +529 -0
  241. package/dist/toast.js.map +1 -0
  242. package/dist/tokens.d.ts +9 -0
  243. package/dist/tokens.d.ts.map +1 -0
  244. package/dist/tokens.js +9 -0
  245. package/dist/tokens.js.map +1 -0
  246. package/dist/tooltip.d.ts +44 -0
  247. package/dist/tooltip.d.ts.map +1 -0
  248. package/dist/tooltip.js +88 -0
  249. package/dist/tooltip.js.map +1 -0
  250. package/dist/tour.d.ts +218 -0
  251. package/dist/tour.d.ts.map +1 -0
  252. package/dist/tour.js +211 -0
  253. package/dist/tour.js.map +1 -0
  254. package/dist/transfer-list.d.ts +207 -0
  255. package/dist/transfer-list.d.ts.map +1 -0
  256. package/dist/transfer-list.js +193 -0
  257. package/dist/transfer-list.js.map +1 -0
  258. package/dist/tree-select.d.ts +78 -0
  259. package/dist/tree-select.d.ts.map +1 -0
  260. package/dist/tree-select.js +132 -0
  261. package/dist/tree-select.js.map +1 -0
  262. package/dist/tree.d.ts +206 -0
  263. package/dist/tree.d.ts.map +1 -0
  264. package/dist/tree.js +223 -0
  265. package/dist/tree.js.map +1 -0
  266. package/dist/upload-item.d.ts +173 -0
  267. package/dist/upload-item.d.ts.map +1 -0
  268. package/dist/upload-item.js +156 -0
  269. package/dist/upload-item.js.map +1 -0
  270. package/dist/version.d.ts +3 -0
  271. package/dist/version.d.ts.map +1 -0
  272. package/dist/version.js +3 -0
  273. package/dist/version.js.map +1 -0
  274. package/docs/affix.md +63 -0
  275. package/docs/anchor.md +59 -0
  276. package/docs/ant-design-coverage.md +119 -0
  277. package/docs/app-provider.md +50 -0
  278. package/docs/app-rn-adoption.md +227 -0
  279. package/docs/architecture.md +320 -0
  280. package/docs/authoring-brief.md +87 -0
  281. package/docs/border-beam.md +66 -0
  282. package/docs/bottom-navigation.md +127 -0
  283. package/docs/breadcrumb.md +82 -0
  284. package/docs/calendar.md +154 -0
  285. package/docs/carousel.md +130 -0
  286. package/docs/cascader.md +93 -0
  287. package/docs/catalog-decision-status.md +306 -0
  288. package/docs/color-picker.md +72 -0
  289. package/docs/command-palette.md +116 -0
  290. package/docs/confirm-popover.md +93 -0
  291. package/docs/consistency-audit.md +383 -0
  292. package/docs/consumer-release-gate.md +90 -0
  293. package/docs/content-state.md +156 -0
  294. package/docs/context-panel.md +88 -0
  295. package/docs/cross-platform-core-normalization.md +118 -0
  296. package/docs/data-table.md +79 -0
  297. package/docs/date-picker.md +84 -0
  298. package/docs/description-list.md +75 -0
  299. package/docs/design-system-provider.md +139 -0
  300. package/docs/dropdown.md +78 -0
  301. package/docs/expansion-roadmap.md +285 -0
  302. package/docs/file-picker.md +59 -0
  303. package/docs/floating-action-button.md +111 -0
  304. package/docs/form.md +134 -0
  305. package/docs/generated/component-maturity.md +103 -0
  306. package/docs/generated/renderer-evidence.json +5597 -0
  307. package/docs/generated/renderer-evidence.md +132 -0
  308. package/docs/generated/showcase-manifest.json +3732 -0
  309. package/docs/icon.md +22 -0
  310. package/docs/identity.md +121 -0
  311. package/docs/image.md +84 -0
  312. package/docs/implementation-0.5.md +85 -0
  313. package/docs/layout-primitives.md +107 -0
  314. package/docs/layout.md +83 -0
  315. package/docs/library-reference-decisions.md +123 -0
  316. package/docs/link.md +67 -0
  317. package/docs/load-more.md +31 -0
  318. package/docs/mentions.md +82 -0
  319. package/docs/migration-0.2.md +108 -0
  320. package/docs/migration-0.3.md +72 -0
  321. package/docs/migration-0.5.md +82 -0
  322. package/docs/migration-0.6.md +197 -0
  323. package/docs/notification.md +54 -0
  324. package/docs/number-field.md +82 -0
  325. package/docs/otp-field.md +103 -0
  326. package/docs/pagination.md +139 -0
  327. package/docs/password-field.md +98 -0
  328. package/docs/popover.md +124 -0
  329. package/docs/promotion-candidates.md +169 -0
  330. package/docs/qr-code.md +69 -0
  331. package/docs/rating.md +58 -0
  332. package/docs/responsive-grid.md +90 -0
  333. package/docs/result.md +96 -0
  334. package/docs/showcase.md +97 -0
  335. package/docs/side-panel.md +71 -0
  336. package/docs/slider.md +79 -0
  337. package/docs/splitter.md +55 -0
  338. package/docs/statistic.md +16 -0
  339. package/docs/steps.md +115 -0
  340. package/docs/tag.md +57 -0
  341. package/docs/time-picker.md +88 -0
  342. package/docs/timeline.md +146 -0
  343. package/docs/toast.md +127 -0
  344. package/docs/tooltip.md +58 -0
  345. package/docs/tour.md +136 -0
  346. package/docs/transfer-list.md +94 -0
  347. package/docs/tree-select.md +101 -0
  348. package/docs/tree.md +123 -0
  349. package/docs/upload-item.md +68 -0
  350. package/docs/utility.md +53 -0
  351. package/docs/virtual-list.md +70 -0
  352. package/docs/watermark.md +58 -0
  353. package/package.json +402 -0
@@ -0,0 +1,182 @@
1
+ import { collectionItemContract, focusIndicatorContract } from "./component-contracts.js";
2
+ import { control, fontWeight, spacing } from "./foundations.js";
3
+ import { semanticColors } from "./semantic-colors.js";
4
+ export const dataTableColumnDefaults = {
5
+ align: "start",
6
+ sortable: false,
7
+ };
8
+ function assertNonEmpty(value, field) {
9
+ if (typeof value !== "string" || value.trim().length === 0) {
10
+ throw new TypeError(`DataTable ${field} must not be empty`);
11
+ }
12
+ }
13
+ export function validateDataTableColumns(columns) {
14
+ if (columns.length === 0) {
15
+ throw new TypeError("DataTable must declare at least one column");
16
+ }
17
+ const ids = new Set();
18
+ for (const column of columns) {
19
+ assertNonEmpty(column.id, "column id");
20
+ if (ids.has(column.id)) {
21
+ throw new TypeError(`Duplicate DataTable column id: ${column.id}`);
22
+ }
23
+ ids.add(column.id);
24
+ assertNonEmpty(column.header, `column "${column.id}" header`);
25
+ if (column.width !== undefined && (!Number.isFinite(column.width) || column.width <= 0)) {
26
+ throw new RangeError(`DataTable column "${column.id}" width must be a positive finite number`);
27
+ }
28
+ }
29
+ }
30
+ export function validateDataTableRows(rows) {
31
+ const ids = new Set();
32
+ for (const row of rows) {
33
+ assertNonEmpty(row.id, "row id");
34
+ if (ids.has(row.id)) {
35
+ throw new TypeError(`Duplicate DataTable row id: ${row.id}`);
36
+ }
37
+ ids.add(row.id);
38
+ }
39
+ }
40
+ /**
41
+ * Header "select all" state as the same tri-state `CheckboxState` the
42
+ * selection column's checkbox already renders (check/dash), instead of a new
43
+ * `"none" | "some" | "all"` enum the recipe would have to translate again.
44
+ * Disabled rows are excluded from both the denominator and the count.
45
+ */
46
+ export function resolveDataTableSelectAllState(rows, selectedKeys) {
47
+ const selectable = rows.filter((row) => !row.disabled);
48
+ if (selectable.length === 0)
49
+ return false;
50
+ const selectedCount = selectable.filter((row) => selectedKeys.has(row.id)).length;
51
+ if (selectedCount === 0)
52
+ return false;
53
+ if (selectedCount === selectable.length)
54
+ return true;
55
+ return "mixed";
56
+ }
57
+ export const dataTableDefaults = {
58
+ sortCycle: "three-state",
59
+ };
60
+ export function validateDataTableSortState(state, columns) {
61
+ if (state === null)
62
+ return;
63
+ if (state.direction !== "ascending" && state.direction !== "descending") {
64
+ throw new TypeError(`Unsupported DataTable sort direction: ${String(state.direction)}`);
65
+ }
66
+ const column = columns.find((candidate) => candidate.id === state.columnId);
67
+ if (!column) {
68
+ throw new TypeError(`DataTable sort references unknown column id: ${String(state.columnId)}`);
69
+ }
70
+ if (!column.sortable) {
71
+ throw new TypeError(`DataTable column "${String(state.columnId)}" is not sortable`);
72
+ }
73
+ }
74
+ /**
75
+ * Pure toggle: does not read or write product data. The product still owns
76
+ * actually re-sorting rows (Combobox's local/external filtering split is the
77
+ * same boundary — HJM judges intent, never executes the data operation).
78
+ */
79
+ export function getNextDataTableSortState(current, columnId, cycle = dataTableDefaults.sortCycle) {
80
+ if (current === null || current.columnId !== columnId) {
81
+ return { columnId, direction: "ascending" };
82
+ }
83
+ if (current.direction === "ascending") {
84
+ return { columnId, direction: "descending" };
85
+ }
86
+ return cycle === "three-state" ? null : { columnId, direction: "ascending" };
87
+ }
88
+ /**
89
+ * Reuses `collectionItemContract`'s hover/selected/focus tokens instead of a
90
+ * second set of row-interaction colors — Menu, Select, and DataTable rows
91
+ * stay one visual vocabulary.
92
+ */
93
+ export const dataTableRecipe = {
94
+ slots: [
95
+ "root",
96
+ "header",
97
+ "headerCell",
98
+ "sortButton",
99
+ "sortIcon",
100
+ "row",
101
+ "cell",
102
+ "selectionCell",
103
+ "emptyState",
104
+ "errorState",
105
+ ],
106
+ defaults: { density: "regular" },
107
+ density: {
108
+ compact: { paddingVertical: spacing.xs, paddingHorizontal: spacing.sm },
109
+ regular: { paddingVertical: spacing.sm, paddingHorizontal: spacing.md },
110
+ },
111
+ header: {
112
+ background: semanticColors.surface.sunken,
113
+ color: semanticColors.content.secondary,
114
+ textVariant: "label",
115
+ fontWeight: fontWeight.bold,
116
+ borderBottom: semanticColors.border.default,
117
+ },
118
+ row: {
119
+ borderBottom: semanticColors.border.subtle,
120
+ hoverBackground: collectionItemContract.highlightedBackground,
121
+ selectedBackground: collectionItemContract.selectedBackground,
122
+ },
123
+ cell: {
124
+ color: semanticColors.content.body,
125
+ textVariant: "body",
126
+ },
127
+ sortButton: {
128
+ minTarget: control.minTouchTarget,
129
+ color: semanticColors.content.secondary,
130
+ activeColor: semanticColors.content.brand,
131
+ },
132
+ selectionCell: {
133
+ width: control.minTouchTarget,
134
+ },
135
+ emptyState: {
136
+ color: semanticColors.content.secondary,
137
+ textVariant: "body",
138
+ },
139
+ errorState: {
140
+ color: semanticColors.content.danger,
141
+ textVariant: "body",
142
+ },
143
+ states: {
144
+ focus: focusIndicatorContract,
145
+ },
146
+ };
147
+ /**
148
+ * No roving-tabindex grid keyboard navigation (arrow keys between cells):
149
+ * no product using this contract has measured demand for full ARIA-grid
150
+ * traversal, and it is a materially bigger accessibility surface than a
151
+ * sortable header button plus native checkbox/radio tab stops.
152
+ */
153
+ export const dataTableBehavior = {
154
+ controlled: ["selection"],
155
+ inputs: ["columns", "rows", "sortState", "asyncState"],
156
+ events: ["onSortChange"],
157
+ configuration: { sortCycle: ["two-state", "three-state"] },
158
+ defaults: dataTableDefaults,
159
+ stateAxes: {
160
+ value: ["selected"],
161
+ content: ["idle", "loading", "loadingMore", "empty", "error"],
162
+ },
163
+ web: {
164
+ roles: ["table", "row", "columnheader", "cell", "button", "checkbox", "radio"],
165
+ keyboard: ["Tab", "Enter", "Space"],
166
+ focus: "native",
167
+ },
168
+ native: { roles: [], states: [], actions: [] },
169
+ scenarios: [
170
+ "row-selection-reuses-the-shared-collection-selection-model-unchanged",
171
+ "select-all-reuses-the-shared-tri-state-checkbox-value",
172
+ "async-state-reuses-the-shared-collection-async-state-unchanged",
173
+ "sortable-header-is-a-button-inside-the-columnheader-not-the-header-itself",
174
+ "sort-direction-values-pass-through-to-aria-sort-without-translation",
175
+ "disabled-rows-are-excluded-from-select-all-accounting",
176
+ "pagination-or-load-more-is-composed-beneath-the-table-not-owned-by-it",
177
+ "row-expansion-is-not-owned-here-compose-the-disclosure-group-contract-per-row",
178
+ "a-data-cell-exposes-at-most-one-focusable-control",
179
+ "no-roving-tabindex-grid-navigation-is-implied",
180
+ ],
181
+ };
182
+ //# sourceMappingURL=data-table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-table.js","sourceRoot":"","sources":["../src/data-table.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ColorReference } from \"./color-references.js\";\nimport type {\n AsyncCollectionState,\n BehaviorContract,\n CheckboxState,\n CollectionKey,\n CollectionSelectionModel,\n} from \"./behaviors.js\";\nimport { collectionItemContract, focusIndicatorContract } from \"./component-contracts.js\";\nimport { control, fontWeight, spacing, type FontWeightValue, type TextVariant } from \"./foundations.js\";\nimport { semanticColors } from \"./semantic-colors.js\";\n\nexport type DataTableAlign = \"start\" | \"center\" | \"end\";\n\nexport type DataTableColumnDescriptor<Key extends CollectionKey = CollectionKey> = Readonly<{\n id: Key;\n /** Visible column header text; also the columnheader's accessible name. */\n header: string;\n align?: DataTableAlign;\n sortable?: boolean;\n /** Layout hint only (px or flex-basis); renderers may ignore or clamp it. */\n width?: number;\n}>;\n\nexport const dataTableColumnDefaults = {\n align: \"start\",\n sortable: false,\n} as const satisfies Readonly<{ align: DataTableAlign; sortable: boolean }>;\n\nfunction assertNonEmpty(value: string, field: string): void {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new TypeError(`DataTable ${field} must not be empty`);\n }\n}\n\nexport function validateDataTableColumns<Key extends CollectionKey>(\n columns: readonly DataTableColumnDescriptor<Key>[],\n): void {\n if (columns.length === 0) {\n throw new TypeError(\"DataTable must declare at least one column\");\n }\n const ids = new Set<Key>();\n for (const column of columns) {\n assertNonEmpty(column.id, \"column id\");\n if (ids.has(column.id)) {\n throw new TypeError(`Duplicate DataTable column id: ${column.id}`);\n }\n ids.add(column.id);\n assertNonEmpty(column.header, `column \"${column.id}\" header`);\n if (column.width !== undefined && (!Number.isFinite(column.width) || column.width <= 0)) {\n throw new RangeError(`DataTable column \"${column.id}\" width must be a positive finite number`);\n }\n }\n}\n\n/**\n * Row identity and selection deliberately do NOT reuse `CollectionItemDescriptor`\n * verbatim: a table row has no single visible `label`/`textValue` the way a\n * Menu or Select item does — its \"content\" is however many columns the\n * product renders per row. Only the parts of the Collection base contract\n * that are genuinely row-shaped (`CollectionKey` identity, `disabled`) apply.\n */\nexport type DataTableRowDescriptor<Key extends CollectionKey = CollectionKey> = Readonly<{\n id: Key;\n disabled?: boolean;\n}>;\n\nexport function validateDataTableRows<Key extends CollectionKey>(\n rows: readonly DataTableRowDescriptor<Key>[],\n): void {\n const ids = new Set<Key>();\n for (const row of rows) {\n assertNonEmpty(row.id, \"row id\");\n if (ids.has(row.id)) {\n throw new TypeError(`Duplicate DataTable row id: ${row.id}`);\n }\n ids.add(row.id);\n }\n}\n\n/** Row selection is the unmodified Collection base contract — no DataTable-only selection shape. */\nexport type DataTableSelection<Key extends CollectionKey = CollectionKey> =\n CollectionSelectionModel<Key>;\n\n/**\n * Header \"select all\" state as the same tri-state `CheckboxState` the\n * selection column's checkbox already renders (check/dash), instead of a new\n * `\"none\" | \"some\" | \"all\"` enum the recipe would have to translate again.\n * Disabled rows are excluded from both the denominator and the count.\n */\nexport function resolveDataTableSelectAllState<Key extends CollectionKey>(\n rows: readonly DataTableRowDescriptor<Key>[],\n selectedKeys: ReadonlySet<Key>,\n): CheckboxState {\n const selectable = rows.filter((row) => !row.disabled);\n if (selectable.length === 0) return false;\n const selectedCount = selectable.filter((row) => selectedKeys.has(row.id)).length;\n if (selectedCount === 0) return false;\n if (selectedCount === selectable.length) return true;\n return \"mixed\";\n}\n\n/**\n * Values are the literal `aria-sort` vocabulary (minus `\"none\"`, which is\n * `null`) so the Web renderer passes them through without a translation\n * table — the same \"pass the platform value through\" choice Slider makes\n * for `valueText`.\n */\nexport type DataTableSortDirection = \"ascending\" | \"descending\";\n\nexport type DataTableSortState<Key extends CollectionKey = CollectionKey> = Readonly<{\n columnId: Key;\n direction: DataTableSortDirection;\n}> | null;\n\nexport type DataTableSortCycle = \"two-state\" | \"three-state\";\n\nexport const dataTableDefaults = {\n sortCycle: \"three-state\",\n} as const satisfies Readonly<{ sortCycle: DataTableSortCycle }>;\n\nexport function validateDataTableSortState<Key extends CollectionKey>(\n state: DataTableSortState<Key>,\n columns: readonly DataTableColumnDescriptor<Key>[],\n): void {\n if (state === null) return;\n if (state.direction !== \"ascending\" && state.direction !== \"descending\") {\n throw new TypeError(`Unsupported DataTable sort direction: ${String(state.direction)}`);\n }\n const column = columns.find((candidate) => candidate.id === state.columnId);\n if (!column) {\n throw new TypeError(`DataTable sort references unknown column id: ${String(state.columnId)}`);\n }\n if (!column.sortable) {\n throw new TypeError(`DataTable column \"${String(state.columnId)}\" is not sortable`);\n }\n}\n\n/**\n * Pure toggle: does not read or write product data. The product still owns\n * actually re-sorting rows (Combobox's local/external filtering split is the\n * same boundary — HJM judges intent, never executes the data operation).\n */\nexport function getNextDataTableSortState<Key extends CollectionKey>(\n current: DataTableSortState<Key>,\n columnId: Key,\n cycle: DataTableSortCycle = dataTableDefaults.sortCycle,\n): DataTableSortState<Key> {\n if (current === null || current.columnId !== columnId) {\n return { columnId, direction: \"ascending\" };\n }\n if (current.direction === \"ascending\") {\n return { columnId, direction: \"descending\" };\n }\n return cycle === \"three-state\" ? null : { columnId, direction: \"ascending\" };\n}\n\n/** The whole table's row-loading status — the unmodified Collection base async contract. */\nexport type DataTableAsyncState = AsyncCollectionState;\n\nexport type DataTableDensity = \"compact\" | \"regular\";\n\n/**\n * Reuses `collectionItemContract`'s hover/selected/focus tokens instead of a\n * second set of row-interaction colors — Menu, Select, and DataTable rows\n * stay one visual vocabulary.\n */\nexport const dataTableRecipe = {\n slots: [\n \"root\",\n \"header\",\n \"headerCell\",\n \"sortButton\",\n \"sortIcon\",\n \"row\",\n \"cell\",\n \"selectionCell\",\n \"emptyState\",\n \"errorState\",\n ] as const,\n defaults: { density: \"regular\" },\n density: {\n compact: { paddingVertical: spacing.xs, paddingHorizontal: spacing.sm },\n regular: { paddingVertical: spacing.sm, paddingHorizontal: spacing.md },\n },\n header: {\n background: semanticColors.surface.sunken,\n color: semanticColors.content.secondary,\n textVariant: \"label\",\n fontWeight: fontWeight.bold,\n borderBottom: semanticColors.border.default,\n },\n row: {\n borderBottom: semanticColors.border.subtle,\n hoverBackground: collectionItemContract.highlightedBackground,\n selectedBackground: collectionItemContract.selectedBackground,\n },\n cell: {\n color: semanticColors.content.body,\n textVariant: \"body\",\n },\n sortButton: {\n minTarget: control.minTouchTarget,\n color: semanticColors.content.secondary,\n activeColor: semanticColors.content.brand,\n },\n selectionCell: {\n width: control.minTouchTarget,\n },\n emptyState: {\n color: semanticColors.content.secondary,\n textVariant: \"body\",\n },\n errorState: {\n color: semanticColors.content.danger,\n textVariant: \"body\",\n },\n states: {\n focus: focusIndicatorContract,\n },\n} as const satisfies {\n slots: readonly [\n \"root\",\n \"header\",\n \"headerCell\",\n \"sortButton\",\n \"sortIcon\",\n \"row\",\n \"cell\",\n \"selectionCell\",\n \"emptyState\",\n \"errorState\",\n ];\n defaults: { density: DataTableDensity };\n density: Record<DataTableDensity, { paddingVertical: number; paddingHorizontal: number }>;\n header: {\n background: ColorReference;\n color: ColorReference;\n textVariant: TextVariant;\n fontWeight: FontWeightValue;\n borderBottom: ColorReference;\n };\n row: {\n borderBottom: ColorReference;\n hoverBackground: ColorReference;\n selectedBackground: ColorReference;\n };\n cell: { color: ColorReference; textVariant: TextVariant };\n sortButton: { minTarget: number; color: ColorReference; activeColor: ColorReference };\n selectionCell: { width: number };\n emptyState: { color: ColorReference; textVariant: TextVariant };\n errorState: { color: ColorReference; textVariant: TextVariant };\n states: { focus: typeof focusIndicatorContract };\n};\n\n/**\n * No roving-tabindex grid keyboard navigation (arrow keys between cells):\n * no product using this contract has measured demand for full ARIA-grid\n * traversal, and it is a materially bigger accessibility surface than a\n * sortable header button plus native checkbox/radio tab stops.\n */\nexport const dataTableBehavior = {\n controlled: [\"selection\"],\n inputs: [\"columns\", \"rows\", \"sortState\", \"asyncState\"],\n events: [\"onSortChange\"],\n configuration: { sortCycle: [\"two-state\", \"three-state\"] },\n defaults: dataTableDefaults,\n stateAxes: {\n value: [\"selected\"],\n content: [\"idle\", \"loading\", \"loadingMore\", \"empty\", \"error\"],\n },\n web: {\n roles: [\"table\", \"row\", \"columnheader\", \"cell\", \"button\", \"checkbox\", \"radio\"],\n keyboard: [\"Tab\", \"Enter\", \"Space\"],\n focus: \"native\",\n },\n native: { roles: [], states: [], actions: [] },\n scenarios: [\n \"row-selection-reuses-the-shared-collection-selection-model-unchanged\",\n \"select-all-reuses-the-shared-tri-state-checkbox-value\",\n \"async-state-reuses-the-shared-collection-async-state-unchanged\",\n \"sortable-header-is-a-button-inside-the-columnheader-not-the-header-itself\",\n \"sort-direction-values-pass-through-to-aria-sort-without-translation\",\n \"disabled-rows-are-excluded-from-select-all-accounting\",\n \"pagination-or-load-more-is-composed-beneath-the-table-not-owned-by-it\",\n \"row-expansion-is-not-owned-here-compose-the-disclosure-group-contract-per-row\",\n \"a-data-cell-exposes-at-most-one-focusable-control\",\n \"no-roving-tabindex-grid-navigation-is-implied\",\n ],\n} as const satisfies BehaviorContract;\n"]}
@@ -0,0 +1,268 @@
1
+ import { type CalendarGridDescriptor, type CalendarMonthNavigation, type ComposeCalendarAccessibleName, type ResolvedCalendarGridCell } from "./calendar.js";
2
+ /**
3
+ * Mirrors `SelectLabel` by shape rather than importing it: Select's type
4
+ * lives in `collection.ts` for Select/Combobox/Menu's shared collection
5
+ * story, and DatePicker's date grid deliberately does not adopt that
6
+ * collection contract (see docs/calendar.md). Repeating the small, obvious
7
+ * "visible label or accessibility label" shape here keeps this module
8
+ * self-sufficient while staying consistent with the rest of the system.
9
+ */
10
+ export type DatePickerLabel = Readonly<{
11
+ label: string;
12
+ accessibilityLabel?: string;
13
+ }> | Readonly<{
14
+ label?: never;
15
+ accessibilityLabel: string;
16
+ }>;
17
+ export type DatePickerOpenChangeReason = "trigger" | "keyboard" | "selection" | "clear" | "escape" | "outside" | "blur" | "programmatic";
18
+ export type DatePickerOpenState = Readonly<{
19
+ open: boolean;
20
+ defaultOpen?: never;
21
+ onOpenChange(open: boolean, reason: DatePickerOpenChangeReason): void;
22
+ }> | Readonly<{
23
+ open?: never;
24
+ defaultOpen?: boolean;
25
+ onOpenChange?: (open: boolean, reason: DatePickerOpenChangeReason) => void;
26
+ }>;
27
+ /**
28
+ * A committed date closes the popover/sheet the same way Select's
29
+ * `selection-requests-close-and-restores-trigger-focus` scenario works.
30
+ * `clear` commits `null` without reopening — this is the field's only
31
+ * "empty" affordance; there is no separate disallow-empty configuration
32
+ * because an optional date field is the common case (unlike Select, which
33
+ * more often names a required option).
34
+ */
35
+ export type DatePickerSelection = Readonly<{
36
+ selectedDate: string | null;
37
+ defaultSelectedDate?: never;
38
+ onSelectionChange(date: string | null, reason: "activate" | "clear"): void;
39
+ }> | Readonly<{
40
+ selectedDate?: never;
41
+ defaultSelectedDate?: string | null;
42
+ onSelectionChange?: (date: string | null, reason: "activate" | "clear") => void;
43
+ }>;
44
+ export declare function validateDatePickerSelection(selection: DatePickerSelection): void;
45
+ /**
46
+ * Field + grid + adaptive overlay. The grid itself is the exact
47
+ * `CalendarGridDescriptor` from `calendar.ts` — Web renders it inside an
48
+ * anchored popover, Native inside a Sheet (the `Select` adaptive split:
49
+ * `adaptive: { web: "popover", native: "sheet" }`), but neither renderer
50
+ * reinterprets the grid's cells, navigation, or accessible-name contract.
51
+ */
52
+ export type DatePickerDescriptor<Content = unknown> = Readonly<{
53
+ grid: CalendarGridDescriptor<Content>;
54
+ /** Product-formatted trigger copy for the committed date ("2026년 8월 19일"); DatePicker never formats a date itself. */
55
+ displayValue: string | null;
56
+ placeholder: string;
57
+ disabled?: boolean;
58
+ readOnly?: boolean;
59
+ invalid?: boolean;
60
+ }> & DatePickerLabel & DatePickerOpenState & DatePickerSelection & CalendarMonthNavigation;
61
+ export declare function validateDatePickerDescriptor<Content>(descriptor: DatePickerDescriptor<Content>): void;
62
+ /** Trigger copy is the committed display value, or the placeholder when nothing is selected yet. */
63
+ export declare function resolveDatePickerTriggerText(descriptor: Pick<DatePickerDescriptor, "displayValue" | "placeholder">): string;
64
+ /**
65
+ * Resolves the popover/sheet content: the exact same cell shape, today/
66
+ * selected marks, and accessible names Calendar renders inline. DatePicker
67
+ * adds no per-cell semantics of its own — only the surrounding field/overlay
68
+ * lifecycle is new.
69
+ */
70
+ export declare function resolveDatePickerGrid<Content>(descriptor: DatePickerDescriptor<Content>, options: Readonly<{
71
+ composeAccessibleName: ComposeCalendarAccessibleName<Content>;
72
+ }>): readonly ResolvedCalendarGridCell<Content>[];
73
+ export type DatePickerSize = "medium" | "large";
74
+ /**
75
+ * Reuses `fieldFrameContract`/`formSupportContract` verbatim, exactly like
76
+ * NumberField and Select each do independently — a second field frame would
77
+ * drift the first time either one's border or height changes. `calendar`
78
+ * anatomy is intentionally not re-declared here: the popover/sheet mounts
79
+ * `calendarRecipe` unchanged, so this recipe only owns the field/trigger and
80
+ * the overlay frame around it.
81
+ */
82
+ export declare const datePickerRecipe: {
83
+ readonly slots: readonly ["root", "label", "trigger", "leading", "value", "placeholder", "clear", "indicator", "description", "error", "popover"];
84
+ readonly defaults: {
85
+ readonly size: "medium";
86
+ };
87
+ readonly adaptive: {
88
+ readonly web: "popover";
89
+ readonly native: "sheet";
90
+ };
91
+ readonly frame: {
92
+ readonly background: Readonly<{
93
+ source: "theme";
94
+ key: "surface";
95
+ alpha?: number;
96
+ }>;
97
+ readonly border: Readonly<{
98
+ source: "theme";
99
+ key: "textMuted";
100
+ alpha?: number;
101
+ }>;
102
+ readonly focusBorder: Readonly<{
103
+ source: "theme";
104
+ key: "contentBrand";
105
+ alpha?: number;
106
+ }>;
107
+ readonly invalidBorder: Readonly<{
108
+ source: "theme";
109
+ key: "danger";
110
+ alpha?: number;
111
+ }>;
112
+ readonly radius: "md";
113
+ readonly borderWidth: 1;
114
+ readonly minHeight: 44;
115
+ readonly paddingHorizontal: 16;
116
+ };
117
+ readonly sizes: {
118
+ readonly medium: {
119
+ readonly minHeight: 44;
120
+ readonly paddingHorizontal: 16;
121
+ readonly textVariant: "body";
122
+ readonly glyph: "sm";
123
+ };
124
+ readonly large: {
125
+ readonly minHeight: 52;
126
+ readonly paddingHorizontal: 20;
127
+ readonly textVariant: "bodyLarge";
128
+ readonly glyph: "md";
129
+ };
130
+ };
131
+ readonly support: {
132
+ readonly label: {
133
+ readonly color: Readonly<{
134
+ source: "theme";
135
+ key: "textBody";
136
+ alpha?: number;
137
+ }>;
138
+ readonly textVariant: "body";
139
+ readonly fontWeight: "600";
140
+ };
141
+ readonly hint: {
142
+ readonly color: Readonly<{
143
+ source: "theme";
144
+ key: "textMuted";
145
+ alpha?: number;
146
+ }>;
147
+ readonly textVariant: "label";
148
+ };
149
+ readonly error: {
150
+ readonly color: Readonly<{
151
+ source: "theme";
152
+ key: "danger";
153
+ alpha?: number;
154
+ }>;
155
+ readonly textVariant: "label";
156
+ };
157
+ readonly gap: 8;
158
+ };
159
+ readonly value: {
160
+ readonly color: Readonly<{
161
+ source: "theme";
162
+ key: "textBody";
163
+ alpha?: number;
164
+ }>;
165
+ readonly placeholderColor: Readonly<{
166
+ source: "theme";
167
+ key: "textMuted";
168
+ alpha?: number;
169
+ }>;
170
+ };
171
+ readonly leading: {
172
+ readonly color: Readonly<{
173
+ source: "theme";
174
+ key: "textMuted";
175
+ alpha?: number;
176
+ }>;
177
+ readonly icon: "calendar";
178
+ };
179
+ readonly indicator: {
180
+ readonly color: Readonly<{
181
+ source: "theme";
182
+ key: "textMuted";
183
+ alpha?: number;
184
+ }>;
185
+ };
186
+ readonly clear: {
187
+ readonly diameter: 36;
188
+ readonly hitSlop: 4;
189
+ readonly glyph: "xs";
190
+ readonly color: Readonly<{
191
+ source: "theme";
192
+ key: "textMuted";
193
+ alpha?: number;
194
+ }>;
195
+ };
196
+ readonly popover: {
197
+ readonly minWidth: 300;
198
+ readonly maxWidth: 360;
199
+ readonly sideOffset: 8;
200
+ readonly collisionPadding: 8;
201
+ readonly background: Readonly<{
202
+ source: "theme";
203
+ key: "bg";
204
+ alpha?: number;
205
+ }>;
206
+ readonly border: Readonly<{
207
+ source: "theme";
208
+ key: "border";
209
+ alpha?: number;
210
+ }>;
211
+ readonly borderWidth: 1;
212
+ readonly radius: "md";
213
+ readonly shadow: {
214
+ readonly color: "#000000";
215
+ readonly opacity: 0.12;
216
+ readonly radius: 12;
217
+ readonly offsetY: 4;
218
+ };
219
+ readonly padding: 8;
220
+ };
221
+ readonly states: {
222
+ readonly focus: {
223
+ readonly color: Readonly<{
224
+ source: "theme";
225
+ key: "contentBrand";
226
+ alpha?: number;
227
+ }>;
228
+ readonly width: 2;
229
+ readonly offset: 2;
230
+ };
231
+ readonly invalidBorder: Readonly<{
232
+ source: "theme";
233
+ key: "danger";
234
+ alpha?: number;
235
+ }>;
236
+ };
237
+ };
238
+ /**
239
+ * Web mounts the grid as a real focus-bearing `dialog` (APG's Date Picker
240
+ * Dialog pattern moves actual DOM focus through gridcells via roving
241
+ * tabindex, unlike Select's `activeDescendant` listbox where focus stays on
242
+ * the trigger). Native mounts the same grid inside a Sheet. Both close on a
243
+ * committed selection or `clear` and restore trigger focus, matching
244
+ * Select's own dismiss-and-restore scenario.
245
+ */
246
+ export declare const datePickerBehavior: {
247
+ readonly controlled: readonly ["selectedDate", "defaultSelectedDate", "onSelectionChange", "open", "defaultOpen", "onOpenChange"];
248
+ readonly inputs: readonly ["grid", "displayValue", "focusedMonth", "defaultFocusedMonth"];
249
+ readonly stateAxes: {
250
+ readonly availability: readonly ["enabled", "disabled", "readOnly", "busy"];
251
+ readonly value: readonly ["empty", "selected", "open"];
252
+ readonly validation: readonly ["valid", "invalid"];
253
+ };
254
+ readonly web: {
255
+ readonly roles: readonly ["button", "dialog", "grid", "row", "gridcell"];
256
+ readonly keyboard: readonly ["Tab", "Enter", "Space", "Escape", "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Home", "End"];
257
+ readonly focus: "roving";
258
+ readonly dismiss: readonly ["selection", "escape", "outside", "blur"];
259
+ };
260
+ readonly native: {
261
+ readonly roles: readonly ["button", "dialog"];
262
+ readonly states: readonly ["disabled", "expanded"];
263
+ readonly actions: readonly ["activate", "dismiss"];
264
+ readonly dismiss: readonly ["selection", "back", "outside"];
265
+ };
266
+ readonly scenarios: readonly ["visible-label-or-accessibility-label-names-trigger", "trigger-shows-the-product-formatted-display-value-or-placeholder", "popover-and-sheet-content-reuse-the-calendar-grid-contract-unchanged", "activating-an-enabled-date-commits-selection-and-closes", "disabled-dates-remain-focusable-but-never-commit-or-close", "clear-commits-null-and-closes-without-reopening", "escape-closes-without-commit-and-restores-trigger-focus", "outside-press-closes-without-commit", "controlled-owner-may-defer-a-selection-close-request", "changing-the-focused-month-never-changes-or-clears-the-selection", "range-selection-is-not-part-of-the-contract"];
267
+ };
268
+ //# sourceMappingURL=date-picker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../src/date-picker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,168 @@
1
+ import { assertIsoCalendarDate, validateCalendarGridDescriptor, resolveCalendarGridDescriptor, validateCalendarMonthNavigation, } from "./calendar.js";
2
+ import { fieldFrameContract, floatingSurfaceContract, focusIndicatorContract, formSupportContract } from "./component-contracts.js";
3
+ import { control, spacing } from "./foundations.js";
4
+ import { semanticColors } from "./semantic-colors.js";
5
+ function assertNonEmpty(value, field) {
6
+ if (typeof value !== "string" || value.trim().length === 0) {
7
+ throw new TypeError(`DatePicker ${field} must not be empty`);
8
+ }
9
+ }
10
+ export function validateDatePickerSelection(selection) {
11
+ const selected = selection.selectedDate ?? selection.defaultSelectedDate;
12
+ if (selected != null)
13
+ assertIsoCalendarDate(selected, "selectedDate");
14
+ }
15
+ export function validateDatePickerDescriptor(descriptor) {
16
+ validateCalendarGridDescriptor(descriptor.grid);
17
+ assertNonEmpty(descriptor.placeholder, "placeholder");
18
+ if (descriptor.displayValue !== null) {
19
+ assertNonEmpty(descriptor.displayValue, "displayValue");
20
+ }
21
+ const label = descriptor.label ?? descriptor.accessibilityLabel;
22
+ assertNonEmpty(label, "label or accessibilityLabel");
23
+ validateDatePickerSelection(descriptor);
24
+ validateCalendarMonthNavigation(descriptor);
25
+ }
26
+ /** Trigger copy is the committed display value, or the placeholder when nothing is selected yet. */
27
+ export function resolveDatePickerTriggerText(descriptor) {
28
+ if (descriptor.displayValue !== null)
29
+ assertNonEmpty(descriptor.displayValue, "displayValue");
30
+ assertNonEmpty(descriptor.placeholder, "placeholder");
31
+ return descriptor.displayValue ?? descriptor.placeholder;
32
+ }
33
+ /**
34
+ * Resolves the popover/sheet content: the exact same cell shape, today/
35
+ * selected marks, and accessible names Calendar renders inline. DatePicker
36
+ * adds no per-cell semantics of its own — only the surrounding field/overlay
37
+ * lifecycle is new.
38
+ */
39
+ export function resolveDatePickerGrid(descriptor, options) {
40
+ validateDatePickerDescriptor(descriptor);
41
+ const selectedDate = descriptor.selectedDate ?? descriptor.defaultSelectedDate ?? null;
42
+ return resolveCalendarGridDescriptor(descriptor.grid, selectedDate, options);
43
+ }
44
+ /**
45
+ * Reuses `fieldFrameContract`/`formSupportContract` verbatim, exactly like
46
+ * NumberField and Select each do independently — a second field frame would
47
+ * drift the first time either one's border or height changes. `calendar`
48
+ * anatomy is intentionally not re-declared here: the popover/sheet mounts
49
+ * `calendarRecipe` unchanged, so this recipe only owns the field/trigger and
50
+ * the overlay frame around it.
51
+ */
52
+ export const datePickerRecipe = {
53
+ slots: [
54
+ "root",
55
+ "label",
56
+ "trigger",
57
+ "leading",
58
+ "value",
59
+ "placeholder",
60
+ "clear",
61
+ "indicator",
62
+ "description",
63
+ "error",
64
+ "popover",
65
+ ],
66
+ defaults: { size: "medium" },
67
+ adaptive: { web: "popover", native: "sheet" },
68
+ frame: fieldFrameContract,
69
+ sizes: {
70
+ medium: {
71
+ minHeight: fieldFrameContract.minHeight,
72
+ paddingHorizontal: fieldFrameContract.paddingHorizontal,
73
+ textVariant: "body",
74
+ glyph: "sm",
75
+ },
76
+ large: {
77
+ minHeight: control.buttonHeight.large,
78
+ paddingHorizontal: spacing.lg,
79
+ textVariant: "bodyLarge",
80
+ glyph: "md",
81
+ },
82
+ },
83
+ support: formSupportContract,
84
+ value: {
85
+ color: semanticColors.content.body,
86
+ placeholderColor: semanticColors.content.secondary,
87
+ },
88
+ leading: { color: semanticColors.content.secondary, icon: "calendar" },
89
+ indicator: { color: semanticColors.content.secondary },
90
+ clear: {
91
+ diameter: control.buttonHeight.small,
92
+ hitSlop: control.buttonHitSlop.small,
93
+ glyph: "xs",
94
+ color: semanticColors.content.secondary,
95
+ },
96
+ popover: {
97
+ ...floatingSurfaceContract,
98
+ minWidth: 300,
99
+ maxWidth: 360,
100
+ sideOffset: spacing.xs,
101
+ collisionPadding: spacing.xs,
102
+ },
103
+ states: {
104
+ focus: focusIndicatorContract,
105
+ invalidBorder: semanticColors.border.danger,
106
+ },
107
+ };
108
+ /**
109
+ * Web mounts the grid as a real focus-bearing `dialog` (APG's Date Picker
110
+ * Dialog pattern moves actual DOM focus through gridcells via roving
111
+ * tabindex, unlike Select's `activeDescendant` listbox where focus stays on
112
+ * the trigger). Native mounts the same grid inside a Sheet. Both close on a
113
+ * committed selection or `clear` and restore trigger focus, matching
114
+ * Select's own dismiss-and-restore scenario.
115
+ */
116
+ export const datePickerBehavior = {
117
+ controlled: [
118
+ "selectedDate",
119
+ "defaultSelectedDate",
120
+ "onSelectionChange",
121
+ "open",
122
+ "defaultOpen",
123
+ "onOpenChange",
124
+ ],
125
+ inputs: ["grid", "displayValue", "focusedMonth", "defaultFocusedMonth"],
126
+ stateAxes: {
127
+ availability: ["enabled", "disabled", "readOnly", "busy"],
128
+ value: ["empty", "selected", "open"],
129
+ validation: ["valid", "invalid"],
130
+ },
131
+ web: {
132
+ roles: ["button", "dialog", "grid", "row", "gridcell"],
133
+ keyboard: [
134
+ "Tab",
135
+ "Enter",
136
+ "Space",
137
+ "Escape",
138
+ "ArrowUp",
139
+ "ArrowDown",
140
+ "ArrowLeft",
141
+ "ArrowRight",
142
+ "Home",
143
+ "End",
144
+ ],
145
+ focus: "roving",
146
+ dismiss: ["selection", "escape", "outside", "blur"],
147
+ },
148
+ native: {
149
+ roles: ["button", "dialog"],
150
+ states: ["disabled", "expanded"],
151
+ actions: ["activate", "dismiss"],
152
+ dismiss: ["selection", "back", "outside"],
153
+ },
154
+ scenarios: [
155
+ "visible-label-or-accessibility-label-names-trigger",
156
+ "trigger-shows-the-product-formatted-display-value-or-placeholder",
157
+ "popover-and-sheet-content-reuse-the-calendar-grid-contract-unchanged",
158
+ "activating-an-enabled-date-commits-selection-and-closes",
159
+ "disabled-dates-remain-focusable-but-never-commit-or-close",
160
+ "clear-commits-null-and-closes-without-reopening",
161
+ "escape-closes-without-commit-and-restores-trigger-focus",
162
+ "outside-press-closes-without-commit",
163
+ "controlled-owner-may-defer-a-selection-close-request",
164
+ "changing-the-focused-month-never-changes-or-clears-the-selection",
165
+ "range-selection-is-not-part-of-the-contract",
166
+ ],
167
+ };
168
+ //# sourceMappingURL=date-picker.js.map