@motifx-community/ui 0.1.0-beta.1 → 0.1.0-beta.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 (160) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/README.md +16 -10
  3. package/dist/components/calendar/Calendar.d.ts +12 -0
  4. package/dist/components/calendar/calendar-props.d.ts +5 -0
  5. package/dist/components/daterangebox/DateRangeBox.d.ts +121 -0
  6. package/dist/components/daterangebox/date-range-box-props.d.ts +35 -0
  7. package/dist/components/daterangebox/date-range-preset.d.ts +6 -0
  8. package/dist/components/daterangebox/date-range.d.ts +2 -0
  9. package/dist/components/daterangebox/index.d.ts +4 -0
  10. package/dist/components/fileuploader/FileUploader.d.ts +133 -0
  11. package/dist/components/fileuploader/file-uploader-props.d.ts +46 -0
  12. package/dist/components/fileuploader/files-added-event-args.d.ts +9 -0
  13. package/dist/components/fileuploader/index.d.ts +7 -0
  14. package/dist/components/fileuploader/upload-event-args.d.ts +10 -0
  15. package/dist/components/fileuploader/upload-item.d.ts +12 -0
  16. package/dist/components/fileuploader/upload-mode.d.ts +2 -0
  17. package/dist/components/fileuploader/upload-status.d.ts +2 -0
  18. package/dist/components/loadpanel/LoadPanel.d.ts +70 -0
  19. package/dist/components/loadpanel/index.d.ts +3 -0
  20. package/dist/components/loadpanel/load-panel-props.d.ts +29 -0
  21. package/dist/components/loadpanel/load-panel-target.d.ts +3 -0
  22. package/dist/components/popover/Popover.d.ts +98 -0
  23. package/dist/components/popover/index.d.ts +5 -0
  24. package/dist/components/popover/popover-close-reason.d.ts +2 -0
  25. package/dist/components/popover/popover-closing-event-args.d.ts +8 -0
  26. package/dist/components/popover/popover-props.d.ts +39 -0
  27. package/dist/components/popover/popover-show-on.d.ts +2 -0
  28. package/dist/components/scrollview/ScrollView.d.ts +109 -0
  29. package/dist/components/scrollview/index.d.ts +7 -0
  30. package/dist/components/scrollview/pull-down-event-args.d.ts +9 -0
  31. package/dist/components/scrollview/reach-bottom-event-args.d.ts +9 -0
  32. package/dist/components/scrollview/scroll-event-args.d.ts +7 -0
  33. package/dist/components/scrollview/scroll-view-bars.d.ts +2 -0
  34. package/dist/components/scrollview/scroll-view-direction.d.ts +2 -0
  35. package/dist/components/scrollview/scroll-view-props.d.ts +31 -0
  36. package/dist/components/sortable/Sortable.d.ts +106 -0
  37. package/dist/components/sortable/index.d.ts +5 -0
  38. package/dist/components/sortable/sortable-drag-event-args.d.ts +15 -0
  39. package/dist/components/sortable/sortable-drop-event-args.d.ts +11 -0
  40. package/dist/components/sortable/sortable-orientation.d.ts +2 -0
  41. package/dist/components/sortable/sortable-props.d.ts +34 -0
  42. package/dist/components/stepper/Stepper.d.ts +121 -0
  43. package/dist/components/stepper/Wizard.d.ts +112 -0
  44. package/dist/components/stepper/WizardStep.d.ts +44 -0
  45. package/dist/components/stepper/index.d.ts +13 -0
  46. package/dist/components/stepper/step-changed-event-args.d.ts +11 -0
  47. package/dist/components/stepper/step-changing-event-args.d.ts +18 -0
  48. package/dist/components/stepper/stepper-item.d.ts +20 -0
  49. package/dist/components/stepper/stepper-label-position.d.ts +2 -0
  50. package/dist/components/stepper/stepper-orientation.d.ts +1 -0
  51. package/dist/components/stepper/stepper-props.d.ts +32 -0
  52. package/dist/components/stepper/stepper-status.d.ts +2 -0
  53. package/dist/components/stepper/wizard-finishing-event-args.d.ts +7 -0
  54. package/dist/components/stepper/wizard-props.d.ts +48 -0
  55. package/dist/components/stepper/wizard-step-props.d.ts +32 -0
  56. package/dist/core/flow-home.d.ts +6 -0
  57. package/dist/core/fold-text.d.ts +6 -0
  58. package/dist/core/ui-locale.d.ts +0 -2
  59. package/dist/core/ui-strings.d.ts +41 -0
  60. package/dist/generated/tokens.d.ts +1146 -11
  61. package/dist/index.d.ts +8 -1
  62. package/dist/index.js +22564 -20283
  63. package/dist/index.js.map +1 -1
  64. package/dist/locales/en.json +38 -1
  65. package/dist/locales/tr.json +38 -1
  66. package/dist/styles.css +1825 -5
  67. package/dist/tokens/index.d.ts +1146 -11
  68. package/dist/tokens/index.js +1146 -11
  69. package/dist/tokens/index.js.map +1 -1
  70. package/dist/tr-B218zMtu.js +1191 -0
  71. package/dist/tr-B218zMtu.js.map +1 -0
  72. package/docs/accordion.md +1 -1
  73. package/docs/actionsheet.md +1 -1
  74. package/docs/avatar.md +1 -1
  75. package/docs/badge.md +1 -1
  76. package/docs/bottomsheet.md +3 -3
  77. package/docs/breadcrumb.md +2 -2
  78. package/docs/button.md +3 -3
  79. package/docs/buttongroup.md +1 -1
  80. package/docs/calendar.md +1 -1
  81. package/docs/card.md +1 -1
  82. package/docs/checkbox.md +3 -3
  83. package/docs/chip.md +1 -1
  84. package/docs/colorbox.md +1 -1
  85. package/docs/combobox.md +1 -1
  86. package/docs/control.md +1 -1
  87. package/docs/datagrid-api.md +3 -3
  88. package/docs/datagrid-bands.md +1 -1
  89. package/docs/datagrid-drag-select.md +1 -1
  90. package/docs/datagrid-drag.md +1 -1
  91. package/docs/datagrid-editing.md +1 -1
  92. package/docs/datagrid-filtering.md +1 -1
  93. package/docs/datagrid-forms.md +1 -1
  94. package/docs/datagrid-grouping.md +1 -1
  95. package/docs/datagrid-layout.md +1 -1
  96. package/docs/datagrid-lookups.md +1 -1
  97. package/docs/datagrid-master-detail.md +1 -1
  98. package/docs/datagrid-scrolling.md +1 -1
  99. package/docs/datagrid-selection.md +1 -1
  100. package/docs/datagrid.md +1 -1
  101. package/docs/datebox.md +3 -3
  102. package/docs/daterangebox.md +192 -0
  103. package/docs/drawer.md +1 -1
  104. package/docs/dropdown.md +3 -3
  105. package/docs/fileuploader.md +201 -0
  106. package/docs/filterbuilder.md +3 -3
  107. package/docs/formlayout.md +1 -1
  108. package/docs/home.md +1 -1
  109. package/docs/keyboard.md +1 -1
  110. package/docs/language.md +229 -0
  111. package/docs/layout.md +3 -3
  112. package/docs/listbox.md +3 -3
  113. package/docs/loadpanel.md +184 -0
  114. package/docs/lookup.md +1 -1
  115. package/docs/menus.md +1 -1
  116. package/docs/numberbox.md +3 -3
  117. package/docs/pagination.md +1 -1
  118. package/docs/popover.md +221 -0
  119. package/docs/progress.md +3 -3
  120. package/docs/radiogroup.md +1 -1
  121. package/docs/rating.md +1 -1
  122. package/docs/scheduler-agenda.md +1 -1
  123. package/docs/scheduler-big-data.md +1 -1
  124. package/docs/scheduler-editing.md +1 -1
  125. package/docs/scheduler-form.md +1 -1
  126. package/docs/scheduler-icalendar.md +1 -1
  127. package/docs/scheduler-mobile.md +1 -1
  128. package/docs/scheduler-recurrence.md +1 -1
  129. package/docs/scheduler-resources.md +1 -1
  130. package/docs/scheduler-timeline.md +1 -1
  131. package/docs/scheduler.md +1 -1
  132. package/docs/scrollview.md +185 -0
  133. package/docs/showcase.md +1 -1
  134. package/docs/skeleton.md +1 -1
  135. package/docs/slider.md +3 -3
  136. package/docs/sortable.md +213 -0
  137. package/docs/stepper.md +238 -0
  138. package/docs/switch.md +1 -1
  139. package/docs/tabdocs-dock.md +1 -1
  140. package/docs/tabdocs-drag.md +1 -1
  141. package/docs/tabdocs-menus.md +1 -1
  142. package/docs/tabdocs-mobile.md +1 -1
  143. package/docs/tabdocs-tabs.md +1 -1
  144. package/docs/tabdocs-windows.md +1 -1
  145. package/docs/tabdocs-workspace.md +1 -1
  146. package/docs/tabdocs.md +1 -1
  147. package/docs/tabs.md +3 -3
  148. package/docs/tagbox.md +3 -3
  149. package/docs/textarea.md +3 -3
  150. package/docs/textbox.md +3 -3
  151. package/docs/toast.md +3 -3
  152. package/docs/tokens.md +349 -122
  153. package/docs/toolbar.md +3 -3
  154. package/docs/tooltip.md +1 -1
  155. package/docs/treeview.md +3 -3
  156. package/docs/window.md +3 -3
  157. package/docs/wizard.md +240 -0
  158. package/llms-full.txt +2415 -240
  159. package/llms.txt +10 -1
  160. package/package.json +9 -3
package/llms-full.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  # @motifx-community/ui
2
2
 
3
- > UI components for MotifJS (@motifx/core) on the MotifJS design system. Version 0.1.0-beta.1: a preview, its API may still change before 1.0.
3
+ > UI components for MotifJS (@motifx/core) on the MotifJS design system. Version 0.1.0-beta.2: a preview, its API may still change before 1.0.
4
4
 
5
5
  Built on MotifJS (`@motifx/core`): a component is an object, made in JSX or with `new`, whose every prop takes a value or a function (`Bind<T>`); `x-model` binds a value two-way. The look is the design system’s (`@motifx-community/design-system`): five design languages (`data-identity`), light and dark themes, density.
6
6
 
@@ -18,6 +18,7 @@ Built on MotifJS (`@motifx/core`): a component is an object, made in JSX or with
18
18
 
19
19
  - [Control](docs/control.md): The base of every control in the package. It gives each one the same `text`, `enabled`, `visible` and `tabStop`, and the same focus methods, whether the…
20
20
  - [Keyboard and focus](docs/keyboard.md): The rules every control follows: Tab order, the active control of a container, focus that never falls to `<body>`, `&File` access keys and app-wide shortcuts.
21
+ - [Language](docs/language.md): The texts the controls write, the locale their dates and numbers follow, and the direction: one `uiLocale` for the kit, with a pack per language loaded as…
21
22
 
22
23
  ## Buttons
23
24
 
@@ -32,10 +33,12 @@ Built on MotifJS (`@motifx/core`): a component is an object, made in JSX or with
32
33
  - [TextArea](docs/textarea.md): A text field of several lines: a box that grows with the text or that the user drags bigger, a character counter, a clear button, Ctrl+Enter to send, and…
33
34
  - [NumberBox](docs/numberbox.md): A number field: arrow keys, PageUp / PageDown and spin buttons that repeat while held, bounds, a step without float noise, a format for display (currency,…
34
35
  - [DateBox](docs/datebox.md): A date, a time or both. It is typed in the order of the locale through a mask, or picked from a calendar and a list of times; `min`, `max` and…
36
+ - [DateRangeBox](docs/daterangebox.md): A start and an end date in one field: typed through two masks, or picked on two months side by side, from ready-made ranges, within the dates and the span…
35
37
  - [ColorBox and ColorPicker](docs/colorbox.md): A colour as a field, with a picker in a popup; or the picker on its own. The picker has an area of saturation and brightness, a hue strip, an opacity strip,…
36
38
  - [Calendar](docs/calendar.md): A month of days to pick a date from, with a year and a decade view to get far quickly. It is the picker of DateBox, and it works on its own.
37
39
  - [Slider](docs/slider.md): A value picked on a track by dragging a thumb or with the keys: one number, or a range with two thumbs. Steps, marks with labels, a value bubble, a vertical…
38
40
  - [Rating](docs/rating.md): A row of stars to give a score or to show one, whole or by halves. It is a field: label, help text, rules and `x-model` work as in every field.
41
+ - [FileUploader](docs/fileuploader.md): Files chosen with a button or dropped on the box, listed with their size and what happens to them: uploaded as they come, on a button or from code, with…
39
42
 
40
43
  ## Choice
41
44
 
@@ -50,6 +53,8 @@ Built on MotifJS (`@motifx/core`): a component is an object, made in JSX or with
50
53
 
51
54
  - [ProgressBar and Spinner](docs/progress.md): ProgressBar shows how far some work is, as a line or a circle, or that it runs when that is not known. Spinner says "busy, wait": a turning ring, alone or…
52
55
  - [Tooltip](docs/tooltip.md): A short description shown next to an element: after the pointer rests on it, when it gets keyboard focus, or from code. It can be hovered, Escape hides it,…
56
+ - [Popover](docs/popover.md): Content next to the element it belongs to: a title, a close button, a form, a card. It opens on a press or while the pointer rests on its target, follows…
57
+ - [LoadPanel](docs/loadpanel.md): A “loading” layer over a container or the whole page: a shade, a pane with the kit’s spinner and a message, a Cancel button when the work can be stopped.…
53
58
  - [Toast](docs/toast.md): Short notifications at an edge of the window: four tones, an action such as Undo, a time of their own or none, six positions and a limit on how many show at…
54
59
 
55
60
  ## Display
@@ -65,12 +70,16 @@ Built on MotifJS (`@motifx/core`): a component is an object, made in JSX or with
65
70
  - [Tabs](docs/tabs.md): Tabs show one panel at a time under a strip of tabs: from JSX or from code, closable, with icons and badges, scroll buttons when the tabs do not fit, four…
66
71
  - [Breadcrumb](docs/breadcrumb.md): The way to the current page: each step a link or a button, the current page last. Steps that do not fit go into a menu after the first.
67
72
  - [Pagination](docs/pagination.md): Moving through pages of items: the sizes to choose from, where the page stands, the steps and a button per page around the current one. It turns compact…
73
+ - [Stepper](docs/stepper.md): The steps of a longer task and where the user stands in them: an indicator and a text per step, a line between them, the steps before the current one…
74
+ - [Wizard](docs/wizard.md): A task in steps: a [Stepper](stepper.md) above or beside one page per step, and the Back and Next buttons under them. Next validates the page first; on the…
68
75
  - [Accordion](docs/accordion.md): An accordion opens and closes sections under their headers: one at a time or several, kept open, with icons, three looks and sections built when they are…
69
76
  - [Window and dialog](docs/window.md): A window or a dialog on a native `<dialog>`: one form, shown modeless or modal by whoever shows it. It has a title bar, moves, resizes, minimizes and…
70
77
  - [BottomSheet](docs/bottomsheet.md): A panel that comes up from the bottom of the page or of a container and stops at a few heights: a peek, half, full, as tall as its content, or heights of…
71
78
  - [Drawer](docs/drawer.md): A panel that slides in from an edge of the page or of a container, over the content or pushing it aside. A finger swipes it in from the edge and back again;…
72
79
  - [ActionSheet](docs/actionsheet.md): A list of commands that comes up from the bottom, made of the kit's menu items and large enough for a finger, with a title, a message and a cancel button…
73
80
  - [Layout](docs/layout.md): Containers that place controls: `Stack` (a row or a column), `Grid` (rows and columns), `Panel` (a plain box that can scroll), `GroupBox` (a titled frame),…
81
+ - [ScrollView](docs/scrollview.md): Content that scrolls in a box of its own: the bars shown as told, a pull from the top that asks for what is new, a reach near the end that asks for more.…
82
+ - [Sortable](docs/sortable.md): Items the user puts in order by dragging them, with the pointer or a finger, or with the keys; lists of one group take each other’s items. A drop moves the…
74
83
  - [FormLayout](docs/formlayout.md): Lays out the fields of a data object on a grid. Each field gets an editor — by name, or by the type of its value — bound to the object both ways; groups,…
75
84
 
76
85
  ## Data
@@ -240,7 +249,7 @@ tokens, with examples.
240
249
 
241
250
  # @motifx-community/ui
242
251
 
243
- > Get started · @motifx-community/ui 0.1.0-beta.1
252
+ > Get started · @motifx-community/ui 0.1.0-beta.2
244
253
 
245
254
  Components for MotifJS that work the way desktop UI does — created when needed, shown anywhere, closed and disposed like windows — drawn from the MotifJS design system's tokens.
246
255
 
@@ -298,7 +307,7 @@ The look comes from `@motifx-community/design-system`: its tokens, three themes,
298
307
 
299
308
  # Showcase: an order screen
300
309
 
301
- > Get started · @motifx-community/ui 0.1.0-beta.1
310
+ > Get started · @motifx-community/ui 0.1.0-beta.2
302
311
 
303
312
  An order screen built with the kit, the way a MotifJS app is built: the state and the operations live in a model (`OrderModel`), the page binds to it. The customer list is a data source of 5,000 rows that answers like a server.
304
313
 
@@ -307,7 +316,7 @@ An order screen built with the kit, the way a MotifJS app is built: the state an
307
316
 
308
317
  # Design tokens
309
318
 
310
- > Get started · @motifx-community/ui 0.1.0-beta.1
319
+ > Get started · @motifx-community/ui 0.1.0-beta.2
311
320
 
312
321
  Five layers. The first four — primitives, the design language's own scales, semantic tokens per theme, density — come from `@motifx-community/design-system` and are listed here for reference. The fifth, the component tokens, is this kit's own: a knob per component, each referencing a design-system token, written in `@layer mx.components`. Every design language gives every one of them its own value.
313
322
 
@@ -444,19 +453,19 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
444
453
  | `avatar.avatar.accent.bg` | `--mx-avatar-avatar-accent-bg` | `color.accent.subtle` | `#fbe6de` |
445
454
  | `avatar.avatar.accent.color` | `--mx-avatar-avatar-accent-color` | `color.accent.on-subtle` | `#983318` |
446
455
  | `avatar.avatar.success.bg` | `--mx-avatar-avatar-success-bg` | `color.success.subtle` | `#dff6dd` |
447
- | `avatar.avatar.success.color` | `--mx-avatar-avatar-success-color` | `color.success.fg` | `#0c6a0c` |
456
+ | `avatar.avatar.success.color` | `--mx-avatar-avatar-success-color` | `color.success.fg` | `#006402` |
448
457
  | `avatar.avatar.caution.bg` | `--mx-avatar-avatar-caution-bg` | `color.caution.subtle` | `#fff4ce` |
449
- | `avatar.avatar.caution.color` | `--mx-avatar-avatar-caution-color` | `color.caution.fg` | `#845000` |
458
+ | `avatar.avatar.caution.color` | `--mx-avatar-avatar-caution-color` | `color.caution.fg` | `#754702` |
450
459
  | `avatar.avatar.danger.bg` | `--mx-avatar-avatar-danger-bg` | `color.danger.subtle` | `#fde7e9` |
451
- | `avatar.avatar.danger.color` | `--mx-avatar-avatar-danger-color` | `color.danger.fg` | `#b3261a` |
460
+ | `avatar.avatar.danger.color` | `--mx-avatar-avatar-danger-color` | `color.danger.fg` | `#b03659` |
452
461
  | `avatar.avatar.info.bg` | `--mx-avatar-avatar-info-bg` | `` | `initial` |
453
462
  | `avatar.avatar.info.color` | `--mx-avatar-avatar-info-color` | `` | `initial` |
454
463
  | `avatar.status.radius` | `--mx-avatar-status-radius` | `radius.full` | `9999px` |
455
464
  | `avatar.status.border-width` | `--mx-avatar-status-border-width` | `border.width.2` | `2px` |
456
465
  | `avatar.status.border-color` | `--mx-avatar-status-border-color` | `color.bg.surface` | `#f8f7f3` |
457
- | `avatar.status.online.bg` | `--mx-avatar-status-online-bg` | `color.success.solid` | `#0c6a0c` |
458
- | `avatar.status.away.bg` | `--mx-avatar-status-away-bg` | `color.caution.solid` | `#845000` |
459
- | `avatar.status.busy.bg` | `--mx-avatar-status-busy-bg` | `color.danger.solid` | `#b3261a` |
466
+ | `avatar.status.online.bg` | `--mx-avatar-status-online-bg` | `color.success.solid` | `#006402` |
467
+ | `avatar.status.away.bg` | `--mx-avatar-status-away-bg` | `color.caution.solid` | `#754702` |
468
+ | `avatar.status.busy.bg` | `--mx-avatar-status-busy-bg` | `color.danger.solid` | `#b03659` |
460
469
  | `avatar.status.offline.bg` | `--mx-avatar-status-offline-bg` | `color.fg.tertiary` | `#8c8a82` |
461
470
  | `avatar.status.offline.border-color` | `--mx-avatar-status-offline-border-color` | `` | `initial` |
462
471
  | `avatar.status-icon.online.display` | `--mx-avatar-status-icon-online-display` | `` | `initial` |
@@ -493,11 +502,11 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
493
502
  | `badge.badge.accent.color` | `--mx-badge-badge-accent-color` | `color.accent.on-solid` | `#ffffff` |
494
503
  | `badge.badge.info.bg` | `--mx-badge-badge-info-bg` | `color.info.solid` | `#5e5c55` |
495
504
  | `badge.badge.info.color` | `--mx-badge-badge-info-color` | `color.info.on-solid` | `#e1e0da` |
496
- | `badge.badge.success.bg` | `--mx-badge-badge-success-bg` | `color.success.solid` | `#0c6a0c` |
505
+ | `badge.badge.success.bg` | `--mx-badge-badge-success-bg` | `color.success.solid` | `#006402` |
497
506
  | `badge.badge.success.color` | `--mx-badge-badge-success-color` | `color.success.on-solid` | `#ffffff` |
498
- | `badge.badge.caution.bg` | `--mx-badge-badge-caution-bg` | `color.caution.solid` | `#845000` |
507
+ | `badge.badge.caution.bg` | `--mx-badge-badge-caution-bg` | `color.caution.solid` | `#754702` |
499
508
  | `badge.badge.caution.color` | `--mx-badge-badge-caution-color` | `color.caution.on-solid` | `#ffffff` |
500
- | `badge.badge.danger.bg` | `--mx-badge-badge-danger-bg` | `color.danger.solid` | `#b3261a` |
509
+ | `badge.badge.danger.bg` | `--mx-badge-badge-danger-bg` | `color.danger.solid` | `#b03659` |
501
510
  | `badge.badge.danger.color` | `--mx-badge-badge-danger-color` | `color.danger.on-solid` | `#ffffff` |
502
511
  | `badge.badge.subtle.bg` | `--mx-badge-badge-subtle-bg` | `color.fill.subtle.secondary` | `rgb(0 0 0 / 0.0373)` |
503
512
  | `badge.badge.subtle.color` | `--mx-badge-badge-subtle-color` | `color.fg.primary` | `#1d1c1a` |
@@ -506,11 +515,11 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
506
515
  | `badge.badge.subtle-info.bg` | `--mx-badge-badge-subtle-info-bg` | `color.fill.subtle.secondary` | `rgb(0 0 0 / 0.0373)` |
507
516
  | `badge.badge.subtle-info.color` | `--mx-badge-badge-subtle-info-color` | `color.fg.primary` | `#1d1c1a` |
508
517
  | `badge.badge.subtle-success.bg` | `--mx-badge-badge-subtle-success-bg` | `color.success.subtle` | `#dff6dd` |
509
- | `badge.badge.subtle-success.color` | `--mx-badge-badge-subtle-success-color` | `color.success.fg` | `#0c6a0c` |
518
+ | `badge.badge.subtle-success.color` | `--mx-badge-badge-subtle-success-color` | `color.success.fg` | `#006402` |
510
519
  | `badge.badge.subtle-caution.bg` | `--mx-badge-badge-subtle-caution-bg` | `color.caution.subtle` | `#fff4ce` |
511
- | `badge.badge.subtle-caution.color` | `--mx-badge-badge-subtle-caution-color` | `color.caution.fg` | `#845000` |
520
+ | `badge.badge.subtle-caution.color` | `--mx-badge-badge-subtle-caution-color` | `color.caution.fg` | `#754702` |
512
521
  | `badge.badge.subtle-danger.bg` | `--mx-badge-badge-subtle-danger-bg` | `color.danger.subtle` | `#fde7e9` |
513
- | `badge.badge.subtle-danger.color` | `--mx-badge-badge-subtle-danger-color` | `color.danger.fg` | `#b3261a` |
522
+ | `badge.badge.subtle-danger.color` | `--mx-badge-badge-subtle-danger-color` | `color.danger.fg` | `#b03659` |
514
523
  | `badge.badge.outline.bg` | `--mx-badge-badge-outline-bg` | `` | `rgb(0 0 0 / 0)` |
515
524
  | `badge.badge.outline.color` | `--mx-badge-badge-outline-color` | `color.fg.secondary` | `#5e5c55` |
516
525
  | `badge.badge.outline.border-width` | `--mx-badge-badge-outline-border-width` | `border.width.1` | `1px` |
@@ -519,12 +528,12 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
519
528
  | `badge.badge.outline-accent.border-color` | `--mx-badge-badge-outline-accent-border-color` | `color.accent.fg` | `#983318` |
520
529
  | `badge.badge.outline-info.color` | `--mx-badge-badge-outline-info-color` | `color.fg.secondary` | `#5e5c55` |
521
530
  | `badge.badge.outline-info.border-color` | `--mx-badge-badge-outline-info-border-color` | `color.fg.secondary` | `#5e5c55` |
522
- | `badge.badge.outline-success.color` | `--mx-badge-badge-outline-success-color` | `color.success.fg` | `#0c6a0c` |
523
- | `badge.badge.outline-success.border-color` | `--mx-badge-badge-outline-success-border-color` | `color.success.fg` | `#0c6a0c` |
524
- | `badge.badge.outline-caution.color` | `--mx-badge-badge-outline-caution-color` | `color.caution.fg` | `#845000` |
525
- | `badge.badge.outline-caution.border-color` | `--mx-badge-badge-outline-caution-border-color` | `color.caution.fg` | `#845000` |
526
- | `badge.badge.outline-danger.color` | `--mx-badge-badge-outline-danger-color` | `color.danger.fg` | `#b3261a` |
527
- | `badge.badge.outline-danger.border-color` | `--mx-badge-badge-outline-danger-border-color` | `color.danger.fg` | `#b3261a` |
531
+ | `badge.badge.outline-success.color` | `--mx-badge-badge-outline-success-color` | `color.success.fg` | `#006402` |
532
+ | `badge.badge.outline-success.border-color` | `--mx-badge-badge-outline-success-border-color` | `color.success.fg` | `#006402` |
533
+ | `badge.badge.outline-caution.color` | `--mx-badge-badge-outline-caution-color` | `color.caution.fg` | `#754702` |
534
+ | `badge.badge.outline-caution.border-color` | `--mx-badge-badge-outline-caution-border-color` | `color.caution.fg` | `#754702` |
535
+ | `badge.badge.outline-danger.color` | `--mx-badge-badge-outline-danger-color` | `color.danger.fg` | `#b03659` |
536
+ | `badge.badge.outline-danger.border-color` | `--mx-badge-badge-outline-danger-border-color` | `color.danger.fg` | `#b03659` |
528
537
  | `badge.badge.dot.padding-inline` | `--mx-badge-badge-dot-padding-inline` | `space.0` | `0px` |
529
538
  | `breadcrumb.font-size.sm` | `--mx-breadcrumb-font-size-sm` | `font.size.caption` | `0.75rem` |
530
539
  | `breadcrumb.font-size.md` | `--mx-breadcrumb-font-size-md` | `font.size.body` | `0.875rem` |
@@ -602,8 +611,8 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
602
611
  | `button.face.accent.border-color` | `--mx-button-face-accent-border-color` | `color.accent.solid` | `#c24523` |
603
612
  | `button.face.accent.border-bottom-color` | `--mx-button-face-accent-border-bottom-color` | `color.stroke.on-accent-bottom` | `rgb(0 0 0 / 0.4)` |
604
613
  | `button.face.accent.color` | `--mx-button-face-accent-color` | `color.accent.on-solid` | `#ffffff` |
605
- | `button.face.danger.bg` | `--mx-button-face-danger-bg` | `color.danger.solid` | `#b3261a` |
606
- | `button.face.danger.border-color` | `--mx-button-face-danger-border-color` | `color.danger.solid` | `#b3261a` |
614
+ | `button.face.danger.bg` | `--mx-button-face-danger-bg` | `color.danger.solid` | `#b03659` |
615
+ | `button.face.danger.border-color` | `--mx-button-face-danger-border-color` | `color.danger.solid` | `#b03659` |
607
616
  | `button.face.danger.border-bottom-color` | `--mx-button-face-danger-border-bottom-color` | `color.stroke.on-accent-bottom` | `rgb(0 0 0 / 0.4)` |
608
617
  | `button.face.danger.color` | `--mx-button-face-danger-color` | `color.danger.on-solid` | `#ffffff` |
609
618
  | `button.face.outline.bg` | `--mx-button-face-outline-bg` | `` | `rgb(0 0 0 / 0)` |
@@ -612,7 +621,7 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
612
621
  | `button.face.outline.shadow` | `--mx-button-face-outline-shadow` | `` | `0 0 #0000` |
613
622
  | `button.face.outline.color` | `--mx-button-face-outline-color` | `color.fg.primary` | `#1d1c1a` |
614
623
  | `button.face.outline-accent.color` | `--mx-button-face-outline-accent-color` | `color.accent.fg` | `#983318` |
615
- | `button.face.outline-danger.color` | `--mx-button-face-outline-danger-color` | `color.danger.fg` | `#b3261a` |
624
+ | `button.face.outline-danger.color` | `--mx-button-face-outline-danger-color` | `color.danger.fg` | `#b03659` |
616
625
  | `button.face.ghost.bg` | `--mx-button-face-ghost-bg` | `` | `rgb(0 0 0 / 0)` |
617
626
  | `button.face.ghost.border-bottom-width` | `--mx-button-face-ghost-border-bottom-width` | `border.width.1` | `1px` |
618
627
  | `button.face.ghost.border-color` | `--mx-button-face-ghost-border-color` | `` | `rgb(0 0 0 / 0)` |
@@ -620,7 +629,7 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
620
629
  | `button.face.ghost.shadow` | `--mx-button-face-ghost-shadow` | `` | `0 0 #0000` |
621
630
  | `button.face.ghost.color` | `--mx-button-face-ghost-color` | `color.fg.primary` | `#1d1c1a` |
622
631
  | `button.face.ghost-accent.color` | `--mx-button-face-ghost-accent-color` | `color.accent.fg` | `#983318` |
623
- | `button.face.ghost-danger.color` | `--mx-button-face-ghost-danger-color` | `color.danger.fg` | `#b3261a` |
632
+ | `button.face.ghost-danger.color` | `--mx-button-face-ghost-danger-color` | `color.danger.fg` | `#b03659` |
624
633
  | `button.face.hover.bg` | `--mx-button-face-hover-bg` | `color.fill.control.secondary` | `#ebeae5` |
625
634
  | `button.face.hover.border-bottom-color` | `--mx-button-face-hover-border-bottom-color` | `color.stroke.control.edge` | `rgb(0 0 0 / 0.3)` |
626
635
  | `button.face.hover.image` | `--mx-button-face-hover-image` | `` | `initial` |
@@ -628,30 +637,30 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
628
637
  | `button.face.accent-hover.bg` | `--mx-button-face-accent-hover-bg` | `color.accent.solid-hover` | `#b43f20` |
629
638
  | `button.face.accent-hover.border-bottom-color` | `--mx-button-face-accent-hover-border-bottom-color` | `color.stroke.on-accent-bottom` | `rgb(0 0 0 / 0.4)` |
630
639
  | `button.face.accent-hover.color` | `--mx-button-face-accent-hover-color` | `color.accent.on-solid` | `#ffffff` |
631
- | `button.face.danger-hover.bg` | `--mx-button-face-danger-hover-bg` | `color.danger.solid-hover` | `#c42b1c` |
640
+ | `button.face.danger-hover.bg` | `--mx-button-face-danger-hover-bg` | `color.danger.solid-hover` | `#c13b61` |
632
641
  | `button.face.danger-hover.border-bottom-color` | `--mx-button-face-danger-hover-border-bottom-color` | `color.stroke.on-accent-bottom` | `rgb(0 0 0 / 0.4)` |
633
642
  | `button.face.danger-hover.color` | `--mx-button-face-danger-hover-color` | `color.danger.on-solid` | `#ffffff` |
634
643
  | `button.face.outline-hover.bg` | `--mx-button-face-outline-hover-bg` | `color.fill.subtle.secondary` | `rgb(0 0 0 / 0.0373)` |
635
644
  | `button.face.outline-hover.border-color` | `--mx-button-face-outline-hover-border-color` | `color.stroke.control.strong` | `rgb(0 0 0 / 0.4458)` |
636
645
  | `button.face.outline-hover.color` | `--mx-button-face-outline-hover-color` | `` | `initial` |
637
646
  | `button.face.outline-accent-hover.color` | `--mx-button-face-outline-accent-hover-color` | `color.accent.fg` | `#983318` |
638
- | `button.face.outline-danger-hover.color` | `--mx-button-face-outline-danger-hover-color` | `color.danger.fg` | `#b3261a` |
647
+ | `button.face.outline-danger-hover.color` | `--mx-button-face-outline-danger-hover-color` | `color.danger.fg` | `#b03659` |
639
648
  | `button.face.ghost-hover.bg` | `--mx-button-face-ghost-hover-bg` | `color.fill.subtle.secondary` | `rgb(0 0 0 / 0.0373)` |
640
649
  | `button.face.ghost-hover.border-color` | `--mx-button-face-ghost-hover-border-color` | `` | `rgb(0 0 0 / 0)` |
641
650
  | `button.face.ghost-hover.color` | `--mx-button-face-ghost-hover-color` | `` | `initial` |
642
651
  | `button.face.ghost-accent-hover.color` | `--mx-button-face-ghost-accent-hover-color` | `color.accent.fg` | `#983318` |
643
- | `button.face.ghost-danger-hover.color` | `--mx-button-face-ghost-danger-hover-color` | `color.danger.fg` | `#b3261a` |
652
+ | `button.face.ghost-danger-hover.color` | `--mx-button-face-ghost-danger-hover-color` | `color.danger.fg` | `#b03659` |
644
653
  | `button.face.toggled-hover.bg` | `--mx-button-face-toggled-hover-bg` | `color.fill.control.secondary` | `#ebeae5` |
645
654
  | `button.face.accent-toggled-hover.bg` | `--mx-button-face-accent-toggled-hover-bg` | `color.accent.solid-hover` | `#b43f20` |
646
- | `button.face.danger-toggled-hover.bg` | `--mx-button-face-danger-toggled-hover-bg` | `color.danger.solid-hover` | `#c42b1c` |
655
+ | `button.face.danger-toggled-hover.bg` | `--mx-button-face-danger-toggled-hover-bg` | `color.danger.solid-hover` | `#c13b61` |
647
656
  | `button.face.outline-toggled-hover.bg` | `--mx-button-face-outline-toggled-hover-bg` | `color.fill.subtle.secondary` | `rgb(0 0 0 / 0.0373)` |
648
657
  | `button.face.outline-toggled-hover.color` | `--mx-button-face-outline-toggled-hover-color` | `` | `initial` |
649
658
  | `button.face.outline-accent-toggled-hover.color` | `--mx-button-face-outline-accent-toggled-hover-color` | `color.accent.fg` | `#983318` |
650
- | `button.face.outline-danger-toggled-hover.color` | `--mx-button-face-outline-danger-toggled-hover-color` | `color.danger.fg` | `#b3261a` |
659
+ | `button.face.outline-danger-toggled-hover.color` | `--mx-button-face-outline-danger-toggled-hover-color` | `color.danger.fg` | `#b03659` |
651
660
  | `button.face.ghost-toggled-hover.bg` | `--mx-button-face-ghost-toggled-hover-bg` | `color.fill.subtle.secondary` | `rgb(0 0 0 / 0.0373)` |
652
661
  | `button.face.ghost-toggled-hover.color` | `--mx-button-face-ghost-toggled-hover-color` | `` | `initial` |
653
662
  | `button.face.ghost-accent-toggled-hover.color` | `--mx-button-face-ghost-accent-toggled-hover-color` | `color.accent.fg` | `#983318` |
654
- | `button.face.ghost-danger-toggled-hover.color` | `--mx-button-face-ghost-danger-toggled-hover-color` | `color.danger.fg` | `#b3261a` |
663
+ | `button.face.ghost-danger-toggled-hover.color` | `--mx-button-face-ghost-danger-toggled-hover-color` | `color.danger.fg` | `#b03659` |
655
664
  | `button.face.pressed.bg` | `--mx-button-face-pressed-bg` | `color.fill.control.tertiary` | `#e1e0da` |
656
665
  | `button.face.pressed.border-bottom-color` | `--mx-button-face-pressed-border-bottom-color` | `color.stroke.control.default` | `rgb(0 0 0 / 0.12)` |
657
666
  | `button.face.pressed.shadow` | `--mx-button-face-pressed-shadow` | `` | `0 0 #0000` |
@@ -660,19 +669,19 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
660
669
  | `button.face.accent-pressed.bg` | `--mx-button-face-accent-pressed-bg` | `color.accent.solid-pressed` | `#a1381c` |
661
670
  | `button.face.accent-pressed.border-bottom-color` | `--mx-button-face-accent-pressed-border-bottom-color` | `color.accent.solid` | `#c24523` |
662
671
  | `button.face.accent-pressed.color` | `--mx-button-face-accent-pressed-color` | `color.accent.on-solid` | `#ffffff` |
663
- | `button.face.danger-pressed.bg` | `--mx-button-face-danger-pressed-bg` | `color.danger.solid-hover` | `#c42b1c` |
664
- | `button.face.danger-pressed.border-bottom-color` | `--mx-button-face-danger-pressed-border-bottom-color` | `color.danger.solid` | `#b3261a` |
672
+ | `button.face.danger-pressed.bg` | `--mx-button-face-danger-pressed-bg` | `color.danger.solid-hover` | `#c13b61` |
673
+ | `button.face.danger-pressed.border-bottom-color` | `--mx-button-face-danger-pressed-border-bottom-color` | `color.danger.solid` | `#b03659` |
665
674
  | `button.face.danger-pressed.color` | `--mx-button-face-danger-pressed-color` | `color.danger.on-solid` | `#ffffff` |
666
675
  | `button.face.outline-pressed.bg` | `--mx-button-face-outline-pressed-bg` | `color.fill.subtle.tertiary` | `rgb(0 0 0 / 0.0241)` |
667
676
  | `button.face.outline-pressed.border-color` | `--mx-button-face-outline-pressed-border-color` | `color.stroke.control.strong` | `rgb(0 0 0 / 0.4458)` |
668
677
  | `button.face.outline-pressed.color` | `--mx-button-face-outline-pressed-color` | `` | `initial` |
669
678
  | `button.face.outline-accent-pressed.color` | `--mx-button-face-outline-accent-pressed-color` | `color.accent.fg` | `#983318` |
670
- | `button.face.outline-danger-pressed.color` | `--mx-button-face-outline-danger-pressed-color` | `color.danger.fg` | `#b3261a` |
679
+ | `button.face.outline-danger-pressed.color` | `--mx-button-face-outline-danger-pressed-color` | `color.danger.fg` | `#b03659` |
671
680
  | `button.face.ghost-pressed.bg` | `--mx-button-face-ghost-pressed-bg` | `color.fill.subtle.tertiary` | `rgb(0 0 0 / 0.0241)` |
672
681
  | `button.face.ghost-pressed.border-color` | `--mx-button-face-ghost-pressed-border-color` | `` | `rgb(0 0 0 / 0)` |
673
682
  | `button.face.ghost-pressed.color` | `--mx-button-face-ghost-pressed-color` | `` | `initial` |
674
683
  | `button.face.ghost-accent-pressed.color` | `--mx-button-face-ghost-accent-pressed-color` | `color.accent.fg` | `#983318` |
675
- | `button.face.ghost-danger-pressed.color` | `--mx-button-face-ghost-danger-pressed-color` | `color.danger.fg` | `#b3261a` |
684
+ | `button.face.ghost-danger-pressed.color` | `--mx-button-face-ghost-danger-pressed-color` | `color.danger.fg` | `#b03659` |
676
685
  | `button.face.focus.glow` | `--mx-button-face-focus-glow` | `focus.ring.halo` | `0px 0px 0px 1px rgb(255 255 255 / 0.7)` |
677
686
  | `button.face.focus.outline-width` | `--mx-button-face-focus-outline-width` | `focus.ring.width` | `2px` |
678
687
  | `button.face.focus.outline-color` | `--mx-button-face-focus-outline-color` | `focus.ring.color` | `#1d1c1a` |
@@ -687,19 +696,19 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
687
696
  | `button.face.accent-toggled.bg` | `--mx-button-face-accent-toggled-bg` | `color.accent.solid-pressed` | `#a1381c` |
688
697
  | `button.face.accent-toggled.border-bottom-color` | `--mx-button-face-accent-toggled-border-bottom-color` | `color.accent.solid` | `#c24523` |
689
698
  | `button.face.accent-toggled.color` | `--mx-button-face-accent-toggled-color` | `color.accent.on-solid` | `#ffffff` |
690
- | `button.face.danger-toggled.bg` | `--mx-button-face-danger-toggled-bg` | `color.danger.solid-hover` | `#c42b1c` |
691
- | `button.face.danger-toggled.border-bottom-color` | `--mx-button-face-danger-toggled-border-bottom-color` | `color.danger.solid` | `#b3261a` |
699
+ | `button.face.danger-toggled.bg` | `--mx-button-face-danger-toggled-bg` | `color.danger.solid-hover` | `#c13b61` |
700
+ | `button.face.danger-toggled.border-bottom-color` | `--mx-button-face-danger-toggled-border-bottom-color` | `color.danger.solid` | `#b03659` |
692
701
  | `button.face.danger-toggled.color` | `--mx-button-face-danger-toggled-color` | `color.danger.on-solid` | `#ffffff` |
693
702
  | `button.face.outline-toggled.bg` | `--mx-button-face-outline-toggled-bg` | `color.fill.subtle.tertiary` | `rgb(0 0 0 / 0.0241)` |
694
703
  | `button.face.outline-toggled.border-color` | `--mx-button-face-outline-toggled-border-color` | `color.stroke.control.strong` | `rgb(0 0 0 / 0.4458)` |
695
704
  | `button.face.outline-toggled.color` | `--mx-button-face-outline-toggled-color` | `` | `initial` |
696
705
  | `button.face.outline-accent-toggled.color` | `--mx-button-face-outline-accent-toggled-color` | `color.accent.fg` | `#983318` |
697
- | `button.face.outline-danger-toggled.color` | `--mx-button-face-outline-danger-toggled-color` | `color.danger.fg` | `#b3261a` |
706
+ | `button.face.outline-danger-toggled.color` | `--mx-button-face-outline-danger-toggled-color` | `color.danger.fg` | `#b03659` |
698
707
  | `button.face.ghost-toggled.bg` | `--mx-button-face-ghost-toggled-bg` | `color.fill.subtle.tertiary` | `rgb(0 0 0 / 0.0241)` |
699
708
  | `button.face.ghost-toggled.border-color` | `--mx-button-face-ghost-toggled-border-color` | `` | `rgb(0 0 0 / 0)` |
700
709
  | `button.face.ghost-toggled.color` | `--mx-button-face-ghost-toggled-color` | `` | `initial` |
701
710
  | `button.face.ghost-accent-toggled.color` | `--mx-button-face-ghost-accent-toggled-color` | `color.accent.fg` | `#983318` |
702
- | `button.face.ghost-danger-toggled.color` | `--mx-button-face-ghost-danger-toggled-color` | `color.danger.fg` | `#b3261a` |
711
+ | `button.face.ghost-danger-toggled.color` | `--mx-button-face-ghost-danger-toggled-color` | `color.danger.fg` | `#b03659` |
703
712
  | `button.face.disabled.bg` | `--mx-button-face-disabled-bg` | `color.fill.control.disabled` | `#ebeae5` |
704
713
  | `button.face.disabled.border-color` | `--mx-button-face-disabled-border-color` | `color.stroke.control.default` | `rgb(0 0 0 / 0.12)` |
705
714
  | `button.face.disabled.border-bottom-color` | `--mx-button-face-disabled-border-bottom-color` | `color.stroke.control.default` | `rgb(0 0 0 / 0.12)` |
@@ -738,10 +747,10 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
738
747
  | `button.spinner.danger.color` | `--mx-button-spinner-danger-color` | `color.danger.on-solid` | `#ffffff` |
739
748
  | `button.spinner.outline.color` | `--mx-button-spinner-outline-color` | `color.fg.primary` | `#1d1c1a` |
740
749
  | `button.spinner.outline-accent.color` | `--mx-button-spinner-outline-accent-color` | `color.accent.fg` | `#983318` |
741
- | `button.spinner.outline-danger.color` | `--mx-button-spinner-outline-danger-color` | `color.danger.fg` | `#b3261a` |
750
+ | `button.spinner.outline-danger.color` | `--mx-button-spinner-outline-danger-color` | `color.danger.fg` | `#b03659` |
742
751
  | `button.spinner.ghost.color` | `--mx-button-spinner-ghost-color` | `color.fg.primary` | `#1d1c1a` |
743
752
  | `button.spinner.ghost-accent.color` | `--mx-button-spinner-ghost-accent-color` | `color.accent.fg` | `#983318` |
744
- | `button.spinner.ghost-danger.color` | `--mx-button-spinner-ghost-danger-color` | `color.danger.fg` | `#b3261a` |
753
+ | `button.spinner.ghost-danger.color` | `--mx-button-spinner-ghost-danger-color` | `color.danger.fg` | `#b03659` |
745
754
  | `button.divider.width` | `--mx-button-divider-width` | `border.width.1` | `1px` |
746
755
  | `button.divider.bg` | `--mx-button-divider-bg` | `color.stroke.control.default` | `rgb(0 0 0 / 0.12)` |
747
756
  | `button.divider.accent.bg` | `--mx-button-divider-accent-bg` | `color.stroke.on-accent-bottom` | `rgb(0 0 0 / 0.4)` |
@@ -797,6 +806,15 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
797
806
  | `calendar.cell.selected.color` | `--mx-calendar-cell-selected-color` | `color.accent.on-solid` | `#ffffff` |
798
807
  | `calendar.cell.selected.shadow` | `--mx-calendar-cell-selected-shadow` | `` | `initial` |
799
808
  | `calendar.cell.selected-hover.bg` | `--mx-calendar-cell-selected-hover-bg` | `color.accent.solid` | `#c24523` |
809
+ | `calendar.cell.range-start.bg` | `--mx-calendar-cell-range-start-bg` | `color.accent.solid` | `#c24523` |
810
+ | `calendar.cell.range-start.color` | `--mx-calendar-cell-range-start-color` | `color.accent.on-solid` | `#ffffff` |
811
+ | `calendar.cell.range-end.bg` | `--mx-calendar-cell-range-end-bg` | `color.accent.solid` | `#c24523` |
812
+ | `calendar.cell.range-end.color` | `--mx-calendar-cell-range-end-color` | `color.accent.on-solid` | `#ffffff` |
813
+ | `calendar.cell.range-single.bg` | `--mx-calendar-cell-range-single-bg` | `color.accent.solid` | `#c24523` |
814
+ | `calendar.cell.range-single.color` | `--mx-calendar-cell-range-single-color` | `color.accent.on-solid` | `#ffffff` |
815
+ | `calendar.cell.range-in.bg` | `--mx-calendar-cell-range-in-bg` | `color.accent.subtle` | `#fbe6de` |
816
+ | `calendar.cell.range-in.color` | `--mx-calendar-cell-range-in-color` | `color.accent.on-subtle` | `#983318` |
817
+ | `calendar.cell.range-in.radius` | `--mx-calendar-cell-range-in-radius` | `radius.none` | `0px` |
800
818
  | `calendar.cell.disabled.color` | `--mx-calendar-cell-disabled-color` | `color.fg.disabled` | `#a2a098` |
801
819
  | `calendar.today.padding-block` | `--mx-calendar-today-padding-block` | `space.1` | `0.25rem` |
802
820
  | `calendar.today.padding-inline` | `--mx-calendar-today-padding-inline` | `space.3` | `0.75rem` |
@@ -906,15 +924,15 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
906
924
  | `checkbox.box.mixed.bg` | `--mx-checkbox-box-mixed-bg` | `color.accent.solid` | `#c24523` |
907
925
  | `checkbox.box.mixed.border-color` | `--mx-checkbox-box-mixed-border-color` | `color.accent.solid` | `#c24523` |
908
926
  | `checkbox.box.mixed.shadow` | `--mx-checkbox-box-mixed-shadow` | `` | `inset 0px 1px 0px 0px rgb(255 255 255 / 0.7), 0 1px 0 rgb(0 0 0 / 0.4)` |
909
- | `checkbox.box.invalid.border-color` | `--mx-checkbox-box-invalid-border-color` | `color.danger.solid` | `#b3261a` |
910
- | `checkbox.box.invalid.shadow` | `--mx-checkbox-box-invalid-shadow` | `` | `inset 0px 1px 0px 0px rgb(255 255 255 / 0.7), 0 1px 0 #b3261a` |
927
+ | `checkbox.box.invalid.border-color` | `--mx-checkbox-box-invalid-border-color` | `color.danger.solid` | `#b03659` |
928
+ | `checkbox.box.invalid.shadow` | `--mx-checkbox-box-invalid-shadow` | `` | `inset 0px 1px 0px 0px rgb(255 255 255 / 0.7), 0 1px 0 #b03659` |
911
929
  | `checkbox.box.hover.bg` | `--mx-checkbox-box-hover-bg` | `color.fill.control.secondary` | `#ebeae5` |
912
930
  | `checkbox.box.hover.border-color` | `--mx-checkbox-box-hover-border-color` | `` | `initial` |
913
931
  | `checkbox.box.checked-hover.bg` | `--mx-checkbox-box-checked-hover-bg` | `color.accent.solid-hover` | `#b43f20` |
914
932
  | `checkbox.box.checked-hover.border-color` | `--mx-checkbox-box-checked-hover-border-color` | `` | `initial` |
915
933
  | `checkbox.box.mixed-hover.bg` | `--mx-checkbox-box-mixed-hover-bg` | `color.accent.solid-hover` | `#b43f20` |
916
934
  | `checkbox.box.mixed-hover.border-color` | `--mx-checkbox-box-mixed-hover-border-color` | `` | `initial` |
917
- | `checkbox.box.invalid-hover.border-color` | `--mx-checkbox-box-invalid-hover-border-color` | `color.danger.solid` | `#b3261a` |
935
+ | `checkbox.box.invalid-hover.border-color` | `--mx-checkbox-box-invalid-hover-border-color` | `color.danger.solid` | `#b03659` |
918
936
  | `checkbox.box.pressed.bg` | `--mx-checkbox-box-pressed-bg` | `color.fill.control.tertiary` | `#e1e0da` |
919
937
  | `checkbox.box.pressed.border-color` | `--mx-checkbox-box-pressed-border-color` | `color.stroke.control.strong` | `rgb(0 0 0 / 0.4458)` |
920
938
  | `checkbox.box.pressed.shadow` | `--mx-checkbox-box-pressed-shadow` | `` | `0 0 #0000` |
@@ -924,7 +942,7 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
924
942
  | `checkbox.box.mixed-pressed.bg` | `--mx-checkbox-box-mixed-pressed-bg` | `color.accent.solid-pressed` | `#a1381c` |
925
943
  | `checkbox.box.mixed-pressed.border-color` | `--mx-checkbox-box-mixed-pressed-border-color` | `color.accent.solid` | `#c24523` |
926
944
  | `checkbox.box.mixed-pressed.shadow` | `--mx-checkbox-box-mixed-pressed-shadow` | `` | `0 0 #0000` |
927
- | `checkbox.box.invalid-pressed.border-color` | `--mx-checkbox-box-invalid-pressed-border-color` | `color.danger.solid` | `#b3261a` |
945
+ | `checkbox.box.invalid-pressed.border-color` | `--mx-checkbox-box-invalid-pressed-border-color` | `color.danger.solid` | `#b03659` |
928
946
  | `checkbox.box.focus.outline-width` | `--mx-checkbox-box-focus-outline-width` | `focus.ring.width` | `2px` |
929
947
  | `checkbox.box.focus.outline-color` | `--mx-checkbox-box-focus-outline-color` | `focus.ring.color` | `#1d1c1a` |
930
948
  | `checkbox.box.focus.outline-offset` | `--mx-checkbox-box-focus-outline-offset` | `focus.ring.offset` | `1px` |
@@ -939,7 +957,7 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
939
957
  | `checkbox.box.mixed-pressed-focus.glow` | `--mx-checkbox-box-mixed-pressed-focus-glow` | `focus.ring.halo` | `0px 0px 0px 1px rgb(255 255 255 / 0.7)` |
940
958
  | `checkbox.box.mixed-pressed-focus.shadow` | `--mx-checkbox-box-mixed-pressed-focus-shadow` | `` | `inset 0px 1px 0px 0px rgb(255 255 255 / 0.7), 0 1px 0 rgb(0 0 0 / 0.4)` |
941
959
  | `checkbox.box.invalid-pressed-focus.glow` | `--mx-checkbox-box-invalid-pressed-focus-glow` | `focus.ring.halo` | `0px 0px 0px 1px rgb(255 255 255 / 0.7)` |
942
- | `checkbox.box.invalid-pressed-focus.shadow` | `--mx-checkbox-box-invalid-pressed-focus-shadow` | `` | `inset 0px 1px 0px 0px rgb(255 255 255 / 0.7), 0 1px 0 #b3261a` |
960
+ | `checkbox.box.invalid-pressed-focus.shadow` | `--mx-checkbox-box-invalid-pressed-focus-shadow` | `` | `inset 0px 1px 0px 0px rgb(255 255 255 / 0.7), 0 1px 0 #b03659` |
943
961
  | `checkbox.box.disabled.bg` | `--mx-checkbox-box-disabled-bg` | `color.fill.control.disabled` | `#ebeae5` |
944
962
  | `checkbox.box.disabled.border-color` | `--mx-checkbox-box-disabled-border-color` | `color.stroke.control.default` | `rgb(0 0 0 / 0.12)` |
945
963
  | `checkbox.box.disabled.shadow` | `--mx-checkbox-box-disabled-shadow` | `` | `0 0 #0000` |
@@ -990,17 +1008,17 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
990
1008
  | `chip.chip.outline-accent.color` | `--mx-chip-chip-outline-accent-color` | `color.accent.fg` | `#983318` |
991
1009
  | `chip.chip.outline-accent.border-color` | `--mx-chip-chip-outline-accent-border-color` | `color.accent.fg` | `#983318` |
992
1010
  | `chip.chip.success.bg` | `--mx-chip-chip-success-bg` | `color.success.subtle` | `#dff6dd` |
993
- | `chip.chip.success.color` | `--mx-chip-chip-success-color` | `color.success.fg` | `#0c6a0c` |
994
- | `chip.chip.outline-success.color` | `--mx-chip-chip-outline-success-color` | `color.success.fg` | `#0c6a0c` |
995
- | `chip.chip.outline-success.border-color` | `--mx-chip-chip-outline-success-border-color` | `color.success.fg` | `#0c6a0c` |
1011
+ | `chip.chip.success.color` | `--mx-chip-chip-success-color` | `color.success.fg` | `#006402` |
1012
+ | `chip.chip.outline-success.color` | `--mx-chip-chip-outline-success-color` | `color.success.fg` | `#006402` |
1013
+ | `chip.chip.outline-success.border-color` | `--mx-chip-chip-outline-success-border-color` | `color.success.fg` | `#006402` |
996
1014
  | `chip.chip.caution.bg` | `--mx-chip-chip-caution-bg` | `color.caution.subtle` | `#fff4ce` |
997
- | `chip.chip.caution.color` | `--mx-chip-chip-caution-color` | `color.caution.fg` | `#845000` |
998
- | `chip.chip.outline-caution.color` | `--mx-chip-chip-outline-caution-color` | `color.caution.fg` | `#845000` |
999
- | `chip.chip.outline-caution.border-color` | `--mx-chip-chip-outline-caution-border-color` | `color.caution.fg` | `#845000` |
1015
+ | `chip.chip.caution.color` | `--mx-chip-chip-caution-color` | `color.caution.fg` | `#754702` |
1016
+ | `chip.chip.outline-caution.color` | `--mx-chip-chip-outline-caution-color` | `color.caution.fg` | `#754702` |
1017
+ | `chip.chip.outline-caution.border-color` | `--mx-chip-chip-outline-caution-border-color` | `color.caution.fg` | `#754702` |
1000
1018
  | `chip.chip.danger.bg` | `--mx-chip-chip-danger-bg` | `color.danger.subtle` | `#fde7e9` |
1001
- | `chip.chip.danger.color` | `--mx-chip-chip-danger-color` | `color.danger.fg` | `#b3261a` |
1002
- | `chip.chip.outline-danger.color` | `--mx-chip-chip-outline-danger-color` | `color.danger.fg` | `#b3261a` |
1003
- | `chip.chip.outline-danger.border-color` | `--mx-chip-chip-outline-danger-border-color` | `color.danger.fg` | `#b3261a` |
1019
+ | `chip.chip.danger.color` | `--mx-chip-chip-danger-color` | `color.danger.fg` | `#b03659` |
1020
+ | `chip.chip.outline-danger.color` | `--mx-chip-chip-outline-danger-color` | `color.danger.fg` | `#b03659` |
1021
+ | `chip.chip.outline-danger.border-color` | `--mx-chip-chip-outline-danger-border-color` | `color.danger.fg` | `#b03659` |
1004
1022
  | `chip.chip.selected.bg` | `--mx-chip-chip-selected-bg` | `color.accent.subtle` | `#fbe6de` |
1005
1023
  | `chip.chip.selected.color` | `--mx-chip-chip-selected-color` | `color.accent.on-subtle` | `#983318` |
1006
1024
  | `chip.chip.selected.border-color` | `--mx-chip-chip-selected-border-color` | `` | `rgb(0 0 0 / 0)` |
@@ -1115,7 +1133,7 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
1115
1133
  | `datagrid.range-anchor-fill` | `--mx-datagrid-range-anchor-fill` | `color.bg.surface` | `#f8f7f3` |
1116
1134
  | `datagrid.row-run-border-color` | `--mx-datagrid-row-run-border-color` | `color.accent.solid` | `#c24523` |
1117
1135
  | `datagrid.row-run-border-width` | `--mx-datagrid-row-run-border-width` | `border.width.2` | `2px` |
1118
- | `datagrid.search-mark-line` | `--mx-datagrid-search-mark-line` | `color.caution.fg` | `#845000` |
1136
+ | `datagrid.search-mark-line` | `--mx-datagrid-search-mark-line` | `color.caution.fg` | `#754702` |
1119
1137
  | `datagrid.search-mark-thickness` | `--mx-datagrid-search-mark-thickness` | `border.width.2` | `2px` |
1120
1138
  | `datagrid.search-mark-offset` | `--mx-datagrid-search-mark-offset` | `border.width.2` | `2px` |
1121
1139
  | `datagrid.filter-text-underline-width` | `--mx-datagrid-filter-text-underline-width` | `border.width.1` | `1px` |
@@ -1281,7 +1299,7 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
1281
1299
  | `datagrid.changed.border-top-color` | `--mx-datagrid-changed-border-top-color` | `color.accent.solid` | `#c24523` |
1282
1300
  | `datagrid.changed.border-color` | `--mx-datagrid-changed-border-color` | `` | `rgb(0 0 0 / 0)` |
1283
1301
  | `datagrid.invalid.border-width` | `--mx-datagrid-invalid-border-width` | `border.width.2` | `2px` |
1284
- | `datagrid.invalid.border-color` | `--mx-datagrid-invalid-border-color` | `color.danger.solid` | `#b3261a` |
1302
+ | `datagrid.invalid.border-color` | `--mx-datagrid-invalid-border-color` | `color.danger.solid` | `#b03659` |
1285
1303
  | `datagrid.placeholder.bg` | `--mx-datagrid-placeholder-bg` | `color.fill.subtle.secondary` | `rgb(0 0 0 / 0.0373)` |
1286
1304
  | `datagrid.placeholder.radius` | `--mx-datagrid-placeholder-radius` | `radius.sm` | `0.25rem` |
1287
1305
  | `datagrid.header-cell.padding-inline` | `--mx-datagrid-header-cell-padding-inline` | `control.padding.sm` | `0.5rem` |
@@ -1371,11 +1389,11 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
1371
1389
  | `datagrid.ghost-rows.bg` | `--mx-datagrid-ghost-rows-bg` | `color.bg.surface` | `#f8f7f3` |
1372
1390
  | `datagrid.status-mark.font-size` | `--mx-datagrid-status-mark-font-size` | `font.size.caption` | `0.75rem` |
1373
1391
  | `datagrid.status-mark.font-weight` | `--mx-datagrid-status-mark-font-weight` | `font.weight.bold` | `700` |
1374
- | `datagrid.status-symbol.new.color` | `--mx-datagrid-status-symbol-new-color` | `color.success.fg` | `#0c6a0c` |
1392
+ | `datagrid.status-symbol.new.color` | `--mx-datagrid-status-symbol-new-color` | `color.success.fg` | `#006402` |
1375
1393
  | `datagrid.status-symbol.changed.color` | `--mx-datagrid-status-symbol-changed-color` | `color.accent.fg` | `#983318` |
1376
1394
  | `datagrid.status-symbol.removed.color` | `--mx-datagrid-status-symbol-removed-color` | `color.fg.secondary` | `#5e5c55` |
1377
1395
  | `datagrid.status-symbol.saving.color` | `--mx-datagrid-status-symbol-saving-color` | `color.accent.fg` | `#983318` |
1378
- | `datagrid.status-symbol.failed.color` | `--mx-datagrid-status-symbol-failed-color` | `color.danger.fg` | `#b3261a` |
1396
+ | `datagrid.status-symbol.failed.color` | `--mx-datagrid-status-symbol-failed-color` | `color.danger.fg` | `#b03659` |
1379
1397
  | `datagrid.check.size` | `--mx-datagrid-check-size` | `` | `0.875rem` |
1380
1398
  | `datagrid.check.bg` | `--mx-datagrid-check-bg` | `color.fill.control.default` | `#f5f4f0` |
1381
1399
  | `datagrid.check.border-width` | `--mx-datagrid-check-border-width` | `border.width.1` | `1px` |
@@ -1426,7 +1444,7 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
1426
1444
  | `datagrid.form.padding` | `--mx-datagrid-form-padding` | `space.3` | `0.75rem` |
1427
1445
  | `datagrid.form.gap` | `--mx-datagrid-form-gap` | `space.3` | `0.75rem` |
1428
1446
  | `datagrid.form.popup.padding` | `--mx-datagrid-form-popup-padding` | `` | `0px` |
1429
- | `datagrid.form-message.color` | `--mx-datagrid-form-message-color` | `color.danger.fg` | `#b3261a` |
1447
+ | `datagrid.form-message.color` | `--mx-datagrid-form-message-color` | `color.danger.fg` | `#b03659` |
1430
1448
  | `datagrid.form-buttons.gap` | `--mx-datagrid-form-buttons-gap` | `space.3` | `0.75rem` |
1431
1449
  | `datagrid.form-label.color` | `--mx-datagrid-form-label-color` | `color.fg.secondary` | `#5e5c55` |
1432
1450
  | `datagrid.form-label.font-size` | `--mx-datagrid-form-label-font-size` | `font.size.caption` | `0.75rem` |
@@ -1440,9 +1458,9 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
1440
1458
  | `datagrid.state.padding-inline` | `--mx-datagrid-state-padding-inline` | `space.3` | `0.75rem` |
1441
1459
  | `datagrid.state.gap` | `--mx-datagrid-state-gap` | `space.2` | `0.5rem` |
1442
1460
  | `datagrid.state.color` | `--mx-datagrid-state-color` | `color.fg.secondary` | `#5e5c55` |
1443
- | `datagrid.state.danger.color` | `--mx-datagrid-state-danger-color` | `color.danger.fg` | `#b3261a` |
1461
+ | `datagrid.state.danger.color` | `--mx-datagrid-state-danger-color` | `color.danger.fg` | `#b03659` |
1444
1462
  | `datagrid.note.gap` | `--mx-datagrid-note-gap` | `space.2` | `0.5rem` |
1445
- | `datagrid.note.danger.color` | `--mx-datagrid-note-danger-color` | `color.danger.fg` | `#b3261a` |
1463
+ | `datagrid.note.danger.color` | `--mx-datagrid-note-danger-color` | `color.danger.fg` | `#b03659` |
1446
1464
  | `datagrid.load-more.margin-bottom` | `--mx-datagrid-load-more-margin-bottom` | `space.2` | `0.5rem` |
1447
1465
  | `datagrid.load-more.padding-block` | `--mx-datagrid-load-more-padding-block` | `space.1` | `0.25rem` |
1448
1466
  | `datagrid.load-more.padding-inline` | `--mx-datagrid-load-more-padding-inline` | `space.3` | `0.75rem` |
@@ -1453,7 +1471,7 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
1453
1471
  | `datagrid.load-more.radius` | `--mx-datagrid-load-more-radius` | `radius.sm` | `0.25rem` |
1454
1472
  | `datagrid.load-more.shadow` | `--mx-datagrid-load-more-shadow` | `elevation.popup` | `0px 8px 16px 0px rgb(0 0 0 / 0.14), 0px 0px 2px 0px rgb(0 0 0 / 0.12)` |
1455
1473
  | `datagrid.load-more.color` | `--mx-datagrid-load-more-color` | `color.fg.secondary` | `#5e5c55` |
1456
- | `datagrid.load-more.failed.color` | `--mx-datagrid-load-more-failed-color` | `color.danger.fg` | `#b3261a` |
1474
+ | `datagrid.load-more.failed.color` | `--mx-datagrid-load-more-failed-color` | `color.danger.fg` | `#b03659` |
1457
1475
  | `datagrid.export-panel.padding` | `--mx-datagrid-export-panel-padding` | `space.3` | `0.75rem` |
1458
1476
  | `datagrid.export-panel.gap` | `--mx-datagrid-export-panel-gap` | `space.3` | `0.75rem` |
1459
1477
  | `datagrid.export-panel.bg` | `--mx-datagrid-export-panel-bg` | `color.bg.surface` | `#f8f7f3` |
@@ -1496,8 +1514,8 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
1496
1514
  | `datagrid.page-sizes.margin-end` | `--mx-datagrid-page-sizes-margin-end` | `space.2` | `0.5rem` |
1497
1515
  | `datagrid.page-gap.padding-inline` | `--mx-datagrid-page-gap-padding-inline` | `space.1` | `0.25rem` |
1498
1516
  | `datagrid.page-info.margin-end` | `--mx-datagrid-page-info-margin-end` | `space.2` | `0.5rem` |
1499
- | `datagrid.tip.error.border-color` | `--mx-datagrid-tip-error-border-color` | `color.danger.solid` | `#b3261a` |
1500
- | `datagrid.tip.error.color` | `--mx-datagrid-tip-error-color` | `color.danger.fg` | `#b3261a` |
1517
+ | `datagrid.tip.error.border-color` | `--mx-datagrid-tip-error-border-color` | `color.danger.solid` | `#b03659` |
1518
+ | `datagrid.tip.error.color` | `--mx-datagrid-tip-error-color` | `color.danger.fg` | `#b03659` |
1501
1519
  | `date-box.popup-gap` | `--mx-date-box-popup-gap` | `space.1` | `0.25rem` |
1502
1520
  | `date-box.calendar.container.padding` | `--mx-date-box-calendar-container-padding` | `space.2` | `0.5rem` |
1503
1521
  | `date-box.times.min-width` | `--mx-date-box-times-min-width` | `` | `6rem` |
@@ -1509,6 +1527,22 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
1509
1527
  | `date-box.times.beside.padding-start` | `--mx-date-box-times-beside-padding-start` | `space.1` | `0.25rem` |
1510
1528
  | `date-box.times.beside.border-start-width` | `--mx-date-box-times-beside-border-start-width` | `border.width.1` | `1px` |
1511
1529
  | `date-box.times.beside.border-start-color` | `--mx-date-box-times-beside-border-start-color` | `color.stroke.divider` | `rgb(0 0 0 / 0.1)` |
1530
+ | `date-range-box.popup-gap` | `--mx-date-range-box-popup-gap` | `space.1` | `0.25rem` |
1531
+ | `date-range-box.field.width` | `--mx-date-range-box-field-width` | `` | `20rem` |
1532
+ | `date-range-box.calendar.container.padding` | `--mx-date-range-box-calendar-container-padding` | `space.2` | `0.5rem` |
1533
+ | `date-range-box.separator.icon` | `--mx-date-range-box-separator-icon` | `` | `var(--mx-icon-dash)` |
1534
+ | `date-range-box.separator.bg` | `--mx-date-range-box-separator-bg` | `color.fg.tertiary` | `#8c8a82` |
1535
+ | `date-range-box.separator.size` | `--mx-date-range-box-separator-size` | `` | `1rem` |
1536
+ | `date-range-box.separator.margin-inline` | `--mx-date-range-box-separator-margin-inline` | `space.1` | `0.25rem` |
1537
+ | `date-range-box.presets.min-width` | `--mx-date-range-box-presets-min-width` | `` | `9rem` |
1538
+ | `date-range-box.presets.max-height` | `--mx-date-range-box-presets-max-height` | `` | `18rem` |
1539
+ | `date-range-box.presets.focus.outline-width` | `--mx-date-range-box-presets-focus-outline-width` | `focus.ring.width` | `2px` |
1540
+ | `date-range-box.presets.focus.outline-color` | `--mx-date-range-box-presets-focus-outline-color` | `focus.ring.color` | `#1d1c1a` |
1541
+ | `date-range-box.presets.focus.outline-offset` | `--mx-date-range-box-presets-focus-outline-offset` | `` | `calc(-1 * 2px)` |
1542
+ | `date-range-box.presets.focus.glow` | `--mx-date-range-box-presets-focus-glow` | `focus.ring.halo` | `0px 0px 0px 1px rgb(255 255 255 / 0.7)` |
1543
+ | `date-range-box.presets.beside.padding-start` | `--mx-date-range-box-presets-beside-padding-start` | `space.1` | `0.25rem` |
1544
+ | `date-range-box.presets.beside.border-start-width` | `--mx-date-range-box-presets-beside-border-start-width` | `border.width.1` | `1px` |
1545
+ | `date-range-box.presets.beside.border-start-color` | `--mx-date-range-box-presets-beside-border-start-color` | `color.stroke.divider` | `rgb(0 0 0 / 0.1)` |
1512
1546
  | `disabled.element.color` | `--mx-disabled-element-color` | `color.fg.disabled` | `#a2a098` |
1513
1547
  | `drawer.font-family` | `--mx-drawer-font-family` | `font.family.sans` | `Archivo, system-ui, -apple-system, 'Helvetica Neue', Arial, sans-serif` |
1514
1548
  | `drawer.size` | `--mx-drawer-size` | `` | `20rem` |
@@ -1677,11 +1711,13 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
1677
1711
  | `field.box.underline-readonly-invalid-focus.shadow` | `--mx-field-box-underline-readonly-invalid-focus-shadow` | `` | `initial` |
1678
1712
  | `field.box.pressed.bg` | `--mx-field-box-pressed-bg` | `` | `initial` |
1679
1713
  | `field.box.pressed.color` | `--mx-field-box-pressed-color` | `` | `initial` |
1714
+ | `field.box.border-style` | `--mx-field-box-border-style` | `` | `initial` |
1715
+ | `field.box.border-color` | `--mx-field-box-border-color` | `` | `initial` |
1680
1716
  | `field.frame.border-color` | `--mx-field-frame-border-color` | `color.stroke.control.default` | `rgb(0 0 0 / 0.12)` |
1681
1717
  | `field.frame.focus.border-bottom-color` | `--mx-field-frame-focus-border-bottom-color` | `color.accent.solid` | `#c24523` |
1682
1718
  | `field.frame.focus.border-color` | `--mx-field-frame-focus-border-color` | `` | `initial` |
1683
1719
  | `field.frame.focus.border-width` | `--mx-field-frame-focus-border-width` | `` | `initial` |
1684
- | `field.frame.invalid.border-color` | `--mx-field-frame-invalid-border-color` | `color.danger.solid` | `#b3261a` |
1720
+ | `field.frame.invalid.border-color` | `--mx-field-frame-invalid-border-color` | `color.danger.solid` | `#b03659` |
1685
1721
  | `field.frame.readonly-focus.border-bottom-color` | `--mx-field-frame-readonly-focus-border-bottom-color` | `color.stroke.control.strong` | `rgb(0 0 0 / 0.4458)` |
1686
1722
  | `field.frame.readonly-focus.border-width` | `--mx-field-frame-readonly-focus-border-width` | `` | `initial` |
1687
1723
  | `field.frame.filled.border-color` | `--mx-field-frame-filled-border-color` | `` | `rgb(0 0 0 / 0)` |
@@ -1689,7 +1725,7 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
1689
1725
  | `field.frame.filled-focus.border-bottom-color` | `--mx-field-frame-filled-focus-border-bottom-color` | `color.accent.solid` | `#c24523` |
1690
1726
  | `field.frame.filled-focus.border-color` | `--mx-field-frame-filled-focus-border-color` | `` | `initial` |
1691
1727
  | `field.frame.filled-focus.border-width` | `--mx-field-frame-filled-focus-border-width` | `` | `initial` |
1692
- | `field.frame.filled-invalid.border-color` | `--mx-field-frame-filled-invalid-border-color` | `color.danger.solid` | `#b3261a` |
1728
+ | `field.frame.filled-invalid.border-color` | `--mx-field-frame-filled-invalid-border-color` | `color.danger.solid` | `#b03659` |
1693
1729
  | `field.frame.filled-readonly-focus.border-bottom-color` | `--mx-field-frame-filled-readonly-focus-border-bottom-color` | `color.stroke.control.strong` | `rgb(0 0 0 / 0.4458)` |
1694
1730
  | `field.frame.filled-readonly-focus.border-width` | `--mx-field-frame-filled-readonly-focus-border-width` | `` | `initial` |
1695
1731
  | `field.frame.filled-disabled.border-color` | `--mx-field-frame-filled-disabled-border-color` | `color.stroke.control.default` | `rgb(0 0 0 / 0.12)` |
@@ -1697,7 +1733,7 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
1697
1733
  | `field.frame.underline.border-bottom-color` | `--mx-field-frame-underline-border-bottom-color` | `color.stroke.control.default` | `rgb(0 0 0 / 0.12)` |
1698
1734
  | `field.frame.underline-focus.border-bottom-color` | `--mx-field-frame-underline-focus-border-bottom-color` | `color.accent.solid` | `#c24523` |
1699
1735
  | `field.frame.underline-focus.border-width` | `--mx-field-frame-underline-focus-border-width` | `` | `initial` |
1700
- | `field.frame.underline-invalid.border-bottom-color` | `--mx-field-frame-underline-invalid-border-bottom-color` | `color.danger.solid` | `#b3261a` |
1736
+ | `field.frame.underline-invalid.border-bottom-color` | `--mx-field-frame-underline-invalid-border-bottom-color` | `color.danger.solid` | `#b03659` |
1701
1737
  | `field.frame.underline-readonly-focus.border-bottom-color` | `--mx-field-frame-underline-readonly-focus-border-bottom-color` | `color.stroke.control.strong` | `rgb(0 0 0 / 0.4458)` |
1702
1738
  | `field.frame.underline-readonly-focus.border-width` | `--mx-field-frame-underline-readonly-focus-border-width` | `` | `initial` |
1703
1739
  | `field.frame.underline-disabled.border-color` | `--mx-field-frame-underline-disabled-border-color` | `color.stroke.control.default` | `rgb(0 0 0 / 0.12)` |
@@ -1726,14 +1762,14 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
1726
1762
  | `field.frame.display` | `--mx-field-frame-display` | `` | `initial` |
1727
1763
  | `field.indicator.radius` | `--mx-field-indicator-radius` | `` | `calc(0.375rem - 1px)` |
1728
1764
  | `field.indicator.focus.shadow` | `--mx-field-indicator-focus-shadow` | `` | `inset 0 -1px 0 0 #c24523` |
1729
- | `field.indicator.invalid-focus.shadow` | `--mx-field-indicator-invalid-focus-shadow` | `` | `inset 0 -1px 0 0 #b3261a` |
1765
+ | `field.indicator.invalid-focus.shadow` | `--mx-field-indicator-invalid-focus-shadow` | `` | `inset 0 -1px 0 0 #b03659` |
1730
1766
  | `field.indicator.readonly-focus.shadow` | `--mx-field-indicator-readonly-focus-shadow` | `` | `inset 0 -1px 0 0 rgb(0 0 0 / 0.4458)` |
1731
1767
  | `field.indicator.filled-focus.shadow` | `--mx-field-indicator-filled-focus-shadow` | `` | `inset 0 -1px 0 0 #c24523` |
1732
- | `field.indicator.filled-invalid-focus.shadow` | `--mx-field-indicator-filled-invalid-focus-shadow` | `` | `inset 0 -1px 0 0 #b3261a` |
1768
+ | `field.indicator.filled-invalid-focus.shadow` | `--mx-field-indicator-filled-invalid-focus-shadow` | `` | `inset 0 -1px 0 0 #b03659` |
1733
1769
  | `field.indicator.filled-readonly-focus.shadow` | `--mx-field-indicator-filled-readonly-focus-shadow` | `` | `inset 0 -1px 0 0 rgb(0 0 0 / 0.4458)` |
1734
1770
  | `field.indicator.underline.radius` | `--mx-field-indicator-underline-radius` | `` | `0px` |
1735
1771
  | `field.indicator.underline-focus.shadow` | `--mx-field-indicator-underline-focus-shadow` | `` | `inset 0 -1px 0 0 #c24523` |
1736
- | `field.indicator.underline-invalid-focus.shadow` | `--mx-field-indicator-underline-invalid-focus-shadow` | `` | `inset 0 -1px 0 0 #b3261a` |
1772
+ | `field.indicator.underline-invalid-focus.shadow` | `--mx-field-indicator-underline-invalid-focus-shadow` | `` | `inset 0 -1px 0 0 #b03659` |
1737
1773
  | `field.indicator.underline-readonly-focus.shadow` | `--mx-field-indicator-underline-readonly-focus-shadow` | `` | `inset 0 -1px 0 0 rgb(0 0 0 / 0.4458)` |
1738
1774
  | `field.indicator.readonly-invalid-focus.shadow` | `--mx-field-indicator-readonly-invalid-focus-shadow` | `` | `inset 0 -1px 0 0 rgb(0 0 0 / 0.4458)` |
1739
1775
  | `field.indicator.filled-readonly-invalid-focus.shadow` | `--mx-field-indicator-filled-readonly-invalid-focus-shadow` | `` | `inset 0 -1px 0 0 rgb(0 0 0 / 0.4458)` |
@@ -1749,7 +1785,7 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
1749
1785
  | `field.label.floating-focus.color` | `--mx-field-label-floating-focus-color` | `` | `initial` |
1750
1786
  | `field.label.floating-invalid.color` | `--mx-field-label-floating-invalid-color` | `` | `initial` |
1751
1787
  | `field.required.margin-start` | `--mx-field-required-margin-start` | `space.1` | `0.25rem` |
1752
- | `field.required.color` | `--mx-field-required-color` | `color.danger.fg` | `#b3261a` |
1788
+ | `field.required.color` | `--mx-field-required-color` | `color.danger.fg` | `#b03659` |
1753
1789
  | `field.icon.color` | `--mx-field-icon-color` | `color.fg.secondary` | `#5e5c55` |
1754
1790
  | `field.prefix.color` | `--mx-field-prefix-color` | `color.fg.secondary` | `#5e5c55` |
1755
1791
  | `field.suffix.color` | `--mx-field-suffix-color` | `color.fg.secondary` | `#5e5c55` |
@@ -1774,7 +1810,7 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
1774
1810
  | `field.foot.color` | `--mx-field-foot-color` | `color.fg.secondary` | `#5e5c55` |
1775
1811
  | `field.foot.shown.padding-top` | `--mx-field-foot-shown-padding-top` | `space.1` | `0.25rem` |
1776
1812
  | `field.foot.display` | `--mx-field-foot-display` | `` | `initial` |
1777
- | `field.message.invalid.color` | `--mx-field-message-invalid-color` | `color.danger.fg` | `#b3261a` |
1813
+ | `field.message.invalid.color` | `--mx-field-message-invalid-color` | `color.danger.fg` | `#b03659` |
1778
1814
  | `field.frame-start.focus.border-block-width` | `--mx-field-frame-start-focus-border-block-width` | `` | `initial` |
1779
1815
  | `field.frame-start.focus.border-start-width` | `--mx-field-frame-start-focus-border-start-width` | `` | `initial` |
1780
1816
  | `field.frame-start.invalid-focus.border-block-width` | `--mx-field-frame-start-invalid-focus-border-block-width` | `` | `initial` |
@@ -1795,6 +1831,71 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
1795
1831
  | `field.frame-end.readonly-focus.border-end-width` | `--mx-field-frame-end-readonly-focus-border-end-width` | `` | `initial` |
1796
1832
  | `field.frame-end.readonly-invalid-focus.border-block-width` | `--mx-field-frame-end-readonly-invalid-focus-border-block-width` | `` | `initial` |
1797
1833
  | `field.frame-end.readonly-invalid-focus.border-end-width` | `--mx-field-frame-end-readonly-invalid-focus-border-end-width` | `` | `initial` |
1834
+ | `file-uploader.box-gap` | `--mx-file-uploader-box-gap` | `space.3` | `0.75rem` |
1835
+ | `file-uploader.button-gap` | `--mx-file-uploader-button-gap` | `space.2` | `0.5rem` |
1836
+ | `file-uploader.item-gap` | `--mx-file-uploader-item-gap` | `space.2` | `0.5rem` |
1837
+ | `file-uploader.field.width` | `--mx-file-uploader-field-width` | `` | `26rem` |
1838
+ | `file-uploader.field.box.border-style` | `--mx-file-uploader-field-box-border-style` | `` | `dashed` |
1839
+ | `file-uploader.field.box.border-color` | `--mx-file-uploader-field-box-border-color` | `color.stroke.control.strong` | `rgb(0 0 0 / 0.4458)` |
1840
+ | `file-uploader.field.box.radius` | `--mx-file-uploader-field-box-radius` | `radius.lg` | `0.625rem` |
1841
+ | `file-uploader.field.box.hover.bg` | `--mx-file-uploader-field-box-hover-bg` | `color.fill.subtle.secondary` | `rgb(0 0 0 / 0.0373)` |
1842
+ | `file-uploader.field.border-width` | `--mx-file-uploader-field-border-width` | `border.width.1` | `1px` |
1843
+ | `file-uploader.field.padding.sm` | `--mx-file-uploader-field-padding-sm` | `space.2` | `0.5rem` |
1844
+ | `file-uploader.field.padding.md` | `--mx-file-uploader-field-padding-md` | `space.3` | `0.75rem` |
1845
+ | `file-uploader.field.padding.lg` | `--mx-file-uploader-field-padding-lg` | `space.4` | `1rem` |
1846
+ | `file-uploader.action.variant` | `--mx-file-uploader-action-variant` | `` | `ghost` |
1847
+ | `file-uploader.over.bg` | `--mx-file-uploader-over-bg` | `color.accent.subtle` | `#fbe6de` |
1848
+ | `file-uploader.over.border-color` | `--mx-file-uploader-over-border-color` | `color.accent.solid` | `#c24523` |
1849
+ | `file-uploader.select.padding-block` | `--mx-file-uploader-select-padding-block` | `space.1` | `0.25rem` |
1850
+ | `file-uploader.select.padding-inline` | `--mx-file-uploader-select-padding-inline` | `space.3` | `0.75rem` |
1851
+ | `file-uploader.select.radius` | `--mx-file-uploader-select-radius` | `radius.sm` | `0.25rem` |
1852
+ | `file-uploader.select.color` | `--mx-file-uploader-select-color` | `color.fg.primary` | `#1d1c1a` |
1853
+ | `file-uploader.select.font-weight` | `--mx-file-uploader-select-font-weight` | `font.weight.semibold` | `600` |
1854
+ | `file-uploader.select.bg` | `--mx-file-uploader-select-bg` | `color.fill.control.default` | `#f5f4f0` |
1855
+ | `file-uploader.select.border-width` | `--mx-file-uploader-select-border-width` | `border.width.1` | `1px` |
1856
+ | `file-uploader.select.border-color` | `--mx-file-uploader-select-border-color` | `color.stroke.control.strong` | `rgb(0 0 0 / 0.4458)` |
1857
+ | `file-uploader.select.hover.bg` | `--mx-file-uploader-select-hover-bg` | `color.fill.subtle.secondary` | `rgb(0 0 0 / 0.0373)` |
1858
+ | `file-uploader.select.hover.cursor` | `--mx-file-uploader-select-hover-cursor` | `` | `pointer` |
1859
+ | `file-uploader.select.pressed.bg` | `--mx-file-uploader-select-pressed-bg` | `color.fill.subtle.tertiary` | `rgb(0 0 0 / 0.0241)` |
1860
+ | `file-uploader.select.focus.glow` | `--mx-file-uploader-select-focus-glow` | `focus.ring.halo` | `0px 0px 0px 1px rgb(255 255 255 / 0.7)` |
1861
+ | `file-uploader.select.focus.outline-width` | `--mx-file-uploader-select-focus-outline-width` | `focus.ring.width` | `2px` |
1862
+ | `file-uploader.select.focus.outline-color` | `--mx-file-uploader-select-focus-outline-color` | `focus.ring.color` | `#1d1c1a` |
1863
+ | `file-uploader.select.focus.outline-offset` | `--mx-file-uploader-select-focus-outline-offset` | `focus.ring.offset` | `1px` |
1864
+ | `file-uploader.select.disabled.color` | `--mx-file-uploader-select-disabled-color` | `color.fg.disabled` | `#a2a098` |
1865
+ | `file-uploader.select.disabled.border-color` | `--mx-file-uploader-select-disabled-border-color` | `color.stroke.control.default` | `rgb(0 0 0 / 0.12)` |
1866
+ | `file-uploader.upload.padding-block` | `--mx-file-uploader-upload-padding-block` | `space.1` | `0.25rem` |
1867
+ | `file-uploader.upload.padding-inline` | `--mx-file-uploader-upload-padding-inline` | `space.3` | `0.75rem` |
1868
+ | `file-uploader.upload.radius` | `--mx-file-uploader-upload-radius` | `radius.sm` | `0.25rem` |
1869
+ | `file-uploader.upload.color` | `--mx-file-uploader-upload-color` | `color.accent.on-solid` | `#ffffff` |
1870
+ | `file-uploader.upload.font-weight` | `--mx-file-uploader-upload-font-weight` | `font.weight.semibold` | `600` |
1871
+ | `file-uploader.upload.bg` | `--mx-file-uploader-upload-bg` | `color.accent.solid` | `#c24523` |
1872
+ | `file-uploader.upload.border-width` | `--mx-file-uploader-upload-border-width` | `border.width.1` | `1px` |
1873
+ | `file-uploader.upload.border-color` | `--mx-file-uploader-upload-border-color` | `color.accent.solid` | `#c24523` |
1874
+ | `file-uploader.upload.hover.bg` | `--mx-file-uploader-upload-hover-bg` | `color.accent.solid-hover` | `#b43f20` |
1875
+ | `file-uploader.upload.hover.cursor` | `--mx-file-uploader-upload-hover-cursor` | `` | `pointer` |
1876
+ | `file-uploader.upload.pressed.bg` | `--mx-file-uploader-upload-pressed-bg` | `color.accent.solid-hover` | `#b43f20` |
1877
+ | `file-uploader.upload.focus.glow` | `--mx-file-uploader-upload-focus-glow` | `focus.ring.halo` | `0px 0px 0px 1px rgb(255 255 255 / 0.7)` |
1878
+ | `file-uploader.upload.focus.outline-width` | `--mx-file-uploader-upload-focus-outline-width` | `focus.ring.width` | `2px` |
1879
+ | `file-uploader.upload.focus.outline-color` | `--mx-file-uploader-upload-focus-outline-color` | `focus.ring.color` | `#1d1c1a` |
1880
+ | `file-uploader.upload.focus.outline-offset` | `--mx-file-uploader-upload-focus-outline-offset` | `focus.ring.offset` | `1px` |
1881
+ | `file-uploader.hint.color` | `--mx-file-uploader-hint-color` | `color.fg.secondary` | `#5e5c55` |
1882
+ | `file-uploader.list.margin-top` | `--mx-file-uploader-list-margin-top` | `space.2` | `0.5rem` |
1883
+ | `file-uploader.list.gap` | `--mx-file-uploader-list-gap` | `space.1` | `0.25rem` |
1884
+ | `file-uploader.item.padding-block` | `--mx-file-uploader-item-padding-block` | `space.1` | `0.25rem` |
1885
+ | `file-uploader.item.padding-inline` | `--mx-file-uploader-item-padding-inline` | `space.2` | `0.5rem` |
1886
+ | `file-uploader.item.radius` | `--mx-file-uploader-item-radius` | `radius.sm` | `0.25rem` |
1887
+ | `file-uploader.item.error.bg` | `--mx-file-uploader-item-error-bg` | `color.danger.subtle` | `#fde7e9` |
1888
+ | `file-uploader.item.invalid.bg` | `--mx-file-uploader-item-invalid-bg` | `color.danger.subtle` | `#fde7e9` |
1889
+ | `file-uploader.icon.icon` | `--mx-file-uploader-icon-icon` | `` | `var(--mx-icon-file)` |
1890
+ | `file-uploader.icon.bg` | `--mx-file-uploader-icon-bg` | `color.fg.secondary` | `#5e5c55` |
1891
+ | `file-uploader.icon.size` | `--mx-file-uploader-icon-size` | `` | `1.25rem` |
1892
+ | `file-uploader.name.color` | `--mx-file-uploader-name-color` | `color.fg.primary` | `#1d1c1a` |
1893
+ | `file-uploader.size.color` | `--mx-file-uploader-size-color` | `color.fg.secondary` | `#5e5c55` |
1894
+ | `file-uploader.size.font-size` | `--mx-file-uploader-size-font-size` | `font.size.caption` | `0.75rem` |
1895
+ | `file-uploader.state.color` | `--mx-file-uploader-state-color` | `color.fg.secondary` | `#5e5c55` |
1896
+ | `file-uploader.state.font-size` | `--mx-file-uploader-state-font-size` | `font.size.caption` | `0.75rem` |
1897
+ | `file-uploader.state.done.color` | `--mx-file-uploader-state-done-color` | `color.success.fg` | `#006402` |
1898
+ | `file-uploader.state.error.color` | `--mx-file-uploader-state-error-color` | `color.danger.fg` | `#b03659` |
1798
1899
  | `filterbuilder.indent` | `--mx-filterbuilder-indent` | `space.6` | `1.5rem` |
1799
1900
  | `filterbuilder.line-width` | `--mx-filterbuilder-line-width` | `border.width.1` | `1px` |
1800
1901
  | `filterbuilder.line-color` | `--mx-filterbuilder-line-color` | `color.stroke.divider` | `rgb(0 0 0 / 0.1)` |
@@ -1961,7 +2062,7 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
1961
2062
  | `listbox.field.frame.disabled.border-color` | `--mx-listbox-field-frame-disabled-border-color` | `color.stroke.control.default` | `rgb(0 0 0 / 0.12)` |
1962
2063
  | `listbox.field.indicator.radius` | `--mx-listbox-field-indicator-radius` | `` | `calc(0.375rem - 1px)` |
1963
2064
  | `listbox.field.indicator.focus.shadow` | `--mx-listbox-field-indicator-focus-shadow` | `` | `inset 0 -1px 0 0 #c24523` |
1964
- | `listbox.field.indicator.invalid-focus.shadow` | `--mx-listbox-field-indicator-invalid-focus-shadow` | `` | `inset 0 -1px 0 0 #b3261a` |
2065
+ | `listbox.field.indicator.invalid-focus.shadow` | `--mx-listbox-field-indicator-invalid-focus-shadow` | `` | `inset 0 -1px 0 0 #b03659` |
1965
2066
  | `listbox.field.indicator.readonly-focus.shadow` | `--mx-listbox-field-indicator-readonly-focus-shadow` | `` | `inset 0 -1px 0 0 rgb(0 0 0 / 0.4458)` |
1966
2067
  | `listbox.field.indicator.readonly-invalid-focus.shadow` | `--mx-listbox-field-indicator-readonly-invalid-focus-shadow` | `` | `inset 0 -1px 0 0 rgb(0 0 0 / 0.4458)` |
1967
2068
  | `listbox.search.variant` | `--mx-listbox-search-variant` | `` | `outline` |
@@ -1992,6 +2093,20 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
1992
2093
  | `listbox.keys.outline-offset` | `--mx-listbox-keys-outline-offset` | `` | `calc(-1 * 2px)` |
1993
2094
  | `listbox.idle.bg` | `--mx-listbox-idle-bg` | `` | `rgb(0 0 0 / 0)` |
1994
2095
  | `listbox.container.margin` | `--mx-listbox-container-margin` | `` | `initial` |
2096
+ | `load-panel.padding` | `--mx-load-panel-padding` | `space.4` | `1rem` |
2097
+ | `load-panel.gap` | `--mx-load-panel-gap` | `space.3` | `0.75rem` |
2098
+ | `load-panel.cancel.variant` | `--mx-load-panel-cancel-variant` | `` | `outline` |
2099
+ | `load-panel.shade.shaded.bg` | `--mx-load-panel-shade-shaded-bg` | `color.bg.smoke` | `rgb(0 0 0 / 0.3)` |
2100
+ | `load-panel.pane.shown.bg` | `--mx-load-panel-pane-shown-bg` | `color.bg.surface` | `#f8f7f3` |
2101
+ | `load-panel.pane.shown.border-width` | `--mx-load-panel-pane-shown-border-width` | `border.width.1` | `1px` |
2102
+ | `load-panel.pane.shown.border-color` | `--mx-load-panel-pane-shown-border-color` | `color.stroke.surface` | `rgb(117 117 117 / 0.4)` |
2103
+ | `load-panel.pane.shown.radius` | `--mx-load-panel-pane-shown-radius` | `radius.lg` | `0.625rem` |
2104
+ | `load-panel.pane.shown.shadow` | `--mx-load-panel-pane-shown-shadow` | `elevation.popup` | `0px 8px 16px 0px rgb(0 0 0 / 0.14), 0px 0px 2px 0px rgb(0 0 0 / 0.12)` |
2105
+ | `load-panel.pane.shown.padding-block` | `--mx-load-panel-pane-shown-padding-block` | `space.4` | `1rem` |
2106
+ | `load-panel.pane.shown.padding-inline` | `--mx-load-panel-pane-shown-padding-inline` | `space.5` | `1.25rem` |
2107
+ | `load-panel.pane.shown.min-width` | `--mx-load-panel-pane-shown-min-width` | `` | `10rem` |
2108
+ | `load-panel.message.color` | `--mx-load-panel-message-color` | `color.fg.primary` | `#1d1c1a` |
2109
+ | `load-panel.message.font-size` | `--mx-load-panel-message-font-size` | `font.size.body` | `0.875rem` |
1995
2110
  | `lookup.popup-width` | `--mx-lookup-popup-width` | `` | `28rem` |
1996
2111
  | `lookup.column-gap` | `--mx-lookup-column-gap` | `space.3` | `0.75rem` |
1997
2112
  | `lookup.header.padding-block` | `--mx-lookup-header-padding-block` | `space.1` | `0.25rem` |
@@ -2018,9 +2133,9 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
2018
2133
  | `menu.item.focus.outline-offset` | `--mx-menu-item-focus-outline-offset` | `focus.ring.offset` | `1px` |
2019
2134
  | `menu.item.disabled.color` | `--mx-menu-item-disabled-color` | `color.fg.disabled` | `#a2a098` |
2020
2135
  | `menu.item.accent.color` | `--mx-menu-item-accent-color` | `color.accent.fg` | `#983318` |
2021
- | `menu.item.success.color` | `--mx-menu-item-success-color` | `color.success.fg` | `#0c6a0c` |
2022
- | `menu.item.caution.color` | `--mx-menu-item-caution-color` | `color.caution.fg` | `#845000` |
2023
- | `menu.item.danger.color` | `--mx-menu-item-danger-color` | `color.danger.fg` | `#b3261a` |
2136
+ | `menu.item.success.color` | `--mx-menu-item-success-color` | `color.success.fg` | `#006402` |
2137
+ | `menu.item.caution.color` | `--mx-menu-item-caution-color` | `color.caution.fg` | `#754702` |
2138
+ | `menu.item.danger.color` | `--mx-menu-item-danger-color` | `color.danger.fg` | `#b03659` |
2024
2139
  | `menu.item.checked.bg` | `--mx-menu-item-checked-bg` | `` | `initial` |
2025
2140
  | `menu.item.first.radius-top` | `--mx-menu-item-first-radius-top` | `` | `initial` |
2026
2141
  | `menu.item.last.radius-bottom` | `--mx-menu-item-last-radius-bottom` | `` | `initial` |
@@ -2029,9 +2144,9 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
2029
2144
  | `menu.check.disabled.color` | `--mx-menu-check-disabled-color` | `` | `initial` |
2030
2145
  | `menu.icon.size` | `--mx-menu-icon-size` | `icon.size.md` | `1rem` |
2031
2146
  | `menu.icon.accent.color` | `--mx-menu-icon-accent-color` | `color.accent.fg` | `#983318` |
2032
- | `menu.icon.success.color` | `--mx-menu-icon-success-color` | `color.success.fg` | `#0c6a0c` |
2033
- | `menu.icon.caution.color` | `--mx-menu-icon-caution-color` | `color.caution.fg` | `#845000` |
2034
- | `menu.icon.danger.color` | `--mx-menu-icon-danger-color` | `color.danger.fg` | `#b3261a` |
2147
+ | `menu.icon.success.color` | `--mx-menu-icon-success-color` | `color.success.fg` | `#006402` |
2148
+ | `menu.icon.caution.color` | `--mx-menu-icon-caution-color` | `color.caution.fg` | `#754702` |
2149
+ | `menu.icon.danger.color` | `--mx-menu-icon-danger-color` | `color.danger.fg` | `#b03659` |
2035
2150
  | `menu.icon.color` | `--mx-menu-icon-color` | `` | `initial` |
2036
2151
  | `menu.icon.disabled.color` | `--mx-menu-icon-disabled-color` | `` | `initial` |
2037
2152
  | `menu.check-mark.icon` | `--mx-menu-check-mark-icon` | `` | `var(--mx-icon-check)` |
@@ -2098,6 +2213,36 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
2098
2213
  | `pagination.info.color` | `--mx-pagination-info-color` | `color.fg.secondary` | `#5e5c55` |
2099
2214
  | `pagination.info.font-size` | `--mx-pagination-info-font-size` | `font.size.body` | `0.875rem` |
2100
2215
  | `pagination.info.padding-inline` | `--mx-pagination-info-padding-inline` | `space.2` | `0.5rem` |
2216
+ | `popover.offset` | `--mx-popover-offset` | `space.2` | `0.5rem` |
2217
+ | `popover.enter-offset` | `--mx-popover-enter-offset` | `` | `4px` |
2218
+ | `popover.header-gap` | `--mx-popover-header-gap` | `space.2` | `0.5rem` |
2219
+ | `popover.close.variant` | `--mx-popover-close-variant` | `` | `ghost` |
2220
+ | `popover.surface.bg` | `--mx-popover-surface-bg` | `color.bg.surface` | `#f8f7f3` |
2221
+ | `popover.surface.border-width` | `--mx-popover-surface-border-width` | `border.width.1` | `1px` |
2222
+ | `popover.surface.border-color` | `--mx-popover-surface-border-color` | `color.stroke.surface` | `rgb(117 117 117 / 0.4)` |
2223
+ | `popover.surface.radius` | `--mx-popover-surface-radius` | `radius.lg` | `0.625rem` |
2224
+ | `popover.surface.shadow` | `--mx-popover-surface-shadow` | `elevation.popup` | `0px 8px 16px 0px rgb(0 0 0 / 0.14), 0px 0px 2px 0px rgb(0 0 0 / 0.12)` |
2225
+ | `popover.surface.color` | `--mx-popover-surface-color` | `color.fg.primary` | `#1d1c1a` |
2226
+ | `popover.surface.font-size` | `--mx-popover-surface-font-size` | `font.size.body` | `0.875rem` |
2227
+ | `popover.surface.line-height` | `--mx-popover-surface-line-height` | `font.line.body` | `1.25rem` |
2228
+ | `popover.surface.max-width` | `--mx-popover-surface-max-width` | `` | `24rem` |
2229
+ | `popover.surface.focus.glow` | `--mx-popover-surface-focus-glow` | `focus.ring.halo` | `0px 0px 0px 1px rgb(255 255 255 / 0.7)` |
2230
+ | `popover.surface.focus.outline-width` | `--mx-popover-surface-focus-outline-width` | `focus.ring.width` | `2px` |
2231
+ | `popover.surface.focus.outline-color` | `--mx-popover-surface-focus-outline-color` | `focus.ring.color` | `#1d1c1a` |
2232
+ | `popover.surface.focus.outline-offset` | `--mx-popover-surface-focus-outline-offset` | `focus.ring.offset` | `1px` |
2233
+ | `popover.arrow.display` | `--mx-popover-arrow-display` | `` | `block` |
2234
+ | `popover.arrow.size` | `--mx-popover-arrow-size` | `` | `0.75rem` |
2235
+ | `popover.arrow.bg` | `--mx-popover-arrow-bg` | `color.bg.surface` | `#f8f7f3` |
2236
+ | `popover.arrow.border-width` | `--mx-popover-arrow-border-width` | `border.width.1` | `1px` |
2237
+ | `popover.arrow.border-color` | `--mx-popover-arrow-border-color` | `color.stroke.surface` | `rgb(117 117 117 / 0.4)` |
2238
+ | `popover.header.padding-block` | `--mx-popover-header-padding-block` | `space.2` | `0.5rem` |
2239
+ | `popover.header.padding-start` | `--mx-popover-header-padding-start` | `space.3` | `0.75rem` |
2240
+ | `popover.header.padding-end` | `--mx-popover-header-padding-end` | `space.2` | `0.5rem` |
2241
+ | `popover.header.border-bottom-width` | `--mx-popover-header-border-bottom-width` | `border.width.1` | `1px` |
2242
+ | `popover.header.border-bottom-color` | `--mx-popover-header-border-bottom-color` | `color.stroke.divider` | `rgb(0 0 0 / 0.1)` |
2243
+ | `popover.title.font-weight` | `--mx-popover-title-font-weight` | `font.weight.semibold` | `600` |
2244
+ | `popover.title.color` | `--mx-popover-title-color` | `color.fg.primary` | `#1d1c1a` |
2245
+ | `popover.body.padding` | `--mx-popover-body-padding` | `space.3` | `0.75rem` |
2101
2246
  | `popup.offset` | `--mx-popup-offset` | `space.1` | `0.25rem` |
2102
2247
  | `popup.list-box.box.bg` | `--mx-popup-list-box-box-bg` | `` | `rgb(0 0 0 / 0)` |
2103
2248
  | `popup.list-box.box.hover.bg` | `--mx-popup-list-box-box-hover-bg` | `` | `rgb(0 0 0 / 0)` |
@@ -2176,11 +2321,11 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
2176
2321
  | `progress.accent-subtle` | `--mx-progress-accent-subtle` | `color.accent.subtle` | `#fbe6de` |
2177
2322
  | `progress.neutral` | `--mx-progress-neutral` | `color.fg.secondary` | `#5e5c55` |
2178
2323
  | `progress.neutral-subtle` | `--mx-progress-neutral-subtle` | `color.fill.subtle.secondary` | `rgb(0 0 0 / 0.0373)` |
2179
- | `progress.success` | `--mx-progress-success` | `color.success.fg` | `#0c6a0c` |
2324
+ | `progress.success` | `--mx-progress-success` | `color.success.fg` | `#006402` |
2180
2325
  | `progress.success-subtle` | `--mx-progress-success-subtle` | `color.success.subtle` | `#dff6dd` |
2181
- | `progress.caution` | `--mx-progress-caution` | `color.caution.fg` | `#845000` |
2326
+ | `progress.caution` | `--mx-progress-caution` | `color.caution.fg` | `#754702` |
2182
2327
  | `progress.caution-subtle` | `--mx-progress-caution-subtle` | `color.caution.subtle` | `#fff4ce` |
2183
- | `progress.danger` | `--mx-progress-danger` | `color.danger.solid` | `#b3261a` |
2328
+ | `progress.danger` | `--mx-progress-danger` | `color.danger.solid` | `#b03659` |
2184
2329
  | `progress.danger-subtle` | `--mx-progress-danger-subtle` | `color.danger.subtle` | `#fde7e9` |
2185
2330
  | `progress.track.bg` | `--mx-progress-track-bg` | `color.stroke.control.default` | `rgb(0 0 0 / 0.12)` |
2186
2331
  | `progress.track.radius` | `--mx-progress-track-radius` | `radius.full` | `9999px` |
@@ -2256,21 +2401,21 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
2256
2401
  | `radiogroup.circle.checked.bg` | `--mx-radiogroup-circle-checked-bg` | `color.accent.solid` | `#c24523` |
2257
2402
  | `radiogroup.circle.checked.border-color` | `--mx-radiogroup-circle-checked-border-color` | `color.accent.solid` | `#c24523` |
2258
2403
  | `radiogroup.circle.checked.shadow` | `--mx-radiogroup-circle-checked-shadow` | `` | `0 1px 0 rgb(0 0 0 / 0.3)` |
2259
- | `radiogroup.circle.invalid.border-color` | `--mx-radiogroup-circle-invalid-border-color` | `color.danger.solid` | `#b3261a` |
2260
- | `radiogroup.circle.invalid.shadow` | `--mx-radiogroup-circle-invalid-shadow` | `` | `inset 0px 1px 0px 0px rgb(255 255 255 / 0.7), 0 1px 0 #b3261a` |
2261
- | `radiogroup.circle.checked-invalid.shadow` | `--mx-radiogroup-circle-checked-invalid-shadow` | `` | `0 1px 0 #b3261a` |
2404
+ | `radiogroup.circle.invalid.border-color` | `--mx-radiogroup-circle-invalid-border-color` | `color.danger.solid` | `#b03659` |
2405
+ | `radiogroup.circle.invalid.shadow` | `--mx-radiogroup-circle-invalid-shadow` | `` | `inset 0px 1px 0px 0px rgb(255 255 255 / 0.7), 0 1px 0 #b03659` |
2406
+ | `radiogroup.circle.checked-invalid.shadow` | `--mx-radiogroup-circle-checked-invalid-shadow` | `` | `0 1px 0 #b03659` |
2262
2407
  | `radiogroup.circle.hover.bg` | `--mx-radiogroup-circle-hover-bg` | `color.fill.control.secondary` | `#ebeae5` |
2263
2408
  | `radiogroup.circle.hover.border-color` | `--mx-radiogroup-circle-hover-border-color` | `` | `initial` |
2264
2409
  | `radiogroup.circle.checked-hover.bg` | `--mx-radiogroup-circle-checked-hover-bg` | `color.accent.solid-hover` | `#b43f20` |
2265
2410
  | `radiogroup.circle.checked-hover.border-color` | `--mx-radiogroup-circle-checked-hover-border-color` | `color.accent.solid-hover` | `#b43f20` |
2266
- | `radiogroup.circle.invalid-hover.border-color` | `--mx-radiogroup-circle-invalid-hover-border-color` | `color.danger.solid` | `#b3261a` |
2411
+ | `radiogroup.circle.invalid-hover.border-color` | `--mx-radiogroup-circle-invalid-hover-border-color` | `color.danger.solid` | `#b03659` |
2267
2412
  | `radiogroup.circle.pressed.bg` | `--mx-radiogroup-circle-pressed-bg` | `color.fill.control.tertiary` | `#e1e0da` |
2268
2413
  | `radiogroup.circle.pressed.border-color` | `--mx-radiogroup-circle-pressed-border-color` | `color.stroke.control.strong` | `rgb(0 0 0 / 0.4458)` |
2269
2414
  | `radiogroup.circle.pressed.shadow` | `--mx-radiogroup-circle-pressed-shadow` | `` | `0 0 #0000` |
2270
2415
  | `radiogroup.circle.checked-pressed.bg` | `--mx-radiogroup-circle-checked-pressed-bg` | `color.accent.solid-hover` | `#b43f20` |
2271
2416
  | `radiogroup.circle.checked-pressed.border-color` | `--mx-radiogroup-circle-checked-pressed-border-color` | `color.accent.solid-hover` | `#b43f20` |
2272
2417
  | `radiogroup.circle.checked-pressed.shadow` | `--mx-radiogroup-circle-checked-pressed-shadow` | `` | `0 0 #0000` |
2273
- | `radiogroup.circle.invalid-pressed.border-color` | `--mx-radiogroup-circle-invalid-pressed-border-color` | `color.danger.solid` | `#b3261a` |
2418
+ | `radiogroup.circle.invalid-pressed.border-color` | `--mx-radiogroup-circle-invalid-pressed-border-color` | `color.danger.solid` | `#b03659` |
2274
2419
  | `radiogroup.circle.focus.outline-width` | `--mx-radiogroup-circle-focus-outline-width` | `focus.ring.width` | `2px` |
2275
2420
  | `radiogroup.circle.focus.outline-color` | `--mx-radiogroup-circle-focus-outline-color` | `focus.ring.color` | `#1d1c1a` |
2276
2421
  | `radiogroup.circle.focus.outline-offset` | `--mx-radiogroup-circle-focus-outline-offset` | `focus.ring.offset` | `1px` |
@@ -2536,9 +2681,9 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
2536
2681
  | `scheduler.cell.line-hour.border-start-color` | `--mx-scheduler-cell-line-hour-border-start-color` | `color.stroke.divider` | `rgb(0 0 0 / 0.1)` |
2537
2682
  | `scheduler.cell.line-day.border-start-color` | `--mx-scheduler-cell-line-day-border-start-color` | `color.stroke.control.strong` | `rgb(0 0 0 / 0.4458)` |
2538
2683
  | `scheduler.now.height` | `--mx-scheduler-now-height` | `border.width.2` | `2px` |
2539
- | `scheduler.now.bg` | `--mx-scheduler-now-bg` | `color.danger.solid` | `#b3261a` |
2684
+ | `scheduler.now.bg` | `--mx-scheduler-now-bg` | `color.danger.solid` | `#b03659` |
2540
2685
  | `scheduler.now-dot.size` | `--mx-scheduler-now-dot-size` | `` | `0px` |
2541
- | `scheduler.now-dot.bg` | `--mx-scheduler-now-dot-bg` | `color.danger.solid` | `#b3261a` |
2686
+ | `scheduler.now-dot.bg` | `--mx-scheduler-now-dot-bg` | `color.danger.solid` | `#b03659` |
2542
2687
  | `scheduler.now-dot.radius` | `--mx-scheduler-now-dot-radius` | `` | `50%` |
2543
2688
  | `scheduler.weekdays.bg` | `--mx-scheduler-weekdays-bg` | `color.bg.surface` | `#f8f7f3` |
2544
2689
  | `scheduler.weekdays.border-bottom-width` | `--mx-scheduler-weekdays-border-bottom-width` | `border.width.1` | `1px` |
@@ -2567,7 +2712,7 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
2567
2712
  | `scheduler.appointment.draft.cursor` | `--mx-scheduler-appointment-draft-cursor` | `` | `grabbing` |
2568
2713
  | `scheduler.appointment.invalid.outline-style` | `--mx-scheduler-appointment-invalid-outline-style` | `` | `dashed` |
2569
2714
  | `scheduler.appointment.invalid.outline-width` | `--mx-scheduler-appointment-invalid-outline-width` | `border.width.2` | `2px` |
2570
- | `scheduler.appointment.invalid.outline-color` | `--mx-scheduler-appointment-invalid-outline-color` | `color.danger.solid` | `#b3261a` |
2715
+ | `scheduler.appointment.invalid.outline-color` | `--mx-scheduler-appointment-invalid-outline-color` | `color.danger.solid` | `#b03659` |
2571
2716
  | `scheduler.appointment.invalid.cursor` | `--mx-scheduler-appointment-invalid-cursor` | `` | `not-allowed` |
2572
2717
  | `scheduler.appointment.saving.opacity` | `--mx-scheduler-appointment-saving-opacity` | `` | `0.7` |
2573
2718
  | `scheduler.appointment.saving.cursor` | `--mx-scheduler-appointment-saving-cursor` | `` | `progress` |
@@ -2660,7 +2805,7 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
2660
2805
  | `scheduler.state.bg` | `--mx-scheduler-state-bg` | `color.bg.surface` | `#f8f7f3` |
2661
2806
  | `scheduler.state.radius` | `--mx-scheduler-state-radius` | `radius.md` | `0.375rem` |
2662
2807
  | `scheduler.state.shadow` | `--mx-scheduler-state-shadow` | `elevation.popup` | `0px 8px 16px 0px rgb(0 0 0 / 0.14), 0px 0px 2px 0px rgb(0 0 0 / 0.12)` |
2663
- | `scheduler.state.danger.color` | `--mx-scheduler-state-danger-color` | `color.danger.fg` | `#b3261a` |
2808
+ | `scheduler.state.danger.color` | `--mx-scheduler-state-danger-color` | `color.danger.fg` | `#b03659` |
2664
2809
  | `scheduler.timeline-row.border-top-width` | `--mx-scheduler-timeline-row-border-top-width` | `border.width.1` | `1px` |
2665
2810
  | `scheduler.timeline-row.border-color` | `--mx-scheduler-timeline-row-border-color` | `color.stroke.divider` | `rgb(0 0 0 / 0.1)` |
2666
2811
  | `scheduler.timeline-row.first.border-top-width` | `--mx-scheduler-timeline-row-first-border-top-width` | `` | `0px` |
@@ -2778,6 +2923,17 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
2778
2923
  | `scheduler.swipe-icon.height` | `--mx-scheduler-swipe-icon-height` | `icon.size.md` | `1rem` |
2779
2924
  | `scheduler.swipe-icon.icon` | `--mx-scheduler-swipe-icon-icon` | `` | `var(--mx-icon-chevron-end)` |
2780
2925
  | `scheduler.swipe-icon.previous.icon` | `--mx-scheduler-swipe-icon-previous-icon` | `` | `var(--mx-icon-chevron-start)` |
2926
+ | `scroll-view.panel-height` | `--mx-scroll-view-panel-height` | `` | `3rem` |
2927
+ | `scroll-view.panel-gap` | `--mx-scroll-view-panel-gap` | `space.2` | `0.5rem` |
2928
+ | `scroll-view.box.focus.glow` | `--mx-scroll-view-box-focus-glow` | `focus.ring.halo` | `0px 0px 0px 1px rgb(255 255 255 / 0.7)` |
2929
+ | `scroll-view.box.focus.outline-width` | `--mx-scroll-view-box-focus-outline-width` | `focus.ring.width` | `2px` |
2930
+ | `scroll-view.box.focus.outline-color` | `--mx-scroll-view-box-focus-outline-color` | `focus.ring.color` | `#1d1c1a` |
2931
+ | `scroll-view.box.focus.outline-offset` | `--mx-scroll-view-box-focus-outline-offset` | `focus.ring.offset` | `1px` |
2932
+ | `scroll-view.pull.color` | `--mx-scroll-view-pull-color` | `color.fg.secondary` | `#5e5c55` |
2933
+ | `scroll-view.pull.font-size` | `--mx-scroll-view-pull-font-size` | `font.size.caption` | `0.75rem` |
2934
+ | `scroll-view.pull.refreshing.color` | `--mx-scroll-view-pull-refreshing-color` | `color.fg.primary` | `#1d1c1a` |
2935
+ | `scroll-view.bottom.color` | `--mx-scroll-view-bottom-color` | `color.fg.secondary` | `#5e5c55` |
2936
+ | `scroll-view.bottom.font-size` | `--mx-scroll-view-bottom-font-size` | `font.size.caption` | `0.75rem` |
2781
2937
  | `sheet.font-family` | `--mx-sheet-font-family` | `font.family.sans` | `Archivo, system-ui, -apple-system, 'Helvetica Neue', Arial, sans-serif` |
2782
2938
  | `sheet.inset` | `--mx-sheet-inset` | `` | `0px` |
2783
2939
  | `sheet.top-gap` | `--mx-sheet-top-gap` | `space.10` | `2.5rem` |
@@ -2964,6 +3120,20 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
2964
3120
  | `slider.stop.radius` | `--mx-slider-stop-radius` | `` | `initial` |
2965
3121
  | `slider.stop.bg` | `--mx-slider-stop-bg` | `` | `initial` |
2966
3122
  | `slider.stop.active.bg` | `--mx-slider-stop-active-bg` | `` | `initial` |
3123
+ | `sortable.gap` | `--mx-sortable-gap` | `space.1` | `0.25rem` |
3124
+ | `sortable.container.target.bg` | `--mx-sortable-container-target-bg` | `color.accent.subtle` | `#fbe6de` |
3125
+ | `sortable.item.sortable.cursor` | `--mx-sortable-item-sortable-cursor` | `` | `grab` |
3126
+ | `sortable.item.dragging.opacity` | `--mx-sortable-item-dragging-opacity` | `` | `0.4` |
3127
+ | `sortable.item.focus.glow` | `--mx-sortable-item-focus-glow` | `focus.ring.halo` | `0px 0px 0px 1px rgb(255 255 255 / 0.7)` |
3128
+ | `sortable.item.focus.outline-width` | `--mx-sortable-item-focus-outline-width` | `focus.ring.width` | `2px` |
3129
+ | `sortable.item.focus.outline-color` | `--mx-sortable-item-focus-outline-color` | `focus.ring.color` | `#1d1c1a` |
3130
+ | `sortable.item.focus.outline-offset` | `--mx-sortable-item-focus-outline-offset` | `focus.ring.offset` | `1px` |
3131
+ | `sortable.line.height` | `--mx-sortable-line-height` | `` | `2px` |
3132
+ | `sortable.line.radius` | `--mx-sortable-line-radius` | `radius.full` | `9999px` |
3133
+ | `sortable.line.bg` | `--mx-sortable-line-bg` | `color.accent.solid` | `#c24523` |
3134
+ | `sortable.ghost.radius` | `--mx-sortable-ghost-radius` | `radius.md` | `0.375rem` |
3135
+ | `sortable.ghost.shadow` | `--mx-sortable-ghost-shadow` | `elevation.popup` | `0px 8px 16px 0px rgb(0 0 0 / 0.14), 0px 0px 2px 0px rgb(0 0 0 / 0.12)` |
3136
+ | `sortable.ghost.opacity` | `--mx-sortable-ghost-opacity` | `` | `0.9` |
2967
3137
  | `spinner.gap` | `--mx-spinner-gap` | `space.2` | `0.5rem` |
2968
3138
  | `spinner.cover-padding` | `--mx-spinner-cover-padding` | `space.4` | `1rem` |
2969
3139
  | `spinner.cover-background` | `--mx-spinner-cover-background` | `color.bg.glass` | `rgb(248 247 243 / 0.78)` |
@@ -2979,9 +3149,9 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
2979
3149
  | `spinner.track-color` | `--mx-spinner-track-color` | `color.stroke.control.default` | `rgb(0 0 0 / 0.12)` |
2980
3150
  | `spinner.accent` | `--mx-spinner-accent` | `color.accent.solid` | `#c24523` |
2981
3151
  | `spinner.neutral` | `--mx-spinner-neutral` | `color.fg.secondary` | `#5e5c55` |
2982
- | `spinner.success` | `--mx-spinner-success` | `color.success.fg` | `#0c6a0c` |
2983
- | `spinner.caution` | `--mx-spinner-caution` | `color.caution.fg` | `#845000` |
2984
- | `spinner.danger` | `--mx-spinner-danger` | `color.danger.solid` | `#b3261a` |
3152
+ | `spinner.success` | `--mx-spinner-success` | `color.success.fg` | `#006402` |
3153
+ | `spinner.caution` | `--mx-spinner-caution` | `color.caution.fg` | `#754702` |
3154
+ | `spinner.danger` | `--mx-spinner-danger` | `color.danger.solid` | `#b03659` |
2985
3155
  | `spinner.radius` | `--mx-spinner-radius` | `radius.full` | `9999px` |
2986
3156
  | `spinner.cover-fg` | `--mx-spinner-cover-fg` | `color.fg.primary` | `#1d1c1a` |
2987
3157
  | `spinner.focus-width` | `--mx-spinner-focus-width` | `focus.ring.width` | `2px` |
@@ -3008,6 +3178,63 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
3008
3178
  | `spinner.shape.display` | `--mx-spinner-shape-display` | `` | `initial` |
3009
3179
  | `spinner.shape.contained.bg` | `--mx-spinner-shape-contained-bg` | `` | `initial` |
3010
3180
  | `spinner.shape.contained.scale` | `--mx-spinner-shape-contained-scale` | `` | `initial` |
3181
+ | `stepper.font-size.sm` | `--mx-stepper-font-size-sm` | `font.size.caption` | `0.75rem` |
3182
+ | `stepper.font-size.md` | `--mx-stepper-font-size-md` | `font.size.body` | `0.875rem` |
3183
+ | `stepper.font-size.lg` | `--mx-stepper-font-size-lg` | `` | `1rem` |
3184
+ | `stepper.description-font-size` | `--mx-stepper-description-font-size` | `font.size.caption` | `0.75rem` |
3185
+ | `stepper.gap` | `--mx-stepper-gap` | `space.2` | `0.5rem` |
3186
+ | `stepper.line-gap` | `--mx-stepper-line-gap` | `space.2` | `0.5rem` |
3187
+ | `stepper.line-min-length` | `--mx-stepper-line-min-length` | `` | `1rem` |
3188
+ | `stepper.size.sm` | `--mx-stepper-size-sm` | `` | `1.5rem` |
3189
+ | `stepper.size.md` | `--mx-stepper-size-md` | `` | `1.75rem` |
3190
+ | `stepper.size.lg` | `--mx-stepper-size-lg` | `` | `2.25rem` |
3191
+ | `stepper.padding.sm` | `--mx-stepper-padding-sm` | `` | `0.25rem` |
3192
+ | `stepper.padding.md` | `--mx-stepper-padding-md` | `` | `0.375rem` |
3193
+ | `stepper.padding.lg` | `--mx-stepper-padding-lg` | `` | `0.5rem` |
3194
+ | `stepper.step.radius` | `--mx-stepper-step-radius` | `radius.sm` | `0.25rem` |
3195
+ | `stepper.step.color` | `--mx-stepper-step-color` | `color.fg.secondary` | `#5e5c55` |
3196
+ | `stepper.step.hover.bg` | `--mx-stepper-step-hover-bg` | `color.fill.subtle.secondary` | `rgb(0 0 0 / 0.0373)` |
3197
+ | `stepper.step.hover.cursor` | `--mx-stepper-step-hover-cursor` | `` | `pointer` |
3198
+ | `stepper.step.pressed.bg` | `--mx-stepper-step-pressed-bg` | `color.fill.subtle.tertiary` | `rgb(0 0 0 / 0.0241)` |
3199
+ | `stepper.step.focus.glow` | `--mx-stepper-step-focus-glow` | `focus.ring.halo` | `0px 0px 0px 1px rgb(255 255 255 / 0.7)` |
3200
+ | `stepper.step.focus.outline-width` | `--mx-stepper-step-focus-outline-width` | `focus.ring.width` | `2px` |
3201
+ | `stepper.step.focus.outline-color` | `--mx-stepper-step-focus-outline-color` | `focus.ring.color` | `#1d1c1a` |
3202
+ | `stepper.step.focus.outline-offset` | `--mx-stepper-step-focus-outline-offset` | `focus.ring.offset` | `1px` |
3203
+ | `stepper.step.disabled.color` | `--mx-stepper-step-disabled-color` | `color.fg.disabled` | `#a2a098` |
3204
+ | `stepper.step.current.color` | `--mx-stepper-step-current-color` | `color.fg.primary` | `#1d1c1a` |
3205
+ | `stepper.step.done.color` | `--mx-stepper-step-done-color` | `color.fg.primary` | `#1d1c1a` |
3206
+ | `stepper.indicator.radius` | `--mx-stepper-indicator-radius` | `radius.full` | `9999px` |
3207
+ | `stepper.indicator.bg` | `--mx-stepper-indicator-bg` | `color.fill.control.default` | `#f5f4f0` |
3208
+ | `stepper.indicator.border-width` | `--mx-stepper-indicator-border-width` | `` | `1px` |
3209
+ | `stepper.indicator.border-color` | `--mx-stepper-indicator-border-color` | `color.stroke.control.strong` | `rgb(0 0 0 / 0.4458)` |
3210
+ | `stepper.indicator.color` | `--mx-stepper-indicator-color` | `color.fg.secondary` | `#5e5c55` |
3211
+ | `stepper.indicator.font-size` | `--mx-stepper-indicator-font-size` | `font.size.caption` | `0.75rem` |
3212
+ | `stepper.indicator.font-weight` | `--mx-stepper-indicator-font-weight` | `font.weight.semibold` | `600` |
3213
+ | `stepper.indicator.current.bg` | `--mx-stepper-indicator-current-bg` | `color.accent.solid` | `#c24523` |
3214
+ | `stepper.indicator.current.border-color` | `--mx-stepper-indicator-current-border-color` | `color.accent.solid` | `#c24523` |
3215
+ | `stepper.indicator.current.color` | `--mx-stepper-indicator-current-color` | `color.accent.on-solid` | `#ffffff` |
3216
+ | `stepper.indicator.done.bg` | `--mx-stepper-indicator-done-bg` | `color.accent.solid` | `#c24523` |
3217
+ | `stepper.indicator.done.border-color` | `--mx-stepper-indicator-done-border-color` | `color.accent.solid` | `#c24523` |
3218
+ | `stepper.indicator.done.color` | `--mx-stepper-indicator-done-color` | `color.accent.on-solid` | `#ffffff` |
3219
+ | `stepper.indicator.error.bg` | `--mx-stepper-indicator-error-bg` | `color.danger.solid` | `#b03659` |
3220
+ | `stepper.indicator.error.border-color` | `--mx-stepper-indicator-error-border-color` | `color.danger.solid` | `#b03659` |
3221
+ | `stepper.indicator.error.color` | `--mx-stepper-indicator-error-color` | `color.danger.on-solid` | `#ffffff` |
3222
+ | `stepper.indicator.disabled.border-color` | `--mx-stepper-indicator-disabled-border-color` | `color.stroke.control.default` | `rgb(0 0 0 / 0.12)` |
3223
+ | `stepper.indicator.disabled.color` | `--mx-stepper-indicator-disabled-color` | `color.fg.disabled` | `#a2a098` |
3224
+ | `stepper.indicator.disabled.bg` | `--mx-stepper-indicator-disabled-bg` | `` | `initial` |
3225
+ | `stepper.mark.done.icon` | `--mx-stepper-mark-done-icon` | `` | `var(--mx-icon-check)` |
3226
+ | `stepper.mark.done.bg` | `--mx-stepper-mark-done-bg` | `color.accent.on-solid` | `#ffffff` |
3227
+ | `stepper.mark.error.icon` | `--mx-stepper-mark-error-icon` | `` | `var(--mx-icon-danger)` |
3228
+ | `stepper.mark.error.bg` | `--mx-stepper-mark-error-bg` | `color.danger.on-solid` | `#ffffff` |
3229
+ | `stepper.label.current.font-weight` | `--mx-stepper-label-current-font-weight` | `font.weight.semibold` | `600` |
3230
+ | `stepper.label.error.color` | `--mx-stepper-label-error-color` | `color.danger.fg` | `#b03659` |
3231
+ | `stepper.description.color` | `--mx-stepper-description-color` | `color.fg.secondary` | `#5e5c55` |
3232
+ | `stepper.description.disabled.color` | `--mx-stepper-description-disabled-color` | `color.fg.disabled` | `#a2a098` |
3233
+ | `stepper.note.color` | `--mx-stepper-note-color` | `color.fg.secondary` | `#5e5c55` |
3234
+ | `stepper.line.height` | `--mx-stepper-line-height` | `` | `2px` |
3235
+ | `stepper.line.bg` | `--mx-stepper-line-bg` | `color.stroke.control.secondary` | `rgb(0 0 0 / 0.2)` |
3236
+ | `stepper.line.done.bg` | `--mx-stepper-line-done-bg` | `color.accent.solid` | `#c24523` |
3237
+ | `stepper.line.radius` | `--mx-stepper-line-radius` | `` | `initial` |
3011
3238
  | `switch.thumb-inset` | `--mx-switch-thumb-inset` | `space.1` | `0.25rem` |
3012
3239
  | `switch.gap` | `--mx-switch-gap` | `space.2` | `0.5rem` |
3013
3240
  | `switch.text-padding` | `--mx-switch-text-padding` | `space.2` | `0.5rem` |
@@ -3042,7 +3269,7 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
3042
3269
  | `switch.track.radius` | `--mx-switch-track-radius` | `radius.full` | `9999px` |
3043
3270
  | `switch.track.checked.bg` | `--mx-switch-track-checked-bg` | `color.accent.solid` | `#c24523` |
3044
3271
  | `switch.track.checked.border-color` | `--mx-switch-track-checked-border-color` | `color.accent.solid` | `#c24523` |
3045
- | `switch.track.invalid.border-color` | `--mx-switch-track-invalid-border-color` | `color.danger.solid` | `#b3261a` |
3272
+ | `switch.track.invalid.border-color` | `--mx-switch-track-invalid-border-color` | `color.danger.solid` | `#b03659` |
3046
3273
  | `switch.track.hover.bg` | `--mx-switch-track-hover-bg` | `color.fill.control.secondary` | `#ebeae5` |
3047
3274
  | `switch.track.checked-hover.bg` | `--mx-switch-track-checked-hover-bg` | `color.accent.solid-hover` | `#b43f20` |
3048
3275
  | `switch.track.pressed.bg` | `--mx-switch-track-pressed-bg` | `color.fill.control.secondary` | `#ebeae5` |
@@ -3190,9 +3417,9 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
3190
3417
  | `tabdocs.indicator.selected.bg` | `--mx-tabdocs-indicator-selected-bg` | `color.stroke.control.strong` | `rgb(0 0 0 / 0.4458)` |
3191
3418
  | `tabdocs.indicator.active.bg` | `--mx-tabdocs-indicator-active-bg` | `color.accent.solid` | `#c24523` |
3192
3419
  | `tabdocs.indicator.title.bg` | `--mx-tabdocs-indicator-title-bg` | `` | `initial` |
3193
- | `tabdocs.title.warning.color` | `--mx-tabdocs-title-warning-color` | `color.caution.fg` | `#845000` |
3194
- | `tabdocs.title.danger.color` | `--mx-tabdocs-title-danger-color` | `color.danger.fg` | `#b3261a` |
3195
- | `tabdocs.title.success.color` | `--mx-tabdocs-title-success-color` | `color.success.fg` | `#0c6a0c` |
3420
+ | `tabdocs.title.warning.color` | `--mx-tabdocs-title-warning-color` | `color.caution.fg` | `#754702` |
3421
+ | `tabdocs.title.danger.color` | `--mx-tabdocs-title-danger-color` | `color.danger.fg` | `#b03659` |
3422
+ | `tabdocs.title.success.color` | `--mx-tabdocs-title-success-color` | `color.success.fg` | `#006402` |
3196
3423
  | `tabdocs.title.accent.color` | `--mx-tabdocs-title-accent-color` | `color.accent.fg` | `#983318` |
3197
3424
  | `tabdocs.letter.font-weight` | `--mx-tabdocs-letter-font-weight` | `font.weight.semibold` | `600` |
3198
3425
  | `tabdocs.pin.radius` | `--mx-tabdocs-pin-radius` | `radius.sm` | `0.25rem` |
@@ -3213,16 +3440,16 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
3213
3440
  | `tabdocs.badge.dot.padding-inline` | `--mx-tabdocs-badge-dot-padding-inline` | `` | `0px` |
3214
3441
  | `tabdocs.badge.dot.bg` | `--mx-tabdocs-badge-dot-bg` | `color.accent.solid` | `#c24523` |
3215
3442
  | `tabdocs.badge.warning.bg` | `--mx-tabdocs-badge-warning-bg` | `color.caution.subtle` | `#fff4ce` |
3216
- | `tabdocs.badge.warning.color` | `--mx-tabdocs-badge-warning-color` | `color.caution.fg` | `#845000` |
3443
+ | `tabdocs.badge.warning.color` | `--mx-tabdocs-badge-warning-color` | `color.caution.fg` | `#754702` |
3217
3444
  | `tabdocs.badge.danger.bg` | `--mx-tabdocs-badge-danger-bg` | `color.danger.subtle` | `#fde7e9` |
3218
- | `tabdocs.badge.danger.color` | `--mx-tabdocs-badge-danger-color` | `color.danger.fg` | `#b3261a` |
3445
+ | `tabdocs.badge.danger.color` | `--mx-tabdocs-badge-danger-color` | `color.danger.fg` | `#b03659` |
3219
3446
  | `tabdocs.badge.success.bg` | `--mx-tabdocs-badge-success-bg` | `color.success.subtle` | `#dff6dd` |
3220
- | `tabdocs.badge.success.color` | `--mx-tabdocs-badge-success-color` | `color.success.fg` | `#0c6a0c` |
3447
+ | `tabdocs.badge.success.color` | `--mx-tabdocs-badge-success-color` | `color.success.fg` | `#006402` |
3221
3448
  | `tabdocs.badge.accent.bg` | `--mx-tabdocs-badge-accent-bg` | `color.accent.subtle` | `#fbe6de` |
3222
3449
  | `tabdocs.badge.accent.color` | `--mx-tabdocs-badge-accent-color` | `color.accent.fg` | `#983318` |
3223
- | `tabdocs.badge.warning-dot.bg` | `--mx-tabdocs-badge-warning-dot-bg` | `color.caution.fg` | `#845000` |
3224
- | `tabdocs.badge.danger-dot.bg` | `--mx-tabdocs-badge-danger-dot-bg` | `color.danger.fg` | `#b3261a` |
3225
- | `tabdocs.badge.success-dot.bg` | `--mx-tabdocs-badge-success-dot-bg` | `color.success.fg` | `#0c6a0c` |
3450
+ | `tabdocs.badge.warning-dot.bg` | `--mx-tabdocs-badge-warning-dot-bg` | `color.caution.fg` | `#754702` |
3451
+ | `tabdocs.badge.danger-dot.bg` | `--mx-tabdocs-badge-danger-dot-bg` | `color.danger.fg` | `#b03659` |
3452
+ | `tabdocs.badge.success-dot.bg` | `--mx-tabdocs-badge-success-dot-bg` | `color.success.fg` | `#006402` |
3226
3453
  | `tabdocs.badge.accent-dot.bg` | `--mx-tabdocs-badge-accent-dot-bg` | `color.accent.fg` | `#983318` |
3227
3454
  | `tabdocs.close.radius` | `--mx-tabdocs-close-radius` | `radius.sm` | `0.25rem` |
3228
3455
  | `tabdocs.close.color` | `--mx-tabdocs-close-color` | `color.fg.secondary` | `#5e5c55` |
@@ -3624,9 +3851,9 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
3624
3851
  | `toast.surface.danger.bg` | `--mx-toast-surface-danger-bg` | `` | `initial` |
3625
3852
  | `toast.icon.size` | `--mx-toast-icon-size` | `icon.size.md` | `1rem` |
3626
3853
  | `toast.icon.color` | `--mx-toast-icon-color` | `color.fg.secondary` | `#5e5c55` |
3627
- | `toast.icon.success.color` | `--mx-toast-icon-success-color` | `color.success.fg` | `#0c6a0c` |
3628
- | `toast.icon.caution.color` | `--mx-toast-icon-caution-color` | `color.caution.fg` | `#845000` |
3629
- | `toast.icon.danger.color` | `--mx-toast-icon-danger-color` | `color.danger.fg` | `#b3261a` |
3854
+ | `toast.icon.success.color` | `--mx-toast-icon-success-color` | `color.success.fg` | `#006402` |
3855
+ | `toast.icon.caution.color` | `--mx-toast-icon-caution-color` | `color.caution.fg` | `#754702` |
3856
+ | `toast.icon.danger.color` | `--mx-toast-icon-danger-color` | `color.danger.fg` | `#b03659` |
3630
3857
  | `toast.mark.icon` | `--mx-toast-mark-icon` | `` | `var(--mx-icon-info)` |
3631
3858
  | `toast.mark.success.icon` | `--mx-toast-mark-success-icon` | `` | `var(--mx-icon-success)` |
3632
3859
  | `toast.mark.caution.icon` | `--mx-toast-mark-caution-icon` | `` | `var(--mx-icon-caution)` |
@@ -3755,7 +3982,7 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
3755
3982
  | `treeview.mark.size` | `--mx-treeview-mark-size` | `icon.size.sm` | `0.75rem` |
3756
3983
  | `treeview.icon.size` | `--mx-treeview-icon-size` | `icon.size.md` | `1rem` |
3757
3984
  | `treeview.error.gap` | `--mx-treeview-error-gap` | `space.1` | `0.25rem` |
3758
- | `treeview.error.color` | `--mx-treeview-error-color` | `color.danger.fg` | `#b3261a` |
3985
+ | `treeview.error.color` | `--mx-treeview-error-color` | `color.danger.fg` | `#b03659` |
3759
3986
  | `treeview.error.font-size` | `--mx-treeview-error-font-size` | `font.size.caption` | `0.75rem` |
3760
3987
  | `treeview.retry.padding-inline` | `--mx-treeview-retry-padding-inline` | `space.1` | `0.25rem` |
3761
3988
  | `treeview.retry.radius` | `--mx-treeview-retry-radius` | `radius.sm` | `0.25rem` |
@@ -3837,9 +4064,18 @@ Source: `tokens/schema/*.json` (names and types) and `tokens/languages/<language
3837
4064
  | `window.message.gap` | `--mx-window-message-gap` | `space.3` | `0.75rem` |
3838
4065
  | `window.message-icon.size` | `--mx-window-message-icon-size` | `icon.size.lg` | `1.25rem` |
3839
4066
  | `window.message-icon.color` | `--mx-window-message-icon-color` | `color.accent.fg` | `#983318` |
3840
- | `window.message-icon.success.color` | `--mx-window-message-icon-success-color` | `color.success.fg` | `#0c6a0c` |
3841
- | `window.message-icon.caution.color` | `--mx-window-message-icon-caution-color` | `color.caution.fg` | `#845000` |
3842
- | `window.message-icon.danger.color` | `--mx-window-message-icon-danger-color` | `color.danger.fg` | `#b3261a` |
4067
+ | `window.message-icon.success.color` | `--mx-window-message-icon-success-color` | `color.success.fg` | `#006402` |
4068
+ | `window.message-icon.caution.color` | `--mx-window-message-icon-caution-color` | `color.caution.fg` | `#754702` |
4069
+ | `window.message-icon.danger.color` | `--mx-window-message-icon-danger-color` | `color.danger.fg` | `#b03659` |
4070
+ | `wizard.gap` | `--mx-wizard-gap` | `space.4` | `1rem` |
4071
+ | `wizard.bar-gap` | `--mx-wizard-bar-gap` | `space.2` | `0.5rem` |
4072
+ | `wizard.rail-width` | `--mx-wizard-rail-width` | `` | `14rem` |
4073
+ | `wizard.previous.variant` | `--mx-wizard-previous-variant` | `` | `outline` |
4074
+ | `wizard.next.variant` | `--mx-wizard-next-variant` | `` | `solid` |
4075
+ | `wizard.next.tone` | `--mx-wizard-next-tone` | `` | `accent` |
4076
+ | `wizard.bar.padding-top` | `--mx-wizard-bar-padding-top` | `space.3` | `0.75rem` |
4077
+ | `wizard.bar.border-top-width` | `--mx-wizard-bar-border-top-width` | `` | `1px` |
4078
+ | `wizard.bar.border-top-color` | `--mx-wizard-bar-border-top-color` | `color.stroke.divider` | `rgb(0 0 0 / 0.1)` |
3843
4079
 
3844
4080
  ## Semantic ({semantic.length} per theme)
3845
4081
 
@@ -3854,13 +4090,13 @@ The theme's language, the only layer a theme redefines — switch the theme abov
3854
4090
  | `color.accent.fg` | `--mx-color-accent-fg` | `#983318` | `#ffb89c` | `#c7c7ff` |
3855
4091
  | `color.accent.subtle` | `--mx-color-accent-subtle` | `#fbe6de` | `#45271d` | `#000000` |
3856
4092
  | `color.accent.on-subtle` | `--mx-color-accent-on-subtle` | `#983318` | `#ffb89c` | `#c7c7ff` |
3857
- | `color.success.fg` | `--mx-color-success-fg` | `#0c6a0c` | `#6ccb5f` | `#3ff23f` |
4093
+ | `color.success.fg` | `--mx-color-success-fg` | `#006402` | `#6dc43a` | `#3ff23f` |
3858
4094
  | `color.success.subtle` | `--mx-color-success-subtle` | `#dff6dd` | `#393d1b` | `#000000` |
3859
- | `color.success.solid` | `--mx-color-success-solid` | `#0c6a0c` | `#6ccb5f` | `#3ff23f` |
4095
+ | `color.success.solid` | `--mx-color-success-solid` | `#006402` | `#6dc43a` | `#3ff23f` |
3860
4096
  | `color.success.on-solid` | `--mx-color-success-on-solid` | `#ffffff` | `#000000` | `#000000` |
3861
- | `color.caution.fg` | `--mx-color-caution-fg` | `#845000` | `#fce100` | `#ffee32` |
4097
+ | `color.caution.fg` | `--mx-color-caution-fg` | `#754702` | `#fce100` | `#ffee32` |
3862
4098
  | `color.caution.subtle` | `--mx-color-caution-subtle` | `#fff4ce` | `#433519` | `#000000` |
3863
- | `color.caution.solid` | `--mx-color-caution-solid` | `#845000` | `#fce100` | `#ffee32` |
4099
+ | `color.caution.solid` | `--mx-color-caution-solid` | `#754702` | `#fce100` | `#ffee32` |
3864
4100
  | `color.caution.on-solid` | `--mx-color-caution-on-solid` | `#ffffff` | `#000000` | `#000000` |
3865
4101
  | `color.bg.canvas` | `--mx-color-bg-canvas` | `#e1e0da` | `#232220` | `#000000` |
3866
4102
  | `color.bg.layer` | `--mx-color-bg-layer` | `#ebeae5` | `#2b2a27` | `#000000` |
@@ -3902,10 +4138,10 @@ The theme's language, the only layer a theme redefines — switch the theme abov
3902
4138
  | `color.stroke.surface` | `--mx-color-stroke-surface` | `rgb(117 117 117 / 0.4)` | `rgb(117 117 117 / 0.4)` | `#ffffff` |
3903
4139
  | `color.stroke.divider` | `--mx-color-stroke-divider` | `rgb(0 0 0 / 0.1)` | `rgb(255 255 255 / 0.0837)` | `#ffffff` |
3904
4140
  | `color.highlight.control` | `--mx-color-highlight-control` | `rgb(255 255 255 / 0.7)` | `rgb(255 255 255 / 0.06)` | `#000000` |
3905
- | `color.danger.solid` | `--mx-color-danger-solid` | `#b3261a` | `#ff99a4` | `#ff8080` |
3906
- | `color.danger.solid-hover` | `--mx-color-danger-solid-hover` | `#c42b1c` | `#e98d97` | `#ffa0a0` |
4141
+ | `color.danger.solid` | `--mx-color-danger-solid` | `#b03659` | `#ff99a4` | `#ff8080` |
4142
+ | `color.danger.solid-hover` | `--mx-color-danger-solid-hover` | `#c13b61` | `#e98d97` | `#ffa0a0` |
3907
4143
  | `color.danger.on-solid` | `--mx-color-danger-on-solid` | `#ffffff` | `#000000` | `#000000` |
3908
- | `color.danger.fg` | `--mx-color-danger-fg` | `#b3261a` | `#ff99a4` | `#ffbcbc` |
4144
+ | `color.danger.fg` | `--mx-color-danger-fg` | `#b03659` | `#ff99a4` | `#ffbcbc` |
3909
4145
  | `color.danger.subtle` | `--mx-color-danger-subtle` | `#fde7e9` | `#442726` | `#000000` |
3910
4146
  | `color.info.subtle` | `--mx-color-info-subtle` | `#ebeae5` | `#2b2a27` | `#000000` |
3911
4147
  | `color.info.solid` | `--mx-color-info-solid` | `#5e5c55` | `#d0cfc9` | `#ffffff` |
@@ -4043,17 +4279,17 @@ The shared palette and scales, the same in every design language. Themes and com
4043
4279
  | `color.accent.light3` | color | `--mx-color-accent-light3` | `#ffb89c` |
4044
4280
  | `color.accent.tint-light` | color | `--mx-color-accent-tint-light` | `#fbe6de` |
4045
4281
  | `color.accent.tint-dark` | color | `--mx-color-accent-tint-dark` | `#45271d` |
4046
- | `color.critical.light` | color | `--mx-color-critical-light` | `#b3261a` |
4047
- | `color.critical.light-hover` | color | `--mx-color-critical-light-hover` | `#c42b1c` |
4282
+ | `color.critical.light` | color | `--mx-color-critical-light` | `#b03659` |
4283
+ | `color.critical.light-hover` | color | `--mx-color-critical-light-hover` | `#c13b61` |
4048
4284
  | `color.critical.light-bg` | color | `--mx-color-critical-light-bg` | `#fde7e9` |
4049
4285
  | `color.critical.dark` | color | `--mx-color-critical-dark` | `#ff99a4` |
4050
4286
  | `color.critical.dark-hover` | color | `--mx-color-critical-dark-hover` | `#e98d97` |
4051
4287
  | `color.critical.dark-bg` | color | `--mx-color-critical-dark-bg` | `#442726` |
4052
- | `color.success.light` | color | `--mx-color-success-light` | `#0c6a0c` |
4288
+ | `color.success.light` | color | `--mx-color-success-light` | `#006402` |
4053
4289
  | `color.success.light-bg` | color | `--mx-color-success-light-bg` | `#dff6dd` |
4054
- | `color.success.dark` | color | `--mx-color-success-dark` | `#6ccb5f` |
4290
+ | `color.success.dark` | color | `--mx-color-success-dark` | `#6dc43a` |
4055
4291
  | `color.success.dark-bg` | color | `--mx-color-success-dark-bg` | `#393d1b` |
4056
- | `color.caution.light` | color | `--mx-color-caution-light` | `#845000` |
4292
+ | `color.caution.light` | color | `--mx-color-caution-light` | `#754702` |
4057
4293
  | `color.caution.light-bg` | color | `--mx-color-caution-light-bg` | `#fff4ce` |
4058
4294
  | `color.caution.dark` | color | `--mx-color-caution-dark` | `#fce100` |
4059
4295
  | `color.caution.dark-bg` | color | `--mx-color-caution-dark-bg` | `#433519` |
@@ -4222,7 +4458,7 @@ cssVar('color.accent.solid'); // 'var(--mx-color-accent-solid)' — a design-sy
4222
4458
 
4223
4459
  # Control
4224
4460
 
4225
- > Foundations · @motifx-community/ui 0.1.0-beta.1
4461
+ > Foundations · @motifx-community/ui 0.1.0-beta.2
4226
4462
 
4227
4463
  The base of every control in the package. It gives each one the same `text`, `enabled`, `visible` and `tabStop`, and the same focus methods, whether the control is written in JSX and bound to state or created with `new` and changed from code.
4228
4464
 
@@ -4458,7 +4694,7 @@ The base adds no listeners per control and pays only for what is used.
4458
4694
 
4459
4695
  # Keyboard and focus
4460
4696
 
4461
- > Foundations · @motifx-community/ui 0.1.0-beta.1
4697
+ > Foundations · @motifx-community/ui 0.1.0-beta.2
4462
4698
 
4463
4699
  The rules every control follows: Tab order, the active control of a container, focus that never falls to `<body>`, `&File` access keys and app-wide shortcuts.
4464
4700
 
@@ -4646,11 +4882,244 @@ export default function FocusGuard() {
4646
4882
  Controls: see `Control` for `tabStop`, `tabIndex`, `focus()`, `onAccessKey()` and `FocusContainer`.
4647
4883
 
4648
4884
 
4885
+ ---
4886
+
4887
+ # Language
4888
+
4889
+ > Foundations · @motifx-community/ui 0.1.0-beta.2
4890
+
4891
+ The texts the controls write, the locale their dates and numbers follow, and the direction: one `uiLocale` for the kit, with a pack per language loaded as it is asked for.
4892
+
4893
+ ## Import
4894
+
4895
+ ```tsx
4896
+ import { uiLocale, connectI18n } from '@motifx-community/ui';
4897
+ ```
4898
+
4899
+ ## Switching the language
4900
+
4901
+ `uiLocale.use('tr')` loads the Turkish pack the first time, then every control on the page draws its texts and formats again. The Language menu in the header of these docs does the same.
4902
+
4903
+ ```tsx
4904
+ import { reactive } from '@motifx/core';
4905
+ import { Button, DateBox, NumberBox, Pagination, Stack, uiLocale } from '@motifx-community/ui';
4906
+ import { kitTexts } from '../../../shared/kit-texts';
4907
+
4908
+ /** The kit's language switched live: the pack is loaded first, then every control draws its texts and formats again. */
4909
+ export default function Switch() {
4910
+ const s = reactive({ price: 1234.5, when: new Date(2026, 2, 18) as Date | null });
4911
+ return (
4912
+ <Stack gap="md">
4913
+ <Stack orientation="horizontal" wrap align="center">
4914
+ <Button text="English" variant="outline" onclick={() => void uiLocale.use('en')} />
4915
+ <Button text="Türkçe" variant="outline" onclick={() => void uiLocale.use('tr')} />
4916
+ <span>
4917
+ In use: <output class="lang-locale">{() => kitTexts.locale}</output>
4918
+ </span>
4919
+ </Stack>
4920
+ <Stack orientation="horizontal" wrap align="center">
4921
+ <NumberBox label="Price" x-model={() => s.price} format={{ style: 'currency', currency: 'EUR' }} />
4922
+ <DateBox label="When" x-model={() => s.when} clearButton />
4923
+ </Stack>
4924
+ <Pagination total={95} pageSizes={[10, 20, 50]} label="Orders" />
4925
+ </Stack>
4926
+ );
4927
+ }
4928
+ ```
4929
+
4930
+ ## The rules
4931
+
4932
+ | Rule | How |
4933
+ | --- | --- |
4934
+ | `Start` | The page’s `<html lang>`, else the browser’s language. Set `lang` before the first control is made; `uiLocale.ready` settles once that language is in. |
4935
+ | `Texts` | Every text a control writes itself (a button’s name, a message, “No items”) comes from the pack of the language in use; English fills what the pack leaves out. |
4936
+ | `Formats` | Dates, numbers, the first day of the week and 12 or 24 hours follow `uiLocale.locale`; a control’s own `locale` prop wins for that control. |
4937
+ | `Direction` | `uiLocale.dir` is `rtl` for Arabic, Hebrew, Persian, Urdu…; the controls lay themselves out from `<html dir>`, which `@motifx-community/i18n` keeps in step. |
4938
+ | `Nothing follows` | A change is one event, `onChanged`: the controls draw again on it, and so can your own texts. No binding reads `uiLocale`. |
4939
+ | `Plurals` | A text with a count is an ICU message, `{count, plural, one {# record} other {# records}}`; a pack writes it the way its language counts. |
4940
+
4941
+ ## Packs
4942
+
4943
+ | Pack | Where it comes from |
4944
+ | --- | --- |
4945
+ | `English` | Built in. What a pack leaves out is shown in English. |
4946
+ | `Turkish` | `uiLocale.use('tr')` loads it the first time, as a chunk of the package. |
4947
+ | `@motifx-community/ui/locales/<language>.json` | The same packs as files, for an app that bundles or serves them its own way: `uiLocale.add('tr', pack)`. |
4948
+ | `uiLocale.loader` | Where the kit asks for a pack it does not have: `(language) => fetch(`/i18n/ui/${language}.json`).then((r) => r.json())`. A language without a pack keeps the English texts. |
4949
+
4950
+ A pack of your own is a plain object of the kit’s texts: `uiLocale.add` gives a language its texts, `use` switches to it. A few texts are enough to start; the rest stay English until the pack has them.
4951
+
4952
+ ```tsx
4953
+ import { Button, DropDown, Stack, uiLocale } from '@motifx-community/ui';
4954
+
4955
+ // A few German texts; what is left out stays English.
4956
+ uiLocale.add('de', {
4957
+ close: 'Schließen',
4958
+ clear: 'Leeren',
4959
+ search: 'Suchen',
4960
+ noItems: 'Keine Einträge',
4961
+ loading: 'Wird geladen…',
4962
+ ok: 'OK',
4963
+ cancel: 'Abbrechen',
4964
+ });
4965
+
4966
+ /** A pack of your own: `uiLocale.add` gives a language its texts, `use` switches to it. */
4967
+ export default function OwnPack() {
4968
+ return (
4969
+ <Stack gap="md">
4970
+ <Stack orientation="horizontal" wrap align="center">
4971
+ <Button text="Deutsch" variant="outline" onclick={() => void uiLocale.use('de')} />
4972
+ <Button text="English" variant="outline" onclick={() => void uiLocale.use('en')} />
4973
+ </Stack>
4974
+ <DropDown label="Empty list" items={[]} placeholder="Open me" />
4975
+ </Stack>
4976
+ );
4977
+ }
4978
+ ```
4979
+
4980
+ ## With your app’s translations
4981
+
4982
+ An app translated with `@motifx-community/i18n` has one locale already. `connectI18n(i18n)` makes the kit follow it: when the app switches, the kit loads its own pack and switches too. The link is undone by what it returns.
4983
+
4984
+ ```tsx
4985
+ import { Component } from '@motifx/core';
4986
+ import { createI18n } from '@motifx-community/i18n';
4987
+ import { Button, connectI18n, Stack, TextBox } from '@motifx-community/ui';
4988
+
4989
+ // The app's own translations; the kit follows their locale.
4990
+ const i18n = createI18n({
4991
+ locale: 'en',
4992
+ messages: {
4993
+ en: { greeting: 'Hello {name}', hint: 'The clear button is named by the kit' },
4994
+ tr: { greeting: 'Merhaba {name}', hint: 'Temizle düğmesini kit adlandırır' },
4995
+ },
4996
+ dom: false,
4997
+ });
4998
+
4999
+ /** One locale for the app and the kit: `connectI18n` switches the kit whenever the app's translations switch. */
5000
+ export default class Connect extends Component<HTMLDivElement> {
5001
+ override onBuilt(): void {
5002
+ this.motif.setDisposable(connectI18n(i18n));
5003
+ }
5004
+
5005
+ override view() {
5006
+ return (
5007
+ <Stack gap="md">
5008
+ <Stack orientation="horizontal" wrap align="center">
5009
+ <Button text="English" variant="outline" onclick={() => void i18n.setLocale('en')} />
5010
+ <Button text="Türkçe" variant="outline" onclick={() => void i18n.setLocale('tr')} />
5011
+ </Stack>
5012
+ <p class="lang-greeting">{() => i18n.t('greeting', { name: 'Ada' })}</p>
5013
+ <TextBox label={() => i18n.t('hint')} value="Clear me" clearButton />
5014
+ </Stack>
5015
+ );
5016
+ }
5017
+ }
5018
+ ```
5019
+
5020
+ ## Your own texts that follow
5021
+
5022
+ The kit follows nothing: a change of language is told once, through `uiLocale.onChanged`. Keep your own texts with it, and fill the kit’s own texts with `uiLocale.text`, plurals included.
5023
+
5024
+ ```tsx
5025
+ import { Component, reactive } from '@motifx/core';
5026
+ import { Button, NumberBox, Stack, uiLocale } from '@motifx-community/ui';
5027
+
5028
+ const OWN = {
5029
+ en: { title: 'Orders', hint: 'Written by the app, kept with the kit’s language' },
5030
+ tr: { title: 'Siparişler', hint: 'Uygulama yazar, kitin diliyle birlikte değişir' },
5031
+ };
5032
+
5033
+ /** Your own texts drawn again on `uiLocale.onChanged`, and the kit's plural texts filled with `uiLocale.text`. */
5034
+ export default class OwnTexts extends Component<HTMLDivElement> {
5035
+ s = reactive({ count: 3, title: '', hint: '', records: '' });
5036
+
5037
+ override onBuilt(): void {
5038
+ this.motif.register(uiLocale.onChanged(() => this.draw()));
5039
+ this.draw();
5040
+ }
5041
+
5042
+ draw(): void {
5043
+ const own = uiLocale.locale.startsWith('tr') ? OWN.tr : OWN.en;
5044
+ this.s.title = own.title;
5045
+ this.s.hint = own.hint;
5046
+ this.s.records = uiLocale.text('gridRecords', { count: this.s.count });
5047
+ }
5048
+
5049
+ override view() {
5050
+ return (
5051
+ <Stack gap="md">
5052
+ <Stack orientation="horizontal" wrap align="center">
5053
+ <Button text="English" variant="outline" onclick={() => void uiLocale.use('en')} />
5054
+ <Button text="Türkçe" variant="outline" onclick={() => void uiLocale.use('tr')} />
5055
+ </Stack>
5056
+ <p>
5057
+ <strong class="lang-own-title">{this.s.title}</strong>
5058
+ </p>
5059
+ <p>{this.s.hint}</p>
5060
+ <Stack orientation="horizontal" wrap align="center">
5061
+ <NumberBox label="Count" min={0} max={99} x-model={() => this.s.count} onValueChanged={() => this.draw()} />
5062
+ <output class="lang-records">{this.s.records}</output>
5063
+ </Stack>
5064
+ </Stack>
5065
+ );
5066
+ }
5067
+ }
5068
+ ```
5069
+
5070
+ ## Formats of one control
5071
+
5072
+ Dates and numbers follow the kit’s locale. A control given a `locale` of its own writes that one, whatever the kit’s language is.
5073
+
5074
+ ```tsx
5075
+ import { reactive } from '@motifx/core';
5076
+ import { DateBox, NumberBox, Stack } from '@motifx-community/ui';
5077
+
5078
+ /** A control's own `locale` wins over the kit's: these write German and Japanese whatever the kit's language is. */
5079
+ export default function Formats() {
5080
+ const s = reactive({ amount: 98765.43, day: new Date(2026, 2, 18) as Date | null });
5081
+ return (
5082
+ <Stack orientation="horizontal" wrap align="center">
5083
+ <NumberBox label="Betrag" locale="de-DE" format={{ style: 'currency', currency: 'EUR' }} x-model={() => s.amount} />
5084
+ <DateBox label="日付" locale="ja-JP" x-model={() => s.day} />
5085
+ <NumberBox label="The kit's locale" format={{ style: 'currency', currency: 'EUR' }} x-model={() => s.amount} />
5086
+ </Stack>
5087
+ );
5088
+ }
5089
+ ```
5090
+
5091
+ ## Checking a pack
5092
+
5093
+ In the repository, `npm run locales` checks every pack the kit ships, and `npm run locales -- path/to/de.json` one of your own. The texts themselves are in `src/locales/en.json`; a pack is the same keys in another language.
5094
+
5095
+ | Check | What it means |
5096
+ | --- | --- |
5097
+ | `Every text` | A pack names every text of `en.json`; one it leaves out is shown in English, and the check says which. |
5098
+ | `Only the kit’s texts` | A key `en.json` does not have is a typo. |
5099
+ | `The same arguments` | A text fills the same `{values}` as the English one, in ICU; the plural forms are the language’s own. |
5100
+ | `The interface` | `UiStrings` and `en.json` name the same keys. |
5101
+
5102
+ ## API reference
5103
+
5104
+ | Member | Type | Description |
5105
+ | --- | --- | --- |
5106
+ | `uiLocale.use(locale)` | `Promise<void>` | Switches to `locale` (`tr`, `tr-TR`): its pack is loaded first when it is not there, then every control draws again. A later call wins over one still loading. |
5107
+ | `uiLocale.locale` | `string` | The locale in use. |
5108
+ | `uiLocale.dir` | `'ltr' \| 'rtl'` | The direction of the locale in use. |
5109
+ | `uiLocale.strings` | `UiStrings` | The texts in use. Assigning a set changes the texts and keeps the locale: `uiLocale.strings = { ...uiLocale.strings, close: 'Shut' }`. |
5110
+ | `uiLocale.text(key, values)` | `string` | A text of the kit with its values filled in: `uiLocale.text('gridRecords', { count: 3 })`. |
5111
+ | `uiLocale.add(language, pack)` | `void` | Adds the pack of a language, or more texts to it; a language in use shows them at once. |
5112
+ | `uiLocale.loader` | `(language) => Promise<UiPackModule>` | Where packs come from; the package by default. |
5113
+ | `uiLocale.ready` | `Promise<void>` | Settles once the starting language is in. |
5114
+ | `uiLocale.onChanged` | event | Raised once the language changed, with `locale` and `previous`. |
5115
+ | `connectI18n(i18n)` | `() => void` | Keeps the kit’s language with your app’s translations (`@motifx-community/i18n`, or anything with `locale` and `onLocaleChanged`); returns what stops it. |
5116
+
5117
+
4649
5118
  ---
4650
5119
 
4651
5120
  # Button
4652
5121
 
4653
- > Buttons · @motifx-community/ui 0.1.0-beta.1
5122
+ > Buttons · @motifx-community/ui 0.1.0-beta.2
4654
5123
 
4655
5124
  A native `<button>` drawn from the design tokens: three variants, three tones, three sizes, an icon, an `&` access key. It can be a toggle, show that work is running, and open a menu or any content — from the whole button, or with `split` from an arrow next to it while the button keeps its own action.
4656
5125
 
@@ -4954,7 +5423,7 @@ The only text a button writes itself is the name of a split button's arrow. It c
4954
5423
 
4955
5424
  ```tsx
4956
5425
  import { reactive } from '@motifx/core';
4957
- import { Button, enStrings, trStrings, uiLocale } from '@motifx-community/ui';
5426
+ import { Button, uiLocale } from '@motifx-community/ui';
4958
5427
  import { kitTexts } from '../../../shared/kit-texts';
4959
5428
 
4960
5429
  /** The name of a split button's arrow, from uiLocale: a shipped language or a text of your own. */
@@ -4963,7 +5432,7 @@ export default function Localization() {
4963
5432
 
4964
5433
  const toggle = () => {
4965
5434
  s.lang = s.lang === 'en' ? 'tr' : 'en';
4966
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
5435
+ void uiLocale.use(s.lang);
4967
5436
  };
4968
5437
 
4969
5438
  return (
@@ -5070,7 +5539,7 @@ The menu and the surface it opens on are shared parts, `MenuList` and `Popup`, e
5070
5539
 
5071
5540
  # ButtonGroup
5072
5541
 
5073
- > Buttons · @motifx-community/ui 0.1.0-beta.1
5542
+ > Buttons · @motifx-community/ui 0.1.0-beta.2
5074
5543
 
5075
5544
  Buttons that belong together: a segmented choice of one or several, or a row of actions. The buttons are the kit’s own, touching by default.
5076
5545
 
@@ -5215,7 +5684,7 @@ export default function Looks() {
5215
5684
 
5216
5685
  # Toolbar
5217
5686
 
5218
- > Buttons · @motifx-community/ui 0.1.0-beta.1
5687
+ > Buttons · @motifx-community/ui 0.1.0-beta.2
5219
5688
 
5220
5689
  A bar of commands: buttons, toggle buttons, menus and fields in groups between separators. It is one Tab stop and the arrow keys move inside it; items that do not fit move into a “more” menu at the end. Items come as data, as JSX children, or both.
5221
5690
 
@@ -5382,7 +5851,7 @@ The only text a toolbar writes itself is the name of its “more” button, from
5382
5851
 
5383
5852
  ```tsx
5384
5853
  import { reactive } from '@motifx/core';
5385
- import { Button, enStrings, trStrings, uiLocale } from '@motifx-community/ui';
5854
+ import { Button, uiLocale } from '@motifx-community/ui';
5386
5855
  import { kitTexts } from '../../../shared/kit-texts';
5387
5856
 
5388
5857
  /** Switches the texts of the kit; the “more” buttons take the new name at once. */
@@ -5390,7 +5859,7 @@ export default function Localization() {
5390
5859
  const s = reactive({ lang: 'en' });
5391
5860
  const toggle = () => {
5392
5861
  s.lang = s.lang === 'en' ? 'tr' : 'en';
5393
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
5862
+ void uiLocale.use(s.lang);
5394
5863
  };
5395
5864
  return (
5396
5865
  <>
@@ -5681,7 +6150,7 @@ export default function SizeAndOrientation() {
5681
6150
 
5682
6151
  # MenuBar and ContextMenu
5683
6152
 
5684
- > Buttons · @motifx-community/ui 0.1.0-beta.1
6153
+ > Buttons · @motifx-community/ui 0.1.0-beta.2
5685
6154
 
5686
6155
  A menu bar of an app (File, Edit, View) and the menu that opens on a right-click. Both show the same menu items: submenus, check and radio items, shortcuts, access keys.
5687
6156
 
@@ -5997,7 +6466,7 @@ Menus write no text of their own: every label, shortcut and name comes from your
5997
6466
 
5998
6467
  # TextBox
5999
6468
 
6000
- > Editors · @motifx-community/ui 0.1.0-beta.1
6469
+ > Editors · @motifx-community/ui 0.1.0-beta.2
6001
6470
 
6002
6471
  A one-line text field with its label, help text and error: placeholder, prefix and suffix, buttons in the box, a clear button, a password that can be shown, a character counter, an input mask and validation — alone, in a group, or every field in a panel.
6003
6472
 
@@ -6313,7 +6782,7 @@ The names of the clear and password buttons and every validation message come fr
6313
6782
 
6314
6783
  ```tsx
6315
6784
  import { reactive } from '@motifx/core';
6316
- import { Button, enStrings, trStrings, uiLocale } from '@motifx-community/ui';
6785
+ import { Button, uiLocale } from '@motifx-community/ui';
6317
6786
  import { kitTexts } from '../../../shared/kit-texts';
6318
6787
 
6319
6788
  /** Switches the texts of every field on the page; errors already shown follow too. */
@@ -6321,7 +6790,7 @@ export default function Localization() {
6321
6790
  const s = reactive({ lang: 'en' });
6322
6791
  const toggle = () => {
6323
6792
  s.lang = s.lang === 'en' ? 'tr' : 'en';
6324
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
6793
+ void uiLocale.use(s.lang);
6325
6794
  };
6326
6795
  return (
6327
6796
  <>
@@ -6450,7 +6919,7 @@ The frame (`Field`), the mask (`InputMask`, which works on any `<input>`) and va
6450
6919
 
6451
6920
  # TextArea
6452
6921
 
6453
- > Editors · @motifx-community/ui 0.1.0-beta.1
6922
+ > Editors · @motifx-community/ui 0.1.0-beta.2
6454
6923
 
6455
6924
  A text field of several lines: a box that grows with the text or that the user drags bigger, a character counter, a clear button, Ctrl+Enter to send, and the label, help text and validation every field has.
6456
6925
 
@@ -6667,7 +7136,7 @@ The name of the clear button and the validation messages come from `uiLocale.str
6667
7136
 
6668
7137
  ```tsx
6669
7138
  import { reactive } from '@motifx/core';
6670
- import { Button, enStrings, trStrings, uiLocale } from '@motifx-community/ui';
7139
+ import { Button, uiLocale } from '@motifx-community/ui';
6671
7140
  import { kitTexts } from '../../../shared/kit-texts';
6672
7141
 
6673
7142
  /** Switches the texts of every field on the page, the clear button's name included. */
@@ -6675,7 +7144,7 @@ export default function Localization() {
6675
7144
  const s = reactive({ lang: 'en' });
6676
7145
  const toggle = () => {
6677
7146
  s.lang = s.lang === 'en' ? 'tr' : 'en';
6678
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
7147
+ void uiLocale.use(s.lang);
6679
7148
  };
6680
7149
  return (
6681
7150
  <>
@@ -6759,7 +7228,7 @@ TextArea uses the field tokens (`field.*`, see TextBox) and has none of its own:
6759
7228
 
6760
7229
  # NumberBox
6761
7230
 
6762
- > Editors · @motifx-community/ui 0.1.0-beta.1
7231
+ > Editors · @motifx-community/ui 0.1.0-beta.2
6763
7232
 
6764
7233
  A number field: arrow keys, PageUp / PageDown and spin buttons that repeat while held, bounds, a step without float noise, a format for display (currency, percent) and typing in the locale’s own way.
6765
7234
 
@@ -6971,7 +7440,7 @@ The names of the spin buttons and the range messages come from `uiLocale.strings
6971
7440
 
6972
7441
  ```tsx
6973
7442
  import { reactive } from '@motifx/core';
6974
- import { Button, enStrings, trStrings, uiLocale } from '@motifx-community/ui';
7443
+ import { Button, uiLocale } from '@motifx-community/ui';
6975
7444
  import { kitTexts } from '../../../shared/kit-texts';
6976
7445
 
6977
7446
  /** Switches the names of the spin buttons and the range messages. */
@@ -6980,7 +7449,7 @@ export default function Localization() {
6980
7449
 
6981
7450
  const toggle = () => {
6982
7451
  s.lang = s.lang === 'en' ? 'tr' : 'en';
6983
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
7452
+ void uiLocale.use(s.lang);
6984
7453
  };
6985
7454
 
6986
7455
  return (
@@ -7072,7 +7541,7 @@ export default function Localization() {
7072
7541
 
7073
7542
  # DateBox
7074
7543
 
7075
- > Editors · @motifx-community/ui 0.1.0-beta.1
7544
+ > Editors · @motifx-community/ui 0.1.0-beta.2
7076
7545
 
7077
7546
  A date, a time or both. It is typed in the order of the locale through a mask, or picked from a calendar and a list of times; `min`, `max` and `disabledDates` limit both ways.
7078
7547
 
@@ -7218,14 +7687,14 @@ Button names and messages come from `uiLocale.strings`; dates and names from `lo
7218
7687
 
7219
7688
  ```tsx
7220
7689
  import { reactive } from '@motifx/core';
7221
- import { Button, enStrings, trStrings, uiLocale } from '@motifx-community/ui';
7690
+ import { Button, uiLocale } from '@motifx-community/ui';
7222
7691
 
7223
7692
  /** Switches the button names and messages of every date box on the page. */
7224
7693
  export default function Localization() {
7225
7694
  const s = reactive({ lang: 'en' });
7226
7695
  const toggle = () => {
7227
7696
  s.lang = s.lang === 'en' ? 'tr' : 'en';
7228
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
7697
+ void uiLocale.use(s.lang);
7229
7698
  };
7230
7699
  return <Button text={() => (s.lang === 'en' ? 'Language: English' : 'Dil: Türkçe')} variant="outline" onclick={toggle} />;
7231
7700
  }
@@ -7273,11 +7742,207 @@ export default function Localization() {
7273
7742
  The date helpers are shared: `datePatternOf(locale, kind)`, `dateToDigits`, `digitsToDate`.
7274
7743
 
7275
7744
 
7745
+ ---
7746
+
7747
+ # DateRangeBox
7748
+
7749
+ > Editors · @motifx-community/ui 0.1.0-beta.2
7750
+
7751
+ A start and an end date in one field: typed through two masks, or picked on two months side by side, from ready-made ranges, within the dates and the span allowed. The value is a `[start, end]` pair.
7752
+
7753
+ ## Import
7754
+
7755
+ ```tsx
7756
+ import { DateRangeBox, type DateRange } from '@motifx-community/ui';
7757
+ ```
7758
+
7759
+ ## From JSX and from code
7760
+
7761
+ ```tsx
7762
+ import { reactive } from '@motifx/core';
7763
+ import { Button, DateRangeBox, Stack, type DateRange } from '@motifx-community/ui';
7764
+
7765
+ const say = (d: Date | null) => (d ? d.toLocaleDateString('en-GB') : '—');
7766
+
7767
+ /** A range bound with x-model, and one made from code and read through its properties. */
7768
+ export default function FromCode() {
7769
+ const s = reactive({ stay: [new Date(2026, 2, 10), new Date(2026, 2, 14)] as DateRange, told: '' });
7770
+ const coded = new DateRangeBox({ label: 'Report period', clearButton: true, onValueChanged: e => (s.told = `${say(e.value[0])} to ${say(e.value[1])}`) });
7771
+
7772
+ return (
7773
+ <Stack gap="md">
7774
+ <Stack orientation="horizontal" wrap align="center">
7775
+ <DateRangeBox label="Stay" x-model={() => s.stay} clearButton />
7776
+ <output class="dr-stay">{() => `${say(s.stay[0])} to ${say(s.stay[1])}`}</output>
7777
+ </Stack>
7778
+ <Stack orientation="horizontal" wrap align="center">
7779
+ <span onConfig={c => c.controls.add(coded)} />
7780
+ <Button text="This week" variant="outline" onclick={() => (coded.value = [new Date(2026, 2, 16), new Date(2026, 2, 22)])} />
7781
+ <output class="dr-told">{() => s.told}</output>
7782
+ </Stack>
7783
+ </Stack>
7784
+ );
7785
+ }
7786
+ ```
7787
+
7788
+ ## Presets
7789
+
7790
+ `presets` puts ready-made ranges beside the calendars: `true` for the kit’s, or your own, each made when it is chosen. `calendars={1}` shows one month.
7791
+
7792
+ ```tsx
7793
+ import { reactive } from '@motifx/core';
7794
+ import { DateRangeBox, Stack, type DateRange, type DateRangePreset } from '@motifx-community/ui';
7795
+
7796
+ const day = (offset: number) => {
7797
+ const d = new Date();
7798
+ d.setHours(0, 0, 0, 0);
7799
+ d.setDate(d.getDate() + offset);
7800
+ return d;
7801
+ };
7802
+
7803
+ // Ranges of our own, made when chosen so they are about today.
7804
+ const QUARTERS: DateRangePreset[] = [
7805
+ { text: 'Next 3 days', range: () => [day(0), day(2)] },
7806
+ { text: 'Next week', range: () => [day(1), day(7)] },
7807
+ { text: 'Next 90 days', range: () => [day(0), day(89)] }
7808
+ ];
7809
+
7810
+ /** The kit's presets beside the calendars, and presets of your own. */
7811
+ export default function Presets() {
7812
+ const s = reactive({ sales: [null, null] as DateRange, plan: [null, null] as DateRange });
7813
+ return (
7814
+ <Stack orientation="horizontal" wrap align="center">
7815
+ <DateRangeBox label="Sales period" presets x-model={() => s.sales} />
7816
+ <DateRangeBox label="Planning" presets={QUARTERS} calendars={1} x-model={() => s.plan} />
7817
+ </Stack>
7818
+ );
7819
+ }
7820
+ ```
7821
+
7822
+ ## Limits
7823
+
7824
+ `min`, `max` and `disabledDates` bound both ends, typed or picked; `minDays` and `maxDays` bound the span, and the calendars offer only the days within while the end is being picked. A failed rule says which.
7825
+
7826
+ ```tsx
7827
+ import { reactive } from '@motifx/core';
7828
+ import { Button, DateRangeBox, Stack, type DateRange } from '@motifx-community/ui';
7829
+
7830
+ const today = new Date();
7831
+ const inMonths = (n: number) => new Date(today.getFullYear(), today.getMonth() + n, today.getDate());
7832
+
7833
+ /** A stay of one to fourteen nights, within the next six months, never starting on a Sunday; the message says which rule failed. */
7834
+ export default function Limits() {
7835
+ const s = reactive({ stay: [null, null] as DateRange, told: '' });
7836
+ let box!: DateRangeBox;
7837
+ return (
7838
+ <Stack orientation="horizontal" wrap align="center">
7839
+ <DateRangeBox
7840
+ ref={(b: DateRangeBox) => (box = b)}
7841
+ label="Stay"
7842
+ min={today}
7843
+ max={inMonths(6)}
7844
+ minDays={1}
7845
+ maxDays={14}
7846
+ disabledDates={d => d.getDay() === 0}
7847
+ required
7848
+ x-model={() => s.stay}
7849
+ />
7850
+ <Button text="Check" variant="outline" onclick={() => void box.validate().then(ok => (s.told = ok ? 'Fine.' : box.validationMessage))} />
7851
+ <output class="dr-check">{() => s.told}</output>
7852
+ </Stack>
7853
+ );
7854
+ }
7855
+ ```
7856
+
7857
+ ## With a time, and in another locale
7858
+
7859
+ ```tsx
7860
+ import { reactive } from '@motifx/core';
7861
+ import { DateRangeBox, Stack, type DateRange } from '@motifx-community/ui';
7862
+
7863
+ /** Date and time on both ends: the time is typed after the date, the calendars keep it; one box in Turkish. */
7864
+ export default function DateTime() {
7865
+ const s = reactive({ shift: [new Date(2026, 2, 10, 8, 30), new Date(2026, 2, 10, 17, 0)] as DateRange, trip: [null, null] as DateRange });
7866
+ return (
7867
+ <Stack orientation="horizontal" wrap align="center">
7868
+ <DateRangeBox label="Shift" type="datetime" x-model={() => s.shift} displayFormat={{ dateStyle: 'short', timeStyle: 'short' }} />
7869
+ <DateRangeBox label="Seyahat" locale="tr-TR" showWeekNumbers x-model={() => s.trip} startPlaceholder="gidiş" endPlaceholder="dönüş" />
7870
+ </Stack>
7871
+ );
7872
+ }
7873
+ ```
7874
+
7875
+ ## Behaviour
7876
+
7877
+ | Topic | How |
7878
+ | --- | --- |
7879
+ | `Typing` | Each side is a masked input in the locale’s order (`22.11.2006`); a whole, real date is taken as it is finished, an emptied side becomes `null`. Tab moves from the start to the end. |
7880
+ | `Picking` | On the popup the first pick is the start, the second the end: an earlier second pick becomes the start. With both chosen, the next pick starts a new range. While the end is being picked, the pointer shows the range it would make. |
7881
+ | `Two months` | The calendars show the start’s month and the next; paging one pages the other with it. |
7882
+ | `Presets` | A list beside the calendars; a press takes the range and closes. |
7883
+ | `Keyboard` | Alt+Down opens the popup; in it the calendars take the arrow keys, Enter picks; Escape closes, and clears the field when `clearButton` is on and the popup is closed. |
7884
+
7885
+ ## Accessibility
7886
+
7887
+ | Topic | How |
7888
+ | --- | --- |
7889
+ | `Inputs` | Two text boxes named “<label>, Start date” and “<label>, End date” in the kit language; the field’s label marks the start. |
7890
+ | `Popup` | A dialog named “Choose date”; the calendars are the kit’s grids, the presets a list box. |
7891
+ | `Messages` | The rules speak in the kit language; a rule of your own in yours. |
7892
+
7893
+ ## Styling
7894
+
7895
+ | Hook | What it is |
7896
+ | --- | --- |
7897
+ | `.mx-date-range-box` | The field. `data-type`. |
7898
+ | `.mx-date-range-box__start, .mx-date-range-box__end, .mx-date-range-box__separator` | The inputs and the glyph between them. |
7899
+ | `.mx-date-range-box__toggle, .mx-date-range-box__clear` | The buttons in the box. |
7900
+ | `.mx-date-range-box__popup, .mx-date-range-box__calendar, .mx-date-range-box__presets` | The popup, each calendar, the presets. |
7901
+
7902
+ ### Component tokens
7903
+
7904
+ | Token | What it sets |
7905
+ | --- | --- |
7906
+ | `date-range-box.separator, .presets` | Units: the glyph between the inputs (`icon`, `bg`), the list of presets (`focus`, `beside`). |
7907
+ | `date-range-box.calendar` | Place: a calendar on the popup. |
7908
+ | `date-range-box.popup-gap` | Between the calendars and the presets. |
7909
+ | `calendar.cell range-start, range-end, range-single, range-in` | The calendar’s cells in a range: its ends and the days between, drawn by each language. |
7910
+
7911
+ ## API reference
7912
+
7913
+ ### Props
7914
+
7915
+ | Prop | Type | Default | Description |
7916
+ | --- | --- | --- | --- |
7917
+ | `value` | `Bind<DateRange>` | `[null, null]` | The `[start, end]` pair; either `null` while not chosen. `x-model` binds it two-way. |
7918
+ | `type` | `Bind<'date' \| 'datetime'>` | `'date'` | With `datetime` the time is typed after the date; the calendars keep it. |
7919
+ | `min, max, disabledDates` | `Bind<Date \| null>`, `Bind<(d: Date) => boolean>` | — | The dates allowed, on both ends, typed or picked. |
7920
+ | `minDays, maxDays` | `Bind<number \| null>` | `null` | The least and the most days a range may span, the end counted from the start; while the end is picked the calendars offer only days within. |
7921
+ | `presets` | `Bind<readonly DateRangePreset[] \| boolean>` | `false` | `true`: the kit’s ready-made ranges beside the calendars (today, yesterday, the last 7 and 30 days, this and last month); your own as `{ text, range: () => DateRange }`. |
7922
+ | `calendars` | `Bind<1 \| 2>` | `2` | Months side by side on the popup; two stay a month apart as one is paged. |
7923
+ | `closeOnComplete` | `Bind<boolean>` | `true` | The popup closes once both ends are picked. |
7924
+ | `locale, displayFormat, firstDayOfWeek, showWeekNumbers, showSeconds` | | | As on the `DateBox`. |
7925
+ | `startPlaceholder, endPlaceholder` | `Bind<string>` | `''` | Shown in an empty box. |
7926
+ | `clearButton, showPickerButton` | `Bind<boolean>` | `false`, `true` | The clear button; the button that opens the calendars. |
7927
+ | `label, helpText, required, rules, readOnly, size, variant…` | | | The field props, as on every editor. |
7928
+
7929
+ ### Events, properties and methods
7930
+
7931
+ | Member | Kind | Description |
7932
+ | --- | --- | --- |
7933
+ | `startDate, endDate` | `Date \| null` | The ends as properties of their own. |
7934
+ | `inputElement, endInputElement` | read-only | The start’s and the end’s inputs. |
7935
+ | `open(), close(), opened` | `boolean` / `void` | The popup with the calendars; `onOpened`, `onClosed`. |
7936
+ | `clear()` | `void` | Empties both ends. |
7937
+ | `validate(), validationMessage, isValid` | | As on every field: an unfinished date, a date outside `min`, `max` or `disabledDates`, a start after the end, a span under `minDays` or over `maxDays`. |
7938
+ | `onValueChanged` | event | The pair changed (`value`, `previousValue`, `byUser`). |
7939
+
7940
+
7276
7941
  ---
7277
7942
 
7278
7943
  # ColorBox and ColorPicker
7279
7944
 
7280
- > Editors · @motifx-community/ui 0.1.0-beta.1
7945
+ > Editors · @motifx-community/ui 0.1.0-beta.2
7281
7946
 
7282
7947
  A colour as a field, with a picker in a popup; or the picker on its own. The picker has an area of saturation and brightness, a hue strip, an opacity strip, inputs for the channels and preset colours.
7283
7948
 
@@ -7434,7 +8099,7 @@ export default function Buttons() {
7434
8099
 
7435
8100
  # Calendar
7436
8101
 
7437
- > Editors · @motifx-community/ui 0.1.0-beta.1
8102
+ > Editors · @motifx-community/ui 0.1.0-beta.2
7438
8103
 
7439
8104
  A month of days to pick a date from, with a year and a decade view to get far quickly. It is the picker of DateBox, and it works on its own.
7440
8105
 
@@ -7574,7 +8239,7 @@ export default function Views() {
7574
8239
 
7575
8240
  # Slider
7576
8241
 
7577
- > Editors · @motifx-community/ui 0.1.0-beta.1
8242
+ > Editors · @motifx-community/ui 0.1.0-beta.2
7578
8243
 
7579
8244
  A value picked on a track by dragging a thumb or with the keys: one number, or a range with two thumbs. Steps, marks with labels, a value bubble, a vertical form and number formatting, with the label, help line and validation every field has.
7580
8245
 
@@ -7821,7 +8486,7 @@ The names of the two thumbs of a range come from `uiLocale.strings` (`minimum`,
7821
8486
 
7822
8487
  ```tsx
7823
8488
  import { reactive } from '@motifx/core';
7824
- import { Button, enStrings, Slider, trStrings, uiLocale } from '@motifx-community/ui';
8489
+ import { Button, Slider, uiLocale } from '@motifx-community/ui';
7825
8490
  import { kitTexts } from '../../../shared/kit-texts';
7826
8491
 
7827
8492
  /** Switches the names of the thumbs; the price slider writes its numbers in the chosen language. */
@@ -7829,7 +8494,7 @@ export default function Localization() {
7829
8494
  const s = reactive({ lang: 'en' });
7830
8495
  const toggle = () => {
7831
8496
  s.lang = s.lang === 'en' ? 'tr' : 'en';
7832
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
8497
+ void uiLocale.use(s.lang);
7833
8498
  };
7834
8499
  return (
7835
8500
  <>
@@ -7939,7 +8604,7 @@ export default function Localization() {
7939
8604
 
7940
8605
  # Rating
7941
8606
 
7942
- > Editors · @motifx-community/ui 0.1.0-beta.1
8607
+ > Editors · @motifx-community/ui 0.1.0-beta.2
7943
8608
 
7944
8609
  A row of stars to give a score or to show one, whole or by halves. It is a field: label, help text, rules and `x-model` work as in every field.
7945
8610
 
@@ -8063,11 +8728,216 @@ export default function Icons() {
8063
8728
  | `label, helpText, readOnly, required, rules, size…` | see Field | | Everything a field has: a rating is one. |
8064
8729
 
8065
8730
 
8731
+ ---
8732
+
8733
+ # FileUploader
8734
+
8735
+ > Editors · @motifx-community/ui 0.1.0-beta.2
8736
+
8737
+ Files chosen with a button or dropped on the box, listed with their size and what happens to them: uploaded as they come, on a button or from code, with progress, cancel, retry and remove on each. Files outside the limits are listed with the reason.
8738
+
8739
+ ## Import
8740
+
8741
+ ```tsx
8742
+ import { FileUploader } from '@motifx-community/ui';
8743
+ ```
8744
+
8745
+ ## Choosing, dropping, uploading
8746
+
8747
+ `upload` is your own way to send a file: report progress, stop on the signal, resolve to the response. With `uploadUrl` instead, the uploader sends the file itself, in one piece or in chunks (`chunkSize`).
8748
+
8749
+ ```tsx
8750
+ import { reactive } from '@motifx/core';
8751
+ import { FileUploader, Stack } from '@motifx-community/ui';
8752
+
8753
+ // Stands in for a server: takes two seconds per megabyte, reports as it goes, stops on the signal.
8754
+ const send = (file: File, report: (fraction: number) => void, signal: AbortSignal) =>
8755
+ new Promise<string>((resolve, reject) => {
8756
+ const steps = 20;
8757
+ const wait = Math.max(600, Math.min(4000, (file.size / 1_000_000) * 2000)) / steps;
8758
+ let step = 0;
8759
+ const timer = setInterval(() => {
8760
+ step++;
8761
+ report(step / steps);
8762
+ if (step === steps) {
8763
+ clearInterval(timer);
8764
+ resolve(`id-${file.name}`);
8765
+ }
8766
+ }, wait);
8767
+ signal.addEventListener('abort', () => {
8768
+ clearInterval(timer);
8769
+ reject(new Error('stopped'));
8770
+ });
8771
+ });
8772
+
8773
+ /** Files chosen or dropped go up as they come, through your own upload; each row shows progress, cancel, retry, remove. */
8774
+ export default function Basic() {
8775
+ const s = reactive({ files: [] as readonly File[], told: '' });
8776
+ return (
8777
+ <Stack gap="md" style="inline-size: 100%">
8778
+ <FileUploader
8779
+ label="Attachments"
8780
+ helpText="Any files; a stand-in server takes them."
8781
+ upload={send}
8782
+ x-model={() => s.files}
8783
+ onUploaded={e => (s.told = `${e.file.name} is up as ${String(e.item.response)}.`)}
8784
+ onUploadAborted={e => (s.told = `${e.file.name} was stopped.`)}
8785
+ />
8786
+ <output class="fu-told">{() => s.told || `${s.files.length} file(s) taken`}</output>
8787
+ </Stack>
8788
+ );
8789
+ }
8790
+ ```
8791
+
8792
+ ## Limits
8793
+
8794
+ ```tsx
8795
+ import { reactive } from '@motifx/core';
8796
+ import { FileUploader, Stack } from '@motifx-community/ui';
8797
+
8798
+ /** Only pictures and PDFs, up to 2 MB each and three in all; a file outside is listed with the reason. */
8799
+ export default function Limits() {
8800
+ const s = reactive({ files: [] as readonly File[], refused: '' });
8801
+ return (
8802
+ <Stack gap="md" style="inline-size: 100%">
8803
+ <FileUploader
8804
+ label="Documents"
8805
+ accept=".pdf,image/*"
8806
+ maxFileSize={2_000_000}
8807
+ maxFiles={3}
8808
+ required
8809
+ x-model={() => s.files}
8810
+ onFilesAdded={e => (s.refused = e.refused.length ? e.refused.map(r => r.message).join(' ') : '')}
8811
+ />
8812
+ <output class="fu-refused">{() => s.refused}</output>
8813
+ </Stack>
8814
+ );
8815
+ }
8816
+ ```
8817
+
8818
+ ## When files go up
8819
+
8820
+ ```tsx
8821
+ import { reactive } from '@motifx/core';
8822
+ import { Button, FileUploader, Stack } from '@motifx-community/ui';
8823
+
8824
+ const quick = (file: File, report: (fraction: number) => void) =>
8825
+ new Promise<void>(resolve => {
8826
+ let step = 0;
8827
+ const timer = setInterval(() => {
8828
+ report(++step / 10);
8829
+ if (step === 10) {
8830
+ clearInterval(timer);
8831
+ resolve();
8832
+ }
8833
+ }, 120);
8834
+ });
8835
+
8836
+ /** An Upload button sends what was chosen; or nothing goes until code says so. One file only, no dropping. */
8837
+ export default function Modes() {
8838
+ const s = reactive({ one: [] as readonly File[] });
8839
+ let manual!: FileUploader;
8840
+ return (
8841
+ <Stack gap="md" style="inline-size: 100%">
8842
+ <FileUploader label="Photo" multiple={false} allowDrop={false} accept="image/*" upload={quick} uploadMode="button" x-model={() => s.one} />
8843
+ <Stack orientation="horizontal" wrap align="center">
8844
+ <FileUploader ref={(u: FileUploader) => (manual = u)} label="Logs" accept=".log,.txt" upload={quick} uploadMode="manual" />
8845
+ <Button text="Send the logs" variant="outline" onclick={() => void manual.upload()} />
8846
+ </Stack>
8847
+ </Stack>
8848
+ );
8849
+ }
8850
+ ```
8851
+
8852
+ ## Sending to a server
8853
+
8854
+ The uploader posts a form with the file in `uploadField` (`file` by default) to `uploadUrl`, with `uploadHeaders`; a 2xx answer is the item’s `response`, JSON parsed when it is JSON. With `chunkSize` each piece carries `Content-Range` and the fields `chunkIndex` and `chunkCount`.
8855
+
8856
+ ```tsx
8857
+ <FileUploader
8858
+ label="Attachments"
8859
+ uploadUrl="/api/files"
8860
+ uploadHeaders={{ Authorization: 'Bearer ' + token }}
8861
+ chunkSize={1_000_000}
8862
+ onUploaded={(e) => this.attachments.push(e.item.response as Attachment)}
8863
+ />
8864
+ ```
8865
+
8866
+ ## Behaviour
8867
+
8868
+ | Topic | How |
8869
+ | --- | --- |
8870
+ | `Choosing` | The button opens the file dialog; files may be dropped on the box too, which lights up while they are over it. |
8871
+ | `Refusing` | A file outside `accept`, the sizes or `maxFiles` is listed as refused with the reason, and is not in the value. |
8872
+ | `Uploading` | As chosen, on the Upload button, or from code. A row shows the progress and a Cancel button meanwhile; afterwards “Uploaded”, or the failure with Retry. The server’s answer is the item’s `response` (JSON parsed). |
8873
+ | `Chunks` | With `chunkSize` the file goes in pieces, each a request with `Content-Range: bytes start-end/total`; progress runs over the whole. |
8874
+ | `Removing` | Each row has a remove button; a running upload is stopped first. |
8875
+
8876
+ ## Accessibility
8877
+
8878
+ | Topic | How |
8879
+ | --- | --- |
8880
+ | `Button` | The select button is the field’s control: the label marks it, Space and Enter open the dialog. |
8881
+ | `List` | A list of rows: the name, the size and the state as text; the progress bar named after the file; the buttons named “Cancel the upload of …”, “Retry”, “Remove …”. |
8882
+ | `Messages` | The reasons a file was refused and the failures speak in the kit language, or in the server’s words. |
8883
+
8884
+ ## Styling
8885
+
8886
+ | Hook | What it is |
8887
+ | --- | --- |
8888
+ | `.mx-file-uploader` | The field. `data-dragover` while files are over it. |
8889
+ | `.mx-file-uploader__select, .mx-file-uploader__drop, .mx-file-uploader__upload` | The select button, the hint, the Upload button. |
8890
+ | `.mx-file-uploader__list, .mx-file-uploader__item` | The list and each row. `data-status` on the row. |
8891
+ | `.mx-file-uploader__icon, __name, __size, __state, __progress, __actions, __action` | The parts of a row. |
8892
+
8893
+ ### Component tokens
8894
+
8895
+ | Token | What it sets |
8896
+ | --- | --- |
8897
+ | `file-uploader.over, .select, .upload, .hint, .list, .item, .icon, .name, .size, .state` | Units: the box with files over it, the two buttons (`hover`, `pressed`, `focus`, `disabled`), the hint, the list, a row per status, the file glyph, the texts. |
8898
+ | `file-uploader.field, .action` | Places: the field’s box as a drop zone (a dashed frame, its corners, its padding); the row’s buttons. |
8899
+ | `file-uploader.box-gap, .button-gap, .item-gap` | The spaces in the box, in a button and in a row. |
8900
+
8901
+ ## API reference
8902
+
8903
+ ### Props
8904
+
8905
+ | Prop | Type | Default | Description |
8906
+ | --- | --- | --- | --- |
8907
+ | `value` | `Bind<readonly File[]>` | `[]` | The files taken (the refused ones are not in it). `x-model` binds it two-way. |
8908
+ | `multiple` | `Bind<boolean>` | `true` | Several files at once; `false` keeps one, the newest. |
8909
+ | `accept` | `Bind<string>` | `''` | What may be chosen, as for `<input type="file">`: `.png,.jpg`, `image/*`, `application/pdf`. |
8910
+ | `maxFileSize, minFileSize` | `Bind<number \| null>` | `null` | Bytes. A file outside is listed as refused, with the reason. |
8911
+ | `maxFiles` | `Bind<number \| null>` | `null` | How many files may be taken in all. |
8912
+ | `allowDrop` | `Bind<boolean>` | `true` | Files may be dropped on the box. |
8913
+ | `uploadMode` | `Bind<UploadMode>` | `instant` / `manual` | `instant`: as chosen; `button`: an Upload button; `manual`: `upload()` from code. Default `instant` with `uploadUrl` or `upload`, else `manual`. |
8914
+ | `uploadUrl, uploadMethod, uploadHeaders, uploadField` | `Bind<string \| null>`, … | `null`, `POST`, `null`, `file` | Where and how the uploader itself sends a file (XMLHttpRequest, with progress), as a form with the file in `uploadField`. |
8915
+ | `chunkSize` | `Bind<number \| null>` | `null` | Bytes per request: the file goes in pieces, each with its `Content-Range` and `chunkIndex` / `chunkCount` fields; the last answer is the response. |
8916
+ | `upload` | `(file, report, signal) => Promise<unknown>` | — | Your own upload instead of `uploadUrl`: call `report(0…1)` as it goes, stop on `signal`; what it resolves to is the response. |
8917
+ | `selectText, dropText, uploadText` | `Bind<string>` | the kit’s | The button, the hint beside it, the Upload button. |
8918
+ | `showFileList` | `Bind<boolean>` | `true` | The list of files under the box. |
8919
+ | `label, helpText, required, rules, readOnly, size, variant…` | | | The field props, as on every editor. |
8920
+
8921
+ ### Events, properties and methods
8922
+
8923
+ | Member | Kind | Description |
8924
+ | --- | --- | --- |
8925
+ | `items` | read-only | Every file in the list with what happened to it: `file`, `status` (`ready`, `uploading`, `done`, `error`, `aborted`, `invalid`), `progress`, `response`, `message`. |
8926
+ | `isUploading` | read-only | An upload is running. |
8927
+ | `openDialog()` | `void` | Opens the browser’s file dialog, as the button does. |
8928
+ | `addFiles(files)` | `void` | Takes files as if chosen: the limits apply, `onFilesAdded` is asked, uploads start as the mode says. |
8929
+ | `upload(item?)` | `Promise<void>` | Uploads the files waiting, or one of them; what `manual` mode calls. |
8930
+ | `abort(item?), remove(item), clear()` | `void` | Stops an upload (the file stays, cancelled); takes a file out; takes every file out. |
8931
+ | `onFilesAdded` | event | Files were chosen or dropped (`files`, `refused`); `cancel = true` takes none. |
8932
+ | `onFileRemoved, onUploadStarted, onProgress, onUploaded, onUploadError, onUploadAborted` | event | One file’s way through: each with `item` and `file`, a failure with `error`. |
8933
+ | `onValueChanged` | event | The files taken changed. |
8934
+
8935
+
8066
8936
  ---
8067
8937
 
8068
8938
  # CheckBox
8069
8939
 
8070
- > Choice · @motifx-community/ui 0.1.0-beta.1
8940
+ > Choice · @motifx-community/ui 0.1.0-beta.2
8071
8941
 
8072
8942
  A checkbox with its caption: checked, unchecked or indeterminate, three states on request, read-only, required and checked with its group. A native checkbox underneath, drawn from the design tokens.
8073
8943
 
@@ -8311,7 +9181,7 @@ The checkbox writes no text of its own; the `required` message comes from `uiLoc
8311
9181
 
8312
9182
  ```tsx
8313
9183
  import { reactive } from '@motifx/core';
8314
- import { Button, enStrings, trStrings, uiLocale } from '@motifx-community/ui';
9184
+ import { Button, uiLocale } from '@motifx-community/ui';
8315
9185
  import { kitTexts } from '../../../shared/kit-texts';
8316
9186
 
8317
9187
  /** Switches the texts of every field on the page; a required message already shown follows too. */
@@ -8319,7 +9189,7 @@ export default function Localization() {
8319
9189
  const s = reactive({ lang: 'en' });
8320
9190
  const toggle = () => {
8321
9191
  s.lang = s.lang === 'en' ? 'tr' : 'en';
8322
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
9192
+ void uiLocale.use(s.lang);
8323
9193
  };
8324
9194
  return (
8325
9195
  <>
@@ -8407,7 +9277,7 @@ export default function Localization() {
8407
9277
 
8408
9278
  # Switch
8409
9279
 
8410
- > Choice · @motifx-community/ui 0.1.0-beta.1
9280
+ > Choice · @motifx-community/ui 0.1.0-beta.2
8411
9281
 
8412
9282
  An on / off switch with its caption: a track with a thumb that slides, an optional on / off text inside or next to it, read-only and required. A native checkbox with the switch role underneath.
8413
9283
 
@@ -8653,7 +9523,7 @@ The switch writes no text of its own: `onText` and `offText` are yours, and can
8653
9523
 
8654
9524
  # RadioGroup
8655
9525
 
8656
- > Choice · @motifx-community/ui 0.1.0-beta.1
9526
+ > Choice · @motifx-community/ui 0.1.0-beta.2
8657
9527
 
8658
9528
  A set of options of which one is chosen: from plain values, from your own objects or from a live list; one under the other, side by side or in columns; options that are disabled, hidden or carry a help line; one Tab stop and the arrow keys.
8659
9529
 
@@ -8981,7 +9851,7 @@ The group writes no text of its own: the option texts are yours (functions of yo
8981
9851
 
8982
9852
  # DropDown
8983
9853
 
8984
- > Choice · @motifx-community/ui 0.1.0-beta.1
9854
+ > Choice · @motifx-community/ui 0.1.0-beta.2
8985
9855
 
8986
9856
  Picks one item from a list. The field shows the chosen item; the list opens below it with the keyboard or a press, can be searched, grouped and drawn your way, and stays fast with thousands of items.
8987
9857
 
@@ -9137,14 +10007,14 @@ The search box, the clear button, the empty list text, the wait (`loading`) and
9137
10007
 
9138
10008
  ```tsx
9139
10009
  import { reactive } from '@motifx/core';
9140
- import { Button, DropDown, enStrings, trStrings, uiLocale } from '@motifx-community/ui';
10010
+ import { Button, DropDown, uiLocale } from '@motifx-community/ui';
9141
10011
 
9142
10012
  /** Switches the texts of every drop-down on the page: the search box, the clear button, the empty list. */
9143
10013
  export default function Localization() {
9144
10014
  const s = reactive({ lang: 'en' });
9145
10015
  const toggle = () => {
9146
10016
  s.lang = s.lang === 'en' ? 'tr' : 'en';
9147
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
10017
+ void uiLocale.use(s.lang);
9148
10018
  };
9149
10019
  return (
9150
10020
  <>
@@ -9308,7 +10178,7 @@ export default function Validation() {
9308
10178
 
9309
10179
  # ComboBox and Autocomplete
9310
10180
 
9311
- > Choice · @motifx-community/ui 0.1.0-beta.1
10181
+ > Choice · @motifx-community/ui 0.1.0-beta.2
9312
10182
 
9313
10183
  A text field with a list that follows what is typed. The items come from memory or from a data source of the data layer, searched on the server. `Autocomplete` is the free-text kind: the value is the text.
9314
10184
 
@@ -9526,7 +10396,7 @@ export default function CustomValues() {
9526
10396
 
9527
10397
  # Lookup
9528
10398
 
9529
- > Choice · @motifx-community/ui 0.1.0-beta.1
10399
+ > Choice · @motifx-community/ui 0.1.0-beta.2
9530
10400
 
9531
10401
  Picks one row of a table-like list, typically from a data source searched on the server: a customer by its company, contact and city. The field shows the chosen row's text; everything else works as in DropDown.
9532
10402
 
@@ -9742,7 +10612,7 @@ export default function ByKey() {
9742
10612
 
9743
10613
  # ProgressBar and Spinner
9744
10614
 
9745
- > Feedback · @motifx-community/ui 0.1.0-beta.1
10615
+ > Feedback · @motifx-community/ui 0.1.0-beta.2
9746
10616
 
9747
10617
  ProgressBar shows how far some work is, as a line or a circle, or that it runs when that is not known. Spinner says "busy, wait": a turning ring, alone or over a panel while it loads, shown only after a delay so quick work does not flash it.
9748
10618
 
@@ -10049,7 +10919,7 @@ A bar or a spinner without a label is named `uiLocale.strings.loading`. The perc
10049
10919
 
10050
10920
  ```tsx
10051
10921
  import { reactive } from '@motifx/core';
10052
- import { Button, enStrings, ProgressBar, trStrings, uiLocale } from '@motifx-community/ui';
10922
+ import { Button, ProgressBar, uiLocale } from '@motifx-community/ui';
10053
10923
  import { kitTexts } from '../../../shared/kit-texts';
10054
10924
 
10055
10925
  /** Switches the name of unlabelled bars and spinners, and the language the percent is written in. */
@@ -10057,7 +10927,7 @@ export default function Localization() {
10057
10927
  const s = reactive({ lang: 'en' });
10058
10928
  const toggle = () => {
10059
10929
  s.lang = s.lang === 'en' ? 'tr' : 'en';
10060
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
10930
+ void uiLocale.use(s.lang);
10061
10931
  };
10062
10932
  return (
10063
10933
  <>
@@ -10147,7 +11017,7 @@ export default function Localization() {
10147
11017
 
10148
11018
  # Tooltip
10149
11019
 
10150
- > Feedback · @motifx-community/ui 0.1.0-beta.1
11020
+ > Feedback · @motifx-community/ui 0.1.0-beta.2
10151
11021
 
10152
11022
  A short description shown next to an element: after the pointer rests on it, when it gets keyboard focus, or from code. It can be hovered, Escape hides it, and one is open at a time on the page.
10153
11023
 
@@ -10486,11 +11356,424 @@ export default function ManyElements() {
10486
11356
  | `onClosed` | It was hidden. |
10487
11357
 
10488
11358
 
11359
+ ---
11360
+
11361
+ # Popover
11362
+
11363
+ > Feedback · @motifx-community/ui 0.1.0-beta.2
11364
+
11365
+ Content next to the element it belongs to: a title, a close button, a form, a card. It opens on a press or while the pointer rests on its target, follows it, and points at it with an arrow where the design language has one.
11366
+
11367
+ ## Import
11368
+
11369
+ ```tsx
11370
+ import { Popover } from '@motifx-community/ui';
11371
+ ```
11372
+
11373
+ ## From JSX and from code
11374
+
11375
+ The JSX children are the content; `target` names the element or component it opens next to. From code, `content` gives the content and `open()`, `close()` and `toggle()` move it; `value` and `x-model` say whether it is open.
11376
+
11377
+ ```tsx
11378
+ import { reactive } from '@motifx/core';
11379
+ import { Button, Popover, Stack, TextBox } from '@motifx-community/ui';
11380
+
11381
+ /** A popover with a title, a close button and a small form; one made from code for a plain element. */
11382
+ export default function Basic() {
11383
+ const s = reactive({ open: false, name: 'Ada', saved: '' });
11384
+ let button!: Button;
11385
+ let link!: HTMLElement;
11386
+ const coded = new Popover({ title: 'From code', content: new Button({ text: 'OK', variant: 'outline', onclick: () => coded.close() }) });
11387
+
11388
+ return (
11389
+ <Stack orientation="horizontal" wrap align="center">
11390
+ <Button ref={(b: Button) => (button = b)} text="Rename" variant="outline" />
11391
+ <Popover target={() => button} title="New name" showClose x-model={() => s.open}>
11392
+ <Stack orientation="horizontal" wrap align="center">
11393
+ <TextBox label="Name" x-model={() => s.name} />
11394
+ <Button text="Save" tone="accent" onclick={() => ((s.saved = s.name), (s.open = false))} />
11395
+ </Stack>
11396
+ </Popover>
11397
+ <output class="po-saved">{() => (s.saved ? `Saved: ${s.saved}` : s.open ? 'Open' : 'Closed')}</output>
11398
+ <a
11399
+ href="#from-code"
11400
+ class="po-link"
11401
+ ref={(c: { element: HTMLElement }) => (link = c.element)}
11402
+ onclick={(e: Event) => {
11403
+ e.preventDefault();
11404
+ coded.target = link;
11405
+ coded.toggle();
11406
+ }}
11407
+ >
11408
+ A popover from code
11409
+ </a>
11410
+ </Stack>
11411
+ );
11412
+ }
11413
+ ```
11414
+
11415
+ ## While the pointer rests
11416
+
11417
+ `showOn: 'hover'` opens it after `delay` while the pointer rests on the target, and when the target has keyboard focus; the pointer may move onto the popover. It closes `hideDelay` after the pointer leaves both.
11418
+
11419
+ ```tsx
11420
+ import { Avatar, Popover, Stack } from '@motifx-community/ui';
11421
+
11422
+ /** A card that opens while the pointer rests on a name, or when the name has keyboard focus. */
11423
+ export default function Hover() {
11424
+ let name!: HTMLElement;
11425
+ return (
11426
+ <Stack orientation="horizontal" wrap align="center">
11427
+ <span>
11428
+ Reviewed by{' '}
11429
+ <a href="#ada" class="po-person" ref={(c: { element: HTMLElement }) => (name = c.element)} onclick={(e: Event) => e.preventDefault()}>
11430
+ Ada Lovelace
11431
+ </a>
11432
+ </span>
11433
+ <Popover target={() => name} showOn="hover" placement="top" label="Ada Lovelace">
11434
+ <Stack orientation="horizontal" align="center">
11435
+ <Avatar name="Ada Lovelace" size="lg" />
11436
+ <Stack>
11437
+ <strong>Ada Lovelace</strong>
11438
+ <span>Analytical Engine, Programs</span>
11439
+ </Stack>
11440
+ </Stack>
11441
+ </Popover>
11442
+ </Stack>
11443
+ );
11444
+ }
11445
+ ```
11446
+
11447
+ ## Placements, the arrow and a width
11448
+
11449
+ ```tsx
11450
+ import { reactive } from '@motifx/core';
11451
+ import { Button, CheckBox, Popover, Stack, type PopupPlacement } from '@motifx-community/ui';
11452
+
11453
+ const PLACEMENTS: PopupPlacement[] = ['top-start', 'top', 'top-end', 'start', 'end', 'bottom-start', 'bottom', 'bottom-end'];
11454
+
11455
+ /** Every placement; the arrow where the language draws one, and a width of its own. */
11456
+ export default function Placements() {
11457
+ const s = reactive({ arrow: true, placement: 'bottom' as PopupPlacement });
11458
+ let button!: Button;
11459
+ return (
11460
+ <Stack gap="md">
11461
+ <Stack orientation="horizontal" wrap align="center">
11462
+ {PLACEMENTS.map(placement => (
11463
+ <Button key={placement} text={placement} variant={() => (s.placement === placement ? 'solid' : 'outline')} size="sm" onclick={() => (s.placement = placement)} />
11464
+ ))}
11465
+ <CheckBox label="Arrow" x-model={() => s.arrow} />
11466
+ </Stack>
11467
+ <div style="display: flex; justify-content: center; padding: 3rem 0">
11468
+ <Button ref={(b: Button) => (button = b)} text="Open" />
11469
+ </div>
11470
+ <Popover target={() => button} placement={() => s.placement} arrow={() => s.arrow} width="16rem" label="Placement">
11471
+ <p>{() => `Placed at ${s.placement}; it moves to the other side when there is no room.`}</p>
11472
+ </Popover>
11473
+ </Stack>
11474
+ );
11475
+ }
11476
+ ```
11477
+
11478
+ ## Keeping it open
11479
+
11480
+ ```tsx
11481
+ import { reactive } from '@motifx/core';
11482
+ import { Button, Popover, Stack, TextArea } from '@motifx-community/ui';
11483
+
11484
+ /** A press outside does not close it, and onClosing keeps it open while there is unsaved text; Escape and the button close it. */
11485
+ export default function Events() {
11486
+ const s = reactive({ note: '', told: '' });
11487
+ let button!: Button;
11488
+ let pop!: Popover;
11489
+ return (
11490
+ <Stack orientation="horizontal" wrap align="center">
11491
+ <Button ref={(b: Button) => (button = b)} text="Add a note" variant="outline" />
11492
+ <Popover
11493
+ ref={(p: Popover) => (pop = p)}
11494
+ target={() => button}
11495
+ title="Note"
11496
+ closeOnOutside={false}
11497
+ onClosing={e => {
11498
+ if (e.reason === 'escape' && s.note.trim() !== '') {
11499
+ e.cancel = true;
11500
+ s.told = 'Save or clear the note first.';
11501
+ }
11502
+ }}
11503
+ onClosed={reason => (s.told = `Closed: ${String(reason)}`)}
11504
+ >
11505
+ <Stack gap="sm">
11506
+ <TextArea label="Text" x-model={() => s.note} rows={3} />
11507
+ <Button text="Save" tone="accent" onclick={() => ((s.note = ''), pop.close())} />
11508
+ </Stack>
11509
+ </Popover>
11510
+ <output class="po-told">{() => s.told}</output>
11511
+ </Stack>
11512
+ );
11513
+ }
11514
+ ```
11515
+
11516
+ ## Behaviour
11517
+
11518
+ | Topic | How |
11519
+ | --- | --- |
11520
+ | `Opening` | By a press on the target, by the pointer resting on it (`hover`), or from code. It appears in the browser’s top layer, next to the target, and follows it while the page scrolls. |
11521
+ | `Focus` | Opened by a press or from code, focus moves to the first focusable part inside, else to the popover; it goes back to the target when the popover closes. Opened by hover, focus stays where it is. |
11522
+ | `Closing` | Escape, a press outside it and its target, focus leaving both (Tab out), the close button, the target pressed again, or the pointer leaving both (`hover`). `onClosing` may keep it open. |
11523
+ | `Placement` | `placement` names the side and the alignment, as for the kit’s popups; without room on that side it opens on the other. |
11524
+ | `Where it lives` | Made from code, it goes into the nearest container of its target that can hold it, so it stays in the target’s window and landmark. |
11525
+
11526
+ ## Accessibility
11527
+
11528
+ | Topic | How |
11529
+ | --- | --- |
11530
+ | `Role` | `dialog`, named by its title, else by `label`: give it one. |
11531
+ | `Target` | `aria-controls` and `aria-expanded`; `aria-haspopup="dialog"` when a press opens it. |
11532
+ | `Keyboard` | Tab moves through the content and out (which closes it); Escape closes and returns focus. A `hover` popover opens on keyboard focus too. |
11533
+ | `Arrow` | Decorative. |
11534
+
11535
+ ## Styling
11536
+
11537
+ | Hook | What it is |
11538
+ | --- | --- |
11539
+ | `.mx-popover` | The popover. `data-side` (`top`, `bottom`, `start`, `end`), `data-arrow`. |
11540
+ | `.mx-popover__arrow` | The arrow. |
11541
+ | `.mx-popover__header, .mx-popover__title, .mx-popover__close` | The header, its title and the close button. |
11542
+ | `.mx-popover__body` | The content. |
11543
+
11544
+ ### Component tokens
11545
+
11546
+ | Token | What it sets |
11547
+ | --- | --- |
11548
+ | `popover.surface, .arrow, .header, .title, .body` | Units: the surface (`focus`), the arrow (`display`, `size`, its fill and frame), the header, the title and the body. |
11549
+ | `popover.close` | Place: the close button’s look (`variant`). |
11550
+ | `popover.offset, .enter-offset, .header-gap` | The gap to the target, how far it comes in as it appears, the space between title and close button. |
11551
+
11552
+ ## API reference
11553
+
11554
+ ### Props
11555
+
11556
+ | Prop | Type | Default | Description |
11557
+ | --- | --- | --- | --- |
11558
+ | `target` | `Bind<Element \| ComponentBase \| null>` | `null` | The element or component it opens next to. |
11559
+ | `title` | `Bind<string>` | `''` | A title in the header. The same property as `text`. |
11560
+ | `label` | `Bind<string>` | `''` | What screen readers call it when it has no title. |
11561
+ | `content` | `Bind<ComponentBase \| null>` | `null` | Content from code, after the JSX children. |
11562
+ | `showOn` | `Bind<PopoverShowOn>` | `'click'` | `click`: a press on the target toggles it; `hover`: the pointer resting on the target, or keyboard focus on it; `manual`: only code. |
11563
+ | `placement` | `Bind<PopupPlacement>` | `'bottom'` | The side and the alignment; it opens on the other side when there is no room. |
11564
+ | `arrow` | `Bind<boolean>` | `true` | An arrow towards the target, where the design language draws one. |
11565
+ | `showClose` | `Bind<boolean>` | `false` | A close button in the header. |
11566
+ | `width` | `Bind<string \| number \| null>` | `null` | A width of its own (a CSS length, or pixels). |
11567
+ | `closeOnOutside` | `Bind<boolean>` | `true` | A press outside it and its target closes it. |
11568
+ | `delay, hideDelay` | `Bind<number>` | `300`, `200` | Milliseconds the pointer rests on the target before it opens, and it stays after the pointer leaves both (`showOn: 'hover'`). |
11569
+ | `value` | `Bind<boolean>` | `false` | Open or not; `x-model` binds it two-way. |
11570
+
11571
+ ### Events, properties and methods
11572
+
11573
+ | Member | Kind | Description |
11574
+ | --- | --- | --- |
11575
+ | `onOpened` | event | It opened. |
11576
+ | `onClosing` | event | About to close (`reason`); `cancel = true` keeps it open. |
11577
+ | `onClosed` | event | It closed, with the reason: `escape`, `outside`, `focus`, `toggle`, `hover`, `close-button`, `code`. |
11578
+ | `open(), close(reason?), toggle()` | `boolean` / `void` | From code; `open()` is `false` without a target on the page or when disabled. |
11579
+ | `place()` | `void` | Lines it up with its target again, after its content changed size. |
11580
+ | `isOpen` | read-only | Whether it is open now. |
11581
+ | `closeButton, body` | read-only | The close button (the kit’s) and the part that holds the content. |
11582
+
11583
+
11584
+ ---
11585
+
11586
+ # LoadPanel
11587
+
11588
+ > Feedback · @motifx-community/ui 0.1.0-beta.2
11589
+
11590
+ A “loading” layer over a container or the whole page: a shade, a pane with the kit’s spinner and a message, a Cancel button when the work can be stopped. Nothing under it can be used meanwhile, and focus comes back afterwards.
11591
+
11592
+ ## Import
11593
+
11594
+ ```tsx
11595
+ import { LoadPanel } from '@motifx-community/ui';
11596
+ ```
11597
+
11598
+ ## Over a container
11599
+
11600
+ `target` names the component or element it covers; `value` (or `x-model`) shows and hides it, `show()` and `hide()` from code. `delay` keeps quick work from flashing it.
11601
+
11602
+ ```tsx
11603
+ import { reactive } from '@motifx/core';
11604
+ import { Button, LoadPanel, Panel, Stack, TextBox } from '@motifx-community/ui';
11605
+
11606
+ /** A load panel over a panel while its orders load: bound with x-model, shown after a short delay. */
11607
+ export default function Container() {
11608
+ const s = reactive({ loading: false, result: '' });
11609
+ let panel!: Panel;
11610
+
11611
+ // Stands in for a call to the server.
11612
+ const load = () => {
11613
+ s.loading = true;
11614
+ s.result = '';
11615
+ setTimeout(() => {
11616
+ s.loading = false;
11617
+ s.result = 'Orders loaded.';
11618
+ }, 1800);
11619
+ };
11620
+
11621
+ return (
11622
+ <Stack gap="md" style="inline-size: 100%">
11623
+ <Panel class="lp-panel" variant="outline" padding="md" style="min-block-size: 10rem" ref={(c: Panel) => (panel = c)}>
11624
+ <Stack orientation="horizontal" wrap align="center">
11625
+ <TextBox label="Customer" value="Ada" />
11626
+ <Button text="Load orders" tone="accent" onclick={load} />
11627
+ </Stack>
11628
+ </Panel>
11629
+ <LoadPanel target={() => panel} message="Loading orders" delay={200} x-model={() => s.loading} />
11630
+ <output class="lp-result">{() => s.result}</output>
11631
+ </Stack>
11632
+ );
11633
+ }
11634
+ ```
11635
+
11636
+ ## Over the page, with Cancel
11637
+
11638
+ ```tsx
11639
+ import { reactive } from '@motifx/core';
11640
+ import { Button, LoadPanel, Stack } from '@motifx-community/ui';
11641
+
11642
+ /** Over the whole page, with a Cancel button: the work stops when it is pressed (or on Escape). */
11643
+ export default function Page() {
11644
+ const s = reactive({ told: '' });
11645
+ let timer: ReturnType<typeof setTimeout> | null = null;
11646
+ const panel = new LoadPanel({
11647
+ message: 'Building the report…',
11648
+ cancelable: true,
11649
+ onCancel: () => {
11650
+ if (timer) clearTimeout(timer);
11651
+ timer = null;
11652
+ s.told = 'Cancelled.';
11653
+ }
11654
+ });
11655
+ const start = () => {
11656
+ s.told = '';
11657
+ panel.show();
11658
+ timer = setTimeout(() => {
11659
+ timer = null;
11660
+ panel.hide();
11661
+ s.told = 'The report is ready.';
11662
+ }, 4000);
11663
+ };
11664
+ return (
11665
+ <Stack orientation="horizontal" wrap align="center">
11666
+ <Button text="Build the report" variant="outline" onclick={start} />
11667
+ <span onConfig={c => c.controls.add(panel)} />
11668
+ <output class="lp-told">{() => s.told}</output>
11669
+ </Stack>
11670
+ );
11671
+ }
11672
+ ```
11673
+
11674
+ ## Shade, pane and indicator
11675
+
11676
+ ```tsx
11677
+ import { reactive } from '@motifx/core';
11678
+ import { Button, LoadPanel, Panel, Stack } from '@motifx-community/ui';
11679
+
11680
+ /** Without the shade, without the pane, without the indicator; a press on the shade may hide it. */
11681
+ export default function Options() {
11682
+ const s = reactive({ clear: false, bare: false, words: false });
11683
+ let clear!: Panel;
11684
+ let bare!: Panel;
11685
+ let words!: Panel;
11686
+ const flash = (key: 'clear' | 'bare' | 'words') => {
11687
+ s[key] = true;
11688
+ setTimeout(() => (s[key] = false), 2500);
11689
+ };
11690
+ return (
11691
+ <Stack orientation="horizontal" wrap align="center" style="inline-size: 100%">
11692
+ <Panel variant="outline" padding="md" style="min-inline-size: 16rem; min-block-size: 9rem" ref={(c: Panel) => (clear = c)}>
11693
+ <Button text="No shade" variant="outline" onclick={() => flash('clear')} />
11694
+ </Panel>
11695
+ <LoadPanel target={() => clear} shade={false} x-model={() => s.clear} closeOnOutside />
11696
+ <Panel variant="outline" padding="md" style="min-inline-size: 16rem; min-block-size: 9rem" ref={(c: Panel) => (bare = c)}>
11697
+ <Button text="No pane" variant="outline" onclick={() => flash('bare')} />
11698
+ </Panel>
11699
+ <LoadPanel target={() => bare} showPane={false} x-model={() => s.bare} />
11700
+ <Panel variant="outline" padding="md" style="min-inline-size: 16rem; min-block-size: 9rem" ref={(c: Panel) => (words = c)}>
11701
+ <Button text="Words only" variant="outline" onclick={() => flash('words')} />
11702
+ </Panel>
11703
+ <LoadPanel target={() => words} showIndicator={false} message="Please wait" x-model={() => s.words} />
11704
+ </Stack>
11705
+ );
11706
+ }
11707
+ ```
11708
+
11709
+ ## Behaviour
11710
+
11711
+ | Topic | How |
11712
+ | --- | --- |
11713
+ | `Over a container` | It goes inside the container, over everything in it; the container is `aria-busy` and what is under the panel is inert: nothing there can be pressed or focused. |
11714
+ | `Over the page` | Without a `target`, it covers the viewport and the rest of the page is inert. |
11715
+ | `Focus` | Focus that was under it waits on the panel (on the Cancel button when there is one) and goes back where it was when the panel hides. |
11716
+ | `Delay` | Quick work shows nothing: it comes after `delay`, and a hide before that cancels it. |
11717
+ | `Spinner.cover` | The kit’s spinner covers a container from code in one call (`Spinner.cover`); the load panel is the component with the pane, the message, the delay and the button. |
11718
+
11719
+ ## Accessibility
11720
+
11721
+ | Topic | How |
11722
+ | --- | --- |
11723
+ | `Pane` | A `status` region: the message is read when the panel appears, and again when it changes. |
11724
+ | `Indicator` | Decorative; the message says what is going on. |
11725
+ | `Under it` | `inert` and `aria-busy`, so readers skip it and nothing there takes a press or focus. |
11726
+ | `Cancel` | The kit’s button, named in the kit language; Escape presses it. |
11727
+
11728
+ ## Styling
11729
+
11730
+ | Hook | What it is |
11731
+ | --- | --- |
11732
+ | `.mx-load-panel` | The layer. `data-shade`, `data-pane`, `data-page`. |
11733
+ | `.mx-load-panel__pane` | The pane. |
11734
+ | `.mx-load-panel__indicator, .mx-load-panel__message, .mx-load-panel__cancel` | The spinner, the message and the button. |
11735
+
11736
+ ### Component tokens
11737
+
11738
+ | Token | What it sets |
11739
+ | --- | --- |
11740
+ | `load-panel.shade, .pane, .message` | Units: the layer (`shaded`), the pane (`shown`), the message. |
11741
+ | `load-panel.cancel` | Place: the Cancel button’s look (`variant`). |
11742
+ | `load-panel.padding, .gap` | The least space to the edge of what it covers; the space between the indicator, the message and the button. |
11743
+
11744
+ ## API reference
11745
+
11746
+ ### Props
11747
+
11748
+ | Prop | Type | Default | Description |
11749
+ | --- | --- | --- | --- |
11750
+ | `target` | `Bind<ComponentBase \| HTMLElement \| null>` | `null` | What it covers: a component or an element; `null` covers the whole page. |
11751
+ | `message` | `Bind<string>` | the kit’s “Loading…” | The message under the indicator. The same property as `text`. |
11752
+ | `value` | `Bind<boolean>` | `false` | Shown or not; `x-model` binds it two-way. |
11753
+ | `delay` | `Bind<number>` | `0` | Milliseconds before it shows; a hide before that shows nothing. |
11754
+ | `shade` | `Bind<boolean>` | `true` | Dims what it covers. |
11755
+ | `showPane` | `Bind<boolean>` | `true` | The box behind the indicator and the message. |
11756
+ | `showIndicator` | `Bind<boolean>` | `true` | The turning indicator (the kit’s spinner). |
11757
+ | `cancelable` | `Bind<boolean>` | `false` | A Cancel button in the pane; Escape presses it too. |
11758
+ | `cancelText` | `Bind<string>` | the kit’s “Cancel” | The button’s text. |
11759
+ | `closeOnOutside` | `Bind<boolean>` | `false` | A press on the shade hides it. |
11760
+
11761
+ ### Events, properties and methods
11762
+
11763
+ | Member | Kind | Description |
11764
+ | --- | --- | --- |
11765
+ | `onShown, onHidden` | event | It came on the screen (after its delay); it went. |
11766
+ | `onCancel` | event | The Cancel button was pressed, or Escape; the panel hides after. |
11767
+ | `show(), hide(), cancel()` | `boolean` / `void` | From code; `show()` is `false` while it is shown or waiting for its delay. |
11768
+ | `isShown` | read-only | Whether it is on the screen now. |
11769
+ | `spinner, cancelButton` | read-only | The kit’s spinner and button in the pane. |
11770
+
11771
+
10489
11772
  ---
10490
11773
 
10491
11774
  # Toast
10492
11775
 
10493
- > Feedback · @motifx-community/ui 0.1.0-beta.1
11776
+ > Feedback · @motifx-community/ui 0.1.0-beta.2
10494
11777
 
10495
11778
  Short notifications at an edge of the window: four tones, an action such as Undo, a time of their own or none, six positions and a limit on how many show at once. Called from code; a region of your own can sit in JSX.
10496
11779
 
@@ -10709,7 +11992,7 @@ The name of the region and of the close button come from `uiLocale.strings` (`no
10709
11992
 
10710
11993
  ```tsx
10711
11994
  import { reactive } from '@motifx/core';
10712
- import { Button, enStrings, toast, trStrings, uiLocale } from '@motifx-community/ui';
11995
+ import { Button, toast, uiLocale } from '@motifx-community/ui';
10713
11996
 
10714
11997
  /** Switches the names of the region and the close button. */
10715
11998
  export default function Localization() {
@@ -10717,7 +12000,7 @@ export default function Localization() {
10717
12000
 
10718
12001
  const toggle = () => {
10719
12002
  s.lang = s.lang === 'en' ? 'tr' : 'en';
10720
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
12003
+ void uiLocale.use(s.lang);
10721
12004
  };
10722
12005
 
10723
12006
  return (
@@ -10807,7 +12090,7 @@ export default function Localization() {
10807
12090
 
10808
12091
  # Badge
10809
12092
 
10810
- > Display · @motifx-community/ui 0.1.0-beta.1
12093
+ > Display · @motifx-community/ui 0.1.0-beta.2
10811
12094
 
10812
12095
  A short text, a count or a dot: in a line of text, or on a corner of a button, an avatar or an icon. A count over its maximum shows “99+”, a count of zero hides.
10813
12096
 
@@ -11004,7 +12287,7 @@ A count is written in the kit language (`uiLocale`), again when it changes: “1
11004
12287
 
11005
12288
  # Avatar and AvatarGroup
11006
12289
 
11007
- > Display · @motifx-community/ui 0.1.0-beta.1
12290
+ > Display · @motifx-community/ui 0.1.0-beta.2
11008
12291
 
11009
12292
  Someone’s picture, or their initials, or a person icon, with their presence on its corner. A group stacks or spreads them and counts the ones it does not show.
11010
12293
 
@@ -11246,7 +12529,7 @@ Initials are written in the capitals of the kit language (`uiLocale`): “ilgin
11246
12529
 
11247
12530
  # Chip and ChipGroup
11248
12531
 
11249
- > Display · @motifx-community/ui 0.1.0-beta.1
12532
+ > Display · @motifx-community/ui 0.1.0-beta.2
11250
12533
 
11251
12534
  A short text with an icon or an avatar before it: a filter to turn on, a choice among a few, or something picked that can be removed. A group selects one or several and moves between them with the arrow keys.
11252
12535
 
@@ -11528,7 +12811,7 @@ The remove button’s name is the kit text `removeItem` (“Remove {text}”) an
11528
12811
 
11529
12812
  # Card
11530
12813
 
11531
- > Display · @motifx-community/ui 0.1.0-beta.1
12814
+ > Display · @motifx-community/ui 0.1.0-beta.2
11532
12815
 
11533
12816
  A surface holding one thing: a picture, a header with an avatar and titles, content and a row of actions. Parts with nothing in them are left out.
11534
12817
 
@@ -11786,7 +13069,7 @@ export default function Sizes() {
11786
13069
 
11787
13070
  # Skeleton
11788
13071
 
11789
- > Display · @motifx-community/ui 0.1.0-beta.1
13072
+ > Display · @motifx-community/ui 0.1.0-beta.2
11790
13073
 
11791
13074
  The shape of what is loading, so the page keeps its layout while data arrives. Given content, it shows the content in the same place once loading ends.
11792
13075
 
@@ -11921,7 +13204,7 @@ export default function Animations() {
11921
13204
 
11922
13205
  # Tabs
11923
13206
 
11924
- > Navigation · @motifx-community/ui 0.1.0-beta.1
13207
+ > Navigation · @motifx-community/ui 0.1.0-beta.2
11925
13208
 
11926
13209
  Tabs show one panel at a time under a strip of tabs: from JSX or from code, closable, with icons and badges, scroll buttons when the tabs do not fit, four placements and panels built when they are first shown.
11927
13210
 
@@ -12267,7 +13550,7 @@ Tabs write one text: the close button's tooltip, `uiLocale.strings.close`. Every
12267
13550
 
12268
13551
  ```tsx
12269
13552
  import { reactive } from '@motifx/core';
12270
- import { Button, enStrings, trStrings, uiLocale } from '@motifx-community/ui';
13553
+ import { Button, uiLocale } from '@motifx-community/ui';
12271
13554
  import { kitTexts } from '../../../shared/kit-texts';
12272
13555
 
12273
13556
  /** Switches the texts of every component on the page, the tabs' close button included. */
@@ -12275,7 +13558,7 @@ export default function Localization() {
12275
13558
  const s = reactive({ lang: 'en' });
12276
13559
  const toggle = () => {
12277
13560
  s.lang = s.lang === 'en' ? 'tr' : 'en';
12278
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
13561
+ void uiLocale.use(s.lang);
12279
13562
  };
12280
13563
  return (
12281
13564
  <>
@@ -12381,7 +13664,7 @@ export default function Localization() {
12381
13664
 
12382
13665
  # Breadcrumb
12383
13666
 
12384
- > Navigation · @motifx-community/ui 0.1.0-beta.1
13667
+ > Navigation · @motifx-community/ui 0.1.0-beta.2
12385
13668
 
12386
13669
  The way to the current page: each step a link or a button, the current page last. Steps that do not fit go into a menu after the first.
12387
13670
 
@@ -12393,7 +13676,7 @@ import { Breadcrumb } from '@motifx-community/ui';
12393
13676
 
12394
13677
  ## Links and buttons
12395
13678
 
12396
- A step with `href` is a link; `rel=&quot;router&quot;` lets the MotifJS router take it. A step without one is a button: `onItemClick` tells it.
13679
+ A step with `href` is a link; `rel='router'` lets the MotifJS router take it. A step without one is a button: `onItemClick` tells it.
12397
13680
 
12398
13681
  ```tsx
12399
13682
  import { reactive } from '@motifx/core';
@@ -12510,7 +13793,7 @@ export default function Sizes() {
12510
13793
 
12511
13794
  # Pagination
12512
13795
 
12513
- > Navigation · @motifx-community/ui 0.1.0-beta.1
13796
+ > Navigation · @motifx-community/ui 0.1.0-beta.2
12514
13797
 
12515
13798
  Moving through pages of items: the sizes to choose from, where the page stands, the steps and a button per page around the current one. It turns compact when it does not fit. It looks and works as the grid’s pager.
12516
13799
 
@@ -12625,11 +13908,497 @@ export default function Looks() {
12625
13908
  | `compact` | read-only | Whether the compact look shows now. |
12626
13909
 
12627
13910
 
13911
+ ---
13912
+
13913
+ # Stepper
13914
+
13915
+ > Navigation · @motifx-community/ui 0.1.0-beta.2
13916
+
13917
+ The steps of a longer task and where the user stands in them: an indicator and a text per step, a line between them, the steps before the current one completed. The [Wizard](wizard.md) adds a page and the buttons to each step.
13918
+
13919
+ ## Import
13920
+
13921
+ ```tsx
13922
+ import { Stepper } from '@motifx-community/ui';
13923
+ ```
13924
+
13925
+ ## From JSX and from code
13926
+
13927
+ The current step is `value`: a step’s `key`, else its index; `x-model` binds it two-way. From code, `next()`, `previous()` and `goTo()` move it and `onStepChanged` tells.
13928
+
13929
+ ```tsx
13930
+ import { reactive } from '@motifx/core';
13931
+ import { Button, Stack, Stepper } from '@motifx-community/ui';
13932
+
13933
+ /** A stepper bound with x-model, and one made from code and moved with its own methods. */
13934
+ export default function FromCode() {
13935
+ const s = reactive({ step: 0 as string | number | null, at: 0, told: '' });
13936
+ const coded = new Stepper({
13937
+ label: 'Order',
13938
+ items: ['Cart', 'Address', 'Payment', 'Done'],
13939
+ linear: false,
13940
+ onStepChanged: e => {
13941
+ s.at = e.index;
13942
+ s.told = `Step ${e.index + 1}${e.byUser ? ', pressed' : ''}`;
13943
+ }
13944
+ });
13945
+
13946
+ return (
13947
+ <Stack gap="lg" style="inline-size: 100%">
13948
+ <Stepper label="Sign up" items={['Account', 'Profile', 'Review']} x-model={() => s.step} />
13949
+ <output class="st-value">{() => `value: ${JSON.stringify(s.step)}`}</output>
13950
+ <span onConfig={c => c.controls.add(coded)} />
13951
+ <Stack orientation="horizontal" wrap align="center">
13952
+ <Button text="Back" variant="outline" enabled={() => s.at > 0} onclick={() => void coded.previous()} />
13953
+ <Button text="Next" variant="outline" enabled={() => s.at < 3} onclick={() => void coded.next()} />
13954
+ <output class="st-told">{() => s.told}</output>
13955
+ </Stack>
13956
+ </Stack>
13957
+ );
13958
+ }
13959
+ ```
13960
+
13961
+ ## Statuses
13962
+
13963
+ The steps before the current one are completed by themselves. An item may say `status: 'done'` or `'error'` whatever the current step is, be `optional`, be disabled, or carry an `icon` in place of its number; its fields may be functions of your state.
13964
+
13965
+ | Status | How |
13966
+ | --- | --- |
13967
+ | `pending` | A step to come: its number in the indicator. |
13968
+ | `current` | The step in hand: `aria-current="step"`. |
13969
+ | `done` | The steps before the current one, and any step whose item says `status: 'done'`: a check in the indicator, the line before it filled. |
13970
+ | `error` | A step whose item says `status: 'error'`: a mark in the indicator, the text in the danger colour; read out as “Needs attention”. |
13971
+ | `optional` | Says “Optional” under the text; in linear order it may be skipped. |
13972
+ | `disabled` | An item with `enabled: false`, or a step linear order does not reach yet: `aria-disabled`, out of the Tab order. |
13973
+
13974
+ ```tsx
13975
+ import { reactive } from '@motifx/core';
13976
+ import { Button, Stack, Stepper } from '@motifx-community/ui';
13977
+
13978
+ const pencil = () => {
13979
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
13980
+ svg.setAttribute('viewBox', '0 0 16 16');
13981
+ svg.setAttribute('aria-hidden', 'true');
13982
+ svg.innerHTML = '<path d="M11.5 2.5l2 2L5 13H3v-2z" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/>';
13983
+ return svg;
13984
+ };
13985
+
13986
+ /** Completed and failed steps told by the items, an optional step, a disabled one, an icon in place of the number. */
13987
+ export default function Statuses() {
13988
+ const s = reactive({ paid: false });
13989
+ const items = [
13990
+ { text: 'Cart', status: 'done' as const },
13991
+ { text: 'Address', description: 'Checked', status: 'done' as const },
13992
+ { text: 'Payment', description: () => (s.paid ? 'Paid' : 'Card declined'), status: () => (s.paid ? 'done' : 'error') },
13993
+ { text: 'Gift note', optional: true, icon: pencil() },
13994
+ { text: 'Pick-up', enabled: false },
13995
+ { text: 'Done' }
13996
+ ];
13997
+ return (
13998
+ <Stack gap="md" style="inline-size: 100%">
13999
+ <Stepper label="Statuses" items={items} value={5} linear={false} />
14000
+ <Button text={() => (s.paid ? 'Decline the card' : 'Take the payment')} variant="outline" onclick={() => (s.paid = !s.paid)} />
14001
+ </Stack>
14002
+ );
14003
+ }
14004
+ ```
14005
+
14006
+ ## In order, or free
14007
+
14008
+ `linear` (the default) lets a press reach only the completed steps and the next one; `linear={false}` lets it reach any. Either way `onStepChanging` is asked first: `cancel` keeps the step, a `promise` waits for a check or a server.
14009
+
14010
+ ```tsx
14011
+ import { reactive } from '@motifx/core';
14012
+ import { CheckBox, Stack, Stepper } from '@motifx-community/ui';
14013
+
14014
+ /** In linear order a step is reached only after the ones before it; `onStepChanging` refuses a step while the box is unchecked. */
14015
+ export default function Linear() {
14016
+ const s = reactive({ step: 0 as string | number | null, agreed: false, note: '' });
14017
+ return (
14018
+ <Stack gap="md" style="inline-size: 100%">
14019
+ <Stepper
14020
+ label="In order"
14021
+ items={['Terms', 'Details', 'Confirm']}
14022
+ x-model={() => s.step}
14023
+ onStepChanging={e => {
14024
+ if (e.to > 0 && !s.agreed) {
14025
+ e.cancel = true;
14026
+ s.note = 'Accept the terms first.';
14027
+ } else {
14028
+ s.note = '';
14029
+ }
14030
+ }}
14031
+ />
14032
+ <CheckBox label="I accept the terms" x-model={() => s.agreed} />
14033
+ <output class="st-note">{() => s.note}</output>
14034
+ </Stack>
14035
+ );
14036
+ }
14037
+ ```
14038
+
14039
+ ## Orientations
14040
+
14041
+ ```tsx
14042
+ import { Stack, Stepper } from '@motifx-community/ui';
14043
+
14044
+ const STEPS = [
14045
+ { text: 'Details', description: 'Name and e-mail' },
14046
+ { text: 'Address', description: 'Where to send it' },
14047
+ { text: 'Payment', description: 'Card or transfer' },
14048
+ { text: 'Review' }
14049
+ ];
14050
+
14051
+ /** Horizontal with the texts under or after the indicators, and vertical. */
14052
+ export default function Orientations() {
14053
+ return (
14054
+ <Stack gap="lg" style="inline-size: 100%">
14055
+ <Stepper label="Texts under" items={STEPS} value={1} linear={false} />
14056
+ <Stepper label="Texts after" items={STEPS.slice(0, 3)} value={1} labelPosition="end" linear={false} />
14057
+ <div style="inline-size: 18rem">
14058
+ <Stepper label="Standing" items={STEPS} value={1} orientation="vertical" linear={false} />
14059
+ </div>
14060
+ </Stack>
14061
+ );
14062
+ }
14063
+ ```
14064
+
14065
+ ## Sizes
14066
+
14067
+ ```tsx
14068
+ import { Stack, Stepper } from '@motifx-community/ui';
14069
+
14070
+ const STEPS = ['Plan', 'Build', 'Ship'];
14071
+
14072
+ /** Three sizes, and a stepper without numbers. */
14073
+ export default function Sizes() {
14074
+ return (
14075
+ <Stack gap="lg" style="inline-size: 100%">
14076
+ <Stepper label="Small" items={STEPS} value={1} size="sm" linear={false} />
14077
+ <Stepper label="Medium" items={STEPS} value={1} linear={false} />
14078
+ <Stepper label="Large" items={STEPS} value={1} size="lg" linear={false} />
14079
+ <Stepper label="Dots" items={STEPS} value={1} showNumbers={false} size="sm" labelPosition="end" linear={false} />
14080
+ </Stack>
14081
+ );
14082
+ }
14083
+ ```
14084
+
14085
+ ## Keyboard
14086
+
14087
+ | Key | What it does |
14088
+ | --- | --- |
14089
+ | `Tab` | One stop: the step focused last, else the current one, else the first that can be reached. |
14090
+ | `Arrow keys` | Left and Right (Up and Down standing) move between the steps that can be reached, around the ends; Home and End go to the first and the last. |
14091
+ | `Enter, Space` | Choose the focused step; `onStepChanging` may refuse. |
14092
+
14093
+ ## Accessibility
14094
+
14095
+ | Topic | How |
14096
+ | --- | --- |
14097
+ | `Landmark` | A `nav` named “Steps” in the kit language, holding an ordered list; several on one page: give each its own `label`. |
14098
+ | `A step` | A button whose name reads “Step 2 of 4, Address, Where to send it, Completed”: the position, the texts and the status are all in it. |
14099
+ | `Not clickable` | Plain elements: nothing to press, the current one still `aria-current`. |
14100
+ | `Lines and marks` | Decorative, hidden from readers. |
14101
+
14102
+ ## Styling
14103
+
14104
+ | Hook | What it is |
14105
+ | --- | --- |
14106
+ | `.mx-stepper` | The stepper. `data-orientation`, `data-labels`, `data-size`. |
14107
+ | `.mx-stepper__list, .mx-stepper__item` | The list and each step with its line. `data-status` on the item. |
14108
+ | `.mx-stepper__step` | The step: a button or a div. `data-status`, `aria-current`, `aria-disabled`. |
14109
+ | `.mx-stepper__indicator, .mx-stepper__number, .mx-stepper__mark, .mx-stepper__icon` | The circle, the number in it, the check or error mark, an icon of your own. |
14110
+ | `.mx-stepper__label, .mx-stepper__description, .mx-stepper__note` | The texts. |
14111
+ | `.mx-stepper__line` | The line to the next step. `data-status="done"` up to the current one. |
14112
+
14113
+ ### Component tokens
14114
+
14115
+ | Token | What it sets |
14116
+ | --- | --- |
14117
+ | `stepper.step, .indicator, .mark, .label, .description, .note, .line` | Units: the step (`hover`, `pressed`, `focus`, `disabled`, `current`, `done`, `error`), its indicator, the mark (`icon` per state), the texts, the line (`done`); the line turns a quarter in a vertical stepper. |
14118
+ | `stepper.size.*, .font-size.*, .padding.*` | The indicator, the text and the space around a step, per size. |
14119
+ | `stepper.description-font-size, .gap, .line-gap, .line-min-length` | The second line, the space between indicator and texts, and the line’s margins and least length. |
14120
+
14121
+ ## API reference
14122
+
14123
+ ### Props
14124
+
14125
+ | Prop | Type | Default | Description |
14126
+ | --- | --- | --- | --- |
14127
+ | `items` | `Bind<readonly (StepperItem \| string)[]>` | `[]` | The steps in order: `StepperItem`s (`text`, `description`, `key`, `icon`, `status`, `optional`, `enabled`, `data`) or plain texts. |
14128
+ | `value` | `Bind<string \| number \| null>` | `0` | The current step: its `key`, else its index; `null` for none. `x-model` binds it two-way. |
14129
+ | `linear` | `Bind<boolean>` | `true` | A press reaches a completed step, or the one right after the last completed; optional steps may be skipped. |
14130
+ | `orientation` | `Bind<StepperOrientation>` | `'horizontal'` | `horizontal` or `vertical`. |
14131
+ | `labelPosition` | `Bind<StepperLabelPosition>` | `'bottom'` | Horizontal only: the texts under the indicator (`bottom`) or after it (`end`). |
14132
+ | `size` | `Bind<ControlSize>` | `'md'` | `sm`, `md`, `lg`. |
14133
+ | `clickable` | `Bind<boolean>` | `true` | `false` shows the way only: no buttons, no Tab stop. |
14134
+ | `showNumbers` | `Bind<boolean>` | `true` | The indicator of a step to come shows its number. |
14135
+ | `label` | `Bind<string>` | the kit’s “Steps” | What screen readers call it. |
14136
+
14137
+ ### Events, properties and methods
14138
+
14139
+ | Member | Kind | Description |
14140
+ | --- | --- | --- |
14141
+ | `onStepChanging` | event | The current step is about to change (`from`, `to`, `fromItem`, `toItem`, `byUser`). `cancel = true` keeps it; `promise` set to a `Promise<boolean>` waits, and the step changes when it resolves to `true`. |
14142
+ | `onStepChanged` | event | The current step changed (`index`, `item`, `previous`, `byUser`). |
14143
+ | `selectedIndex` | read-only | The index of the current step; -1 when there is none. |
14144
+ | `count` | read-only | How many steps there are. |
14145
+ | `canGoNext, canGoPrevious` | read-only | There is an enabled step after, or before, the current one. |
14146
+ | `next(), previous()` | `Promise<boolean>` | Goes to the next or the previous enabled step; `false` when there is none or the change was refused. |
14147
+ | `goTo(step)` | `Promise<boolean>` | Goes to a step by index or key, whatever the order; `onStepChanging` is asked first. |
14148
+ | `statusOf(index)` | `StepperStatus` | `pending`, `current`, `done` or `error`, as drawn. |
14149
+ | `canReach(index)` | `boolean` | Whether a press may reach the step. |
14150
+ | `refresh()` | `void` | Reads the items again after they were changed in place. |
14151
+
14152
+
14153
+ ---
14154
+
14155
+ # Wizard
14156
+
14157
+ > Navigation · @motifx-community/ui 0.1.0-beta.2
14158
+
14159
+ A task in steps: a [Stepper](stepper.md) above or beside one page per step, and the Back and Next buttons under them. Next validates the page first; on the last step it finishes.
14160
+
14161
+ ## Import
14162
+
14163
+ ```tsx
14164
+ import { Wizard, WizardStep } from '@motifx-community/ui';
14165
+ ```
14166
+
14167
+ ## Pages from JSX
14168
+
14169
+ Each `WizardStep` is a step and its page. Next validates the kit’s fields on the page, then the step’s own `validate`; a page that fails keeps the wizard, marks its step and focuses the first invalid field. On the last step Next reads Finish and raises `onFinished`.
14170
+
14171
+ ```tsx
14172
+ import { reactive } from '@motifx/core';
14173
+ import { CheckBox, Stack, TextBox, Wizard, WizardStep } from '@motifx-community/ui';
14174
+
14175
+ /** Three pages with the kit's fields: Next validates the page first; Finish tells the app. */
14176
+ export default function Basic() {
14177
+ const s = reactive({ name: '', email: '', city: '', agreed: false, result: '' });
14178
+ return (
14179
+ <Stack gap="md" style="inline-size: 100%">
14180
+ <Wizard label="Sign up" onFinished={() => (s.result = `Welcome, ${s.name}.`)}>
14181
+ <WizardStep title="Account" description="Who you are">
14182
+ <Stack orientation="horizontal" wrap align="center">
14183
+ <TextBox label="Name" x-model={() => s.name} required />
14184
+ <TextBox label="E-mail" x-model={() => s.email} required rules={[{ type: 'email' }]} />
14185
+ </Stack>
14186
+ </WizardStep>
14187
+ <WizardStep title="Address" description="Where you live">
14188
+ <TextBox label="City" x-model={() => s.city} required />
14189
+ </WizardStep>
14190
+ <WizardStep title="Review" validate={() => s.agreed}>
14191
+ <p>{() => `${s.name || '—'}, ${s.email || '—'}, ${s.city || '—'}`}</p>
14192
+ <CheckBox label="Everything is right" x-model={() => s.agreed} />
14193
+ </WizardStep>
14194
+ </Wizard>
14195
+ <output class="wz-result">{() => s.result}</output>
14196
+ </Stack>
14197
+ );
14198
+ }
14199
+ ```
14200
+
14201
+ ## From code
14202
+
14203
+ `steps` makes the steps from props, each page from a `content` factory when it is first shown; `add`, `insert` and `remove` change them later. `next()`, `previous()`, `goTo()` and `finish()` move it.
14204
+
14205
+ ```tsx
14206
+ import { Component, reactive } from '@motifx/core';
14207
+ import { Button, Stack, Wizard, WizardStep } from '@motifx-community/ui';
14208
+
14209
+ // A page made from code: any MotifJS component.
14210
+ class Note extends Component<HTMLDivElement, { text: string }> {
14211
+ override view() {
14212
+ return <p>{this.props.text}</p>;
14213
+ }
14214
+ }
14215
+
14216
+ /** A wizard made from code: its steps as props with content factories, moved with its methods, a step added later. */
14217
+ export default function FromCode() {
14218
+ const s = reactive({ told: '' });
14219
+ const wizard = new Wizard({
14220
+ label: 'Setup',
14221
+ steps: [
14222
+ { title: 'Welcome', content: () => new Note({ text: 'A page made by a factory, built when first shown.' }) },
14223
+ { title: 'Options', description: 'Pick what you need', content: () => new Note({ text: 'The second page.' }) },
14224
+ { title: 'Done', content: () => new Note({ text: 'The last page; Next reads Finish here.' }) }
14225
+ ],
14226
+ onStepChanged: e => (s.told = `Step ${e.index + 1}: ${(e.item as { text: string }).text}`),
14227
+ onFinished: () => (s.told = 'Finished.')
14228
+ });
14229
+ const addStep = () => {
14230
+ wizard.insert(2, new WizardStep({ title: 'Extra', optional: true, content: () => new Note({ text: 'Added from code.' }) }));
14231
+ };
14232
+ return (
14233
+ <Stack gap="md" style="inline-size: 100%">
14234
+ <span onConfig={c => c.controls.add(wizard)} />
14235
+ <Stack orientation="horizontal" wrap align="center">
14236
+ <Button text="Go to Done" variant="outline" onclick={() => void wizard.goTo(wizard.steps.length - 1)} />
14237
+ <Button text="Add a step" variant="outline" onclick={addStep} />
14238
+ <output class="wz-told">{() => s.told}</output>
14239
+ </Stack>
14240
+ </Stack>
14241
+ );
14242
+ }
14243
+ ```
14244
+
14245
+ ## Standing
14246
+
14247
+ ```tsx
14248
+ import { reactive } from '@motifx/core';
14249
+ import { RadioGroup, Switch, TextArea, Wizard, WizardStep } from '@motifx-community/ui';
14250
+
14251
+ /** The stepper beside the pages, the texts after the indicators. */
14252
+ export default function Vertical() {
14253
+ const s = reactive({ plan: 'Team', notify: true, note: '' });
14254
+ return (
14255
+ <Wizard label="Subscription" orientation="vertical" style="min-block-size: 16rem; inline-size: 100%">
14256
+ <WizardStep title="Plan" description="What you pay for">
14257
+ <RadioGroup label="Plan" items={['Solo', 'Team', 'Business']} x-model={() => s.plan} />
14258
+ </WizardStep>
14259
+ <WizardStep title="Alerts" description="How we reach you">
14260
+ <Switch label="Send me a monthly summary" x-model={() => s.notify} />
14261
+ </WizardStep>
14262
+ <WizardStep title="Notes" optional>
14263
+ <TextArea label="Anything else?" x-model={() => s.note} rows={3} />
14264
+ </WizardStep>
14265
+ </Wizard>
14266
+ );
14267
+ }
14268
+ ```
14269
+
14270
+ ## Your own buttons, finishing that waits
14271
+
14272
+ `showNavigation={false}` takes the bar away; your own buttons call the methods. `onFinishing` may set a `promise`: the wizard finishes when it resolves to `true`, and stays otherwise.
14273
+
14274
+ ```tsx
14275
+ import { reactive } from '@motifx/core';
14276
+ import { Button, Stack, TextBox, Wizard, WizardStep } from '@motifx-community/ui';
14277
+
14278
+ /** No bar: buttons of your own drive it; finishing waits for a promise (a server) and may be refused. */
14279
+ export default function Custom() {
14280
+ const s = reactive({ code: '', busy: false, note: '' });
14281
+ let wizard!: Wizard;
14282
+ const finish = () => {
14283
+ s.note = '';
14284
+ void wizard.finish().then(ok => (s.note = ok ? 'Saved.' : s.note || 'Not finished.'));
14285
+ };
14286
+ return (
14287
+ <Stack gap="md" style="inline-size: 100%">
14288
+ <Wizard
14289
+ ref={(w: Wizard) => (wizard = w)}
14290
+ label="Redeem"
14291
+ showNavigation={false}
14292
+ labelPosition="end"
14293
+ onFinishing={e => {
14294
+ s.busy = true;
14295
+ e.promise = new Promise<boolean>(resolve => setTimeout(() => resolve(s.code.toUpperCase() === 'MOTIF'), 600)).then(ok => {
14296
+ s.busy = false;
14297
+ if (!ok) s.note = 'That code is not known.';
14298
+ return ok;
14299
+ });
14300
+ }}
14301
+ >
14302
+ <WizardStep title="Code">
14303
+ <TextBox label="Gift code" x-model={() => s.code} required placeholder="MOTIF" />
14304
+ </WizardStep>
14305
+ <WizardStep title="Confirm">
14306
+ <p>{() => `Redeem “${s.code}”?`}</p>
14307
+ </WizardStep>
14308
+ </Wizard>
14309
+ <Stack orientation="horizontal" wrap align="center">
14310
+ <Button text="Back" variant="outline" onclick={() => void wizard.previous()} />
14311
+ <Button text="Next" variant="outline" onclick={() => void wizard.next()} />
14312
+ <Button text="Redeem" busy={() => s.busy} onclick={finish} />
14313
+ <output class="wz-note">{() => s.note}</output>
14314
+ </Stack>
14315
+ </Stack>
14316
+ );
14317
+ }
14318
+ ```
14319
+
14320
+ ## Accessibility
14321
+
14322
+ | Topic | How |
14323
+ | --- | --- |
14324
+ | `Stepper` | A `nav` of steps as on the [Stepper](stepper.md) page: each a button with its position and status in its name, one Tab stop. |
14325
+ | `Page` | A `group` named after its step; the hidden pages are out of the tree. |
14326
+ | `Validation` | A page that fails keeps focus on its first invalid field, with its message; the step reads “Needs attention”. |
14327
+ | `Buttons` | The kit’s buttons, named in the kit language: “Back”, “Next”, “Finish”. |
14328
+
14329
+ ## Styling
14330
+
14331
+ | Hook | What it is |
14332
+ | --- | --- |
14333
+ | `.mx-wizard` | The wizard. `data-orientation`. |
14334
+ | `.mx-wizard__stepper` | The stepper (`.mx-stepper` too). |
14335
+ | `.mx-wizard__pages, .mx-wizard__page` | The pages and each page; a hidden page carries `hidden`. |
14336
+ | `.mx-wizard__bar, .mx-wizard__previous, .mx-wizard__next` | The bar and its buttons. |
14337
+
14338
+ ### Component tokens
14339
+
14340
+ | Token | What it sets |
14341
+ | --- | --- |
14342
+ | `wizard.frame, .page, .bar` | Units: the whole, a page, the bar (a rule over it, its padding). |
14343
+ | `wizard.previous, wizard.next` | Places: the buttons’ look in the bar (`variant`). |
14344
+ | `wizard.gap, .bar-gap, .rail-width` | Between the stepper, the pages and the bar; between the buttons; the stepper’s width when it stands beside the pages. |
14345
+
14346
+ ## API reference
14347
+
14348
+ ### Wizard props
14349
+
14350
+ | Prop | Type | Default | Description |
14351
+ | --- | --- | --- | --- |
14352
+ | `steps` | `readonly WizardStepProps[]` | `[]` | Steps made from code, each as the props of a `WizardStep`; the JSX `WizardStep` children come first. |
14353
+ | `value` | `Bind<string \| number \| null>` | `0` | The current step: its `key`, else its index. `x-model` binds it two-way. |
14354
+ | `linear` | `Bind<boolean>` | `true` | A step is reached only after the ones before it; optional steps may be skipped. |
14355
+ | `orientation` | `Bind<StepperOrientation>` | `'horizontal'` | `horizontal`: the stepper above the pages; `vertical`: beside them. |
14356
+ | `labelPosition` | `Bind<StepperLabelPosition>` | `'bottom'` | Where the stepper’s texts sit, horizontal only. |
14357
+ | `size` | `Bind<ControlSize>` | `'md'` | The stepper’s size. |
14358
+ | `showStepper, showNavigation` | `Bind<boolean>` | `true` | The stepper, and the bar with the Back and Next buttons. |
14359
+ | `clickable` | `Bind<boolean>` | `true` | The steps of the stepper can be pressed. |
14360
+ | `lazy` | `Bind<boolean>` | `true` | A page is built when first shown, then kept (a step’s own `lazy` wins). |
14361
+ | `keepAlive` | `Bind<boolean>` | `true` | `false`: what a step’s `content` made is disposed while hidden and made again when it shows (a step’s own `keepAlive` wins). |
14362
+ | `previousText, nextText, finishText` | `Bind<string>` | the kit’s “Back”, “Next”, “Finish” | The buttons’ texts. |
14363
+ | `label` | `Bind<string>` | the kit’s “Steps” | What screen readers call the stepper. |
14364
+
14365
+ ### WizardStep props
14366
+
14367
+ | Prop | Type | Default | Description |
14368
+ | --- | --- | --- | --- |
14369
+ | `title` | `Bind<string>` | `''` | The step’s text in the stepper. The same property as `text`. |
14370
+ | `description` | `Bind<string>` | `''` | A second line under the title. |
14371
+ | `key` | `Bind<string>` | the index | Names the step in `value`; the JSX `key` works too. |
14372
+ | `icon` | `Bind<IconSource \| null>` | `null` | Drawn in the indicator in place of the number. |
14373
+ | `optional` | `Bind<boolean>` | `false` | May be skipped; says so under the title. |
14374
+ | `enabled` | `Bind<boolean>` | `true` | `false` keeps the step from being reached. |
14375
+ | `error` | `Bind<boolean>` | `false` | Draws the step with an error; the wizard sets it when the page does not validate, and clears it when it does. |
14376
+ | `validateFields` | `Bind<boolean>` | `true` | The kit’s fields on the page are validated before the wizard moves on from it; the first invalid one takes focus. |
14377
+ | `validate` | `() => boolean \| Promise<boolean>` | — | Asked after the fields; `false` keeps the page and marks the step. |
14378
+ | `lazy, keepAlive` | `Bind<boolean \| undefined>` | the wizard’s | See the wizard’s. |
14379
+ | `content` | `() => ComponentBase \| ComponentBase[]` | — | Makes the page from code, when the page is built. |
14380
+
14381
+ ### Events, properties and methods
14382
+
14383
+ | Member | Kind | Description |
14384
+ | --- | --- | --- |
14385
+ | `onStepChanging, onStepChanged` | event | The stepper’s events: `onStepChanging` (`cancel`, `promise`) runs before the page is validated. |
14386
+ | `onFinishing` | event | The last page validated and the wizard is about to finish; `cancel = true` keeps it open, `promise` waits and finishes on `true`. |
14387
+ | `onFinished` | event | The wizard finished: every step is drawn done. |
14388
+ | `next(), previous(), goTo(step)` | `Promise<boolean>` | Next validates the page first and finishes on the last step; Back validates nothing; `goTo` validates when it goes forward. |
14389
+ | `finish()` | `Promise<boolean>` | Validates the page, asks `onFinishing`, then finishes. |
14390
+ | `leaveCheck()` | `Promise<boolean>` | Validates the current page the way Next does, without moving. |
14391
+ | `add(step), insert(index, step), remove(step)` | `WizardStep` / `boolean` | Steps from code; a step of another wizard moves here. |
14392
+ | `stepper, steps, currentStep, selectedIndex` | read-only | The `Stepper`, the `WizardStep`s in order, the current one and its index. |
14393
+ | `isLast, isFinished` | read-only | The current step is the last that can be gone to (Next finishes); the wizard finished. |
14394
+ | `previousButton, nextButton` | read-only | The kit’s buttons in the bar, for an icon or a look of your own. |
14395
+
14396
+
12628
14397
  ---
12629
14398
 
12630
14399
  # Accordion
12631
14400
 
12632
- > Navigation · @motifx-community/ui 0.1.0-beta.1
14401
+ > Navigation · @motifx-community/ui 0.1.0-beta.2
12633
14402
 
12634
14403
  An accordion opens and closes sections under their headers: one at a time or several, kept open, with icons, three looks and sections built when they are first opened.
12635
14404
 
@@ -12928,7 +14697,7 @@ The accordion writes no text of its own, so it has nothing in `uiLocale`.
12928
14697
 
12929
14698
  # Window and dialog
12930
14699
 
12931
- > Navigation · @motifx-community/ui 0.1.0-beta.1
14700
+ > Navigation · @motifx-community/ui 0.1.0-beta.2
12932
14701
 
12933
14702
  A window or a dialog on a native `<dialog>`: one form, shown modeless or modal by whoever shows it. It has a title bar, moves, resizes, minimizes and maximizes; Enter and Escape press its buttons; forms open forms. `messageBox` and `confirm` cover the common questions.
12934
14703
 
@@ -13255,7 +15024,7 @@ The title bar buttons and the `ok`, `cancel`, `yes`, `no` buttons of a message b
13255
15024
 
13256
15025
  ```tsx
13257
15026
  import { reactive } from '@motifx/core';
13258
- import { Button, enStrings, messageBox, trStrings, uiLocale } from '@motifx-community/ui';
15027
+ import { Button, messageBox, uiLocale } from '@motifx-community/ui';
13259
15028
 
13260
15029
  /** Switches the names of the title bar buttons and of the message box buttons. */
13261
15030
  export default function Localization() {
@@ -13263,7 +15032,7 @@ export default function Localization() {
13263
15032
 
13264
15033
  const toggle = () => {
13265
15034
  s.lang = s.lang === 'en' ? 'tr' : 'en';
13266
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
15035
+ void uiLocale.use(s.lang);
13267
15036
  };
13268
15037
 
13269
15038
  const ask = () =>
@@ -13488,7 +15257,7 @@ export default function DefaultButtons() {
13488
15257
 
13489
15258
  # BottomSheet
13490
15259
 
13491
- > Navigation · @motifx-community/ui 0.1.0-beta.1
15260
+ > Navigation · @motifx-community/ui 0.1.0-beta.2
13492
15261
 
13493
15262
  A panel that comes up from the bottom of the page or of a container and stops at a few heights: a peek, half, full, as tall as its content, or heights of your own. Dragged by its handle and its title, flicked, swiped down to close; modal or not, with the browser's back closing it on a phone.
13494
15263
 
@@ -13713,7 +15482,7 @@ The handle's name and heights, the default name and the close button come from `
13713
15482
 
13714
15483
  ```tsx
13715
15484
  import { reactive } from '@motifx/core';
13716
- import { BottomSheet, Button, enStrings, trStrings, uiLocale } from '@motifx-community/ui';
15485
+ import { BottomSheet, Button, uiLocale } from '@motifx-community/ui';
13717
15486
 
13718
15487
  /** The handle's name and heights and the close button's name come from uiLocale. */
13719
15488
  export default function Localization() {
@@ -13721,7 +15490,7 @@ export default function Localization() {
13721
15490
 
13722
15491
  const toggle = () => {
13723
15492
  s.lang = s.lang === 'en' ? 'tr' : 'en';
13724
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
15493
+ void uiLocale.use(s.lang);
13725
15494
  };
13726
15495
 
13727
15496
  return (
@@ -13808,7 +15577,7 @@ Every prop is a property too, taking a value or a function. The shared parts (th
13808
15577
 
13809
15578
  # Drawer
13810
15579
 
13811
- > Navigation · @motifx-community/ui 0.1.0-beta.1
15580
+ > Navigation · @motifx-community/ui 0.1.0-beta.2
13812
15581
 
13813
15582
  A panel that slides in from an edge of the page or of a container, over the content or pushing it aside. A finger swipes it in from the edge and back again; Escape, the scrim and the browser's back close it.
13814
15583
 
@@ -14041,7 +15810,7 @@ Its default name and the close button come from `uiLocale.strings` (`drawerLabel
14041
15810
 
14042
15811
  # ActionSheet
14043
15812
 
14044
- > Navigation · @motifx-community/ui 0.1.0-beta.1
15813
+ > Navigation · @motifx-community/ui 0.1.0-beta.2
14045
15814
 
14046
15815
  A list of commands that comes up from the bottom, made of the kit's menu items and large enough for a finger, with a title, a message and a cancel button apart. A context menu opens its items here on a touch screen.
14047
15816
 
@@ -14254,7 +16023,7 @@ Cancel, the way back and its default name come from `uiLocale.strings` (`cancel`
14254
16023
 
14255
16024
  # Layout
14256
16025
 
14257
- > Navigation · @motifx-community/ui 0.1.0-beta.1
16026
+ > Navigation · @motifx-community/ui 0.1.0-beta.2
14258
16027
 
14259
16028
  Containers that place controls: `Stack` (a row or a column), `Grid` (rows and columns), `Panel` (a plain box that can scroll), `GroupBox` (a titled frame), `DockPanel` (children stuck to its edges) and `SplitContainer` (two panes and a splitter). All of them are controls: they disable and hide what is inside, and lay out children added at any time.
14260
16029
 
@@ -14680,7 +16449,7 @@ The only text the containers write is the splitter's name, `uiLocale.strings.res
14680
16449
 
14681
16450
  ```tsx
14682
16451
  import { reactive } from '@motifx/core';
14683
- import { Button, enStrings, trStrings, uiLocale } from '@motifx-community/ui';
16452
+ import { Button, uiLocale } from '@motifx-community/ui';
14684
16453
  import { kitTexts } from '../../../shared/kit-texts';
14685
16454
 
14686
16455
  /** Switches the texts of the kit; the splitters on the page take the new name at once. */
@@ -14688,7 +16457,7 @@ export default function Localization() {
14688
16457
  const s = reactive({ lang: 'en' });
14689
16458
  const toggle = () => {
14690
16459
  s.lang = s.lang === 'en' ? 'tr' : 'en';
14691
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
16460
+ void uiLocale.use(s.lang);
14692
16461
  };
14693
16462
  return (
14694
16463
  <>
@@ -14838,11 +16607,417 @@ Every container also has the shared properties of `Control`: `enabled` / `disabl
14838
16607
  `ChildSettings` — the part that reads a child's settings from its props and follows children added later — is exported for containers of your own.
14839
16608
 
14840
16609
 
16610
+ ---
16611
+
16612
+ # ScrollView
16613
+
16614
+ > Navigation · @motifx-community/ui 0.1.0-beta.2
16615
+
16616
+ Content that scrolls in a box of its own: the bars shown as told, a pull from the top that asks for what is new, a reach near the end that asks for more. Moved from code to a position or to an element.
16617
+
16618
+ ## Import
16619
+
16620
+ ```tsx
16621
+ import { ScrollView } from '@motifx-community/ui';
16622
+ ```
16623
+
16624
+ ## A box that scrolls
16625
+
16626
+ The JSX children are the content. `showScrollbar` says when the bars show; `scrollTo` and `scrollToElement` move the content from code, `onScrolled` tells where it stands.
16627
+
16628
+ ```tsx
16629
+ import { reactive } from '@motifx/core';
16630
+ import { Button, ScrollView, Stack, type ScrollViewBars } from '@motifx-community/ui';
16631
+
16632
+ const LINES = Array.from({ length: 40 }, (_, i) => `Line ${i + 1} of a long text that needs a box of its own to scroll in.`);
16633
+ const MODES: ScrollViewBars[] = ['onScroll', 'onHover', 'always', 'never'];
16634
+
16635
+ /** A box that scrolls, its bars shown as told; moved from code to a line and back to the top. */
16636
+ export default function Bars() {
16637
+ const s = reactive({ bars: 'onScroll' as ScrollViewBars, top: 0 });
16638
+ let view!: ScrollView;
16639
+ return (
16640
+ <Stack gap="md" style="inline-size: 100%">
16641
+ <Stack orientation="horizontal" wrap align="center">
16642
+ {MODES.map(mode => (
16643
+ <Button key={mode} text={mode} size="sm" variant={() => (s.bars === mode ? 'solid' : 'outline')} onclick={() => (s.bars = mode)} />
16644
+ ))}
16645
+ <Button text="Line 20" variant="outline" size="sm" onclick={() => view.scrollToElement(view.content.element.querySelectorAll('p')[19], true)} />
16646
+ <Button text="Top" variant="outline" size="sm" onclick={() => view.scrollTo(0, true)} />
16647
+ <output class="sv-top">{() => `scrollTop: ${Math.round(s.top)}`}</output>
16648
+ </Stack>
16649
+ <ScrollView ref={(v: ScrollView) => (view = v)} label="Long text" class="sv-text" showScrollbar={() => s.bars} style="block-size: 12rem" onScrolled={e => (s.top = e.top)}>
16650
+ {LINES.map(line => (
16651
+ <p key={line}>{line}</p>
16652
+ ))}
16653
+ </ScrollView>
16654
+ </Stack>
16655
+ );
16656
+ }
16657
+ ```
16658
+
16659
+ ## Pull to refresh
16660
+
16661
+ With `pullToRefresh`, the content pulled down from its top asks `onPullDown`. Set `promise` (or call `release()`) and the panel goes when the work is done.
16662
+
16663
+ ```tsx
16664
+ import { reactive } from '@motifx/core';
16665
+ import { Panel, ScrollView, Stack } from '@motifx-community/ui';
16666
+
16667
+ /** Pulled down from the top, the list asks for what is new and shows the panel until the promise settles. */
16668
+ export default function Pull() {
16669
+ const s = reactive({ notes: ['Welcome aboard', 'Your plan was renewed', 'A new comment on "Roadmap"'], count: 0 });
16670
+ const reload = () =>
16671
+ new Promise<void>(resolve =>
16672
+ setTimeout(() => {
16673
+ s.count++;
16674
+ s.notes = [`Fresh note ${s.count}`, ...s.notes];
16675
+ resolve();
16676
+ }, 1200)
16677
+ );
16678
+ return (
16679
+ <Stack gap="sm" style="inline-size: 100%">
16680
+ <span>Drag the list down from its top (a finger, or the mouse) and let go.</span>
16681
+ <ScrollView label="Notes" class="sv-notes" pullToRefresh onPullDown={e => (e.promise = reload())} style="block-size: 12rem">
16682
+ {s.notes.map(note => (
16683
+ <Panel key={note} variant="outline" padding="sm">
16684
+ {note}
16685
+ </Panel>
16686
+ ))}
16687
+ </ScrollView>
16688
+ </Stack>
16689
+ );
16690
+ }
16691
+ ```
16692
+
16693
+ ## Load more near the end
16694
+
16695
+ With `loadOnReachBottom`, a scroll within `reachBottomOffset` of the end asks `onReachBottom` once; `release()` lets the next reach ask again, `release(true)` says there is no more. Content that does not fill the box asks at once.
16696
+
16697
+ ```tsx
16698
+ import { reactive } from '@motifx/core';
16699
+ import { Panel, ScrollView, Stack } from '@motifx-community/ui';
16700
+
16701
+ const TOTAL = 60;
16702
+ const PAGE = 15;
16703
+
16704
+ // A page of rows, as a server would send them.
16705
+ const fetchRows = (from: number) =>
16706
+ new Promise<string[]>(resolve => setTimeout(() => resolve(Array.from({ length: Math.min(PAGE, TOTAL - from) }, (_, i) => `Order #${1000 + from + i}`)), 800));
16707
+
16708
+ /** Near the end the view asks for more; the indicator stays until the rows are in, and `release(true)` ends it for good when there is no more. */
16709
+ export default function More() {
16710
+ const s = reactive({ rows: [] as string[] });
16711
+ const more = () =>
16712
+ fetchRows(s.rows.length).then(rows => {
16713
+ s.rows = [...s.rows, ...rows];
16714
+ return s.rows.length >= TOTAL;
16715
+ });
16716
+ return (
16717
+ <Stack gap="sm" style="inline-size: 100%">
16718
+ <output class="sv-more-told">{() => (s.rows.length >= TOTAL ? `All ${TOTAL} orders are in.` : `${s.rows.length} of ${TOTAL} orders`)}</output>
16719
+ <ScrollView label="Orders" class="sv-orders" loadOnReachBottom reachBottomOffset={80} onReachBottom={e => more().then(done => e.release(done))} style="block-size: 14rem">
16720
+ {s.rows.map(row => (
16721
+ <Panel key={row} variant="outline" padding="sm">
16722
+ {row}
16723
+ </Panel>
16724
+ ))}
16725
+ </ScrollView>
16726
+ </Stack>
16727
+ );
16728
+ }
16729
+ ```
16730
+
16731
+ ## Behaviour
16732
+
16733
+ | Topic | How |
16734
+ | --- | --- |
16735
+ | `Scrolling` | The box scrolls with the wheel, the keys when focused, a finger, and from code. `direction` locks the other axis; the page behind does not scroll on when the content ends. |
16736
+ | `Scrollbars` | The design system’s bars. With `onScroll` the thumb shows while the content moves and goes a moment after; with `onHover` while the pointer is over the view or focus is in it; `always` leaves them; `never` hides them, the content still scrolls. |
16737
+ | `Pull to refresh` | From the top, with a finger or the pointer: the content comes down (harder the farther it goes) and the panel above it says to pull, then to release. Let go far enough it refreshes: the spinner turns until `release()` or the promise. A short pull goes back. |
16738
+ | `Load more` | Within `reachBottomOffset` of the end, `onReachBottom` is asked once; the panel under the content shows meanwhile. Released, the next reach asks again, until `release(true)`. Content that does not fill the box asks at once, and again as it grows. |
16739
+ | `Texts` | The kit’s, in the kit language, unless the text props say otherwise. |
16740
+
16741
+ ## Accessibility
16742
+
16743
+ | Topic | How |
16744
+ | --- | --- |
16745
+ | `Region` | A focusable box named by `label`; the arrow keys, Page Up/Down, Home and End scroll it as the browser does. |
16746
+ | `Panels` | Live regions: “Refreshing…” and “Loading…” are read when they appear. |
16747
+ | `Spinners` | Decorative; the texts say what is going on. |
16748
+ | `Motion` | A finger that pulls does not scroll the page; a finger that scrolls does not pull. |
16749
+
16750
+ ## Styling
16751
+
16752
+ | Hook | What it is |
16753
+ | --- | --- |
16754
+ | `.mx-scroll-view` | The box. `data-direction`, `data-bars`, `data-scrolling` while the content moves, `data-pull` when pulling is on, `data-pulling` during a pull, `data-pull-state` (`pull`, `release`, `refreshing`), `data-loading`. |
16755
+ | `.mx-scroll-view__content` | What holds the children; it moves down during a pull. |
16756
+ | `.mx-scroll-view__pull, .mx-scroll-view__pull-text, .mx-scroll-view__pull-spinner` | The panel above the content, its text and the kit’s spinner. |
16757
+ | `.mx-scroll-view__bottom, .mx-scroll-view__bottom-text, .mx-scroll-view__bottom-spinner` | The panel under the content while more loads. |
16758
+
16759
+ ### Component tokens
16760
+
16761
+ | Token | What it sets |
16762
+ | --- | --- |
16763
+ | `scroll-view.box` | Unit: the box (`focus`). |
16764
+ | `scroll-view.pull, .pull-text, .bottom, .bottom-text` | Units: the two panels (the pull one `release` and `refreshing`) and their texts. |
16765
+ | `scroll-view.panel-height, .panel-gap` | The panels’ height; the space between a panel’s spinner and its text. |
16766
+
16767
+ ## API reference
16768
+
16769
+ ### Props
16770
+
16771
+ | Prop | Type | Default | Description |
16772
+ | --- | --- | --- | --- |
16773
+ | `direction` | `Bind<ScrollViewDirection>` | `'vertical'` | `vertical`, `horizontal` or `both`: which way the content scrolls. |
16774
+ | `showScrollbar` | `Bind<ScrollViewBars>` | `'onScroll'` | When the bars show: `onScroll` while scrolling, `onHover` while the pointer is over the view, `always`, `never`. |
16775
+ | `pullToRefresh` | `Bind<boolean>` | `false` | Pulling the content down from its top asks `onPullDown` for what is new. |
16776
+ | `loadOnReachBottom` | `Bind<boolean>` | `false` | Scrolling near the end asks `onReachBottom` for more; so does content that does not reach the end. |
16777
+ | `reachBottomOffset` | `Bind<number>` | `100` | Pixels before the end at which `onReachBottom` is asked. |
16778
+ | `pullDownText, releaseText, refreshingText` | `Bind<string>` | the kit’s texts | The pull panel’s texts: while pulling, once far enough, while refreshing. |
16779
+ | `reachBottomText` | `Bind<string>` | the kit’s “Loading…” | The text under the content while more loads. |
16780
+ | `label` | `Bind<string>` | `''` | What screen readers call the scrolling region. |
16781
+
16782
+ ### Events, properties and methods
16783
+
16784
+ | Member | Kind | Description |
16785
+ | --- | --- | --- |
16786
+ | `onPullDown` | event | The content was pulled down and let go. Load what is new, then `release()`, or set `promise` and the panel goes when it settles. |
16787
+ | `onReachBottom` | event | The content was scrolled near its end. Load more, then `release()`; `release(true)` says there is no more and the view stops asking. A `promise` releases too. |
16788
+ | `onScrolled` | event | The position changed: `top`, `left`. |
16789
+ | `scrollTo(where, smooth?)` | `void` | To a top, or `{ top, left }`; `smooth` animates. |
16790
+ | `scrollBy({ top, left }, smooth?)` | `void` | By a distance. |
16791
+ | `scrollToElement(target, smooth?)` | `void` | Brings an element (or a component) of the content into view. |
16792
+ | `refresh(), release()` | `void` | Starts a refresh as a pull would; ends it. |
16793
+ | `loadMore(), update()` | `boolean` / `void` | Asks for more now; looks at the position again after the content changed. |
16794
+ | `scrollTop, scrollLeft` | read-only | Where the content stands. |
16795
+ | `isRefreshing, isLoading` | read-only | A refresh or a loading is going on. |
16796
+ | `content` | read-only | The element that holds the children, between the two panels. |
16797
+
16798
+
16799
+ ---
16800
+
16801
+ # Sortable
16802
+
16803
+ > Navigation · @motifx-community/ui 0.1.0-beta.2
16804
+
16805
+ Items the user puts in order by dragging them, with the pointer or a finger, or with the keys; lists of one group take each other’s items. A drop moves the element and tells you the indexes: your data stays yours.
16806
+
16807
+ ## Import
16808
+
16809
+ ```tsx
16810
+ import { Sortable } from '@motifx-community/ui';
16811
+ ```
16812
+
16813
+ ## Children as items
16814
+
16815
+ The JSX children are the items. Drag one, or focus it and press Ctrl + Down; `onReorder` says from where to where, and the app reorders its own data.
16816
+
16817
+ ```tsx
16818
+ import { reactive } from '@motifx/core';
16819
+ import { Panel, Sortable, Stack } from '@motifx-community/ui';
16820
+
16821
+ /** Rows put in order by dragging, or with Ctrl + an arrow on the focused row; the app reorders its data when told. */
16822
+ export default function Basic() {
16823
+ const s = reactive({ steps: ['Collect the order', 'Pack it', 'Print the label', 'Hand it over'], told: '' });
16824
+ return (
16825
+ <Stack gap="md" style="inline-size: 100%">
16826
+ <Sortable
16827
+ label="Steps"
16828
+ class="so-steps"
16829
+ onReorder={e => {
16830
+ const next = s.steps.slice();
16831
+ next.splice(e.toIndex, 0, ...next.splice(e.fromIndex, 1));
16832
+ s.steps = next;
16833
+ s.told = `"${next[e.toIndex]}" is step ${e.toIndex + 1} now`;
16834
+ }}
16835
+ >
16836
+ <Panel variant="outline" padding="sm">
16837
+ Collect the order
16838
+ </Panel>
16839
+ <Panel variant="outline" padding="sm">
16840
+ Pack it
16841
+ </Panel>
16842
+ <Panel variant="outline" padding="sm">
16843
+ Print the label
16844
+ </Panel>
16845
+ <Panel variant="outline" padding="sm">
16846
+ Hand it over
16847
+ </Panel>
16848
+ </Sortable>
16849
+ <output class="so-told">{() => s.told || `Order: ${s.steps.join(' → ')}`}</output>
16850
+ </Stack>
16851
+ );
16852
+ }
16853
+ ```
16854
+
16855
+ ## Items from data, across lists
16856
+
16857
+ `items` with an `itemTemplate` draws the rows from your data and keeps each row as the order changes. Two sortables of one `group` take each other’s items: `onRemove` and `onAdd` tell both sides, and each list draws its array again.
16858
+
16859
+ ```tsx
16860
+ import { reactive } from '@motifx/core';
16861
+ import { Panel, Sortable, Stack } from '@motifx-community/ui';
16862
+
16863
+ interface Task {
16864
+ id: number;
16865
+ title: string;
16866
+ }
16867
+
16868
+ // A task as a row.
16869
+ const row = (task: Task) => {
16870
+ const panel = new Panel({ variant: 'outline', padding: 'sm' });
16871
+ panel.element.textContent = task.title;
16872
+ return panel;
16873
+ };
16874
+
16875
+ /** Two lists of one group take each other's items; each list draws its own data and the app moves the task between arrays when told. */
16876
+ export default function Groups() {
16877
+ const s = reactive({
16878
+ todo: [{ id: 1, title: 'Write the brief' }, { id: 2, title: 'Book the room' }, { id: 3, title: 'Send the invites' }] as Task[],
16879
+ done: [{ id: 4, title: 'Pick the date' }] as Task[]
16880
+ });
16881
+ const reorder = (key: 'todo' | 'done') => (e: { fromIndex: number; toIndex: number }) => {
16882
+ const next = s[key].slice();
16883
+ next.splice(e.toIndex, 0, ...next.splice(e.fromIndex, 1));
16884
+ s[key] = next;
16885
+ };
16886
+ // The item leaves one array when removed and joins the other when added: the lists draw themselves again.
16887
+ const remove = (key: 'todo' | 'done') => (e: { fromIndex: number }) => (s[key] = s[key].filter((_, i) => i !== e.fromIndex));
16888
+ const add = (key: 'todo' | 'done') => (e: { item: Task; toIndex: number }) => {
16889
+ const next = s[key].slice();
16890
+ next.splice(e.toIndex, 0, e.item);
16891
+ s[key] = next;
16892
+ };
16893
+ return (
16894
+ <Stack orientation="horizontal" gap="lg" style="inline-size: 100%">
16895
+ <Stack gap="sm" grow>
16896
+ <strong>To do</strong>
16897
+ <Sortable<Task> label="To do" class="so-todo" group="tasks" items={() => s.todo} itemTemplate={row} onReorder={reorder('todo')} onRemove={remove('todo')} onAdd={add('todo')} style="min-block-size: 8rem" />
16898
+ </Stack>
16899
+ <Stack gap="sm" grow>
16900
+ <strong>Done</strong>
16901
+ <Sortable<Task> label="Done" class="so-done" group="tasks" items={() => s.done} itemTemplate={row} onReorder={reorder('done')} onRemove={remove('done')} onAdd={add('done')} style="min-block-size: 8rem" />
16902
+ </Stack>
16903
+ </Stack>
16904
+ );
16905
+ }
16906
+ ```
16907
+
16908
+ ## A handle, side by side, a refused drag
16909
+
16910
+ ```tsx
16911
+ import { reactive } from '@motifx/core';
16912
+ import { Chip, Sortable, Stack } from '@motifx-community/ui';
16913
+
16914
+ /** Chips side by side, moved by their handle only (the dots), with Ctrl + Left / Right on the handle; a drag may be refused. */
16915
+ export default function Handle() {
16916
+ const s = reactive({ tags: ['Design', 'Build', 'Test', 'Ship', 'Locked'], told: '' });
16917
+ return (
16918
+ <Stack gap="md" style="inline-size: 100%">
16919
+ <Sortable
16920
+ label="Tags"
16921
+ class="so-tags"
16922
+ orientation="horizontal"
16923
+ handle=".so-grip"
16924
+ items={() => s.tags}
16925
+ itemTemplate={tag => {
16926
+ const chip = new Chip({ text: tag });
16927
+ const grip = document.createElement('span');
16928
+ grip.className = 'mx-glyph so-grip';
16929
+ grip.dataset.icon = 'drag-dots';
16930
+ grip.setAttribute('aria-label', `Move ${tag}`);
16931
+ chip.element.prepend(grip);
16932
+ return chip;
16933
+ }}
16934
+ onDragStarting={e => {
16935
+ if (e.item === 'Locked') {
16936
+ e.cancel = true;
16937
+ s.told = 'Locked stays where it is.';
16938
+ }
16939
+ }}
16940
+ onReorder={e => {
16941
+ const next = s.tags.slice();
16942
+ next.splice(e.toIndex, 0, ...next.splice(e.fromIndex, 1));
16943
+ s.tags = next;
16944
+ s.told = next.join(', ');
16945
+ }}
16946
+ />
16947
+ <output class="so-tags-told">{() => s.told}</output>
16948
+ </Stack>
16949
+ );
16950
+ }
16951
+ ```
16952
+
16953
+ ## Behaviour
16954
+
16955
+ | Topic | How |
16956
+ | --- | --- |
16957
+ | `Dragging` | With the pointer after a few pixels; with a finger after a long press (a finger that moves before that scrolls). A copy follows the pointer, the item stays faint in its place, a line shows where it would land; the list scrolls near its edges. |
16958
+ | `Dropping` | The item’s element moves there at once and `onReorder` says from where to where: your data is yours to reorder. Across sortables of a group, `onRemove` and `onAdd` say the same on both sides. |
16959
+ | `Items from data` | With `items`, each item keeps its component as the order changes (the rows are keyed by item): reordering your array moves the rows, no row is made again. |
16960
+ | `Keys` | The focused item (its handle when there is one) takes Ctrl + Up / Down (Left / Right side by side), Ctrl + Home / End; each move is told to `onReorder` and read out. |
16961
+ | `Escape` | Cancels a drag; nothing moves. |
16962
+
16963
+ ## Accessibility
16964
+
16965
+ | Topic | How |
16966
+ | --- | --- |
16967
+ | `List` | A `group` named by `label`; the items are whatever you put in it. |
16968
+ | `Items` | One Tab stop that moves between the items with the keys; an item with a focusable part of its own keeps that. A handle is a button named by you. |
16969
+ | `Moves` | Each move by the keys is read out: “Moved to 2 of 5”. |
16970
+
16971
+ ## Styling
16972
+
16973
+ | Hook | What it is |
16974
+ | --- | --- |
16975
+ | `.mx-sortable` | The list. `data-orientation`, `data-sortable`, `data-drop-target` while a dragged item may land here. |
16976
+ | `.mx-sortable__item` | Each item. `data-dragging` on the one being dragged. |
16977
+ | `.mx-sortable__line` | The line where a drop would land. |
16978
+ | `.mx-sortable__ghost` | The copy after the pointer. |
16979
+
16980
+ ### Component tokens
16981
+
16982
+ | Token | What it sets |
16983
+ | --- | --- |
16984
+ | `sortable.container, .item, .line, .ghost` | Units: the list (`target`), an item (`sortable`, `dragging`, `focus`), the line (its thickness and colour; standing in a horizontal list), the copy. |
16985
+ | `sortable.gap` | Between the items. |
16986
+
16987
+ ## API reference
16988
+
16989
+ ### Props
16990
+
16991
+ | Prop | Type | Default | Description |
16992
+ | --- | --- | --- | --- |
16993
+ | `items` | `Bind<readonly T[]>` | — | The items, each drawn with `itemTemplate`; without them the JSX children are the items. |
16994
+ | `itemTemplate` | `(item, index) => ComponentBase` | the item’s text | Makes an item’s component. A function, so it is not bound like the other props. |
16995
+ | `handle` | `Bind<string \| null>` | `null` | A selector inside an item that takes the drag and the keys; without one the whole item does. |
16996
+ | `group` | `Bind<string \| null>` | `null` | Sortables of one group take each other’s items. |
16997
+ | `allowReordering` | `Bind<boolean>` | `true` | The items can be moved; `false` leaves them as they are. |
16998
+ | `orientation` | `Bind<SortableOrientation>` | `'vertical'` | `vertical` or `horizontal`: the drop line and the move keys follow. |
16999
+ | `label` | `Bind<string>` | `''` | What screen readers call the list. |
17000
+
17001
+ ### Events, properties and methods
17002
+
17003
+ | Member | Kind | Description |
17004
+ | --- | --- | --- |
17005
+ | `onDragStarting` | event | A drag (or a move by the keys) is about to start (`item`, `fromIndex`); `cancel = true` refuses. |
17006
+ | `onDragChanging` | event | The place it would land changed (`to`, `toIndex`); `cancel = true` refuses that place. |
17007
+ | `onDragEnding` | event | About to drop; `cancel = true` leaves everything as it was. |
17008
+ | `onReorder` | event | An item moved within this sortable (`fromIndex`, `toIndex`, `item`), by a drop or the keys. Reorder your data here. |
17009
+ | `onRemove, onAdd` | event | An item went to another sortable of the group, and came into one: `from`, `to`, the indexes and the item. Move the data between your arrays here. |
17010
+ | `move(fromIndex, toIndex)` | `boolean` | Moves an item from code as a drop would, telling `onReorder`. |
17011
+ | `elements` | read-only | The items’ elements, in order. |
17012
+ | `isDragging` | read-only | An item is being dragged. |
17013
+ | `refresh()` | `void` | Reads the items again after they were changed in place. |
17014
+
17015
+
14841
17016
  ---
14842
17017
 
14843
17018
  # FormLayout
14844
17019
 
14845
- > Navigation · @motifx-community/ui 0.1.0-beta.1
17020
+ > Navigation · @motifx-community/ui 0.1.0-beta.2
14846
17021
 
14847
17022
  Lays out the fields of a data object on a grid. Each field gets an editor — by name, or by the type of its value — bound to the object both ways; groups, spans and buttons arrange them; sending the form checks every field first.
14848
17023
 
@@ -14964,7 +17139,7 @@ FormLayout.editors.set('color', (props) => new ColorPicker(props));
14964
17139
 
14965
17140
  # TreeView
14966
17141
 
14967
- > Data · @motifx-community/ui 0.1.0-beta.1
17142
+ > Data · @motifx-community/ui 0.1.0-beta.2
14968
17143
 
14969
17144
  A tree view shows items in a hierarchy. Rows open and close, are selected one or many at a time, can carry check boxes that add up to their parents, can be searched, and can load their children when they are first opened. Long trees draw only the rows in view.
14970
17145
 
@@ -15149,7 +17324,7 @@ The tree writes four texts, all from `uiLocale.strings`: `noItems` (nothing to s
15149
17324
 
15150
17325
  ```tsx
15151
17326
  import { reactive } from '@motifx/core';
15152
- import { Button, enStrings, trStrings, uiLocale } from '@motifx-community/ui';
17327
+ import { Button, uiLocale } from '@motifx-community/ui';
15153
17328
  import { kitTexts } from '../../../shared/kit-texts';
15154
17329
 
15155
17330
  /** Switches the texts of the kit; the trees on the page follow at once. */
@@ -15157,7 +17332,7 @@ export default function Localization() {
15157
17332
  const s = reactive({ lang: 'en' });
15158
17333
  const toggle = () => {
15159
17334
  s.lang = s.lang === 'en' ? 'tr' : 'en';
15160
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
17335
+ void uiLocale.use(s.lang);
15161
17336
  };
15162
17337
  return (
15163
17338
  <>
@@ -15731,7 +17906,7 @@ export default function SizesAndLines() {
15731
17906
 
15732
17907
  # ListBox
15733
17908
 
15734
- > Data · @motifx-community/ui 0.1.0-beta.1
17909
+ > Data · @motifx-community/ui 0.1.0-beta.2
15735
17910
 
15736
17911
  A list that stays on the page. One item or several are chosen with the keys or the pointer; items come from memory or from a data source, can be searched and grouped, and long lists draw only the rows in view.
15737
17912
 
@@ -15895,14 +18070,14 @@ export const cities = ['Ankara', 'Antalya', 'Bursa', 'İstanbul', 'İzmir', 'Kon
15895
18070
 
15896
18071
  ```tsx
15897
18072
  import { reactive } from '@motifx/core';
15898
- import { Button, ListBox, enStrings, trStrings, uiLocale } from '@motifx-community/ui';
18073
+ import { Button, ListBox, uiLocale } from '@motifx-community/ui';
15899
18074
 
15900
18075
  /** Switches the texts of every list on the page: “Select all”, the search box, “No items”. */
15901
18076
  export default function Localization() {
15902
18077
  const s = reactive({ lang: 'en' });
15903
18078
  const toggle = () => {
15904
18079
  s.lang = s.lang === 'en' ? 'tr' : 'en';
15905
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
18080
+ void uiLocale.use(s.lang);
15906
18081
  };
15907
18082
  return (
15908
18083
  <>
@@ -16109,7 +18284,7 @@ export default function Validation() {
16109
18284
 
16110
18285
  # TagBox
16111
18286
 
16112
- > Data · @motifx-community/ui 0.1.0-beta.1
18287
+ > Data · @motifx-community/ui 0.1.0-beta.2
16113
18288
 
16114
18289
  Picks several items. The chosen ones are tags in the field, followed by a text input that searches the list; items come from memory or from a data source, and typed text can become a tag of its own.
16115
18290
 
@@ -16450,7 +18625,7 @@ export default function Validation() {
16450
18625
 
16451
18626
  ```tsx
16452
18627
  import { reactive } from '@motifx/core';
16453
- import { Button, TagBox, enStrings, trStrings, uiLocale } from '@motifx-community/ui';
18628
+ import { Button, TagBox, uiLocale } from '@motifx-community/ui';
16454
18629
  import { skills } from './skills';
16455
18630
 
16456
18631
  /** Switches the texts of every tag box on the page: remove buttons, “+3”, “Select all”. */
@@ -16458,7 +18633,7 @@ export default function Localization() {
16458
18633
  const s = reactive({ lang: 'en' });
16459
18634
  const toggle = () => {
16460
18635
  s.lang = s.lang === 'en' ? 'tr' : 'en';
16461
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
18636
+ void uiLocale.use(s.lang);
16462
18637
  };
16463
18638
  return (
16464
18639
  <>
@@ -16474,7 +18649,7 @@ export default function Localization() {
16474
18649
 
16475
18650
  # FilterBuilder
16476
18651
 
16477
- > Data · @motifx-community/ui 0.1.0-beta.1
18652
+ > Data · @motifx-community/ui 0.1.0-beta.2
16478
18653
 
16479
18654
  A filter builder lets people put a filter together by hand: groups joined by And, Or, Not And or Not Or, and conditions of a field, an operation and a value. Its value is the data layer's filter expression, so it goes to rows in memory and to every adapter as it is. The DataGrid opens it from its filter panel; on its own it serves a report screen or a saved search.
16480
18655
 
@@ -17048,7 +19223,7 @@ export default function CustomOperations() {
17048
19223
  ```tsx
17049
19224
  import { reactive } from '@motifx/core';
17050
19225
  import { data } from '@motifx-community/data';
17051
- import { Button, FilterBuilder, enStrings, trStrings, uiLocale } from '@motifx-community/ui';
19226
+ import { Button, FilterBuilder, uiLocale } from '@motifx-community/ui';
17052
19227
  import { saleFields } from './sales';
17053
19228
 
17054
19229
  /** The builder's texts come from `uiLocale`; `texts` changes some for one builder only. */
@@ -17056,7 +19231,7 @@ export default function Localization() {
17056
19231
  const s = reactive({ lang: 'en' });
17057
19232
  const toggle = () => {
17058
19233
  s.lang = s.lang === 'en' ? 'tr' : 'en';
17059
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
19234
+ void uiLocale.use(s.lang);
17060
19235
  };
17061
19236
  return (
17062
19237
  <>
@@ -17079,7 +19254,7 @@ export default function Localization() {
17079
19254
 
17080
19255
  # TabDocumentManager
17081
19256
 
17082
- > TabDocumentManager · @motifx-community/ui 0.1.0-beta.1
19257
+ > TabDocumentManager · @motifx-community/ui 0.1.0-beta.2
17083
19258
 
17084
19259
  A document manager in the way code editors arrange files: documents in tabs, tabs in groups, groups split side by side and one under the other. A document's content is any component, a form, a grid or plain text, and it is moved, never made again, when its tab goes to another group. Everything the user does is a method too, asks first and reports after; the whole layout saves to JSON and comes back. Preview and pinned tabs, sizes and copies are on [Tabs](tabdocs-tabs.md); context menus, lists and keys on [Menus and keys](tabdocs-menus.md).
17085
19260
 
@@ -17971,7 +20146,7 @@ export default function SaveRestore() {
17971
20146
 
17972
20147
  # TabDocumentManager: Tabs
17973
20148
 
17974
- > TabDocumentManager · @motifx-community/ui 0.1.0-beta.1
20149
+ > TabDocumentManager · @motifx-community/ui 0.1.0-beta.2
17975
20150
 
17976
20151
  What a tab does in a code editor: preview tabs that the next preview replaces, pinned tabs that stay at the start, tabs that shrink, wrap or scroll, counts and colours, and the same document open in two groups.
17977
20152
 
@@ -18805,7 +20980,7 @@ export default function Duplicates() {
18805
20980
 
18806
20981
  # TabDocumentManager: Menus and keys
18807
20982
 
18808
- > TabDocumentManager · @motifx-community/ui 0.1.0-beta.1
20983
+ > TabDocumentManager · @motifx-community/ui 0.1.0-beta.2
18809
20984
 
18810
20985
  The commands around the tabs: context menus on tabs and on the empty strip, a searchable list of a group's documents, the app's own toolbar buttons, the recently used list, back and forward, reopening what was closed, locked groups, and the keys for all of them.
18811
20986
 
@@ -19498,7 +21673,7 @@ export function customerCard(customer: Customer): ComponentBase {
19498
21673
 
19499
21674
  # TabDocumentManager: Drag and drop
19500
21675
 
19501
- > TabDocumentManager · @motifx-community/ui 0.1.0-beta.1
21676
+ > TabDocumentManager · @motifx-community/ui 0.1.0-beta.2
19502
21677
 
19503
21678
  Tabs and whole groups dragged as in a code editor: along a strip, to another group, beside a group or along an edge of the layout, between two managers, and the same moves from the keyboard. Every drop goes through the methods and events of what it does.
19504
21679
 
@@ -20056,7 +22231,7 @@ export default function MoveWithKeys() {
20056
22231
 
20057
22232
  # TabDocumentManager: Dock and floating windows
20058
22233
 
20059
- > TabDocumentManager · @motifx-community/ui 0.1.0-beta.1
22234
+ > TabDocumentManager · @motifx-community/ui 0.1.0-beta.2
20060
22235
 
20061
22236
  Documents and whole groups float in windows of their own in the page and dock again into the documents' groups or into dock areas around them, which fold to the manager's edge. The mouse, the keys and the code do the same, through the same events.
20062
22237
 
@@ -20937,7 +23112,7 @@ export function customerCard(customer: Customer): ComponentBase {
20937
23112
 
20938
23113
  # TabDocumentManager: New windows
20939
23114
 
20940
- > TabDocumentManager · @motifx-community/ui 0.1.0-beta.1
23115
+ > TabDocumentManager · @motifx-community/ui 0.1.0-beta.2
20941
23116
 
20942
23117
  A document, a group or a floating window moves into a browser window of its own, and back. Its content moves with it, nothing is made again, and the new window is a part of the same manager: its tabs, menus, keys and drag work as they do here.
20943
23118
 
@@ -21598,7 +23773,7 @@ export default function WindowLayout() {
21598
23773
 
21599
23774
  # TabDocumentManager: Tablet and phone
21600
23775
 
21601
- > TabDocumentManager · @motifx-community/ui 0.1.0-beta.1
23776
+ > TabDocumentManager · @motifx-community/ui 0.1.0-beta.2
21602
23777
 
21603
23778
  On a tablet and a phone a layout of groups, splits and dock areas does not fit as it is. The manager keeps the layout and shows it another way: the same documents, groups and areas, the same saved JSON, the content moved and never made again. It goes by its own width, not by the device; on a touch screen its tabs and buttons get larger.
21604
23779
 
@@ -21879,7 +24054,7 @@ The drawers and sheets are the kit's [Drawer](drawer.md) and [BottomSheet](botto
21879
24054
 
21880
24055
  # TabDocumentManager: A whole workspace
21881
24056
 
21882
- > TabDocumentManager · @motifx-community/ui 0.1.0-beta.1
24057
+ > TabDocumentManager · @motifx-community/ui 0.1.0-beta.2
21883
24058
 
21884
24059
  A whole screen made of the kit's parts: a menu bar, the manager, a DataGrid with everything turned on, forms and a tool docked at the bottom. Each part is the same component it is on its own page; the manager only holds them.
21885
24060
 
@@ -22292,7 +24467,7 @@ export function customerCard(customer: Customer): ComponentBase {
22292
24467
 
22293
24468
  # Scheduler
22294
24469
 
22295
- > Scheduler · @motifx-community/ui 0.1.0-beta.1
24470
+ > Scheduler · @motifx-community/ui 0.1.0-beta.2
22296
24471
 
22297
24472
  Appointments over days and hours: day, week, work week and month views, all-day and multi-day bars, appointments at the same time side by side, and "+N more" where a day is full. From an array or a data source, with every setting live.
22298
24473
 
@@ -22888,7 +25063,7 @@ export class SlowAdapter<T extends object, K> extends data.ArrayAdapter<T, K> {
22888
25063
 
22889
25064
  # Scheduler: Editing
22890
25065
 
22891
- > Scheduler · @motifx-community/ui 0.1.0-beta.1
25066
+ > Scheduler · @motifx-community/ui 0.1.0-beta.2
22892
25067
 
22893
25068
  Appointments are added, moved, resized, copied and deleted with the pointer, the keys and code; every change asks its event first, can wait for a server, and goes back when saving fails.
22894
25069
 
@@ -23437,7 +25612,7 @@ export class SlowAdapter<T extends object, K> extends data.ArrayAdapter<T, K> {
23437
25612
 
23438
25613
  # Scheduler: Recurrence and time zones
23439
25614
 
23440
- > Scheduler · @motifx-community/ui 0.1.0-beta.1
25615
+ > Scheduler · @motifx-community/ui 0.1.0-beta.2
23441
25616
 
23442
25617
  Appointments that repeat by an RFC 5545 rule, with times left out and occurrences changed apart; a question on what a change reaches; an editor of the rule; and the days on the clock of any time zone, summer time included.
23443
25618
 
@@ -23861,7 +26036,7 @@ export class SlowAdapter<T extends object, K> extends data.ArrayAdapter<T, K> {
23861
26036
 
23862
26037
  # Scheduler: Resources and groups
23863
26038
 
23864
- > Scheduler · @motifx-community/ui 0.1.0-beta.1
26039
+ > Scheduler · @motifx-community/ui 0.1.0-beta.2
23865
26040
 
23866
26041
  Rooms, people and any other kind of resource: they colour the appointments, split the columns into groups (nested, or under each date), say when each one works and when nothing may be put in.
23867
26042
 
@@ -24567,7 +26742,7 @@ export class SlowAdapter<T extends object, K> extends data.ArrayAdapter<T, K> {
24567
26742
 
24568
26743
  # Scheduler: The appointment form
24569
26744
 
24570
- > Scheduler · @motifx-community/ui 0.1.0-beta.1
26745
+ > Scheduler · @motifx-community/ui 0.1.0-beta.2
24571
26746
 
24572
26747
  The appointment form set up without events: which fields, in which order, in groups and tabs; editors of your own; checks per field; fields shown or locked for one appointment only. Or a form of your own.
24573
26748
 
@@ -25202,7 +27377,7 @@ export default function OwnForm() {
25202
27377
 
25203
27378
  # Scheduler: Timeline
25204
27379
 
25205
- > Scheduler · @motifx-community/ui 0.1.0-beta.1
27380
+ > Scheduler · @motifx-community/ui 0.1.0-beta.2
25206
27381
 
25207
27382
  A row per resource with the time running along it: a day, a week, a work week or a month. Appointments at the same time stack in their row, and the row grows to fit them.
25208
27383
 
@@ -25838,7 +28013,7 @@ export default function TimelineTemplates() {
25838
28013
 
25839
28014
  # Scheduler: Agenda
25840
28015
 
25841
- > Scheduler · @motifx-community/ui 0.1.0-beta.1
28016
+ > Scheduler · @motifx-community/ui 0.1.0-beta.2
25842
28017
 
25843
28018
  The coming days as a list: each day with its appointments in time order, a day with none left out.
25844
28019
 
@@ -26439,7 +28614,7 @@ export default function AgendaTemplates() {
26439
28614
 
26440
28615
  # Scheduler: Big data
26441
28616
 
26442
- > Scheduler · @motifx-community/ui 0.1.0-beta.1
28617
+ > Scheduler · @motifx-community/ui 0.1.0-beta.2
26443
28618
 
26444
28619
  Thousands of resources and appointments: the scheduler builds only what is in view, and lays out only what changed.
26445
28620
 
@@ -26696,7 +28871,7 @@ export default function BigWeek() {
26696
28871
 
26697
28872
  # Scheduler: Tablet and phone
26698
28873
 
26699
- > Scheduler · @motifx-community/ui 0.1.0-beta.1
28874
+ > Scheduler · @motifx-community/ui 0.1.0-beta.2
26700
28875
 
26701
28876
  On a tablet and a phone the scheduler keeps its appointments, views and date and shows them another way: a phone gets the agenda, a compact bar and sheets from the bottom; a finger lifts, resizes, swipes and pinches.
26702
28877
 
@@ -27364,7 +29539,7 @@ export default function Touch() {
27364
29539
 
27365
29540
  # Scheduler: iCalendar and print
27366
29541
 
27367
- > Scheduler · @motifx-community/ui 0.1.0-beta.1
29542
+ > Scheduler · @motifx-community/ui 0.1.0-beta.2
27368
29543
 
27369
29544
  Appointments out to an iCalendar file and back in (RFC 5545), for Outlook, Google Calendar and Apple Calendar; and the scheduler on paper.
27370
29545
 
@@ -27959,7 +30134,7 @@ export function sampleAppointments(): Meeting[] {
27959
30134
 
27960
30135
  # DataGrid
27961
30136
 
27962
- > DataGrid · @motifx-community/ui 0.1.0-beta.1
30137
+ > DataGrid · @motifx-community/ui 0.1.0-beta.2
27963
30138
 
27964
30139
  A grid for data entry and large data: rows in memory or from any adapter of the data layer, a virtual list or pages, sorting, column layout, editing with the kit's editors, new rows with the Tab chain, three save modes, row actions, selection, filters, a search panel, grouping, summaries, a toolbar, lookup columns from other services, copy and paste, export and a layout that is kept — and every feature can be turned off, for the grid or for one column.
27965
30140
 
@@ -28325,7 +30500,7 @@ export default function Pager() {
28325
30500
 
28326
30501
  # DataGrid: Editing
28327
30502
 
28328
- > DataGrid · @motifx-community/ui 0.1.0-beta.1
30503
+ > DataGrid · @motifx-community/ui 0.1.0-beta.2
28329
30504
 
28330
30505
  ## Editing and save modes
28331
30506
 
@@ -28866,7 +31041,7 @@ export default function BarActions() {
28866
31041
 
28867
31042
  # DataGrid: Edit forms and popups
28868
31043
 
28869
- > DataGrid · @motifx-community/ui 0.1.0-beta.1
31044
+ > DataGrid · @motifx-community/ui 0.1.0-beta.2
28870
31045
 
28871
31046
  ## Edit forms and popups
28872
31047
 
@@ -29272,7 +31447,7 @@ export default function ValidationRules() {
29272
31447
 
29273
31448
  # DataGrid: Filtering and search
29274
31449
 
29275
- > DataGrid · @motifx-community/ui 0.1.0-beta.1
31450
+ > DataGrid · @motifx-community/ui 0.1.0-beta.2
29276
31451
 
29277
31452
  ## Filters
29278
31453
 
@@ -29731,7 +31906,7 @@ export function makeCustomers(n: number): Customer[] {
29731
31906
 
29732
31907
  # DataGrid: Lookup columns
29733
31908
 
29734
- > DataGrid · @motifx-community/ui 0.1.0-beta.1
31909
+ > DataGrid · @motifx-community/ui 0.1.0-beta.2
29735
31910
 
29736
31911
  ## Lookup columns
29737
31912
 
@@ -30098,7 +32273,7 @@ export default function TextFrom() {
30098
32273
 
30099
32274
  # DataGrid: Grouping and summaries
30100
32275
 
30101
- > DataGrid · @motifx-community/ui 0.1.0-beta.1
32276
+ > DataGrid · @motifx-community/ui 0.1.0-beta.2
30102
32277
 
30103
32278
  ## Grouping
30104
32279
 
@@ -30521,7 +32696,7 @@ export default function SummariesServer() {
30521
32696
 
30522
32697
  # DataGrid: Master-detail
30523
32698
 
30524
- > DataGrid · @motifx-community/ui 0.1.0-beta.1
32699
+ > DataGrid · @motifx-community/ui 0.1.0-beta.2
30525
32700
 
30526
32701
  ## Master-detail
30527
32702
 
@@ -30851,7 +33026,7 @@ export default function DetailTabs() {
30851
33026
 
30852
33027
  # DataGrid: Bands and adaptive columns
30853
33028
 
30854
- > DataGrid · @motifx-community/ui 0.1.0-beta.1
33029
+ > DataGrid · @motifx-community/ui 0.1.0-beta.2
30855
33030
 
30856
33031
  ## Band headers
30857
33032
 
@@ -31172,7 +33347,7 @@ export default function AdaptiveColumns() {
31172
33347
 
31173
33348
  # DataGrid: Selection and export
31174
33349
 
31175
- > DataGrid · @motifx-community/ui 0.1.0-beta.1
33350
+ > DataGrid · @motifx-community/ui 0.1.0-beta.2
31176
33351
 
31177
33352
  ## Selection
31178
33353
 
@@ -31775,7 +33950,7 @@ export default function PdfExport() {
31775
33950
 
31776
33951
  # DataGrid: Row drag and drop
31777
33952
 
31778
- > DataGrid · @motifx-community/ui 0.1.0-beta.1
33953
+ > DataGrid · @motifx-community/ui 0.1.0-beta.2
31779
33954
 
31780
33955
  ## Reorder rows
31781
33956
 
@@ -32120,7 +34295,7 @@ export default function RowDragBetween() {
32120
34295
 
32121
34296
  # DataGrid: Selecting by dragging
32122
34297
 
32123
- > DataGrid · @motifx-community/ui 0.1.0-beta.1
34298
+ > DataGrid · @motifx-community/ui 0.1.0-beta.2
32124
34299
 
32125
34300
  ## Rows
32126
34301
 
@@ -32450,7 +34625,7 @@ export default function CellRanges() {
32450
34625
 
32451
34626
  # DataGrid: Scrolling
32452
34627
 
32453
- > DataGrid · @motifx-community/ui 0.1.0-beta.1
34628
+ > DataGrid · @motifx-community/ui 0.1.0-beta.2
32454
34629
 
32455
34630
  ## Scrolling modes
32456
34631
 
@@ -32802,7 +34977,7 @@ export default function InfiniteGroups() {
32802
34977
 
32803
34978
  # DataGrid: Layout and events
32804
34979
 
32805
- > DataGrid · @motifx-community/ui 0.1.0-beta.1
34980
+ > DataGrid · @motifx-community/ui 0.1.0-beta.2
32806
34981
 
32807
34982
  ## Toolbar
32808
34983
 
@@ -33346,7 +35521,7 @@ export default function Events() {
33346
35521
 
33347
35522
  # DataGrid: API reference
33348
35523
 
33349
- > DataGrid · @motifx-community/ui 0.1.0-beta.1
35524
+ > DataGrid · @motifx-community/ui 0.1.0-beta.2
33350
35525
 
33351
35526
  ## Columns
33352
35527
 
@@ -33652,7 +35827,7 @@ The rows and their saving are the data layer's: `grid.dataSource` and `grid.chan
33652
35827
 
33653
35828
  ```tsx
33654
35829
  import { reactive } from '@motifx/core';
33655
- import { Button, DataGrid, enStrings, Stack, trStrings, uiLocale } from '@motifx-community/ui';
35830
+ import { Button, DataGrid, Stack, uiLocale } from '@motifx-community/ui';
33656
35831
  import { kitTexts } from '../../../shared/kit-texts';
33657
35832
  import type { Order } from './order';
33658
35833
  import { columns } from './orders';
@@ -33662,7 +35837,7 @@ export default function Localization() {
33662
35837
  const s = reactive({ lang: 'en' });
33663
35838
  const toggle = () => {
33664
35839
  s.lang = s.lang === 'en' ? 'tr' : 'en';
33665
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
35840
+ void uiLocale.use(s.lang);
33666
35841
  };
33667
35842
 
33668
35843
  return (