@zeyos/zx 4.4.0 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (252) hide show
  1. package/CHANGELOG.md +447 -0
  2. package/README.md +44 -11
  3. package/dist/types/components/account-menu/account-menu.d.ts +8 -0
  4. package/dist/types/components/activity-list/activity-list.d.ts +31 -1
  5. package/dist/types/components/app-icon/app-icon.d.ts +14 -2
  6. package/dist/types/components/app-sidebar/app-sidebar.d.ts +293 -17
  7. package/dist/types/components/avatar/avatar.d.ts +46 -7
  8. package/dist/types/components/badge/badge.d.ts +21 -1
  9. package/dist/types/components/button/button.d.ts +15 -0
  10. package/dist/types/components/calendar/calendar.d.ts +67 -5
  11. package/dist/types/components/card-view/card-view.d.ts +7 -4
  12. package/dist/types/components/card-view/record-card.d.ts +11 -0
  13. package/dist/types/components/chart/chart.d.ts +10 -0
  14. package/dist/types/components/checklist/checklist.d.ts +9 -0
  15. package/dist/types/components/code-editor/code-editor.d.ts +6 -17
  16. package/dist/types/components/context-menu/context-menu.d.ts +6 -2
  17. package/dist/types/components/data-filter/data-filter.d.ts +4 -4
  18. package/dist/types/components/datebox/date-range-box.d.ts +5 -1
  19. package/dist/types/components/datebox/datebox.d.ts +7 -2
  20. package/dist/types/components/dialog/dialog.d.ts +46 -6
  21. package/dist/types/components/dropdown/dropdown.d.ts +24 -9
  22. package/dist/types/components/entity-ref/entity-ref.d.ts +2 -2
  23. package/dist/types/components/field/field.d.ts +54 -2
  24. package/dist/types/components/fieldset/external-adapter.d.ts +83 -0
  25. package/dist/types/components/fieldset/fieldset.d.ts +26 -1
  26. package/dist/types/components/file-item/file-item.d.ts +34 -6
  27. package/dist/types/components/file-list/file-list.d.ts +35 -3
  28. package/dist/types/components/filter/filter.d.ts +127 -3
  29. package/dist/types/components/filter-panel/filter-panel.d.ts +36 -7
  30. package/dist/types/components/form/form.d.ts +12 -1
  31. package/dist/types/components/kanban-view/kanban-card.d.ts +8 -0
  32. package/dist/types/components/launcher/launcher.d.ts +268 -15
  33. package/dist/types/components/list-toolbar/list-toolbar.d.ts +16 -7
  34. package/dist/types/components/menu-button/menu-button.d.ts +39 -5
  35. package/dist/types/components/message/message.d.ts +132 -17
  36. package/dist/types/components/modal/modal.d.ts +43 -2
  37. package/dist/types/components/module-bar/module-bar.d.ts +395 -0
  38. package/dist/types/components/pagination/pagination.d.ts +17 -3
  39. package/dist/types/components/select/color.d.ts +12 -0
  40. package/dist/types/components/select/glyphs.d.ts +124 -0
  41. package/dist/types/components/select/select.d.ts +17 -3
  42. package/dist/types/components/sheet/sheet.d.ts +15 -0
  43. package/dist/types/components/stat-tile/stat-tile.d.ts +16 -5
  44. package/dist/types/components/tabbox/tabbox.d.ts +9 -0
  45. package/dist/types/components/table/table.d.ts +311 -18
  46. package/dist/types/components/tag-picker/tag-picker.d.ts +21 -4
  47. package/dist/types/components/tree/tree.d.ts +13 -0
  48. package/dist/types/components/view/record-view.d.ts +59 -2
  49. package/dist/types/components/view-settings/view-settings.d.ts +879 -0
  50. package/dist/types/components/workspace-switcher/workspace-switcher.d.ts +327 -0
  51. package/dist/types/core/breakpoint.d.ts +1 -1
  52. package/dist/types/core/component.d.ts +12 -2
  53. package/dist/types/core/i18n.d.ts +27 -3
  54. package/dist/types/core/icons.d.ts +23 -25
  55. package/dist/types/core/keyboard.d.ts +98 -1
  56. package/dist/types/core/messages.d.ts +382 -0
  57. package/dist/types/core/motion.d.ts +59 -0
  58. package/dist/types/core/overlay-host.d.ts +42 -1
  59. package/dist/types/core/overlay-stack.d.ts +260 -0
  60. package/dist/types/index.d.ts +10 -5
  61. package/dist/types/internal/app-rail.d.ts +38 -0
  62. package/dist/types/internal/menu-items.d.ts +71 -3
  63. package/dist/types/zeyos/connect.d.ts +6 -0
  64. package/dist/types/zeyos/form.d.ts +50 -9
  65. package/dist/types/zeyos/index.d.ts +2 -1
  66. package/dist/types/zeyos/launcher.d.ts +9 -0
  67. package/dist/types/zeyos/module-bar.d.ts +176 -0
  68. package/dist/types/zeyos/query.d.ts +110 -5
  69. package/dist/types/zeyos/schema.d.ts +24 -1
  70. package/dist/types/zeyos/table.d.ts +345 -22
  71. package/dist/types/zeyos/view.d.ts +26 -2
  72. package/dist/zx-zeyos.esm.js +6178 -1008
  73. package/dist/zx-zeyos.esm.min.js +53 -5
  74. package/dist/zx.css +2861 -827
  75. package/dist/zx.esm.js +8909 -1480
  76. package/dist/zx.esm.min.js +55 -7
  77. package/dist/zx.global.js +8911 -1482
  78. package/dist/zx.global.min.js +55 -7
  79. package/dist/zx.min.css +1 -1
  80. package/docs/api.json +1079 -117
  81. package/docs/llms.md +956 -154
  82. package/docs/llms.txt +9 -5
  83. package/package.json +1 -1
  84. package/src/components/account-menu/account-menu.css +35 -10
  85. package/src/components/account-menu/account-menu.js +12 -0
  86. package/src/components/activity-item/activity-item.css +1 -1
  87. package/src/components/activity-item/activity-item.js +3 -0
  88. package/src/components/activity-list/activity-list.css +38 -3
  89. package/src/components/activity-list/activity-list.js +61 -1
  90. package/src/components/app-icon/app-icon.css +14 -3
  91. package/src/components/app-icon/app-icon.js +11 -1
  92. package/src/components/app-rail/app-rail.css +59 -79
  93. package/src/components/app-sidebar/app-sidebar.css +304 -168
  94. package/src/components/app-sidebar/app-sidebar.js +667 -46
  95. package/src/components/aurora/aurora.css +5 -3
  96. package/src/components/avatar/avatar.css +32 -7
  97. package/src/components/avatar/avatar.js +72 -8
  98. package/src/components/badge/badge.css +54 -2
  99. package/src/components/badge/badge.js +29 -2
  100. package/src/components/breadcrumb/breadcrumb.css +1 -1
  101. package/src/components/button/button.css +67 -9
  102. package/src/components/button/button.js +38 -0
  103. package/src/components/calendar/calendar.css +47 -47
  104. package/src/components/calendar/calendar.js +26 -52
  105. package/src/components/card/card.css +4 -4
  106. package/src/components/card-view/card-view.css +14 -12
  107. package/src/components/card-view/card-view.js +13 -9
  108. package/src/components/card-view/record-card.js +14 -3
  109. package/src/components/chart/chart.css +4 -1
  110. package/src/components/chart/chart.js +12 -0
  111. package/src/components/check-button/check-button.css +10 -2
  112. package/src/components/checklist/checklist.css +9 -2
  113. package/src/components/checklist/checklist.js +11 -5
  114. package/src/components/checklist/field-adapter.js +3 -1
  115. package/src/components/code-editor/code-editor.css +7 -6
  116. package/src/components/code-editor/code-editor.js +19 -1
  117. package/src/components/code-editor/field-adapter.js +9 -2
  118. package/src/components/context-menu/context-menu.css +9 -4
  119. package/src/components/context-menu/context-menu.js +8 -2
  120. package/src/components/copy/copy-button.css +6 -0
  121. package/src/components/copy/copy-input.css +9 -4
  122. package/src/components/data-filter/data-filter.css +5 -4
  123. package/src/components/data-filter/data-filter.js +2 -2
  124. package/src/components/date-picker/date-picker.css +6 -6
  125. package/src/components/date-picker/date-range-picker.css +3 -3
  126. package/src/components/date-picker/time-picker.css +3 -3
  127. package/src/components/datebox/date-range-box.css +79 -2
  128. package/src/components/datebox/date-range-box.js +13 -2
  129. package/src/components/datebox/datebox.css +79 -2
  130. package/src/components/datebox/datebox.js +13 -2
  131. package/src/components/dialog/dialog.css +26 -0
  132. package/src/components/dialog/dialog.js +99 -17
  133. package/src/components/dock/dock.css +5 -4
  134. package/src/components/dropdown/dropdown.css +1 -1
  135. package/src/components/dropdown/dropdown.js +159 -72
  136. package/src/components/empty-state/empty-state.css +2 -2
  137. package/src/components/entity-ref/entity-ref.css +1 -1
  138. package/src/components/entity-ref/entity-ref.js +1 -1
  139. package/src/components/field/field.css +28 -9
  140. package/src/components/field/field.js +101 -29
  141. package/src/components/field-upload/field-upload.css +1 -1
  142. package/src/components/fieldset/external-adapter.js +363 -0
  143. package/src/components/fieldset/fieldset.css +5 -3
  144. package/src/components/fieldset/fieldset.js +38 -64
  145. package/src/components/file-item/file-item.js +144 -10
  146. package/src/components/file-list/file-list.js +144 -21
  147. package/src/components/filter/filter.css +86 -2
  148. package/src/components/filter/filter.js +307 -11
  149. package/src/components/filter-panel/filter-panel.css +1 -1
  150. package/src/components/filter-panel/filter-panel.js +149 -32
  151. package/src/components/finder/finder.css +16 -14
  152. package/src/components/form/form.css +5 -4
  153. package/src/components/form/form.js +11 -2
  154. package/src/components/grid/grid.css +1 -1
  155. package/src/components/groupbox/groupbox.css +1 -1
  156. package/src/components/kanban-view/kanban-card.js +11 -3
  157. package/src/components/kanban-view/kanban-view.css +42 -18
  158. package/src/components/kanban-view/kanban-view.js +9 -6
  159. package/src/components/launcher/launcher.css +108 -26
  160. package/src/components/launcher/launcher.js +530 -42
  161. package/src/components/list-toolbar/list-toolbar.css +13 -8
  162. package/src/components/list-toolbar/list-toolbar.js +40 -14
  163. package/src/components/master-panel/master-panel.css +2 -0
  164. package/src/components/master-panel/master-panel.js +0 -1
  165. package/src/components/menu-button/menu-button.css +72 -4
  166. package/src/components/menu-button/menu-button.js +160 -18
  167. package/src/components/message/message.css +33 -3
  168. package/src/components/message/message.js +264 -22
  169. package/src/components/modal/modal.css +1 -1
  170. package/src/components/modal/modal.js +83 -15
  171. package/src/components/module-bar/module-bar.css +486 -0
  172. package/src/components/module-bar/module-bar.js +1074 -0
  173. package/src/components/multi-value-editor/multi-value-editor.css +1 -1
  174. package/src/components/navigation-bar/navigation-bar.css +18 -9
  175. package/src/components/number-field/field-adapter.js +3 -1
  176. package/src/components/number-field/number-field.css +70 -0
  177. package/src/components/number-field/number-field.js +2 -0
  178. package/src/components/pagination/pagination.css +13 -11
  179. package/src/components/pagination/pagination.js +20 -4
  180. package/src/components/panel/panel.css +4 -3
  181. package/src/components/questionnaire/questionnaire.css +4 -4
  182. package/src/components/rating/field-adapter.js +2 -1
  183. package/src/components/rating/rating.css +8 -1
  184. package/src/components/search/search.css +4 -1
  185. package/src/components/select/color.js +22 -0
  186. package/src/components/select/field-adapter.js +2 -0
  187. package/src/components/select/glyphs.js +165 -0
  188. package/src/components/select/select.css +138 -45
  189. package/src/components/select/select.js +92 -47
  190. package/src/components/sheet/sheet.css +12 -9
  191. package/src/components/sheet/sheet.js +74 -32
  192. package/src/components/slider/field-adapter.js +6 -1
  193. package/src/components/slider/slider.css +18 -4
  194. package/src/components/slider/slider.js +1 -1
  195. package/src/components/sort-control/sort-control.css +4 -1
  196. package/src/components/split-view/split-view.css +1 -1
  197. package/src/components/stat-tile/stat-tile.css +42 -47
  198. package/src/components/stat-tile/stat-tile.js +17 -6
  199. package/src/components/stepper/stepper.css +1 -1
  200. package/src/components/tabbox/tabbox.css +41 -32
  201. package/src/components/tabbox/tabbox.js +5 -1
  202. package/src/components/table/table.css +187 -37
  203. package/src/components/table/table.js +718 -73
  204. package/src/components/tag-picker/field-adapter.js +2 -1
  205. package/src/components/tag-picker/tag-picker.css +83 -5
  206. package/src/components/tag-picker/tag-picker.js +25 -8
  207. package/src/components/timebox/timebox.css +22 -2
  208. package/src/components/toggle/toggle.css +12 -1
  209. package/src/components/toolbar/toolbar.js +2 -2
  210. package/src/components/tooltip/tooltip.css +4 -0
  211. package/src/components/tooltip/tooltip.js +44 -19
  212. package/src/components/tree/tree.css +26 -17
  213. package/src/components/tree/tree.js +31 -0
  214. package/src/components/value-list/value-list.css +3 -3
  215. package/src/components/view/record-view.css +1 -1
  216. package/src/components/view/record-view.js +178 -18
  217. package/src/components/view-settings/view-settings.css +285 -0
  218. package/src/components/view-settings/view-settings.js +1830 -0
  219. package/src/components/workspace-switcher/workspace-switcher.css +188 -0
  220. package/src/components/workspace-switcher/workspace-switcher.js +463 -0
  221. package/src/core/breakpoint.js +1 -1
  222. package/src/core/component.js +88 -17
  223. package/src/core/fontawesome.js +5 -1
  224. package/src/core/i18n.js +47 -4
  225. package/src/core/icons.js +204 -61
  226. package/src/core/keyboard.js +206 -11
  227. package/src/core/messages.js +427 -0
  228. package/src/core/motion.js +147 -0
  229. package/src/core/overlay-host.js +77 -3
  230. package/src/core/overlay-stack.js +487 -0
  231. package/src/core/position.js +22 -3
  232. package/src/index.js +10 -5
  233. package/src/internal/app-rail.js +135 -55
  234. package/src/internal/menu-items.js +61 -3
  235. package/src/zeyos/connect.js +6 -2
  236. package/src/zeyos/form.js +69 -27
  237. package/src/zeyos/index.js +4 -1
  238. package/src/zeyos/launcher.js +8 -3
  239. package/src/zeyos/module-bar.js +181 -0
  240. package/src/zeyos/query.js +197 -13
  241. package/src/zeyos/schema.js +144 -27
  242. package/src/zeyos/table.js +287 -84
  243. package/src/zeyos/view.js +49 -93
  244. package/styles/base.css +72 -1
  245. package/styles/icons.css +11 -1
  246. package/styles/print.css +1 -1
  247. package/styles/tokens/dark.css +117 -37
  248. package/styles/tokens/global.css +121 -27
  249. package/styles/tokens/semantic.css +140 -43
  250. package/styles/tokens/themes.css +7 -6
  251. package/styles/zx.css +3 -1
  252. package/styles/tokens/density.css +0 -9
@@ -0,0 +1,427 @@
1
+ // @ts-check
2
+ /**
3
+ * The library's default English catalogue: every message key a component resolves through
4
+ * `msg()`, mapped to the English text it shows when nothing else answers.
5
+ *
6
+ * `Component#msg()` asks, in order, the instance's own `msg` option, the host translator installed
7
+ * with `setTranslator()`, the component class's built-in `msg` defaults, this catalogue, and only
8
+ * then gives the key back. `translate()` asks the translator and then this catalogue. A host
9
+ * starting a locale copies this object and translates the values; keys are `component.key`,
10
+ * placeholders are `%1`, `%2`, … in the order the component passes its arguments.
11
+ *
12
+ * `tests/unit/messages.test.js` scans `src/` for every key a component asks for and fails when one
13
+ * has no entry here, or when an entry disagrees with the English fallback written beside the call.
14
+ * Three keys are deliberately absent, because something other than English must win when the
15
+ * translator has no answer: `tree.empty` and `finder.empty` fall back to the component's
16
+ * `emptyText` option, and `priority.medium` is probed before the older `priority.normal`.
17
+ */
18
+ export const defaultMessages = Object.freeze({
19
+ 'activityItem.actions': 'Actions for %1',
20
+ 'activityItem.attachments': 'Attachments',
21
+ 'activityItem.failed': 'Failed',
22
+ 'activityItem.label': 'Activity',
23
+ 'activityItem.metadata': 'Activity metadata',
24
+ 'activityItem.pending': 'Sending…',
25
+ 'activityItem.untitled': 'activity',
26
+
27
+ 'appRail.subNavigation': '%1 sub-navigation',
28
+
29
+ 'appSidebar.expand': 'Expand application sidebar',
30
+ 'appSidebar.itemBadge': '%1 (%2)',
31
+ 'appSidebar.minimize': 'Minimize application sidebar',
32
+ 'appSidebar.presentation': 'Navigation layout',
33
+ 'appSidebar.presentationCollapsed': 'Both menus collapsed',
34
+ 'appSidebar.presentationCompact': 'Module menu collapsed',
35
+ 'appSidebar.presentationExpanded': 'Both menus expanded',
36
+
37
+ 'breadcrumb.label': 'Breadcrumb',
38
+ 'breadcrumb.more': 'Show hidden levels',
39
+
40
+ 'calendar.agenda': 'Agenda',
41
+ 'calendar.allDay': 'All day',
42
+ 'calendar.day': 'Day',
43
+ 'calendar.dayEvent': '%1, %2 event',
44
+ 'calendar.dayEvents': '%1, %2 events',
45
+ 'calendar.editCancelled': 'Calendar edit cancelled.',
46
+ 'calendar.editCommitted': '%1 updated.',
47
+ 'calendar.editPreview': '%1, %2 to %3',
48
+ 'calendar.label': 'Calendar',
49
+ 'calendar.loading': 'Loading calendar…',
50
+ 'calendar.month': 'Month',
51
+ 'calendar.more': '+%1 more',
52
+ 'calendar.moveStarted': 'Moving %1. Use arrow keys, Space to drop, or Escape to cancel.',
53
+ 'calendar.new': 'New',
54
+ 'calendar.next': 'Next period',
55
+ 'calendar.noEvents': 'No events',
56
+ 'calendar.previous': 'Previous period',
57
+ 'calendar.resize': 'Resize %1',
58
+ 'calendar.resizeStarted': 'Resizing %1. Use arrow keys, Space to drop, or Escape to cancel.',
59
+ 'calendar.today': 'Today',
60
+ 'calendar.viewSwitch': 'Calendar view',
61
+ 'calendar.week': 'Week',
62
+ 'calendar.weekNumber': 'Week %1',
63
+ 'calendar.year': 'Year',
64
+
65
+ 'card.actions': 'Card actions',
66
+
67
+ 'cardView.groupEmpty': 'No records in this group.',
68
+ 'cardView.label': 'Card view',
69
+ 'cardView.sort': 'Sort',
70
+ 'cardView.sortAscending': '%1 (ascending)',
71
+ 'cardView.sortCards': 'Sort cards',
72
+ 'cardView.sortDescending': '%1 (descending)',
73
+ 'cardView.ungrouped': 'Ungrouped',
74
+ 'cardView.unsorted': 'Unsorted',
75
+
76
+ 'checklist.empty': 'No matches',
77
+ 'checklist.label': 'Checklist',
78
+ 'checklist.search': 'Search',
79
+
80
+ 'dataFilter.all': 'All',
81
+ 'dataFilter.clear': 'Clear',
82
+
83
+ 'datePicker.calendar': 'Calendar',
84
+ 'datePicker.chooseMonthYear': 'Choose month and year, %1',
85
+ 'datePicker.nextMonth': 'Next month',
86
+ 'datePicker.nextYear': 'Next year',
87
+ 'datePicker.previousMonth': 'Previous month',
88
+ 'datePicker.previousYear': 'Previous year',
89
+ 'datePicker.week': 'Week %1',
90
+ 'datePicker.weekNumber': 'Week number',
91
+
92
+ 'daterange.choose': 'Choose date range',
93
+ 'daterange.clear': 'Clear date range',
94
+ 'daterange.day.end': 'range end',
95
+ 'daterange.day.middle': 'in selected range',
96
+ 'daterange.day.start': 'range start',
97
+ 'daterange.label': 'Date range',
98
+ 'daterange.nextMonth': 'Next month',
99
+ 'daterange.night': '1 night',
100
+ 'daterange.nights': '%1 nights',
101
+ 'daterange.preset.last30': 'Last 30 days',
102
+ 'daterange.preset.last7': 'Last 7 days',
103
+ 'daterange.preset.lastMonth': 'Last month',
104
+ 'daterange.preset.thisMonth': 'This month',
105
+ 'daterange.preset.thisQuarter': 'This quarter',
106
+ 'daterange.preset.thisYear': 'This year',
107
+ 'daterange.preset.today': 'Today',
108
+ 'daterange.preset.yesterday': 'Yesterday',
109
+ 'daterange.presets': 'Date range presets',
110
+ 'daterange.previousMonth': 'Previous month',
111
+ 'daterange.status.empty': 'No date range selected',
112
+ 'daterange.status.start': '%1 selected, choose an end date',
113
+ 'daterange.week': 'Week %1',
114
+ 'daterange.weekNumber': 'Week number',
115
+
116
+ 'dialog.cancel': 'Cancel',
117
+ 'dialog.close': 'Close',
118
+ 'dialog.ok': 'OK',
119
+ 'dialog.promptValue': 'Prompt value',
120
+ 'dialog.typeToConfirm': 'Type %1 to confirm',
121
+
122
+ 'field.float': 'Enter a valid number.',
123
+ 'field.int': 'Enter a whole number.',
124
+ 'field.unknown': 'Unknown field type: %1',
125
+
126
+ 'filter.addFilter': 'Add filter',
127
+ 'filter.addGroup': 'Add group',
128
+ 'filter.addSubgroup': 'Add subgroup',
129
+ 'filter.and': 'and',
130
+ 'filter.apply': 'Apply filters',
131
+ 'filter.booleanFalse': 'False',
132
+ 'filter.booleanTrue': 'True',
133
+ 'filter.choose': 'Choose…',
134
+ 'filter.chooseField': 'Choose a field…',
135
+ 'filter.chooseOperator': 'Choose an operator…',
136
+ 'filter.choosePart': 'Choose %1…',
137
+ 'filter.clear': 'Clear',
138
+ 'filter.commaSeparated': 'Comma-separated values',
139
+ 'filter.conditionNoun': 'Filter',
140
+ 'filter.conditions': 'conditions',
141
+ 'filter.field': 'Filter field',
142
+ 'filter.fieldValue': '%1 value',
143
+ 'filter.fieldValueAt': '%1 value %2',
144
+ 'filter.filterNoun': 'filter',
145
+ 'filter.groupLogic': 'Group filter logic',
146
+ 'filter.groupNoun': 'Filter group',
147
+ 'filter.inThisGroup': 'in this group',
148
+ 'filter.matchAll': 'Match all',
149
+ 'filter.matchAllConditions': 'Match all conditions',
150
+ 'filter.matchAny': 'Match any',
151
+ 'filter.matchAnyConditions': 'Match any conditions',
152
+ 'filter.noValue': 'No value',
153
+ 'filter.operator': 'Filter operator',
154
+ 'filter.or': 'or',
155
+ 'filter.relativeAmount': '%1: number of units',
156
+ 'filter.relativeInvalid': 'Enter a whole number of days, weeks or months',
157
+ 'filter.relativeUnit': '%1: unit',
158
+ 'filter.remove': 'Remove %1',
159
+ 'filter.removed': '%1 removed',
160
+ 'filter.removeGroup': 'Remove group',
161
+ 'filter.rootLogic': 'Root filter logic',
162
+ 'filter.switchToAll': '%1 — switch to all',
163
+ 'filter.switchToAny': '%1 — switch to any',
164
+ 'filter.unavailable': 'Unavailable: %1',
165
+ 'filter.unit.days': 'days',
166
+ 'filter.unit.months': 'months',
167
+ 'filter.unit.weeks': 'weeks',
168
+
169
+ 'filterPanel.apply': 'Apply',
170
+ 'filterPanel.clear': 'Clear all',
171
+ 'filterPanel.empty': 'No filters are available here.',
172
+ 'filterPanel.from': 'From',
173
+ 'filterPanel.label': 'Filters',
174
+ 'filterPanel.rangeFrom': '%1 from',
175
+ 'filterPanel.rangeTo': '%1 to',
176
+ 'filterPanel.to': 'To',
177
+ 'filterPanel.unsupported': 'Unsupported filter type: %1',
178
+
179
+ 'finder.loading': 'Loading…',
180
+ 'finder.root': 'Root',
181
+
182
+ 'form.float': 'Enter a valid number.',
183
+ 'form.int': 'Enter a whole number.',
184
+ 'form.required': 'This field is required.',
185
+
186
+ 'launcher.back': 'Back to %1',
187
+ 'launcher.close': 'Close launcher',
188
+ 'launcher.empty': 'No results',
189
+ 'launcher.hintBack': 'Back',
190
+ 'launcher.hintClose': 'Close',
191
+ 'launcher.hintMove': 'Move',
192
+ 'launcher.hintOpen': 'Open',
193
+ 'launcher.label': 'Launcher',
194
+ 'launcher.loading': 'Searching…',
195
+ 'launcher.pageEmpty': '%1, no results',
196
+ 'launcher.pageLabel': 'Search %1',
197
+ 'launcher.pagePlaceholder': 'Search',
198
+ 'launcher.pageResult': '%1, 1 result',
199
+ 'launcher.pageResults': '%1, %2 results',
200
+ 'launcher.placeholder': 'Search applications and records',
201
+ 'launcher.results': 'Launcher results',
202
+
203
+ 'listToolbar.label': 'List controls',
204
+ 'listToolbar.results': '%1 results',
205
+ 'listToolbar.search': 'Search',
206
+ 'listToolbar.toolBadge': '%1 (%2)',
207
+ 'listToolbar.viewAuto': 'Auto',
208
+ 'listToolbar.viewBoard': 'Board',
209
+ 'listToolbar.viewCards': 'Cards',
210
+ 'listToolbar.viewGallery': 'Gallery',
211
+ 'listToolbar.viewList': 'List',
212
+ 'listToolbar.views': 'View',
213
+ 'listToolbar.viewTable': 'Table',
214
+
215
+ 'message.close': 'Close message',
216
+ 'message.closeTitle': 'Close',
217
+
218
+ 'moduleBar.empty': 'No modules',
219
+ 'moduleBar.filter': 'Filter modules',
220
+ 'moduleBar.itemBadge': '%1 (%2)',
221
+ 'moduleBar.label': 'Modules',
222
+ 'moduleBar.more': 'All modules',
223
+
224
+ 'monthPicker.chooseMonth': 'Choose month',
225
+ 'monthPicker.nextYear': 'Next year',
226
+ 'monthPicker.previousYear': 'Previous year',
227
+
228
+ 'numberField.empty': 'Empty',
229
+
230
+ 'pagination.empty': '0 of 0',
231
+ 'pagination.label': 'Pagination',
232
+ 'pagination.loaded': '%1 of %2',
233
+ 'pagination.loadMore': 'Load more',
234
+ 'pagination.next': 'Next page',
235
+ 'pagination.page': 'Page %1',
236
+ 'pagination.pageSize': 'Rows per page',
237
+ 'pagination.previous': 'Previous page',
238
+ 'pagination.summary': '%1–%2 of %3',
239
+
240
+ 'panel.actions': 'Panel actions',
241
+ 'panel.footerActions': 'Panel footer actions',
242
+
243
+ 'permission.private': 'Private',
244
+ 'permission.public': 'Public',
245
+
246
+ 'priority.high': 'High',
247
+ 'priority.highest': 'Highest',
248
+ 'priority.low': 'Low',
249
+ 'priority.lowest': 'Lowest',
250
+ 'priority.none': 'No priority',
251
+ 'priority.normal': 'Medium',
252
+
253
+ 'questionnaire.counter': 'Question %1 of %2',
254
+ 'questionnaire.edit': 'Edit',
255
+ 'questionnaire.empty': 'There is nothing to answer.',
256
+ 'questionnaire.next': 'Continue',
257
+ 'questionnaire.noAnswer': 'Skipped',
258
+ 'questionnaire.previous': 'Back',
259
+ 'questionnaire.required': 'Choose an answer to continue.',
260
+ 'questionnaire.requiredInput': 'Enter an answer to continue.',
261
+ 'questionnaire.review': 'Review answers',
262
+ 'questionnaire.reviewTitle': 'Check your answers',
263
+ 'questionnaire.skip': 'Skip',
264
+ 'questionnaire.submit': 'Submit',
265
+
266
+ 'rating.count': '%1 ratings',
267
+ 'rating.value': '%1 of %2',
268
+
269
+ 'recordCard.actions': 'Actions for %1',
270
+ 'recordCard.notSelected': 'Not selected',
271
+ 'recordCard.select': 'Select %1',
272
+ 'recordCard.selected': 'Selected',
273
+ 'recordCard.untitled': 'record',
274
+
275
+ 'recordView.fieldMoved': '%1 moved to position %2 of %3',
276
+ 'recordView.fields': 'Fields',
277
+ 'recordView.moveFieldDown': 'Move %1 down',
278
+ 'recordView.moveFieldUp': 'Move %1 up',
279
+
280
+ 'search.clear': 'Clear search',
281
+ 'search.label': 'Search',
282
+ 'search.submit': 'Submit search',
283
+ 'search.submitTitle': 'Search',
284
+
285
+ 'select.clear': 'Clear selection',
286
+ 'select.empty': 'No matches',
287
+ 'select.loading': 'Loading',
288
+ 'select.none': 'No selection',
289
+ 'select.toggle': 'Toggle options',
290
+
291
+ 'sheet.resize': 'Resize sheet',
292
+
293
+ 'statTile.down': 'down %1',
294
+ 'statTile.loading': 'Loading',
295
+ 'statTile.unchanged': 'no change',
296
+ 'statTile.up': 'up %1',
297
+
298
+ 'stepper.completed': 'Completed',
299
+ 'stepper.counter': 'Step %1 of %2',
300
+ 'stepper.current': 'Current step',
301
+ 'stepper.error': 'Error',
302
+ 'stepper.optional': 'Optional',
303
+
304
+ 'tabbox.close': 'Close',
305
+
306
+ 'table.collapseRow': 'Collapse %1',
307
+ 'table.columns': 'Columns',
308
+ 'table.empty': 'No records',
309
+ 'table.label': 'Table',
310
+ 'table.expandRow': 'Expand %1',
311
+ 'table.invalid': 'Invalid value',
312
+ 'table.more': 'Show %1 more',
313
+ 'table.moveColumn': 'Move %1',
314
+ 'table.moveRow': 'Move %1',
315
+ 'table.row': 'row %1',
316
+ 'table.selectAll': 'Select all rows',
317
+ 'table.selectRow': 'Select %1',
318
+
319
+ 'tagPicker.create': 'Create “%1”',
320
+ 'tagPicker.empty': 'No matches',
321
+ 'tagPicker.input': 'Add a value',
322
+ 'tagPicker.loading': 'Loading…',
323
+ 'tagPicker.remove': 'Remove %1',
324
+ 'tagPicker.toggle': 'Toggle options',
325
+
326
+ 'timebox.duration': 'Duration in hours and minutes',
327
+ 'timebox.durationWithSeconds': 'Duration in hours, minutes, and seconds',
328
+ 'timebox.hours': 'Hours',
329
+ 'timebox.minutes': 'Minutes',
330
+ 'timebox.seconds': 'Seconds',
331
+ 'timebox.toggleSign': 'Toggle duration sign',
332
+
333
+ 'timePicker.clock': 'Pick the time on a clock',
334
+ 'timePicker.hour': 'Hour',
335
+ 'timePicker.label': 'Time',
336
+ 'timePicker.minute': 'Minute',
337
+ 'timePicker.minutes': 'Minutes',
338
+ 'timePicker.second': 'Second',
339
+ 'timePicker.selectHour': 'Select the hour',
340
+ 'timePicker.selectMinutes': 'Select the minutes',
341
+
342
+ 'valueList.add': 'Add value',
343
+ 'valueList.duplicate': 'This value already exists.',
344
+ 'valueList.instructions': 'Press Enter to add. Focus a value and press Ctrl plus Left or Right to reorder.',
345
+ 'valueList.invalid': 'This value is not valid.',
346
+ 'valueList.removable': '%1. Press Delete to remove.',
347
+ 'valueList.values': 'Values',
348
+
349
+ 'viewSettings.add': 'Add',
350
+ 'viewSettings.added': '%1 added at position %2 of %3',
351
+ 'viewSettings.addField': 'Add %1',
352
+ 'viewSettings.allShown': 'Every field is shown.',
353
+ 'viewSettings.board': 'Board',
354
+ 'viewSettings.canceled': 'Move canceled. %1 is back at position %2 of %3',
355
+ 'viewSettings.chooseField': 'Choose a field',
356
+ 'viewSettings.columns': 'Columns',
357
+ 'viewSettings.dragging': '%1 picked up, position %2 of %3',
358
+ 'viewSettings.dropped': '%1 dropped at position %2 of %3',
359
+ 'viewSettings.emptyColumns': 'Show empty columns',
360
+ 'viewSettings.fields': 'Fields',
361
+ 'viewSettings.grabbed': '%1 picked up, position %2 of %3. Use the arrow keys to move it, Space to drop it, Escape to cancel.',
362
+ 'viewSettings.group': 'Group by',
363
+ 'viewSettings.hidden': 'Hidden (%1)',
364
+ 'viewSettings.hiddenField': '%1 hidden',
365
+ 'viewSettings.hide': 'Hide %1',
366
+ 'viewSettings.instructions': 'Press Space to pick the field up, the arrow keys to move it, Space again to drop it, or Escape to cancel.',
367
+ 'viewSettings.label': 'View settings',
368
+ 'viewSettings.lastField': 'At least one field stays shown',
369
+ 'viewSettings.locked': 'Always shown',
370
+ 'viewSettings.moved': '%1 moved to position %2 of %3',
371
+ 'viewSettings.noMatch': 'No hidden field matches “%1”.',
372
+ 'viewSettings.none': 'None',
373
+ 'viewSettings.reorder': 'Reorder %1',
374
+ 'viewSettings.search': 'Find a field',
375
+ 'viewSettings.shown': 'Shown (%1)',
376
+ 'viewSettings.swimlanes': 'Swim lanes',
377
+ 'viewSettings.typeBoolean': 'Checkbox',
378
+ 'viewSettings.typeDate': 'Date',
379
+ 'viewSettings.typeDatetime': 'Date and time',
380
+ 'viewSettings.typeEmail': 'Email',
381
+ 'viewSettings.typeEntity': 'Linked record',
382
+ 'viewSettings.typeFile': 'File',
383
+ 'viewSettings.typeImage': 'Image',
384
+ 'viewSettings.typeMoney': 'Money',
385
+ 'viewSettings.typeNumber': 'Number',
386
+ 'viewSettings.typePriority': 'Priority',
387
+ 'viewSettings.typeRating': 'Rating',
388
+ 'viewSettings.typeSelect': 'Select',
389
+ 'viewSettings.typeStatus': 'Status',
390
+ 'viewSettings.typeTags': 'Tags',
391
+ 'viewSettings.typeText': 'Text',
392
+ 'viewSettings.typeTime': 'Time',
393
+ 'viewSettings.typeUrl': 'URL',
394
+
395
+ 'workspaceSwitcher.heading': 'Workspaces',
396
+ 'workspaceSwitcher.label': 'Switch workspace: %1',
397
+ 'workspaceSwitcher.labelEmpty': 'Switch workspace'
398
+ });
399
+
400
+ /**
401
+ * Keys renamed in 5.x, each mapped to the key it replaced. `Component#msg()` reads the old key
402
+ * second — after the new one, in the instance `msg` option and in the host translator alike — so a
403
+ * translation written against the old name keeps working for one more major version.
404
+ */
405
+ export const legacyMessageKeys = Object.freeze({
406
+ 'calendar.agenda': 'agenda',
407
+ 'calendar.allDay': 'allDay',
408
+ 'calendar.day': 'day',
409
+ 'calendar.editCancelled': 'editCancelled',
410
+ 'calendar.editCommitted': 'editCommitted',
411
+ 'calendar.editPreview': 'editPreview',
412
+ 'calendar.label': 'calendar',
413
+ 'calendar.loading': 'loading',
414
+ 'calendar.month': 'month',
415
+ 'calendar.more': 'more',
416
+ 'calendar.moveStarted': 'moveStarted',
417
+ 'calendar.new': 'new',
418
+ 'calendar.next': 'next',
419
+ 'calendar.noEvents': 'noEvents',
420
+ 'calendar.previous': 'previous',
421
+ 'calendar.resize': 'resize',
422
+ 'calendar.resizeStarted': 'resizeStarted',
423
+ 'calendar.today': 'today',
424
+ 'calendar.week': 'week',
425
+ 'calendar.weekNumber': 'weekNumber',
426
+ 'calendar.year': 'year'
427
+ });
@@ -0,0 +1,147 @@
1
+ // @ts-check
2
+ /**
3
+ * Motion as a setting, for the code that animates in script.
4
+ *
5
+ * CSS motion needs nothing from here: `tokens/global.css` sets every `--zx-dur-*` to 0ms and
6
+ * `base.css` stops animations and transitions both under the operating system's reduced-motion
7
+ * preference and inside any `data-zx-motion="reduced"` region. A chart engine's own tweening, a
8
+ * `requestAnimationFrame` loop, or `element.animate()` never sees those rules, so a component that
9
+ * moves things itself asks `prefersReducedMotion()` before it starts and `watchMotion()` for the
10
+ * moment the answer changes.
11
+ *
12
+ * There is no "full motion" value: a region can only ask for less. Someone who asked their system
13
+ * for reduced motion gets it whatever an application or a region says.
14
+ * @module zx/core/motion
15
+ */
16
+
17
+ /** The attribute that marks a reduced-motion region. Its one meaningful value is `reduced`. */
18
+ export const MOTION_ATTRIBUTE = 'data-zx-motion';
19
+
20
+ const REDUCED_REGION = '[data-zx-motion="reduced"]';
21
+ const REDUCED_QUERY = '(prefers-reduced-motion: reduce)';
22
+
23
+ /**
24
+ * Whether motion should stop where `element` is: true under the operating system's reduced-motion
25
+ * preference, or when the element sits inside a `data-zx-motion="reduced"` region (the element
26
+ * itself included). The region check crosses shadow-root boundaries.
27
+ * @param {Element|null} [element] Where the motion would happen. Omitted, the document root is
28
+ * asked — which answers for an application that sets the attribute on `<html>`.
29
+ * @returns {boolean}
30
+ */
31
+ export function prefersReducedMotion(element) {
32
+ if (systemPrefersReducedMotion()) return true;
33
+ const target = element ?? globalThis.document?.documentElement ?? null;
34
+ return inReducedRegion(target);
35
+ }
36
+
37
+ /**
38
+ * @typedef {Object} WatchMotionOptions
39
+ * @property {AbortSignal} [signal] Stops watching when aborted, exactly as calling the returned
40
+ * disposer does. A signal that is already aborted watches nothing.
41
+ * @property {boolean} [immediate=false] Also calls back once, synchronously, with the current
42
+ * answer — convenient for a loop that starts or stays stopped in the same callback.
43
+ */
44
+
45
+ /**
46
+ * Calls back whenever `prefersReducedMotion(element)` changes: when the operating-system preference
47
+ * flips, or when a `data-zx-motion` attribute is set, changed, or removed on the element or any
48
+ * ancestor (in the document, or in the shadow root the element lives in). The callback receives
49
+ * the new answer and runs only on a real change.
50
+ *
51
+ * Moving the element into or out of a reduced region is not observed — ask
52
+ * `prefersReducedMotion()` again after re-parenting.
53
+ * @param {Element|null} element Where the motion happens. Null watches the document root.
54
+ * @param {(reduced: boolean) => void} fn Receives `true` when motion must stop, `false` when it may
55
+ * run again.
56
+ * @param {WatchMotionOptions} [options={}]
57
+ * @returns {() => void} Disposer: stops watching. Safe to call more than once.
58
+ */
59
+ export function watchMotion(element, fn, options = {}) {
60
+ if (typeof fn !== 'function') throw new TypeError('watchMotion requires a callback');
61
+ const { signal, immediate = false } = options;
62
+ if (signal?.aborted) return () => {};
63
+
64
+ let current = prefersReducedMotion(element);
65
+ let stopped = false;
66
+
67
+ const check = () => {
68
+ if (stopped) return;
69
+ const next = prefersReducedMotion(element);
70
+ if (next === current) return;
71
+ current = next;
72
+ fn(next);
73
+ };
74
+
75
+ const media = typeof globalThis.matchMedia === 'function' ? globalThis.matchMedia(REDUCED_QUERY) : null;
76
+ media?.addEventListener?.('change', check);
77
+
78
+ // One observer over every tree the element's ancestry passes through: the document, and each
79
+ // shadow root on the way up. The attribute filter keeps it to the one attribute that matters.
80
+ const observer = typeof MutationObserver === 'function' ? new MutationObserver(check) : null;
81
+ if (observer) {
82
+ for (const root of treesAbove(element)) {
83
+ observer.observe(root, { attributes: true, attributeFilter: [MOTION_ATTRIBUTE], subtree: true });
84
+ }
85
+ }
86
+
87
+ const stop = () => {
88
+ if (stopped) return;
89
+ stopped = true;
90
+ media?.removeEventListener?.('change', check);
91
+ observer?.disconnect();
92
+ signal?.removeEventListener('abort', stop);
93
+ };
94
+ signal?.addEventListener('abort', stop, { once: true });
95
+
96
+ if (immediate) fn(current);
97
+ return stop;
98
+ }
99
+
100
+ /** @returns {boolean} Whether the operating system asks for reduced motion. */
101
+ function systemPrefersReducedMotion() {
102
+ return typeof globalThis.matchMedia === 'function' && globalThis.matchMedia(REDUCED_QUERY).matches;
103
+ }
104
+
105
+ /**
106
+ * @param {Element|null} element
107
+ * @returns {boolean} Whether the element is inside a reduced region, across shadow boundaries.
108
+ */
109
+ function inReducedRegion(element) {
110
+ /** @type {Element|null} */
111
+ let node = element;
112
+ while (node && typeof node.closest === 'function') {
113
+ if (node.closest(REDUCED_REGION)) return true;
114
+ const root = node.getRootNode?.();
115
+ node = isShadowRoot(root) ? root.host : null;
116
+ }
117
+ return false;
118
+ }
119
+
120
+ /**
121
+ * The trees a region attribute could be set in: the shadow roots on the element's way up, and the
122
+ * document element.
123
+ * @param {Element|null} element
124
+ * @returns {Node[]}
125
+ */
126
+ function treesAbove(element) {
127
+ const trees = [];
128
+ /** @type {Element|null} */
129
+ let node = element;
130
+ while (node && typeof node.getRootNode === 'function') {
131
+ const root = node.getRootNode();
132
+ if (!isShadowRoot(root)) break;
133
+ trees.push(root);
134
+ node = root.host;
135
+ }
136
+ const documentElement = (element?.ownerDocument ?? globalThis.document)?.documentElement;
137
+ if (documentElement) trees.push(documentElement);
138
+ return trees;
139
+ }
140
+
141
+ /**
142
+ * @param {unknown} node
143
+ * @returns {node is ShadowRoot}
144
+ */
145
+ function isShadowRoot(node) {
146
+ return Boolean(node) && /** @type {Node} */ (node).nodeType === 11 && 'host' in /** @type {object} */ (node);
147
+ }
@@ -1,22 +1,96 @@
1
1
  import { resolveElement } from './dom.js';
2
2
 
3
- const SCOPE_SELECTOR = '.zx-scope, [data-zx-theme], [data-zx-density], [data-zx-preset]';
3
+ const SCOPE_SELECTOR = '.zx-scope, [data-zx-theme], [data-zx-preset]';
4
+
5
+ /**
6
+ * Open dialogs an anchored overlay must live inside. A modal one makes everything outside its
7
+ * subtree inert, and a focus-trapping one sends Tab back into itself, so a panel parked outside
8
+ * either could be seen but never used. `:popover-open` is the floating non-modal Sheet.
9
+ */
10
+ const DIALOG_SELECTOR = 'dialog:modal, dialog[open], dialog:popover-open';
4
11
 
5
12
  /**
6
13
  * Finds the closest styling scope for a top-layer element.
7
14
  *
8
15
  * Popovers and dialogs escape clipping even when their DOM parent is inside an application shell,
9
- * so keeping them below that parent preserves inherited theme, density, material, and product
16
+ * so keeping them below that parent preserves inherited theme, preset, material, and product
10
17
  * token overrides without sacrificing top-layer behaviour. The document body remains the safe
11
18
  * fallback for unscoped applications.
12
19
  *
20
+ * Never answers a dialog: this is where a dialog itself, or anything at rest, belongs.
21
+ *
13
22
  * @param {Element|string|null} [source=null] Element or selector whose styling scope should own the overlay.
14
23
  * @returns {Element}
15
24
  */
25
+ export function overlayScope(source = null) {
26
+ return scopeOf(contextOf(source));
27
+ }
28
+
29
+ /**
30
+ * Finds the element an anchored overlay should live in while it is open.
31
+ *
32
+ * A source inside an open `<dialog>` — modal, focus-trapping, or a floating non-modal Sheet — is
33
+ * hosted by that dialog: the panel still rises into the top layer above it, and being in its
34
+ * subtree is what keeps the panel out of `showModal()`'s inertness and inside a focus trap's
35
+ * reach. Anywhere else the answer is the nearest styling scope, as `overlayScope()` gives it.
36
+ *
37
+ * Without a source the focused element supplies the scope, and no dialog is chosen: what is
38
+ * being hosted then is not anchored to the focused element, only themed by it.
39
+ *
40
+ * @param {Element|string|null} [source=null] Element or selector the overlay is anchored to.
41
+ * @returns {Element}
42
+ */
16
43
  export function overlayHost(source = null) {
17
- const context = source == null
44
+ const context = contextOf(source);
45
+ return (source == null ? null : openDialogOf(context)) ?? scopeOf(context);
46
+ }
47
+
48
+ /**
49
+ * Like `overlayHost()`, but declines to guess for a source that is not in the document yet.
50
+ *
51
+ * A component created before its anchor is connected cannot know which themed region the anchor
52
+ * will end up in: the anchor's ancestors are not there yet, so `overlayHost()` would answer
53
+ * `<body>`, outside every `[data-zx-theme]` and `.zx-scope`. This returns null instead, so the
54
+ * overlay can stay detached until it first opens and resolve its host with `overlayHost()` then,
55
+ * when the anchor is in place. The focused-element default (`source` null) is always connected and
56
+ * resolves exactly as `overlayHost()` does.
57
+ *
58
+ * @param {Element|string|null} [source=null] Element or selector whose styling scope should own the overlay.
59
+ * @param {{dialog?: boolean}} [options={}] `dialog: false` answers the styling scope only, as
60
+ * `overlayScope()` does — where a closed panel rests until it opens.
61
+ * @returns {Element|null} The host, or null while the source is not connected to the document.
62
+ */
63
+ export function connectedOverlayHost(source = null, options = {}) {
64
+ const host = options.dialog === false ? overlayScope : overlayHost;
65
+ if (source == null) return host(null);
66
+ const context = resolveElement(source);
67
+ return context?.isConnected ? host(context) : null;
68
+ }
69
+
70
+ /**
71
+ * The open dialog an element sits in, or null.
72
+ * @param {Element|null|undefined} element
73
+ * @returns {Element|null}
74
+ */
75
+ export function openDialogOf(element) {
76
+ if (!element || typeof element.closest !== 'function') return null;
77
+ try {
78
+ return element.closest(DIALOG_SELECTOR);
79
+ } catch {
80
+ // A browser without `:modal` or `:popover-open` still knows an open dialog by its attribute.
81
+ return element.closest('dialog[open]');
82
+ }
83
+ }
84
+
85
+ /** @param {Element|string|null} source @returns {Element|null} */
86
+ function contextOf(source) {
87
+ return source == null
18
88
  ? (document.activeElement instanceof Element ? document.activeElement : null)
19
89
  : resolveElement(source);
90
+ }
91
+
92
+ /** @param {Element|null} context @returns {Element} */
93
+ function scopeOf(context) {
20
94
  const scope = context?.closest?.(SCOPE_SELECTOR) ?? null;
21
95
  if (!scope || scope === document.documentElement || scope === document.body) return document.body;
22
96
  return scope;