@vuu-ui/vuu-table-extras 2.1.19-beta.1 → 2.1.19-beta.2

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 (96) hide show
  1. package/package.json +13 -14
  2. package/src/calculated-column/CalculatedColumnPanel.js +95 -0
  3. package/src/calculated-column/useCalculatedColumnPanel.js +60 -0
  4. package/src/calculated-column/useEditCalculatedColumn.js +104 -0
  5. package/src/cell-edit-validators/CaseValidator.js +21 -0
  6. package/src/cell-edit-validators/PatternValidator.js +23 -0
  7. package/src/cell-edit-validators/index.js +2 -0
  8. package/src/cell-renderers/background-cell/BackgroundCell.css.js +103 -0
  9. package/src/cell-renderers/background-cell/BackgroundCell.js +76 -0
  10. package/src/cell-renderers/background-cell/BackgroundCellConfigurationEditor.css.js +9 -0
  11. package/src/cell-renderers/background-cell/BackgroundCellConfigurationEditor.js +71 -0
  12. package/src/cell-renderers/background-cell/BackgroundKeyframes.css.js +187 -0
  13. package/src/cell-renderers/background-cell/index.js +2 -0
  14. package/src/cell-renderers/background-cell/useDirection.js +25 -0
  15. package/src/cell-renderers/button-cell/IconButtonCell.css.js +23 -0
  16. package/src/cell-renderers/button-cell/IconButtonCell.js +33 -0
  17. package/src/cell-renderers/dropdown-cell/DropdownCell.css.js +36 -0
  18. package/src/cell-renderers/dropdown-cell/DropdownCell.js +84 -0
  19. package/src/cell-renderers/dropdown-cell/index.js +1 -0
  20. package/src/cell-renderers/index.js +6 -0
  21. package/src/cell-renderers/lookup-cell/LookupCell.js +15 -0
  22. package/src/cell-renderers/lookup-cell/index.js +1 -0
  23. package/src/cell-renderers/pct-progress-cell/PctProgressCell.css.js +31 -0
  24. package/src/cell-renderers/pct-progress-cell/PctProgressCell.js +49 -0
  25. package/src/cell-renderers/pct-progress-cell/index.js +1 -0
  26. package/src/cell-renderers/progress-cell/ProgressCell.css.js +43 -0
  27. package/src/cell-renderers/progress-cell/ProgressCell.js +74 -0
  28. package/src/cell-renderers/progress-cell/index.js +1 -0
  29. package/src/column-expression-input/ColumnExpressionInput.css.js +94 -0
  30. package/src/column-expression-input/ColumnExpressionInput.js +28 -0
  31. package/src/column-expression-input/column-function-descriptors.js +281 -0
  32. package/src/column-expression-input/column-language-parser/ColumnExpressionLanguage.js +18 -0
  33. package/src/column-expression-input/column-language-parser/ColumnExpressionTreeWalker.js +381 -0
  34. package/src/column-expression-input/column-language-parser/column-expression-parse-utils.js +56 -0
  35. package/src/column-expression-input/column-language-parser/index.js +3 -0
  36. package/src/column-expression-input/functionDocInfo.js +24 -0
  37. package/src/column-expression-input/highlighting.js +18 -0
  38. package/src/column-expression-input/index.js +4 -0
  39. package/src/column-expression-input/theme.js +57 -0
  40. package/src/column-expression-input/useColumnAutoComplete.js +307 -0
  41. package/src/column-expression-input/useColumnExpressionEditor.js +133 -0
  42. package/src/column-expression-input/useColumnExpressionSuggestionProvider.js +211 -0
  43. package/src/column-formatting-settings/BaseNumericFormattingSettings.js +96 -0
  44. package/src/column-formatting-settings/ColumnFormattingPanel.js +112 -0
  45. package/src/column-formatting-settings/DateTimeFormattingSettings.js +116 -0
  46. package/src/column-formatting-settings/LongTypeFormattingSettings.css.js +11 -0
  47. package/src/column-formatting-settings/LongTypeFormattingSettings.js +54 -0
  48. package/src/column-formatting-settings/index.js +3 -0
  49. package/src/column-menu/ColumnMenu.css.js +25 -0
  50. package/src/column-menu/ColumnMenu.js +69 -0
  51. package/src/column-menu/column-action-types.js +0 -0
  52. package/src/column-menu/column-menu-utils.js +318 -0
  53. package/src/column-menu/useColumnActions.js +77 -0
  54. package/src/column-picker/ColumnModel.js +113 -0
  55. package/src/column-picker/ColumnPicker.css.js +96 -0
  56. package/src/column-picker/ColumnPicker.js +204 -0
  57. package/src/column-picker/ColumnPickerAction.js +24 -0
  58. package/src/column-picker/useColumnPicker.js +42 -0
  59. package/src/column-picker/useTableColumnPicker.js +27 -0
  60. package/src/column-picker/useTableColumnPickerDeprecated.js +87 -0
  61. package/src/column-settings-panel/ColumnNameLabel.css.js +18 -0
  62. package/src/column-settings-panel/ColumnNameLabel.js +54 -0
  63. package/src/column-settings-panel/ColumnSettingsPanel.css.js +70 -0
  64. package/src/column-settings-panel/ColumnSettingsPanel.js +173 -0
  65. package/src/column-settings-panel/useColumnSettings.js +205 -0
  66. package/src/csv-upload/CsvUpload.css.js +28 -0
  67. package/src/csv-upload/CsvUpload.js +95 -0
  68. package/src/csv-upload/index.js +7 -0
  69. package/src/csv-upload/parse/csv-constants.js +3 -0
  70. package/src/csv-upload/parse/csv-errors.js +54 -0
  71. package/src/csv-upload/parse/csv-parse.js +79 -0
  72. package/src/csv-upload/parse/csv-schema-validation.js +45 -0
  73. package/src/csv-upload/parse/csv-upload-utils.js +59 -0
  74. package/src/csv-upload/parse/index.js +5 -0
  75. package/src/csv-upload/useCsvUpload.js +260 -0
  76. package/src/csv-upload/useCsvUploadSessionPreview.js +70 -0
  77. package/src/datasource-stats/DatasourceStats.css.js +56 -0
  78. package/src/datasource-stats/DatasourceStats.js +89 -0
  79. package/src/datasource-stats/useDatasourceStats.js +48 -0
  80. package/src/freeze-control/FreezeControl.css.js +108 -0
  81. package/src/freeze-control/FreezeControl.js +96 -0
  82. package/src/freeze-control/FrozenBanner.css.js +16 -0
  83. package/src/freeze-control/FrozenBanner.js +48 -0
  84. package/src/freeze-control/freezeControlBadge.js +9 -0
  85. package/src/freeze-control/useFreezeControl.js +68 -0
  86. package/src/index.js +22 -0
  87. package/src/tabbed-table-config-panel/TabbedTableConfigPanel.css.js +23 -0
  88. package/src/tabbed-table-config-panel/TabbedTableConfigPanel.js +99 -0
  89. package/src/tabbed-table-config-panel/TabbedTableSettingsAction.js +28 -0
  90. package/src/tabbed-table-config-panel/useTabbedTableConfigPanel.js +29 -0
  91. package/src/table-footer/TableFooter.css.js +22 -0
  92. package/src/table-footer/TableFooter.js +30 -0
  93. package/src/table-provider/TableProvider.js +33 -0
  94. package/src/table-settings-panel/TableSettingsPanel.css.js +70 -0
  95. package/src/table-settings-panel/TableSettingsPanel.js +128 -0
  96. package/src/table-settings-panel/useTableSettings.js +50 -0
@@ -0,0 +1,108 @@
1
+ const css = `
2
+ .vuuFreezeControl {
3
+ --freeze-control-flash-duration: .25s;
4
+ --freeze-control-active-button-color: var(--salt-palette-error-background);
5
+ --freeze-control-badge-color: var(--salt-palette-success-background);
6
+ height: fit-content;
7
+ display: inline-flex;
8
+
9
+ & .vuuFreezeControl-buttonRow {
10
+ background-color: var(--salt-container-secondary-background);
11
+ border: 1px solid var(--salt-container-secondary-borderColor);
12
+ white-space: nowrap;
13
+ border-radius: 50px;
14
+ display: flex;
15
+ overflow: hidden;
16
+ }
17
+
18
+ & .vuuFreezeControl-buttonWrapper {
19
+ padding: 0 var(--salt-spacing-150);
20
+ background-color: var(--salt-container-secondary-background);
21
+ border-radius: 50px;
22
+ }
23
+
24
+ & .vuuFreezeControl-buttonWrapper-active {
25
+ background-color: var(--freeze-control-active-button-color);
26
+ }
27
+
28
+ & .saltToggleButtonGroup {
29
+ padding: var(--vuuFreezeControl-padding, 0px);
30
+ }
31
+
32
+ & .vuuFreezeControl-buttonWrapper-active .saltToggleButton {
33
+ background-color: var(--freeze-control-active-button-color);
34
+ color: var(--salt-actionable-secondary-foreground-active);
35
+ }
36
+
37
+ & .saltToggleButtonGroup.vuuStateButtonGroup {
38
+ background-color: var(--salt-container-secondary-background);
39
+ }
40
+
41
+ & .saltToggleButtonGroup.vuuStateButtonGroup .saltToggleButton {
42
+ background-color: #0000;
43
+ }
44
+
45
+ & .vuuFreezeControl-customBadge {
46
+ color: var(--salt-text-primary-foreground);
47
+ font-size: var(--salt-text-fontSize);
48
+ height: var(--salt-size-base);
49
+ width: var(--salt-size-base);
50
+ min-width: var(--salt-size-base);
51
+ margin-left: var(--salt-spacing-100);
52
+ background-color: #0000;
53
+ border-radius: 50%;
54
+ justify-content: center;
55
+ align-items: center;
56
+ font-weight: bold;
57
+ line-height: 1;
58
+ display: flex;
59
+ position: relative;
60
+ overflow: visible;
61
+ }
62
+
63
+ & .vuuFreezeControl-newItems {
64
+ background-color: var(--salt-container-secondary-background);
65
+ font-size: var(--salt-text-fontSize);
66
+ padding: 0 var(--salt-spacing-200);
67
+ align-items: center;
68
+ display: flex;
69
+ }
70
+ }
71
+
72
+ .vuuFreezeControl-customBadge-flashing {
73
+ animation: flashGreenRed var(--freeze-control-flash-duration, .25s)
74
+ steps(1, end) infinite;
75
+ }
76
+
77
+ .vuuFreezeControl-customBadge[data-overflow="true"] {
78
+ padding-right: .2em;
79
+ }
80
+
81
+ .vuuFreezeControl-plus {
82
+ color: inherit;
83
+ pointer-events: none;
84
+ font-size: .8em;
85
+ font-weight: bold;
86
+ line-height: 1;
87
+ position: absolute;
88
+ top: .1em;
89
+ right: -.05em;
90
+ }
91
+
92
+ @keyframes flashGreenRed {
93
+ 0% {
94
+ background-color: var(--freeze-control-badge-color);
95
+ }
96
+
97
+ 50% {
98
+ background-color: #0000;
99
+ }
100
+
101
+ 100% {
102
+ background-color: var(--freeze-control-badge-color);
103
+ }
104
+ }
105
+
106
+
107
+ `;
108
+ export default css;
@@ -0,0 +1,96 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useComponentCssInjection } from "@salt-ds/styles";
3
+ import { useWindow } from "@salt-ds/window";
4
+ import { ToggleButton, ToggleButtonGroup } from "@salt-ds/core";
5
+ import { useFreezeControl } from "./useFreezeControl.js";
6
+ import { useEffect, useRef, useState } from "react";
7
+ import clsx from "clsx";
8
+ import { calculateBadgeState } from "./freezeControlBadge.js";
9
+ import FreezeControl from "./FreezeControl.css";
10
+ const FLASH_DURATION_MS = 3000;
11
+ const classBase = "vuuFreezeControl";
12
+ const FreezeControl_FreezeControl = ({ dataSource, className, newItemsLabel = "New Orders", flashDuration = 0.25, ...htmlAttributes })=>{
13
+ const targetWindow = useWindow();
14
+ useComponentCssInjection({
15
+ testId: "vuu-freeze-control",
16
+ css: FreezeControl,
17
+ window: targetWindow
18
+ });
19
+ const { isFrozen, newRecordCount, onToggleChange } = useFreezeControl({
20
+ dataSource
21
+ });
22
+ const [isFlashing, setIsFlashing] = useState(false);
23
+ const flashTimeoutRef = useRef(null);
24
+ useEffect(()=>{
25
+ if (isFrozen && newRecordCount > 0) {
26
+ setIsFlashing(true);
27
+ if (flashTimeoutRef.current) clearTimeout(flashTimeoutRef.current);
28
+ flashTimeoutRef.current = setTimeout(()=>{
29
+ setIsFlashing(false);
30
+ }, FLASH_DURATION_MS);
31
+ }
32
+ }, [
33
+ newRecordCount,
34
+ isFrozen
35
+ ]);
36
+ const { badgeValue, isOverflow } = calculateBadgeState(newRecordCount);
37
+ return /*#__PURE__*/ jsx("div", {
38
+ ...htmlAttributes,
39
+ className: clsx(classBase, className),
40
+ style: {
41
+ ...htmlAttributes.style,
42
+ "--freeze-control-flash-duration": `${flashDuration}s`
43
+ },
44
+ children: /*#__PURE__*/ jsxs("div", {
45
+ className: `${classBase}-buttonRow`,
46
+ children: [
47
+ /*#__PURE__*/ jsxs(ToggleButtonGroup, {
48
+ className: "vuuStateButtonGroup",
49
+ onChange: onToggleChange,
50
+ value: isFrozen ? "frozen" : "live",
51
+ children: [
52
+ /*#__PURE__*/ jsx("div", {
53
+ className: clsx(`${classBase}-buttonWrapper`, {
54
+ [`${classBase}-buttonWrapper-active`]: isFrozen
55
+ }),
56
+ children: /*#__PURE__*/ jsx(ToggleButton, {
57
+ value: "frozen",
58
+ children: isFrozen ? "Frozen" : "Freeze"
59
+ })
60
+ }),
61
+ /*#__PURE__*/ jsx("div", {
62
+ className: clsx(`${classBase}-buttonWrapper`, {
63
+ [`${classBase}-buttonWrapper-active`]: !isFrozen
64
+ }),
65
+ children: /*#__PURE__*/ jsx(ToggleButton, {
66
+ value: "live",
67
+ children: "Active"
68
+ })
69
+ })
70
+ ]
71
+ }),
72
+ isFrozen && /*#__PURE__*/ jsxs("div", {
73
+ className: `${classBase}-newItems`,
74
+ children: [
75
+ newItemsLabel,
76
+ /*#__PURE__*/ jsxs("div", {
77
+ className: clsx(`${classBase}-customBadge`, {
78
+ [`${classBase}-customBadge-flashing`]: isFlashing,
79
+ [`${classBase}-customBadge-overflow`]: isOverflow
80
+ }),
81
+ "data-overflow": isOverflow ? "true" : void 0,
82
+ children: [
83
+ badgeValue,
84
+ isOverflow && /*#__PURE__*/ jsx("span", {
85
+ className: `${classBase}-plus`,
86
+ children: "+"
87
+ })
88
+ ]
89
+ })
90
+ ]
91
+ })
92
+ ]
93
+ })
94
+ });
95
+ };
96
+ export { FreezeControl_FreezeControl as FreezeControl };
@@ -0,0 +1,16 @@
1
+ const css = `
2
+ .FrozenBanner {
3
+ --freeze-control-active-button-color: var(--salt-palette-error-background);
4
+ background-color: var(--freeze-control-active-button-color);
5
+ color: var(--salt-actionable-secondary-foreground-active);
6
+ font-size: var(--salt-text-fontSize);
7
+ height: var(--salt-size-base);
8
+ padding: 0 var(--salt-spacing-200);
9
+ border-radius: 4px;
10
+ align-items: center;
11
+ display: flex;
12
+ }
13
+
14
+
15
+ `;
16
+ export default css;
@@ -0,0 +1,48 @@
1
+ import { jsxs } from "react/jsx-runtime";
2
+ import { useComponentCssInjection } from "@salt-ds/styles";
3
+ import { useWindow } from "@salt-ds/window";
4
+ import { useEffect, useState } from "react";
5
+ import clsx from "clsx";
6
+ import FrozenBanner from "./FrozenBanner.css";
7
+ const classBase = "FrozenBanner";
8
+ const formatFreezeTime = (ts)=>{
9
+ const date = new Date(ts);
10
+ return date.toLocaleTimeString(void 0, {
11
+ hour: "2-digit",
12
+ minute: "2-digit"
13
+ });
14
+ };
15
+ const FrozenBanner_FrozenBanner = ({ dataSource, className, ...htmlAttributes })=>{
16
+ const targetWindow = useWindow();
17
+ useComponentCssInjection({
18
+ testId: "vuu-frozen-banner",
19
+ css: FrozenBanner,
20
+ window: targetWindow
21
+ });
22
+ const [isFrozen, setIsFrozen] = useState(dataSource.isFrozen ?? false);
23
+ const [freezeTime, setFreezeTime] = useState(dataSource.freezeTimestamp);
24
+ useEffect(()=>{
25
+ const handleFreezeChange = (frozen, timestamp)=>{
26
+ setIsFrozen(frozen);
27
+ setFreezeTime(timestamp);
28
+ };
29
+ setIsFrozen(dataSource.isFrozen ?? false);
30
+ setFreezeTime(dataSource.freezeTimestamp);
31
+ dataSource.on("freeze", handleFreezeChange);
32
+ return ()=>{
33
+ dataSource.removeListener("freeze", handleFreezeChange);
34
+ };
35
+ }, [
36
+ dataSource
37
+ ]);
38
+ if (!isFrozen) return null;
39
+ return /*#__PURE__*/ jsxs("div", {
40
+ ...htmlAttributes,
41
+ className: clsx(classBase, className),
42
+ children: [
43
+ "Frozen at ",
44
+ freezeTime ? formatFreezeTime(freezeTime) : "--:--"
45
+ ]
46
+ });
47
+ };
48
+ export { FrozenBanner_FrozenBanner as FrozenBanner };
@@ -0,0 +1,9 @@
1
+ const calculateBadgeState = (newRecordCount)=>{
2
+ const badgeValue = Math.min(newRecordCount, 99);
3
+ const isOverflow = newRecordCount > 99;
4
+ return {
5
+ badgeValue,
6
+ isOverflow
7
+ };
8
+ };
9
+ export { calculateBadgeState };
@@ -0,0 +1,68 @@
1
+ import { messageHasSize, useData } from "@vuu-ui/vuu-utils";
2
+ import { useCallback, useMemo, useState } from "react";
3
+ const FreezeState = (dataSource, newRecordCount)=>({
4
+ isFrozen: dataSource.isFrozen ?? false,
5
+ newRecordCount
6
+ });
7
+ const useFreezeControl = ({ dataSource })=>{
8
+ const { VuuDataSource } = useData();
9
+ const table = useMemo(()=>{
10
+ if (void 0 === dataSource.table) throw Error("[useFreezeControls] dataSource must have VuuTable");
11
+ return dataSource.table;
12
+ }, [
13
+ dataSource
14
+ ]);
15
+ const [freezeState, setFreezeState] = useState(FreezeState(dataSource, 0));
16
+ const [startTrackingNewRows, stopTrackingNewRows] = useMemo(()=>{
17
+ let ds;
18
+ const dataCallback = (message)=>{
19
+ if (messageHasSize(message)) setFreezeState((prev)=>({
20
+ ...prev,
21
+ newRecordCount: message.size
22
+ }));
23
+ };
24
+ const start = (ts)=>{
25
+ ds = new VuuDataSource({
26
+ columns: [
27
+ "vuuCreatedTimestamp"
28
+ ],
29
+ table
30
+ });
31
+ ds.subscribe({
32
+ filterSpec: {
33
+ filter: `vuuCreatedTimestamp > ${ts}`
34
+ }
35
+ }, dataCallback);
36
+ };
37
+ const stop = ()=>{
38
+ ds?.unsubscribe();
39
+ };
40
+ return [
41
+ start,
42
+ stop
43
+ ];
44
+ }, [
45
+ VuuDataSource,
46
+ table
47
+ ]);
48
+ const handleToggleChange = useCallback((evt)=>{
49
+ const value = evt.target.value;
50
+ if ("frozen" === value) {
51
+ dataSource.freeze?.();
52
+ startTrackingNewRows(dataSource.freezeTimestamp);
53
+ } else {
54
+ dataSource.unfreeze?.();
55
+ stopTrackingNewRows();
56
+ }
57
+ setFreezeState(FreezeState(dataSource, 0));
58
+ }, [
59
+ dataSource,
60
+ startTrackingNewRows,
61
+ stopTrackingNewRows
62
+ ]);
63
+ return {
64
+ ...freezeState,
65
+ onToggleChange: handleToggleChange
66
+ };
67
+ };
68
+ export { useFreezeControl };
package/src/index.js ADDED
@@ -0,0 +1,22 @@
1
+ export * from "./csv-upload/index.js";
2
+ export * from "./cell-edit-validators/index.js";
3
+ export * from "./cell-renderers/index.js";
4
+ export * from "./column-expression-input/index.js";
5
+ export * from "./column-formatting-settings/index.js";
6
+ export { CalculatedColumnPanel } from "./calculated-column/CalculatedColumnPanel.js";
7
+ export { ColumnMenu } from "./column-menu/ColumnMenu.js";
8
+ export { useColumnActions } from "./column-menu/useColumnActions.js";
9
+ export { ColumnChangeSource, ColumnModel, SelectedColumnChangeType, isColumnAdded, isColumnRemoved, isColumnsReordered } from "./column-picker/ColumnModel.js";
10
+ export { ColumnPicker } from "./column-picker/ColumnPicker.js";
11
+ export { ColumnPickerAction } from "./column-picker/ColumnPickerAction.js";
12
+ export { useTableColumnPicker } from "./column-picker/useTableColumnPicker.js";
13
+ export { ColumnSettingsPanel } from "./column-settings-panel/ColumnSettingsPanel.js";
14
+ export { useColumnSettings } from "./column-settings-panel/useColumnSettings.js";
15
+ export { DataSourceStats } from "./datasource-stats/DatasourceStats.js";
16
+ export { FreezeControl } from "./freeze-control/FreezeControl.js";
17
+ export { FrozenBanner } from "./freeze-control/FrozenBanner.js";
18
+ export { TabbedTableConfigPanel } from "./tabbed-table-config-panel/TabbedTableConfigPanel.js";
19
+ export { TabbedTableSettingsAction } from "./tabbed-table-config-panel/TabbedTableSettingsAction.js";
20
+ export { TableFooter, TableFooterTray } from "./table-footer/TableFooter.js";
21
+ export { TableProvider, useTableContext } from "./table-provider/TableProvider.js";
22
+ export { TableSettingsPanel, defaultTableSettingsPermissions } from "./table-settings-panel/TableSettingsPanel.js";
@@ -0,0 +1,23 @@
1
+ const css = `
2
+ .vuuTabbedTableConfigPanel {
3
+ --tabs-height: 25px;
4
+ position: absolute;
5
+ inset: 0;
6
+
7
+ & .saltTabsNext {
8
+ height: 100%;
9
+
10
+ & .saltTabListNext {
11
+ border-bottom: solid var(--salt-separable-secondary-borderColor) 1px;
12
+ height: var(--tabs-height);
13
+ }
14
+
15
+ & .saltTabNextPanel {
16
+ height: calc(100% - var(--tabs-height));
17
+ }
18
+ }
19
+ }
20
+
21
+
22
+ `;
23
+ export default css;
@@ -0,0 +1,99 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { TabListNext, TabNext, TabNextPanel, TabNextTrigger, TabsNext } from "@salt-ds/lab";
3
+ import { useComponentCssInjection } from "@salt-ds/styles";
4
+ import { useWindow } from "@salt-ds/window";
5
+ import clsx from "clsx";
6
+ import { useCallback, useState } from "react";
7
+ import { useEditCalculatedColumn } from "../calculated-column/useEditCalculatedColumn.js";
8
+ import { ColumnPicker } from "../column-picker/ColumnPicker.js";
9
+ import { ColumnSettingsPanel } from "../column-settings-panel/ColumnSettingsPanel.js";
10
+ import { TableSettingsPanel } from "../table-settings-panel/TableSettingsPanel.js";
11
+ import TabbedTableConfigPanel from "./TabbedTableConfigPanel.css";
12
+ const classBase = "vuuTabbedTableConfigPanel";
13
+ const TabbedTableConfigPanel_TabbedTableConfigPanel = ({ allowCreateCalculatedColumn = false, className, columnModel, config, onDisplayAttributeChange, selectedTab = "table-settings", vuuTable, ...htmlAttributes })=>{
14
+ const targetWindow = useWindow();
15
+ useComponentCssInjection({
16
+ testId: "vuu-tabbed-table-config-panel",
17
+ css: TabbedTableConfigPanel,
18
+ window: targetWindow
19
+ });
20
+ const [columns, setColumns] = useState([]);
21
+ const [value, setValue] = useState(selectedTab);
22
+ const handleChange = useCallback((_e, value)=>{
23
+ setValue(value);
24
+ }, []);
25
+ const handleSelectionChange = useCallback((_e, selectedItems)=>{
26
+ setColumns(selectedItems);
27
+ }, []);
28
+ const handleSaveCalculatedColumn = useCallback((column)=>{
29
+ setColumns([
30
+ column
31
+ ]);
32
+ }, []);
33
+ const { onCreateCalculatedColumn, onEditCalculatedColumn } = useEditCalculatedColumn({
34
+ columnModel,
35
+ calculatedColumn: columns[0],
36
+ onSaveColumn: handleSaveCalculatedColumn,
37
+ vuuTable
38
+ });
39
+ return /*#__PURE__*/ jsx("div", {
40
+ ...htmlAttributes,
41
+ className: clsx(classBase, className),
42
+ children: /*#__PURE__*/ jsxs(TabsNext, {
43
+ onChange: handleChange,
44
+ value: value,
45
+ children: [
46
+ /*#__PURE__*/ jsxs(TabListNext, {
47
+ appearance: "transparent",
48
+ children: [
49
+ /*#__PURE__*/ jsx(TabNext, {
50
+ value: "table-settings",
51
+ children: /*#__PURE__*/ jsx(TabNextTrigger, {
52
+ children: "Table settings"
53
+ })
54
+ }),
55
+ /*#__PURE__*/ jsx(TabNext, {
56
+ value: "table-columns",
57
+ children: /*#__PURE__*/ jsx(TabNextTrigger, {
58
+ children: "Table columns"
59
+ })
60
+ }),
61
+ /*#__PURE__*/ jsx(TabNext, {
62
+ disabled: 0 === columns.length,
63
+ value: "column-settings",
64
+ children: /*#__PURE__*/ jsx(TabNextTrigger, {
65
+ children: "Column settings"
66
+ })
67
+ })
68
+ ]
69
+ }),
70
+ /*#__PURE__*/ jsx(TabNextPanel, {
71
+ value: "table-settings",
72
+ children: /*#__PURE__*/ jsx(TableSettingsPanel, {
73
+ onDisplayAttributeChange: onDisplayAttributeChange,
74
+ tableDisplayAttributes: config
75
+ })
76
+ }),
77
+ /*#__PURE__*/ jsx(TabNextPanel, {
78
+ value: "table-columns",
79
+ children: /*#__PURE__*/ jsx(ColumnPicker, {
80
+ allowCreateCalculatedColumn: allowCreateCalculatedColumn,
81
+ columnModel: columnModel,
82
+ onClickCreateCalculatedColumn: onCreateCalculatedColumn,
83
+ onSelectionChange: handleSelectionChange,
84
+ selected: columns
85
+ })
86
+ }),
87
+ /*#__PURE__*/ jsx(TabNextPanel, {
88
+ value: "column-settings",
89
+ children: columns.length > 0 ? /*#__PURE__*/ jsx(ColumnSettingsPanel, {
90
+ column: columns[0],
91
+ columnModel: columnModel,
92
+ onClickEditCalculatedColumn: onEditCalculatedColumn
93
+ }) : null
94
+ })
95
+ ]
96
+ })
97
+ });
98
+ };
99
+ export { TabbedTableConfigPanel_TabbedTableConfigPanel as TabbedTableConfigPanel };
@@ -0,0 +1,28 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { IconButton } from "@vuu-ui/vuu-ui-controls";
3
+ import { useCallback } from "react";
4
+ import { useTabbedTableConfigPanel } from "./useTabbedTableConfigPanel.js";
5
+ const TabbedTableSettingsAction = ({ allowCreateCalculatedColumn, appearance = "transparent", columnModel, config, icon = "settings", onDisplayAttributeChange, sentiment = "neutral", vuuTable, ...IconButtonProps })=>{
6
+ const { showTabbedTableConfigPanel } = useTabbedTableConfigPanel({
7
+ allowCreateCalculatedColumn,
8
+ columnModel,
9
+ config,
10
+ onDisplayAttributeChange,
11
+ vuuTable
12
+ });
13
+ const handleClick = useCallback(()=>{
14
+ showTabbedTableConfigPanel();
15
+ }, [
16
+ showTabbedTableConfigPanel
17
+ ]);
18
+ return /*#__PURE__*/ jsx(IconButton, {
19
+ ...IconButtonProps,
20
+ appearance: appearance,
21
+ "data-action": "table-settings",
22
+ icon: icon,
23
+ onClick: handleClick,
24
+ sentiment: sentiment,
25
+ size: 20
26
+ });
27
+ };
28
+ export { TabbedTableSettingsAction };
@@ -0,0 +1,29 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useCallback, useRef } from "react";
3
+ import { useContextPanel } from "@vuu-ui/vuu-ui-controls";
4
+ import { TabbedTableConfigPanel } from "./TabbedTableConfigPanel.js";
5
+ const useTabbedTableConfigPanel = ({ allowCreateCalculatedColumn, columnModel, config, onDisplayAttributeChange, vuuTable })=>{
6
+ const showContextPanel = useContextPanel();
7
+ const contextPanelShowing = useRef(false);
8
+ const showTabbedTableConfigPanel = useCallback((title = "Table settings")=>{
9
+ contextPanelShowing.current = true;
10
+ showContextPanel(/*#__PURE__*/ jsx(TabbedTableConfigPanel, {
11
+ allowCreateCalculatedColumn: allowCreateCalculatedColumn,
12
+ columnModel: columnModel,
13
+ config: config,
14
+ onDisplayAttributeChange: onDisplayAttributeChange,
15
+ vuuTable: vuuTable
16
+ }), title);
17
+ }, [
18
+ allowCreateCalculatedColumn,
19
+ columnModel,
20
+ config,
21
+ onDisplayAttributeChange,
22
+ showContextPanel,
23
+ vuuTable
24
+ ]);
25
+ return {
26
+ showTabbedTableConfigPanel
27
+ };
28
+ };
29
+ export { useTabbedTableConfigPanel };
@@ -0,0 +1,22 @@
1
+ const css = `
2
+ .vuuTableFooter {
3
+ background-color: var(--salt-container-secondary-background);
4
+ --table-footer-height: var(--vuuTableFooter-height, 32px);
5
+ flex: 0 0 var(--table-footer-height);
6
+ height: var(--table-footer-height);
7
+ grid-template: "panel-start panel-center panel-end"
8
+ / 1fr 1fr 1fr;
9
+ display: grid;
10
+
11
+ & .vuuTableFooterTray {
12
+ margin: 0 var(--salt-spacing-200);
13
+ grid-area: panel-end;
14
+ justify-self: end;
15
+ align-items: center;
16
+ display: flex;
17
+ }
18
+ }
19
+
20
+
21
+ `;
22
+ export default css;
@@ -0,0 +1,30 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import clsx from "clsx";
3
+ import { useComponentCssInjection } from "@salt-ds/styles";
4
+ import { useWindow } from "@salt-ds/window";
5
+ import TableFooter from "./TableFooter.css";
6
+ const classBase = "vuuTableFooter";
7
+ const TableFooterTray = ({ children })=>/*#__PURE__*/ jsx("div", {
8
+ className: `${classBase}Tray`,
9
+ children: children
10
+ });
11
+ const TableFooter_TableFooter = ({ children, className, onInvokeAction, tooltrayActions, ...htmlAttributes })=>{
12
+ const targetWindow = useWindow();
13
+ useComponentCssInjection({
14
+ testId: "vuu-table-footer",
15
+ css: TableFooter,
16
+ window: targetWindow
17
+ });
18
+ return /*#__PURE__*/ jsxs("div", {
19
+ ...htmlAttributes,
20
+ className: clsx(classBase, className),
21
+ children: [
22
+ children,
23
+ tooltrayActions ? /*#__PURE__*/ jsx("div", {
24
+ className: `${classBase}-tooltray`,
25
+ children: tooltrayActions
26
+ }) : null
27
+ ]
28
+ });
29
+ };
30
+ export { TableFooterTray, TableFooter_TableFooter as TableFooter };
@@ -0,0 +1,33 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext } from "react";
3
+ const NullMenuActionHandler = (menuItemId)=>{
4
+ console.log(`[TableContext] no menu action handler installed (menuItemHandler invoked with ${menuItemId})`);
5
+ return false;
6
+ };
7
+ const NullDataSource = {};
8
+ const TableContext = /*#__PURE__*/ createContext({
9
+ dataSource: NullDataSource,
10
+ menuActionHandler: NullMenuActionHandler
11
+ });
12
+ const TableProvider = ({ children, dataSource, menuActionHandler, rowActionHandlers })=>/*#__PURE__*/ jsx(TableContext.Provider, {
13
+ value: {
14
+ dataSource,
15
+ menuActionHandler,
16
+ rowActionHandlers
17
+ },
18
+ children: children
19
+ });
20
+ function useTableContext(throwIfNoDataSource = false) {
21
+ const { dataSource, menuActionHandler } = useContext(TableContext);
22
+ if (dataSource !== NullDataSource || menuActionHandler != NullMenuActionHandler || !throwIfNoDataSource) return {
23
+ dataSource,
24
+ menuActionHandler
25
+ };
26
+ throw Error("[TableProvider] no DataSourceProvider has been declared");
27
+ }
28
+ const useRowAction = (actionId)=>{
29
+ const { rowActionHandlers } = useContext(TableContext);
30
+ if (rowActionHandlers?.[actionId]) return rowActionHandlers[actionId];
31
+ throw Error(`[TableProvider] useRowAction, no action configured #${actionId}`);
32
+ };
33
+ export { TableContext, TableProvider, useRowAction, useTableContext };