@vuu-ui/vuu-table-extras 0.13.30 → 0.13.32

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.
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var dataSourceStats = ".vuuDatasourceStats {\n display: flex;\n font-size: 10px;\n gap: var(--salt-spacing-100);\n padding: 4px 0 0 12px;\n}\n\n.vuuDatasourceStats-label {\n color: var(--salt-content-secondary-foreground);\n}\n";
3
+ var dataSourceStats = ".vuuDatasourceStats {\n align-items: center;\n display: grid;\n font-size: var(--vuuDatasourceStats-fontSize, 10px);\n gap: var(--vuuDatasourceStats-gap, var(--salt-spacing-100));\n grid-template-areas: \"panel-start panel-center panel-end\";\n grid-template-columns: 1fr 1fr 1fr;\n grid-template-rows: auto;\n height: var(--vuuDatasourceStats-height, 100%);\n padding: 0 var(--salt-spacing-200);\n\n .vuuDatasourceStats-statsPanel {\n align-items: center;\n display: flex;\n gap: var(--salt-spacing-100);\n width: fit-content;\n }\n\n .vuuDatasourceStats-rowStats {\n justify-self: flex-start;\n grid-area: panel-start;\n }\n .vuuDatasourceStats-freezeStatus {\n justify-self: flex-start;\n grid-area: panel-start;\n }\n .vuuDatasourceStats-selectionStats {\n justify-self: center;\n grid-area: panel-center;\n }\n\n.vuuDatasourceStats-label {\n color: var(--salt-content-secondary-foreground);\n}\n\n.vuuDatasourceStats-value {\n color: var(--salt-content-primary-foreground);\n}\n.vuuDatasourceStats-actions {\n margin: 0 var(--salt-spacing-200);\n}\n\n}\n\n";
4
4
 
5
5
  module.exports = dataSourceStats;
6
6
  //# sourceMappingURL=DatasourceStats.css.js.map
@@ -4,23 +4,27 @@ var jsxRuntime = require('react/jsx-runtime');
4
4
  var cx = require('clsx');
5
5
  var styles = require('@salt-ds/styles');
6
6
  var window = require('@salt-ds/window');
7
- var react = require('react');
8
7
  var DatasourceStats = require('./DatasourceStats.css.js');
9
- var vuuUtils = require('@vuu-ui/vuu-utils');
8
+ var useDatasourceStats = require('./useDatasourceStats.js');
10
9
 
11
10
  const classBase = "vuuDatasourceStats";
12
11
  const numberFormatter = new Intl.NumberFormat();
13
- const timeFormatter = vuuUtils.formatDate({ time: "hh:mm:ss" });
14
- const formatTime = (ts) => {
15
- if (typeof ts === "number") {
16
- return timeFormatter(new Date(ts));
12
+ const getLabel = (label, count = 1) => {
13
+ if (count === 1) {
14
+ return typeof label === "string" ? label : label.singlular;
17
15
  } else {
18
- return void 0;
16
+ return typeof label === "string" ? `${label}s` : label.plural;
19
17
  }
20
18
  };
21
19
  const DataSourceStats = ({
22
- className: classNameProp,
23
- dataSource
20
+ children,
21
+ className,
22
+ dataSource,
23
+ itemLabel = "row",
24
+ showFreezeStatus = true,
25
+ showRowStats = true,
26
+ showSelectionStats = true,
27
+ ...htmlAttributes
24
28
  }) => {
25
29
  const targetWindow = window.useWindow();
26
30
  styles.useComponentCssInjection({
@@ -28,54 +32,64 @@ const DataSourceStats = ({
28
32
  css: DatasourceStats,
29
33
  window: targetWindow
30
34
  });
31
- const [range, setRange] = react.useState(dataSource.range);
32
- const [size, setSize] = react.useState(dataSource.size);
33
- const [freezeTime, setFreezeTime] = react.useState(
34
- formatTime(dataSource.freezeTimestamp)
35
- );
36
- const handleFreeze = react.useCallback(
37
- (isFrozen, freezeTimestamp) => {
38
- console.log(`DatasourceStats isFrozen ${isFrozen}`);
39
- if (isFrozen) {
40
- setFreezeTime(formatTime(freezeTimestamp));
41
- } else {
42
- setFreezeTime(void 0);
43
- }
44
- },
45
- []
46
- );
47
- react.useEffect(() => {
48
- setSize(dataSource.size);
49
- dataSource.on("resize", setSize);
50
- dataSource.on("range", setRange);
51
- dataSource.on("freeze", handleFreeze);
52
- return () => {
53
- dataSource.removeListener("resize", setSize);
54
- dataSource.removeListener("range", setRange);
55
- };
56
- }, [dataSource, handleFreeze]);
57
- const className = cx(classBase, classNameProp);
35
+ const { freezeTime, range, selectedCount, size } = useDatasourceStats.useDatasourceStats({
36
+ dataSource,
37
+ showFreezeStatus,
38
+ showRowStats,
39
+ showSelectionStats
40
+ });
58
41
  const from = numberFormatter.format(range.firstRowInViewport);
59
- const to = numberFormatter.format(range.lastRowInViewport);
42
+ const to = numberFormatter.format(Math.min(range.lastRowInViewport, size));
60
43
  const value = numberFormatter.format(size);
44
+ const showSelection = showSelectionStats && selectedCount > 0;
61
45
  if (size === 0) {
62
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-label`, children: "No Rows to display" }) });
46
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ...htmlAttributes, className: cx(classBase, className), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-label`, children: "No Rows to display" }) });
63
47
  } else {
64
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
65
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-label`, children: "Rows" }),
66
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-range`, children: from }),
67
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "-" }),
68
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-range`, children: to }),
69
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "of" }),
70
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-size`, children: value }),
71
- freezeTime !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
72
- "span",
73
- {
74
- className: `${classBase}-label`,
75
- children: `(frozen at ${freezeTime})`
76
- }
77
- ) : null
78
- ] });
48
+ return /* @__PURE__ */ jsxRuntime.jsxs(
49
+ "div",
50
+ {
51
+ ...htmlAttributes,
52
+ className: cx(classBase, className, {
53
+ [`${classBase}-withSelection`]: showSelection
54
+ }),
55
+ children: [
56
+ showRowStats ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${classBase}-statsPanel ${classBase}-rowStats`, children: [
57
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-label`, children: "Row count" }),
58
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${classBase}-range`, children: [
59
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-value`, children: from }),
60
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-label`, children: "-" }),
61
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-value`, children: to })
62
+ ] }),
63
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-label`, children: "of" }),
64
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-value`, children: value })
65
+ ] }) : null,
66
+ showFreezeStatus && freezeTime !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${classBase}-statsPanel ${classBase}-freezeStatus`, children: /* @__PURE__ */ jsxRuntime.jsx(
67
+ "span",
68
+ {
69
+ className: `${classBase}-label`,
70
+ children: `(frozen at ${freezeTime})`
71
+ }
72
+ ) }) : null,
73
+ showSelection ? /* @__PURE__ */ jsxRuntime.jsxs(
74
+ "div",
75
+ {
76
+ className: `${classBase}-statsPanel ${classBase}-selectionStats`,
77
+ children: [
78
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-value`, children: selectedCount }),
79
+ /* @__PURE__ */ jsxRuntime.jsx(
80
+ "span",
81
+ {
82
+ className: `${classBase}-label`,
83
+ children: `selected ${getLabel(itemLabel, selectedCount)}`
84
+ }
85
+ ),
86
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-actions`, children })
87
+ ]
88
+ }
89
+ ) : null
90
+ ]
91
+ }
92
+ );
79
93
  }
80
94
  };
81
95
 
@@ -1 +1 @@
1
- {"version":3,"file":"DatasourceStats.js","sources":["../../../../packages/vuu-table-extras/src/datasource-stats/DatasourceStats.tsx"],"sourcesContent":["import { DataSource } from \"@vuu-ui/vuu-data-types\";\nimport cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { HTMLAttributes, useCallback, useEffect, useState } from \"react\";\n\nimport dataSourceStats from \"./DatasourceStats.css\";\nimport { formatDate, Range } from \"@vuu-ui/vuu-utils\";\n\ninterface DataSourceStatsProps extends HTMLAttributes<HTMLSpanElement> {\n dataSource: DataSource;\n}\n\nconst classBase = \"vuuDatasourceStats\";\n\nconst numberFormatter = new Intl.NumberFormat();\nconst timeFormatter = formatDate({ time: \"hh:mm:ss\" });\n\nconst formatTime = (ts: number | undefined) => {\n if (typeof ts === \"number\") {\n return timeFormatter(new Date(ts));\n } else {\n return undefined;\n }\n};\n\nexport const DataSourceStats = ({\n className: classNameProp,\n dataSource,\n}: DataSourceStatsProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-datasource-stats\",\n css: dataSourceStats,\n window: targetWindow,\n });\n\n const [range, setRange] = useState<Range>(dataSource.range);\n const [size, setSize] = useState(dataSource.size);\n const [freezeTime, setFreezeTime] = useState(\n formatTime(dataSource.freezeTimestamp),\n );\n\n const handleFreeze = useCallback(\n (isFrozen: boolean, freezeTimestamp: number) => {\n console.log(`DatasourceStats isFrozen ${isFrozen}`);\n if (isFrozen) {\n setFreezeTime(formatTime(freezeTimestamp));\n } else {\n setFreezeTime(undefined);\n }\n },\n [],\n );\n\n useEffect(() => {\n setSize(dataSource.size);\n dataSource.on(\"resize\", setSize);\n dataSource.on(\"range\", setRange);\n dataSource.on(\"freeze\", handleFreeze);\n return () => {\n dataSource.removeListener(\"resize\", setSize);\n dataSource.removeListener(\"range\", setRange);\n };\n }, [dataSource, handleFreeze]);\n\n const className = cx(classBase, classNameProp);\n const from = numberFormatter.format(range.firstRowInViewport);\n const to = numberFormatter.format(range.lastRowInViewport);\n const value = numberFormatter.format(size);\n\n if (size === 0) {\n return (\n <div className={className}>\n <span className={`${classBase}-label`}>No Rows to display</span>\n </div>\n );\n } else {\n return (\n <div className={className}>\n <span className={`${classBase}-label`}>Rows</span>\n <span className={`${classBase}-range`}>{from}</span>\n <span>-</span>\n <span className={`${classBase}-range`}>{to}</span>\n <span>of</span>\n <span className={`${classBase}-size`}>{value}</span>\n {freezeTime !== undefined ? (\n <span\n className={`${classBase}-label`}\n >{`(frozen at ${freezeTime})`}</span>\n ) : null}\n </div>\n );\n }\n};\n"],"names":["formatDate","useWindow","useComponentCssInjection","dataSourceStats","useState","useCallback","useEffect","jsx","jsxs"],"mappings":"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"}
1
+ {"version":3,"file":"DatasourceStats.js","sources":["../../../../packages/vuu-table-extras/src/datasource-stats/DatasourceStats.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { HTMLAttributes, ReactNode } from \"react\";\n\nimport dataSourceStats from \"./DatasourceStats.css\";\nimport {\n DatasourceStatsHookProps,\n useDatasourceStats,\n} from \"./useDatasourceStats\";\n\nexport type ItemLabel =\n | string\n | {\n singlular: string;\n plural: string;\n };\n\nexport interface DataSourceStatsProps\n extends DatasourceStatsHookProps,\n Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /**\n * children will be displayed when selection present. Intended\n * use case is display of action button(s) that will operate on\n * selected rows.\n */\n children?: ReactNode;\n /**\n * Label will be used in display of selected row count, e.g\n * '6 trades selected', where 'trade' is the itemLabel, will\n * default to 'row'\n */\n itemLabel?: ItemLabel;\n}\n\nconst classBase = \"vuuDatasourceStats\";\n\nconst numberFormatter = new Intl.NumberFormat();\n\nconst getLabel = (label: ItemLabel, count = 1) => {\n if (count === 1) {\n return typeof label === \"string\" ? label : label.singlular;\n } else {\n return typeof label === \"string\" ? `${label}s` : label.plural;\n }\n};\n\nexport const DataSourceStats = ({\n children,\n className,\n dataSource,\n itemLabel = \"row\",\n showFreezeStatus = true,\n showRowStats = true,\n showSelectionStats = true,\n ...htmlAttributes\n}: DataSourceStatsProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-datasource-stats\",\n css: dataSourceStats,\n window: targetWindow,\n });\n\n const { freezeTime, range, selectedCount, size } = useDatasourceStats({\n dataSource,\n showFreezeStatus,\n showRowStats,\n showSelectionStats,\n });\n\n const from = numberFormatter.format(range.firstRowInViewport);\n const to = numberFormatter.format(Math.min(range.lastRowInViewport, size));\n const value = numberFormatter.format(size);\n const showSelection = showSelectionStats && selectedCount > 0;\n\n if (size === 0) {\n return (\n <div {...htmlAttributes} className={cx(classBase, className)}>\n <span className={`${classBase}-label`}>No Rows to display</span>\n </div>\n );\n } else {\n return (\n <div\n {...htmlAttributes}\n className={cx(classBase, className, {\n [`${classBase}-withSelection`]: showSelection,\n })}\n >\n {showRowStats ? (\n <div className={`${classBase}-statsPanel ${classBase}-rowStats`}>\n <span className={`${classBase}-label`}>Row count</span>\n <span className={`${classBase}-range`}>\n <span className={`${classBase}-value`}>{from}</span>\n <span className={`${classBase}-label`}>-</span>\n <span className={`${classBase}-value`}>{to}</span>\n </span>\n <span className={`${classBase}-label`}>of</span>\n <span className={`${classBase}-value`}>{value}</span>\n </div>\n ) : null}\n {showFreezeStatus && freezeTime !== undefined ? (\n <div className={`${classBase}-statsPanel ${classBase}-freezeStatus`}>\n <span\n className={`${classBase}-label`}\n >{`(frozen at ${freezeTime})`}</span>\n </div>\n ) : null}\n {showSelection ? (\n <div\n className={`${classBase}-statsPanel ${classBase}-selectionStats`}\n >\n <span className={`${classBase}-value`}>{selectedCount}</span>\n <span\n className={`${classBase}-label`}\n >{`selected ${getLabel(itemLabel, selectedCount)}`}</span>\n <span className={`${classBase}-actions`}>{children}</span>\n </div>\n ) : null}\n </div>\n );\n }\n};\n"],"names":["useWindow","useComponentCssInjection","dataSourceStats","useDatasourceStats","jsx","jsxs"],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ 'use strict';
2
+
3
+ var vuuUtils = require('@vuu-ui/vuu-utils');
4
+ var react = require('react');
5
+
6
+ const timeFormatter = vuuUtils.formatDate({ time: "hh:mm:ss" });
7
+ const formatTime = (ts) => {
8
+ if (typeof ts === "number") {
9
+ return timeFormatter(new Date(ts));
10
+ } else {
11
+ return void 0;
12
+ }
13
+ };
14
+ const useDatasourceStats = ({
15
+ dataSource
16
+ }) => {
17
+ const [selectedCount, setSelectedCount] = react.useState(0);
18
+ const [range, setRange] = react.useState(dataSource.range);
19
+ const [size, setSize] = react.useState(dataSource.size);
20
+ const [freezeTime, setFreezeTime] = react.useState(
21
+ formatTime(dataSource.freezeTimestamp)
22
+ );
23
+ const handleFreeze = react.useCallback(
24
+ (isFrozen, freezeTimestamp) => {
25
+ if (isFrozen) {
26
+ setFreezeTime(formatTime(freezeTimestamp));
27
+ } else {
28
+ setFreezeTime(void 0);
29
+ }
30
+ },
31
+ []
32
+ );
33
+ const handleRowSelection = react.useCallback(
34
+ (_, count) => {
35
+ setSelectedCount(count);
36
+ },
37
+ []
38
+ );
39
+ const handleSize = react.useCallback((size2) => {
40
+ setSize(size2);
41
+ }, []);
42
+ react.useMemo(() => {
43
+ setSize(dataSource.size);
44
+ dataSource.on("resize", handleSize);
45
+ dataSource.on("range", setRange);
46
+ dataSource.on("freeze", handleFreeze);
47
+ dataSource.on("row-selection", handleRowSelection);
48
+ return () => {
49
+ dataSource.removeListener("resize", handleSize);
50
+ dataSource.removeListener("range", setRange);
51
+ dataSource.removeListener("freeze", handleFreeze);
52
+ dataSource.removeListener("row-selection", handleRowSelection);
53
+ };
54
+ }, [dataSource, handleFreeze, handleRowSelection, handleSize]);
55
+ return {
56
+ range,
57
+ selectedCount,
58
+ size,
59
+ freezeTime
60
+ };
61
+ };
62
+
63
+ exports.useDatasourceStats = useDatasourceStats;
64
+ //# sourceMappingURL=useDatasourceStats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDatasourceStats.js","sources":["../../../../packages/vuu-table-extras/src/datasource-stats/useDatasourceStats.ts"],"sourcesContent":["import { DataSource, RowSelectionEventHandler } from \"@vuu-ui/vuu-data-types\";\nimport { formatDate, Range } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useMemo, useState } from \"react\";\n\nexport interface DatasourceStatsHookProps {\n dataSource: DataSource;\n showFreezeStatus?: boolean;\n showRowStats?: boolean;\n showSelectionStats?: boolean;\n}\n\nconst timeFormatter = formatDate({ time: \"hh:mm:ss\" });\n\nconst formatTime = (ts: number | undefined) => {\n if (typeof ts === \"number\") {\n return timeFormatter(new Date(ts));\n } else {\n return undefined;\n }\n};\n\nexport const useDatasourceStats = ({\n dataSource,\n}: DatasourceStatsHookProps) => {\n const [selectedCount, setSelectedCount] = useState(0);\n const [range, setRange] = useState<Range>(dataSource.range);\n const [size, setSize] = useState(dataSource.size);\n const [freezeTime, setFreezeTime] = useState(\n formatTime(dataSource.freezeTimestamp),\n );\n\n const handleFreeze = useCallback(\n (isFrozen: boolean, freezeTimestamp: number) => {\n if (isFrozen) {\n setFreezeTime(formatTime(freezeTimestamp));\n } else {\n setFreezeTime(undefined);\n }\n },\n [],\n );\n\n const handleRowSelection = useCallback<RowSelectionEventHandler>(\n (_, count) => {\n setSelectedCount(count);\n },\n [],\n );\n\n const handleSize = useCallback((size: number) => {\n setSize(size);\n }, []);\n\n useMemo(() => {\n setSize(dataSource.size);\n dataSource.on(\"resize\", handleSize);\n dataSource.on(\"range\", setRange);\n dataSource.on(\"freeze\", handleFreeze);\n dataSource.on(\"row-selection\", handleRowSelection);\n return () => {\n dataSource.removeListener(\"resize\", handleSize);\n dataSource.removeListener(\"range\", setRange);\n dataSource.removeListener(\"freeze\", handleFreeze);\n dataSource.removeListener(\"row-selection\", handleRowSelection);\n };\n }, [dataSource, handleFreeze, handleRowSelection, handleSize]);\n\n return {\n range,\n selectedCount,\n size,\n freezeTime,\n };\n};\n"],"names":["formatDate","useState","useCallback","size","useMemo"],"mappings":";;;;;AAWA,MAAM,aAAgB,GAAAA,mBAAA,CAAW,EAAE,IAAA,EAAM,YAAY,CAAA;AAErD,MAAM,UAAA,GAAa,CAAC,EAA2B,KAAA;AAC7C,EAAI,IAAA,OAAO,OAAO,QAAU,EAAA;AAC1B,IAAA,OAAO,aAAc,CAAA,IAAI,IAAK,CAAA,EAAE,CAAC,CAAA;AAAA,GAC5B,MAAA;AACL,IAAO,OAAA,KAAA,CAAA;AAAA;AAEX,CAAA;AAEO,MAAM,qBAAqB,CAAC;AAAA,EACjC;AACF,CAAgC,KAAA;AAC9B,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAIC,eAAS,CAAC,CAAA;AACpD,EAAA,MAAM,CAAC,KAAO,EAAA,QAAQ,CAAI,GAAAA,cAAA,CAAgB,WAAW,KAAK,CAAA;AAC1D,EAAA,MAAM,CAAC,IAAM,EAAA,OAAO,CAAI,GAAAA,cAAA,CAAS,WAAW,IAAI,CAAA;AAChD,EAAM,MAAA,CAAC,UAAY,EAAA,aAAa,CAAI,GAAAA,cAAA;AAAA,IAClC,UAAA,CAAW,WAAW,eAAe;AAAA,GACvC;AAEA,EAAA,MAAM,YAAe,GAAAC,iBAAA;AAAA,IACnB,CAAC,UAAmB,eAA4B,KAAA;AAC9C,MAAA,IAAI,QAAU,EAAA;AACZ,QAAc,aAAA,CAAA,UAAA,CAAW,eAAe,CAAC,CAAA;AAAA,OACpC,MAAA;AACL,QAAA,aAAA,CAAc,KAAS,CAAA,CAAA;AAAA;AACzB,KACF;AAAA,IACA;AAAC,GACH;AAEA,EAAA,MAAM,kBAAqB,GAAAA,iBAAA;AAAA,IACzB,CAAC,GAAG,KAAU,KAAA;AACZ,MAAA,gBAAA,CAAiB,KAAK,CAAA;AAAA,KACxB;AAAA,IACA;AAAC,GACH;AAEA,EAAM,MAAA,UAAA,GAAaA,iBAAY,CAAA,CAACC,KAAiB,KAAA;AAC/C,IAAA,OAAA,CAAQA,KAAI,CAAA;AAAA,GACd,EAAG,EAAE,CAAA;AAEL,EAAAC,aAAA,CAAQ,MAAM;AACZ,IAAA,OAAA,CAAQ,WAAW,IAAI,CAAA;AACvB,IAAW,UAAA,CAAA,EAAA,CAAG,UAAU,UAAU,CAAA;AAClC,IAAW,UAAA,CAAA,EAAA,CAAG,SAAS,QAAQ,CAAA;AAC/B,IAAW,UAAA,CAAA,EAAA,CAAG,UAAU,YAAY,CAAA;AACpC,IAAW,UAAA,CAAA,EAAA,CAAG,iBAAiB,kBAAkB,CAAA;AACjD,IAAA,OAAO,MAAM;AACX,MAAW,UAAA,CAAA,cAAA,CAAe,UAAU,UAAU,CAAA;AAC9C,MAAW,UAAA,CAAA,cAAA,CAAe,SAAS,QAAQ,CAAA;AAC3C,MAAW,UAAA,CAAA,cAAA,CAAe,UAAU,YAAY,CAAA;AAChD,MAAW,UAAA,CAAA,cAAA,CAAe,iBAAiB,kBAAkB,CAAA;AAAA,KAC/D;AAAA,KACC,CAAC,UAAA,EAAY,YAAc,EAAA,kBAAA,EAAoB,UAAU,CAAC,CAAA;AAE7D,EAAO,OAAA;AAAA,IACL,KAAA;AAAA,IACA,aAAA;AAAA,IACA,IAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
@@ -1,4 +1,4 @@
1
- var dataSourceStats = ".vuuDatasourceStats {\n display: flex;\n font-size: 10px;\n gap: var(--salt-spacing-100);\n padding: 4px 0 0 12px;\n}\n\n.vuuDatasourceStats-label {\n color: var(--salt-content-secondary-foreground);\n}\n";
1
+ var dataSourceStats = ".vuuDatasourceStats {\n align-items: center;\n display: grid;\n font-size: var(--vuuDatasourceStats-fontSize, 10px);\n gap: var(--vuuDatasourceStats-gap, var(--salt-spacing-100));\n grid-template-areas: \"panel-start panel-center panel-end\";\n grid-template-columns: 1fr 1fr 1fr;\n grid-template-rows: auto;\n height: var(--vuuDatasourceStats-height, 100%);\n padding: 0 var(--salt-spacing-200);\n\n .vuuDatasourceStats-statsPanel {\n align-items: center;\n display: flex;\n gap: var(--salt-spacing-100);\n width: fit-content;\n }\n\n .vuuDatasourceStats-rowStats {\n justify-self: flex-start;\n grid-area: panel-start;\n }\n .vuuDatasourceStats-freezeStatus {\n justify-self: flex-start;\n grid-area: panel-start;\n }\n .vuuDatasourceStats-selectionStats {\n justify-self: center;\n grid-area: panel-center;\n }\n\n.vuuDatasourceStats-label {\n color: var(--salt-content-secondary-foreground);\n}\n\n.vuuDatasourceStats-value {\n color: var(--salt-content-primary-foreground);\n}\n.vuuDatasourceStats-actions {\n margin: 0 var(--salt-spacing-200);\n}\n\n}\n\n";
2
2
 
3
3
  export { dataSourceStats as default };
4
4
  //# sourceMappingURL=DatasourceStats.css.js.map
@@ -2,23 +2,27 @@ import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import cx from 'clsx';
3
3
  import { useComponentCssInjection } from '@salt-ds/styles';
4
4
  import { useWindow } from '@salt-ds/window';
5
- import { useState, useCallback, useEffect } from 'react';
6
5
  import dataSourceStats from './DatasourceStats.css.js';
7
- import { formatDate } from '@vuu-ui/vuu-utils';
6
+ import { useDatasourceStats } from './useDatasourceStats.js';
8
7
 
9
8
  const classBase = "vuuDatasourceStats";
10
9
  const numberFormatter = new Intl.NumberFormat();
11
- const timeFormatter = formatDate({ time: "hh:mm:ss" });
12
- const formatTime = (ts) => {
13
- if (typeof ts === "number") {
14
- return timeFormatter(new Date(ts));
10
+ const getLabel = (label, count = 1) => {
11
+ if (count === 1) {
12
+ return typeof label === "string" ? label : label.singlular;
15
13
  } else {
16
- return void 0;
14
+ return typeof label === "string" ? `${label}s` : label.plural;
17
15
  }
18
16
  };
19
17
  const DataSourceStats = ({
20
- className: classNameProp,
21
- dataSource
18
+ children,
19
+ className,
20
+ dataSource,
21
+ itemLabel = "row",
22
+ showFreezeStatus = true,
23
+ showRowStats = true,
24
+ showSelectionStats = true,
25
+ ...htmlAttributes
22
26
  }) => {
23
27
  const targetWindow = useWindow();
24
28
  useComponentCssInjection({
@@ -26,54 +30,64 @@ const DataSourceStats = ({
26
30
  css: dataSourceStats,
27
31
  window: targetWindow
28
32
  });
29
- const [range, setRange] = useState(dataSource.range);
30
- const [size, setSize] = useState(dataSource.size);
31
- const [freezeTime, setFreezeTime] = useState(
32
- formatTime(dataSource.freezeTimestamp)
33
- );
34
- const handleFreeze = useCallback(
35
- (isFrozen, freezeTimestamp) => {
36
- console.log(`DatasourceStats isFrozen ${isFrozen}`);
37
- if (isFrozen) {
38
- setFreezeTime(formatTime(freezeTimestamp));
39
- } else {
40
- setFreezeTime(void 0);
41
- }
42
- },
43
- []
44
- );
45
- useEffect(() => {
46
- setSize(dataSource.size);
47
- dataSource.on("resize", setSize);
48
- dataSource.on("range", setRange);
49
- dataSource.on("freeze", handleFreeze);
50
- return () => {
51
- dataSource.removeListener("resize", setSize);
52
- dataSource.removeListener("range", setRange);
53
- };
54
- }, [dataSource, handleFreeze]);
55
- const className = cx(classBase, classNameProp);
33
+ const { freezeTime, range, selectedCount, size } = useDatasourceStats({
34
+ dataSource,
35
+ showFreezeStatus,
36
+ showRowStats,
37
+ showSelectionStats
38
+ });
56
39
  const from = numberFormatter.format(range.firstRowInViewport);
57
- const to = numberFormatter.format(range.lastRowInViewport);
40
+ const to = numberFormatter.format(Math.min(range.lastRowInViewport, size));
58
41
  const value = numberFormatter.format(size);
42
+ const showSelection = showSelectionStats && selectedCount > 0;
59
43
  if (size === 0) {
60
- return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsx("span", { className: `${classBase}-label`, children: "No Rows to display" }) });
44
+ return /* @__PURE__ */ jsx("div", { ...htmlAttributes, className: cx(classBase, className), children: /* @__PURE__ */ jsx("span", { className: `${classBase}-label`, children: "No Rows to display" }) });
61
45
  } else {
62
- return /* @__PURE__ */ jsxs("div", { className, children: [
63
- /* @__PURE__ */ jsx("span", { className: `${classBase}-label`, children: "Rows" }),
64
- /* @__PURE__ */ jsx("span", { className: `${classBase}-range`, children: from }),
65
- /* @__PURE__ */ jsx("span", { children: "-" }),
66
- /* @__PURE__ */ jsx("span", { className: `${classBase}-range`, children: to }),
67
- /* @__PURE__ */ jsx("span", { children: "of" }),
68
- /* @__PURE__ */ jsx("span", { className: `${classBase}-size`, children: value }),
69
- freezeTime !== void 0 ? /* @__PURE__ */ jsx(
70
- "span",
71
- {
72
- className: `${classBase}-label`,
73
- children: `(frozen at ${freezeTime})`
74
- }
75
- ) : null
76
- ] });
46
+ return /* @__PURE__ */ jsxs(
47
+ "div",
48
+ {
49
+ ...htmlAttributes,
50
+ className: cx(classBase, className, {
51
+ [`${classBase}-withSelection`]: showSelection
52
+ }),
53
+ children: [
54
+ showRowStats ? /* @__PURE__ */ jsxs("div", { className: `${classBase}-statsPanel ${classBase}-rowStats`, children: [
55
+ /* @__PURE__ */ jsx("span", { className: `${classBase}-label`, children: "Row count" }),
56
+ /* @__PURE__ */ jsxs("span", { className: `${classBase}-range`, children: [
57
+ /* @__PURE__ */ jsx("span", { className: `${classBase}-value`, children: from }),
58
+ /* @__PURE__ */ jsx("span", { className: `${classBase}-label`, children: "-" }),
59
+ /* @__PURE__ */ jsx("span", { className: `${classBase}-value`, children: to })
60
+ ] }),
61
+ /* @__PURE__ */ jsx("span", { className: `${classBase}-label`, children: "of" }),
62
+ /* @__PURE__ */ jsx("span", { className: `${classBase}-value`, children: value })
63
+ ] }) : null,
64
+ showFreezeStatus && freezeTime !== void 0 ? /* @__PURE__ */ jsx("div", { className: `${classBase}-statsPanel ${classBase}-freezeStatus`, children: /* @__PURE__ */ jsx(
65
+ "span",
66
+ {
67
+ className: `${classBase}-label`,
68
+ children: `(frozen at ${freezeTime})`
69
+ }
70
+ ) }) : null,
71
+ showSelection ? /* @__PURE__ */ jsxs(
72
+ "div",
73
+ {
74
+ className: `${classBase}-statsPanel ${classBase}-selectionStats`,
75
+ children: [
76
+ /* @__PURE__ */ jsx("span", { className: `${classBase}-value`, children: selectedCount }),
77
+ /* @__PURE__ */ jsx(
78
+ "span",
79
+ {
80
+ className: `${classBase}-label`,
81
+ children: `selected ${getLabel(itemLabel, selectedCount)}`
82
+ }
83
+ ),
84
+ /* @__PURE__ */ jsx("span", { className: `${classBase}-actions`, children })
85
+ ]
86
+ }
87
+ ) : null
88
+ ]
89
+ }
90
+ );
77
91
  }
78
92
  };
79
93
 
@@ -1 +1 @@
1
- {"version":3,"file":"DatasourceStats.js","sources":["../../../../packages/vuu-table-extras/src/datasource-stats/DatasourceStats.tsx"],"sourcesContent":["import { DataSource } from \"@vuu-ui/vuu-data-types\";\nimport cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { HTMLAttributes, useCallback, useEffect, useState } from \"react\";\n\nimport dataSourceStats from \"./DatasourceStats.css\";\nimport { formatDate, Range } from \"@vuu-ui/vuu-utils\";\n\ninterface DataSourceStatsProps extends HTMLAttributes<HTMLSpanElement> {\n dataSource: DataSource;\n}\n\nconst classBase = \"vuuDatasourceStats\";\n\nconst numberFormatter = new Intl.NumberFormat();\nconst timeFormatter = formatDate({ time: \"hh:mm:ss\" });\n\nconst formatTime = (ts: number | undefined) => {\n if (typeof ts === \"number\") {\n return timeFormatter(new Date(ts));\n } else {\n return undefined;\n }\n};\n\nexport const DataSourceStats = ({\n className: classNameProp,\n dataSource,\n}: DataSourceStatsProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-datasource-stats\",\n css: dataSourceStats,\n window: targetWindow,\n });\n\n const [range, setRange] = useState<Range>(dataSource.range);\n const [size, setSize] = useState(dataSource.size);\n const [freezeTime, setFreezeTime] = useState(\n formatTime(dataSource.freezeTimestamp),\n );\n\n const handleFreeze = useCallback(\n (isFrozen: boolean, freezeTimestamp: number) => {\n console.log(`DatasourceStats isFrozen ${isFrozen}`);\n if (isFrozen) {\n setFreezeTime(formatTime(freezeTimestamp));\n } else {\n setFreezeTime(undefined);\n }\n },\n [],\n );\n\n useEffect(() => {\n setSize(dataSource.size);\n dataSource.on(\"resize\", setSize);\n dataSource.on(\"range\", setRange);\n dataSource.on(\"freeze\", handleFreeze);\n return () => {\n dataSource.removeListener(\"resize\", setSize);\n dataSource.removeListener(\"range\", setRange);\n };\n }, [dataSource, handleFreeze]);\n\n const className = cx(classBase, classNameProp);\n const from = numberFormatter.format(range.firstRowInViewport);\n const to = numberFormatter.format(range.lastRowInViewport);\n const value = numberFormatter.format(size);\n\n if (size === 0) {\n return (\n <div className={className}>\n <span className={`${classBase}-label`}>No Rows to display</span>\n </div>\n );\n } else {\n return (\n <div className={className}>\n <span className={`${classBase}-label`}>Rows</span>\n <span className={`${classBase}-range`}>{from}</span>\n <span>-</span>\n <span className={`${classBase}-range`}>{to}</span>\n <span>of</span>\n <span className={`${classBase}-size`}>{value}</span>\n {freezeTime !== undefined ? (\n <span\n className={`${classBase}-label`}\n >{`(frozen at ${freezeTime})`}</span>\n ) : null}\n </div>\n );\n }\n};\n"],"names":[],"mappings":";;;;;;;;AAaA,MAAM,SAAY,GAAA,oBAAA;AAElB,MAAM,eAAA,GAAkB,IAAI,IAAA,CAAK,YAAa,EAAA;AAC9C,MAAM,aAAgB,GAAA,UAAA,CAAW,EAAE,IAAA,EAAM,YAAY,CAAA;AAErD,MAAM,UAAA,GAAa,CAAC,EAA2B,KAAA;AAC7C,EAAI,IAAA,OAAO,OAAO,QAAU,EAAA;AAC1B,IAAA,OAAO,aAAc,CAAA,IAAI,IAAK,CAAA,EAAE,CAAC,CAAA;AAAA,GAC5B,MAAA;AACL,IAAO,OAAA,KAAA,CAAA;AAAA;AAEX,CAAA;AAEO,MAAM,kBAAkB,CAAC;AAAA,EAC9B,SAAW,EAAA,aAAA;AAAA,EACX;AACF,CAA4B,KAAA;AAC1B,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,sBAAA;AAAA,IACR,GAAK,EAAA,eAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,MAAM,CAAC,KAAO,EAAA,QAAQ,CAAI,GAAA,QAAA,CAAgB,WAAW,KAAK,CAAA;AAC1D,EAAA,MAAM,CAAC,IAAM,EAAA,OAAO,CAAI,GAAA,QAAA,CAAS,WAAW,IAAI,CAAA;AAChD,EAAM,MAAA,CAAC,UAAY,EAAA,aAAa,CAAI,GAAA,QAAA;AAAA,IAClC,UAAA,CAAW,WAAW,eAAe;AAAA,GACvC;AAEA,EAAA,MAAM,YAAe,GAAA,WAAA;AAAA,IACnB,CAAC,UAAmB,eAA4B,KAAA;AAC9C,MAAQ,OAAA,CAAA,GAAA,CAAI,CAA4B,yBAAA,EAAA,QAAQ,CAAE,CAAA,CAAA;AAClD,MAAA,IAAI,QAAU,EAAA;AACZ,QAAc,aAAA,CAAA,UAAA,CAAW,eAAe,CAAC,CAAA;AAAA,OACpC,MAAA;AACL,QAAA,aAAA,CAAc,KAAS,CAAA,CAAA;AAAA;AACzB,KACF;AAAA,IACA;AAAC,GACH;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,OAAA,CAAQ,WAAW,IAAI,CAAA;AACvB,IAAW,UAAA,CAAA,EAAA,CAAG,UAAU,OAAO,CAAA;AAC/B,IAAW,UAAA,CAAA,EAAA,CAAG,SAAS,QAAQ,CAAA;AAC/B,IAAW,UAAA,CAAA,EAAA,CAAG,UAAU,YAAY,CAAA;AACpC,IAAA,OAAO,MAAM;AACX,MAAW,UAAA,CAAA,cAAA,CAAe,UAAU,OAAO,CAAA;AAC3C,MAAW,UAAA,CAAA,cAAA,CAAe,SAAS,QAAQ,CAAA;AAAA,KAC7C;AAAA,GACC,EAAA,CAAC,UAAY,EAAA,YAAY,CAAC,CAAA;AAE7B,EAAM,MAAA,SAAA,GAAY,EAAG,CAAA,SAAA,EAAW,aAAa,CAAA;AAC7C,EAAA,MAAM,IAAO,GAAA,eAAA,CAAgB,MAAO,CAAA,KAAA,CAAM,kBAAkB,CAAA;AAC5D,EAAA,MAAM,EAAK,GAAA,eAAA,CAAgB,MAAO,CAAA,KAAA,CAAM,iBAAiB,CAAA;AACzD,EAAM,MAAA,KAAA,GAAQ,eAAgB,CAAA,MAAA,CAAO,IAAI,CAAA;AAEzC,EAAA,IAAI,SAAS,CAAG,EAAA;AACd,IACE,uBAAA,GAAA,CAAC,KAAI,EAAA,EAAA,SAAA,EACH,QAAC,kBAAA,GAAA,CAAA,MAAA,EAAA,EAAK,WAAW,CAAG,EAAA,SAAS,CAAU,MAAA,CAAA,EAAA,QAAA,EAAA,oBAAA,EAAkB,CAC3D,EAAA,CAAA;AAAA,GAEG,MAAA;AACL,IACE,uBAAA,IAAA,CAAC,SAAI,SACH,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,MAAK,EAAA,EAAA,SAAA,EAAW,CAAG,EAAA,SAAS,UAAU,QAAI,EAAA,MAAA,EAAA,CAAA;AAAA,0BAC1C,MAAK,EAAA,EAAA,SAAA,EAAW,CAAG,EAAA,SAAS,UAAW,QAAK,EAAA,IAAA,EAAA,CAAA;AAAA,sBAC7C,GAAA,CAAC,UAAK,QAAC,EAAA,GAAA,EAAA,CAAA;AAAA,0BACN,MAAK,EAAA,EAAA,SAAA,EAAW,CAAG,EAAA,SAAS,UAAW,QAAG,EAAA,EAAA,EAAA,CAAA;AAAA,sBAC3C,GAAA,CAAC,UAAK,QAAE,EAAA,IAAA,EAAA,CAAA;AAAA,0BACP,MAAK,EAAA,EAAA,SAAA,EAAW,CAAG,EAAA,SAAS,SAAU,QAAM,EAAA,KAAA,EAAA,CAAA;AAAA,MAC5C,eAAe,KACd,CAAA,mBAAA,GAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAW,GAAG,SAAS,CAAA,MAAA,CAAA;AAAA,UACvB,wBAAc,UAAU,CAAA,CAAA;AAAA;AAAA,OACxB,GAAA;AAAA,KACN,EAAA,CAAA;AAAA;AAGN;;;;"}
1
+ {"version":3,"file":"DatasourceStats.js","sources":["../../../../packages/vuu-table-extras/src/datasource-stats/DatasourceStats.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { HTMLAttributes, ReactNode } from \"react\";\n\nimport dataSourceStats from \"./DatasourceStats.css\";\nimport {\n DatasourceStatsHookProps,\n useDatasourceStats,\n} from \"./useDatasourceStats\";\n\nexport type ItemLabel =\n | string\n | {\n singlular: string;\n plural: string;\n };\n\nexport interface DataSourceStatsProps\n extends DatasourceStatsHookProps,\n Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /**\n * children will be displayed when selection present. Intended\n * use case is display of action button(s) that will operate on\n * selected rows.\n */\n children?: ReactNode;\n /**\n * Label will be used in display of selected row count, e.g\n * '6 trades selected', where 'trade' is the itemLabel, will\n * default to 'row'\n */\n itemLabel?: ItemLabel;\n}\n\nconst classBase = \"vuuDatasourceStats\";\n\nconst numberFormatter = new Intl.NumberFormat();\n\nconst getLabel = (label: ItemLabel, count = 1) => {\n if (count === 1) {\n return typeof label === \"string\" ? label : label.singlular;\n } else {\n return typeof label === \"string\" ? `${label}s` : label.plural;\n }\n};\n\nexport const DataSourceStats = ({\n children,\n className,\n dataSource,\n itemLabel = \"row\",\n showFreezeStatus = true,\n showRowStats = true,\n showSelectionStats = true,\n ...htmlAttributes\n}: DataSourceStatsProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-datasource-stats\",\n css: dataSourceStats,\n window: targetWindow,\n });\n\n const { freezeTime, range, selectedCount, size } = useDatasourceStats({\n dataSource,\n showFreezeStatus,\n showRowStats,\n showSelectionStats,\n });\n\n const from = numberFormatter.format(range.firstRowInViewport);\n const to = numberFormatter.format(Math.min(range.lastRowInViewport, size));\n const value = numberFormatter.format(size);\n const showSelection = showSelectionStats && selectedCount > 0;\n\n if (size === 0) {\n return (\n <div {...htmlAttributes} className={cx(classBase, className)}>\n <span className={`${classBase}-label`}>No Rows to display</span>\n </div>\n );\n } else {\n return (\n <div\n {...htmlAttributes}\n className={cx(classBase, className, {\n [`${classBase}-withSelection`]: showSelection,\n })}\n >\n {showRowStats ? (\n <div className={`${classBase}-statsPanel ${classBase}-rowStats`}>\n <span className={`${classBase}-label`}>Row count</span>\n <span className={`${classBase}-range`}>\n <span className={`${classBase}-value`}>{from}</span>\n <span className={`${classBase}-label`}>-</span>\n <span className={`${classBase}-value`}>{to}</span>\n </span>\n <span className={`${classBase}-label`}>of</span>\n <span className={`${classBase}-value`}>{value}</span>\n </div>\n ) : null}\n {showFreezeStatus && freezeTime !== undefined ? (\n <div className={`${classBase}-statsPanel ${classBase}-freezeStatus`}>\n <span\n className={`${classBase}-label`}\n >{`(frozen at ${freezeTime})`}</span>\n </div>\n ) : null}\n {showSelection ? (\n <div\n className={`${classBase}-statsPanel ${classBase}-selectionStats`}\n >\n <span className={`${classBase}-value`}>{selectedCount}</span>\n <span\n className={`${classBase}-label`}\n >{`selected ${getLabel(itemLabel, selectedCount)}`}</span>\n <span className={`${classBase}-actions`}>{children}</span>\n </div>\n ) : null}\n </div>\n );\n }\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import { formatDate } from '@vuu-ui/vuu-utils';
2
+ import { useState, useCallback, useMemo } from 'react';
3
+
4
+ const timeFormatter = formatDate({ time: "hh:mm:ss" });
5
+ const formatTime = (ts) => {
6
+ if (typeof ts === "number") {
7
+ return timeFormatter(new Date(ts));
8
+ } else {
9
+ return void 0;
10
+ }
11
+ };
12
+ const useDatasourceStats = ({
13
+ dataSource
14
+ }) => {
15
+ const [selectedCount, setSelectedCount] = useState(0);
16
+ const [range, setRange] = useState(dataSource.range);
17
+ const [size, setSize] = useState(dataSource.size);
18
+ const [freezeTime, setFreezeTime] = useState(
19
+ formatTime(dataSource.freezeTimestamp)
20
+ );
21
+ const handleFreeze = useCallback(
22
+ (isFrozen, freezeTimestamp) => {
23
+ if (isFrozen) {
24
+ setFreezeTime(formatTime(freezeTimestamp));
25
+ } else {
26
+ setFreezeTime(void 0);
27
+ }
28
+ },
29
+ []
30
+ );
31
+ const handleRowSelection = useCallback(
32
+ (_, count) => {
33
+ setSelectedCount(count);
34
+ },
35
+ []
36
+ );
37
+ const handleSize = useCallback((size2) => {
38
+ setSize(size2);
39
+ }, []);
40
+ useMemo(() => {
41
+ setSize(dataSource.size);
42
+ dataSource.on("resize", handleSize);
43
+ dataSource.on("range", setRange);
44
+ dataSource.on("freeze", handleFreeze);
45
+ dataSource.on("row-selection", handleRowSelection);
46
+ return () => {
47
+ dataSource.removeListener("resize", handleSize);
48
+ dataSource.removeListener("range", setRange);
49
+ dataSource.removeListener("freeze", handleFreeze);
50
+ dataSource.removeListener("row-selection", handleRowSelection);
51
+ };
52
+ }, [dataSource, handleFreeze, handleRowSelection, handleSize]);
53
+ return {
54
+ range,
55
+ selectedCount,
56
+ size,
57
+ freezeTime
58
+ };
59
+ };
60
+
61
+ export { useDatasourceStats };
62
+ //# sourceMappingURL=useDatasourceStats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDatasourceStats.js","sources":["../../../../packages/vuu-table-extras/src/datasource-stats/useDatasourceStats.ts"],"sourcesContent":["import { DataSource, RowSelectionEventHandler } from \"@vuu-ui/vuu-data-types\";\nimport { formatDate, Range } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useMemo, useState } from \"react\";\n\nexport interface DatasourceStatsHookProps {\n dataSource: DataSource;\n showFreezeStatus?: boolean;\n showRowStats?: boolean;\n showSelectionStats?: boolean;\n}\n\nconst timeFormatter = formatDate({ time: \"hh:mm:ss\" });\n\nconst formatTime = (ts: number | undefined) => {\n if (typeof ts === \"number\") {\n return timeFormatter(new Date(ts));\n } else {\n return undefined;\n }\n};\n\nexport const useDatasourceStats = ({\n dataSource,\n}: DatasourceStatsHookProps) => {\n const [selectedCount, setSelectedCount] = useState(0);\n const [range, setRange] = useState<Range>(dataSource.range);\n const [size, setSize] = useState(dataSource.size);\n const [freezeTime, setFreezeTime] = useState(\n formatTime(dataSource.freezeTimestamp),\n );\n\n const handleFreeze = useCallback(\n (isFrozen: boolean, freezeTimestamp: number) => {\n if (isFrozen) {\n setFreezeTime(formatTime(freezeTimestamp));\n } else {\n setFreezeTime(undefined);\n }\n },\n [],\n );\n\n const handleRowSelection = useCallback<RowSelectionEventHandler>(\n (_, count) => {\n setSelectedCount(count);\n },\n [],\n );\n\n const handleSize = useCallback((size: number) => {\n setSize(size);\n }, []);\n\n useMemo(() => {\n setSize(dataSource.size);\n dataSource.on(\"resize\", handleSize);\n dataSource.on(\"range\", setRange);\n dataSource.on(\"freeze\", handleFreeze);\n dataSource.on(\"row-selection\", handleRowSelection);\n return () => {\n dataSource.removeListener(\"resize\", handleSize);\n dataSource.removeListener(\"range\", setRange);\n dataSource.removeListener(\"freeze\", handleFreeze);\n dataSource.removeListener(\"row-selection\", handleRowSelection);\n };\n }, [dataSource, handleFreeze, handleRowSelection, handleSize]);\n\n return {\n range,\n selectedCount,\n size,\n freezeTime,\n };\n};\n"],"names":["size"],"mappings":";;;AAWA,MAAM,aAAgB,GAAA,UAAA,CAAW,EAAE,IAAA,EAAM,YAAY,CAAA;AAErD,MAAM,UAAA,GAAa,CAAC,EAA2B,KAAA;AAC7C,EAAI,IAAA,OAAO,OAAO,QAAU,EAAA;AAC1B,IAAA,OAAO,aAAc,CAAA,IAAI,IAAK,CAAA,EAAE,CAAC,CAAA;AAAA,GAC5B,MAAA;AACL,IAAO,OAAA,KAAA,CAAA;AAAA;AAEX,CAAA;AAEO,MAAM,qBAAqB,CAAC;AAAA,EACjC;AACF,CAAgC,KAAA;AAC9B,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAI,SAAS,CAAC,CAAA;AACpD,EAAA,MAAM,CAAC,KAAO,EAAA,QAAQ,CAAI,GAAA,QAAA,CAAgB,WAAW,KAAK,CAAA;AAC1D,EAAA,MAAM,CAAC,IAAM,EAAA,OAAO,CAAI,GAAA,QAAA,CAAS,WAAW,IAAI,CAAA;AAChD,EAAM,MAAA,CAAC,UAAY,EAAA,aAAa,CAAI,GAAA,QAAA;AAAA,IAClC,UAAA,CAAW,WAAW,eAAe;AAAA,GACvC;AAEA,EAAA,MAAM,YAAe,GAAA,WAAA;AAAA,IACnB,CAAC,UAAmB,eAA4B,KAAA;AAC9C,MAAA,IAAI,QAAU,EAAA;AACZ,QAAc,aAAA,CAAA,UAAA,CAAW,eAAe,CAAC,CAAA;AAAA,OACpC,MAAA;AACL,QAAA,aAAA,CAAc,KAAS,CAAA,CAAA;AAAA;AACzB,KACF;AAAA,IACA;AAAC,GACH;AAEA,EAAA,MAAM,kBAAqB,GAAA,WAAA;AAAA,IACzB,CAAC,GAAG,KAAU,KAAA;AACZ,MAAA,gBAAA,CAAiB,KAAK,CAAA;AAAA,KACxB;AAAA,IACA;AAAC,GACH;AAEA,EAAM,MAAA,UAAA,GAAa,WAAY,CAAA,CAACA,KAAiB,KAAA;AAC/C,IAAA,OAAA,CAAQA,KAAI,CAAA;AAAA,GACd,EAAG,EAAE,CAAA;AAEL,EAAA,OAAA,CAAQ,MAAM;AACZ,IAAA,OAAA,CAAQ,WAAW,IAAI,CAAA;AACvB,IAAW,UAAA,CAAA,EAAA,CAAG,UAAU,UAAU,CAAA;AAClC,IAAW,UAAA,CAAA,EAAA,CAAG,SAAS,QAAQ,CAAA;AAC/B,IAAW,UAAA,CAAA,EAAA,CAAG,UAAU,YAAY,CAAA;AACpC,IAAW,UAAA,CAAA,EAAA,CAAG,iBAAiB,kBAAkB,CAAA;AACjD,IAAA,OAAO,MAAM;AACX,MAAW,UAAA,CAAA,cAAA,CAAe,UAAU,UAAU,CAAA;AAC9C,MAAW,UAAA,CAAA,cAAA,CAAe,SAAS,QAAQ,CAAA;AAC3C,MAAW,UAAA,CAAA,cAAA,CAAe,UAAU,YAAY,CAAA;AAChD,MAAW,UAAA,CAAA,cAAA,CAAe,iBAAiB,kBAAkB,CAAA;AAAA,KAC/D;AAAA,KACC,CAAC,UAAA,EAAY,YAAc,EAAA,kBAAA,EAAoB,UAAU,CAAC,CAAA;AAE7D,EAAO,OAAA;AAAA,IACL,KAAA;AAAA,IACA,aAAA;AAAA,IACA,IAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
package/package.json CHANGED
@@ -1,20 +1,20 @@
1
1
  {
2
- "version": "0.13.30",
2
+ "version": "0.13.32",
3
3
  "author": "heswell",
4
4
  "license": "Apache-2.0",
5
5
  "devDependencies": {
6
- "@vuu-ui/vuu-filter-types": "0.13.30",
7
- "@vuu-ui/vuu-protocol-types": "0.13.30"
6
+ "@vuu-ui/vuu-filter-types": "0.13.32",
7
+ "@vuu-ui/vuu-protocol-types": "0.13.32"
8
8
  },
9
9
  "dependencies": {
10
- "@vuu-ui/vuu-codemirror": "0.13.30",
11
- "@vuu-ui/vuu-data-react": "0.13.30",
12
- "@vuu-ui/vuu-data-types": "0.13.30",
13
- "@vuu-ui/vuu-table-types": "0.13.30",
14
- "@vuu-ui/vuu-popups": "0.13.30",
15
- "@vuu-ui/vuu-table": "0.13.30",
16
- "@vuu-ui/vuu-utils": "0.13.30",
17
- "@vuu-ui/vuu-ui-controls": "0.13.30",
10
+ "@vuu-ui/vuu-codemirror": "0.13.32",
11
+ "@vuu-ui/vuu-data-react": "0.13.32",
12
+ "@vuu-ui/vuu-data-types": "0.13.32",
13
+ "@vuu-ui/vuu-table-types": "0.13.32",
14
+ "@vuu-ui/vuu-popups": "0.13.32",
15
+ "@vuu-ui/vuu-table": "0.13.32",
16
+ "@vuu-ui/vuu-utils": "0.13.32",
17
+ "@vuu-ui/vuu-ui-controls": "0.13.32",
18
18
  "@lezer/lr": "1.4.2",
19
19
  "@salt-ds/core": "1.43.0",
20
20
  "@salt-ds/styles": "0.2.1",
@@ -1,7 +1,21 @@
1
- import { DataSource } from "@vuu-ui/vuu-data-types";
2
- import { HTMLAttributes } from "react";
3
- interface DataSourceStatsProps extends HTMLAttributes<HTMLSpanElement> {
4
- dataSource: DataSource;
1
+ import { HTMLAttributes, ReactNode } from "react";
2
+ import { DatasourceStatsHookProps } from "./useDatasourceStats";
3
+ export type ItemLabel = string | {
4
+ singlular: string;
5
+ plural: string;
6
+ };
7
+ export interface DataSourceStatsProps extends DatasourceStatsHookProps, Omit<HTMLAttributes<HTMLDivElement>, "children"> {
8
+ /**
9
+ * children will be displayed when selection present. Intended
10
+ * use case is display of action button(s) that will operate on
11
+ * selected rows.
12
+ */
13
+ children?: ReactNode;
14
+ /**
15
+ * Label will be used in display of selected row count, e.g
16
+ * '6 trades selected', where 'trade' is the itemLabel, will
17
+ * default to 'row'
18
+ */
19
+ itemLabel?: ItemLabel;
5
20
  }
6
- export declare const DataSourceStats: ({ className: classNameProp, dataSource, }: DataSourceStatsProps) => import("react/jsx-runtime").JSX.Element;
7
- export {};
21
+ export declare const DataSourceStats: ({ children, className, dataSource, itemLabel, showFreezeStatus, showRowStats, showSelectionStats, ...htmlAttributes }: DataSourceStatsProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,14 @@
1
+ import { DataSource } from "@vuu-ui/vuu-data-types";
2
+ import { Range } from "@vuu-ui/vuu-utils";
3
+ export interface DatasourceStatsHookProps {
4
+ dataSource: DataSource;
5
+ showFreezeStatus?: boolean;
6
+ showRowStats?: boolean;
7
+ showSelectionStats?: boolean;
8
+ }
9
+ export declare const useDatasourceStats: ({ dataSource, }: DatasourceStatsHookProps) => {
10
+ range: Range;
11
+ selectedCount: number;
12
+ size: number;
13
+ freezeTime: string | undefined;
14
+ };
package/types/index.d.ts CHANGED
@@ -12,7 +12,7 @@ export { columnSettingsFromColumnMenuPermissions, tableSettingsFromColumnMenuPer
12
12
  export * from "./column-expression-input";
13
13
  export * from "./column-expression-panel";
14
14
  export * from "./column-formatting-settings";
15
- export * from "./datasource-stats";
15
+ export { DataSourceStats, type DataSourceStatsProps, } from "./datasource-stats/DatasourceStats";
16
16
  export { TableProvider, useTableContext } from "./table-provider/TableProvider";
17
17
  export { FreezeControl } from "./freeze-control/FreezeControl";
18
18
  export { type ColumnChangeHandler, type ColumnItem, ColumnList, } from "./column-list";
@@ -1 +0,0 @@
1
- export * from "./DatasourceStats";