@duro-app/ui 4.5.0 → 5.1.0

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 (242) hide show
  1. package/dist/Table-BkrgH0jb.js +1199 -0
  2. package/dist/Table-BkrgH0jb.js.map +1 -0
  3. package/dist/components/ActionBar/ActionBar.stories.d.ts.map +1 -1
  4. package/dist/components/ActionBar/styles.css.d.ts +7 -7
  5. package/dist/components/ActionBar/styles.css.d.ts.map +1 -1
  6. package/dist/components/Alert/styles.css.d.ts +2 -2
  7. package/dist/components/Alert/styles.css.d.ts.map +1 -1
  8. package/dist/components/Badge/styles.css.d.ts +2 -2
  9. package/dist/components/Button/styles.css.d.ts +5 -5
  10. package/dist/components/Button/styles.css.d.ts.map +1 -1
  11. package/dist/components/Callout/styles.css.d.ts +1 -1
  12. package/dist/components/Callout/styles.css.d.ts.map +1 -1
  13. package/dist/components/Card/Card.stories.d.ts.map +1 -1
  14. package/dist/components/Card/styles.css.d.ts +3 -3
  15. package/dist/components/Card/styles.css.d.ts.map +1 -1
  16. package/dist/components/Checkbox/Checkbox.d.ts.map +1 -1
  17. package/dist/components/Checkbox/styles.css.d.ts +7 -11
  18. package/dist/components/Checkbox/styles.css.d.ts.map +1 -1
  19. package/dist/components/Cluster/Cluster.stories.d.ts.map +1 -1
  20. package/dist/components/ColorInput/styles.css.d.ts +6 -6
  21. package/dist/components/ColorInput/styles.css.d.ts.map +1 -1
  22. package/dist/components/ColorMode/styles.css.d.ts +3 -3
  23. package/dist/components/ColorMode/styles.css.d.ts.map +1 -1
  24. package/dist/components/Combobox/styles.css.d.ts +3 -3
  25. package/dist/components/Combobox/styles.css.d.ts.map +1 -1
  26. package/dist/components/DetailPanel/DetailPanel.d.ts.map +1 -1
  27. package/dist/components/DetailPanel/DetailPanel.stories.d.ts.map +1 -1
  28. package/dist/components/DetailPanel/styles.css.d.ts +19 -10
  29. package/dist/components/DetailPanel/styles.css.d.ts.map +1 -1
  30. package/dist/components/Dialog/Dialog.d.ts.map +1 -1
  31. package/dist/components/Dialog/Dialog.stories.d.ts.map +1 -1
  32. package/dist/components/Dialog/styles.css.d.ts +18 -9
  33. package/dist/components/Dialog/styles.css.d.ts.map +1 -1
  34. package/dist/components/DragDrop/DragDrop.d.ts.map +1 -1
  35. package/dist/components/DragDrop/DragDrop.stories.d.ts.map +1 -1
  36. package/dist/components/DragDrop/styles.css.d.ts +0 -6
  37. package/dist/components/DragDrop/styles.css.d.ts.map +1 -1
  38. package/dist/components/Drawer/Drawer.d.ts.map +1 -1
  39. package/dist/components/Drawer/styles.css.d.ts +19 -10
  40. package/dist/components/Drawer/styles.css.d.ts.map +1 -1
  41. package/dist/components/Field/Field.stories.d.ts.map +1 -1
  42. package/dist/components/Field/styles.css.d.ts +1 -1
  43. package/dist/components/Field/styles.css.d.ts.map +1 -1
  44. package/dist/components/Form/Form.stories.d.ts.map +1 -1
  45. package/dist/components/Grid/Grid.d.ts +6 -4
  46. package/dist/components/Grid/Grid.d.ts.map +1 -1
  47. package/dist/components/Grid/Grid.stories.d.ts.map +1 -1
  48. package/dist/components/Grid/styles.css.d.ts +5 -5
  49. package/dist/components/Grid/styles.css.d.ts.map +1 -1
  50. package/dist/components/Input/Input.stories.d.ts.map +1 -1
  51. package/dist/components/Input/styles.css.d.ts +3 -3
  52. package/dist/components/Input/styles.css.d.ts.map +1 -1
  53. package/dist/components/InputGroup/InputGroup.d.ts +4 -2
  54. package/dist/components/InputGroup/InputGroup.d.ts.map +1 -1
  55. package/dist/components/InputGroup/InputGroup.stories.d.ts.map +1 -1
  56. package/dist/components/InputGroup/styles.css.d.ts +3 -3
  57. package/dist/components/InputGroup/styles.css.d.ts.map +1 -1
  58. package/dist/components/LinkButton/styles.css.d.ts +1 -1
  59. package/dist/components/LinkButton/styles.css.d.ts.map +1 -1
  60. package/dist/components/List/List.stories.d.ts.map +1 -1
  61. package/dist/components/List/styles.css.d.ts +3 -3
  62. package/dist/components/List/styles.css.d.ts.map +1 -1
  63. package/dist/components/Menu/styles.css.d.ts +4 -4
  64. package/dist/components/Menu/styles.css.d.ts.map +1 -1
  65. package/dist/components/PageShell/styles.css.d.ts +3 -3
  66. package/dist/components/PageShell/styles.css.d.ts.map +1 -1
  67. package/dist/components/Panel/styles.css.d.ts +3 -3
  68. package/dist/components/Panel/styles.css.d.ts.map +1 -1
  69. package/dist/components/Popover/Popover.stories.d.ts.map +1 -1
  70. package/dist/components/Popover/styles.css.d.ts +2 -2
  71. package/dist/components/Popover/styles.css.d.ts.map +1 -1
  72. package/dist/components/RadioGroup/RadioGroup.d.ts.map +1 -1
  73. package/dist/components/RadioGroup/styles.css.d.ts +5 -9
  74. package/dist/components/RadioGroup/styles.css.d.ts.map +1 -1
  75. package/dist/components/ScrollArea/ScrollArea.d.ts +2 -1
  76. package/dist/components/ScrollArea/ScrollArea.d.ts.map +1 -1
  77. package/dist/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
  78. package/dist/components/ScrollArea/styles.css.d.ts +8 -8
  79. package/dist/components/ScrollArea/styles.css.d.ts.map +1 -1
  80. package/dist/components/Select/styles.css.d.ts +4 -4
  81. package/dist/components/Select/styles.css.d.ts.map +1 -1
  82. package/dist/components/SideNav/styles.css.d.ts +7 -7
  83. package/dist/components/SideNav/styles.css.d.ts.map +1 -1
  84. package/dist/components/Spinner/Spinner.d.ts.map +1 -1
  85. package/dist/components/Spinner/styles.css.d.ts +10 -14
  86. package/dist/components/Spinner/styles.css.d.ts.map +1 -1
  87. package/dist/components/StatusIcon/StatusIcon.stories.d.ts.map +1 -1
  88. package/dist/components/Switch/Switch.d.ts.map +1 -1
  89. package/dist/components/Switch/styles.css.d.ts +10 -14
  90. package/dist/components/Switch/styles.css.d.ts.map +1 -1
  91. package/dist/components/Table/ColumnFilter.d.ts.map +1 -1
  92. package/dist/components/Table/FromTanstack.d.ts +2 -1
  93. package/dist/components/Table/FromTanstack.d.ts.map +1 -1
  94. package/dist/components/Table/Pagination.d.ts.map +1 -1
  95. package/dist/components/Table/SortIndicator.d.ts.map +1 -1
  96. package/dist/components/Table/Table.d.ts +11 -9
  97. package/dist/components/Table/Table.d.ts.map +1 -1
  98. package/dist/components/Table/Table.stories.d.ts +1 -0
  99. package/dist/components/Table/Table.stories.d.ts.map +1 -1
  100. package/dist/components/Table/styles.css.d.ts +6 -6
  101. package/dist/components/Table/styles.css.d.ts.map +1 -1
  102. package/dist/components/Tabs/styles.css.d.ts +8 -8
  103. package/dist/components/Tabs/styles.css.d.ts.map +1 -1
  104. package/dist/components/Tag/Tag.stories.d.ts.map +1 -1
  105. package/dist/components/Tag/styles.css.d.ts +4 -4
  106. package/dist/components/Tag/styles.css.d.ts.map +1 -1
  107. package/dist/components/TagGroup/TagGroup.d.ts.map +1 -1
  108. package/dist/components/TagGroup/styles.css.d.ts +4 -10
  109. package/dist/components/TagGroup/styles.css.d.ts.map +1 -1
  110. package/dist/components/Textarea/Textarea.stories.d.ts.map +1 -1
  111. package/dist/components/Textarea/styles.css.d.ts +3 -3
  112. package/dist/components/Textarea/styles.css.d.ts.map +1 -1
  113. package/dist/components/ThemeProvider/ThemeProvider.stories.d.ts.map +1 -1
  114. package/dist/components/Toast/Toast.stories.d.ts.map +1 -1
  115. package/dist/components/Toast/styles.css.d.ts +12 -12
  116. package/dist/components/Toast/styles.css.d.ts.map +1 -1
  117. package/dist/components/Toggle/styles.css.d.ts +8 -8
  118. package/dist/components/Toggle/styles.css.d.ts.map +1 -1
  119. package/dist/components/ToggleGroup/ToggleGroup.stories.d.ts.map +1 -1
  120. package/dist/components/ToggleGroup/styles.css.d.ts +1 -1
  121. package/dist/components/ToggleGroup/styles.css.d.ts.map +1 -1
  122. package/dist/components/Tooltip/styles.css.d.ts +1 -1
  123. package/dist/components/Tooltip/styles.css.d.ts.map +1 -1
  124. package/dist/components/Tree/styles.css.d.ts +4 -4
  125. package/dist/components/Tree/styles.css.d.ts.map +1 -1
  126. package/dist/components/VirtualTable/VirtualTable.d.ts +2 -1
  127. package/dist/components/VirtualTable/VirtualTable.d.ts.map +1 -1
  128. package/dist/components/VirtualTable/VirtualTable.stories.d.ts.map +1 -1
  129. package/dist/components/VirtualTable/styles.css.d.ts +7 -7
  130. package/dist/components/VirtualTable/styles.css.d.ts.map +1 -1
  131. package/dist/docs/Spacing.stories.d.ts.map +1 -1
  132. package/dist/docs/Typography.stories.d.ts.map +1 -1
  133. package/dist/docs/helpers.d.ts.map +1 -1
  134. package/dist/index.css +1 -1
  135. package/dist/index.js +2833 -2828
  136. package/dist/index.js.map +1 -1
  137. package/dist/shared/length.d.ts +29 -0
  138. package/dist/shared/length.d.ts.map +1 -0
  139. package/dist/shared/length.typecheck.d.ts +31 -0
  140. package/dist/shared/length.typecheck.d.ts.map +1 -0
  141. package/dist/styles/visually-hidden.css.d.ts +10 -0
  142. package/dist/styles/visually-hidden.css.d.ts.map +1 -0
  143. package/dist/table.js +166 -166
  144. package/dist/table.js.map +1 -1
  145. package/package.json +2 -2
  146. package/src/components/ActionBar/ActionBar.stories.tsx +4 -2
  147. package/src/components/ActionBar/styles.css.ts +11 -9
  148. package/src/components/Alert/styles.css.ts +4 -3
  149. package/src/components/Badge/styles.css.ts +3 -3
  150. package/src/components/Button/styles.css.ts +8 -7
  151. package/src/components/Callout/styles.css.ts +2 -1
  152. package/src/components/Card/Card.stories.tsx +2 -1
  153. package/src/components/Card/styles.css.ts +4 -3
  154. package/src/components/Checkbox/Checkbox.tsx +2 -1
  155. package/src/components/Checkbox/styles.css.ts +10 -11
  156. package/src/components/Cluster/Cluster.stories.tsx +2 -1
  157. package/src/components/ColorInput/styles.css.ts +9 -7
  158. package/src/components/ColorMode/styles.css.ts +4 -3
  159. package/src/components/Combobox/styles.css.ts +5 -3
  160. package/src/components/DetailPanel/DetailPanel.stories.tsx +5 -3
  161. package/src/components/DetailPanel/DetailPanel.tsx +3 -0
  162. package/src/components/DetailPanel/styles.css.ts +17 -11
  163. package/src/components/Dialog/Dialog.stories.tsx +2 -1
  164. package/src/components/Dialog/Dialog.tsx +3 -0
  165. package/src/components/Dialog/styles.css.ts +14 -9
  166. package/src/components/DragDrop/DragDrop.stories.tsx +2 -1
  167. package/src/components/DragDrop/DragDrop.tsx +2 -1
  168. package/src/components/DragDrop/styles.css.ts +0 -7
  169. package/src/components/Drawer/Drawer.tsx +3 -0
  170. package/src/components/Drawer/DrawerScroll.stories.tsx +5 -5
  171. package/src/components/Drawer/styles.css.ts +15 -10
  172. package/src/components/Field/Field.stories.tsx +3 -2
  173. package/src/components/Field/styles.css.ts +2 -1
  174. package/src/components/Form/Form.stories.tsx +4 -3
  175. package/src/components/Grid/Grid.meta.ts +2 -2
  176. package/src/components/Grid/Grid.stories.tsx +3 -2
  177. package/src/components/Grid/Grid.tsx +8 -6
  178. package/src/components/Grid/styles.css.ts +5 -4
  179. package/src/components/Input/Input.stories.tsx +2 -1
  180. package/src/components/Input/styles.css.ts +4 -3
  181. package/src/components/InputGroup/InputGroup.stories.tsx +3 -2
  182. package/src/components/InputGroup/InputGroup.tsx +5 -3
  183. package/src/components/InputGroup/styles.css.ts +4 -3
  184. package/src/components/LinkButton/styles.css.ts +2 -1
  185. package/src/components/List/List.stories.tsx +4 -2
  186. package/src/components/List/styles.css.ts +6 -4
  187. package/src/components/Menu/styles.css.ts +6 -4
  188. package/src/components/PageShell/styles.css.ts +4 -3
  189. package/src/components/Panel/styles.css.ts +4 -3
  190. package/src/components/Popover/Popover.stories.tsx +6 -4
  191. package/src/components/Popover/styles.css.ts +3 -2
  192. package/src/components/RadioGroup/RadioGroup.tsx +2 -1
  193. package/src/components/RadioGroup/styles.css.ts +8 -9
  194. package/src/components/ScrollArea/ScrollArea.meta.ts +1 -1
  195. package/src/components/ScrollArea/ScrollArea.stories.tsx +7 -5
  196. package/src/components/ScrollArea/ScrollArea.tsx +7 -2
  197. package/src/components/ScrollArea/styles.css.ts +10 -9
  198. package/src/components/Select/styles.css.ts +6 -4
  199. package/src/components/SideNav/styles.css.ts +10 -8
  200. package/src/components/Spinner/Spinner.tsx +2 -1
  201. package/src/components/Spinner/styles.css.ts +14 -14
  202. package/src/components/StatusIcon/StatusIcon.stories.tsx +2 -2
  203. package/src/components/Switch/Switch.tsx +2 -1
  204. package/src/components/Switch/styles.css.ts +15 -15
  205. package/src/components/Table/ColumnFilter.tsx +5 -4
  206. package/src/components/Table/FromTanstack.tsx +2 -1
  207. package/src/components/Table/Pagination.tsx +6 -4
  208. package/src/components/Table/SortIndicator.tsx +4 -2
  209. package/src/components/Table/Table.stories.tsx +47 -8
  210. package/src/components/Table/Table.tsx +19 -15
  211. package/src/components/Table/styles.css.ts +9 -7
  212. package/src/components/Tabs/styles.css.ts +11 -9
  213. package/src/components/Tag/Tag.stories.tsx +4 -2
  214. package/src/components/Tag/styles.css.ts +6 -5
  215. package/src/components/TagGroup/TagGroup.tsx +2 -1
  216. package/src/components/TagGroup/styles.css.ts +6 -10
  217. package/src/components/Textarea/Textarea.stories.tsx +2 -1
  218. package/src/components/Textarea/styles.css.ts +4 -3
  219. package/src/components/ThemeProvider/ThemeProvider.stories.tsx +7 -5
  220. package/src/components/Toast/Toast.stories.tsx +2 -1
  221. package/src/components/Toast/styles.css.ts +16 -14
  222. package/src/components/Toggle/Toggle.meta.ts +1 -1
  223. package/src/components/Toggle/styles.css.ts +12 -10
  224. package/src/components/ToggleGroup/ToggleGroup.meta.ts +1 -1
  225. package/src/components/ToggleGroup/ToggleGroup.stories.tsx +7 -6
  226. package/src/components/ToggleGroup/styles.css.ts +7 -6
  227. package/src/components/Tooltip/styles.css.ts +2 -1
  228. package/src/components/Tree/styles.css.ts +8 -6
  229. package/src/components/VirtualTable/VirtualTable.stories.tsx +4 -3
  230. package/src/components/VirtualTable/VirtualTable.tsx +5 -3
  231. package/src/components/VirtualTable/styles.css.ts +9 -8
  232. package/src/docs/Spacing.stories.tsx +11 -10
  233. package/src/docs/Typography.stories.tsx +8 -6
  234. package/src/docs/helpers.tsx +3 -2
  235. package/src/shared/length.ts +70 -0
  236. package/src/shared/length.typecheck.tsx +56 -0
  237. package/src/styles/visually-hidden.css.ts +16 -0
  238. package/dist/Table-CUp12BKZ.js +0 -1099
  239. package/dist/Table-CUp12BKZ.js.map +0 -1
  240. package/dist/components/Toggle/rowHeight.d.ts +0 -17
  241. package/dist/components/Toggle/rowHeight.d.ts.map +0 -1
  242. package/src/components/Toggle/rowHeight.ts +0 -12
@@ -3,10 +3,11 @@ import {expect, fn, waitFor} from 'storybook/test'
3
3
  import {createColumnHelper} from '@tanstack/react-table'
4
4
  import {css, html} from 'react-strict-dom'
5
5
  import {VirtualTable} from './VirtualTable'
6
+ import {sizes} from '@duro-app/tokens/tokens/sizes.css'
6
7
 
7
8
  const storyStyles = css.create({
8
9
  // Phone-width wrapper: below VirtualTable's 640px stackBelow default.
9
- narrow: {width: 400},
10
+ narrow: {width: sizes.dialogSm},
10
11
  })
11
12
 
12
13
  interface Item {
@@ -49,7 +50,7 @@ export const SmallList: Story = {
49
50
  export const Virtualized: Story = {
50
51
  args: {
51
52
  data: makeData(500),
52
- maxHeight: 300,
53
+ maxHeight: 'listMaxH',
53
54
  rangeLabel: ({from, to, total}) => `${from}-${to} of ${total}`,
54
55
  onVisiblePageChange: fn(),
55
56
  },
@@ -69,7 +70,7 @@ export const Virtualized: Story = {
69
70
  export const ScrollReportsPage: Story = {
70
71
  args: {
71
72
  data: makeData(500),
72
- maxHeight: 300,
73
+ maxHeight: 'listMaxH',
73
74
  pageSize: 50,
74
75
  rangeLabel: ({page, pages}) => `page ${page}/${pages}`,
75
76
  onVisiblePageChange: fn(),
@@ -13,6 +13,8 @@ import {
13
13
  import {useVirtualizer} from '@tanstack/react-virtual'
14
14
  import {breakpointsPx, type Breakpoint} from '@duro-app/tokens/tokens/breakpoints.css'
15
15
  import {styles} from './styles.css'
16
+ import {SIZES_PX} from '@duro-app/tokens/keys'
17
+ import {resolveLength, type Length} from '../../shared/length'
16
18
 
17
19
  // Measure + commit before paint on the client; no-op-safe on the server.
18
20
  const useIsoLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect
@@ -56,7 +58,7 @@ interface VirtualTableProps<TData> {
56
58
  /** Estimated row height for the virtualizer. Default 44. */
57
59
  estimateRowHeight?: number
58
60
  /** Max height of the scroll viewport once virtualized. Default '70vh'. */
59
- maxHeight?: number | string
61
+ maxHeight?: Length
60
62
  /** Render every row (no windowing) at or below this count. Default 150. */
61
63
  virtualizeThreshold?: number
62
64
  /**
@@ -94,7 +96,7 @@ export function VirtualTable<TData>({
94
96
  onVisiblePageChange,
95
97
  rangeLabel,
96
98
  pageSize = 50,
97
- estimateRowHeight = 44,
99
+ estimateRowHeight = SIZES_PX.touchTarget,
98
100
  maxHeight = '70vh',
99
101
  virtualizeThreshold = 150,
100
102
  stackBelow = 'sm',
@@ -288,7 +290,7 @@ export function VirtualTable<TData>({
288
290
  role="table"
289
291
  style={[
290
292
  stacked ? styles.stackScroll : styles.scroll,
291
- virtualize && styles.scrollMax(maxHeight),
293
+ virtualize && styles.scrollMax(resolveLength(maxHeight)),
292
294
  ]}
293
295
  >
294
296
  {stacked ? null : (
@@ -1,7 +1,8 @@
1
1
  import {css} from 'react-strict-dom'
2
2
  import {colors} from '@duro-app/tokens/tokens/colors.css'
3
- import {spacing, radii} from '@duro-app/tokens/tokens/spacing.css'
3
+ import {microSpacing, radii, spacing} from '@duro-app/tokens/tokens/spacing.css'
4
4
  import {typography} from '@duro-app/tokens/tokens/typography.css'
5
+ import {borders} from '@duro-app/tokens/tokens/borders.css'
5
6
 
6
7
  export const styles = css.create({
7
8
  wrap: {
@@ -11,7 +12,7 @@ export const styles = css.create({
11
12
  scroll: {
12
13
  position: 'relative',
13
14
  width: '100%',
14
- borderWidth: 1,
15
+ borderWidth: borders.hairline,
15
16
  borderStyle: 'solid',
16
17
  borderColor: colors.border,
17
18
  borderRadius: radii.md,
@@ -32,7 +33,7 @@ export const styles = css.create({
32
33
  headRow: {
33
34
  display: 'flex',
34
35
  flexDirection: 'row',
35
- borderBottomWidth: 1,
36
+ borderBottomWidth: borders.hairline,
36
37
  borderBottomStyle: 'solid',
37
38
  borderBottomColor: colors.border,
38
39
  },
@@ -71,7 +72,7 @@ export const styles = css.create({
71
72
  flexDirection: 'row',
72
73
  alignItems: 'center',
73
74
  width: '100%',
74
- borderBottomWidth: 1,
75
+ borderBottomWidth: borders.hairline,
75
76
  borderBottomStyle: 'solid',
76
77
  borderBottomColor: colors.border,
77
78
  },
@@ -124,7 +125,7 @@ export const styles = css.create({
124
125
  gap: spacing.xs,
125
126
  width: '100%',
126
127
  padding: spacing.sm,
127
- borderWidth: 1,
128
+ borderWidth: borders.hairline,
128
129
  borderStyle: 'solid',
129
130
  borderColor: colors.border,
130
131
  borderRadius: radii.sm,
@@ -161,13 +162,13 @@ export const styles = css.create({
161
162
  position: 'absolute',
162
163
  right: spacing.sm,
163
164
  bottom: spacing.sm,
164
- paddingTop: 3,
165
- paddingBottom: 3,
165
+ paddingTop: microSpacing.px3,
166
+ paddingBottom: microSpacing.px3,
166
167
  paddingLeft: spacing.sm,
167
168
  paddingRight: spacing.sm,
168
169
  borderRadius: radii.full,
169
170
  backgroundColor: colors.bgCardHover,
170
- borderWidth: 1,
171
+ borderWidth: borders.hairline,
171
172
  borderStyle: 'solid',
172
173
  borderColor: colors.border,
173
174
  color: colors.textMuted,
@@ -7,6 +7,8 @@ import {Inline} from '../components/Inline/Inline'
7
7
  import {useContainerQuery} from '../hooks/useContainerQuery'
8
8
  import {TokenTable} from './helpers'
9
9
  import {typography, typeScale} from '@duro-app/tokens/tokens/typography.css'
10
+ import {borders} from '@duro-app/tokens/tokens/borders.css'
11
+ import {sizes} from '@duro-app/tokens/tokens/sizes.css'
10
12
 
11
13
  const primitiveTokens: Record<string, string> = {
12
14
  xs: '4px',
@@ -33,7 +35,7 @@ export default meta
33
35
 
34
36
  const styles = css.create({
35
37
  wrapper: {
36
- maxWidth: 640,
38
+ maxWidth: sizes.panelLg,
37
39
  },
38
40
  hint: {
39
41
  fontSize: typography.fontSizeXs,
@@ -41,10 +43,10 @@ const styles = css.create({
41
43
  fontStyle: 'italic',
42
44
  },
43
45
  baselineRow: {
44
- height: 24,
46
+ height: sizes.iconLg,
45
47
  display: 'flex',
46
48
  alignItems: 'center',
47
- borderBottomWidth: 1,
49
+ borderBottomWidth: borders.hairline,
48
50
  borderBottomStyle: 'dashed',
49
51
  borderBottomColor: colors.border,
50
52
  },
@@ -52,11 +54,10 @@ const styles = css.create({
52
54
  fontSize: typography.fontSizeXs,
53
55
  fontFamily: 'monospace',
54
56
  color: colors.textMuted,
55
- width: 50,
57
+ width: sizes.iconXxl,
56
58
  },
57
59
  baselineBlock: {
58
- flexGrow: 1,
59
- height: 24,
60
+ height: sizes.iconLg,
60
61
  backgroundColor: colors.accent,
61
62
  opacity: 0.15,
62
63
  borderRadius: radii.xs,
@@ -64,13 +65,13 @@ const styles = css.create({
64
65
  resizableContainer: {
65
66
  resize: 'horizontal',
66
67
  overflow: 'auto',
67
- borderWidth: 2,
68
+ borderWidth: borders.strong,
68
69
  borderStyle: 'dashed',
69
70
  borderColor: colors.border,
70
71
  padding: spacing.md,
71
- minWidth: 200,
72
+ minWidth: sizes.listMaxHSm,
72
73
  maxWidth: '100%',
73
- width: 600,
74
+ width: sizes.pageSm,
74
75
  },
75
76
  sizeLabel: {
76
77
  fontSize: typography.fontSizeHeading,
@@ -87,7 +88,7 @@ const styles = css.create({
87
88
  color: colors.successText,
88
89
  },
89
90
  mappingRow: {
90
- borderBottomWidth: 1,
91
+ borderBottomWidth: borders.hairline,
91
92
  borderBottomStyle: 'solid',
92
93
  borderBottomColor: colors.border,
93
94
  fontFamily: 'monospace',
@@ -8,6 +8,8 @@ import {Text} from '../components/Text/Text'
8
8
  import {Heading} from '../components/Heading/Heading'
9
9
  import {TypeScaleTable} from './helpers'
10
10
  import {typography} from '@duro-app/tokens/tokens/typography.css'
11
+ import {borders} from '@duro-app/tokens/tokens/borders.css'
12
+ import {sizes} from '@duro-app/tokens/tokens/sizes.css'
11
13
 
12
14
  const meta: Meta = {
13
15
  title: 'Foundations/Typography',
@@ -169,7 +171,7 @@ export const TextVariants: StoryObj = {
169
171
 
170
172
  const localStyles = css.create({
171
173
  wrapper: {
172
- maxWidth: 720,
174
+ maxWidth: sizes.dialogLg,
173
175
  },
174
176
  hint: {
175
177
  fontSize: typography.fontSizeXs,
@@ -187,8 +189,8 @@ const localStyles = css.create({
187
189
  position: 'relative',
188
190
  },
189
191
  gridLine: {
190
- height: 24,
191
- borderBottomWidth: 1,
192
+ height: sizes.iconLg,
193
+ borderBottomWidth: borders.hairline,
192
194
  borderBottomStyle: 'dashed',
193
195
  borderBottomColor: colors.border,
194
196
  },
@@ -201,12 +203,12 @@ const localStyles = css.create({
201
203
  resizableContainer: {
202
204
  resize: 'horizontal',
203
205
  overflow: 'auto',
204
- borderWidth: 2,
206
+ borderWidth: borders.strong,
205
207
  borderStyle: 'dashed',
206
208
  borderColor: colors.border,
207
209
  padding: spacing.md,
208
- minWidth: 280,
210
+ minWidth: sizes.gridColMd,
209
211
  maxWidth: '100%',
210
- width: 700,
212
+ width: sizes.dialogLg,
211
213
  },
212
214
  })
@@ -1,12 +1,13 @@
1
1
  import {css, html} from 'react-strict-dom'
2
2
  import {colors} from '@duro-app/tokens/tokens/colors.css'
3
- import {typography, typeScale} from '@duro-app/tokens/tokens/typography.css'
3
+ import {typography} from '@duro-app/tokens/tokens/typography.css'
4
4
  import {Table} from '../components/Table/Table'
5
5
  import {radii, spacing} from '@duro-app/tokens/tokens/spacing.css'
6
+ import {sizes} from '@duro-app/tokens/tokens/sizes.css'
6
7
 
7
8
  const styles = css.create({
8
9
  bar: {
9
- height: 12,
10
+ height: sizes.glyphSm,
10
11
  borderRadius: radii.xs,
11
12
  backgroundColor: colors.accent,
12
13
  },
@@ -0,0 +1,70 @@
1
+ import {sizes} from '@duro-app/tokens/tokens/sizes.css'
2
+ import {SIZE_KEYS, type SizeToken} from '@duro-app/tokens/keys'
3
+
4
+ /**
5
+ * A length a measure prop accepts without a token: zero, a relative unit or a
6
+ * keyword. These are the exemptions of design-system.every-measure-is-a-token
7
+ * (ADR-0027); a px value is not one of them.
8
+ */
9
+ export type RelativeLength =
10
+ | 0
11
+ | '0'
12
+ | 'auto'
13
+ | 'none'
14
+ | 'min-content'
15
+ | 'max-content'
16
+ | 'fit-content'
17
+ | `${number}%`
18
+ | `${number}vh`
19
+ | `${number}vw`
20
+ | `${number}dvh`
21
+ | `${number}svh`
22
+ | `${number}lvh`
23
+ | `${number}em`
24
+ | `${number}rem`
25
+ | `${number}ch`
26
+
27
+ /** A measure prop: a `sizes` token key (`"gridColMd"`) or a relative length. */
28
+ export type Length = SizeToken | RelativeLength
29
+
30
+ /** A Length written as a string, as it appears inside a track function. */
31
+ type LengthString = Exclude<Length, number>
32
+
33
+ /** One argument of `minmax()`: a Length or a fraction. */
34
+ type TrackBreadth = LengthString | `${number}fr`
35
+
36
+ /**
37
+ * A CSS grid track: a Length, a fraction, or a track function whose
38
+ * arguments are themselves Lengths or fractions — `'minmax(gridColSm, 1fr)'`,
39
+ * `'minmax(0, 2fr)'`, `'fit-content(labelMinW)'`. A px inside is a type
40
+ * error, as it is anywhere else. Arguments are separated by `, `.
41
+ */
42
+ export type GridTrack =
43
+ | Length
44
+ | `${number}fr`
45
+ | `minmax(${TrackBreadth}, ${TrackBreadth})`
46
+ | `fit-content(${LengthString})`
47
+
48
+ const sizeKeys: ReadonlySet<string> = new Set(SIZE_KEYS)
49
+
50
+ /** The CSS value for a Length: a size token key becomes its variable. */
51
+ export function resolveLength(value: Length): string | number {
52
+ return typeof value === 'string' && sizeKeys.has(value) ? sizes[value as SizeToken] : value
53
+ }
54
+
55
+ /**
56
+ * The CSS value for a GridTrack: a size token key becomes its variable, also
57
+ * as an argument of `minmax()` / `fit-content()`.
58
+ */
59
+ export function resolveTrack(track: GridTrack): string | number {
60
+ // Read as a plain value: narrowing the template-literal union is more than
61
+ // the checker will represent (TS2590), and the callers only need the CSS.
62
+ const value: string | number = track
63
+ if (typeof value !== 'string') return value
64
+ const fn = /^(minmax|fit-content)\((.*)\)$/.exec(value)
65
+ if (fn) {
66
+ const args = fn[2]!.split(',').map((arg) => String(resolveLength(arg.trim() as Length)))
67
+ return `${fn[1]}(${args.join(', ')})`
68
+ }
69
+ return sizeKeys.has(value) ? sizes[value as SizeToken] : value
70
+ }
@@ -0,0 +1,56 @@
1
+ // Compile-only fixtures for measure props (ADR-0027, plan 2c′). `pnpm typecheck`
2
+ // fails if a raw px becomes assignable to a measure prop, or if a token key or
3
+ // a relative length stops being. Never imported at runtime.
4
+
5
+ import type {Grid} from '../components/Grid/Grid'
6
+ import type {InputGroup} from '../components/InputGroup/InputGroup'
7
+ import type {ScrollArea} from '../components/ScrollArea/ScrollArea'
8
+ import type {Table} from '../components/Table/Table'
9
+ import type {VirtualTable} from '../components/VirtualTable/VirtualTable'
10
+ import type {GridTrack, Length} from './length'
11
+
12
+ /** `true` when every member of T is assignable to U. */
13
+ type Assignable<T, U> = [T] extends [U] ? true : false
14
+
15
+ /** The props a function component takes. */
16
+ type PropsOf<C> = C extends (props: infer P) => unknown ? P : never
17
+ type Prop<C, K extends keyof PropsOf<C>> = NonNullable<PropsOf<C>[K]>
18
+
19
+ // Accepted: token keys, zero, relative lengths, keywords.
20
+ export const lengthTokens: Assignable<'gridColMd' | 'touchTarget', Length> = true
21
+ export const lengthRelative: Assignable<0 | '0' | '100%' | '70vh' | '2rem' | 'auto', Length> = true
22
+ export const trackForms: Assignable<
23
+ 'iconButton' | '2fr' | 'max-content' | 'minmax(0, 2fr)',
24
+ GridTrack
25
+ > = true
26
+
27
+ // Refused: px as a string or a number.
28
+ export const lengthPxString: Assignable<'280px', Length> = false
29
+ export const lengthPxNumber: Assignable<44, Length> = false
30
+ export const trackPx: Assignable<'40px', GridTrack> = false
31
+ export const trackMinmaxPx: Assignable<'minmax(40px, 1fr)', GridTrack> = false
32
+ export const trackFitPx: Assignable<'fit-content(120px)', GridTrack> = false
33
+ export const trackMinmaxTokens: Assignable<
34
+ | 'minmax(gridColSm, 1fr)'
35
+ | 'minmax(0, 2fr)'
36
+ | 'minmax(labelMinW, auto)'
37
+ | 'fit-content(labelMinW)',
38
+ GridTrack
39
+ > = true
40
+
41
+ // The props themselves.
42
+ export const gridMin: Assignable<'280px', Prop<typeof Grid, 'minColumnWidth'>> = false
43
+ export const gridMinToken: Assignable<'gridColMd', Prop<typeof Grid, 'minColumnWidth'>> = true
44
+ export const addonMin: Assignable<80, Prop<typeof InputGroup.Addon, 'minWidth'>> = false
45
+ export const viewportMax: Assignable<300, Prop<typeof ScrollArea.Viewport, 'maxHeight'>> = false
46
+ export const viewportMaxToken: Assignable<
47
+ 'listMaxH',
48
+ Prop<typeof ScrollArea.Viewport, 'maxHeight'>
49
+ > = true
50
+ export const tableMin: Assignable<120, Prop<typeof Table.Root, 'minColumnWidth'>> = false
51
+ export const headerWidth: Assignable<'40px', Prop<typeof Table.HeaderCell, 'width'>> = false
52
+ export const headerWidthToken: Assignable<
53
+ 'iconButton',
54
+ Prop<typeof Table.HeaderCell, 'width'>
55
+ > = true
56
+ export const virtualMax: Assignable<300, Prop<typeof VirtualTable, 'maxHeight'>> = false
@@ -0,0 +1,16 @@
1
+ import {css} from 'react-strict-dom'
2
+
3
+ // The visually-hidden technique: a 1×1 box clipped by overflow, still in the
4
+ // accessibility tree and still focusable where the element is. The 1px is the
5
+ // technique, not a design measure, so this module is the one file the
6
+ // every-measure-is-a-token rule exempts (ADR-0027; `exemptFiles` in
7
+ // eslint.config.js). Components layer their own extras on top (`opacity: 0`
8
+ // for a native input, `clip` for a label).
9
+ export const visuallyHidden = css.create({
10
+ base: {
11
+ position: 'absolute',
12
+ width: 1,
13
+ height: 1,
14
+ overflow: 'hidden',
15
+ },
16
+ })