@xh/hoist 83.1.0 → 84.0.1

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 (250) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/admin/tabs/cluster/instances/logs/levels/LogLevelDialogModel.ts +106 -10
  3. package/admin/tabs/cluster/metrics/MetricsModel.ts +3 -3
  4. package/appcontainer/AppContainerModel.ts +1 -1
  5. package/appcontainer/README.md +20 -0
  6. package/assets.d.ts +34 -0
  7. package/build/types/cmp/ag-grid/AgGrid.d.ts +8 -19
  8. package/build/types/cmp/ag-grid/AgGridModel.d.ts +18 -5
  9. package/build/types/cmp/card/Card.d.ts +9 -4
  10. package/build/types/cmp/card/CardModel.d.ts +15 -2
  11. package/build/types/cmp/chart/Chart.d.ts +2 -2
  12. package/build/types/cmp/chart/ChartModel.d.ts +11 -1
  13. package/build/types/cmp/dataview/DataView.d.ts +4 -2
  14. package/build/types/cmp/dataview/DataViewModel.d.ts +16 -4
  15. package/build/types/cmp/filter/FilterChooserModel.d.ts +7 -1
  16. package/build/types/cmp/form/Form.d.ts +2 -1
  17. package/build/types/cmp/form/FormModel.d.ts +12 -0
  18. package/build/types/cmp/form/field/BaseFieldModel.d.ts +7 -0
  19. package/build/types/cmp/form/formfieldset/FormFieldSetModel.d.ts +7 -1
  20. package/build/types/cmp/grid/GridModel.d.ts +16 -1
  21. package/build/types/cmp/grid/GridSorter.d.ts +14 -0
  22. package/build/types/cmp/grid/Types.d.ts +18 -0
  23. package/build/types/cmp/grid/columns/Column.d.ts +40 -2
  24. package/build/types/cmp/grid/columns/ColumnGroup.d.ts +10 -0
  25. package/build/types/cmp/grouping/GroupingChooserModel.d.ts +9 -2
  26. package/build/types/cmp/layout/Box.d.ts +19 -7
  27. package/build/types/cmp/layout/Frame.d.ts +17 -5
  28. package/build/types/cmp/loadingindicator/LoadingIndicator.d.ts +6 -4
  29. package/build/types/cmp/pinpad/PinPadModel.d.ts +6 -1
  30. package/build/types/cmp/spinner/Spinner.d.ts +31 -10
  31. package/build/types/cmp/tab/TabContainerModel.d.ts +11 -0
  32. package/build/types/cmp/tab/TabModel.d.ts +7 -0
  33. package/build/types/cmp/tab/Types.d.ts +4 -0
  34. package/build/types/cmp/treemap/TreeMapModel.d.ts +3 -3
  35. package/build/types/cmp/viewmanager/ViewManagerModel.d.ts +9 -0
  36. package/build/types/cmp/zoneGrid/ZoneGridModel.d.ts +22 -3
  37. package/build/types/cmp/zoneGrid/impl/ZoneMapperModel.d.ts +6 -0
  38. package/build/types/core/HoistComponent.d.ts +29 -8
  39. package/build/types/core/HoistProps.d.ts +9 -3
  40. package/build/types/core/load/LoadSpec.d.ts +1 -1
  41. package/build/types/core/persist/provider/ViewManagerProvider.d.ts +7 -0
  42. package/build/types/data/Store.d.ts +35 -1
  43. package/build/types/data/StoreSelectionModel.d.ts +18 -2
  44. package/build/types/data/cube/Cube.d.ts +26 -6
  45. package/build/types/data/cube/Query.d.ts +10 -0
  46. package/build/types/data/cube/View.d.ts +21 -2
  47. package/build/types/data/cube/aggregate/Aggregator.d.ts +13 -0
  48. package/build/types/data/cube/aggregate/AverageAggregator.d.ts +1 -0
  49. package/build/types/data/cube/aggregate/AverageStrictAggregator.d.ts +1 -0
  50. package/build/types/data/cube/aggregate/ChildCountAggregator.d.ts +1 -0
  51. package/build/types/data/cube/aggregate/LeafCountAggregator.d.ts +1 -0
  52. package/build/types/data/cube/aggregate/MaxAggregator.d.ts +1 -0
  53. package/build/types/data/cube/aggregate/MinAggregator.d.ts +1 -0
  54. package/build/types/data/cube/aggregate/NullAggregator.d.ts +1 -0
  55. package/build/types/data/cube/aggregate/SingleAggregator.d.ts +1 -0
  56. package/build/types/data/cube/aggregate/SumAggregator.d.ts +1 -0
  57. package/build/types/data/cube/aggregate/SumStrictAggregator.d.ts +1 -0
  58. package/build/types/data/cube/aggregate/UniqueAggregator.d.ts +1 -0
  59. package/build/types/data/filter/BaseFilterFieldSpec.d.ts +9 -0
  60. package/build/types/data/filter/Types.d.ts +12 -0
  61. package/build/types/desktop/cmp/button/AppMenuButton.d.ts +5 -0
  62. package/build/types/desktop/cmp/button/Button.d.ts +5 -1
  63. package/build/types/desktop/cmp/dash/canvas/DashCanvasModel.d.ts +12 -3
  64. package/build/types/desktop/cmp/dash/container/DashContainerModel.d.ts +9 -0
  65. package/build/types/desktop/cmp/dock/DockViewModel.d.ts +7 -0
  66. package/build/types/desktop/cmp/filechooser/FileChooserModel.d.ts +8 -0
  67. package/build/types/desktop/cmp/grid/editors/BooleanEditor.d.ts +1 -0
  68. package/build/types/desktop/cmp/grid/editors/DateEditor.d.ts +1 -0
  69. package/build/types/desktop/cmp/grid/editors/NumberEditor.d.ts +1 -0
  70. package/build/types/desktop/cmp/grid/editors/SelectEditor.d.ts +1 -0
  71. package/build/types/desktop/cmp/grid/editors/TextAreaEditor.d.ts +1 -0
  72. package/build/types/desktop/cmp/grid/editors/TextEditor.d.ts +1 -0
  73. package/build/types/desktop/cmp/input/Picker.d.ts +1 -1
  74. package/build/types/desktop/cmp/input/SegmentedControl.d.ts +16 -2
  75. package/build/types/desktop/cmp/leftrightchooser/LeftRightChooserModel.d.ts +7 -0
  76. package/build/types/desktop/cmp/modalsupport/ModalSupportModel.d.ts +28 -2
  77. package/build/types/desktop/cmp/panel/Panel.d.ts +5 -2
  78. package/build/types/desktop/cmp/panel/PanelModel.d.ts +12 -2
  79. package/build/types/desktop/cmp/rest/RestGrid.d.ts +10 -0
  80. package/build/types/desktop/cmp/rest/RestGridModel.d.ts +9 -1
  81. package/build/types/desktop/cmp/toolbar/Toolbar.d.ts +4 -1
  82. package/build/types/format/FormatDate.d.ts +4 -4
  83. package/build/types/icon/Icon.d.ts +3 -0
  84. package/build/types/kit/blueprint/Wrappers.d.ts +12 -1
  85. package/build/types/mobile/cmp/navigator/NavigatorModel.d.ts +8 -0
  86. package/build/types/mobile/cmp/navigator/PageModel.d.ts +7 -0
  87. package/build/types/mobile/cmp/panel/DialogPanel.d.ts +0 -2
  88. package/build/types/security/BaseOAuthClient.d.ts +9 -0
  89. package/build/types/security/authzero/AuthZeroClient.d.ts +6 -0
  90. package/build/types/security/msal/MsalClient.d.ts +6 -0
  91. package/build/types/svc/FetchService.d.ts +10 -7
  92. package/build/types/svc/TraceService.d.ts +17 -2
  93. package/build/types/utils/async/Timer.d.ts +6 -0
  94. package/build/types/utils/js/LangUtils.d.ts +1 -1
  95. package/build/types/utils/js/TestUtils.d.ts +1 -1
  96. package/build/types/utils/react/index.d.ts +0 -1
  97. package/build/types/utils/telemetry/Span.d.ts +12 -2
  98. package/cmp/ag-grid/AgGrid.ts +8 -19
  99. package/cmp/ag-grid/AgGridModel.ts +18 -5
  100. package/cmp/card/Card.ts +9 -4
  101. package/cmp/card/CardModel.ts +15 -2
  102. package/cmp/chart/Chart.ts +2 -2
  103. package/cmp/chart/ChartModel.ts +11 -1
  104. package/cmp/dataview/DataView.ts +4 -2
  105. package/cmp/dataview/DataViewModel.ts +16 -4
  106. package/cmp/filter/FilterChooserModel.ts +7 -1
  107. package/cmp/form/Form.ts +2 -1
  108. package/cmp/form/FormModel.ts +12 -0
  109. package/cmp/form/README.md +13 -0
  110. package/cmp/form/field/BaseFieldModel.ts +7 -0
  111. package/cmp/form/formfieldset/FormFieldSetModel.ts +7 -1
  112. package/cmp/grid/Grid.scss +14 -8
  113. package/cmp/grid/GridModel.ts +16 -1
  114. package/cmp/grid/GridSorter.ts +14 -0
  115. package/cmp/grid/README.md +12 -0
  116. package/cmp/grid/Types.ts +18 -0
  117. package/cmp/grid/columns/Column.ts +40 -2
  118. package/cmp/grid/columns/ColumnGroup.ts +10 -0
  119. package/cmp/grouping/GroupingChooserModel.ts +9 -2
  120. package/cmp/layout/Box.ts +19 -7
  121. package/cmp/layout/Frame.ts +17 -5
  122. package/cmp/layout/README.md +16 -21
  123. package/cmp/loadingindicator/LoadingIndicator.scss +1 -1
  124. package/cmp/loadingindicator/LoadingIndicator.ts +11 -9
  125. package/cmp/pinpad/PinPadModel.ts +6 -1
  126. package/cmp/spinner/Spinner.scss +13 -0
  127. package/cmp/spinner/Spinner.ts +58 -20
  128. package/cmp/tab/TabContainerModel.ts +11 -0
  129. package/cmp/tab/TabModel.ts +7 -0
  130. package/cmp/tab/Types.ts +4 -0
  131. package/cmp/treemap/TreeMapModel.ts +3 -3
  132. package/cmp/viewmanager/ViewManagerModel.ts +9 -0
  133. package/cmp/zoneGrid/ZoneGridModel.ts +22 -3
  134. package/cmp/zoneGrid/impl/ZoneMapperModel.ts +6 -0
  135. package/core/ExceptionHandler.ts +1 -1
  136. package/core/HoistComponent.ts +36 -11
  137. package/core/HoistProps.ts +9 -3
  138. package/core/README.md +68 -6
  139. package/core/impl/InstanceManager.ts +1 -0
  140. package/core/load/LoadSpec.ts +1 -1
  141. package/core/persist/provider/ViewManagerProvider.ts +7 -0
  142. package/data/README.md +48 -124
  143. package/data/Store.ts +35 -1
  144. package/data/StoreSelectionModel.ts +18 -2
  145. package/data/cube/Cube.ts +26 -6
  146. package/data/cube/Query.ts +10 -0
  147. package/data/cube/README.md +236 -0
  148. package/data/cube/View.ts +21 -2
  149. package/data/cube/aggregate/Aggregator.ts +13 -0
  150. package/data/cube/aggregate/AverageAggregator.ts +1 -0
  151. package/data/cube/aggregate/AverageStrictAggregator.ts +1 -0
  152. package/data/cube/aggregate/ChildCountAggregator.ts +1 -0
  153. package/data/cube/aggregate/LeafCountAggregator.ts +1 -0
  154. package/data/cube/aggregate/MaxAggregator.ts +1 -0
  155. package/data/cube/aggregate/MinAggregator.ts +1 -0
  156. package/data/cube/aggregate/NullAggregator.ts +1 -0
  157. package/data/cube/aggregate/SingleAggregator.ts +1 -0
  158. package/data/cube/aggregate/SumAggregator.ts +1 -0
  159. package/data/cube/aggregate/SumStrictAggregator.ts +1 -0
  160. package/data/cube/aggregate/UniqueAggregator.ts +1 -0
  161. package/data/filter/BaseFilterFieldSpec.ts +9 -0
  162. package/data/filter/Types.ts +12 -0
  163. package/desktop/README.md +131 -9
  164. package/desktop/appcontainer/AboutDialog.ts +2 -0
  165. package/desktop/appcontainer/Banner.ts +5 -2
  166. package/desktop/appcontainer/ChangelogDialog.ts +1 -0
  167. package/desktop/appcontainer/ExceptionDialog.ts +4 -0
  168. package/desktop/appcontainer/ExceptionDialogDetails.ts +4 -1
  169. package/desktop/appcontainer/FeedbackDialog.ts +4 -1
  170. package/desktop/appcontainer/ImpersonationBar.ts +4 -0
  171. package/desktop/appcontainer/LockoutPanel.ts +4 -1
  172. package/desktop/appcontainer/LoginPanel.ts +7 -3
  173. package/desktop/appcontainer/Message.ts +9 -3
  174. package/desktop/appcontainer/OptionsDialog.ts +3 -1
  175. package/desktop/appcontainer/VersionBar.ts +1 -0
  176. package/desktop/appcontainer/suspend/IdlePanel.ts +4 -4
  177. package/desktop/appcontainer/suspend/SuspendPanel.ts +3 -0
  178. package/desktop/cmp/button/AppMenuButton.ts +5 -0
  179. package/desktop/cmp/button/Button.ts +14 -4
  180. package/desktop/cmp/dash/README.md +14 -0
  181. package/desktop/cmp/dash/canvas/DashCanvasModel.ts +12 -3
  182. package/desktop/cmp/dash/container/DashContainerModel.ts +9 -0
  183. package/desktop/cmp/dock/DockViewModel.ts +7 -0
  184. package/desktop/cmp/filechooser/FileChooserModel.ts +9 -2
  185. package/desktop/cmp/grid/editors/BooleanEditor.ts +1 -0
  186. package/desktop/cmp/grid/editors/DateEditor.ts +1 -0
  187. package/desktop/cmp/grid/editors/NumberEditor.ts +1 -0
  188. package/desktop/cmp/grid/editors/SelectEditor.ts +1 -0
  189. package/desktop/cmp/grid/editors/TextAreaEditor.ts +1 -0
  190. package/desktop/cmp/grid/editors/TextEditor.ts +1 -0
  191. package/desktop/cmp/input/Picker.ts +2 -2
  192. package/desktop/cmp/input/SegmentedControl.ts +20 -2
  193. package/desktop/cmp/leftrightchooser/LeftRightChooserModel.ts +7 -0
  194. package/desktop/cmp/modalsupport/ModalSupportModel.ts +31 -2
  195. package/desktop/cmp/panel/Panel.ts +29 -21
  196. package/desktop/cmp/panel/PanelModel.ts +12 -2
  197. package/desktop/cmp/panel/README.md +20 -0
  198. package/desktop/cmp/rest/RestGrid.ts +10 -0
  199. package/desktop/cmp/rest/RestGridModel.ts +9 -1
  200. package/desktop/cmp/toolbar/Toolbar.ts +9 -2
  201. package/desktop/cmp/viewmanager/ViewManager.ts +1 -1
  202. package/docs/README.md +9 -4
  203. package/docs/coding-conventions.md +29 -21
  204. package/docs/doc-registry.json +31 -15
  205. package/docs/planning/docs-roadmap-log.md +11 -0
  206. package/docs/planning/docs-roadmap.md +1 -0
  207. package/docs/upgrade-notes/v84-upgrade-notes.md +136 -0
  208. package/docs/version-compatibility.md +2 -0
  209. package/format/FormatDate.ts +4 -4
  210. package/icon/Icon.ts +9 -0
  211. package/icon/README.md +62 -22
  212. package/icon/index.ts +24 -0
  213. package/kit/README.md +8 -2
  214. package/kit/blueprint/Wrappers.ts +12 -1
  215. package/mcp/README.md +47 -26
  216. package/mcp/cli/ts.ts +39 -4
  217. package/mcp/data/ts-registry.ts +57 -17
  218. package/mcp/tools/typescript.ts +32 -4
  219. package/mobile/appcontainer/AboutDialog.ts +3 -0
  220. package/mobile/appcontainer/Banner.ts +2 -0
  221. package/mobile/appcontainer/ExceptionDialog.ts +4 -0
  222. package/mobile/appcontainer/ExceptionDialogDetails.ts +1 -0
  223. package/mobile/appcontainer/FeedbackDialog.ts +4 -1
  224. package/mobile/appcontainer/ImpersonationBar.ts +2 -0
  225. package/mobile/appcontainer/LockoutPanel.ts +2 -0
  226. package/mobile/appcontainer/LoginPanel.ts +7 -3
  227. package/mobile/appcontainer/Message.ts +9 -3
  228. package/mobile/appcontainer/OptionsDialog.ts +5 -1
  229. package/mobile/appcontainer/VersionBar.ts +1 -0
  230. package/mobile/appcontainer/suspend/IdlePanel.ts +5 -6
  231. package/mobile/appcontainer/suspend/SuspendPanel.ts +3 -0
  232. package/mobile/cmp/navigator/NavigatorModel.ts +8 -0
  233. package/mobile/cmp/navigator/PageModel.ts +7 -0
  234. package/mobile/cmp/panel/DialogPanel.ts +0 -2
  235. package/package.json +11 -11
  236. package/security/BaseOAuthClient.ts +9 -0
  237. package/security/authzero/AuthZeroClient.ts +6 -0
  238. package/security/msal/MsalClient.ts +6 -0
  239. package/styles/vars.scss +14 -0
  240. package/svc/FetchService.ts +25 -15
  241. package/svc/README.md +39 -9
  242. package/svc/TraceService.ts +69 -11
  243. package/utils/README.md +0 -1
  244. package/utils/async/Timer.ts +6 -0
  245. package/utils/js/LangUtils.ts +1 -1
  246. package/utils/js/TestUtils.ts +1 -1
  247. package/utils/react/index.ts +0 -1
  248. package/utils/telemetry/Span.ts +21 -4
  249. package/build/types/utils/react/ClassName.d.ts +0 -14
  250. package/utils/react/ClassName.ts +0 -24
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import {hbox} from '@xh/hoist/cmp/layout';
8
8
  import {div} from '@xh/hoist/cmp/layout/Tags';
9
- import {spinner as spinnerCmp} from '@xh/hoist/cmp/spinner';
9
+ import {spinner as spinnerCmp, SpinnerProps} from '@xh/hoist/cmp/spinner';
10
10
  import {
11
11
  Corner,
12
12
  hoistCmp,
@@ -18,8 +18,9 @@ import {
18
18
  } from '@xh/hoist/core';
19
19
  import {withDefault} from '@xh/hoist/utils/js';
20
20
  import classNames from 'classnames';
21
- import {truncate} from 'lodash';
21
+ import {isString, truncate} from 'lodash';
22
22
  import './LoadingIndicator.scss';
23
+ import {ReactNode} from 'react';
23
24
 
24
25
  export interface LoadingIndicatorProps extends HoistProps {
25
26
  /** TaskObserver(s) that should be monitored to determine if the Indicator should be displayed. */
@@ -28,12 +29,12 @@ export interface LoadingIndicatorProps extends HoistProps {
28
29
  corner?: Corner;
29
30
  /** True to display the indicator. */
30
31
  isDisplayed?: boolean;
31
- /** Max characters allowed in message, after which it will be elided. Default 30. */
32
+ /** Max characters allowed in a String message, after which it will be elided. Default 30. */
32
33
  maxMessageLength?: number;
33
34
  /** Optional text to be displayed - can also be sourced from bound TaskObserver. */
34
- message?: string;
35
- /** True (default) to display with an animated spinner. */
36
- spinner?: boolean;
35
+ message?: ReactNode;
36
+ /** True (default) to display with an animated spinner, or SpinnerProps to customize. */
37
+ spinner?: boolean | Omit<SpinnerProps, 'compact'>;
37
38
  }
38
39
 
39
40
  /**
@@ -56,7 +57,7 @@ export const [LoadingIndicator, loadingIndicator] = hoistCmp.withFactory<Loading
56
57
 
57
58
  isDisplayed = withDefault(isDisplayed, impl.task?.isPending);
58
59
  message = withDefault(message, impl.task?.message);
59
- message = truncate(message, {length: maxMessageLength});
60
+ message = isString(message) ? truncate(message, {length: maxMessageLength}) : message;
60
61
 
61
62
  if (!isDisplayed || (!spinner && !message)) return null;
62
63
 
@@ -65,7 +66,8 @@ export const [LoadingIndicator, loadingIndicator] = hoistCmp.withFactory<Loading
65
66
  cornerCls = `xh-loading-indicator--${corner}`;
66
67
 
67
68
  const innerItems = () => {
68
- let spinnerEl = spinnerCmp({compact: true});
69
+ const spinnerProps = spinner === true ? {} : spinner || {};
70
+ let spinnerEl = spinnerCmp({compact: true, ...spinnerProps});
69
71
 
70
72
  if (!message) return [spinnerEl];
71
73
 
@@ -83,7 +85,7 @@ export const [LoadingIndicator, loadingIndicator] = hoistCmp.withFactory<Loading
83
85
  });
84
86
 
85
87
  class LocalMaskModel extends HoistModel {
86
- task;
88
+ task: TaskObserver;
87
89
 
88
90
  override onLinked() {
89
91
  const {bind} = this.componentProps;
@@ -14,6 +14,11 @@ import {times} from 'lodash';
14
14
  // safe to use with the desktop kit.
15
15
  import FastClick from '@onsenui/fastclick';
16
16
 
17
+ /**
18
+ * Configuration for a {@link PinPadModel} - a numeric keypad for collecting a PIN.
19
+ *
20
+ * @see PinPadModel
21
+ */
17
22
  export interface PinPadConfig {
18
23
  /** The length of the PIN to get from the user, default 4. */
19
24
  pinLength?: number;
@@ -22,7 +27,7 @@ export interface PinPadConfig {
22
27
  }
23
28
 
24
29
  /**
25
- * Model for a PinPad a numeric keypad prompt for collecting a PIN from the user.
30
+ * Model for a PinPad - a numeric keypad prompt for collecting a PIN from the user.
26
31
  *
27
32
  * Tracks entered digits, validates PIN completion, and provides observable `value` and
28
33
  * `isComplete` getters. Supports configurable PIN length and custom header/subheader text.
@@ -0,0 +1,13 @@
1
+ .xh-spinner {
2
+ color: var(--xh-spinner-color);
3
+ }
4
+
5
+ svg.xh-spinner {
6
+ animation: xh-spin 2s linear infinite;
7
+ }
8
+
9
+ @keyframes xh-spin {
10
+ to {
11
+ transform: rotate(360deg);
12
+ }
13
+ }
@@ -4,43 +4,81 @@
4
4
  *
5
5
  * Copyright © 2026 Extremely Heavy Industries Inc.
6
6
  */
7
+ import {IconName} from '@fortawesome/fontawesome-svg-core';
7
8
  import {img} from '@xh/hoist/cmp/layout';
8
9
  import {hoistCmp, HoistProps} from '@xh/hoist/core';
9
- import {ImgHTMLAttributes} from 'react';
10
-
11
- // @ts-ignore
10
+ import {HoistIconPrefix, Icon} from '@xh/hoist/icon';
12
11
  import compactSpinnerImg from './spinner-20px.png';
13
- // @ts-ignore
14
12
  import spinnerImg from './spinner-50px.png';
13
+ import './Spinner.scss';
14
+
15
+ export interface SpinnerDefaults {
16
+ iconName?: IconName;
17
+ prefix?: HoistIconPrefix;
18
+ usePng?: boolean;
19
+ }
15
20
 
16
- export interface SpinnerProps extends HoistProps, ImgHTMLAttributes<HTMLImageElement> {
17
- /** True to return a smaller 20px image vs default 50px. */
21
+ export interface SpinnerProps extends HoistProps {
22
+ /** True to return a smaller spinner suitable for inline/compact use. */
18
23
  compact?: boolean;
24
+ /** FA icon name to use. Default set via `Spinner.defaults.iconName`. */
25
+ iconName?: IconName;
26
+ /** FA icon prefix/weight. Default set via `Spinner.defaults.prefix`. */
27
+ prefix?: HoistIconPrefix;
28
+ /** True to use legacy animated PNG images. Default set via `Spinner.defaults.usePng`. */
29
+ usePng?: boolean;
19
30
  }
20
31
 
21
32
  /**
22
- * Returns an img-based spinner in one of two sizes - default 50px spinner or smaller 20px spinner
23
- * when `compact: true`. Used for the platform-specific `Mask` and `LoadingIndicator` components.
33
+ * An animated spinner rendered via a FontAwesome icon with a CSS rotation animation. Used for
34
+ * the platform-specific `Mask` and `LoadingIndicator` components.
35
+ *
36
+ * The rotation animation is applied via CSS on the `.xh-spinner` class rather than FA's
37
+ * animation props, ensuring the spinner remains functional when the OS-level
38
+ * `prefers-reduced-motion` preference is enabled (FA disables all its animations in that case).
24
39
  *
25
- * Note that the source images are animated PNGs generated via https://loading.io. These are used
26
- * in place of SVG-based options to reduce rendering overhead, especially when accessing an app
27
- * via a remote desktop technology such as Citrix (where the spinners bundled with e.g. Blueprint
28
- * were observed to cause unpredictable and unexpectedly severe performance issues).
40
+ * The icon and legacy PNG fallback can be configured per-instance via props or globally via
41
+ * `Spinner.defaults` (e.g. in app Bootstrap.ts):
42
+ *
43
+ * ```ts
44
+ * Spinner.defaults.iconName = 'circle-notch';
45
+ * Spinner.defaults.prefix = 'far';
46
+ * Spinner.defaults.usePng = true; // fall back to animated PNG
47
+ * ```
29
48
  */
30
- export const [Spinner, spinner] = hoistCmp.withFactory<SpinnerProps>({
49
+ export const [Spinner, spinner] = hoistCmp.withFactory<SpinnerProps, SpinnerDefaults>({
31
50
  displayName: 'Spinner',
32
51
  className: 'xh-spinner',
33
52
  model: false,
34
53
  observer: false,
35
-
54
+ defaults: {
55
+ iconName: 'spinner-third',
56
+ prefix: 'fal',
57
+ usePng: false
58
+ },
36
59
  render({compact, className, ...props}) {
37
- const pxSize = compact ? '20px' : '50px';
38
- return img({
39
- src: compact ? compactSpinnerImg : spinnerImg,
40
- width: pxSize,
41
- height: pxSize,
60
+ const {defaults} = Spinner,
61
+ iconName: IconName = props.iconName ?? defaults.iconName,
62
+ prefix = props.prefix ?? defaults.prefix,
63
+ usePng = props.usePng ?? defaults.usePng;
64
+
65
+ if (usePng) {
66
+ const pxSize = compact ? '20px' : '50px';
67
+ return img({
68
+ src: compact ? compactSpinnerImg : spinnerImg,
69
+ width: pxSize,
70
+ height: pxSize,
71
+ className
72
+ });
73
+ }
74
+
75
+ // Animation is applied via CSS on .xh-spinner rather than FA's animation props,
76
+ // which are disabled by FA's blanket prefers-reduced-motion override.
77
+ return Icon.icon({
78
+ iconName,
79
+ prefix,
42
80
  className,
43
- ...props
81
+ size: compact ? 'lg' : '3x'
44
82
  });
45
83
  }
46
84
  });
@@ -28,6 +28,14 @@ import {difference, find, findLast, isObject, isString, without} from 'lodash';
28
28
  import {ReactNode} from 'react';
29
29
  import {TabConfig, TabModel} from './TabModel';
30
30
 
31
+ /**
32
+ * Configuration for a {@link TabContainerModel} - the primary tabbed navigation container
33
+ * in Hoist. Supports routing, lazy rendering/refresh strategies, and optional persistence
34
+ * of the active tab.
35
+ *
36
+ * @see TabContainerModel
37
+ * @see TabConfig
38
+ */
31
39
  export interface TabContainerConfig {
32
40
  /** Tabs to be displayed. */
33
41
  tabs: TabConfig[];
@@ -93,6 +101,9 @@ export interface TabContainerConfig {
93
101
  * unmounting of inactive tabs, and customizable refreshing of tabs via a built-in RefreshContextModel.
94
102
  *
95
103
  * Note: Routing is currently enabled for desktop applications only.
104
+ *
105
+ * See the tab package README (`cmp/tab/README.md`) for render/refresh mode options, routing
106
+ * configuration, and usage patterns.
96
107
  */
97
108
  export class TabContainerModel extends HoistModel {
98
109
  declare config: TabContainerConfig;
@@ -21,6 +21,13 @@ import {isArray, isUndefined, startCase} from 'lodash';
21
21
  import {TabContainerConfig, TabContainerModel, tabContainer} from '@xh/hoist/cmp/tab';
22
22
  import {ReactElement, ReactNode} from 'react';
23
23
 
24
+ /**
25
+ * Configuration for a {@link TabModel} - a single tab within a {@link TabContainerModel}.
26
+ * Passed as entries in the `tabs` array of a {@link TabContainerConfig}.
27
+ *
28
+ * @see TabModel
29
+ * @see TabContainerConfig
30
+ */
24
31
  export interface TabConfig {
25
32
  /** Unique ID, used by container for locating tabs and generating routes. */
26
33
  id: string;
package/cmp/tab/Types.ts CHANGED
@@ -37,6 +37,10 @@ export interface TabSwitcherProps extends HoistProps<TabContainerModel>, BoxProp
37
37
  tabMaxWidth?: number;
38
38
  }
39
39
 
40
+ /**
41
+ * Configuration for the tab switcher UI within a {@link TabContainerModel}. Passed via the
42
+ * `switcher` config on {@link TabContainerConfig}.
43
+ */
40
44
  export interface TabSwitcherConfig {
41
45
  /** Specification for type of switcher. Specify `dynamic`for user-configurable tabs */
42
46
  mode: 'static' | 'dynamic';
@@ -108,9 +108,9 @@ export interface TreeMapModelDefaults {
108
108
  *
109
109
  * Node colors are normalized to a 0-1 range and mapped to a colorAxis. The `colorMode` config
110
110
  * controls how:
111
- * - 'linear' distributes values across the colorAxis according to the heatField.
112
- * - 'wash' ignores heat intensity, applying a single positive/negative color.
113
- * - 'none' ignores the colorAxis entirely, using the neutral color.
111
+ * - 'linear' - distributes values across the colorAxis according to the heatField.
112
+ * - 'wash' - ignores heat intensity, applying a single positive/negative color.
113
+ * - 'none' - ignores the colorAxis entirely, using the neutral color.
114
114
  *
115
115
  * Color customization can be managed by setting colorAxis stops via `highchartsConfig`.
116
116
  * See {@link https://www.highcharts.com/docs/chart-and-series-types/treemap} for Highcharts
@@ -55,6 +55,12 @@ export interface ViewUserState {
55
55
  autoSave: boolean;
56
56
  }
57
57
 
58
+ /**
59
+ * Configuration for a {@link ViewManagerModel} - persists and manages named user views
60
+ * (saved configurations) for grids, dashboards, or other stateful components.
61
+ *
62
+ * @see ViewManagerModel
63
+ */
58
64
  export interface ViewManagerConfig {
59
65
  /**
60
66
  * Required discriminator for the particular class of views to be loaded and managed by this
@@ -159,6 +165,9 @@ export interface ViewManagerConfig {
159
165
  * - Views can be private to their owner, or optionally enabled for sharing to (all) other users.
160
166
  * - Views can be marked as pinned for quick access.
161
167
  * - See the desktop {@link ViewManager} component - the initial Hoist UI for this model.
168
+ *
169
+ * See the view manager package README (`cmp/viewmanager/README.md`) for architecture,
170
+ * integration patterns, and access control configuration.
162
171
  */
163
172
  export class ViewManagerModel<T = PlainObject> extends HoistModel {
164
173
  /**
@@ -61,6 +61,14 @@ import {initPersist} from './impl/InitPersist';
61
61
  import {ZoneMapperConfig, ZoneMapperModel} from './impl/ZoneMapperModel';
62
62
  import {Zone, ZoneGridModelPersistOptions, ZoneLimit, ZoneMapping} from './Types';
63
63
 
64
+ /**
65
+ * Configuration for a {@link ZoneGridModel} - a card-style grid that arranges column data
66
+ * into four zones (top-left, top-right, bottom-left, bottom-right) within each row.
67
+ * Provide `columns` and `mappings` to define which fields appear in each zone.
68
+ *
69
+ * @see ZoneGridModel
70
+ * @see ZoneMapperConfig
71
+ */
64
72
  export interface ZoneGridConfig {
65
73
  /**
66
74
  * Available columns for this grid. Columns with an omit property evaluating to true will be
@@ -296,10 +304,21 @@ export interface ZoneGridConfig {
296
304
  }
297
305
 
298
306
  /**
299
- * ZoneGridModel is a wrapper around GridModel, which shows date in a grid with multi-line
300
- * full-width rows, each broken into four zones for top/bottom and left/right.
307
+ * Model for a ZoneGrid - a card-style grid that renders each row as a full-width block
308
+ * divided into four zones: top-left, top-right, bottom-left, and bottom-right. Built on
309
+ * {@link GridModel} internally.
310
+ *
311
+ * Use ZoneGrid when you want a structured multi-field card layout per row without writing
312
+ * a fully custom renderer. Especially well-suited for mobile or other space-constrained
313
+ * contexts where horizontal scrolling is undesirable but four or more user-configurable
314
+ * fields need to be visible per row. The `mappings` config controls which columns appear
315
+ * in each zone, and users can rearrange them via the optional ZoneMapper UI.
316
+ *
317
+ * For a standard column-based grid, use {@link GridModel}. For fully custom row rendering,
318
+ * use {@link DataViewModel}.
301
319
  *
302
- * This is the primary app entry-point for specifying ZoneGrid component options and behavior.
320
+ * @see ZoneGrid
321
+ * @see ZoneGridConfig
303
322
  */
304
323
  export class ZoneGridModel extends HoistModel {
305
324
  @managed
@@ -15,6 +15,12 @@ import {ReactNode} from 'react';
15
15
  import {ZoneGridModel} from '../ZoneGridModel';
16
16
  import {ZoneField, Zone, ZoneLimit, ZoneMapping} from '../Types';
17
17
 
18
+ /**
19
+ * Configuration for a ZoneMapperModel - the UI for user-driven customization of zone
20
+ * column mappings. Passed via the `zoneMapperModel` config on {@link ZoneGridConfig}.
21
+ *
22
+ * @see ZoneGridModel
23
+ */
18
24
  export interface ZoneMapperConfig {
19
25
  /** The ZoneGridModel to be configured. */
20
26
  zoneGridModel: ZoneGridModel;
@@ -275,7 +275,7 @@ export class ExceptionHandler {
275
275
  }
276
276
  delete fetchOptions.loadSpec;
277
277
  }
278
- // Remove Span object not useful in serialized output.
278
+ // Remove Span object - not useful in serialized output.
279
279
  delete fetchOptions.span;
280
280
  }
281
281
 
@@ -12,7 +12,8 @@ import {
12
12
  DefaultHoistProps,
13
13
  elementFactory,
14
14
  ElementFactory,
15
- TestSupportProps
15
+ TestSupportProps,
16
+ PlainObject
16
17
  } from './';
17
18
  import {
18
19
  useModelLinker,
@@ -67,7 +68,7 @@ export type RenderPropsOf<P extends HoistProps> = P & {
67
68
  * Configuration for creating a Component. May be specified either as a render function,
68
69
  * or an object containing a render function and associated metadata.
69
70
  */
70
- export type ComponentConfig<P extends HoistProps> =
71
+ export type ComponentConfig<P extends HoistProps, D extends PlainObject = never> =
71
72
  | ((props: RenderPropsOf<P>, ref?: ForwardedRef<any>) => ReactNode)
72
73
  | {
73
74
  /** Render function defining the component. */
@@ -103,12 +104,22 @@ export type ComponentConfig<P extends HoistProps> =
103
104
  * state may set this to `false`, but this is not typically done by application code.
104
105
  */
105
106
  observer?: boolean;
107
+
108
+ /**
109
+ * Static, app-wide configuration for the component, attached to the returned component
110
+ * as a typed `defaults` object that applications can modify at bootstrap to customize
111
+ * behavior for all instances (e.g. `Button.defaults.minimal = false` in Bootstrap.ts).
112
+ *
113
+ * Most commonly used to supply default values for selected props. May also be used for
114
+ * other app-overridable settings that are not exposed as props.
115
+ */
116
+ defaults?: D;
106
117
  };
107
118
 
108
119
  let cmpIndex = 0; // index for anonymous component dispay names
109
120
 
110
121
  /**
111
- * The primary entry point for defining Hoist components functional React components enhanced
122
+ * The primary entry point for defining Hoist components - functional React components enhanced
112
123
  * with MobX reactivity and integrated model support.
113
124
  *
114
125
  * Accepts a configuration object (or a bare render function) and returns a React functional
@@ -120,17 +131,23 @@ let cmpIndex = 0; // index for anonymous component dispay names
120
131
  * when observable state read during render changes.
121
132
  *
122
133
  * Forward refs ({@link https://reactjs.org/docs/forwarding-refs.html}) are supported by
123
- * specifying a render function with two arguments the second is treated as a ref, and
134
+ * specifying a render function with two arguments - the second is treated as a ref, and
124
135
  * `React.forwardRef` is applied automatically.
125
136
  *
126
137
  * Most components should be defined via one of two convenience methods rather than calling
127
138
  * this function directly:
128
- * - `hoistCmp.factory()` returns an element factory (the standard pattern for app components).
129
- * - `hoistCmp.withFactory()` returns a `[Component, factory]` pair (the standard pattern for
139
+ * - `hoistCmp.factory()` - returns an element factory (the standard pattern for app components).
140
+ * - `hoistCmp.withFactory()` - returns a `[Component, factory]` pair (the standard pattern for
130
141
  * library components that need to export both).
131
142
  *
132
- * See `core/README.md` for full documentation on component configuration, model specs, and
133
- * context lookup behavior.
143
+ * See the core package README (`core/README.md`) for full documentation on component
144
+ * configuration, model specs, and context lookup behavior.
145
+ *
146
+ * Components can also declare a typed `defaults` object in their config to expose static,
147
+ * app-wide configuration - most typically default values for selected props, but also other
148
+ * settings designed to be overridden by applications at bootstrap (e.g.
149
+ * `Button.defaults.minimal = false` in Bootstrap.ts). When specified, the returned component
150
+ * exposes a typed `defaults` property.
134
151
  *
135
152
  * @param config - specification object, or a render function defining the component.
136
153
  * @returns a functional React Component for use within Hoist apps.
@@ -138,6 +155,9 @@ let cmpIndex = 0; // index for anonymous component dispay names
138
155
  export function hoistCmp<M extends HoistModel>(
139
156
  config: ComponentConfig<DefaultHoistProps<M>>
140
157
  ): FC<DefaultHoistProps<M>>;
158
+ export function hoistCmp<P extends HoistProps, D extends PlainObject>(
159
+ config: ComponentConfig<P, D>
160
+ ): FC<P> & {defaults: D};
141
161
  export function hoistCmp<P extends HoistProps>(config: ComponentConfig<P>): FC<P>;
142
162
  export function hoistCmp<P extends HoistProps>(config: ComponentConfig<P>): FC<P> {
143
163
  // 0) Pre-process/parse args.
@@ -157,7 +177,8 @@ export function hoistCmp<P extends HoistProps>(config: ComponentConfig<P>): FC<P
157
177
  isMemo: withDefault(config.memo, true),
158
178
  isObserver: withDefault(config.observer, true),
159
179
  isForwardRef: render.length === 2,
160
- modelSpec: modelSpec ? modelSpec : null
180
+ modelSpec: modelSpec ? modelSpec : null,
181
+ defaults: config.defaults ?? null
161
182
  };
162
183
 
163
184
  warnIf(
@@ -176,16 +197,16 @@ export function hoistCmp<P extends HoistProps>(config: ComponentConfig<P>): FC<P
176
197
  render = wrapWithClonedProps(render);
177
198
  }
178
199
 
179
- // 4) Wrap with standard react HOCs, mark, and return.
200
+ // 4) Wrap with standard react HOCs, mark, install defaults if specified, and return.
180
201
  let ret = render as any;
181
202
  ret.displayName = cfg.displayName;
182
203
  if (cfg.isForwardRef) ret = forwardRef(ret);
183
204
  if (cfg.isObserver) ret = observer(ret);
184
205
  if (cfg.isMemo && !cfg.isObserver) ret = memo(ret);
185
206
 
186
- // 4) Mark and return.
187
207
  ret.displayName = cfg.displayName;
188
208
  ret.isHoistComponent = true;
209
+ if (cfg.defaults) ret.defaults = cfg.defaults;
189
210
 
190
211
  return ret;
191
212
  }
@@ -220,6 +241,9 @@ hoistCmp.factory = hoistCmpFactory;
220
241
  export function hoistCmpWithFactory<M extends HoistModel>(
221
242
  config: ComponentConfig<DefaultHoistProps<M>>
222
243
  ): [FC<DefaultHoistProps<M>>, ElementFactory<DefaultHoistProps<M>>];
244
+ export function hoistCmpWithFactory<P extends HoistProps, D extends PlainObject>(
245
+ config: ComponentConfig<P, D>
246
+ ): [FC<P> & {defaults: D}, ElementFactory<P>];
223
247
  export function hoistCmpWithFactory<P extends HoistProps>(
224
248
  config: ComponentConfig<P>
225
249
  ): [FC<P>, ElementFactory<P>];
@@ -245,6 +269,7 @@ interface Config {
245
269
  isForwardRef: boolean;
246
270
  isMemo: boolean;
247
271
  modelSpec: ModelSpec;
272
+ defaults: PlainObject;
248
273
  }
249
274
 
250
275
  interface ResolvedModel {
@@ -61,10 +61,16 @@ export interface DefaultHoistProps<M extends HoistModel = HoistModel> extends Ho
61
61
  }
62
62
 
63
63
  /**
64
- * Props for Components that support standard Layout attributes
64
+ * Props for components that support standard layout attributes (margin, padding, dimensions,
65
+ * flex, alignment, overflow). Extends {@link LayoutProps} with test support and standard
66
+ * HTML div attributes.
65
67
  *
66
- * Most component will typically separate these props out and pass them along to another component
67
- * which also supports this interface. Eventually, they should be passed to a Box class.
68
+ * Higher-level components accept these props and pass them through to a {@link Box} or
69
+ * {@link Frame} at the bottom of their render tree, where they are resolved to CSS styles.
70
+ *
71
+ * @see Box
72
+ * @see Frame
73
+ * @see LayoutProps
68
74
  */
69
75
  export interface BoxProps
70
76
  extends
package/core/README.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Core Package
2
2
 
3
+ | Section | Description |
4
+ |---------|-------------|
5
+ | [Overview](#overview) | Architecture overview and primary artifact types |
6
+ | [Class Hierarchy](#class-hierarchy) | Inheritance tree for Hoist's foundational classes |
7
+ | [HoistBase](#hoistbase) | MobX integration, resource management, and lifecycle |
8
+ | [HoistModel](#hoistmodel) | Stateful UI backing — linked/unlinked models, loading, lookup |
9
+ | [HoistService](#hoistservice) | Singleton services for app-wide state and data access |
10
+ | [Components and hoistCmp](#components-and-hoistcmp) | Functional components with MobX reactivity, model wiring, and defaults |
11
+ | [Element Factories](#element-factories) | Declarative JS-native alternative to JSX |
12
+ | [XH Singleton](#xh-singleton) | Top-level API entry point for the framework |
13
+ | [Decorators Reference](#decorators-reference) | Quick reference for all Hoist and MobX decorators |
14
+ | [Common Patterns](#common-patterns) | Constructor boilerplate, async naming, multiple models, error handling |
15
+ | [Common Pitfalls](#common-pitfalls) | Frequently encountered issues and how to avoid them |
16
+
3
17
  ## Overview
4
18
 
5
19
  The `/core/` package contains the foundational classes and utilities that define Hoist's architecture.
@@ -349,7 +363,7 @@ export const userDetail = hoistCmp.factory({
349
363
  // Simple component with no model
350
364
  export const statusBadge = hoistCmp.factory({
351
365
  model: false,
352
- className: 'status-badge',
366
+ className: 'my-app-status-badge',
353
367
  render({status, className}) {
354
368
  return div({className, item: status});
355
369
  }
@@ -366,11 +380,20 @@ export const statusBadge = hoistCmp.factory({
366
380
  | `displayName` | - | Component name for debugging |
367
381
  | `memo` | `true` | Wrap with React.memo |
368
382
  | `observer` | `true` | Enable MobX reactivity |
369
-
370
- > **Note:** When `className` is specified in the component config, it becomes the base class for
371
- > the component. Any `className` passed by callers is added as an additional class, and the
372
- > combined value is provided to `render()` via props. Apply this merged `className` to the
373
- > component's root element.
383
+ | `defaults` | - | Typed static config for the component, overridable at app bootstrap (see below) |
384
+
385
+ > **Best practice: Define `className` in the component spec** rather than hardcoding it inside
386
+ > the render function. The framework automatically merges the spec's base class with any
387
+ > `className` passed by callers, ensuring every component consistently supports caller-provided
388
+ > CSS class overrides without each render function needing to handle the merging itself.
389
+ >
390
+ > The merged `className` is provided to `render()` via props — it already contains both the
391
+ > base class from the spec and any caller-supplied classes. Apply it to the component's root
392
+ > element. If you need to add conditional modifier classes, combine them with the prop value
393
+ > (e.g. via the `classNames` library) — but don't re-add the base class, it's already included.
394
+ >
395
+ > Hoist library components use the `xh-` prefix for their base class names (e.g.
396
+ > `className: 'xh-panel'`). Applications should standardize on their own app-specific prefix.
374
397
 
375
398
  ### Model Specs: creates() vs uses()
376
399
 
@@ -454,6 +477,45 @@ export const myInput = hoistCmp.factory({
454
477
  });
455
478
  ```
456
479
 
480
+ ### Component Defaults
481
+
482
+ Components can declare a typed `defaults` object to expose **static, app-wide configuration** that
483
+ applications can override at bootstrap (e.g. in `Bootstrap.ts`) to customize all instances of the
484
+ component.
485
+
486
+ Most often this supplies default values for selected props — when read in `render` as fallbacks,
487
+ **instance props take precedence**. But `defaults` is not restricted to props and may carry other
488
+ app-overridable settings (thresholds, modes, etc.).
489
+
490
+ ```typescript
491
+ // 1) Define a defaults interface — typically mirrors a few props the author wants to be
492
+ // globally configurable, but may also include non-prop tunables.
493
+ export interface ButtonDefaults {
494
+ minimal?: boolean;
495
+ outlined?: boolean;
496
+ }
497
+
498
+ // 2) Pass as a second generic and include in the component config
499
+ export const [Button, button] = hoistCmp.withFactory<ButtonProps, ButtonDefaults>({
500
+ displayName: 'Button',
501
+ defaults: {
502
+ minimal: true,
503
+ outlined: false
504
+ },
505
+ render(props) {
506
+ const {defaults} = Button;
507
+ const {minimal = defaults.minimal, outlined = defaults.outlined, ...rest} = props;
508
+ // ...
509
+ }
510
+ });
511
+
512
+ // 3) Override in app Bootstrap.ts — mutate fields directly.
513
+ Button.defaults.minimal = false;
514
+ ```
515
+
516
+ This pattern is analogous to `static defaults` on Model and Service classes (e.g.
517
+ `GridModel.defaults`), adapted for functional components created via `hoistCmp`.
518
+
457
519
  ## Element Factories
458
520
 
459
521
  **File**: `elem.ts`
@@ -51,6 +51,7 @@ class InstanceManager {
51
51
  registerModelWithTestId(testId: string, m: HoistModel) {
52
52
  if (
53
53
  isNil(testId) ||
54
+ isNil(m) ||
54
55
  !m.isHoistModel ||
55
56
  !this.testSupportedModels.has(m.constructor.name) ||
56
57
  this.modelsByTestId.has(testId)
@@ -25,7 +25,7 @@ export type LoadSpecConfig = {
25
25
  * LoadSpec instances directly.
26
26
  *
27
27
  * Within `doLoadAsync()`, check {@link isStale} after any async call to determine if a newer
28
- * load has already been requested if so, return early to avoid applying outdated results.
28
+ * load has already been requested - if so, return early to avoid applying outdated results.
29
29
  * Check {@link isAutoRefresh} to adjust behavior for background refreshes (e.g. skip expensive
30
30
  * operations, avoid user-facing error dialogs).
31
31
  *
@@ -9,6 +9,13 @@ import {throwIf} from '@xh/hoist/utils/js';
9
9
  import {PersistenceProvider, PersistenceProviderConfig} from '../PersistenceProvider';
10
10
  import type {ViewManagerModel} from '@xh/hoist/cmp/viewmanager/ViewManagerModel';
11
11
 
12
+ /**
13
+ * PersistenceProvider that delegates state storage to a ViewManagerModel, enabling components
14
+ * to persist their state as part of user-managed named views.
15
+ *
16
+ * @see ViewManagerModel
17
+ * @see PersistenceProvider
18
+ */
12
19
  export class ViewManagerProvider<S> extends PersistenceProvider<S> {
13
20
  readonly viewManagerModel: ViewManagerModel;
14
21