@remix-run/ui 0.3.0 → 0.4.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 (308) hide show
  1. package/README.md +50 -164
  2. package/dist/accordion/index.d.ts +46 -0
  3. package/dist/accordion/index.js +142 -0
  4. package/dist/accordion/index.js.map +1 -0
  5. package/dist/accordion/primitives.d.ts +104 -0
  6. package/dist/accordion/primitives.js +312 -0
  7. package/dist/accordion/primitives.js.map +1 -0
  8. package/dist/{components/anchor/anchor.js → anchor/index.js} +1 -1
  9. package/dist/anchor/index.js.map +1 -0
  10. package/dist/animation/demos/reordering.js +9 -6
  11. package/dist/animation/demos/reordering.js.map +1 -1
  12. package/dist/{components/breadcrumbs/breadcrumbs.js → breadcrumbs/index.js} +19 -19
  13. package/dist/breadcrumbs/index.js.map +1 -0
  14. package/dist/button/index.d.ts +15 -0
  15. package/dist/button/index.js +128 -0
  16. package/dist/button/index.js.map +1 -0
  17. package/dist/checkbox/index.d.ts +14 -0
  18. package/dist/checkbox/index.js +125 -0
  19. package/dist/checkbox/index.js.map +1 -0
  20. package/dist/combobox/index.d.ts +21 -0
  21. package/dist/combobox/index.js +58 -0
  22. package/dist/combobox/index.js.map +1 -0
  23. package/dist/{components/combobox/combobox.d.ts → combobox/primitives.d.ts} +3 -7
  24. package/dist/{components/combobox/combobox.js → combobox/primitives.js} +8 -61
  25. package/dist/combobox/primitives.js.map +1 -0
  26. package/dist/input/index.d.ts +13 -0
  27. package/dist/input/index.js +121 -0
  28. package/dist/input/index.js.map +1 -0
  29. package/dist/listbox/flash-attribute.js.map +1 -0
  30. package/dist/{components/listbox/listbox.d.ts → listbox/index.d.ts} +2 -6
  31. package/dist/{components/listbox/listbox.js → listbox/index.js} +4 -82
  32. package/dist/listbox/index.js.map +1 -0
  33. package/dist/menu/hover-aim.js.map +1 -0
  34. package/dist/menu/index.d.ts +42 -0
  35. package/dist/menu/index.js +250 -0
  36. package/dist/menu/index.js.map +1 -0
  37. package/dist/{components/menu/menu.d.ts → menu/primitives.d.ts} +3 -32
  38. package/dist/{components/menu/menu.js → menu/primitives.js} +97 -314
  39. package/dist/menu/primitives.js.map +1 -0
  40. package/dist/{components/popover/popover.d.ts → popover/index.d.ts} +2 -4
  41. package/dist/{components/popover/popover.js → popover/index.js} +5 -48
  42. package/dist/popover/index.js.map +1 -0
  43. package/dist/{interactions/outside-click/outside-click-mixin.js → popover/outside-click.js} +1 -1
  44. package/dist/popover/outside-click.js.map +1 -0
  45. package/dist/popover/scroll-lock.d.ts +1 -0
  46. package/dist/{utils → popover}/scroll-lock.js +0 -18
  47. package/dist/popover/scroll-lock.js.map +1 -0
  48. package/dist/radio/index.d.ts +12 -0
  49. package/dist/radio/index.js +77 -0
  50. package/dist/radio/index.js.map +1 -0
  51. package/dist/runtime/reconcile.js +11 -5
  52. package/dist/runtime/reconcile.js.map +1 -1
  53. package/dist/runtime/vdom.js +3 -0
  54. package/dist/runtime/vdom.js.map +1 -1
  55. package/dist/select/index.d.ts +19 -0
  56. package/dist/select/index.js +95 -0
  57. package/dist/select/index.js.map +1 -0
  58. package/dist/select/keydown.js.map +1 -0
  59. package/dist/{components/select/select.d.ts → select/primitives.d.ts} +4 -6
  60. package/dist/{components/select/select.js → select/primitives.js} +11 -63
  61. package/dist/select/primitives.js.map +1 -0
  62. package/dist/server/stream.js +2 -2
  63. package/dist/server/stream.js.map +1 -1
  64. package/dist/shared/focus-styles.d.ts +1 -0
  65. package/dist/shared/focus-styles.js +2 -0
  66. package/dist/shared/focus-styles.js.map +1 -0
  67. package/dist/shared/icons.d.ts +9 -0
  68. package/dist/shared/icons.js +42 -0
  69. package/dist/shared/icons.js.map +1 -0
  70. package/dist/shared/listbox-popover-styles.d.ts +6 -0
  71. package/dist/shared/listbox-popover-styles.js +137 -0
  72. package/dist/shared/listbox-popover-styles.js.map +1 -0
  73. package/dist/shared/style-values.d.ts +78 -0
  74. package/dist/{theme/presets/rmx-01/index.js → shared/style-values.js} +3 -34
  75. package/dist/shared/style-values.js.map +1 -0
  76. package/dist/{interactions/typeahead/typeahead-mixin.js → shared/typeahead.js} +1 -1
  77. package/dist/shared/typeahead.js.map +1 -0
  78. package/dist/shared/wait-for-css-transition.js.map +1 -0
  79. package/dist/shared/wait.js.map +1 -0
  80. package/dist/tabs/index.d.ts +32 -0
  81. package/dist/tabs/index.js +157 -0
  82. package/dist/tabs/index.js.map +1 -0
  83. package/dist/tabs/primitives.d.ts +57 -0
  84. package/dist/tabs/primitives.js +238 -0
  85. package/dist/tabs/primitives.js.map +1 -0
  86. package/dist/toggle/index.d.ts +9 -0
  87. package/dist/toggle/index.js +108 -0
  88. package/dist/toggle/index.js.map +1 -0
  89. package/dist/toggle/primitives.d.ts +29 -0
  90. package/dist/toggle/primitives.js +127 -0
  91. package/dist/toggle/primitives.js.map +1 -0
  92. package/package.json +73 -44
  93. package/src/{components/accordion → accordion}/README.md +50 -14
  94. package/src/accordion/index.tsx +285 -0
  95. package/src/accordion/primitives.tsx +512 -0
  96. package/src/{components/anchor → anchor}/README.md +37 -2
  97. package/src/animation/demos/reordering.tsx +9 -6
  98. package/src/{components/breadcrumbs → breadcrumbs}/README.md +4 -4
  99. package/src/{components/breadcrumbs/breadcrumbs.tsx → breadcrumbs/index.tsx} +18 -18
  100. package/src/button/README.md +44 -0
  101. package/src/button/index.ts +168 -0
  102. package/src/checkbox/README.md +59 -0
  103. package/src/checkbox/index.ts +162 -0
  104. package/src/{components/combobox → combobox}/README.md +58 -9
  105. package/src/combobox/index.tsx +112 -0
  106. package/src/{components/combobox/combobox.tsx → combobox/primitives.tsx} +5 -91
  107. package/src/input/README.md +52 -0
  108. package/src/input/index.ts +147 -0
  109. package/src/{components/listbox → listbox}/README.md +9 -41
  110. package/src/{components/listbox/listbox.ts → listbox/index.ts} +2 -87
  111. package/src/{components/menu → menu}/README.md +55 -14
  112. package/src/menu/index.tsx +354 -0
  113. package/src/{components/menu/menu.tsx → menu/primitives.tsx} +99 -413
  114. package/src/{components/popover → popover}/README.md +20 -39
  115. package/src/{components/popover/popover.ts → popover/index.ts} +3 -57
  116. package/src/{utils → popover}/scroll-lock.ts +0 -28
  117. package/src/radio/README.md +53 -0
  118. package/src/radio/index.ts +100 -0
  119. package/src/runtime/demos/readme.demo.tsx +16 -14
  120. package/src/runtime/reconcile.ts +11 -5
  121. package/src/runtime/vdom.ts +3 -0
  122. package/src/{components/select → select}/README.md +29 -19
  123. package/src/select/index.tsx +159 -0
  124. package/src/{components/select/select.tsx → select/primitives.tsx} +10 -98
  125. package/src/server/stream.ts +3 -3
  126. package/src/shared/focus-styles.ts +2 -0
  127. package/src/shared/icons.tsx +62 -0
  128. package/src/shared/listbox-popover-styles.ts +146 -0
  129. package/src/shared/style-values.ts +165 -0
  130. package/src/tabs/README.md +141 -0
  131. package/src/tabs/index.tsx +244 -0
  132. package/src/tabs/primitives.ts +365 -0
  133. package/src/toggle/README.md +56 -0
  134. package/src/toggle/index.tsx +134 -0
  135. package/src/toggle/primitives.ts +192 -0
  136. package/dist/animation/demos/animation.demo.d.ts +0 -5
  137. package/dist/animation/demos/animation.demo.js +0 -92
  138. package/dist/animation/demos/animation.demo.js.map +0 -1
  139. package/dist/animation/demos/spring.demo.d.ts +0 -6
  140. package/dist/animation/demos/spring.demo.js +0 -304
  141. package/dist/animation/demos/spring.demo.js.map +0 -1
  142. package/dist/components/accordion/accordion.d.ts +0 -92
  143. package/dist/components/accordion/accordion.js +0 -335
  144. package/dist/components/accordion/accordion.js.map +0 -1
  145. package/dist/components/accordion/demos/card.demo.d.ts +0 -7
  146. package/dist/components/accordion/demos/card.demo.js +0 -59
  147. package/dist/components/accordion/demos/card.demo.js.map +0 -1
  148. package/dist/components/accordion/demos/multiple.demo.d.ts +0 -7
  149. package/dist/components/accordion/demos/multiple.demo.js +0 -20
  150. package/dist/components/accordion/demos/multiple.demo.js.map +0 -1
  151. package/dist/components/accordion/demos/overview.demo.d.ts +0 -7
  152. package/dist/components/accordion/demos/overview.demo.js +0 -20
  153. package/dist/components/accordion/demos/overview.demo.js.map +0 -1
  154. package/dist/components/anchor/anchor.js.map +0 -1
  155. package/dist/components/breadcrumbs/basic.demo.d.ts +0 -6
  156. package/dist/components/breadcrumbs/basic.demo.js +0 -15
  157. package/dist/components/breadcrumbs/basic.demo.js.map +0 -1
  158. package/dist/components/breadcrumbs/breadcrumbs.js.map +0 -1
  159. package/dist/components/breadcrumbs/separator.demo.d.ts +0 -6
  160. package/dist/components/breadcrumbs/separator.demo.js +0 -15
  161. package/dist/components/breadcrumbs/separator.demo.js.map +0 -1
  162. package/dist/components/button/button.d.ts +0 -105
  163. package/dist/components/button/button.js +0 -207
  164. package/dist/components/button/button.js.map +0 -1
  165. package/dist/components/button/demos/aliases.demo.d.ts +0 -7
  166. package/dist/components/button/demos/aliases.demo.js +0 -19
  167. package/dist/components/button/demos/aliases.demo.js.map +0 -1
  168. package/dist/components/button/demos/basic.demo.d.ts +0 -7
  169. package/dist/components/button/demos/basic.demo.js +0 -20
  170. package/dist/components/button/demos/basic.demo.js.map +0 -1
  171. package/dist/components/button/demos/states.demo.d.ts +0 -7
  172. package/dist/components/button/demos/states.demo.js +0 -30
  173. package/dist/components/button/demos/states.demo.js.map +0 -1
  174. package/dist/components/combobox/combobox.js.map +0 -1
  175. package/dist/components/combobox/overview.demo.d.ts +0 -7
  176. package/dist/components/combobox/overview.demo.js +0 -154
  177. package/dist/components/combobox/overview.demo.js.map +0 -1
  178. package/dist/components/glyph/glyph.d.ts +0 -14
  179. package/dist/components/glyph/glyph.js +0 -65
  180. package/dist/components/glyph/glyph.js.map +0 -1
  181. package/dist/components/listbox/listbox.js.map +0 -1
  182. package/dist/components/listbox/overview.demo.d.ts +0 -7
  183. package/dist/components/listbox/overview.demo.js +0 -65
  184. package/dist/components/listbox/overview.demo.js.map +0 -1
  185. package/dist/components/menu/demos/bubbling.demo.d.ts +0 -6
  186. package/dist/components/menu/demos/bubbling.demo.js +0 -16
  187. package/dist/components/menu/demos/bubbling.demo.js.map +0 -1
  188. package/dist/components/menu/demos/context-trigger.demo.d.ts +0 -7
  189. package/dist/components/menu/demos/context-trigger.demo.js +0 -87
  190. package/dist/components/menu/demos/context-trigger.demo.js.map +0 -1
  191. package/dist/components/menu/demos/overview.demo.d.ts +0 -7
  192. package/dist/components/menu/demos/overview.demo.js +0 -33
  193. package/dist/components/menu/demos/overview.demo.js.map +0 -1
  194. package/dist/components/menu/hover-aim.js.map +0 -1
  195. package/dist/components/menu/menu.js.map +0 -1
  196. package/dist/components/popover/overview.demo.d.ts +0 -7
  197. package/dist/components/popover/overview.demo.js +0 -65
  198. package/dist/components/popover/overview.demo.js.map +0 -1
  199. package/dist/components/popover/popover.js.map +0 -1
  200. package/dist/components/select/deconstructed.demo.d.ts +0 -7
  201. package/dist/components/select/deconstructed.demo.js +0 -54
  202. package/dist/components/select/deconstructed.demo.js.map +0 -1
  203. package/dist/components/select/overview.demo.d.ts +0 -6
  204. package/dist/components/select/overview.demo.js +0 -28
  205. package/dist/components/select/overview.demo.js.map +0 -1
  206. package/dist/components/select/select.js.map +0 -1
  207. package/dist/components/separator/separator.d.ts +0 -2
  208. package/dist/components/separator/separator.js +0 -15
  209. package/dist/components/separator/separator.js.map +0 -1
  210. package/dist/components/tabs/tabs.d.ts +0 -78
  211. package/dist/components/tabs/tabs.js +0 -339
  212. package/dist/components/tabs/tabs.js.map +0 -1
  213. package/dist/interactions/keydown/keydown.js.map +0 -1
  214. package/dist/interactions/outside-click/outside-click-mixin.js.map +0 -1
  215. package/dist/interactions/typeahead/typeahead-mixin.js.map +0 -1
  216. package/dist/runtime/demos/basic.demo.d.ts +0 -6
  217. package/dist/runtime/demos/basic.demo.js +0 -16
  218. package/dist/runtime/demos/basic.demo.js.map +0 -1
  219. package/dist/runtime/demos/controlled-uncontrolled-values.demo.d.ts +0 -6
  220. package/dist/runtime/demos/controlled-uncontrolled-values.demo.js +0 -77
  221. package/dist/runtime/demos/controlled-uncontrolled-values.demo.js.map +0 -1
  222. package/dist/runtime/demos/keyed-list.demo.d.ts +0 -6
  223. package/dist/runtime/demos/keyed-list.demo.js +0 -62
  224. package/dist/runtime/demos/keyed-list.demo.js.map +0 -1
  225. package/dist/runtime/demos/readme.demo.d.ts +0 -5
  226. package/dist/runtime/demos/readme.demo.js +0 -396
  227. package/dist/runtime/demos/readme.demo.js.map +0 -1
  228. package/dist/theme/contract.d.ts +0 -61
  229. package/dist/theme/contract.js +0 -131
  230. package/dist/theme/contract.js.map +0 -1
  231. package/dist/theme/glyph-contract.d.ts +0 -11
  232. package/dist/theme/glyph-contract.js +0 -34
  233. package/dist/theme/glyph-contract.js.map +0 -1
  234. package/dist/theme/presets/rmx-01/glyphs.d.ts +0 -2
  235. package/dist/theme/presets/rmx-01/glyphs.js +0 -252
  236. package/dist/theme/presets/rmx-01/glyphs.js.map +0 -1
  237. package/dist/theme/presets/rmx-01/index.d.ts +0 -4
  238. package/dist/theme/presets/rmx-01/index.js.map +0 -1
  239. package/dist/theme/runtime.d.ts +0 -2
  240. package/dist/theme/runtime.js +0 -84
  241. package/dist/theme/runtime.js.map +0 -1
  242. package/dist/theme/theme.d.ts +0 -6
  243. package/dist/theme/theme.js +0 -5
  244. package/dist/theme/theme.js.map +0 -1
  245. package/dist/utils/flash-attribute.js.map +0 -1
  246. package/dist/utils/scroll-lock.d.ts +0 -3
  247. package/dist/utils/scroll-lock.js.map +0 -1
  248. package/dist/utils/wait-for-css-transition.js.map +0 -1
  249. package/dist/utils/wait.js.map +0 -1
  250. package/src/animation/demos/animation.demo.tsx +0 -194
  251. package/src/animation/demos/spring.demo.tsx +0 -385
  252. package/src/components/accordion/accordion.tsx +0 -565
  253. package/src/components/accordion/demos/card.demo.tsx +0 -114
  254. package/src/components/accordion/demos/multiple.demo.tsx +0 -57
  255. package/src/components/accordion/demos/overview.demo.tsx +0 -57
  256. package/src/components/breadcrumbs/basic.demo.tsx +0 -18
  257. package/src/components/breadcrumbs/separator.demo.tsx +0 -19
  258. package/src/components/button/README.md +0 -44
  259. package/src/components/button/button.tsx +0 -286
  260. package/src/components/button/demos/aliases.demo.tsx +0 -28
  261. package/src/components/button/demos/basic.demo.tsx +0 -31
  262. package/src/components/button/demos/states.demo.tsx +0 -53
  263. package/src/components/combobox/overview.demo.tsx +0 -200
  264. package/src/components/glyph/README.md +0 -72
  265. package/src/components/glyph/glyph.tsx +0 -110
  266. package/src/components/listbox/overview.demo.tsx +0 -102
  267. package/src/components/menu/demos/bubbling.demo.tsx +0 -35
  268. package/src/components/menu/demos/context-trigger.demo.tsx +0 -133
  269. package/src/components/menu/demos/overview.demo.tsx +0 -77
  270. package/src/components/popover/overview.demo.tsx +0 -144
  271. package/src/components/select/deconstructed.demo.tsx +0 -96
  272. package/src/components/select/overview.demo.tsx +0 -52
  273. package/src/components/separator/separator.ts +0 -19
  274. package/src/components/tabs/README.md +0 -105
  275. package/src/components/tabs/tabs.tsx +0 -504
  276. package/src/runtime/demos/basic.demo.tsx +0 -21
  277. package/src/runtime/demos/controlled-uncontrolled-values.demo.tsx +0 -177
  278. package/src/runtime/demos/keyed-list.demo.tsx +0 -94
  279. package/src/theme/README.md +0 -103
  280. package/src/theme/contract.ts +0 -215
  281. package/src/theme/glyph-contract.ts +0 -59
  282. package/src/theme/presets/rmx-01/glyphs.tsx +0 -308
  283. package/src/theme/presets/rmx-01/index.ts +0 -123
  284. package/src/theme/runtime.ts +0 -119
  285. package/src/theme/theme.ts +0 -15
  286. package/src/utils/scroll-lock/README.md +0 -33
  287. /package/dist/{components/anchor/anchor.d.ts → anchor/index.d.ts} +0 -0
  288. /package/dist/{components/breadcrumbs/breadcrumbs.d.ts → breadcrumbs/index.d.ts} +0 -0
  289. /package/dist/{utils → listbox}/flash-attribute.d.ts +0 -0
  290. /package/dist/{utils → listbox}/flash-attribute.js +0 -0
  291. /package/dist/{components/menu → menu}/hover-aim.d.ts +0 -0
  292. /package/dist/{components/menu → menu}/hover-aim.js +0 -0
  293. /package/dist/{interactions/outside-click/outside-click-mixin.d.ts → popover/outside-click.d.ts} +0 -0
  294. /package/dist/{interactions/keydown → select}/keydown.d.ts +0 -0
  295. /package/dist/{interactions/keydown → select}/keydown.js +0 -0
  296. /package/dist/{interactions/typeahead/typeahead-mixin.d.ts → shared/typeahead.d.ts} +0 -0
  297. /package/dist/{utils → shared}/wait-for-css-transition.d.ts +0 -0
  298. /package/dist/{utils → shared}/wait-for-css-transition.js +0 -0
  299. /package/dist/{utils → shared}/wait.d.ts +0 -0
  300. /package/dist/{utils → shared}/wait.js +0 -0
  301. /package/src/{components/anchor/anchor.ts → anchor/index.ts} +0 -0
  302. /package/src/{utils → listbox}/flash-attribute.ts +0 -0
  303. /package/src/{components/menu → menu}/hover-aim.ts +0 -0
  304. /package/src/{interactions/outside-click/outside-click-mixin.ts → popover/outside-click.ts} +0 -0
  305. /package/src/{interactions/keydown → select}/keydown.ts +0 -0
  306. /package/src/{interactions/typeahead/typeahead-mixin.ts → shared/typeahead.ts} +0 -0
  307. /package/src/{utils → shared}/wait-for-css-transition.ts +0 -0
  308. /package/src/{utils → shared}/wait.ts +0 -0
@@ -1,200 +0,0 @@
1
- import { css, type Handle } from '@remix-run/ui'
2
- import { Combobox, ComboboxOption, onComboboxChange } from '@remix-run/ui/combobox'
3
- import { theme } from '@remix-run/ui/theme'
4
-
5
- /**
6
- * @name Combobox Overview
7
- * @description A searchable combobox with keyboard navigation. Try typing airport names or codes like ord, lax, or jfk.
8
- * @layout center
9
- */
10
- export default function Example(handle: Handle) {
11
- let value: string | null = null
12
-
13
- return () => (
14
- <div mix={stackCss}>
15
- <div mix={fieldCss}>
16
- <label for="airport-combobox" mix={labelCss}>
17
- Airport
18
- </label>
19
-
20
- <Combobox
21
- inputId="airport-combobox"
22
- mix={[
23
- comboboxCss,
24
- onComboboxChange((event) => {
25
- value = event.value
26
- void handle.update()
27
- }),
28
- ]}
29
- name="airport"
30
- placeholder="Search airports or codes"
31
- >
32
- {airportOptions.map((airport) => (
33
- <ComboboxOption
34
- key={airport.value}
35
- disabled={airport.disabled}
36
- label={airport.label}
37
- searchValue={airport.searchValue}
38
- value={airport.value}
39
- />
40
- ))}
41
- </Combobox>
42
-
43
- <div mix={helpCss}>
44
- Try typing `san`, `wash`, or airport codes like `ord`, `lax`, or `jfk`, then use ArrowDown
45
- and Enter.
46
- </div>
47
- </div>
48
-
49
- <p mix={valueCss}>{`value=${value ?? 'null'}`}</p>
50
- </div>
51
- )
52
- }
53
-
54
- type AirportOption = {
55
- disabled?: boolean
56
- label: string
57
- searchValue: string[]
58
- value: string
59
- }
60
-
61
- const airportOptions: AirportOption[] = [
62
- {
63
- label: 'Hartsfield-Jackson Atlanta International',
64
- searchValue: ['atl', 'atlanta', 'hartsfield-jackson atlanta international'],
65
- value: 'ATL',
66
- },
67
- {
68
- label: 'Austin-Bergstrom International',
69
- searchValue: ['aus', 'austin', 'austin-bergstrom international'],
70
- value: 'AUS',
71
- },
72
- {
73
- label: 'Boston Logan International',
74
- searchValue: ['bos', 'boston', 'boston logan international'],
75
- value: 'BOS',
76
- },
77
- {
78
- label: 'Baltimore/Washington International',
79
- searchValue: ['bwi', 'baltimore', 'washington', 'baltimore/washington international'],
80
- value: 'BWI',
81
- },
82
- {
83
- label: 'Ronald Reagan Washington National',
84
- searchValue: ['dca', 'reagan', 'washington', 'ronald reagan washington national'],
85
- value: 'DCA',
86
- },
87
- {
88
- label: 'Denver International',
89
- searchValue: ['den', 'denver', 'denver international'],
90
- value: 'DEN',
91
- },
92
- {
93
- label: 'Dallas/Fort Worth International',
94
- searchValue: ['dfw', 'dallas', 'fort worth', 'dallas/fort worth international'],
95
- value: 'DFW',
96
- },
97
- {
98
- label: 'Newark Liberty International',
99
- searchValue: ['ewr', 'newark', 'newark liberty international'],
100
- value: 'EWR',
101
- },
102
- {
103
- label: 'Daniel K. Inouye International',
104
- searchValue: ['hnl', 'honolulu', 'daniel k. inouye international'],
105
- value: 'HNL',
106
- },
107
- {
108
- label: 'Washington Dulles International',
109
- searchValue: ['iad', 'dulles', 'washington', 'washington dulles international'],
110
- value: 'IAD',
111
- },
112
- {
113
- label: 'John F. Kennedy International',
114
- searchValue: ['jfk', 'kennedy', 'new york', 'john f. kennedy international'],
115
- value: 'JFK',
116
- },
117
- {
118
- label: 'Harry Reid International',
119
- searchValue: ['las', 'las vegas', 'harry reid international'],
120
- value: 'LAS',
121
- },
122
- {
123
- label: 'Los Angeles International',
124
- searchValue: ['lax', 'los angeles', 'los angeles international'],
125
- value: 'LAX',
126
- },
127
- {
128
- label: 'Orlando International',
129
- searchValue: ['mco', 'orlando', 'orlando international'],
130
- value: 'MCO',
131
- },
132
- {
133
- label: 'Miami International',
134
- searchValue: ['mia', 'miami', 'miami international'],
135
- value: 'MIA',
136
- },
137
- {
138
- label: "Chicago O'Hare International",
139
- searchValue: ['ord', 'ohare', 'chicago', "chicago o'hare international"],
140
- value: 'ORD',
141
- },
142
- {
143
- label: 'Portland International',
144
- searchValue: ['pdx', 'portland', 'portland international'],
145
- value: 'PDX',
146
- },
147
- {
148
- label: 'San Diego International',
149
- searchValue: ['san', 'san diego', 'san diego international'],
150
- value: 'SAN',
151
- },
152
- {
153
- label: 'San Francisco International',
154
- searchValue: ['sfo', 'san francisco', 'san francisco international'],
155
- value: 'SFO',
156
- },
157
- {
158
- disabled: true,
159
- label: 'San Jose Mineta International',
160
- searchValue: ['sjc', 'san jose', 'san jose mineta international'],
161
- value: 'SJC',
162
- },
163
- ]
164
-
165
- const comboboxCss = css({
166
- width: '16rem',
167
- })
168
-
169
- const stackCss = css({
170
- display: 'flex',
171
- flexDirection: 'column',
172
- gap: theme.space.sm,
173
- width: '100%',
174
- })
175
-
176
- const fieldCss = css({
177
- display: 'flex',
178
- flexDirection: 'column',
179
- gap: theme.space.xs,
180
- })
181
-
182
- const labelCss = css({
183
- margin: 0,
184
- fontSize: theme.fontSize.xs,
185
- fontWeight: theme.fontWeight.semibold,
186
- color: theme.colors.text.primary,
187
- })
188
-
189
- const helpCss = css({
190
- fontSize: theme.fontSize.xs,
191
- lineHeight: theme.lineHeight.relaxed,
192
- color: theme.colors.text.secondary,
193
- })
194
-
195
- const valueCss = css({
196
- margin: 0,
197
- fontFamily: theme.fontFamily.mono,
198
- fontSize: theme.fontSize.xs,
199
- color: theme.colors.text.secondary,
200
- })
@@ -1,72 +0,0 @@
1
- # glyph
2
-
3
- `Glyph` renders references into a shared SVG sprite sheet. Render a glyph sheet once, then render individual `Glyph` instances by name.
4
-
5
- ## Usage
6
-
7
- ```tsx
8
- import { Glyph } from 'remix/ui/glyph'
9
- import { RMX_01_GLYPHS } from 'remix/ui/theme'
10
-
11
- function Layout() {
12
- return (
13
- <html>
14
- <body>
15
- <RMX_01_GLYPHS />
16
- <button aria-label="Delete">
17
- <Glyph name="trash" />
18
- </button>
19
- </body>
20
- </html>
21
- )
22
- }
23
- ```
24
-
25
- Most glyphs are decorative because the surrounding control supplies the accessible name. `Glyph` sets `aria-hidden` by default in that case.
26
-
27
- ```tsx
28
- <button aria-label="Search">
29
- <Glyph name="search" />
30
- </button>
31
- ```
32
-
33
- Give the glyph its own label only when the SVG itself is the accessible element.
34
-
35
- ```tsx
36
- <Glyph aria-label="Search" name="search" viewBox="0 0 20 20" width="24" />
37
- ```
38
-
39
- Use `createGlyphSheet` when a theme or app provides its own complete glyph set. The generated sheet exposes the stable symbol ids and the original values for reuse.
40
-
41
- ```tsx
42
- import { createGlyphSheet, type GlyphValues } from 'remix/ui/glyph'
43
-
44
- declare const glyphValues: GlyphValues
45
-
46
- export const AppGlyphs = createGlyphSheet(glyphValues)
47
-
48
- AppGlyphs.ids.trash
49
- AppGlyphs.values.trash
50
- ```
51
-
52
- ## `glyph.*`
53
-
54
- - `Glyph`: renders an `<svg>` with a `<use>` element that points at the package-owned symbol id for `name`.
55
- - `createGlyphSheet(values)`: creates a hidden SVG sprite sheet component from a complete glyph value set.
56
- - `GlyphName`: typed union of supported glyph names.
57
- - `GlyphProps`: props accepted by `Glyph`.
58
- - `GlyphSheetProps`: props accepted by generated glyph sheet components.
59
- - `GlyphSymbol`: SVG symbol value accepted by glyph value maps.
60
- - `GlyphValues`: object shape expected by `createGlyphSheet`.
61
- - `GlyphSheetComponent`: generated sprite sheet component with `ids` and `values` attached.
62
-
63
- The built-in glyph names are `add`, `alert`, `check`, `chevronDown`, `chevronVertical`, `chevronUp`, `chevronRight`, `close`, `copy`, `edit`, `expand`, `info`, `menu`, `open`, `search`, `spinner`, and `trash`.
64
-
65
- ## Behavior Notes
66
-
67
- - Render the glyph sheet once before rendering glyph instances that reference it.
68
- - `createGlyphSheet` renders a hidden zero-size SVG and clones each provided `<symbol>` with the stable package id.
69
- - `Glyph` is `aria-hidden` by default when no accessible label or labelled-by relationship is provided.
70
- - Labeled glyphs keep their accessible label and do not force `aria-hidden`.
71
- - Host SVG props such as `viewBox`, `width`, `mix`, and `aria-label` are preserved.
72
- - `createGlyphSheet` throws if a provided glyph value is not a `<symbol>` element.
@@ -1,110 +0,0 @@
1
- import { createElement } from '@remix-run/ui'
2
- import type { Handle, Props, RemixElement } from '@remix-run/ui'
3
-
4
- import {
5
- glyphContract,
6
- glyphNames,
7
- type GlyphName,
8
- type GlyphValues,
9
- } from '../../theme/glyph-contract.ts'
10
-
11
- export type { GlyphName, GlyphSymbol, GlyphValues } from '../../theme/glyph-contract.ts'
12
-
13
- export type GlyphSheetProps = Omit<Props<'svg'>, 'children'>
14
-
15
- type GlyphSheetRenderer = (handle: Handle<GlyphSheetProps>) => () => RemixElement
16
-
17
- export type GlyphSheetComponent = GlyphSheetRenderer & {
18
- ids: Readonly<Record<GlyphName, string>>
19
- values: GlyphValues
20
- }
21
-
22
- export type GlyphProps = Omit<Props<'svg'>, 'children'> & {
23
- name: GlyphName
24
- }
25
-
26
- export function createGlyphSheet(values: GlyphValues): GlyphSheetComponent {
27
- let ids = Object.freeze(
28
- Object.fromEntries(glyphNames.map((name) => [name, glyphContract[name].id])) as Record<
29
- GlyphName,
30
- string
31
- >,
32
- )
33
-
34
- function GlyphSheet(handle: Handle<GlyphSheetProps>): () => RemixElement {
35
- return () => {
36
- let { style, ...svgProps } = handle.props
37
- let hiddenStyle = {
38
- position: 'absolute',
39
- width: '0',
40
- height: '0',
41
- overflow: 'hidden',
42
- pointerEvents: 'none',
43
- }
44
- let nextStyle =
45
- typeof style === 'object' && style !== null ? { ...hiddenStyle, ...style } : hiddenStyle
46
-
47
- return createElement(
48
- 'svg',
49
- {
50
- ...svgProps,
51
- 'aria-hidden': handle.props['aria-hidden'] ?? true,
52
- focusable: handle.props.focusable ?? 'false',
53
- height: handle.props.height ?? '0',
54
- style: nextStyle,
55
- width: handle.props.width ?? '0',
56
- xmlns: 'http://www.w3.org/2000/svg',
57
- },
58
- glyphNames.map((name) => {
59
- let glyph = values[name]
60
-
61
- return cloneGlyphSymbol(name, glyph, ids[name])
62
- }),
63
- )
64
- }
65
- }
66
-
67
- return Object.assign(GlyphSheet, {
68
- ids,
69
- values,
70
- })
71
- }
72
-
73
- export function Glyph(handle: Handle<GlyphProps>): () => RemixElement {
74
- return () => {
75
- let { fill, name, ...svgProps } = handle.props
76
- let glyphId = glyphContract[name].id
77
- let hiddenByDefault =
78
- handle.props['aria-hidden'] === undefined &&
79
- handle.props['aria-label'] === undefined &&
80
- handle.props['aria-labelledby'] === undefined
81
-
82
- return createElement(
83
- 'svg',
84
- {
85
- ...svgProps,
86
- 'aria-hidden': hiddenByDefault ? true : handle.props['aria-hidden'],
87
- fill: fill ?? 'none',
88
- xmlns: 'http://www.w3.org/2000/svg',
89
- },
90
- createElement('use', {
91
- xlinkHref: `#${glyphId}`,
92
- }),
93
- )
94
- }
95
- }
96
-
97
- function cloneGlyphSymbol(name: GlyphName, glyph: RemixElement, id: string): RemixElement {
98
- if (glyph.type !== 'symbol') {
99
- throw new TypeError(`Expected glyph "${name}" to be a <symbol> element`)
100
- }
101
-
102
- return {
103
- ...glyph,
104
- key: name,
105
- props: {
106
- ...glyph.props,
107
- id,
108
- },
109
- }
110
- }
@@ -1,102 +0,0 @@
1
- import { css, on, type Handle } from '@remix-run/ui'
2
- import { Glyph } from '@remix-run/ui/glyph'
3
- import * as listbox from '@remix-run/ui/listbox'
4
- import type { ListboxValue } from '@remix-run/ui/listbox'
5
- import { theme } from '@remix-run/ui/theme'
6
-
7
- /**
8
- * @name Listbox Overview
9
- * @description A keyboard-navigable listbox with selection, highlighting, and an optional flash-selection animation.
10
- * @layout center
11
- */
12
- export default function Example(handle: Handle) {
13
- let value: ListboxValue = options[0]!.value
14
- let activeValue: ListboxValue = options[0]!.value
15
- let flashSelection = false
16
-
17
- return () => {
18
- return (
19
- <div mix={stackCss}>
20
- <listbox.Context
21
- value={value}
22
- activeValue={activeValue}
23
- flashSelection={flashSelection}
24
- onSelect={(nextValue) => {
25
- value = nextValue
26
- handle.update()
27
- }}
28
- onHighlight={(nextActiveValue) => {
29
- activeValue = nextActiveValue
30
- handle.update()
31
- }}
32
- >
33
- <div tabIndex={0} mix={[listbox.listStyle, listbox.list(), containerCss]}>
34
- {options.map((option) => (
35
- <div key={option.value} mix={[listbox.optionStyle, listbox.option(option)]}>
36
- <Glyph mix={listbox.glyphStyle} name="check" />
37
- <span mix={listbox.labelStyle}>{option.label}</span>
38
- </div>
39
- ))}
40
- </div>
41
- </listbox.Context>
42
- <div mix={controlsCss}>
43
- <label mix={checkboxLabelCss}>
44
- <input
45
- type="checkbox"
46
- defaultChecked={flashSelection}
47
- mix={on('change', (event) => {
48
- flashSelection = event.currentTarget.checked
49
- handle.update()
50
- })}
51
- />{' '}
52
- Flash selection
53
- </label>
54
- <p mix={valueCss}>{`value=${value ?? 'null'}`}</p>
55
- </div>
56
- </div>
57
- )
58
- }
59
- }
60
-
61
- const options = [
62
- { label: 'Apple', value: 'apple' },
63
- { label: 'Banana', value: 'banana' },
64
- { label: 'Cherry', value: 'cherry' },
65
- { label: 'Date', value: 'date' },
66
- { label: 'Elderberry', value: 'elderberry' },
67
- { label: 'Fig', value: 'fig' },
68
- { label: 'Grape', value: 'grape' },
69
- ] as const
70
-
71
- const containerCss = css({
72
- borderColor: theme.colors.border.subtle,
73
- padding: theme.space.xs,
74
- borderRadius: theme.radius.lg,
75
- borderStyle: 'solid',
76
- })
77
-
78
- const stackCss = css({
79
- display: 'flex',
80
- flexDirection: 'column',
81
- gap: theme.space.md,
82
- width: '100%',
83
- })
84
-
85
- const controlsCss = css({
86
- display: 'flex',
87
- flexDirection: 'column',
88
- gap: theme.space.xs,
89
- })
90
-
91
- const checkboxLabelCss = css({
92
- fontSize: theme.fontSize.sm,
93
- lineHeight: theme.lineHeight.normal,
94
- color: theme.colors.text.secondary,
95
- })
96
-
97
- const valueCss = css({
98
- margin: 0,
99
- fontFamily: theme.fontFamily.mono,
100
- fontSize: theme.fontSize.xs,
101
- color: theme.colors.text.secondary,
102
- })
@@ -1,35 +0,0 @@
1
- import { on } from '@remix-run/ui'
2
- import { Menu, MenuItem, onMenuSelect } from '@remix-run/ui/menu'
3
-
4
- /**
5
- * @name Menu Event Bubbling
6
- * @description Item-level handlers fire before the root handler, letting individual items intercept events while others bubble up.
7
- * @layout center
8
- */
9
- export default function Example() {
10
- return () => (
11
- <Menu
12
- label="Project"
13
- menuLabel="Project actions"
14
- mix={onMenuSelect((event) => {
15
- console.log('Menu root handler:', event.item)
16
- })}
17
- >
18
- <MenuItem name="open" value="open-project">
19
- Open project
20
- </MenuItem>
21
- <MenuItem
22
- name="rename"
23
- value="rename-project"
24
- mix={onMenuSelect((event) => {
25
- console.log('Menu item handler:', event.item)
26
- })}
27
- >
28
- Rename project
29
- </MenuItem>
30
- <MenuItem name="duplicate" value="duplicate-project">
31
- Duplicate project
32
- </MenuItem>
33
- </Menu>
34
- )
35
- }
@@ -1,133 +0,0 @@
1
- import { css, type Handle } from '@remix-run/ui'
2
- import * as menu from '@remix-run/ui/menu'
3
- import { MenuItem, MenuList, onMenuSelect, Submenu } from '@remix-run/ui/menu'
4
- import { separatorStyle } from '@remix-run/ui/separator'
5
- import { theme } from '@remix-run/ui/theme'
6
-
7
- type FileAction = 'copyPath' | 'duplicate' | 'move' | 'rename' | 'reveal' | 'trash'
8
-
9
- const actionLabelByName: Record<FileAction, string> = {
10
- copyPath: 'Copied path',
11
- duplicate: 'Duplicated file',
12
- move: 'Moved file',
13
- rename: 'Renamed file',
14
- reveal: 'Revealed in Finder',
15
- trash: 'Moved to trash',
16
- }
17
-
18
- /**
19
- * @name Context Menu Trigger
20
- * @description A lower-level menu composition that opens from right-click coordinates while keeping standard menu selection and submenu behavior.
21
- * @layout center
22
- */
23
- export default function Example(handle: Handle) {
24
- let latestAction = 'Right-click the card.'
25
-
26
- return () => (
27
- <menu.Context label="File actions">
28
- <div mix={layoutCss}>
29
- <div tabIndex={0} mix={[fileCardCss, menu.contextTrigger()]}>
30
- <span mix={fileIconCss}>TS</span>
31
- <span mix={fileTextCss}>
32
- <strong mix={fileNameCss}>context-menu.tsx</strong>
33
- <span mix={fileMetaCss}>Right-click or press Shift+F10</span>
34
- </span>
35
- </div>
36
-
37
- <p aria-live="polite" mix={statusCss}>
38
- {latestAction}
39
- </p>
40
- </div>
41
-
42
- <MenuList
43
- mix={onMenuSelect((event) => {
44
- latestAction =
45
- actionLabelByName[event.item.name as FileAction] ?? `Selected ${event.item.label}`
46
- void handle.update()
47
- })}
48
- >
49
- <MenuItem name="rename">Rename</MenuItem>
50
- <MenuItem name="duplicate">Duplicate</MenuItem>
51
- <MenuItem name="copyPath">Copy path</MenuItem>
52
- <hr mix={separatorStyle} />
53
- <Submenu label="Move to">
54
- <MenuItem name="move" value="drafts">
55
- Drafts
56
- </MenuItem>
57
- <MenuItem name="move" value="archive">
58
- Archive
59
- </MenuItem>
60
- </Submenu>
61
- <MenuItem name="reveal">Reveal in Finder</MenuItem>
62
- <hr mix={separatorStyle} />
63
- <MenuItem name="trash">Move to trash</MenuItem>
64
- </MenuList>
65
- </menu.Context>
66
- )
67
- }
68
-
69
- const layoutCss = css({
70
- display: 'grid',
71
- justifyItems: 'start',
72
- gap: theme.space.md,
73
- })
74
-
75
- const fileCardCss = css({
76
- display: 'grid',
77
- gridTemplateColumns: 'auto minmax(0, 1fr)',
78
- alignItems: 'center',
79
- gap: theme.space.md,
80
- width: 'min(100%, 21rem)',
81
- padding: theme.space.md,
82
- border: `1px solid ${theme.colors.border.subtle}`,
83
- borderRadius: theme.radius.lg,
84
- backgroundColor: theme.surface.lvl1,
85
- color: theme.colors.text.primary,
86
- boxShadow: theme.shadow.xs,
87
- cursor: 'context-menu',
88
- userSelect: 'none',
89
- '&:focus-visible': {
90
- outline: `2px solid ${theme.colors.focus.ring}`,
91
- outlineOffset: '2px',
92
- },
93
- })
94
-
95
- const fileIconCss = css({
96
- display: 'inline-grid',
97
- placeItems: 'center',
98
- width: theme.control.height.lg,
99
- height: theme.control.height.lg,
100
- borderRadius: theme.radius.md,
101
- backgroundColor: theme.colors.action.primary.background,
102
- color: theme.colors.action.primary.foreground,
103
- fontSize: theme.fontSize.xs,
104
- fontWeight: theme.fontWeight.bold,
105
- })
106
-
107
- const fileTextCss = css({
108
- display: 'grid',
109
- gap: theme.space.px,
110
- minWidth: 0,
111
- })
112
-
113
- const fileNameCss = css({
114
- overflow: 'hidden',
115
- textOverflow: 'ellipsis',
116
- whiteSpace: 'nowrap',
117
- fontSize: theme.fontSize.sm,
118
- lineHeight: theme.lineHeight.normal,
119
- })
120
-
121
- const fileMetaCss = css({
122
- color: theme.colors.text.secondary,
123
- fontSize: theme.fontSize.xs,
124
- lineHeight: theme.lineHeight.normal,
125
- })
126
-
127
- const statusCss = css({
128
- margin: 0,
129
- minHeight: theme.lineHeight.normal,
130
- color: theme.colors.text.secondary,
131
- fontSize: theme.fontSize.sm,
132
- lineHeight: theme.lineHeight.normal,
133
- })