@xh/hoist 87.1.1 → 87.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 (263) hide show
  1. package/.npmignore +39 -0
  2. package/CHANGELOG.md +92 -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/grouping/GroupingChooserModel.d.ts +3 -1
  86. package/build/types/cmp/input/HoistInputProps.d.ts +49 -2
  87. package/build/types/cmp/tab/TabContainerModel.d.ts +3 -1
  88. package/build/types/cmp/tab/TabModel.d.ts +3 -1
  89. package/build/types/cmp/treemap/TreeMapModel.d.ts +2 -0
  90. package/build/types/cmp/viewmanager/ViewManagerModel.d.ts +2 -0
  91. package/build/types/cmp/zoneGrid/ZoneGridModel.d.ts +2 -0
  92. package/build/types/core/HoistBase.d.ts +7 -0
  93. package/build/types/core/HoistProps.d.ts +26 -1
  94. package/build/types/core/model/RootRefreshContextModel.d.ts +1 -0
  95. package/build/types/core/types/Telemetry.d.ts +1 -1
  96. package/build/types/data/Store.d.ts +3 -1
  97. package/build/types/data/StoreSelectionModel.d.ts +3 -1
  98. package/build/types/data/cube/Cube.d.ts +5 -2
  99. package/build/types/data/cube/View.d.ts +2 -0
  100. package/build/types/desktop/cmp/appOption/AutoRefreshAppOption.d.ts +3 -0
  101. package/build/types/desktop/cmp/appOption/ThemeAppOption.d.ts +3 -0
  102. package/build/types/desktop/cmp/button/Button.d.ts +2 -2
  103. package/build/types/desktop/cmp/button/ButtonGroup.d.ts +2 -2
  104. package/build/types/desktop/cmp/dash/DashConfig.d.ts +2 -0
  105. package/build/types/desktop/cmp/dash/DashViewModel.d.ts +3 -1
  106. package/build/types/desktop/cmp/dash/canvas/DashCanvasModel.d.ts +1 -1
  107. package/build/types/desktop/cmp/dash/container/DashContainerModel.d.ts +1 -1
  108. package/build/types/desktop/cmp/daterange/DateRangePicker.d.ts +66 -0
  109. package/build/types/desktop/cmp/daterange/impl/CustomTab.d.ts +3 -0
  110. package/build/types/desktop/cmp/daterange/impl/DateRangePickerLocalModel.d.ts +121 -0
  111. package/build/types/desktop/cmp/daterange/impl/PeriodTab.d.ts +2 -0
  112. package/build/types/desktop/cmp/daterange/impl/PresetsTab.d.ts +3 -0
  113. package/build/types/desktop/cmp/daterange/impl/RelativeTab.d.ts +3 -0
  114. package/build/types/desktop/cmp/daterange/impl/TabUtils.d.ts +21 -0
  115. package/build/types/desktop/cmp/daterange/index.d.ts +2 -0
  116. package/build/types/desktop/cmp/dock/DockContainerModel.d.ts +3 -1
  117. package/build/types/desktop/cmp/dock/DockViewModel.d.ts +3 -1
  118. package/build/types/desktop/cmp/grouping/GroupingChooser.d.ts +4 -1
  119. package/build/types/desktop/cmp/input/IntentInput.d.ts +38 -0
  120. package/build/types/desktop/cmp/input/NumberInput.d.ts +2 -2
  121. package/build/types/desktop/cmp/input/SegmentedControl.d.ts +25 -4
  122. package/build/types/desktop/cmp/input/TextArea.d.ts +2 -2
  123. package/build/types/desktop/cmp/input/TextInput.d.ts +2 -2
  124. package/build/types/desktop/cmp/input/index.d.ts +1 -0
  125. package/build/types/desktop/cmp/leftrightchooser/LeftRightChooserModel.d.ts +3 -1
  126. package/build/types/desktop/cmp/panel/PanelModel.d.ts +3 -1
  127. package/build/types/desktop/cmp/rest/RestGridModel.d.ts +1 -1
  128. package/build/types/desktop/cmp/tab/impl/TabContainer.d.ts +1 -1
  129. package/build/types/icon/Icon.d.ts +3 -0
  130. package/build/types/inspector/impl/InspectorUtils.d.ts +3 -0
  131. package/build/types/inspector/instances/InstancesModel.d.ts +4 -0
  132. package/build/types/kit/react-day-picker/index.d.ts +3 -3
  133. package/build/types/mobile/cmp/button/Button.d.ts +2 -2
  134. package/build/types/mobile/cmp/input/NumberInput.d.ts +2 -2
  135. package/build/types/mobile/cmp/input/SegmentedControl.d.ts +18 -4
  136. package/build/types/mobile/cmp/input/TextArea.d.ts +2 -2
  137. package/build/types/mobile/cmp/input/TextInput.d.ts +2 -2
  138. package/build/types/mobile/cmp/navigator/NavigatorModel.d.ts +3 -1
  139. package/build/types/mobile/cmp/navigator/PageModel.d.ts +3 -1
  140. package/build/types/mobile/cmp/tab/impl/TabContainer.d.ts +1 -1
  141. package/build/types/svc/InspectorService.d.ts +1 -0
  142. package/build/types/utils/js/LangUtils.d.ts +24 -5
  143. package/cmp/README.md +1 -0
  144. package/cmp/ag-grid/AgGridModel.ts +5 -0
  145. package/cmp/badge/Badge.ts +5 -3
  146. package/cmp/card/Card.ts +4 -3
  147. package/cmp/chart/ChartModel.ts +11 -1
  148. package/cmp/dataview/DataViewModel.ts +7 -1
  149. package/cmp/daterange/DateRangePickerModel.ts +628 -0
  150. package/cmp/daterange/DateRangePresets.ts +274 -0
  151. package/cmp/daterange/DateRangeUtils.ts +557 -0
  152. package/cmp/daterange/README.md +434 -0
  153. package/cmp/daterange/Types.ts +203 -0
  154. package/cmp/daterange/index.ts +10 -0
  155. package/cmp/filter/FilterChooserModel.ts +7 -4
  156. package/cmp/form/FormModel.ts +6 -0
  157. package/cmp/form/README.md +1 -0
  158. package/cmp/grid/GridModel.ts +24 -4
  159. package/cmp/grid/Types.ts +3 -0
  160. package/cmp/grid/filter/GridFilterModel.ts +3 -1
  161. package/cmp/grouping/GroupingChooserModel.ts +6 -1
  162. package/cmp/input/HoistInputProps.ts +50 -2
  163. package/cmp/input/README.md +42 -0
  164. package/cmp/layout/Box.ts +3 -2
  165. package/cmp/tab/TabContainerModel.ts +9 -1
  166. package/cmp/tab/TabModel.ts +5 -0
  167. package/cmp/treemap/SplitTreeMapModel.ts +12 -2
  168. package/cmp/treemap/TreeMapModel.ts +6 -1
  169. package/cmp/viewmanager/ViewManagerModel.ts +6 -1
  170. package/cmp/zoneGrid/ZoneGridModel.ts +7 -0
  171. package/core/HoistBase.ts +11 -0
  172. package/core/HoistProps.ts +27 -0
  173. package/core/README.md +46 -0
  174. package/core/impl/InstallServices.ts +5 -1
  175. package/core/model/RootRefreshContextModel.ts +2 -0
  176. package/core/types/Telemetry.ts +1 -1
  177. package/data/README.md +3 -1
  178. package/data/Store.ts +7 -0
  179. package/data/StoreSelectionModel.ts +5 -1
  180. package/data/cube/Cube.ts +12 -3
  181. package/data/cube/View.ts +5 -1
  182. package/desktop/README.md +2 -0
  183. package/desktop/appcontainer/LoginPanel.ts +2 -0
  184. package/desktop/cmp/button/Button.scss +71 -42
  185. package/desktop/cmp/button/Button.ts +10 -1
  186. package/desktop/cmp/button/ButtonGroup.ts +4 -1
  187. package/desktop/cmp/button/grid/ColChooserButton.ts +9 -1
  188. package/desktop/cmp/button/zoneGrid/ZoneMapperButton.ts +1 -0
  189. package/desktop/cmp/dash/DashConfig.ts +3 -0
  190. package/desktop/cmp/dash/DashViewModel.ts +14 -1
  191. package/desktop/cmp/dash/canvas/DashCanvasModel.ts +3 -1
  192. package/desktop/cmp/dash/container/DashContainerModel.ts +3 -1
  193. package/desktop/cmp/daterange/DateRangePicker.scss +577 -0
  194. package/desktop/cmp/daterange/DateRangePicker.ts +357 -0
  195. package/desktop/cmp/daterange/impl/CustomTab.ts +165 -0
  196. package/desktop/cmp/daterange/impl/DateRangePickerLocalModel.ts +482 -0
  197. package/desktop/cmp/daterange/impl/PeriodTab.ts +138 -0
  198. package/desktop/cmp/daterange/impl/PresetsTab.ts +58 -0
  199. package/desktop/cmp/daterange/impl/RelativeTab.ts +108 -0
  200. package/desktop/cmp/daterange/impl/TabUtils.ts +34 -0
  201. package/desktop/cmp/daterange/index.ts +8 -0
  202. package/desktop/cmp/dock/DockContainerModel.ts +6 -1
  203. package/desktop/cmp/dock/DockViewModel.ts +6 -1
  204. package/desktop/cmp/filechooser/FileChooser.ts +4 -0
  205. package/desktop/cmp/form/FormField.ts +1 -0
  206. package/desktop/cmp/grouping/GroupingChooser.ts +8 -2
  207. package/desktop/cmp/input/Checkbox.ts +1 -0
  208. package/desktop/cmp/input/CodeInput.ts +1 -0
  209. package/desktop/cmp/input/DateInput.scss +1 -1
  210. package/desktop/cmp/input/DateInput.ts +1 -0
  211. package/desktop/cmp/input/IntentInput.scss +202 -0
  212. package/desktop/cmp/input/IntentInput.ts +213 -0
  213. package/desktop/cmp/input/NumberInput.ts +11 -2
  214. package/desktop/cmp/input/Picker.ts +1 -0
  215. package/desktop/cmp/input/RadioInput.ts +2 -1
  216. package/desktop/cmp/input/SegmentedControl.scss +45 -2
  217. package/desktop/cmp/input/SegmentedControl.ts +66 -11
  218. package/desktop/cmp/input/Select.ts +9 -7
  219. package/desktop/cmp/input/Slider.ts +2 -0
  220. package/desktop/cmp/input/SwitchInput.ts +1 -0
  221. package/desktop/cmp/input/TextArea.ts +11 -2
  222. package/desktop/cmp/input/TextInput.ts +11 -2
  223. package/desktop/cmp/input/index.ts +1 -0
  224. package/desktop/cmp/leftrightchooser/LeftRightChooserModel.ts +5 -0
  225. package/desktop/cmp/panel/Panel.ts +8 -5
  226. package/desktop/cmp/panel/PanelModel.ts +8 -0
  227. package/desktop/cmp/panel/impl/ResizeContainer.ts +2 -1
  228. package/desktop/cmp/rest/RestGridModel.ts +4 -0
  229. package/desktop/cmp/tab/impl/TabContainer.ts +2 -0
  230. package/docs/README.md +2 -0
  231. package/docs/build-and-publish.md +23 -7
  232. package/docs/doc-registry.json +8 -0
  233. package/docs/version-compatibility.md +2 -0
  234. package/icon/Icon.ts +9 -0
  235. package/icon/index.ts +24 -0
  236. package/inspector/README.md +8 -2
  237. package/inspector/impl/InspectorUtils.ts +12 -0
  238. package/inspector/instances/DiagnosticsModel.ts +3 -2
  239. package/inspector/instances/InstancesModel.ts +81 -14
  240. package/inspector/instances/InstancesPanel.ts +6 -0
  241. package/kit/react-day-picker/index.ts +3 -3
  242. package/mobile/appcontainer/LoginPanel.ts +2 -0
  243. package/mobile/cmp/button/Button.ts +16 -3
  244. package/mobile/cmp/form/FormField.ts +1 -0
  245. package/mobile/cmp/input/Checkbox.ts +1 -0
  246. package/mobile/cmp/input/DateInput.ts +1 -0
  247. package/mobile/cmp/input/Label.ts +13 -8
  248. package/mobile/cmp/input/NumberInput.ts +11 -2
  249. package/mobile/cmp/input/SearchInput.ts +1 -0
  250. package/mobile/cmp/input/SegmentedControl.scss +36 -6
  251. package/mobile/cmp/input/SegmentedControl.ts +37 -11
  252. package/mobile/cmp/input/Select.ts +2 -0
  253. package/mobile/cmp/input/SwitchInput.ts +1 -0
  254. package/mobile/cmp/input/TextArea.ts +11 -2
  255. package/mobile/cmp/input/TextInput.ts +11 -2
  256. package/mobile/cmp/navigator/NavigatorModel.ts +6 -1
  257. package/mobile/cmp/navigator/PageModel.ts +6 -1
  258. package/mobile/cmp/tab/impl/TabContainer.ts +9 -1
  259. package/package.json +19 -19
  260. package/styles/vars.scss +32 -2
  261. package/svc/InspectorService.ts +2 -0
  262. package/svc/TraceService.ts +5 -2
  263. package/utils/js/LangUtils.ts +37 -5
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import {hspacer} from '@xh/hoist/cmp/layout';
8
8
  import {
9
+ DomAttrsProps,
9
10
  LayoutProps,
10
11
  StyleProps,
11
12
  hoistCmp,
@@ -23,7 +24,7 @@ import {ReactNode, ReactElement, MouseEvent} from 'react';
23
24
  import './Button.scss';
24
25
 
25
26
  export interface ButtonProps<M extends HoistModel = HoistModel>
26
- extends HoistProps<M>, TestSupportProps, LayoutProps, StyleProps {
27
+ extends HoistProps<M>, TestSupportProps, DomAttrsProps, LayoutProps, StyleProps {
27
28
  active?: boolean;
28
29
  disabled?: boolean;
29
30
  icon?: ReactElement;
@@ -51,8 +52,19 @@ export const [Button, button] = hoistCmp.withFactory<ButtonProps>({
51
52
  classes = [],
52
53
  items = [];
53
54
 
54
- const {active, className, disabled, icon, intent, onClick, style, testId, text, ...rest} =
55
- nonLayoutProps;
55
+ const {
56
+ active,
57
+ className,
58
+ disabled,
59
+ domAttrs,
60
+ icon,
61
+ intent,
62
+ onClick,
63
+ style,
64
+ testId,
65
+ text,
66
+ ...rest
67
+ } = nonLayoutProps;
56
68
 
57
69
  let {outlined, minimal} = nonLayoutProps;
58
70
  if (disabled) {
@@ -91,6 +103,7 @@ export const [Button, button] = hoistCmp.withFactory<ButtonProps>({
91
103
  ...layoutProps
92
104
  },
93
105
  [TEST_ID]: testId,
106
+ ...domAttrs,
94
107
  ...rest
95
108
  });
96
109
  }
@@ -160,6 +160,7 @@ export const [FormField, formField] = hoistCmp.withFactory<FormFieldProps>({
160
160
  return box({
161
161
  ref,
162
162
  testId,
163
+ domAttrs: props.domAttrs,
163
164
  className: classNames(className, classes),
164
165
  ...layoutProps,
165
166
  items: [
@@ -46,6 +46,7 @@ const cmp = hoistCmp.factory<CheckboxInputModel>(({model, className, ...props},
46
46
 
47
47
  style: props.style,
48
48
  [TEST_ID]: props.testId,
49
+ ...props.domAttrs,
49
50
 
50
51
  onBlur: model.onBlur,
51
52
  onFocus: model.onFocus,
@@ -163,6 +163,7 @@ const cmp = hoistCmp.factory<DateInputModel>(({model, className, ...props}, ref)
163
163
  style: {textAlign},
164
164
  tabIndex: props.tabIndex,
165
165
  [TEST_ID]: props.testId,
166
+ ...props.domAttrs,
166
167
  item: model.formattedRenderValue,
167
168
  onClick: () => model.openPicker()
168
169
  }),
@@ -8,6 +8,7 @@ import {HoistInputModel, HoistInputProps, useHoistInputModel} from '@xh/hoist/cm
8
8
  import {div} from '@xh/hoist/cmp/layout';
9
9
  import {hoistCmp, HoistProps, StyleProps} from '@xh/hoist/core';
10
10
  import '@xh/hoist/mobile/register';
11
+ import {TEST_ID} from '@xh/hoist/utils/js';
11
12
  import './Label.scss';
12
13
 
13
14
  export interface LabelProps extends HoistProps, HoistInputProps, StyleProps {}
@@ -30,11 +31,15 @@ class LabelInputModel extends HoistInputModel {
30
31
  //-----------------------
31
32
  // Implementation
32
33
  //-----------------------
33
- const cmp = hoistCmp.factory(({model, className, style, width, children}, ref) => {
34
- return div({
35
- className,
36
- style: {...style, whiteSpace: 'nowrap', width},
37
- items: children,
38
- ref
39
- });
40
- });
34
+ const cmp = hoistCmp.factory(
35
+ ({model, className, style, width, children, testId, domAttrs}, ref) => {
36
+ return div({
37
+ className,
38
+ [TEST_ID]: testId,
39
+ ...domAttrs,
40
+ style: {...style, whiteSpace: 'nowrap', width},
41
+ items: children,
42
+ ref
43
+ });
44
+ }
45
+ );
@@ -4,7 +4,13 @@
4
4
  *
5
5
  * Copyright © 2026 Extremely Heavy Industries Inc.
6
6
  */
7
- import {HoistInputModel, HoistInputProps, useHoistInputModel} from '@xh/hoist/cmp/input';
7
+ import {
8
+ getPasswordManagerAttrs,
9
+ HoistInputModel,
10
+ HoistInputProps,
11
+ PasswordManagerSupportProps,
12
+ useHoistInputModel
13
+ } from '@xh/hoist/cmp/input';
8
14
  import {hoistCmp, HoistProps, LayoutProps, StyleProps} from '@xh/hoist/core';
9
15
  import {fmtNumber, NumericPrecision, Precision, ZeroPad} from '@xh/hoist/format';
10
16
  import {input} from '@xh/hoist/kit/onsen';
@@ -16,7 +22,8 @@ import type {Property} from 'csstype';
16
22
  import {debounce, isNaN, isNil, isNumber, round} from 'lodash';
17
23
  import './NumberInput.scss';
18
24
 
19
- export interface NumberInputProps extends HoistProps, HoistInputProps, StyleProps, LayoutProps {
25
+ export interface NumberInputProps
26
+ extends HoistProps, HoistInputProps, PasswordManagerSupportProps, StyleProps, LayoutProps {
20
27
  value?: number;
21
28
 
22
29
  /** True to commit on every change/keystroke, default false. */
@@ -257,6 +264,8 @@ const cmp = hoistCmp.factory<NumberInputModel>(
257
264
  },
258
265
  spellCheck: false,
259
266
  [TEST_ID]: props.testId,
267
+ ...getPasswordManagerAttrs(props.enablePasswordManagers),
268
+ ...props.domAttrs,
260
269
 
261
270
  onInput: model.onValueChange,
262
271
  onKeyDown: model.onKeyDown,
@@ -94,6 +94,7 @@ const cmp = hoistCmp.factory<SearchInputModel>(({model, className, ...props}, re
94
94
  textAlign: withDefault(props.textAlign, 'left')
95
95
  },
96
96
  [TEST_ID]: props.testId,
97
+ ...props.domAttrs,
97
98
 
98
99
  onInput: model.onChange,
99
100
  onKeyDown: model.onKeyDown,
@@ -86,21 +86,51 @@
86
86
  flex-basis: 0;
87
87
  }
88
88
 
89
- // Outlined mode - border around the tray with no inner background fill.
89
+ // Outlined mode (default) - a border around the tray. Independent of the tray fill, which is
90
+ // governed by --no-tray-bg below.
90
91
  &.xh-segmented-control--outlined {
91
- background-color: transparent;
92
92
  border: 1px solid var(--xh-border-color);
93
+ }
94
+
95
+ // Tray background suppressed - a lighter presentation, with no fill behind the options.
96
+ &.xh-segmented-control--no-tray-bg {
97
+ background-color: transparent;
93
98
 
94
- // Reserve border space on every option so selecting one does not shift the row. The
95
- // transparent tray offers no recessed backdrop to set a filled tile against, so indicate
96
- // selection with a ring instead - currentColor keeps it in step with the option's
97
- // text / intent color.
99
+ // Reserve border space on every option so selecting one does not shift the row. With no
100
+ // tray there is no recessed backdrop to set a filled tile against, so indicate selection
101
+ // with a ring instead - currentColor keeps it in step with the option's text / intent color.
98
102
  .xh-button.xh-segmented-control-option {
99
103
  border: 1px solid transparent;
100
104
  }
101
105
 
102
106
  .xh-button.xh-segmented-control-option--selected {
103
107
  border-color: currentColor;
108
+ background-color: transparent;
109
+ }
110
+ }
111
+
112
+ // Option dividers - internal structure for a tray whose options are otherwise undifferentiated,
113
+ // most notably in the empty state where no selected option breaks up the row. Drawn in the gap
114
+ // to the left of each option after the first, and suppressed on either side of the selected
115
+ // option so they never crowd it.
116
+ &.xh-segmented-control--dividers {
117
+ .xh-button.xh-segmented-control-option {
118
+ position: relative;
119
+ }
120
+
121
+ .xh-segmented-control-option + .xh-segmented-control-option::before {
122
+ content: '';
123
+ position: absolute;
124
+ left: calc(var(--xh-segmented-control-pad-px) / -2);
125
+ top: 20%;
126
+ bottom: 20%;
127
+ width: 1px;
128
+ background-color: var(--xh-border-color);
129
+ }
130
+
131
+ .xh-segmented-control-option--selected::before,
132
+ .xh-segmented-control-option--selected + .xh-segmented-control-option::before {
133
+ display: none;
104
134
  }
105
135
  }
106
136
 
@@ -17,7 +17,6 @@ import {hoistCmp, HoistProps, Intent} from '@xh/hoist/core';
17
17
  import {button} from '@xh/hoist/mobile/cmp/button';
18
18
  import '@xh/hoist/mobile/register';
19
19
  import {computed, makeObservable} from '@xh/hoist/mobx';
20
- import {TEST_ID} from '@xh/hoist/utils/js';
21
20
  import {getLayoutProps, getNonLayoutProps} from '@xh/hoist/utils/react';
22
21
  import classNames from 'classnames';
23
22
  import {filter, isObject} from 'lodash';
@@ -34,8 +33,8 @@ export interface SegmentedControlProps extends HoistProps, HoistInputProps {
34
33
  equalSegmentWidths?: boolean;
35
34
 
36
35
  /**
37
- * True (default) to stretch the control to fill available width,
38
- * distributing space equally among options.
36
+ * True (default) to stretch the control to fill available width. Set false to size the control
37
+ * to its options. See `equalSegmentWidths` for how the filled width is divided up.
39
38
  */
40
39
  fill?: boolean;
41
40
 
@@ -54,10 +53,26 @@ export interface SegmentedControlProps extends HoistProps, HoistInputProps {
54
53
  options: Array<SegmentedControlOption | SegmentedControlNullOption | OptionPrimitive>;
55
54
 
56
55
  /**
57
- * True to render with an outlined style - a border around the control tray
58
- * with no inner background fill. Border color follows the current intent.
56
+ * True (default) to render a border around the control tray. Border color follows the current
57
+ * intent. Note this controls the tray border only - it does not remove the tray background,
58
+ * which is governed independently by `showTrayBackground`.
59
59
  */
60
60
  outlined?: boolean;
61
+
62
+ /**
63
+ * True (default) to fill the control tray with a background, setting it off from the surface
64
+ * behind it. Set false to omit that fill for a lighter presentation. With no tray to set a
65
+ * filled tile against, the selected option is indicated with a ring instead.
66
+ */
67
+ showTrayBackground?: boolean;
68
+
69
+ /**
70
+ * True to render dividers between options, adding internal structure to the tray. Dividers
71
+ * are suppressed on either side of the selected option so they do not compete with it.
72
+ * Defaults to 'auto', showing dividers only while no option is selected - the state in which
73
+ * the tray offers no other cue that its options are separate and selectable.
74
+ */
75
+ showOptionDividers?: boolean | 'auto';
61
76
  }
62
77
 
63
78
  /**
@@ -114,11 +129,14 @@ class SegmentedControlModel extends HoistInputModel {
114
129
  });
115
130
  }
116
131
 
117
- /** Map the current render value to the string key used to identify the selected option. */
132
+ /**
133
+ * Key of the option matching the current render value, or null if no option matches -
134
+ * including whenever the bound value is itself null.
135
+ */
118
136
  @computed
119
- get selectedKey(): string {
137
+ get selectedKey(): string | null {
120
138
  const {renderValue, normalizedOptions} = this;
121
- return normalizedOptions.find(o => o.value === renderValue)?._key;
139
+ return normalizedOptions.find(o => o.value === renderValue)?._key ?? null;
122
140
  }
123
141
 
124
142
  get enabledButtons(): HTMLButtonElement[] {
@@ -160,13 +178,18 @@ const cmp = hoistCmp.factory<SegmentedControlModel>(({model, className, ...props
160
178
  equalSegmentWidths = true,
161
179
  fill = true,
162
180
  intent,
163
- outlined,
181
+ outlined = true,
182
+ showTrayBackground = true,
183
+ showOptionDividers = 'auto',
164
184
  testId,
185
+ domAttrs,
165
186
  ...rest
166
187
  } = getNonLayoutProps(props);
167
188
 
168
189
  const {selectedKey} = model,
169
- defaultIntent = intent && intent !== 'none' ? intent : null;
190
+ defaultIntent = intent && intent !== 'none' ? intent : null,
191
+ // 'auto' dividers track the empty state - shown only while nothing is selected.
192
+ dividers = showOptionDividers === 'auto' ? selectedKey == null : showOptionDividers;
170
193
 
171
194
  const buttons = model.normalizedOptions.map(opt => {
172
195
  const optIntent = opt.intent ?? defaultIntent,
@@ -200,6 +223,8 @@ const cmp = hoistCmp.factory<SegmentedControlModel>(({model, className, ...props
200
223
  className,
201
224
  defaultIntent && `xh-segmented-control--${defaultIntent}`,
202
225
  outlined && 'xh-segmented-control--outlined',
226
+ !showTrayBackground && 'xh-segmented-control--no-tray-bg',
227
+ dividers && 'xh-segmented-control--dividers',
203
228
  fill && 'xh-segmented-control--fill',
204
229
  fill && equalSegmentWidths && 'xh-segmented-control--equal-widths'
205
230
  ),
@@ -207,7 +232,8 @@ const cmp = hoistCmp.factory<SegmentedControlModel>(({model, className, ...props
207
232
  onFocus: model.onFocus,
208
233
  onBlur: model.onBlur,
209
234
  ...getLayoutProps(props),
210
- [TEST_ID]: testId,
235
+ testId,
236
+ domAttrs,
211
237
  items: buttons,
212
238
  ...rest
213
239
  });
@@ -696,6 +696,7 @@ const cmp = hoistCmp.factory<SelectInputModel>(({model, className, ...props}, re
696
696
  item: factory(rsProps),
697
697
  className,
698
698
  testId: props.testId,
699
+ domAttrs: props.domAttrs,
699
700
  ref
700
701
  })
701
702
  }),
@@ -708,6 +709,7 @@ const cmp = hoistCmp.factory<SelectInputModel>(({model, className, ...props}, re
708
709
  ...layoutProps,
709
710
  width: withDefault(width, null),
710
711
  testId: props.testId,
712
+ domAttrs: props.domAttrs,
711
713
  ref
712
714
  });
713
715
  }
@@ -47,6 +47,7 @@ const cmp = hoistCmp.factory<SwitchInputModel>(({model, className, ...props}, re
47
47
  className,
48
48
  style: props.style,
49
49
  [TEST_ID]: props.testId,
50
+ ...props.domAttrs,
50
51
 
51
52
  onBlur: model.onBlur,
52
53
  onFocus: model.onFocus,
@@ -4,7 +4,13 @@
4
4
  *
5
5
  * Copyright © 2026 Extremely Heavy Industries Inc.
6
6
  */
7
- import {HoistInputModel, HoistInputProps, useHoistInputModel} from '@xh/hoist/cmp/input';
7
+ import {
8
+ getPasswordManagerAttrs,
9
+ HoistInputModel,
10
+ HoistInputProps,
11
+ PasswordManagerSupportProps,
12
+ useHoistInputModel
13
+ } from '@xh/hoist/cmp/input';
8
14
  import {div, textarea as textareaTag} from '@xh/hoist/cmp/layout';
9
15
  import {hoistCmp, HoistProps, LayoutProps, StyleProps} from '@xh/hoist/core';
10
16
  import '@xh/hoist/mobile/register';
@@ -12,7 +18,8 @@ import {TEST_ID, withDefault} from '@xh/hoist/utils/js';
12
18
  import {getLayoutProps} from '@xh/hoist/utils/react';
13
19
  import './TextArea.scss';
14
20
 
15
- export interface TextAreaProps extends HoistProps, HoistInputProps, StyleProps, LayoutProps {
21
+ export interface TextAreaProps
22
+ extends HoistProps, HoistInputProps, PasswordManagerSupportProps, StyleProps, LayoutProps {
16
23
  value?: string;
17
24
 
18
25
  /** True to commit on every change/keystroke, default false. */
@@ -85,6 +92,8 @@ const cmp = hoistCmp.factory<TextAreaInputModel>(({model, className, ...props},
85
92
  spellCheck: withDefault(props.spellCheck, false),
86
93
  tabIndex: props.tabIndex,
87
94
  [TEST_ID]: props.testId,
95
+ ...getPasswordManagerAttrs(props.enablePasswordManagers),
96
+ ...props.domAttrs,
88
97
 
89
98
  onChange: model.onChange,
90
99
  onKeyDown: model.onKeyDown,
@@ -4,7 +4,13 @@
4
4
  *
5
5
  * Copyright © 2026 Extremely Heavy Industries Inc.
6
6
  */
7
- import {HoistInputModel, HoistInputProps, useHoistInputModel} from '@xh/hoist/cmp/input';
7
+ import {
8
+ getPasswordManagerAttrs,
9
+ HoistInputModel,
10
+ HoistInputProps,
11
+ PasswordManagerSupportProps,
12
+ useHoistInputModel
13
+ } from '@xh/hoist/cmp/input';
8
14
  import {box, hbox} from '@xh/hoist/cmp/layout';
9
15
  import {hoistCmp, HoistProps, LayoutProps, StyleProps} from '@xh/hoist/core';
10
16
  import {Icon} from '@xh/hoist/icon';
@@ -18,7 +24,8 @@ import {isEmpty} from 'lodash';
18
24
  import {ReactElement} from 'react';
19
25
  import './TextInput.scss';
20
26
 
21
- export interface TextInputProps extends HoistProps, HoistInputProps, StyleProps, LayoutProps {
27
+ export interface TextInputProps
28
+ extends HoistProps, HoistInputProps, PasswordManagerSupportProps, StyleProps, LayoutProps {
22
29
  value?: string;
23
30
 
24
31
  /**
@@ -145,6 +152,8 @@ const cmp = hoistCmp.factory<TextInputModel>(({model, className, ...props}, ref)
145
152
  className: 'xh-text-input__input',
146
153
  style: {textAlign: withDefault(props.textAlign, 'left')},
147
154
  [TEST_ID]: props.testId,
155
+ ...getPasswordManagerAttrs(props.enablePasswordManagers),
156
+ ...props.domAttrs,
148
157
 
149
158
  onInput: model.onChange,
150
159
  onKeyDown: model.onKeyDown,
@@ -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
  /**
@@ -101,10 +104,12 @@ export class NavigatorModel extends HoistModel {
101
104
  pullDownToRefresh = true,
102
105
  transitionMs = 500,
103
106
  renderMode = 'lazy',
104
- refreshMode = 'onShowLazy'
107
+ refreshMode = 'onShowLazy',
108
+ xhName = null
105
109
  }: NavigatorConfig) {
106
110
  super();
107
111
  makeObservable(this);
112
+ this.xhName = xhName;
108
113
 
109
114
  ensureNotEmpty(pages, 'NavigatorModel needs at least one page.');
110
115
  ensureUniqueBy(pages, 'id', 'Multiple NavigatorModel PageModels have the same id.');
@@ -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.2.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;