@xh/hoist 87.1.1 → 87.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.npmignore +39 -0
- package/CHANGELOG.md +92 -20
- package/admin/AdminUtils.ts +64 -0
- package/admin/App.scss +88 -0
- package/admin/columns/UserData.ts +30 -3
- package/admin/detail/RestDetailModel.ts +64 -0
- package/admin/detail/RestDetailPanel.ts +106 -0
- package/admin/tabs/activity/tracking/ActivityTrackingModel.ts +27 -94
- package/admin/tabs/activity/tracking/ActivityTrackingPanel.ts +23 -60
- package/admin/tabs/activity/tracking/detail/ActivityDetailView.ts +1 -2
- package/admin/tabs/general/alertBanner/AlertBannerPanel.ts +2 -13
- package/admin/tabs/general/config/ConfigDetailPanel.ts +72 -0
- package/admin/tabs/general/config/ConfigPanel.ts +41 -53
- package/admin/tabs/general/config/ConfigPanelModel.ts +3 -0
- package/admin/tabs/general/config/ConfigValue.scss +14 -0
- package/admin/tabs/general/config/ConfigValue.ts +104 -65
- package/admin/tabs/userData/jsonblob/JsonBlobDetailPanel.ts +93 -0
- package/admin/tabs/userData/jsonblob/JsonBlobModel.ts +4 -0
- package/admin/tabs/userData/jsonblob/JsonBlobPanel.ts +2 -0
- package/admin/tabs/userData/prefs/UserPreferenceDetailPanel.ts +62 -0
- package/admin/tabs/userData/prefs/UserPreferenceModel.ts +10 -3
- package/admin/tabs/userData/prefs/UserPreferencePanel.ts +3 -1
- package/admin/tabs/userData/roles/details/RoleDetails.scss +2 -19
- package/admin/tabs/userData/roles/details/RoleDetails.ts +13 -13
- package/appcontainer/AboutDialogModel.ts +1 -0
- package/appcontainer/AppContainerModel.ts +3 -0
- package/appcontainer/AppStateModel.ts +1 -0
- package/appcontainer/BannerSourceModel.ts +1 -0
- package/appcontainer/ChangelogDialogModel.ts +1 -0
- package/appcontainer/ColChooserOptionsModel.ts +1 -0
- package/appcontainer/ExceptionDialogModel.ts +1 -0
- package/appcontainer/FeedbackDialogModel.ts +1 -0
- package/appcontainer/ImpersonationBarModel.ts +1 -0
- package/appcontainer/MessageSourceModel.ts +1 -0
- package/appcontainer/OptionsDialogModel.ts +1 -0
- package/appcontainer/PageStateModel.ts +1 -0
- package/appcontainer/RouterModel.ts +2 -0
- package/appcontainer/SizingModeModel.ts +1 -0
- package/appcontainer/ThemeModel.ts +1 -0
- package/appcontainer/ToastSourceModel.ts +1 -0
- package/appcontainer/UserAgentModel.ts +1 -0
- package/appcontainer/ViewportSizeModel.ts +1 -0
- package/build/types/admin/AdminUtils.d.ts +29 -0
- package/build/types/admin/columns/UserData.d.ts +3 -0
- package/build/types/admin/detail/RestDetailModel.d.ts +20 -0
- package/build/types/admin/detail/RestDetailPanel.d.ts +34 -0
- package/build/types/admin/tabs/activity/tracking/ActivityTrackingModel.d.ts +5 -17
- package/build/types/admin/tabs/general/config/ConfigDetailPanel.d.ts +7 -0
- package/build/types/admin/tabs/general/config/ConfigValue.d.ts +10 -4
- package/build/types/admin/tabs/userData/jsonblob/JsonBlobDetailPanel.d.ts +3 -0
- package/build/types/admin/tabs/userData/prefs/UserPreferenceDetailPanel.d.ts +3 -0
- package/build/types/admin/tabs/userData/prefs/UserPreferenceModel.d.ts +3 -0
- package/build/types/appcontainer/AboutDialogModel.d.ts +1 -0
- package/build/types/appcontainer/AppContainerModel.d.ts +1 -0
- package/build/types/appcontainer/AppStateModel.d.ts +1 -0
- package/build/types/appcontainer/BannerSourceModel.d.ts +1 -0
- package/build/types/appcontainer/ChangelogDialogModel.d.ts +1 -0
- package/build/types/appcontainer/ColChooserOptionsModel.d.ts +1 -0
- package/build/types/appcontainer/ExceptionDialogModel.d.ts +1 -0
- package/build/types/appcontainer/FeedbackDialogModel.d.ts +1 -0
- package/build/types/appcontainer/ImpersonationBarModel.d.ts +1 -0
- package/build/types/appcontainer/MessageSourceModel.d.ts +1 -0
- package/build/types/appcontainer/OptionsDialogModel.d.ts +1 -0
- package/build/types/appcontainer/PageStateModel.d.ts +1 -0
- package/build/types/appcontainer/RouterModel.d.ts +1 -0
- package/build/types/appcontainer/SizingModeModel.d.ts +1 -0
- package/build/types/appcontainer/ThemeModel.d.ts +1 -0
- package/build/types/appcontainer/ToastSourceModel.d.ts +1 -0
- package/build/types/appcontainer/UserAgentModel.d.ts +1 -0
- package/build/types/appcontainer/ViewportSizeModel.d.ts +1 -0
- package/build/types/cmp/ag-grid/AgGridModel.d.ts +3 -1
- package/build/types/cmp/card/Card.d.ts +2 -2
- package/build/types/cmp/chart/ChartModel.d.ts +2 -0
- package/build/types/cmp/dataview/DataViewModel.d.ts +2 -0
- package/build/types/cmp/daterange/DateRangePickerModel.d.ts +266 -0
- package/build/types/cmp/daterange/DateRangePresets.d.ts +26 -0
- package/build/types/cmp/daterange/DateRangeUtils.d.ts +96 -0
- package/build/types/cmp/daterange/Types.d.ts +152 -0
- package/build/types/cmp/daterange/index.d.ts +4 -0
- package/build/types/cmp/filter/FilterChooserModel.d.ts +3 -1
- package/build/types/cmp/form/FormModel.d.ts +3 -1
- package/build/types/cmp/grid/GridModel.d.ts +2 -0
- package/build/types/cmp/grid/Types.d.ts +2 -0
- package/build/types/cmp/grid/filter/GridFilterModel.d.ts +1 -1
- package/build/types/cmp/grouping/GroupingChooserModel.d.ts +3 -1
- package/build/types/cmp/input/HoistInputProps.d.ts +49 -2
- package/build/types/cmp/tab/TabContainerModel.d.ts +3 -1
- package/build/types/cmp/tab/TabModel.d.ts +3 -1
- package/build/types/cmp/treemap/TreeMapModel.d.ts +2 -0
- package/build/types/cmp/viewmanager/ViewManagerModel.d.ts +2 -0
- package/build/types/cmp/zoneGrid/ZoneGridModel.d.ts +2 -0
- package/build/types/core/HoistBase.d.ts +7 -0
- package/build/types/core/HoistProps.d.ts +26 -1
- package/build/types/core/model/RootRefreshContextModel.d.ts +1 -0
- package/build/types/core/types/Telemetry.d.ts +1 -1
- package/build/types/data/Store.d.ts +3 -1
- package/build/types/data/StoreSelectionModel.d.ts +3 -1
- package/build/types/data/cube/Cube.d.ts +5 -2
- package/build/types/data/cube/View.d.ts +2 -0
- package/build/types/desktop/cmp/appOption/AutoRefreshAppOption.d.ts +3 -0
- package/build/types/desktop/cmp/appOption/ThemeAppOption.d.ts +3 -0
- package/build/types/desktop/cmp/button/Button.d.ts +2 -2
- package/build/types/desktop/cmp/button/ButtonGroup.d.ts +2 -2
- package/build/types/desktop/cmp/dash/DashConfig.d.ts +2 -0
- package/build/types/desktop/cmp/dash/DashViewModel.d.ts +3 -1
- package/build/types/desktop/cmp/dash/canvas/DashCanvasModel.d.ts +1 -1
- package/build/types/desktop/cmp/dash/container/DashContainerModel.d.ts +1 -1
- package/build/types/desktop/cmp/daterange/DateRangePicker.d.ts +66 -0
- package/build/types/desktop/cmp/daterange/impl/CustomTab.d.ts +3 -0
- package/build/types/desktop/cmp/daterange/impl/DateRangePickerLocalModel.d.ts +121 -0
- package/build/types/desktop/cmp/daterange/impl/PeriodTab.d.ts +2 -0
- package/build/types/desktop/cmp/daterange/impl/PresetsTab.d.ts +3 -0
- package/build/types/desktop/cmp/daterange/impl/RelativeTab.d.ts +3 -0
- package/build/types/desktop/cmp/daterange/impl/TabUtils.d.ts +21 -0
- package/build/types/desktop/cmp/daterange/index.d.ts +2 -0
- package/build/types/desktop/cmp/dock/DockContainerModel.d.ts +3 -1
- package/build/types/desktop/cmp/dock/DockViewModel.d.ts +3 -1
- package/build/types/desktop/cmp/grouping/GroupingChooser.d.ts +4 -1
- package/build/types/desktop/cmp/input/IntentInput.d.ts +38 -0
- package/build/types/desktop/cmp/input/NumberInput.d.ts +2 -2
- package/build/types/desktop/cmp/input/SegmentedControl.d.ts +25 -4
- package/build/types/desktop/cmp/input/TextArea.d.ts +2 -2
- package/build/types/desktop/cmp/input/TextInput.d.ts +2 -2
- package/build/types/desktop/cmp/input/index.d.ts +1 -0
- package/build/types/desktop/cmp/leftrightchooser/LeftRightChooserModel.d.ts +3 -1
- package/build/types/desktop/cmp/panel/PanelModel.d.ts +3 -1
- package/build/types/desktop/cmp/rest/RestGridModel.d.ts +1 -1
- package/build/types/desktop/cmp/tab/impl/TabContainer.d.ts +1 -1
- package/build/types/icon/Icon.d.ts +3 -0
- package/build/types/inspector/impl/InspectorUtils.d.ts +3 -0
- package/build/types/inspector/instances/InstancesModel.d.ts +4 -0
- package/build/types/kit/react-day-picker/index.d.ts +3 -3
- package/build/types/mobile/cmp/button/Button.d.ts +2 -2
- package/build/types/mobile/cmp/input/NumberInput.d.ts +2 -2
- package/build/types/mobile/cmp/input/SegmentedControl.d.ts +18 -4
- package/build/types/mobile/cmp/input/TextArea.d.ts +2 -2
- package/build/types/mobile/cmp/input/TextInput.d.ts +2 -2
- package/build/types/mobile/cmp/navigator/NavigatorModel.d.ts +3 -1
- package/build/types/mobile/cmp/navigator/PageModel.d.ts +3 -1
- package/build/types/mobile/cmp/tab/impl/TabContainer.d.ts +1 -1
- package/build/types/svc/InspectorService.d.ts +1 -0
- package/build/types/utils/js/LangUtils.d.ts +24 -5
- package/cmp/README.md +1 -0
- package/cmp/ag-grid/AgGridModel.ts +5 -0
- package/cmp/badge/Badge.ts +5 -3
- package/cmp/card/Card.ts +4 -3
- package/cmp/chart/ChartModel.ts +11 -1
- package/cmp/dataview/DataViewModel.ts +7 -1
- package/cmp/daterange/DateRangePickerModel.ts +628 -0
- package/cmp/daterange/DateRangePresets.ts +274 -0
- package/cmp/daterange/DateRangeUtils.ts +557 -0
- package/cmp/daterange/README.md +434 -0
- package/cmp/daterange/Types.ts +203 -0
- package/cmp/daterange/index.ts +10 -0
- package/cmp/filter/FilterChooserModel.ts +7 -4
- package/cmp/form/FormModel.ts +6 -0
- package/cmp/form/README.md +1 -0
- package/cmp/grid/GridModel.ts +24 -4
- package/cmp/grid/Types.ts +3 -0
- package/cmp/grid/filter/GridFilterModel.ts +3 -1
- package/cmp/grouping/GroupingChooserModel.ts +6 -1
- package/cmp/input/HoistInputProps.ts +50 -2
- package/cmp/input/README.md +42 -0
- package/cmp/layout/Box.ts +3 -2
- package/cmp/tab/TabContainerModel.ts +9 -1
- package/cmp/tab/TabModel.ts +5 -0
- package/cmp/treemap/SplitTreeMapModel.ts +12 -2
- package/cmp/treemap/TreeMapModel.ts +6 -1
- package/cmp/viewmanager/ViewManagerModel.ts +6 -1
- package/cmp/zoneGrid/ZoneGridModel.ts +7 -0
- package/core/HoistBase.ts +11 -0
- package/core/HoistProps.ts +27 -0
- package/core/README.md +46 -0
- package/core/impl/InstallServices.ts +5 -1
- package/core/model/RootRefreshContextModel.ts +2 -0
- package/core/types/Telemetry.ts +1 -1
- package/data/README.md +3 -1
- package/data/Store.ts +7 -0
- package/data/StoreSelectionModel.ts +5 -1
- package/data/cube/Cube.ts +12 -3
- package/data/cube/View.ts +5 -1
- package/desktop/README.md +2 -0
- package/desktop/appcontainer/LoginPanel.ts +2 -0
- package/desktop/cmp/button/Button.scss +71 -42
- package/desktop/cmp/button/Button.ts +10 -1
- package/desktop/cmp/button/ButtonGroup.ts +4 -1
- package/desktop/cmp/button/grid/ColChooserButton.ts +9 -1
- package/desktop/cmp/button/zoneGrid/ZoneMapperButton.ts +1 -0
- package/desktop/cmp/dash/DashConfig.ts +3 -0
- package/desktop/cmp/dash/DashViewModel.ts +14 -1
- package/desktop/cmp/dash/canvas/DashCanvasModel.ts +3 -1
- package/desktop/cmp/dash/container/DashContainerModel.ts +3 -1
- package/desktop/cmp/daterange/DateRangePicker.scss +577 -0
- package/desktop/cmp/daterange/DateRangePicker.ts +357 -0
- package/desktop/cmp/daterange/impl/CustomTab.ts +165 -0
- package/desktop/cmp/daterange/impl/DateRangePickerLocalModel.ts +482 -0
- package/desktop/cmp/daterange/impl/PeriodTab.ts +138 -0
- package/desktop/cmp/daterange/impl/PresetsTab.ts +58 -0
- package/desktop/cmp/daterange/impl/RelativeTab.ts +108 -0
- package/desktop/cmp/daterange/impl/TabUtils.ts +34 -0
- package/desktop/cmp/daterange/index.ts +8 -0
- package/desktop/cmp/dock/DockContainerModel.ts +6 -1
- package/desktop/cmp/dock/DockViewModel.ts +6 -1
- package/desktop/cmp/filechooser/FileChooser.ts +4 -0
- package/desktop/cmp/form/FormField.ts +1 -0
- package/desktop/cmp/grouping/GroupingChooser.ts +8 -2
- package/desktop/cmp/input/Checkbox.ts +1 -0
- package/desktop/cmp/input/CodeInput.ts +1 -0
- package/desktop/cmp/input/DateInput.scss +1 -1
- package/desktop/cmp/input/DateInput.ts +1 -0
- package/desktop/cmp/input/IntentInput.scss +202 -0
- package/desktop/cmp/input/IntentInput.ts +213 -0
- package/desktop/cmp/input/NumberInput.ts +11 -2
- package/desktop/cmp/input/Picker.ts +1 -0
- package/desktop/cmp/input/RadioInput.ts +2 -1
- package/desktop/cmp/input/SegmentedControl.scss +45 -2
- package/desktop/cmp/input/SegmentedControl.ts +66 -11
- package/desktop/cmp/input/Select.ts +9 -7
- package/desktop/cmp/input/Slider.ts +2 -0
- package/desktop/cmp/input/SwitchInput.ts +1 -0
- package/desktop/cmp/input/TextArea.ts +11 -2
- package/desktop/cmp/input/TextInput.ts +11 -2
- package/desktop/cmp/input/index.ts +1 -0
- package/desktop/cmp/leftrightchooser/LeftRightChooserModel.ts +5 -0
- package/desktop/cmp/panel/Panel.ts +8 -5
- package/desktop/cmp/panel/PanelModel.ts +8 -0
- package/desktop/cmp/panel/impl/ResizeContainer.ts +2 -1
- package/desktop/cmp/rest/RestGridModel.ts +4 -0
- package/desktop/cmp/tab/impl/TabContainer.ts +2 -0
- package/docs/README.md +2 -0
- package/docs/build-and-publish.md +23 -7
- package/docs/doc-registry.json +8 -0
- package/docs/version-compatibility.md +2 -0
- package/icon/Icon.ts +9 -0
- package/icon/index.ts +24 -0
- package/inspector/README.md +8 -2
- package/inspector/impl/InspectorUtils.ts +12 -0
- package/inspector/instances/DiagnosticsModel.ts +3 -2
- package/inspector/instances/InstancesModel.ts +81 -14
- package/inspector/instances/InstancesPanel.ts +6 -0
- package/kit/react-day-picker/index.ts +3 -3
- package/mobile/appcontainer/LoginPanel.ts +2 -0
- package/mobile/cmp/button/Button.ts +16 -3
- package/mobile/cmp/form/FormField.ts +1 -0
- package/mobile/cmp/input/Checkbox.ts +1 -0
- package/mobile/cmp/input/DateInput.ts +1 -0
- package/mobile/cmp/input/Label.ts +13 -8
- package/mobile/cmp/input/NumberInput.ts +11 -2
- package/mobile/cmp/input/SearchInput.ts +1 -0
- package/mobile/cmp/input/SegmentedControl.scss +36 -6
- package/mobile/cmp/input/SegmentedControl.ts +37 -11
- package/mobile/cmp/input/Select.ts +2 -0
- package/mobile/cmp/input/SwitchInput.ts +1 -0
- package/mobile/cmp/input/TextArea.ts +11 -2
- package/mobile/cmp/input/TextInput.ts +11 -2
- package/mobile/cmp/navigator/NavigatorModel.ts +6 -1
- package/mobile/cmp/navigator/PageModel.ts +6 -1
- package/mobile/cmp/tab/impl/TabContainer.ts +9 -1
- package/package.json +19 -19
- package/styles/vars.scss +32 -2
- package/svc/InspectorService.ts +2 -0
- package/svc/TraceService.ts +5 -2
- package/utils/js/LangUtils.ts +37 -5
|
@@ -0,0 +1,108 @@
|
|
|
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
|
+
import {DATE_RANGE_UNITS, getDateRangeUnitLabel} from '@xh/hoist/cmp/daterange';
|
|
8
|
+
import type {DateRangePickerLocalModel} from './DateRangePickerLocalModel';
|
|
9
|
+
import {div, hbox, span, vbox} from '@xh/hoist/cmp/layout';
|
|
10
|
+
import {hoistCmp} from '@xh/hoist/core';
|
|
11
|
+
import {button} from '@xh/hoist/desktop/cmp/button';
|
|
12
|
+
import {numberInput, segmentedControl} from '@xh/hoist/desktop/cmp/input';
|
|
13
|
+
import {controlGroup} from '@xh/hoist/kit/blueprint';
|
|
14
|
+
import {getTestId, TEST_ID} from '@xh/hoist/utils/js';
|
|
15
|
+
import {sectionHeader} from './TabUtils';
|
|
16
|
+
|
|
17
|
+
/** Relative tab - a lookback of N units ending on the anchor date, drafted until applied. */
|
|
18
|
+
export const relativeTab = hoistCmp.factory<DateRangePickerLocalModel>(({model, testId}) => {
|
|
19
|
+
const {parentModel, relativeRange} = model;
|
|
20
|
+
|
|
21
|
+
return vbox({
|
|
22
|
+
className: 'xh-date-range-picker-popover__tab',
|
|
23
|
+
items: [
|
|
24
|
+
sectionHeader('Relative Lookback'),
|
|
25
|
+
hbox({
|
|
26
|
+
className: 'xh-date-range-picker-popover__rel-row',
|
|
27
|
+
items: [
|
|
28
|
+
span({className: 'xh-date-range-picker-popover__rel-prefix', item: 'Prev'}),
|
|
29
|
+
controlGroup({
|
|
30
|
+
items: [
|
|
31
|
+
button({
|
|
32
|
+
text: '−',
|
|
33
|
+
minWidth: 20,
|
|
34
|
+
testId: getTestId(testId, 'count-down'),
|
|
35
|
+
onClick: () => model.stepCount(-1)
|
|
36
|
+
}),
|
|
37
|
+
numberInput({
|
|
38
|
+
model,
|
|
39
|
+
bind: 'relativeCount',
|
|
40
|
+
min: 1,
|
|
41
|
+
max: 999,
|
|
42
|
+
width: 56,
|
|
43
|
+
textAlign: 'center',
|
|
44
|
+
commitOnChange: true,
|
|
45
|
+
testId: getTestId(testId, 'count')
|
|
46
|
+
}),
|
|
47
|
+
button({
|
|
48
|
+
text: '+',
|
|
49
|
+
minWidth: 20,
|
|
50
|
+
testId: getTestId(testId, 'count-up'),
|
|
51
|
+
onClick: () => model.stepCount(1)
|
|
52
|
+
})
|
|
53
|
+
]
|
|
54
|
+
}),
|
|
55
|
+
segmentedControl({
|
|
56
|
+
model,
|
|
57
|
+
bind: 'relativeUnit',
|
|
58
|
+
testId: getTestId(testId, 'unit'),
|
|
59
|
+
options: DATE_RANGE_UNITS.map(unit => ({
|
|
60
|
+
value: unit,
|
|
61
|
+
label: getDateRangeUnitLabel(unit)
|
|
62
|
+
}))
|
|
63
|
+
})
|
|
64
|
+
]
|
|
65
|
+
}),
|
|
66
|
+
div({
|
|
67
|
+
className: 'xh-date-range-picker-popover__snap-box',
|
|
68
|
+
items: [
|
|
69
|
+
// Two ways of counting, named as peers rather than as a checkbox modifier.
|
|
70
|
+
// Days have nothing to round out, so no choice at that grain.
|
|
71
|
+
segmentedControl({
|
|
72
|
+
omit: !model.snapApplies,
|
|
73
|
+
model,
|
|
74
|
+
bind: 'relativeSnap',
|
|
75
|
+
fill: false,
|
|
76
|
+
testId: getTestId(testId, 'snap'),
|
|
77
|
+
options: [
|
|
78
|
+
{value: false, label: 'Rolling'},
|
|
79
|
+
{value: true, label: 'Calendar'}
|
|
80
|
+
]
|
|
81
|
+
}),
|
|
82
|
+
div({
|
|
83
|
+
className: 'xh-date-range-picker-popover__snap-help',
|
|
84
|
+
[TEST_ID]: getTestId(testId, 'snap-help'),
|
|
85
|
+
item: model.relativeModeHelpText
|
|
86
|
+
})
|
|
87
|
+
]
|
|
88
|
+
}),
|
|
89
|
+
div({
|
|
90
|
+
className: 'xh-date-range-picker-popover__preview',
|
|
91
|
+
items: [
|
|
92
|
+
div({
|
|
93
|
+
className: 'xh-date-range-picker-popover__preview-label',
|
|
94
|
+
item: 'Resolves To'
|
|
95
|
+
}),
|
|
96
|
+
div({
|
|
97
|
+
className: 'xh-date-range-picker-popover__preview-range',
|
|
98
|
+
item: parentModel.fmtRange(relativeRange)
|
|
99
|
+
}),
|
|
100
|
+
div({
|
|
101
|
+
className: 'xh-date-range-picker-popover__preview-days',
|
|
102
|
+
item: model.relativePreviewCountText
|
|
103
|
+
})
|
|
104
|
+
]
|
|
105
|
+
})
|
|
106
|
+
]
|
|
107
|
+
});
|
|
108
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
import {div} from '@xh/hoist/cmp/layout';
|
|
8
|
+
import type {KeyboardEvent} from 'react';
|
|
9
|
+
|
|
10
|
+
export const sectionHeader = (text: string) =>
|
|
11
|
+
div({className: 'xh-date-range-picker-popover__section-hdr', item: text});
|
|
12
|
+
|
|
13
|
+
/** Props making a styled div act as a keyboard-accessible button. Pass null to disable. */
|
|
14
|
+
export const clickable = (onClick: () => void) =>
|
|
15
|
+
onClick
|
|
16
|
+
? {
|
|
17
|
+
role: 'button',
|
|
18
|
+
tabIndex: 0,
|
|
19
|
+
onClick,
|
|
20
|
+
onKeyDown: (e: KeyboardEvent) => {
|
|
21
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
22
|
+
e.preventDefault();
|
|
23
|
+
e.stopPropagation();
|
|
24
|
+
onClick();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
: {role: 'button', 'aria-disabled': true};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Spread arbitrary `data-*` attributes onto a plain element spec. Needed only for attributes
|
|
32
|
+
* `ElementSpec` does not declare - `data-testid` is declared, so pass that as `[TEST_ID]` directly.
|
|
33
|
+
*/
|
|
34
|
+
export const dataAttrs = (attrs: Record<string, string>) => attrs as object;
|
|
@@ -0,0 +1,8 @@
|
|
|
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
|
+
export * from './DateRangePicker';
|
|
8
|
+
export * from '@xh/hoist/cmp/daterange';
|
|
@@ -20,6 +20,9 @@ interface DockContainerConfig {
|
|
|
20
20
|
renderMode?: RenderMode;
|
|
21
21
|
/** Strategy for refreshing DockViews. Can also be set per-view via `DockViewModelConfig.refreshMode` */
|
|
22
22
|
refreshMode?: RefreshMode;
|
|
23
|
+
|
|
24
|
+
/** See {@link HoistBase.xhName}. */
|
|
25
|
+
xhName?: string;
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
/**
|
|
@@ -38,10 +41,12 @@ export class DockContainerModel extends HoistModel {
|
|
|
38
41
|
views = [],
|
|
39
42
|
direction = 'rtl',
|
|
40
43
|
renderMode = 'lazy',
|
|
41
|
-
refreshMode = 'onShowLazy'
|
|
44
|
+
refreshMode = 'onShowLazy',
|
|
45
|
+
xhName = null
|
|
42
46
|
}: DockContainerConfig = {}) {
|
|
43
47
|
super();
|
|
44
48
|
makeObservable(this);
|
|
49
|
+
this.xhName = xhName;
|
|
45
50
|
views = views.filter(v => !isOmitted(v));
|
|
46
51
|
|
|
47
52
|
ensureUniqueBy(views as [], 'id', 'Multiple DockContainerModel views have the same id.');
|
|
@@ -66,6 +66,9 @@ export interface DockViewConfig {
|
|
|
66
66
|
allowDialog?: boolean;
|
|
67
67
|
/** Awaitable callback invoked on close. Return false to prevent close. */
|
|
68
68
|
onClose?: () => Awaitable<boolean | void>;
|
|
69
|
+
|
|
70
|
+
/** See {@link HoistBase.xhName}. */
|
|
71
|
+
xhName?: string;
|
|
69
72
|
}
|
|
70
73
|
|
|
71
74
|
/**
|
|
@@ -128,7 +131,8 @@ export class DockViewModel extends HoistModel {
|
|
|
128
131
|
collapsed = false,
|
|
129
132
|
allowClose = true,
|
|
130
133
|
allowDialog = true,
|
|
131
|
-
onClose
|
|
134
|
+
onClose,
|
|
135
|
+
xhName = null
|
|
132
136
|
}: DockViewConfig) {
|
|
133
137
|
super();
|
|
134
138
|
makeObservable(this);
|
|
@@ -136,6 +140,7 @@ export class DockViewModel extends HoistModel {
|
|
|
136
140
|
|
|
137
141
|
this.id = id;
|
|
138
142
|
this.containerModel = containerModel;
|
|
143
|
+
this.xhName = xhName ?? containerModel?.childXhName(id);
|
|
139
144
|
this.title = title;
|
|
140
145
|
this.icon = icon;
|
|
141
146
|
this.content = content;
|
|
@@ -112,6 +112,8 @@ export const [FileChooser, fileChooser] = hoistCmp.withFactory<FileChooserProps>
|
|
|
112
112
|
container = isTop ? vframe : hframe;
|
|
113
113
|
return container({
|
|
114
114
|
className,
|
|
115
|
+
testId: props.testId,
|
|
116
|
+
domAttrs: props.domAttrs,
|
|
115
117
|
items: [
|
|
116
118
|
// `box` (flex: none) so the rail keeps a fixed size beside the grid;
|
|
117
119
|
// `frame` would grow and crowd it out.
|
|
@@ -149,6 +151,8 @@ export const [FileChooser, fileChooser] = hoistCmp.withFactory<FileChooserProps>
|
|
|
149
151
|
!hasFiles ? 'xh-file-chooser__target--empty' : null,
|
|
150
152
|
clickable ? 'xh-file-chooser__target--clickable' : null
|
|
151
153
|
),
|
|
154
|
+
testId: props.testId,
|
|
155
|
+
domAttrs: props.domAttrs,
|
|
152
156
|
items: [dropzoneItem, targetMask, input({...getInputProps()})],
|
|
153
157
|
...getRootProps(),
|
|
154
158
|
...getLayoutProps(props)
|
|
@@ -62,7 +62,10 @@ export interface GroupingChooserProps extends ButtonProps<GroupingChooserModel>
|
|
|
62
62
|
*/
|
|
63
63
|
popoverWidth?: number;
|
|
64
64
|
|
|
65
|
-
/**
|
|
65
|
+
/**
|
|
66
|
+
* True (default) to style trigger button background and borders to match inputs. Set to false
|
|
67
|
+
* to render an outlined button instead.
|
|
68
|
+
*/
|
|
66
69
|
styleButtonAsInput?: boolean;
|
|
67
70
|
}
|
|
68
71
|
|
|
@@ -125,7 +128,10 @@ export const [GroupingChooser, groupingChooser] = hoistCmp.withFactory<GroupingC
|
|
|
125
128
|
'xh-grouping-chooser-button',
|
|
126
129
|
styleButtonAsInput ? 'xh-grouping-chooser-button--as-input' : null
|
|
127
130
|
),
|
|
128
|
-
|
|
131
|
+
// Input mode relies on the `--as-input` class for its chrome, so renders
|
|
132
|
+
// minimal. Button mode renders outlined, to match the ViewManager trigger.
|
|
133
|
+
...(styleButtonAsInput ? {minimal: true} : {outlined: true}),
|
|
134
|
+
active: isOpen,
|
|
129
135
|
...buttonProps,
|
|
130
136
|
onClick: () => impl.toggleEditor(),
|
|
131
137
|
testId
|
|
@@ -468,6 +468,7 @@ const cmp = hoistCmp.factory<DateInputProps & {model: DateInputModel}>(
|
|
|
468
468
|
inputRef: model.inputRef,
|
|
469
469
|
ref: model.textInputRef,
|
|
470
470
|
testId: getTestId(props),
|
|
471
|
+
domAttrs: props.domAttrs,
|
|
471
472
|
...getLayoutProps(props)
|
|
472
473
|
}),
|
|
473
474
|
className: 'xh-date-input__click-target',
|
|
@@ -0,0 +1,202 @@
|
|
|
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
|
+
.xh-intent-input {
|
|
9
|
+
display: inline-flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
gap: var(--xh-intent-input-gap-px);
|
|
12
|
+
|
|
13
|
+
// Selection ring geometry. Drawn as an outline on the swatch fill, so it takes no part in
|
|
14
|
+
// layout - the container reserves room for it with matching padding, derived from these two
|
|
15
|
+
// values so the two cannot drift apart.
|
|
16
|
+
--ring-offset: 2px;
|
|
17
|
+
--ring-width: 1px;
|
|
18
|
+
|
|
19
|
+
padding: calc(var(--ring-offset) + var(--ring-width));
|
|
20
|
+
// Pin the box against the line rather than letting its own baseline drive the line box. An
|
|
21
|
+
// inline-flex box takes its baseline from its first flex item, so the baseline would otherwise
|
|
22
|
+
// shift as the first swatch gains or loses the check - moving neighboring content (e.g. a
|
|
23
|
+
// FormField label) by a couple of pixels on every selection change.
|
|
24
|
+
vertical-align: middle;
|
|
25
|
+
|
|
26
|
+
&__swatch {
|
|
27
|
+
// Inset hairline color, shared by every fill state below. Overridden by the --none variant,
|
|
28
|
+
// whose transparent fill needs a visible outline rather than a darkening edge.
|
|
29
|
+
--swatch-hairline-color: rgba(0, 0, 0, 0.15);
|
|
30
|
+
|
|
31
|
+
// Reset the UA button styling - the swatch fill below is the entire control.
|
|
32
|
+
appearance: none;
|
|
33
|
+
background: none;
|
|
34
|
+
border: none;
|
|
35
|
+
padding: 0;
|
|
36
|
+
margin: 0;
|
|
37
|
+
display: inline-flex;
|
|
38
|
+
align-items: center;
|
|
39
|
+
gap: var(--xh-pad-half-px);
|
|
40
|
+
cursor: pointer;
|
|
41
|
+
color: var(--xh-text-color);
|
|
42
|
+
font-family: inherit;
|
|
43
|
+
font-size: var(--xh-font-size-px);
|
|
44
|
+
line-height: 1;
|
|
45
|
+
|
|
46
|
+
// Focus ring - drawn in the primary intent so it reads as focus rather than as selection.
|
|
47
|
+
// Higher specificity than the selected/hover rules below, so focus wins where they coincide.
|
|
48
|
+
&:focus-visible {
|
|
49
|
+
outline: none;
|
|
50
|
+
|
|
51
|
+
.xh-intent-input__swatch__fill {
|
|
52
|
+
outline: var(--ring-width) solid var(--xh-intent-primary);
|
|
53
|
+
outline-offset: var(--ring-offset);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// The color chip itself. Sized identically whether or not it holds the check, so selecting
|
|
58
|
+
// an option never shifts the row.
|
|
59
|
+
&__fill {
|
|
60
|
+
flex: none;
|
|
61
|
+
width: var(--xh-intent-input-swatch-size-px);
|
|
62
|
+
height: var(--xh-intent-input-swatch-size-px);
|
|
63
|
+
border-radius: var(--xh-intent-input-border-radius-px);
|
|
64
|
+
display: flex;
|
|
65
|
+
align-items: center;
|
|
66
|
+
justify-content: center;
|
|
67
|
+
// Inner hairline keeps a swatch legible where its color sits close to the surface behind it.
|
|
68
|
+
box-shadow: inset 0 0 0 1px var(--swatch-hairline-color);
|
|
69
|
+
transition:
|
|
70
|
+
box-shadow 100ms,
|
|
71
|
+
outline-color 100ms;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Check is rendered for every swatch and merely hidden when unselected. This keeps each
|
|
75
|
+
// swatch's box AND its baseline identical in both states: a flex container takes its baseline
|
|
76
|
+
// from its first flex item, so a fill that gained/lost the check would move the whole control's
|
|
77
|
+
// baseline, shifting baseline-aligned siblings - most visibly an inline FormField label, which
|
|
78
|
+
// aligns its row with `align-items: baseline`.
|
|
79
|
+
&__check {
|
|
80
|
+
color: var(--xh-white);
|
|
81
|
+
font-size: calc(var(--xh-intent-input-swatch-size-px) * 0.6);
|
|
82
|
+
|
|
83
|
+
&--hidden {
|
|
84
|
+
visibility: hidden;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
&__name {
|
|
89
|
+
white-space: nowrap;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Selected / hover - a ring offset from the swatch, echoing its own color. Drawn as an
|
|
93
|
+
// outline rather than a second box-shadow: the offset gap then shows the actual surface
|
|
94
|
+
// behind the control, instead of a band painted in --xh-bg that would be the wrong color on
|
|
95
|
+
// any other surface (a panel, a toolbar, a grid cell).
|
|
96
|
+
&--selected .xh-intent-input__swatch__fill,
|
|
97
|
+
&:hover:not(:disabled) .xh-intent-input__swatch__fill {
|
|
98
|
+
outline: var(--ring-width) solid currentColor;
|
|
99
|
+
outline-offset: var(--ring-offset);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
&:disabled {
|
|
103
|
+
cursor: default;
|
|
104
|
+
color: var(--xh-input-disabled-text-color);
|
|
105
|
+
|
|
106
|
+
.xh-intent-input__swatch__fill {
|
|
107
|
+
opacity: 0.5;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// The null option, shown when `enableClear` is set - an empty outlined box standing in for
|
|
112
|
+
// "no intent". Keeps the shared geometry, so it selects and checks exactly like the others.
|
|
113
|
+
&--none {
|
|
114
|
+
// With no fill behind it, this outline IS the swatch, so it needs real contrast against the
|
|
115
|
+
// surface - the standard border color is too faint to read as a selectable target. Mixed
|
|
116
|
+
// from the text color so it adapts per theme; --xh-text-color-muted resolves to the same
|
|
117
|
+
// mid-gray in both, which lands too light against a white background.
|
|
118
|
+
--swatch-hairline-color: color-mix(in srgb, var(--xh-text-color) 60%, var(--xh-bg));
|
|
119
|
+
|
|
120
|
+
color: var(--xh-text-color-muted);
|
|
121
|
+
|
|
122
|
+
.xh-intent-input__swatch__fill {
|
|
123
|
+
background-color: transparent;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// No colored fill to sit on, so the check takes the normal text color instead of white.
|
|
127
|
+
.xh-intent-input__swatch__check {
|
|
128
|
+
color: var(--xh-text-color);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Per-intent coloring. `color` carries the intent so the selected ring and the label can
|
|
133
|
+
// both pick it up via currentColor - the check reasserts white against the fill.
|
|
134
|
+
@each $intent in (primary, success, warning, danger) {
|
|
135
|
+
&--#{$intent} {
|
|
136
|
+
color: var(--xh-intent-#{$intent});
|
|
137
|
+
|
|
138
|
+
.xh-intent-input__swatch__fill {
|
|
139
|
+
background-color: var(--xh-intent-#{$intent});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Names shown - label text returns to the standard text color, leaving the swatch to carry
|
|
146
|
+
// the intent's color. Selected names are emphasized instead.
|
|
147
|
+
&--with-names .xh-intent-input__swatch {
|
|
148
|
+
margin-right: var(--xh-pad-half-px);
|
|
149
|
+
|
|
150
|
+
&__name {
|
|
151
|
+
color: var(--xh-text-color);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
&--selected .xh-intent-input__swatch__name {
|
|
155
|
+
font-weight: 600;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
&:disabled .xh-intent-input__swatch__name {
|
|
159
|
+
color: var(--xh-input-disabled-text-color);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Compact mode - reduced sizing for toolbars and space-constrained contexts. The ring offset
|
|
164
|
+
// tightens too, keeping the control inside the compact toolbar's item height.
|
|
165
|
+
&--compact {
|
|
166
|
+
--ring-offset: 1px;
|
|
167
|
+
|
|
168
|
+
gap: calc(var(--xh-intent-input-gap-px) / 2);
|
|
169
|
+
|
|
170
|
+
.xh-intent-input__swatch {
|
|
171
|
+
font-size: var(--xh-tbar-compact-font-size-px);
|
|
172
|
+
|
|
173
|
+
&__fill {
|
|
174
|
+
width: var(--xh-intent-input-compact-swatch-size-px);
|
|
175
|
+
height: var(--xh-intent-input-compact-swatch-size-px);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
&__check {
|
|
179
|
+
font-size: calc(var(--xh-intent-input-compact-swatch-size-px) * 0.6);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Validation borders - drawn on the container, as the swatches themselves are borderless.
|
|
185
|
+
&.xh-input--invalid,
|
|
186
|
+
&.xh-input--warning,
|
|
187
|
+
&.xh-input--info {
|
|
188
|
+
border-radius: var(--xh-intent-input-border-radius-px);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
&.xh-input--invalid {
|
|
192
|
+
border: var(--xh-form-field-invalid-border);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
&.xh-input--warning {
|
|
196
|
+
border: var(--xh-form-field-warning-border);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
&.xh-input--info {
|
|
200
|
+
border: var(--xh-form-field-info-border);
|
|
201
|
+
}
|
|
202
|
+
}
|