@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
@@ -92,7 +92,15 @@ export abstract class DashViewModel<T extends DashViewSpec = DashViewSpec> exten
92
92
  return this.viewSpec.refreshMode ?? this.containerModel.refreshMode;
93
93
  }
94
94
 
95
- constructor({id, viewSpec, icon, title, viewState = null, containerModel}: DashViewConfig<T>) {
95
+ constructor({
96
+ id,
97
+ viewSpec,
98
+ icon,
99
+ title,
100
+ viewState = null,
101
+ containerModel,
102
+ xhName = null
103
+ }: DashViewConfig<T>) {
96
104
  super();
97
105
  makeObservable(this);
98
106
  throwIf(!id, 'DashViewModel requires an id');
@@ -104,8 +112,10 @@ export abstract class DashViewModel<T extends DashViewSpec = DashViewSpec> exten
104
112
  this.title = title ?? viewSpec.title;
105
113
  this.viewState = viewState;
106
114
  this.containerModel = containerModel;
115
+ this.xhName = xhName ?? containerModel?.childXhName(id);
107
116
 
108
117
  this.refreshContextModel = new ManagedRefreshContextModel(this);
118
+ this.refreshContextModel.xhName = this.childXhName('refreshContextModel');
109
119
  }
110
120
 
111
121
  /**
@@ -154,4 +164,7 @@ export interface DashViewConfig<T extends DashViewSpec = DashViewSpec> {
154
164
  title?: string;
155
165
  viewState?: DashViewState;
156
166
  containerModel?: any;
167
+
168
+ /** See {@link HoistBase.xhName}. */
169
+ xhName?: string;
157
170
  }
@@ -229,10 +229,12 @@ export class DashCanvasModel
229
229
  showAddViewButtonWhenEmpty = true,
230
230
  allowsDrop = false,
231
231
  onDropDone,
232
- onDropDragOver
232
+ onDropDragOver,
233
+ xhName = null
233
234
  }: DashCanvasConfig) {
234
235
  super();
235
236
  makeObservable(this);
237
+ this.xhName = xhName;
236
238
  viewSpecs = viewSpecs.filter(it => !isOmitted(it));
237
239
  ensureUniqueBy(viewSpecs, 'id');
238
240
  this.viewSpecs = viewSpecs.map(cfg => {
@@ -207,10 +207,12 @@ export class DashContainerModel
207
207
  persistWith = null,
208
208
  emptyText = 'No views have been added to the container.',
209
209
  addViewButtonText = 'Add View',
210
- extraMenuItems
210
+ extraMenuItems,
211
+ xhName = null
211
212
  }: DashContainerConfig) {
212
213
  super();
213
214
  makeObservable(this);
215
+ this.xhName = xhName;
214
216
  viewSpecs = viewSpecs.filter(it => !isOmitted(it));
215
217
  ensureUniqueBy(viewSpecs, 'id');
216
218
  this.viewSpecs = viewSpecs.map(cfg => {
@@ -0,0 +1,577 @@
1
+ /*
2
+ * This file belongs to Hoist, an application development toolkit
3
+ * developed by Extremely Heavy Industries (www.xh.io | info@xh.io)
4
+ *
5
+ * Copyright © 2026 Extremely Heavy Industries Inc.
6
+ */
7
+
8
+ // DateRangePicker - trigger + popover styling. Colors and key sizes come from the
9
+ // `--xh-date-range-picker-*` vars declared in styles/vars.scss, so both themes work without any
10
+ // theme-specific overrides here and apps can re-key the picker via the unprefixed hooks.
11
+
12
+ // Fixed type scale for the picker's secondary text - tuned to the popover's layout, rather than
13
+ // derived from the app font size.
14
+ $drp-font-size-micro: 10px;
15
+ $drp-font-size-secondary: 11px;
16
+ $drp-icon-size: 12px;
17
+ $drp-transition-dur: 120ms;
18
+
19
+ // Uppercase header for a tab section or an input label.
20
+ @mixin drp-micro-label {
21
+ font-size: $drp-font-size-secondary;
22
+ font-weight: 600;
23
+ text-transform: uppercase;
24
+ letter-spacing: 0.06em;
25
+ color: var(--xh-text-color-muted);
26
+ }
27
+
28
+ // Muted annotation text - helper copy, footnotes, secondary counts.
29
+ @mixin drp-secondary-text {
30
+ font-size: $drp-font-size-secondary;
31
+ color: var(--xh-text-color-muted);
32
+ }
33
+
34
+ // As above, for wrapped explanatory sentences - looser leading at this size.
35
+ @mixin drp-secondary-prose {
36
+ @include drp-secondary-text;
37
+
38
+ line-height: 1.45;
39
+ }
40
+
41
+ // The picker's date font, for the resolved dates shown throughout.
42
+ @mixin drp-date {
43
+ font-family: var(--xh-date-range-picker-date-font-family);
44
+ font-size: var(--xh-date-range-picker-date-font-size);
45
+ }
46
+
47
+ // A resolved range shown beside a label - receding.
48
+ @mixin drp-date-secondary {
49
+ @include drp-date;
50
+
51
+ color: var(--xh-text-color-muted);
52
+ }
53
+
54
+ // The primary resolved value on a tab - foregrounded.
55
+ @mixin drp-date-emphasis {
56
+ @include drp-date;
57
+
58
+ font-size: calc(var(--xh-date-range-picker-date-font-size) + 2px);
59
+ color: var(--xh-text-color-headings);
60
+ }
61
+
62
+ @mixin drp-footer-shell {
63
+ padding: 7px 10px;
64
+ background: var(--xh-date-range-picker-footer-bg);
65
+ border-top: 1px solid var(--xh-border-color);
66
+ border-radius: 0 0 var(--xh-border-radius-px) var(--xh-border-radius-px);
67
+ }
68
+
69
+ // Scoped under .xh-app to out-rank Hoist base button rules of the same class count.
70
+ .xh-app {
71
+ .xh-date-range-picker {
72
+ // Outer box is sized via layoutSupport - the trigger stretches to fill, beside any step buttons.
73
+ gap: 2px;
74
+
75
+ .bp6-popover-target {
76
+ flex: 1;
77
+ min-width: 0;
78
+ display: block;
79
+ }
80
+
81
+ &__step-btn.xh-button.bp6-button {
82
+ flex: none;
83
+ min-width: 24px;
84
+ padding-left: 4px;
85
+ padding-right: 4px;
86
+ }
87
+
88
+ &__trigger.xh-button.bp6-button {
89
+ width: 100%;
90
+
91
+ > .bp6-button-text {
92
+ display: flex;
93
+ align-items: center;
94
+ gap: 7px;
95
+ width: 100%;
96
+ min-width: 0;
97
+ white-space: nowrap;
98
+ }
99
+
100
+ > .xh-icon {
101
+ font-size: $drp-icon-size;
102
+ opacity: 0.85;
103
+ }
104
+
105
+ .xh-date-range-picker__trigger-label {
106
+ font-size: var(--xh-font-size-px);
107
+ font-weight: 500;
108
+ }
109
+
110
+ .xh-date-range-picker__trigger-divider {
111
+ opacity: 0.35;
112
+ }
113
+
114
+ .xh-date-range-picker__trigger-range {
115
+ flex: 1;
116
+ text-align: left;
117
+ overflow: hidden;
118
+ text-overflow: ellipsis;
119
+ @include drp-date;
120
+
121
+ letter-spacing: -0.2px;
122
+ }
123
+
124
+ // Input styling for the trigger, matching GroupingChooser and Picker.
125
+ &.xh-date-range-picker__trigger--as-input {
126
+ background-color: var(--xh-input-bg) !important;
127
+ border: none;
128
+ box-shadow: var(--xh-form-field-box-shadow);
129
+ padding-left: var(--xh-pad-px) !important;
130
+ padding-right: var(--xh-pad-px) !important;
131
+
132
+ > .xh-icon {
133
+ color: var(--xh-text-color-muted);
134
+ }
135
+
136
+ // Preserve input-style box-shadow and add subtle surface highlight on hover/active -
137
+ // Blueprint's minimal button rules set `box-shadow: none` on these states, hiding the
138
+ // input outline in dark mode.
139
+ &:hover {
140
+ background-color: color-mix(in srgb, var(--xh-input-bg) 94%, gray) !important;
141
+ box-shadow: var(--xh-form-field-box-shadow) !important;
142
+ }
143
+
144
+ &:active,
145
+ &.xh-button--active,
146
+ &.bp6-active {
147
+ background-color: color-mix(in srgb, var(--xh-input-bg) 88%, gray) !important;
148
+ box-shadow: var(--xh-form-field-box-shadow) !important;
149
+ }
150
+ }
151
+ }
152
+
153
+ // Compact variant (narrow hosts, or `showRange: false`): the trigger carries the period label
154
+ // alone. The resolved range remains available via the trigger's title.
155
+ &--compact .xh-date-range-picker__trigger-label {
156
+ flex: 1;
157
+ text-align: left;
158
+ overflow: hidden;
159
+ text-overflow: ellipsis;
160
+ // Keep a truncated label's ellipsis off the trigger's edge.
161
+ padding-right: var(--xh-pad-half-px);
162
+ }
163
+ }
164
+
165
+ .xh-date-range-picker-popover {
166
+ // Selection accent - the primary intent by default, re-keyed by the component's `intent`
167
+ // prop via the modifier classes below.
168
+ &--intent-success {
169
+ --xh-date-range-picker-accent: var(--xh-intent-success);
170
+ }
171
+
172
+ &--intent-warning {
173
+ --xh-date-range-picker-accent: var(--xh-intent-warning);
174
+ }
175
+
176
+ &--intent-danger {
177
+ --xh-date-range-picker-accent: var(--xh-intent-danger);
178
+ }
179
+
180
+ .bp6-popover-content {
181
+ padding: 0;
182
+ background: var(--xh-popup-bg);
183
+ border-radius: var(--xh-border-radius-px);
184
+ }
185
+
186
+ &.bp6-popover {
187
+ border: 1px solid var(--xh-popup-border-color);
188
+ border-radius: var(--xh-border-radius-px);
189
+ }
190
+
191
+ &__content {
192
+ width: var(--xh-date-range-picker-popover-width);
193
+ font-size: var(--xh-font-size-px);
194
+ color: var(--xh-text-color);
195
+ }
196
+
197
+ &__body {
198
+ min-height: var(--xh-date-range-picker-popover-min-height);
199
+ align-items: stretch;
200
+
201
+ .xh-tab-switcher--left {
202
+ --xh-tab-switcher-vertical-item-hover-bg: var(--xh-date-range-picker-hover-bg);
203
+
204
+ background: var(--xh-date-range-picker-rail-bg);
205
+ }
206
+ }
207
+
208
+ // Single-tab variant: no rail to navigate, so the popover shrinks to the tab's width.
209
+ // Written as explicit descendants - `&--single &__content` would re-expand the .xh-app
210
+ // wrapper mid-selector and never match.
211
+ &--single {
212
+ .xh-date-range-picker-popover__content {
213
+ width: var(--xh-date-range-picker-popover-single-width);
214
+ }
215
+
216
+ .xh-date-range-picker-popover__body {
217
+ min-height: 0;
218
+ }
219
+ }
220
+
221
+ //------------------
222
+ // Tab shell
223
+ //------------------
224
+ &__tab {
225
+ flex: 1;
226
+ padding: var(--xh-pad-px);
227
+ min-width: 0;
228
+ }
229
+
230
+ &__section-hdr {
231
+ @include drp-micro-label;
232
+
233
+ padding: 2px 6px 6px;
234
+ }
235
+
236
+ //------------------
237
+ // Presets tab
238
+ //------------------
239
+ &__preset-row {
240
+ display: flex;
241
+ align-items: center;
242
+ gap: 8px;
243
+ height: var(--xh-date-range-picker-row-height);
244
+ min-height: var(--xh-date-range-picker-row-height);
245
+ padding: 0 6px;
246
+ border-radius: var(--xh-border-radius-px);
247
+ cursor: pointer;
248
+ transition:
249
+ background-color $drp-transition-dur,
250
+ color $drp-transition-dur;
251
+
252
+ &:hover {
253
+ background: var(--xh-date-range-picker-hover-bg);
254
+ }
255
+
256
+ &--selected {
257
+ background: var(--xh-date-range-picker-selected-bg);
258
+ color: var(--xh-text-color-headings);
259
+
260
+ &:hover {
261
+ background: var(--xh-date-range-picker-selected-bg);
262
+ }
263
+
264
+ .xh-date-range-picker-popover__row-range {
265
+ color: var(--xh-text-color);
266
+ }
267
+ }
268
+ }
269
+
270
+ &__row-check {
271
+ font-size: $drp-font-size-micro;
272
+ width: 12px;
273
+ color: var(--xh-date-range-picker-accent);
274
+
275
+ &--hidden {
276
+ visibility: hidden;
277
+ }
278
+ }
279
+
280
+ &__row-name {
281
+ flex: 1;
282
+ }
283
+
284
+ &__row-range {
285
+ @include drp-date-secondary;
286
+ }
287
+
288
+ //------------------
289
+ // Relative tab
290
+ //------------------
291
+ &__rel-row {
292
+ align-items: center;
293
+ gap: 8px;
294
+ padding: 0 6px;
295
+ margin-bottom: var(--xh-pad-px);
296
+ }
297
+
298
+ &__rel-prefix {
299
+ color: var(--xh-text-color-muted);
300
+ }
301
+
302
+ &__snap-box {
303
+ margin: 0 6px var(--xh-pad-px);
304
+ padding: 8px;
305
+ border: 1px solid var(--xh-border-color);
306
+ border-radius: var(--xh-border-radius-px);
307
+
308
+ // `fill: false` sizes the options but leaves the tray stretched - hug the content.
309
+ .xh-segmented-control {
310
+ width: fit-content;
311
+ }
312
+ }
313
+
314
+ &__snap-help {
315
+ @include drp-secondary-prose;
316
+
317
+ margin-top: 6px;
318
+ }
319
+
320
+ &__preview {
321
+ margin: 0 6px;
322
+ padding: 8px 10px;
323
+ background: var(--xh-bg-alt);
324
+ border: 1px solid var(--xh-border-color);
325
+ border-radius: var(--xh-border-radius-px);
326
+ }
327
+
328
+ &__preview-label {
329
+ @include drp-micro-label;
330
+
331
+ margin-bottom: 4px;
332
+ }
333
+
334
+ &__preview-range {
335
+ @include drp-date-emphasis;
336
+ }
337
+
338
+ &__preview-days {
339
+ @include drp-secondary-text;
340
+
341
+ margin-top: 2px;
342
+ }
343
+
344
+ //------------------
345
+ // Months & Years tab
346
+ //------------------
347
+ &__month-hdr {
348
+ align-items: center;
349
+
350
+ .xh-date-range-picker-popover__section-hdr {
351
+ padding-bottom: 2px;
352
+ }
353
+ }
354
+
355
+ &__nav-btn.xh-button.bp6-button {
356
+ width: 24px;
357
+ min-width: 24px;
358
+ height: 24px;
359
+ min-height: 24px;
360
+ padding: 0;
361
+ color: var(--xh-text-color-muted);
362
+
363
+ &.xh-button--disabled {
364
+ opacity: 0.3;
365
+ }
366
+ }
367
+
368
+ &__year-val {
369
+ @include drp-date-emphasis;
370
+
371
+ font-weight: 500;
372
+ width: 52px;
373
+ text-align: center;
374
+ }
375
+
376
+ // A row per quarter - its three months across the left, its button in a narrow trailing column.
377
+ &__month-grid {
378
+ display: grid;
379
+ grid-template-columns: repeat(3, 1fr) minmax(44px, auto);
380
+ gap: 6px;
381
+ padding: 4px 6px 0;
382
+ }
383
+
384
+ // Grid cells stretch; the buttons bring their own chrome, hover, active and disabled states.
385
+ &__month-btn.xh-button,
386
+ &__quarter-btn.xh-button {
387
+ width: 100%;
388
+ }
389
+
390
+ // The quarter reads as the row's label - quieter than the months it contains, until selected.
391
+ &__quarter-btn.xh-button:not(.xh-button--active) {
392
+ color: var(--xh-text-color-muted);
393
+ }
394
+
395
+ &__year-row.xh-button {
396
+ margin: 14px 6px 0;
397
+
398
+ // Blueprint wraps `items` in a non-flex text span - lay them out, as the trigger does.
399
+ > .bp6-button-text {
400
+ display: flex;
401
+ align-items: center;
402
+ gap: 8px;
403
+ width: 100%;
404
+ }
405
+
406
+ svg {
407
+ font-size: $drp-icon-size;
408
+ }
409
+
410
+ // The range span sets its own muted color; when selected, let the filled button's
411
+ // text color win instead.
412
+ &.xh-button--active .xh-date-range-picker-popover__row-range {
413
+ color: inherit;
414
+ }
415
+ }
416
+
417
+ &__year-row-label {
418
+ flex: 1;
419
+ min-width: 0;
420
+ overflow: hidden;
421
+ text-overflow: ellipsis;
422
+ white-space: nowrap;
423
+ }
424
+
425
+ //------------------
426
+ // Custom tab
427
+ //------------------
428
+ &__custom-fields {
429
+ align-items: end;
430
+ gap: 8px;
431
+ padding: 0 6px;
432
+ margin-bottom: var(--xh-pad-px);
433
+ }
434
+
435
+ &__field {
436
+ flex: 1;
437
+
438
+ .xh-date-input .bp6-input {
439
+ font-family: var(--xh-date-range-picker-date-font-family);
440
+ }
441
+
442
+ // Accents the field whose edge the next calendar click will set. Overrides the resolved
443
+ // `--xh-` var, not the `--form-field-` hook: the hook is only read where Hoist declares
444
+ // these vars, on `body`, so it has no effect scoped to a descendant.
445
+ &--armed {
446
+ --xh-form-field-box-shadow: inset 0 0 0 1px var(--xh-date-range-picker-accent);
447
+ }
448
+ }
449
+
450
+ &__field-label {
451
+ @include drp-micro-label;
452
+
453
+ margin-bottom: 4px;
454
+ }
455
+
456
+ &__field-arrow {
457
+ font-size: $drp-font-size-micro;
458
+ color: var(--xh-text-color-muted);
459
+ margin-bottom: 9px;
460
+ }
461
+
462
+ &__cal-nav {
463
+ align-items: center;
464
+ margin-bottom: 4px;
465
+ }
466
+
467
+ &__cal-title {
468
+ flex: 1;
469
+ text-align: center;
470
+ font-weight: 600;
471
+ color: var(--xh-text-color-headings);
472
+ }
473
+
474
+ &__cals {
475
+ gap: 16px;
476
+ padding: 0 6px;
477
+ }
478
+
479
+ &__cal {
480
+ flex: 1;
481
+ min-width: 0;
482
+ }
483
+
484
+ &__cal-dow {
485
+ display: grid;
486
+ grid-template-columns: repeat(7, 1fr);
487
+ padding-bottom: 3px;
488
+
489
+ > span {
490
+ font-size: $drp-font-size-micro;
491
+ font-weight: 600;
492
+ color: var(--xh-text-color-muted);
493
+ text-align: center;
494
+ }
495
+ }
496
+
497
+ &__cal-week {
498
+ display: grid;
499
+ grid-template-columns: repeat(7, 1fr);
500
+ gap: 1px;
501
+ margin-bottom: 1px;
502
+ }
503
+
504
+ &__cal-cell {
505
+ height: var(--xh-date-range-picker-day-size);
506
+ display: flex;
507
+ align-items: center;
508
+ justify-content: center;
509
+ @include drp-date;
510
+
511
+ border-radius: 2px;
512
+ cursor: pointer;
513
+ transition:
514
+ background-color $drp-transition-dur,
515
+ color $drp-transition-dur;
516
+
517
+ &:empty {
518
+ cursor: default;
519
+ pointer-events: none;
520
+ }
521
+
522
+ &:hover:not(:empty):not(.xh-date-range-picker-popover__cal-cell--edge):not(
523
+ .xh-date-range-picker-popover__cal-cell--disabled
524
+ ) {
525
+ background: var(--xh-date-range-picker-hover-bg);
526
+ }
527
+
528
+ &--in-range {
529
+ background: var(--xh-date-range-picker-selected-bg);
530
+ }
531
+
532
+ &--edge {
533
+ background: var(--xh-date-range-picker-accent);
534
+ color: var(--xh-date-range-picker-accent-text-color);
535
+ font-weight: 600;
536
+ border-radius: 3px;
537
+ }
538
+
539
+ &--disabled {
540
+ opacity: 0.35;
541
+ cursor: default;
542
+ pointer-events: none;
543
+ }
544
+ }
545
+
546
+ //------------------
547
+ // Footer
548
+ //------------------
549
+ &__footer {
550
+ @include drp-footer-shell;
551
+
552
+ align-items: center;
553
+ gap: 8px;
554
+ }
555
+
556
+ &__footer-icon {
557
+ @include drp-secondary-text;
558
+ }
559
+
560
+ &__footer-note {
561
+ @include drp-secondary-prose;
562
+ }
563
+
564
+ // The date the note names - in the date font, receding with the prose around it.
565
+ &__footer-date {
566
+ @include drp-date-secondary;
567
+
568
+ margin-left: 4px;
569
+ }
570
+
571
+ &__single-footer {
572
+ @include drp-footer-shell;
573
+
574
+ @include drp-date-secondary;
575
+ }
576
+ }
577
+ }