@xh/hoist 87.1.1 → 87.3.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 (270) hide show
  1. package/.npmignore +39 -0
  2. package/CHANGELOG.md +108 -20
  3. package/admin/AdminUtils.ts +64 -0
  4. package/admin/App.scss +88 -0
  5. package/admin/columns/UserData.ts +30 -3
  6. package/admin/detail/RestDetailModel.ts +64 -0
  7. package/admin/detail/RestDetailPanel.ts +106 -0
  8. package/admin/tabs/activity/tracking/ActivityTrackingModel.ts +27 -94
  9. package/admin/tabs/activity/tracking/ActivityTrackingPanel.ts +23 -60
  10. package/admin/tabs/activity/tracking/detail/ActivityDetailView.ts +1 -2
  11. package/admin/tabs/general/alertBanner/AlertBannerPanel.ts +2 -13
  12. package/admin/tabs/general/config/ConfigDetailPanel.ts +72 -0
  13. package/admin/tabs/general/config/ConfigPanel.ts +41 -53
  14. package/admin/tabs/general/config/ConfigPanelModel.ts +3 -0
  15. package/admin/tabs/general/config/ConfigValue.scss +14 -0
  16. package/admin/tabs/general/config/ConfigValue.ts +104 -65
  17. package/admin/tabs/userData/jsonblob/JsonBlobDetailPanel.ts +93 -0
  18. package/admin/tabs/userData/jsonblob/JsonBlobModel.ts +4 -0
  19. package/admin/tabs/userData/jsonblob/JsonBlobPanel.ts +2 -0
  20. package/admin/tabs/userData/prefs/UserPreferenceDetailPanel.ts +62 -0
  21. package/admin/tabs/userData/prefs/UserPreferenceModel.ts +10 -3
  22. package/admin/tabs/userData/prefs/UserPreferencePanel.ts +3 -1
  23. package/admin/tabs/userData/roles/details/RoleDetails.scss +2 -19
  24. package/admin/tabs/userData/roles/details/RoleDetails.ts +13 -13
  25. package/appcontainer/AboutDialogModel.ts +1 -0
  26. package/appcontainer/AppContainerModel.ts +3 -0
  27. package/appcontainer/AppStateModel.ts +1 -0
  28. package/appcontainer/BannerSourceModel.ts +1 -0
  29. package/appcontainer/ChangelogDialogModel.ts +1 -0
  30. package/appcontainer/ColChooserOptionsModel.ts +1 -0
  31. package/appcontainer/ExceptionDialogModel.ts +1 -0
  32. package/appcontainer/FeedbackDialogModel.ts +1 -0
  33. package/appcontainer/ImpersonationBarModel.ts +1 -0
  34. package/appcontainer/MessageSourceModel.ts +1 -0
  35. package/appcontainer/OptionsDialogModel.ts +1 -0
  36. package/appcontainer/PageStateModel.ts +1 -0
  37. package/appcontainer/RouterModel.ts +2 -0
  38. package/appcontainer/SizingModeModel.ts +1 -0
  39. package/appcontainer/ThemeModel.ts +1 -0
  40. package/appcontainer/ToastSourceModel.ts +1 -0
  41. package/appcontainer/UserAgentModel.ts +1 -0
  42. package/appcontainer/ViewportSizeModel.ts +1 -0
  43. package/build/types/admin/AdminUtils.d.ts +29 -0
  44. package/build/types/admin/columns/UserData.d.ts +3 -0
  45. package/build/types/admin/detail/RestDetailModel.d.ts +20 -0
  46. package/build/types/admin/detail/RestDetailPanel.d.ts +34 -0
  47. package/build/types/admin/tabs/activity/tracking/ActivityTrackingModel.d.ts +5 -17
  48. package/build/types/admin/tabs/general/config/ConfigDetailPanel.d.ts +7 -0
  49. package/build/types/admin/tabs/general/config/ConfigValue.d.ts +10 -4
  50. package/build/types/admin/tabs/userData/jsonblob/JsonBlobDetailPanel.d.ts +3 -0
  51. package/build/types/admin/tabs/userData/prefs/UserPreferenceDetailPanel.d.ts +3 -0
  52. package/build/types/admin/tabs/userData/prefs/UserPreferenceModel.d.ts +3 -0
  53. package/build/types/appcontainer/AboutDialogModel.d.ts +1 -0
  54. package/build/types/appcontainer/AppContainerModel.d.ts +1 -0
  55. package/build/types/appcontainer/AppStateModel.d.ts +1 -0
  56. package/build/types/appcontainer/BannerSourceModel.d.ts +1 -0
  57. package/build/types/appcontainer/ChangelogDialogModel.d.ts +1 -0
  58. package/build/types/appcontainer/ColChooserOptionsModel.d.ts +1 -0
  59. package/build/types/appcontainer/ExceptionDialogModel.d.ts +1 -0
  60. package/build/types/appcontainer/FeedbackDialogModel.d.ts +1 -0
  61. package/build/types/appcontainer/ImpersonationBarModel.d.ts +1 -0
  62. package/build/types/appcontainer/MessageSourceModel.d.ts +1 -0
  63. package/build/types/appcontainer/OptionsDialogModel.d.ts +1 -0
  64. package/build/types/appcontainer/PageStateModel.d.ts +1 -0
  65. package/build/types/appcontainer/RouterModel.d.ts +1 -0
  66. package/build/types/appcontainer/SizingModeModel.d.ts +1 -0
  67. package/build/types/appcontainer/ThemeModel.d.ts +1 -0
  68. package/build/types/appcontainer/ToastSourceModel.d.ts +1 -0
  69. package/build/types/appcontainer/UserAgentModel.d.ts +1 -0
  70. package/build/types/appcontainer/ViewportSizeModel.d.ts +1 -0
  71. package/build/types/cmp/ag-grid/AgGridModel.d.ts +3 -1
  72. package/build/types/cmp/card/Card.d.ts +2 -2
  73. package/build/types/cmp/chart/ChartModel.d.ts +2 -0
  74. package/build/types/cmp/dataview/DataViewModel.d.ts +2 -0
  75. package/build/types/cmp/daterange/DateRangePickerModel.d.ts +266 -0
  76. package/build/types/cmp/daterange/DateRangePresets.d.ts +26 -0
  77. package/build/types/cmp/daterange/DateRangeUtils.d.ts +96 -0
  78. package/build/types/cmp/daterange/Types.d.ts +152 -0
  79. package/build/types/cmp/daterange/index.d.ts +4 -0
  80. package/build/types/cmp/filter/FilterChooserModel.d.ts +3 -1
  81. package/build/types/cmp/form/FormModel.d.ts +3 -1
  82. package/build/types/cmp/grid/GridModel.d.ts +2 -0
  83. package/build/types/cmp/grid/Types.d.ts +2 -0
  84. package/build/types/cmp/grid/filter/GridFilterModel.d.ts +1 -1
  85. package/build/types/cmp/grid/impl/ColumnWidthCalculator.d.ts +1 -1
  86. package/build/types/cmp/grouping/GroupingChooserModel.d.ts +3 -1
  87. package/build/types/cmp/input/HoistInputProps.d.ts +49 -2
  88. package/build/types/cmp/tab/TabContainerModel.d.ts +3 -1
  89. package/build/types/cmp/tab/TabModel.d.ts +3 -1
  90. package/build/types/cmp/treemap/TreeMapModel.d.ts +2 -0
  91. package/build/types/cmp/viewmanager/ViewManagerModel.d.ts +2 -0
  92. package/build/types/cmp/zoneGrid/ZoneGridModel.d.ts +2 -0
  93. package/build/types/core/HoistBase.d.ts +7 -0
  94. package/build/types/core/HoistProps.d.ts +26 -1
  95. package/build/types/core/model/RootRefreshContextModel.d.ts +1 -0
  96. package/build/types/core/types/Telemetry.d.ts +1 -1
  97. package/build/types/data/Store.d.ts +3 -1
  98. package/build/types/data/StoreSelectionModel.d.ts +3 -1
  99. package/build/types/data/cube/Cube.d.ts +5 -2
  100. package/build/types/data/cube/View.d.ts +2 -0
  101. package/build/types/desktop/cmp/appOption/AutoRefreshAppOption.d.ts +3 -0
  102. package/build/types/desktop/cmp/appOption/ThemeAppOption.d.ts +3 -0
  103. package/build/types/desktop/cmp/button/Button.d.ts +2 -2
  104. package/build/types/desktop/cmp/button/ButtonGroup.d.ts +2 -2
  105. package/build/types/desktop/cmp/dash/DashConfig.d.ts +2 -0
  106. package/build/types/desktop/cmp/dash/DashViewModel.d.ts +3 -1
  107. package/build/types/desktop/cmp/dash/canvas/DashCanvasModel.d.ts +1 -1
  108. package/build/types/desktop/cmp/dash/container/DashContainerModel.d.ts +1 -1
  109. package/build/types/desktop/cmp/daterange/DateRangePicker.d.ts +66 -0
  110. package/build/types/desktop/cmp/daterange/impl/CustomTab.d.ts +3 -0
  111. package/build/types/desktop/cmp/daterange/impl/DateRangePickerLocalModel.d.ts +121 -0
  112. package/build/types/desktop/cmp/daterange/impl/PeriodTab.d.ts +2 -0
  113. package/build/types/desktop/cmp/daterange/impl/PresetsTab.d.ts +3 -0
  114. package/build/types/desktop/cmp/daterange/impl/RelativeTab.d.ts +3 -0
  115. package/build/types/desktop/cmp/daterange/impl/TabUtils.d.ts +21 -0
  116. package/build/types/desktop/cmp/daterange/index.d.ts +2 -0
  117. package/build/types/desktop/cmp/dock/DockContainerModel.d.ts +3 -1
  118. package/build/types/desktop/cmp/dock/DockViewModel.d.ts +3 -1
  119. package/build/types/desktop/cmp/grouping/GroupingChooser.d.ts +4 -1
  120. package/build/types/desktop/cmp/input/IntentInput.d.ts +38 -0
  121. package/build/types/desktop/cmp/input/NumberInput.d.ts +2 -2
  122. package/build/types/desktop/cmp/input/SegmentedControl.d.ts +25 -4
  123. package/build/types/desktop/cmp/input/TextArea.d.ts +2 -2
  124. package/build/types/desktop/cmp/input/TextInput.d.ts +2 -2
  125. package/build/types/desktop/cmp/input/index.d.ts +1 -0
  126. package/build/types/desktop/cmp/leftrightchooser/LeftRightChooserModel.d.ts +3 -1
  127. package/build/types/desktop/cmp/panel/PanelModel.d.ts +3 -1
  128. package/build/types/desktop/cmp/rest/RestGridModel.d.ts +1 -1
  129. package/build/types/desktop/cmp/tab/impl/TabContainer.d.ts +1 -1
  130. package/build/types/desktop/hooks/UseHotkeys.d.ts +4 -3
  131. package/build/types/icon/Icon.d.ts +3 -0
  132. package/build/types/inspector/impl/InspectorUtils.d.ts +3 -0
  133. package/build/types/inspector/instances/InstancesModel.d.ts +4 -0
  134. package/build/types/kit/react-day-picker/index.d.ts +3 -3
  135. package/build/types/mobile/cmp/button/Button.d.ts +2 -2
  136. package/build/types/mobile/cmp/input/NumberInput.d.ts +2 -2
  137. package/build/types/mobile/cmp/input/SegmentedControl.d.ts +18 -4
  138. package/build/types/mobile/cmp/input/TextArea.d.ts +2 -2
  139. package/build/types/mobile/cmp/input/TextInput.d.ts +2 -2
  140. package/build/types/mobile/cmp/navigator/NavigatorModel.d.ts +8 -2
  141. package/build/types/mobile/cmp/navigator/PageModel.d.ts +3 -1
  142. package/build/types/mobile/cmp/tab/impl/TabContainer.d.ts +1 -1
  143. package/build/types/svc/InspectorService.d.ts +1 -0
  144. package/build/types/utils/js/LangUtils.d.ts +24 -5
  145. package/cmp/README.md +1 -0
  146. package/cmp/ag-grid/AgGridModel.ts +5 -0
  147. package/cmp/badge/Badge.ts +5 -3
  148. package/cmp/card/Card.ts +4 -3
  149. package/cmp/chart/ChartModel.ts +11 -1
  150. package/cmp/clock/Clock.ts +1 -1
  151. package/cmp/dataview/DataViewModel.ts +7 -1
  152. package/cmp/daterange/DateRangePickerModel.ts +628 -0
  153. package/cmp/daterange/DateRangePresets.ts +274 -0
  154. package/cmp/daterange/DateRangeUtils.ts +557 -0
  155. package/cmp/daterange/README.md +434 -0
  156. package/cmp/daterange/Types.ts +203 -0
  157. package/cmp/daterange/index.ts +10 -0
  158. package/cmp/filter/FilterChooserModel.ts +7 -4
  159. package/cmp/form/FormModel.ts +6 -0
  160. package/cmp/form/README.md +1 -0
  161. package/cmp/grid/GridModel.ts +24 -4
  162. package/cmp/grid/Types.ts +3 -0
  163. package/cmp/grid/filter/GridFilterModel.ts +3 -1
  164. package/cmp/grid/impl/ColumnWidthCalculator.ts +5 -10
  165. package/cmp/grouping/GroupingChooserModel.ts +6 -1
  166. package/cmp/input/HoistInputProps.ts +50 -2
  167. package/cmp/input/README.md +42 -0
  168. package/cmp/layout/Box.ts +3 -2
  169. package/cmp/tab/TabContainerModel.ts +9 -1
  170. package/cmp/tab/TabModel.ts +5 -0
  171. package/cmp/treemap/SplitTreeMapModel.ts +12 -2
  172. package/cmp/treemap/TreeMapModel.ts +6 -1
  173. package/cmp/viewmanager/ViewManagerModel.ts +6 -1
  174. package/cmp/zoneGrid/ZoneGridModel.ts +7 -0
  175. package/core/HoistBase.ts +11 -0
  176. package/core/HoistProps.ts +27 -0
  177. package/core/README.md +46 -0
  178. package/core/impl/InstallServices.ts +5 -1
  179. package/core/model/RootRefreshContextModel.ts +2 -0
  180. package/core/types/Telemetry.ts +1 -1
  181. package/data/README.md +3 -1
  182. package/data/Store.ts +7 -0
  183. package/data/StoreSelectionModel.ts +5 -1
  184. package/data/cube/Cube.ts +12 -3
  185. package/data/cube/View.ts +5 -1
  186. package/desktop/README.md +2 -0
  187. package/desktop/appcontainer/LoginPanel.ts +2 -0
  188. package/desktop/cmp/button/Button.scss +71 -42
  189. package/desktop/cmp/button/Button.ts +10 -1
  190. package/desktop/cmp/button/ButtonGroup.ts +4 -1
  191. package/desktop/cmp/button/grid/ColChooserButton.ts +9 -1
  192. package/desktop/cmp/button/zoneGrid/ZoneMapperButton.ts +1 -0
  193. package/desktop/cmp/dash/DashConfig.ts +3 -0
  194. package/desktop/cmp/dash/DashViewModel.ts +14 -1
  195. package/desktop/cmp/dash/canvas/DashCanvasModel.ts +3 -1
  196. package/desktop/cmp/dash/container/DashContainerModel.ts +3 -1
  197. package/desktop/cmp/daterange/DateRangePicker.scss +577 -0
  198. package/desktop/cmp/daterange/DateRangePicker.ts +357 -0
  199. package/desktop/cmp/daterange/impl/CustomTab.ts +165 -0
  200. package/desktop/cmp/daterange/impl/DateRangePickerLocalModel.ts +482 -0
  201. package/desktop/cmp/daterange/impl/PeriodTab.ts +138 -0
  202. package/desktop/cmp/daterange/impl/PresetsTab.ts +58 -0
  203. package/desktop/cmp/daterange/impl/RelativeTab.ts +108 -0
  204. package/desktop/cmp/daterange/impl/TabUtils.ts +34 -0
  205. package/desktop/cmp/daterange/index.ts +8 -0
  206. package/desktop/cmp/dock/DockContainerModel.ts +6 -1
  207. package/desktop/cmp/dock/DockViewModel.ts +6 -1
  208. package/desktop/cmp/filechooser/FileChooser.ts +4 -0
  209. package/desktop/cmp/form/FormField.ts +1 -0
  210. package/desktop/cmp/grid/editors/DateEditor.ts +11 -2
  211. package/desktop/cmp/grouping/GroupingChooser.ts +8 -2
  212. package/desktop/cmp/input/Checkbox.ts +1 -0
  213. package/desktop/cmp/input/CodeInput.ts +1 -0
  214. package/desktop/cmp/input/DateInput.scss +1 -1
  215. package/desktop/cmp/input/DateInput.ts +1 -0
  216. package/desktop/cmp/input/IntentInput.scss +202 -0
  217. package/desktop/cmp/input/IntentInput.ts +213 -0
  218. package/desktop/cmp/input/NumberInput.ts +11 -2
  219. package/desktop/cmp/input/Picker.ts +1 -0
  220. package/desktop/cmp/input/RadioInput.ts +2 -1
  221. package/desktop/cmp/input/SegmentedControl.scss +57 -5
  222. package/desktop/cmp/input/SegmentedControl.ts +66 -11
  223. package/desktop/cmp/input/Select.ts +9 -7
  224. package/desktop/cmp/input/Slider.ts +2 -0
  225. package/desktop/cmp/input/SwitchInput.ts +1 -0
  226. package/desktop/cmp/input/TextArea.ts +11 -2
  227. package/desktop/cmp/input/TextInput.ts +11 -2
  228. package/desktop/cmp/input/index.ts +1 -0
  229. package/desktop/cmp/leftrightchooser/LeftRightChooserModel.ts +5 -0
  230. package/desktop/cmp/panel/Panel.ts +8 -5
  231. package/desktop/cmp/panel/PanelModel.ts +8 -0
  232. package/desktop/cmp/panel/impl/ResizeContainer.ts +2 -1
  233. package/desktop/cmp/rest/RestGridModel.ts +4 -0
  234. package/desktop/cmp/tab/impl/TabContainer.ts +2 -0
  235. package/desktop/cmp/toolbar/Toolbar.scss +20 -6
  236. package/desktop/hooks/UseHotkeys.ts +41 -12
  237. package/docs/README.md +2 -0
  238. package/docs/build-and-publish.md +23 -7
  239. package/docs/doc-registry.json +8 -0
  240. package/docs/version-compatibility.md +2 -0
  241. package/icon/Icon.ts +9 -0
  242. package/icon/index.ts +24 -0
  243. package/inspector/README.md +8 -2
  244. package/inspector/impl/InspectorUtils.ts +12 -0
  245. package/inspector/instances/DiagnosticsModel.ts +3 -2
  246. package/inspector/instances/InstancesModel.ts +81 -14
  247. package/inspector/instances/InstancesPanel.ts +6 -0
  248. package/kit/react-day-picker/index.ts +3 -3
  249. package/mobile/appcontainer/LoginPanel.ts +2 -0
  250. package/mobile/cmp/button/Button.ts +16 -3
  251. package/mobile/cmp/form/FormField.ts +1 -0
  252. package/mobile/cmp/input/Checkbox.ts +1 -0
  253. package/mobile/cmp/input/DateInput.ts +1 -0
  254. package/mobile/cmp/input/Label.ts +13 -8
  255. package/mobile/cmp/input/NumberInput.ts +11 -2
  256. package/mobile/cmp/input/SearchInput.ts +1 -0
  257. package/mobile/cmp/input/SegmentedControl.scss +36 -6
  258. package/mobile/cmp/input/SegmentedControl.ts +37 -11
  259. package/mobile/cmp/input/Select.ts +2 -0
  260. package/mobile/cmp/input/SwitchInput.ts +1 -0
  261. package/mobile/cmp/input/TextArea.ts +11 -2
  262. package/mobile/cmp/input/TextInput.ts +11 -2
  263. package/mobile/cmp/navigator/NavigatorModel.ts +20 -8
  264. package/mobile/cmp/navigator/PageModel.ts +6 -1
  265. package/mobile/cmp/tab/impl/TabContainer.ts +9 -1
  266. package/package.json +19 -19
  267. package/styles/vars.scss +32 -2
  268. package/svc/InspectorService.ts +2 -0
  269. package/svc/TraceService.ts +5 -2
  270. package/utils/js/LangUtils.ts +37 -5
@@ -52,6 +52,9 @@ export interface NavigatorConfig {
52
52
  * See enum for description of supported modes.
53
53
  */
54
54
  refreshMode?: RefreshMode;
55
+
56
+ /** See {@link HoistBase.xhName}. */
57
+ xhName?: string;
55
58
  }
56
59
 
57
60
  /**
@@ -64,6 +67,12 @@ export class NavigatorModel extends HoistModel {
64
67
  @bindable.ref
65
68
  stack: PageModel[] = [];
66
69
 
70
+ /**
71
+ * Index of the active page, synced from Swiper as each transition completes. Observable so
72
+ * `allowSlideNext`/`allowSlidePrev` stay current - Swiper silently skips locked directions.
73
+ */
74
+ @bindable activePageIdx: number = 0;
75
+
67
76
  pages: PageConfig[] = [];
68
77
  track: boolean;
69
78
  pullDownToRefresh: boolean;
@@ -83,10 +92,6 @@ export class NavigatorModel extends HoistModel {
83
92
  return this.stack[this.activePageIdx];
84
93
  }
85
94
 
86
- get activePageIdx(): number {
87
- return this._swiper?.activeIndex ?? 0;
88
- }
89
-
90
95
  get allowSlideNext(): boolean {
91
96
  return this.activePageIdx < this.stack.length - 1;
92
97
  }
@@ -101,10 +106,12 @@ export class NavigatorModel extends HoistModel {
101
106
  pullDownToRefresh = true,
102
107
  transitionMs = 500,
103
108
  renderMode = 'lazy',
104
- refreshMode = 'onShowLazy'
109
+ refreshMode = 'onShowLazy',
110
+ xhName = null
105
111
  }: NavigatorConfig) {
106
112
  super();
107
113
  makeObservable(this);
114
+ this.xhName = xhName;
108
115
 
109
116
  ensureNotEmpty(pages, 'NavigatorModel needs at least one page.');
110
117
  ensureUniqueBy(pages, 'id', 'Multiple NavigatorModel PageModels have the same id.');
@@ -213,8 +220,9 @@ export class NavigatorModel extends HoistModel {
213
220
  /** @internal */
214
221
  @action
215
222
  onPageChange = () => {
216
- // 1) Clear any pages after the active page. These can be left over from a back swipe.
217
- this.stack = this.stack.slice(0, this._swiper.activeIndex + 1);
223
+ // 1) Sync the active index, then clear any pages after it - left over from a back swipe.
224
+ this.activePageIdx = this._swiper.activeIndex;
225
+ this.stack = this.stack.slice(0, this.activePageIdx + 1);
218
226
 
219
227
  // 2) Sync route to match the current page stack
220
228
  const newRouteName = this.stack.map(it => it.id).join('.'),
@@ -298,7 +306,8 @@ export class NavigatorModel extends HoistModel {
298
306
  if (init) {
299
307
  this.stack = stack;
300
308
  this._swiper.update();
301
- this._swiper.activeIndex = this.stack.length - 1;
309
+ this.activePageIdx = this.stack.length - 1;
310
+ this._swiper.activeIndex = this.activePageIdx;
302
311
  return;
303
312
  }
304
313
 
@@ -310,6 +319,9 @@ export class NavigatorModel extends HoistModel {
310
319
  forwardOnePage = isEqual(newKeyStack.slice(0, -1), currKeyStack);
311
320
 
312
321
  if (backOnePage) {
322
+ // Set directly - a stale `false` here makes slidePrev() a silent no-op.
323
+ this._swiper.allowSlidePrev = true;
324
+
313
325
  // Don't update the stack yet. Instead, wait until after the animation has
314
326
  // completed in onPageChange().
315
327
  this._swiper.slidePrev(transitionMs);
@@ -62,6 +62,9 @@ export interface PageConfig {
62
62
  * no need to specify manually.
63
63
  */
64
64
  navigatorModel?: NavigatorModel;
65
+
66
+ /** See {@link HoistBase.xhName}. */
67
+ xhName?: string;
65
68
  }
66
69
 
67
70
  /**
@@ -116,7 +119,8 @@ export class PageModel extends HoistModel {
116
119
  renderMode,
117
120
  refreshMode,
118
121
  disableDirectLink,
119
- disableAppRefreshButton
122
+ disableAppRefreshButton,
123
+ xhName = null
120
124
  }: PageConfig) {
121
125
  super();
122
126
  makeObservable(this);
@@ -127,6 +131,7 @@ export class PageModel extends HoistModel {
127
131
 
128
132
  this.id = id;
129
133
  this.navigatorModel = navigatorModel;
134
+ this.xhName = xhName ?? navigatorModel?.childXhName(id);
130
135
  this.content = content;
131
136
  this.props = withDefault(props, {});
132
137
  this.disableDirectLink = withDefault(disableDirectLink, false);
@@ -20,7 +20,13 @@ import {TabContainerProps, TabModel, TabSwitcherProps} from '@xh/hoist/cmp/tab';
20
20
  *
21
21
  * @internal
22
22
  */
23
- export function tabContainerImpl({model, className, testId, ...props}: TabContainerProps) {
23
+ export function tabContainerImpl({
24
+ model,
25
+ className,
26
+ testId,
27
+ domAttrs,
28
+ ...props
29
+ }: TabContainerProps) {
24
30
  const switcherProps = getSwitcherProps(props),
25
31
  {activeTab} = model,
26
32
  tabs = model.tabs.filter(it => !it.excludeFromSwitcher),
@@ -34,6 +40,7 @@ export function tabContainerImpl({model, className, testId, ...props}: TabContai
34
40
  if (isEmpty(tabs)) {
35
41
  return page({
36
42
  [TEST_ID]: testId,
43
+ ...domAttrs,
37
44
  className: 'xh-tab-page',
38
45
  item: placeholder(model.emptyText)
39
46
  });
@@ -41,6 +48,7 @@ export function tabContainerImpl({model, className, testId, ...props}: TabContai
41
48
 
42
49
  return onsenTabbar({
43
50
  [TEST_ID]: testId,
51
+ ...domAttrs,
44
52
  className: classNames(className, `xh-tab-container--${switcherProps?.orientation}`),
45
53
  position: switcherProps?.orientation,
46
54
  activeIndex: activeTab ? tabs.indexOf(activeTab) : 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xh/hoist",
3
- "version": "87.1.1",
3
+ "version": "87.3.0",
4
4
  "description": "Hoist add-on for building and deploying React Applications.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -48,8 +48,9 @@
48
48
  "@codemirror/language": "^6.12.4",
49
49
  "@codemirror/language-data": "^6.5.2",
50
50
  "@codemirror/lint": "^6.9.7",
51
- "@codemirror/state": "^6.7.1",
52
- "@codemirror/view": "^6.43.9",
51
+ "@codemirror/state": "^6.7.4",
52
+ "@codemirror/view": "^6.43.11",
53
+ "@daypicker/react": "^10.0.1",
53
54
  "@floating-ui/react": "^0.27.20",
54
55
  "@fortawesome/fontawesome-pro": "^7.3.1",
55
56
  "@fortawesome/fontawesome-svg-core": "^7.3.1",
@@ -64,9 +65,9 @@
64
65
  "classnames": "^2.5.1",
65
66
  "commander": "^15.0.0",
66
67
  "core-js": "^3.50.0",
67
- "dompurify": "^3.4.14",
68
+ "dompurify": "^3.4.15",
68
69
  "fast-deep-equal": "^3.1.3",
69
- "filesize": "~11.0.22",
70
+ "filesize": "~11.0.23",
70
71
  "http-status-codes": "^2.3.0",
71
72
  "inter-ui": "~4.1.1",
72
73
  "jwt-decode": "^4.0.0",
@@ -77,14 +78,13 @@
77
78
  "moment": "~2.30.1",
78
79
  "numbro": "~2.5.0",
79
80
  "onsenui": "~2.12.9",
80
- "qs": "^6.15.3",
81
- "react-day-picker": "^9.14.0",
81
+ "qs": "^6.16.0",
82
82
  "react-dropzone": "~20.1.1",
83
83
  "react-grid-layout": "~2.2.4",
84
84
  "react-markdown": "~10.1.0",
85
85
  "react-onsenui": "~1.13.3",
86
86
  "react-select": "~5.10.2",
87
- "react-window": "~2.3.0",
87
+ "react-window": "~2.3.1",
88
88
  "react-windowed-select": "~5.2.0",
89
89
  "remark-breaks": "~4.0.0",
90
90
  "remark-gfm": "~4.0.1",
@@ -96,10 +96,10 @@
96
96
  "store2": "^2.14.4",
97
97
  "swiper": "~12.2.0",
98
98
  "ts-morph": "^27.0.2",
99
- "tsx": "^4.23.12",
99
+ "tsx": "^4.23.13",
100
100
  "ua-parser-js": "^2.0.10",
101
101
  "unified": "~11.0.5",
102
- "zod": "^4.4.3"
102
+ "zod": "^4.5.4"
103
103
  },
104
104
  "peerDependencies": {
105
105
  "react": "^19.2.0",
@@ -108,25 +108,25 @@
108
108
  "devDependencies": {
109
109
  "@types/lodash": "^4.17.25",
110
110
  "@types/react": "^19.2.18",
111
- "@types/react-dom": "^19.2.5",
112
- "@xh/eslint-config": "^8.0.0",
113
- "@xh/hoist-dev-utils": "^14.0.1",
111
+ "@types/react-dom": "^19.2.7",
112
+ "@xh/eslint-config": "^8.0.1",
113
+ "@xh/hoist-dev-utils": "^15.0.1",
114
114
  "ag-grid-community": "^35.3.1",
115
115
  "ag-grid-react": "^35.3.1",
116
116
  "csstype": "^3.2.3",
117
- "eslint": "^10.9.1",
117
+ "eslint": "^10.10.0",
118
118
  "eslint-config-prettier": "^10.1.8",
119
119
  "eslint-plugin-tsdoc": "^0.5.2",
120
- "globals": "^17.11.0",
120
+ "globals": "^17.12.0",
121
121
  "husky": "^9.1.7",
122
- "lint-staged": "^17.3.0",
123
- "postcss": "^8.5.26",
122
+ "lint-staged": "^17.5.0",
123
+ "postcss": "^8.5.28",
124
124
  "prettier": "^3.9.6",
125
125
  "react": "^19.2.8",
126
126
  "react-dom": "^19.2.8",
127
- "stylelint": "^17.14.1",
127
+ "stylelint": "^17.15.0",
128
128
  "stylelint-config-recommended-scss": "^17.0.1",
129
- "type-fest": "^5.8.0",
129
+ "type-fest": "^5.9.0",
130
130
  "typescript": "^5.9.3"
131
131
  },
132
132
  "scripts": {
package/styles/vars.scss CHANGED
@@ -684,7 +684,7 @@ body {
684
684
  //------------------------
685
685
  // Segmented Control
686
686
  //------------------------
687
- --xh-segmented-control-bg: var(--segmented-control-bg, #{color.mix(mc('blue-grey', '100'), mc('blue-grey', '50'))});
687
+ --xh-segmented-control-bg: var(--segmented-control-bg, var(--xh-bg-alt));
688
688
  --xh-segmented-control-selected-bg: var(--segmented-control-selected-bg, var(--xh-bg));
689
689
  --xh-segmented-control-text-color: var(--segmented-control-text-color, color-mix(in srgb, var(--xh-text-color) 75%, var(--xh-segmented-control-bg)));
690
690
  --xh-segmented-control-selected-text-color: var(--segmented-control-selected-text-color, var(--xh-text-color));
@@ -694,10 +694,40 @@ body {
694
694
  --xh-segmented-control-pad-px: calc(var(--xh-segmented-control-pad) * 1px);
695
695
 
696
696
  &.xh-dark {
697
- --xh-segmented-control-bg: var(--segmented-control-bg, #{color.mix(mc('blue-grey', '800'), mc('blue-grey', '900'))});
697
+ // Tray bg follows --xh-bg-alt in both themes - no dark-mode override needed.
698
698
  --xh-segmented-control-selected-bg: var(--segmented-control-selected-bg, #{mc('blue-grey', '700')});
699
699
  }
700
700
 
701
+ //------------------------
702
+ // Intent Input
703
+ //------------------------
704
+ --xh-intent-input-swatch-size-px: var(--intent-input-swatch-size-px, 20px);
705
+ --xh-intent-input-compact-swatch-size-px: var(--intent-input-compact-swatch-size-px, 16px);
706
+ --xh-intent-input-gap-px: var(--intent-input-gap-px, var(--xh-pad-half-px));
707
+ --xh-intent-input-border-radius-px: var(--intent-input-border-radius-px, var(--xh-border-radius-px));
708
+
709
+ //------------------------
710
+ // Date Range Picker
711
+ //------------------------
712
+ --xh-date-range-picker-popover-width: var(--date-range-picker-popover-width, 640px);
713
+ --xh-date-range-picker-popover-single-width: var(--date-range-picker-popover-single-width, 300px);
714
+ --xh-date-range-picker-popover-min-height: var(--date-range-picker-popover-min-height, 322px);
715
+ --xh-date-range-picker-accent: var(--date-range-picker-accent, var(--xh-intent-primary));
716
+ --xh-date-range-picker-accent-text-color: var(--date-range-picker-accent-text-color, var(--xh-white));
717
+ --xh-date-range-picker-selected-bg: var(--date-range-picker-selected-bg, var(--xh-bg-highlight));
718
+ --xh-date-range-picker-hover-bg: var(--date-range-picker-hover-bg, var(--xh-grid-bg-hover));
719
+ --xh-date-range-picker-date-font-family: var(--date-range-picker-date-font-family, var(--xh-font-family-mono));
720
+ --xh-date-range-picker-date-font-size: var(--date-range-picker-date-font-size, 12px);
721
+ --xh-date-range-picker-row-height: var(--date-range-picker-row-height, 32px);
722
+ --xh-date-range-picker-day-size: var(--date-range-picker-day-size, 26px);
723
+ --xh-date-range-picker-footer-bg: var(--date-range-picker-footer-bg, var(--xh-tbar-bg));
724
+ // Tab rail stays on the popover background in light theme, where a distinct fill would set
725
+ // muted tab labels on grey and lose contrast. In dark theme a distinct fill reads well.
726
+ --xh-date-range-picker-rail-bg: var(--date-range-picker-rail-bg, transparent);
727
+
728
+ &.xh-dark {
729
+ --xh-date-range-picker-rail-bg: var(--date-range-picker-rail-bg, var(--xh-tbar-bg));
730
+ }
701
731
 
702
732
  //------------------------
703
733
  // Mask + LoadingIndicator
@@ -201,6 +201,7 @@ export class InspectorService extends HoistService {
201
201
  return {
202
202
  id: xhId,
203
203
  className: inst.constructor.name,
204
+ xhName: inst.xhName,
204
205
  created: inst._created,
205
206
  isHoistService: inst.isHoistService,
206
207
  isHoistModel: inst.isHoistModel,
@@ -239,6 +240,7 @@ export class InspectorService extends HoistService {
239
240
 
240
241
  interface InspectorInstanceData {
241
242
  className: string;
243
+ xhName: string;
242
244
  created: number;
243
245
  isHoistModel: boolean;
244
246
  isHoistService: boolean;
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import {HoistService, PlainObject, XH, Span, FullSpanConfig} from '@xh/hoist/core';
8
8
  import {SECONDS} from '@xh/hoist/utils/datetime';
9
- import {debounced, parseNameSource} from '@xh/hoist/utils/js';
9
+ import {debounced, parseTypeName} from '@xh/hoist/utils/js';
10
10
  import {every, forEach, groupBy, isEmpty, isString, omitBy, takeRight} from 'lodash';
11
11
  import {terminationSafePostJson} from './impl/Fetch';
12
12
 
@@ -119,12 +119,15 @@ export class TraceService extends HoistService {
119
119
 
120
120
  // Apply default tags - safe to call even before identity is resolved (getUsername is null).
121
121
  // Remove nulls they are used in this API to just prevent defaults
122
+ const {caller} = ret,
123
+ xhName = caller?.['xhName'];
122
124
  ret.tags = {
123
125
  'xh.clientApp': XH.clientAppCode,
124
126
  'xh.loadId': XH.loadId,
125
127
  'xh.tabId': XH.tabId,
126
128
  'xh.source': ret.name.startsWith('xh.') ? 'hoist' : 'app',
127
- ...(ret.caller ? {'code.namespace': parseNameSource(ret.caller)} : {}),
129
+ ...(caller ? {'code.namespace': parseTypeName(caller)} : {}),
130
+ ...(xhName ? {'xh.name': xhName} : {}),
128
131
  ...this.identityTags(),
129
132
  ...ret.tags
130
133
  };
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * Copyright © 2026 Extremely Heavy Industries Inc.
6
6
  */
7
- import type {PlainObject, Thunkable} from '@xh/hoist/core';
7
+ import type {HoistBase, PlainObject, Thunkable} from '@xh/hoist/core';
8
8
  import {Exception} from '@xh/hoist/exception';
9
9
  import {
10
10
  flatMap,
@@ -282,13 +282,45 @@ export function mergeDeep(target: PlainObject, ...sources: PlainObject[]): Plain
282
282
  }
283
283
 
284
284
  /**
285
- * A string, or an object from which a name can be derived - via `displayName` (e.g. React
286
- * components) or `constructor.name` (e.g. class instances). Used for logging and tracing.
285
+ * A string, or an object from which a name can be derived - via `xhName` (HoistBase instances),
286
+ * `displayName` (e.g. React components), or `constructor.name` (class instances). Used for
287
+ * logging and tracing.
287
288
  */
288
- export type NameSource = string | {displayName: string} | {constructor: {name: string}};
289
+ export type NameSource = string | HoistBase | {displayName: string} | {constructor: {name: string}};
289
290
 
290
- /** Resolve a {@link NameSource} to a string, or null if unresolvable. */
291
+ /**
292
+ * Resolve a {@link NameSource} to a string, or null if unresolvable.
293
+ *
294
+ * A HoistBase instance is labelled per {@link formatInstanceLabel}. Other sources resolve via
295
+ * `xhName` or {@link parseTypeName}.
296
+ */
291
297
  export function parseNameSource(source: NameSource): string {
298
+ if (!source) return null;
299
+ if (isString(source)) return source;
300
+ const typeName = parseTypeName(source);
301
+ if (!source['isHoistBase']) return source['xhName'] || typeName;
302
+ return formatInstanceLabel(typeName, source['xhName'], source['xhId']);
303
+ }
304
+
305
+ /**
306
+ * Label for a HoistBase instance - `ClassName [xhName]`, or `ClassName [id]` (short `xhId`) when
307
+ * unnamed. An `xhName` matching the class name (e.g. `fetchService`) marks a singleton and is
308
+ * omitted.
309
+ */
310
+ export function formatInstanceLabel(className: string, xhName: string, xhId: string): string {
311
+ if (!xhName) return `${className} [${xhId.replace(/^xh-id-/, '')}]`;
312
+ return xhName.toLowerCase() === className.toLowerCase()
313
+ ? className
314
+ : `${className} [${xhName}]`;
315
+ }
316
+
317
+ /**
318
+ * Resolve a {@link NameSource} to its type-level name - `displayName` or `constructor.name` -
319
+ * ignoring any instance-level `xhName`. Returns null if unresolvable.
320
+ *
321
+ * @internal - use {@link parseNameSource}.
322
+ */
323
+ export function parseTypeName(source: NameSource): string {
292
324
  if (!source) return null;
293
325
  if (isString(source)) return source;
294
326
  if (source['displayName']) return source['displayName'];