@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.
- package/CHANGELOG.md +76 -0
- package/admin/tabs/cluster/instances/logs/levels/LogLevelDialogModel.ts +106 -10
- package/admin/tabs/cluster/metrics/MetricsModel.ts +3 -3
- package/appcontainer/AppContainerModel.ts +1 -1
- package/appcontainer/README.md +20 -0
- package/assets.d.ts +34 -0
- package/build/types/cmp/ag-grid/AgGrid.d.ts +8 -19
- package/build/types/cmp/ag-grid/AgGridModel.d.ts +18 -5
- package/build/types/cmp/card/Card.d.ts +9 -4
- package/build/types/cmp/card/CardModel.d.ts +15 -2
- package/build/types/cmp/chart/Chart.d.ts +2 -2
- package/build/types/cmp/chart/ChartModel.d.ts +11 -1
- package/build/types/cmp/dataview/DataView.d.ts +4 -2
- package/build/types/cmp/dataview/DataViewModel.d.ts +16 -4
- package/build/types/cmp/filter/FilterChooserModel.d.ts +7 -1
- package/build/types/cmp/form/Form.d.ts +2 -1
- package/build/types/cmp/form/FormModel.d.ts +12 -0
- package/build/types/cmp/form/field/BaseFieldModel.d.ts +7 -0
- package/build/types/cmp/form/formfieldset/FormFieldSetModel.d.ts +7 -1
- package/build/types/cmp/grid/GridModel.d.ts +16 -1
- package/build/types/cmp/grid/GridSorter.d.ts +14 -0
- package/build/types/cmp/grid/Types.d.ts +18 -0
- package/build/types/cmp/grid/columns/Column.d.ts +40 -2
- package/build/types/cmp/grid/columns/ColumnGroup.d.ts +10 -0
- package/build/types/cmp/grouping/GroupingChooserModel.d.ts +9 -2
- package/build/types/cmp/layout/Box.d.ts +19 -7
- package/build/types/cmp/layout/Frame.d.ts +17 -5
- package/build/types/cmp/loadingindicator/LoadingIndicator.d.ts +6 -4
- package/build/types/cmp/pinpad/PinPadModel.d.ts +6 -1
- package/build/types/cmp/spinner/Spinner.d.ts +31 -10
- package/build/types/cmp/tab/TabContainerModel.d.ts +11 -0
- package/build/types/cmp/tab/TabModel.d.ts +7 -0
- package/build/types/cmp/tab/Types.d.ts +4 -0
- package/build/types/cmp/treemap/TreeMapModel.d.ts +3 -3
- package/build/types/cmp/viewmanager/ViewManagerModel.d.ts +9 -0
- package/build/types/cmp/zoneGrid/ZoneGridModel.d.ts +22 -3
- package/build/types/cmp/zoneGrid/impl/ZoneMapperModel.d.ts +6 -0
- package/build/types/core/HoistComponent.d.ts +29 -8
- package/build/types/core/HoistProps.d.ts +9 -3
- package/build/types/core/load/LoadSpec.d.ts +1 -1
- package/build/types/core/persist/provider/ViewManagerProvider.d.ts +7 -0
- package/build/types/data/Store.d.ts +35 -1
- package/build/types/data/StoreSelectionModel.d.ts +18 -2
- package/build/types/data/cube/Cube.d.ts +26 -6
- package/build/types/data/cube/Query.d.ts +10 -0
- package/build/types/data/cube/View.d.ts +21 -2
- package/build/types/data/cube/aggregate/Aggregator.d.ts +13 -0
- package/build/types/data/cube/aggregate/AverageAggregator.d.ts +1 -0
- package/build/types/data/cube/aggregate/AverageStrictAggregator.d.ts +1 -0
- package/build/types/data/cube/aggregate/ChildCountAggregator.d.ts +1 -0
- package/build/types/data/cube/aggregate/LeafCountAggregator.d.ts +1 -0
- package/build/types/data/cube/aggregate/MaxAggregator.d.ts +1 -0
- package/build/types/data/cube/aggregate/MinAggregator.d.ts +1 -0
- package/build/types/data/cube/aggregate/NullAggregator.d.ts +1 -0
- package/build/types/data/cube/aggregate/SingleAggregator.d.ts +1 -0
- package/build/types/data/cube/aggregate/SumAggregator.d.ts +1 -0
- package/build/types/data/cube/aggregate/SumStrictAggregator.d.ts +1 -0
- package/build/types/data/cube/aggregate/UniqueAggregator.d.ts +1 -0
- package/build/types/data/filter/BaseFilterFieldSpec.d.ts +9 -0
- package/build/types/data/filter/Types.d.ts +12 -0
- package/build/types/desktop/cmp/button/AppMenuButton.d.ts +5 -0
- package/build/types/desktop/cmp/button/Button.d.ts +5 -1
- package/build/types/desktop/cmp/dash/canvas/DashCanvasModel.d.ts +12 -3
- package/build/types/desktop/cmp/dash/container/DashContainerModel.d.ts +9 -0
- package/build/types/desktop/cmp/dock/DockViewModel.d.ts +7 -0
- package/build/types/desktop/cmp/filechooser/FileChooserModel.d.ts +8 -0
- package/build/types/desktop/cmp/grid/editors/BooleanEditor.d.ts +1 -0
- package/build/types/desktop/cmp/grid/editors/DateEditor.d.ts +1 -0
- package/build/types/desktop/cmp/grid/editors/NumberEditor.d.ts +1 -0
- package/build/types/desktop/cmp/grid/editors/SelectEditor.d.ts +1 -0
- package/build/types/desktop/cmp/grid/editors/TextAreaEditor.d.ts +1 -0
- package/build/types/desktop/cmp/grid/editors/TextEditor.d.ts +1 -0
- package/build/types/desktop/cmp/input/Picker.d.ts +1 -1
- package/build/types/desktop/cmp/input/SegmentedControl.d.ts +16 -2
- package/build/types/desktop/cmp/leftrightchooser/LeftRightChooserModel.d.ts +7 -0
- package/build/types/desktop/cmp/modalsupport/ModalSupportModel.d.ts +28 -2
- package/build/types/desktop/cmp/panel/Panel.d.ts +5 -2
- package/build/types/desktop/cmp/panel/PanelModel.d.ts +12 -2
- package/build/types/desktop/cmp/rest/RestGrid.d.ts +10 -0
- package/build/types/desktop/cmp/rest/RestGridModel.d.ts +9 -1
- package/build/types/desktop/cmp/toolbar/Toolbar.d.ts +4 -1
- package/build/types/format/FormatDate.d.ts +4 -4
- package/build/types/icon/Icon.d.ts +3 -0
- package/build/types/kit/blueprint/Wrappers.d.ts +12 -1
- package/build/types/mobile/cmp/navigator/NavigatorModel.d.ts +8 -0
- package/build/types/mobile/cmp/navigator/PageModel.d.ts +7 -0
- package/build/types/mobile/cmp/panel/DialogPanel.d.ts +0 -2
- package/build/types/security/BaseOAuthClient.d.ts +9 -0
- package/build/types/security/authzero/AuthZeroClient.d.ts +6 -0
- package/build/types/security/msal/MsalClient.d.ts +6 -0
- package/build/types/svc/FetchService.d.ts +10 -7
- package/build/types/svc/TraceService.d.ts +17 -2
- package/build/types/utils/async/Timer.d.ts +6 -0
- package/build/types/utils/js/LangUtils.d.ts +1 -1
- package/build/types/utils/js/TestUtils.d.ts +1 -1
- package/build/types/utils/react/index.d.ts +0 -1
- package/build/types/utils/telemetry/Span.d.ts +12 -2
- package/cmp/ag-grid/AgGrid.ts +8 -19
- package/cmp/ag-grid/AgGridModel.ts +18 -5
- package/cmp/card/Card.ts +9 -4
- package/cmp/card/CardModel.ts +15 -2
- package/cmp/chart/Chart.ts +2 -2
- package/cmp/chart/ChartModel.ts +11 -1
- package/cmp/dataview/DataView.ts +4 -2
- package/cmp/dataview/DataViewModel.ts +16 -4
- package/cmp/filter/FilterChooserModel.ts +7 -1
- package/cmp/form/Form.ts +2 -1
- package/cmp/form/FormModel.ts +12 -0
- package/cmp/form/README.md +13 -0
- package/cmp/form/field/BaseFieldModel.ts +7 -0
- package/cmp/form/formfieldset/FormFieldSetModel.ts +7 -1
- package/cmp/grid/Grid.scss +14 -8
- package/cmp/grid/GridModel.ts +16 -1
- package/cmp/grid/GridSorter.ts +14 -0
- package/cmp/grid/README.md +12 -0
- package/cmp/grid/Types.ts +18 -0
- package/cmp/grid/columns/Column.ts +40 -2
- package/cmp/grid/columns/ColumnGroup.ts +10 -0
- package/cmp/grouping/GroupingChooserModel.ts +9 -2
- package/cmp/layout/Box.ts +19 -7
- package/cmp/layout/Frame.ts +17 -5
- package/cmp/layout/README.md +16 -21
- package/cmp/loadingindicator/LoadingIndicator.scss +1 -1
- package/cmp/loadingindicator/LoadingIndicator.ts +11 -9
- package/cmp/pinpad/PinPadModel.ts +6 -1
- package/cmp/spinner/Spinner.scss +13 -0
- package/cmp/spinner/Spinner.ts +58 -20
- package/cmp/tab/TabContainerModel.ts +11 -0
- package/cmp/tab/TabModel.ts +7 -0
- package/cmp/tab/Types.ts +4 -0
- package/cmp/treemap/TreeMapModel.ts +3 -3
- package/cmp/viewmanager/ViewManagerModel.ts +9 -0
- package/cmp/zoneGrid/ZoneGridModel.ts +22 -3
- package/cmp/zoneGrid/impl/ZoneMapperModel.ts +6 -0
- package/core/ExceptionHandler.ts +1 -1
- package/core/HoistComponent.ts +36 -11
- package/core/HoistProps.ts +9 -3
- package/core/README.md +68 -6
- package/core/impl/InstanceManager.ts +1 -0
- package/core/load/LoadSpec.ts +1 -1
- package/core/persist/provider/ViewManagerProvider.ts +7 -0
- package/data/README.md +48 -124
- package/data/Store.ts +35 -1
- package/data/StoreSelectionModel.ts +18 -2
- package/data/cube/Cube.ts +26 -6
- package/data/cube/Query.ts +10 -0
- package/data/cube/README.md +236 -0
- package/data/cube/View.ts +21 -2
- package/data/cube/aggregate/Aggregator.ts +13 -0
- package/data/cube/aggregate/AverageAggregator.ts +1 -0
- package/data/cube/aggregate/AverageStrictAggregator.ts +1 -0
- package/data/cube/aggregate/ChildCountAggregator.ts +1 -0
- package/data/cube/aggregate/LeafCountAggregator.ts +1 -0
- package/data/cube/aggregate/MaxAggregator.ts +1 -0
- package/data/cube/aggregate/MinAggregator.ts +1 -0
- package/data/cube/aggregate/NullAggregator.ts +1 -0
- package/data/cube/aggregate/SingleAggregator.ts +1 -0
- package/data/cube/aggregate/SumAggregator.ts +1 -0
- package/data/cube/aggregate/SumStrictAggregator.ts +1 -0
- package/data/cube/aggregate/UniqueAggregator.ts +1 -0
- package/data/filter/BaseFilterFieldSpec.ts +9 -0
- package/data/filter/Types.ts +12 -0
- package/desktop/README.md +131 -9
- package/desktop/appcontainer/AboutDialog.ts +2 -0
- package/desktop/appcontainer/Banner.ts +5 -2
- package/desktop/appcontainer/ChangelogDialog.ts +1 -0
- package/desktop/appcontainer/ExceptionDialog.ts +4 -0
- package/desktop/appcontainer/ExceptionDialogDetails.ts +4 -1
- package/desktop/appcontainer/FeedbackDialog.ts +4 -1
- package/desktop/appcontainer/ImpersonationBar.ts +4 -0
- package/desktop/appcontainer/LockoutPanel.ts +4 -1
- package/desktop/appcontainer/LoginPanel.ts +7 -3
- package/desktop/appcontainer/Message.ts +9 -3
- package/desktop/appcontainer/OptionsDialog.ts +3 -1
- package/desktop/appcontainer/VersionBar.ts +1 -0
- package/desktop/appcontainer/suspend/IdlePanel.ts +4 -4
- package/desktop/appcontainer/suspend/SuspendPanel.ts +3 -0
- package/desktop/cmp/button/AppMenuButton.ts +5 -0
- package/desktop/cmp/button/Button.ts +14 -4
- package/desktop/cmp/dash/README.md +14 -0
- package/desktop/cmp/dash/canvas/DashCanvasModel.ts +12 -3
- package/desktop/cmp/dash/container/DashContainerModel.ts +9 -0
- package/desktop/cmp/dock/DockViewModel.ts +7 -0
- package/desktop/cmp/filechooser/FileChooserModel.ts +9 -2
- package/desktop/cmp/grid/editors/BooleanEditor.ts +1 -0
- package/desktop/cmp/grid/editors/DateEditor.ts +1 -0
- package/desktop/cmp/grid/editors/NumberEditor.ts +1 -0
- package/desktop/cmp/grid/editors/SelectEditor.ts +1 -0
- package/desktop/cmp/grid/editors/TextAreaEditor.ts +1 -0
- package/desktop/cmp/grid/editors/TextEditor.ts +1 -0
- package/desktop/cmp/input/Picker.ts +2 -2
- package/desktop/cmp/input/SegmentedControl.ts +20 -2
- package/desktop/cmp/leftrightchooser/LeftRightChooserModel.ts +7 -0
- package/desktop/cmp/modalsupport/ModalSupportModel.ts +31 -2
- package/desktop/cmp/panel/Panel.ts +29 -21
- package/desktop/cmp/panel/PanelModel.ts +12 -2
- package/desktop/cmp/panel/README.md +20 -0
- package/desktop/cmp/rest/RestGrid.ts +10 -0
- package/desktop/cmp/rest/RestGridModel.ts +9 -1
- package/desktop/cmp/toolbar/Toolbar.ts +9 -2
- package/desktop/cmp/viewmanager/ViewManager.ts +1 -1
- package/docs/README.md +9 -4
- package/docs/coding-conventions.md +29 -21
- package/docs/doc-registry.json +31 -15
- package/docs/planning/docs-roadmap-log.md +11 -0
- package/docs/planning/docs-roadmap.md +1 -0
- package/docs/upgrade-notes/v84-upgrade-notes.md +136 -0
- package/docs/version-compatibility.md +2 -0
- package/format/FormatDate.ts +4 -4
- package/icon/Icon.ts +9 -0
- package/icon/README.md +62 -22
- package/icon/index.ts +24 -0
- package/kit/README.md +8 -2
- package/kit/blueprint/Wrappers.ts +12 -1
- package/mcp/README.md +47 -26
- package/mcp/cli/ts.ts +39 -4
- package/mcp/data/ts-registry.ts +57 -17
- package/mcp/tools/typescript.ts +32 -4
- package/mobile/appcontainer/AboutDialog.ts +3 -0
- package/mobile/appcontainer/Banner.ts +2 -0
- package/mobile/appcontainer/ExceptionDialog.ts +4 -0
- package/mobile/appcontainer/ExceptionDialogDetails.ts +1 -0
- package/mobile/appcontainer/FeedbackDialog.ts +4 -1
- package/mobile/appcontainer/ImpersonationBar.ts +2 -0
- package/mobile/appcontainer/LockoutPanel.ts +2 -0
- package/mobile/appcontainer/LoginPanel.ts +7 -3
- package/mobile/appcontainer/Message.ts +9 -3
- package/mobile/appcontainer/OptionsDialog.ts +5 -1
- package/mobile/appcontainer/VersionBar.ts +1 -0
- package/mobile/appcontainer/suspend/IdlePanel.ts +5 -6
- package/mobile/appcontainer/suspend/SuspendPanel.ts +3 -0
- package/mobile/cmp/navigator/NavigatorModel.ts +8 -0
- package/mobile/cmp/navigator/PageModel.ts +7 -0
- package/mobile/cmp/panel/DialogPanel.ts +0 -2
- package/package.json +11 -11
- package/security/BaseOAuthClient.ts +9 -0
- package/security/authzero/AuthZeroClient.ts +6 -0
- package/security/msal/MsalClient.ts +6 -0
- package/styles/vars.scss +14 -0
- package/svc/FetchService.ts +25 -15
- package/svc/README.md +39 -9
- package/svc/TraceService.ts +69 -11
- package/utils/README.md +0 -1
- package/utils/async/Timer.ts +6 -0
- package/utils/js/LangUtils.ts +1 -1
- package/utils/js/TestUtils.ts +1 -1
- package/utils/react/index.ts +0 -1
- package/utils/telemetry/Span.ts +21 -4
- package/build/types/utils/react/ClassName.d.ts +0 -14
- 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?:
|
|
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
|
-
|
|
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
|
|
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.
|
package/cmp/spinner/Spinner.ts
CHANGED
|
@@ -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 {
|
|
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
|
|
17
|
-
/** True to return a smaller
|
|
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
|
-
*
|
|
23
|
-
*
|
|
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
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
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
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
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;
|
package/cmp/tab/TabModel.ts
CHANGED
|
@@ -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'
|
|
112
|
-
* - 'wash'
|
|
113
|
-
* - 'none'
|
|
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
|
-
*
|
|
300
|
-
*
|
|
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
|
-
*
|
|
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;
|
package/core/ExceptionHandler.ts
CHANGED
package/core/HoistComponent.ts
CHANGED
|
@@ -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
|
|
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
|
|
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()`
|
|
129
|
-
* - `hoistCmp.withFactory()`
|
|
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
|
|
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 {
|
package/core/HoistProps.ts
CHANGED
|
@@ -61,10 +61,16 @@ export interface DefaultHoistProps<M extends HoistModel = HoistModel> extends Ho
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
|
-
* Props for
|
|
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
|
-
*
|
|
67
|
-
*
|
|
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
|
-
|
|
371
|
-
>
|
|
372
|
-
>
|
|
373
|
-
> component
|
|
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`
|
package/core/load/LoadSpec.ts
CHANGED
|
@@ -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
|
|
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
|
|