@vuu-ui/vuu-utils 4.0.0-alpha.8 → 4.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +10 -9
- package/src/array-utils.js +5 -4
- package/src/column-utils.js +33 -20
- package/src/component-registry.js +3 -2
- package/src/data-utils.js +1 -0
- package/src/datasource/BaseDataSource.js +5 -3
- package/src/date/EpochTimestamp.js +85 -0
- package/src/date/date-utils.js +50 -18
- package/src/date/dateTimePattern.js +33 -5
- package/src/date/formatter.js +54 -16
- package/src/date/index.js +5 -2
- package/src/date/temporal.js +131 -0
- package/src/date/time-zone.js +56 -0
- package/src/event-emitter.js +1 -3
- package/src/feature-utils.js +14 -8
- package/src/filters/filter-utils.js +13 -7
- package/src/filters/filterAsQuery.js +107 -45
- package/src/filters/index.js +1 -0
- package/src/filters/temporal-cell-filter.js +63 -0
- package/src/form-utils.js +44 -6
- package/src/formatting-utils.js +46 -25
- package/src/html-utils.js +35 -1
- package/src/index.js +0 -1
- package/src/keyset.js +15 -9
- package/src/react-utils.js +8 -2
- package/src/table-schema-utils.js +6 -5
- package/src/useResizeObserver.js +3 -3
- package/src/vendor/@preact/signals-core/dist/signals-core.js +1 -1
- package/src/vendor/@preact/signals-core/dist/signals-core.js.map +1 -1
- package/types/ThemeProvider.d.ts +1 -1
- package/types/array-utils.d.ts +3 -2
- package/types/column-utils.d.ts +45 -43
- package/types/context-definitions/DataProvider.d.ts +1 -1
- package/types/context-definitions/DataSourceProvider.d.ts +1 -1
- package/types/datasource/BaseDataSource.d.ts +2 -2
- package/types/date/EpochTimestamp.d.ts +66 -0
- package/types/date/date-utils.d.ts +34 -9
- package/types/date/dateTimePattern.d.ts +20 -2
- package/types/date/formatter.d.ts +26 -1
- package/types/date/index.d.ts +6 -2
- package/types/date/temporal.d.ts +68 -0
- package/types/date/time-zone.d.ts +52 -0
- package/types/feature-utils.d.ts +34 -30
- package/types/filters/filter-utils.d.ts +6 -1
- package/types/filters/filterAsQuery.d.ts +41 -0
- package/types/filters/index.d.ts +1 -0
- package/types/filters/temporal-cell-filter.d.ts +27 -0
- package/types/form-utils.d.ts +19 -0
- package/types/formatting-utils.d.ts +23 -1
- package/types/html-utils.d.ts +16 -0
- package/types/index.d.ts +0 -1
- package/types/keyset.d.ts +11 -1
- package/types/react-utils.d.ts +1 -1
- package/types/sort-utils.d.ts +2 -2
- package/types/table-schema-utils.d.ts +2 -2
- package/types/tree-types.d.ts +2 -0
- package/types/src/Clock.d.ts +0 -20
- package/types/src/PageVisibilityObserver.d.ts +0 -36
- package/types/src/ScaledDecimal.d.ts +0 -12
- package/types/src/ShellContext.d.ts +0 -11
- package/types/src/ThemeProvider.d.ts +0 -32
- package/types/src/array-utils.d.ts +0 -16
- package/types/src/box-utils.d.ts +0 -24
- package/types/src/broadcast-channel.d.ts +0 -16
- package/types/src/column-utils.d.ts +0 -243
- package/types/src/common-types.d.ts +0 -6
- package/types/src/component-registry.d.ts +0 -65
- package/types/src/context-definitions/DataContext.d.ts +0 -21
- package/types/src/context-definitions/DataProvider.d.ts +0 -7
- package/types/src/context-definitions/DataSourceProvider.d.ts +0 -12
- package/types/src/context-definitions/WorkspaceContext.d.ts +0 -17
- package/types/src/cookie-utils.d.ts +0 -9
- package/types/src/css-utils.d.ts +0 -1
- package/types/src/data-utils.d.ts +0 -33
- package/types/src/datasource/BaseDataSource.d.ts +0 -63
- package/types/src/datasource/datasource-action-utils.d.ts +0 -7
- package/types/src/datasource/datasource-filter-utils.d.ts +0 -2
- package/types/src/datasource/datasource-utils.d.ts +0 -61
- package/types/src/date/date-utils.d.ts +0 -39
- package/types/src/date/dateTimePattern.d.ts +0 -8
- package/types/src/date/formatter.d.ts +0 -9
- package/types/src/date/index.d.ts +0 -4
- package/types/src/date/types.d.ts +0 -29
- package/types/src/debug-utils.d.ts +0 -9
- package/types/src/edit-utils.d.ts +0 -2
- package/types/src/errors.d.ts +0 -2
- package/types/src/event-emitter.d.ts +0 -21
- package/types/src/feature-utils.d.ts +0 -110
- package/types/src/filters/filter-utils.d.ts +0 -75
- package/types/src/filters/filterAsQuery.d.ts +0 -8
- package/types/src/filters/index.d.ts +0 -2
- package/types/src/form-utils.d.ts +0 -37
- package/types/src/formatting-utils.d.ts +0 -14
- package/types/src/getUniqueId.d.ts +0 -1
- package/types/src/group-utils.d.ts +0 -10
- package/types/src/html-utils.d.ts +0 -21
- package/types/src/index.d.ts +0 -76
- package/types/src/input-utils.d.ts +0 -2
- package/types/src/invariant.d.ts +0 -1
- package/types/src/itemToString.d.ts +0 -2
- package/types/src/json-types.d.ts +0 -52
- package/types/src/json-utils.d.ts +0 -6
- package/types/src/keyboard-utils.d.ts +0 -15
- package/types/src/keyset.d.ts +0 -16
- package/types/src/layout-types.d.ts +0 -22
- package/types/src/list-utils.d.ts +0 -2
- package/types/src/local-storage-utils.d.ts +0 -4
- package/types/src/logging-utils.d.ts +0 -45
- package/types/src/module-utils.d.ts +0 -8
- package/types/src/nanoid/index.d.ts +0 -1
- package/types/src/perf-utils.d.ts +0 -5
- package/types/src/promise-utils.d.ts +0 -8
- package/types/src/protocol-message-utils.d.ts +0 -43
- package/types/src/range-utils.d.ts +0 -29
- package/types/src/react-utils.d.ts +0 -15
- package/types/src/round-decimal.d.ts +0 -4
- package/types/src/row-utils.d.ts +0 -28
- package/types/src/selection-utils.d.ts +0 -9
- package/types/src/shell-layout-types.d.ts +0 -15
- package/types/src/sort-utils.d.ts +0 -11
- package/types/src/table-schema-utils.d.ts +0 -5
- package/types/src/text-utils.d.ts +0 -10
- package/types/src/theme-utils.d.ts +0 -14
- package/types/src/tree-types.d.ts +0 -9
- package/types/src/tree-utils.d.ts +0 -9
- package/types/src/ts-utils.d.ts +0 -20
- package/types/src/typeahead-utils.d.ts +0 -1
- package/types/src/url-utils.d.ts +0 -3
- package/types/src/useId.d.ts +0 -1
- package/types/src/useLayoutEffectSkipFirst.d.ts +0 -2
- package/types/src/useResizeObserver.d.ts +0 -15
- package/types/src/useStateRef.d.ts +0 -2
- package/types/src/user-types.d.ts +0 -3
package/package.json
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "4.0.0-
|
|
2
|
+
"version": "4.0.0-beta.1",
|
|
3
3
|
"author": "heswell",
|
|
4
4
|
"main": "./src/index.js",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"types": "types/index.d.ts",
|
|
7
|
-
"type": "module",
|
|
8
7
|
"scripts": {
|
|
9
8
|
"build:dev": "node ../../scripts/run-build.mjs",
|
|
10
9
|
"build": "node ../../scripts/run-build-rslib.ts",
|
|
@@ -12,18 +11,18 @@
|
|
|
12
11
|
"type-defs": "node ../../scripts/build-type-defs.mjs"
|
|
13
12
|
},
|
|
14
13
|
"dependencies": {
|
|
15
|
-
"@salt-ds/core": "1.
|
|
14
|
+
"@salt-ds/core": "1.72.0"
|
|
16
15
|
},
|
|
17
16
|
"devDependencies": {
|
|
18
17
|
"@dnd-kit/react": "^0.1.21",
|
|
19
|
-
"@vuu-ui/vuu-data-types": "4.0.0-
|
|
20
|
-
"@vuu-ui/vuu-table-types": "4.0.0-
|
|
21
|
-
"@vuu-ui/vuu-filter-types": "4.0.0-
|
|
22
|
-
"@vuu-ui/vuu-protocol-types": "4.0.0-
|
|
18
|
+
"@vuu-ui/vuu-data-types": "4.0.0-beta.1",
|
|
19
|
+
"@vuu-ui/vuu-table-types": "4.0.0-beta.1",
|
|
20
|
+
"@vuu-ui/vuu-filter-types": "4.0.0-beta.1",
|
|
21
|
+
"@vuu-ui/vuu-protocol-types": "4.0.0-beta.1"
|
|
23
22
|
},
|
|
24
23
|
"peerDependencies": {
|
|
25
24
|
"@internationalized/date": "^3.0.0",
|
|
26
|
-
"@vuu-ui/vuu-filter-parser": "4.0.0-
|
|
25
|
+
"@vuu-ui/vuu-filter-parser": "4.0.0-beta.1",
|
|
27
26
|
"clsx": "^2.0.0",
|
|
28
27
|
"react": "^19.2.3",
|
|
29
28
|
"react-dom": "^19.2.3"
|
|
@@ -38,9 +37,11 @@
|
|
|
38
37
|
"exports": {
|
|
39
38
|
".": {
|
|
40
39
|
"import": "./src/index.js",
|
|
40
|
+
"default": "./src/index.js",
|
|
41
41
|
"types": "./types/index.d.ts"
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
44
|
"module": "./src/index.js",
|
|
45
|
-
"name": "@vuu-ui/vuu-utils"
|
|
45
|
+
"name": "@vuu-ui/vuu-utils",
|
|
46
|
+
"type": "module"
|
|
46
47
|
}
|
package/src/array-utils.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const simpleIdentity = (a, b)=>a === b;
|
|
1
2
|
function partition(array, test, pass = [], fail = []) {
|
|
2
3
|
for(let i = 0, len = array.length; i < len; i++)(test(array[i], i) ? pass : fail).push(array[i]);
|
|
3
4
|
return [
|
|
@@ -41,15 +42,15 @@ const moveItem = (items, fromIndex, toIndex)=>{
|
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
};
|
|
44
|
-
const getAddedItems = (currentItems, newItems)=>{
|
|
45
|
-
const isNew = (i)=>!currentItems?.includes(i);
|
|
45
|
+
const getAddedItems = (currentItems, newItems, compareItems = simpleIdentity)=>{
|
|
46
46
|
if (void 0 === currentItems) return newItems;
|
|
47
|
+
const isNew = (item)=>currentItems.every((currentItem)=>false === compareItems(item, currentItem));
|
|
47
48
|
if (newItems.some(isNew)) return newItems.filter(isNew);
|
|
48
49
|
return [];
|
|
49
50
|
};
|
|
50
|
-
const getRemovedItems = (currentItems, newItems)=>{
|
|
51
|
-
const isRemoved = (i)=>!newItems?.includes(i);
|
|
51
|
+
const getRemovedItems = (currentItems, newItems, compareItems = simpleIdentity)=>{
|
|
52
52
|
if (void 0 === newItems) return currentItems;
|
|
53
|
+
const isRemoved = (item)=>newItems.every((newItem)=>false === compareItems(item, newItem));
|
|
53
54
|
if (currentItems.some(isRemoved)) return currentItems.filter(isRemoved);
|
|
54
55
|
return [];
|
|
55
56
|
};
|
package/src/column-utils.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { moveItem } from "./array-utils.js";
|
|
2
|
+
import { getTemporalInfo } from "./date/temporal.js";
|
|
2
3
|
import { queryClosest } from "./html-utils.js";
|
|
3
|
-
const NO_HEADINGS = [];
|
|
4
4
|
const SORT_ASC = "asc";
|
|
5
|
+
const NO_HEADINGS = [];
|
|
5
6
|
const DEFAULT_COL_WIDTH = 100;
|
|
6
7
|
const DEFAULT_MAX_WIDTH = 250;
|
|
7
8
|
const DEFAULT_MIN_WIDTH = 50;
|
|
@@ -44,14 +45,17 @@ const getRuntimeColumnWidth = (col, runtimeColumns)=>{
|
|
|
44
45
|
if (runtimeColumn) return runtimeColumn.width;
|
|
45
46
|
return DEFAULT_COL_WIDTH;
|
|
46
47
|
};
|
|
47
|
-
const applyRuntimeColumnWidthsToConfig = (tableConfig, columns)=>
|
|
48
|
+
const applyRuntimeColumnWidthsToConfig = (tableConfig, columns)=>{
|
|
49
|
+
const runtimeColumns = columns.flatMap((column)=>isGroupColumn(column) ? column.columns : column);
|
|
50
|
+
return {
|
|
48
51
|
...tableConfig,
|
|
49
|
-
columns: columns.map((column)=>({
|
|
52
|
+
columns: tableConfig.columns.map((column)=>({
|
|
50
53
|
...column,
|
|
51
|
-
width: column.width ??
|
|
54
|
+
width: runtimeColumns.find(({ name })=>name === column.name)?.width ?? column.width ?? DEFAULT_COL_WIDTH
|
|
52
55
|
})),
|
|
53
56
|
columnLayout: "manual"
|
|
54
|
-
}
|
|
57
|
+
};
|
|
58
|
+
};
|
|
55
59
|
const isValidColumnAlignment = (v)=>"left" === v || "right" === v;
|
|
56
60
|
const isValidPinLocation = (v)=>isValidColumnAlignment(v) || "floating" === v || "" === v;
|
|
57
61
|
const VUU_COLUMN_DATA_TYPES = [
|
|
@@ -77,22 +81,35 @@ const fromServerDataType = (serverDataType)=>{
|
|
|
77
81
|
return "number";
|
|
78
82
|
case "boolean":
|
|
79
83
|
return "boolean";
|
|
84
|
+
case "epochtimestamp":
|
|
85
|
+
case "epochtimestampnano":
|
|
86
|
+
return "date/time";
|
|
80
87
|
default:
|
|
81
88
|
return "string";
|
|
82
89
|
}
|
|
83
90
|
};
|
|
84
91
|
const isNanoTimestampColumn = ({ serverDataType })=>"epochtimestampnano" === serverDataType;
|
|
85
92
|
const isTimestampColumn = (column)=>"epochtimestamp" === column.serverDataType || isNanoTimestampColumn(column);
|
|
86
|
-
const
|
|
93
|
+
const isTemporalColumn = (column)=>void 0 !== getTemporalInfo(column);
|
|
94
|
+
const isNumericColumn = (column)=>{
|
|
95
|
+
const { serverDataType, type } = column;
|
|
96
|
+
if (isTemporalColumn(column)) return false;
|
|
87
97
|
if ("int" === serverDataType || "long" === serverDataType || "double" === serverDataType) return true;
|
|
88
98
|
if ("string" == typeof type) return "number" === type;
|
|
89
99
|
if ("string" == typeof type?.name) return type?.name === "number";
|
|
90
100
|
return false;
|
|
91
101
|
};
|
|
92
|
-
const isDateTimeDataType = (column)=>
|
|
102
|
+
const isDateTimeDataType = (column)=>{
|
|
103
|
+
const typeName = isTypeDescriptor(column.type) ? column.type.name : column.type;
|
|
104
|
+
return "date/time" === typeName || "date" === typeName;
|
|
105
|
+
};
|
|
93
106
|
const isTimeDataType = (column)=>(isTypeDescriptor(column.type) ? column.type.name : column.type) === "time";
|
|
94
|
-
const isDateTimeDataValue = (column)=>
|
|
95
|
-
const
|
|
107
|
+
const isDateTimeDataValue = (column)=>{
|
|
108
|
+
const kind = getTemporalInfo(column)?.kind;
|
|
109
|
+
return "datetime" === kind || "date" === kind;
|
|
110
|
+
};
|
|
111
|
+
const isTimeDataValue = (column)=>getTemporalInfo(column)?.kind === "time";
|
|
112
|
+
const isTimeDataValueWithMilliseconds = (column)=>isTimeDataValue(column) && isTypeDescriptor(column.type) && column.type.formatting?.pattern?.time === "hh:mm:ss.ms";
|
|
96
113
|
const isPinned = (column)=>"string" == typeof column.pin;
|
|
97
114
|
const hasHeadings = (column)=>Array.isArray(column.heading) && column.heading.length > 0;
|
|
98
115
|
const isResizing = (column)=>column.resizing;
|
|
@@ -297,7 +314,7 @@ const measurePinnedColumns = (columns, selectionEndSize)=>{
|
|
|
297
314
|
unpinnedWidth
|
|
298
315
|
};
|
|
299
316
|
};
|
|
300
|
-
const getTableHeadings = (columns
|
|
317
|
+
const getTableHeadings = (columns)=>{
|
|
301
318
|
if (columns.some(hasHeadings)) {
|
|
302
319
|
const maxHeadingDepth = columns.reduce((max, { heading })=>Math.max(max, heading?.length ?? 0), 0);
|
|
303
320
|
let heading;
|
|
@@ -305,9 +322,8 @@ const getTableHeadings = (columns, selectionBookendWidth = 0)=>{
|
|
|
305
322
|
let tableHeadingsRow;
|
|
306
323
|
for(let level = 0; level < maxHeadingDepth; level++){
|
|
307
324
|
tableHeadingsRow = [];
|
|
308
|
-
columns.forEach(({ heading: columnHeading = NO_HEADINGS,
|
|
325
|
+
columns.forEach(({ heading: columnHeading = NO_HEADINGS, width })=>{
|
|
309
326
|
const label = columnHeading[level] ?? "";
|
|
310
|
-
if (hidden) return;
|
|
311
327
|
if (heading && heading.label === label) heading.width += width;
|
|
312
328
|
else {
|
|
313
329
|
heading = {
|
|
@@ -319,10 +335,6 @@ const getTableHeadings = (columns, selectionBookendWidth = 0)=>{
|
|
|
319
335
|
});
|
|
320
336
|
tableHeadings.push(tableHeadingsRow);
|
|
321
337
|
}
|
|
322
|
-
if (selectionBookendWidth > 0) tableHeadings.forEach((tableHeading)=>{
|
|
323
|
-
tableHeading[0].width += selectionBookendWidth;
|
|
324
|
-
tableHeading[tableHeading.length - 1].width += selectionBookendWidth;
|
|
325
|
-
});
|
|
326
338
|
return tableHeadings;
|
|
327
339
|
}
|
|
328
340
|
return NO_HEADINGS;
|
|
@@ -538,6 +550,7 @@ const getDefaultColumnType = (serverDataType)=>{
|
|
|
538
550
|
case "boolean":
|
|
539
551
|
return "boolean";
|
|
540
552
|
case "epochtimestamp":
|
|
553
|
+
case "epochtimestampnano":
|
|
541
554
|
return "date/time";
|
|
542
555
|
default:
|
|
543
556
|
return "string";
|
|
@@ -596,7 +609,7 @@ const getTypeFormattingFromColumn = (column)=>{
|
|
|
596
609
|
};
|
|
597
610
|
const assertAllColumnsAreIncludedInSubscription = (columns, columnNames)=>{
|
|
598
611
|
const unsubscribedColumns = [];
|
|
599
|
-
for (const column of columns)if ("client" !== column.source &&
|
|
612
|
+
for (const column of columns)if ("client" !== column.source && "vuuAction" !== column.name && !columnNames?.includes(column.name)) unsubscribedColumns.push(column.name);
|
|
600
613
|
if (unsubscribedColumns.length > 0) throw Error(`[column-utils] assertAllColumnsAreIncludedInSubscription columns not included in subscription: ${unsubscribedColumns.join(", ")}`);
|
|
601
614
|
};
|
|
602
615
|
const subscribedOnly = (columnNames)=>(column)=>"client" === column.source || columnNames?.includes(column.name);
|
|
@@ -631,7 +644,7 @@ const getCalculatedColumnDetails = (column)=>{
|
|
|
631
644
|
serverDataType: isVuuColumnDataType(serverDataType) ? serverDataType : void 0
|
|
632
645
|
};
|
|
633
646
|
}
|
|
634
|
-
throw Error(
|
|
647
|
+
throw Error("column.name is nor a calculated column");
|
|
635
648
|
};
|
|
636
649
|
const setCalculatedColumnName = (column, name)=>{
|
|
637
650
|
const [, type, expression] = column.name.split(":");
|
|
@@ -778,7 +791,7 @@ const stretchColumnsToFillAvailableSpace = (columns, availableWidth, totalWidth,
|
|
|
778
791
|
return adjustedColumns;
|
|
779
792
|
};
|
|
780
793
|
const dataAndColumnUnchanged = (p, p1)=>p.column === p1.column && p.column.valueFormatter(p.dataRow[p.column.name]) === p1.column.valueFormatter(p1.dataRow[p1.column.name]);
|
|
781
|
-
const dataColumnAndKeyUnchanged = (p, p1)=>p.column === p1.column && p.dataRow.key === p1.dataRow.key && p.
|
|
794
|
+
const dataColumnAndKeyUnchanged = (p, p1)=>p.column === p1.column && p.dataRow.key === p1.dataRow.key && p.column.valueFormatter(p.dataRow[p.column.name]) === p1.column.valueFormatter(p1.dataRow[p1.column.name]);
|
|
782
795
|
const toColumnName = (column)=>column.name;
|
|
783
796
|
const isStringColumn = (column)=>"string" === column.serverDataType;
|
|
784
797
|
const columnByAriaIndex = (columns, ariaColIndex)=>{
|
|
@@ -789,4 +802,4 @@ const columnByAriaIndex = (columns, ariaColIndex)=>{
|
|
|
789
802
|
}
|
|
790
803
|
throw Error(`no column with aria-colIndex ${ariaColIndex}`);
|
|
791
804
|
};
|
|
792
|
-
export { AggregationType,
|
|
805
|
+
export { AggregationType, addColumnToSubscribedColumns, applyDefaultColumnConfig, applyGroupByToColumns, applyRuntimeColumnWidthsToConfig, applySortToColumns, applyWidthToColumns, assertAllColumnsAreIncludedInSubscription, buildColumnMap, checkConfirmationPending, columnByAriaIndex, dataAndColumnUnchanged, dataColumnAndKeyUnchanged, dataSourceRowToDataRowDto, existingSort, extractGroupColumn, findColumn, flattenColumnGroup, fromServerDataType, getAllCellsInColumn, getAriaColIndex, getAriaRowIndex, getCalculatedColumnDetails, getColumnLabel, getColumnName, getColumnStyle, getColumnsInViewport, getDefaultAlignment, getDefaultColumnType, getGroupIcon, getGroupValue, getPinStateFromElement, getRuntimeColumnWidth, getServerDataType, getTableHeadings, getTypeFormattingFromColumn, hasCustomRenderer, hasHeadings, hasValidationRules, isCalculatedColumn, isColumnTypeRenderer, isDataLoading, isDataValueEditable, isDateTimeDataType, isDateTimeDataValue, isGroupColumn, isJsonAttribute, isJsonColumn, isJsonGroup, isLookupRenderer, isMappedValueTypeRenderer, isNanoTimestampColumn, isNotHidden, isNumericColumn, isPinned, isResizing, isStringColumn, isTemporalColumn, isTextColumn, isTimeDataType, isTimeDataValue, isTimeDataValueWithMilliseconds, isTimestampColumn, isTypeDescriptor, isValidColumnAlignment, isValidPinLocation, isValueListRenderer, isVuuColumnDataType, mapSortCriteria, measurePinnedColumns, metadataKeys, moveColumnTo, projectUpdates, removeSort, replaceColumn, setAggregations, setCalculatedColumnExpression, setCalculatedColumnName, setCalculatedColumnType, sortPinnedColumns, subscribedOnly, toColumnDescriptor, toColumnName, toDataSourceColumns, updateColumn, updateColumnFormatting, updateColumnRenderProps, updateColumnType, visibleColumnAtIndex };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { hasCustomRenderer, isColumnTypeRenderer,
|
|
1
|
+
import { hasCustomRenderer, isColumnTypeRenderer, isTemporalColumn, isTypeDescriptor } from "./column-utils.js";
|
|
2
2
|
const containersSet = new Set();
|
|
3
3
|
const viewsSet = new Set();
|
|
4
4
|
const layoutComponentsMap = new Map();
|
|
@@ -76,7 +76,8 @@ function getEditRuleValidator(name) {
|
|
|
76
76
|
}
|
|
77
77
|
function dataCellRenderer(column) {
|
|
78
78
|
if ("boolean" === column.serverDataType && !hasCustomRenderer(column.type)) return cellRenderersMap.get("checkbox-cell");
|
|
79
|
-
if (
|
|
79
|
+
if (column.editable && !hasCustomRenderer(column.type) && isTemporalColumn(column) && cellRenderersMap.has("temporal-input-cell")) return cellRenderersMap.get("temporal-input-cell");
|
|
80
|
+
if (column.editable && !hasCustomRenderer(column.type)) return cellRenderersMap.get("input-cell");
|
|
80
81
|
if (isTypeDescriptor(column.type) && isColumnTypeRenderer(column.type.renderer)) return cellRenderersMap.get(column.type.renderer?.name);
|
|
81
82
|
if ("boolean" === column.serverDataType) return cellRenderersMap.get("checkbox-cell");
|
|
82
83
|
}
|
package/src/data-utils.js
CHANGED
|
@@ -3,7 +3,7 @@ import { EventEmitter } from "../event-emitter.js";
|
|
|
3
3
|
import { uuid } from "../nanoid/index.js";
|
|
4
4
|
import { isConfigChanged, stripVisualLink, vanillaConfig, withConfigDefaults } from "./datasource-utils.js";
|
|
5
5
|
import { Range } from "../range-utils.js";
|
|
6
|
-
import { filterAsQuery } from "../filters/index.js";
|
|
6
|
+
import { filterAsQuery, getColumnsByNameForFilter } from "../filters/index.js";
|
|
7
7
|
const defaultSuspenseProps = {
|
|
8
8
|
escalateToDisable: true
|
|
9
9
|
};
|
|
@@ -88,9 +88,11 @@ class BaseDataSource extends EventEmitter {
|
|
|
88
88
|
filterSpec: filter
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
|
-
setFilter(filter) {
|
|
91
|
+
setFilter(filter, options) {
|
|
92
92
|
const dataSourceFilter = {
|
|
93
|
-
filter: filterAsQuery(filter
|
|
93
|
+
filter: filterAsQuery(filter, {
|
|
94
|
+
columnsByName: getColumnsByNameForFilter(this.tableSchema, options?.columnsByName)
|
|
95
|
+
}),
|
|
94
96
|
filterStruct: filter
|
|
95
97
|
};
|
|
96
98
|
this.filter = dataSourceFilter;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { fromDateTimeFields, getDateTimeFields } from "./time-zone.js";
|
|
2
|
+
const NANOS_PER_MILLI = 1000000n;
|
|
3
|
+
const integerPattern = /^-?\d+$/;
|
|
4
|
+
const MAX_EPOCH_MILLIS = 8.64e15;
|
|
5
|
+
class EpochTimestamp {
|
|
6
|
+
epochMillis;
|
|
7
|
+
subMilliNanos;
|
|
8
|
+
constructor(epochMillis, subMilliNanos = 0){
|
|
9
|
+
this.epochMillis = epochMillis;
|
|
10
|
+
this.subMilliNanos = subMilliNanos;
|
|
11
|
+
}
|
|
12
|
+
static fromMillis(epochMillis, subMilliNanos = 0) {
|
|
13
|
+
const millis = Math.floor(epochMillis);
|
|
14
|
+
return new EpochTimestamp(millis, subMilliNanos);
|
|
15
|
+
}
|
|
16
|
+
static fromNanos(epochNanos) {
|
|
17
|
+
const nanos = "bigint" == typeof epochNanos ? epochNanos : BigInt(epochNanos);
|
|
18
|
+
let millis = nanos / NANOS_PER_MILLI;
|
|
19
|
+
let remainder = nanos % NANOS_PER_MILLI;
|
|
20
|
+
if (remainder < 0n) {
|
|
21
|
+
millis -= 1n;
|
|
22
|
+
remainder += NANOS_PER_MILLI;
|
|
23
|
+
}
|
|
24
|
+
return new EpochTimestamp(Number(millis), Number(remainder));
|
|
25
|
+
}
|
|
26
|
+
static fromDate(date) {
|
|
27
|
+
return new EpochTimestamp(date.getTime());
|
|
28
|
+
}
|
|
29
|
+
static fromFields(fields, timeZone, subMilliNanos = 0) {
|
|
30
|
+
return new EpochTimestamp(fromDateTimeFields(fields, timeZone), subMilliNanos);
|
|
31
|
+
}
|
|
32
|
+
static isEmpty(value) {
|
|
33
|
+
return null == value || "" === value || 0 === value || "0" === value || 0n === value;
|
|
34
|
+
}
|
|
35
|
+
static fromWire(value, encoding) {
|
|
36
|
+
const ts = EpochTimestamp.decode(value, encoding);
|
|
37
|
+
return void 0 !== ts && Math.abs(ts.epochMillis) <= MAX_EPOCH_MILLIS ? ts : void 0;
|
|
38
|
+
}
|
|
39
|
+
static decode(value, encoding) {
|
|
40
|
+
if (EpochTimestamp.isEmpty(value)) return;
|
|
41
|
+
if (value instanceof EpochTimestamp) return value;
|
|
42
|
+
if ("epochNanos" === encoding) {
|
|
43
|
+
if ("bigint" == typeof value) return EpochTimestamp.fromNanos(value);
|
|
44
|
+
else if ("string" == typeof value && integerPattern.test(value)) return EpochTimestamp.fromNanos(value);
|
|
45
|
+
else if ("number" == typeof value && Number.isFinite(value)) return EpochTimestamp.fromNanos(BigInt(Math.trunc(value)));
|
|
46
|
+
} else if ("number" == typeof value && Number.isFinite(value)) return EpochTimestamp.fromMillis(value);
|
|
47
|
+
else if ("bigint" == typeof value) return EpochTimestamp.fromMillis(Number(value));
|
|
48
|
+
else if ("string" == typeof value && integerPattern.test(value)) return EpochTimestamp.fromMillis(Number(value));
|
|
49
|
+
}
|
|
50
|
+
get epochNanos() {
|
|
51
|
+
return BigInt(this.epochMillis) * NANOS_PER_MILLI + BigInt(this.subMilliNanos);
|
|
52
|
+
}
|
|
53
|
+
toDate() {
|
|
54
|
+
return new Date(this.epochMillis);
|
|
55
|
+
}
|
|
56
|
+
fractionalSecond(digits) {
|
|
57
|
+
if (digits <= 0) return "";
|
|
58
|
+
const millisOfSecond = (this.epochMillis % 1000 + 1000) % 1000;
|
|
59
|
+
const nineDigits = `${millisOfSecond}`.padStart(3, "0").concat(`${this.subMilliNanos}`.padStart(6, "0"));
|
|
60
|
+
return nineDigits.slice(0, Math.min(digits, 9));
|
|
61
|
+
}
|
|
62
|
+
getFields(timeZone) {
|
|
63
|
+
return getDateTimeFields(this.epochMillis, timeZone);
|
|
64
|
+
}
|
|
65
|
+
toWire(encoding) {
|
|
66
|
+
return "epochNanos" === encoding ? this.epochNanos.toString() : this.epochMillis;
|
|
67
|
+
}
|
|
68
|
+
toLiteral(encoding) {
|
|
69
|
+
return `${this.toWire(encoding)}`;
|
|
70
|
+
}
|
|
71
|
+
addUnits(units, encoding) {
|
|
72
|
+
return "epochNanos" === encoding ? EpochTimestamp.fromNanos(this.epochNanos + BigInt(units)) : EpochTimestamp.fromMillis(this.epochMillis + units, this.subMilliNanos);
|
|
73
|
+
}
|
|
74
|
+
compare(other) {
|
|
75
|
+
return this.epochMillis === other.epochMillis ? this.subMilliNanos - other.subMilliNanos : this.epochMillis - other.epochMillis;
|
|
76
|
+
}
|
|
77
|
+
equals(other) {
|
|
78
|
+
return void 0 !== other && 0 === this.compare(other);
|
|
79
|
+
}
|
|
80
|
+
toString() {
|
|
81
|
+
const fraction = this.subMilliNanos ? this.fractionalSecond(9) : this.fractionalSecond(3);
|
|
82
|
+
return this.toDate().toISOString().replace(/\.\d{3}Z$/, `.${fraction}Z`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
export { EpochTimestamp };
|
package/src/date/date-utils.js
CHANGED
|
@@ -3,50 +3,71 @@ function toCalendarDate(d) {
|
|
|
3
3
|
return new CalendarDate(d.getFullYear(), d.getMonth() + 1, d.getDate());
|
|
4
4
|
}
|
|
5
5
|
const zeroTime = "00:00:00";
|
|
6
|
+
const zeroTimeMillis = "00:00:00.000";
|
|
6
7
|
const zeroTimeUnit = "00";
|
|
8
|
+
const unitMaxValue = {
|
|
9
|
+
hours: 23,
|
|
10
|
+
minutes: 59,
|
|
11
|
+
seconds: 59,
|
|
12
|
+
milliseconds: 999
|
|
13
|
+
};
|
|
14
|
+
const unitLength = (unit)=>"milliseconds" === unit ? 3 : 2;
|
|
7
15
|
function incrementTimeUnitValue(unit, value) {
|
|
8
16
|
const num = parseInt(value);
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (num < 59) return `${num + 1}`.padStart(2, "0").slice(-2);
|
|
12
|
-
if (59 === num) return "00";
|
|
13
|
-
return value;
|
|
17
|
+
const newValue = num >= unitMaxValue[unit] ? 0 : num + 1;
|
|
18
|
+
return `${newValue}`.padStart(unitLength(unit), "0");
|
|
14
19
|
}
|
|
15
20
|
function decrementTimeUnitValue(unit, value) {
|
|
16
21
|
const num = parseInt(value);
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if (num > 0) return `${num - 1}`.padStart(2, "0").slice(-2);
|
|
20
|
-
if (0 === num) return "59";
|
|
21
|
-
return value;
|
|
22
|
+
const newValue = num <= 0 ? unitMaxValue[unit] : num - 1;
|
|
23
|
+
return `${newValue}`.padStart(unitLength(unit), "0");
|
|
22
24
|
}
|
|
23
25
|
function updateTimeString(timeString, unit, value) {
|
|
24
|
-
const newTimeString = "hours" === unit ? value.concat(timeString.slice(2)) : "minutes" === unit ? timeString.slice(0, 3).concat(value).concat(timeString.slice(5)) : timeString.slice(0, 6).concat(value);
|
|
25
|
-
if (isValidTimeString(newTimeString)) return newTimeString;
|
|
26
|
+
const newTimeString = "hours" === unit ? value.concat(timeString.slice(2)) : "minutes" === unit ? timeString.slice(0, 3).concat(value).concat(timeString.slice(5)) : "seconds" === unit ? timeString.slice(0, 6).concat(value).concat(timeString.slice(8)) : timeString.slice(0, 9).concat(value);
|
|
27
|
+
if (isValidTimeString(newTimeString) || isValidTimeStringMillis(newTimeString)) return newTimeString;
|
|
26
28
|
throw Error(`[date-utils] udateTimeSting invalid result ${newTimeString}`);
|
|
27
29
|
}
|
|
28
|
-
const validTimePattern =
|
|
30
|
+
const validTimePattern = /^(?:[0-1][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$/;
|
|
31
|
+
const validTimeMillisPattern = /^(?:[0-1][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\.[0-9]{3}$/;
|
|
29
32
|
const isValidTimeString = (value)=>"string" == typeof value && validTimePattern.test(value);
|
|
33
|
+
const isValidTimeStringMillis = (value)=>"string" == typeof value && validTimeMillisPattern.test(value);
|
|
34
|
+
function normaliseTimeString(value, milliseconds = false) {
|
|
35
|
+
if (isValidTimeString(value)) return milliseconds ? `${value}.000` : value;
|
|
36
|
+
if (isValidTimeStringMillis(value)) return milliseconds ? value : value.slice(0, 8);
|
|
37
|
+
}
|
|
30
38
|
function asTimeString(value, allowUndefined = false) {
|
|
31
39
|
if (void 0 === value) if (allowUndefined) return value;
|
|
32
40
|
else throw Error("[date-utils] asTimeString, value cannot be undefined");
|
|
33
41
|
if (isValidTimeString(value)) return value;
|
|
42
|
+
if (isValidTimeStringMillis(value)) return value.slice(0, 8);
|
|
34
43
|
if ("number" == typeof value) return Time.millisToTimeString(value);
|
|
35
44
|
if ("string" == typeof value) {
|
|
36
45
|
const valueAsInt = parseInt(value);
|
|
37
46
|
if (!isNaN(valueAsInt)) return Time.millisToTimeString(valueAsInt);
|
|
38
47
|
} else throw Error(`[date-utils] asTimeString, value ${value} is not valid TimeString`);
|
|
39
48
|
}
|
|
49
|
+
function asTimeStringMillis(value, allowUndefined = false) {
|
|
50
|
+
if (void 0 === value) if (allowUndefined) return value;
|
|
51
|
+
else throw Error("[date-utils] asTimeStringMillis, value cannot be undefined");
|
|
52
|
+
const timeString = normaliseTimeString(value, true);
|
|
53
|
+
if (timeString) return timeString;
|
|
54
|
+
if ("number" == typeof value) return Time.millisToTimeStringMillis(value);
|
|
55
|
+
if ("string" == typeof value && /^\d+$/.test(value)) return Time.millisToTimeStringMillis(parseInt(value));
|
|
56
|
+
throw Error(`[date-utils] asTimeStringMillis, value ${value} is not valid TimeStringMillis`);
|
|
57
|
+
}
|
|
40
58
|
const padZero = (val)=>`${val}`.padStart(2, "0");
|
|
41
59
|
class TimeImpl {
|
|
42
60
|
#hours;
|
|
43
61
|
#minutes;
|
|
44
62
|
#seconds;
|
|
63
|
+
#milliseconds;
|
|
45
64
|
constructor(timeString){
|
|
46
|
-
const [hours, minutes,
|
|
65
|
+
const [hours, minutes, secondsAndMillis] = timeString.split(":");
|
|
66
|
+
const [seconds, milliseconds] = secondsAndMillis.split(".");
|
|
47
67
|
this.#hours = parseInt(hours);
|
|
48
68
|
this.#minutes = parseInt(minutes);
|
|
49
69
|
this.#seconds = parseInt(seconds);
|
|
70
|
+
this.#milliseconds = void 0 === milliseconds ? void 0 : parseInt(milliseconds);
|
|
50
71
|
}
|
|
51
72
|
get hours() {
|
|
52
73
|
return this.#hours;
|
|
@@ -57,24 +78,35 @@ class TimeImpl {
|
|
|
57
78
|
get seconds() {
|
|
58
79
|
return this.#seconds;
|
|
59
80
|
}
|
|
81
|
+
get milliseconds() {
|
|
82
|
+
return this.#milliseconds ?? 0;
|
|
83
|
+
}
|
|
60
84
|
asDate(date) {
|
|
61
85
|
const dt = void 0 === date ? new Date() : "string" == typeof date ? new Date(date) : date;
|
|
62
86
|
dt.setHours(this.#hours);
|
|
63
87
|
dt.setMinutes(this.#minutes);
|
|
64
88
|
dt.setSeconds(this.seconds);
|
|
65
|
-
dt.setMilliseconds(
|
|
89
|
+
dt.setMilliseconds(this.milliseconds);
|
|
66
90
|
return dt;
|
|
67
91
|
}
|
|
68
92
|
toString() {
|
|
69
|
-
return Time.toString(this.#hours, this.#minutes, this.#seconds);
|
|
93
|
+
return Time.toString(this.#hours, this.#minutes, this.#seconds, this.#milliseconds);
|
|
70
94
|
}
|
|
71
95
|
}
|
|
72
96
|
const Time = (timeString)=>new TimeImpl(timeString);
|
|
73
97
|
Time.millisToTimeString = (timestamp)=>new Date(timestamp).toTimeString().slice(0, 8);
|
|
74
|
-
Time.
|
|
98
|
+
Time.millisToTimeStringMillis = (timestamp)=>{
|
|
99
|
+
const date = new Date(timestamp);
|
|
100
|
+
return `${date.toTimeString().slice(0, 8)}.${`${date.getMilliseconds()}`.padStart(3, "0")}`;
|
|
101
|
+
};
|
|
102
|
+
function timeToString(hours, minutes, seconds, milliseconds) {
|
|
103
|
+
const timeString = `${padZero(hours)}:${padZero(minutes)}:${padZero(seconds)}`;
|
|
104
|
+
return void 0 === milliseconds ? timeString : `${timeString}.${`${milliseconds}`.padStart(3, "0")}`;
|
|
105
|
+
}
|
|
106
|
+
Time.toString = timeToString;
|
|
75
107
|
Time.isDateInMillis = (dtInMillis)=>{
|
|
76
108
|
const n = "number" == typeof dtInMillis ? dtInMillis : Number(dtInMillis);
|
|
77
109
|
if (!Number.isFinite(n) || !Number.isInteger(n)) return false;
|
|
78
110
|
return new Date(n).getTime() === n;
|
|
79
111
|
};
|
|
80
|
-
export { Time, asTimeString, decrementTimeUnitValue, incrementTimeUnitValue, isValidTimeString, toCalendarDate, updateTimeString, zeroTime, zeroTimeUnit };
|
|
112
|
+
export { Time, asTimeString, asTimeStringMillis, decrementTimeUnitValue, incrementTimeUnitValue, isValidTimeString, isValidTimeStringMillis, normaliseTimeString, toCalendarDate, updateTimeString, zeroTime, zeroTimeMillis, zeroTimeUnit };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getTemporalInfo } from "./temporal.js";
|
|
2
2
|
import { isDateTimePattern } from "./types.js";
|
|
3
3
|
const defaultPatternsByType = {
|
|
4
4
|
time: "hh:mm:ss",
|
|
@@ -8,10 +8,38 @@ const fallbackDateTimePattern = {
|
|
|
8
8
|
date: defaultPatternsByType["date"],
|
|
9
9
|
time: defaultPatternsByType["time"]
|
|
10
10
|
};
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const defaultDateTimePatternByKind = {
|
|
12
|
+
date: {
|
|
13
|
+
date: defaultPatternsByType.date
|
|
14
|
+
},
|
|
15
|
+
datetime: fallbackDateTimePattern,
|
|
16
|
+
time: {
|
|
17
|
+
time: defaultPatternsByType.time
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
const kindFromType = (type)=>{
|
|
21
|
+
const typeName = "string" == typeof type ? type : type?.name;
|
|
22
|
+
return "time" === typeName ? "time" : "date" === typeName ? "date" : "date/time" === typeName ? "datetime" : void 0;
|
|
23
|
+
};
|
|
24
|
+
function dateTimePattern(type, kind = kindFromType(type)) {
|
|
25
|
+
if ("object" == typeof type && null !== type) {
|
|
13
26
|
if (type.formatting && isDateTimePattern(type.formatting.pattern)) return type.formatting.pattern;
|
|
14
27
|
}
|
|
15
|
-
return fallbackDateTimePattern;
|
|
28
|
+
return kind ? defaultDateTimePatternByKind[kind] : fallbackDateTimePattern;
|
|
16
29
|
}
|
|
17
|
-
|
|
30
|
+
const withDateTimePattern = (descriptor, pattern)=>{
|
|
31
|
+
if (void 0 === pattern || void 0 === getTemporalInfo(descriptor)) return descriptor;
|
|
32
|
+
const name = pattern.date && pattern.time ? "date/time" : pattern.date ? "date" : "time";
|
|
33
|
+
const formatting = "object" == typeof descriptor.type ? descriptor.type.formatting : void 0;
|
|
34
|
+
return {
|
|
35
|
+
...descriptor,
|
|
36
|
+
type: {
|
|
37
|
+
name,
|
|
38
|
+
formatting: {
|
|
39
|
+
...formatting,
|
|
40
|
+
pattern
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
export { dateTimePattern, defaultDateTimePatternByKind, defaultPatternsByType, fallbackDateTimePattern, withDateTimePattern };
|
package/src/date/formatter.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { DateFormatter } from "@internationalized/date";
|
|
2
|
+
import { EpochTimestamp } from "./EpochTimestamp.js";
|
|
3
|
+
import { resolveTimeZone } from "./time-zone.js";
|
|
2
4
|
const baseTimeFormatOptions = {
|
|
3
5
|
hour: "2-digit",
|
|
4
6
|
minute: "2-digit",
|
|
@@ -23,8 +25,7 @@ const formatConfigByTimePatterns = {
|
|
|
23
25
|
locale: "en-GB",
|
|
24
26
|
options: {
|
|
25
27
|
...baseTimeFormatOptions,
|
|
26
|
-
hour12: false
|
|
27
|
-
fractionalSecondDigits: 3
|
|
28
|
+
hour12: false
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
31
|
};
|
|
@@ -81,21 +82,58 @@ const formatConfigByDatePatterns = {
|
|
|
81
82
|
}
|
|
82
83
|
}
|
|
83
84
|
};
|
|
84
|
-
const
|
|
85
|
-
|
|
85
|
+
const NARROW_NBSP = /\u202f/g;
|
|
86
|
+
const intlFormatterCache = new Map();
|
|
87
|
+
const getIntlFormatter = (locale, options)=>{
|
|
88
|
+
const key = `${locale}:${JSON.stringify(options)}`;
|
|
89
|
+
let formatter = intlFormatterCache.get(key);
|
|
90
|
+
if (void 0 === formatter) {
|
|
91
|
+
formatter = new Intl.DateTimeFormat(locale, options);
|
|
92
|
+
intlFormatterCache.set(key, formatter);
|
|
93
|
+
}
|
|
94
|
+
return formatter;
|
|
86
95
|
};
|
|
87
|
-
|
|
88
|
-
|
|
96
|
+
const isoDateFormatter = (timeZone)=>{
|
|
97
|
+
const formatter = getIntlFormatter("en-GB", {
|
|
98
|
+
...baseDateFormatOptions,
|
|
99
|
+
month: "2-digit",
|
|
100
|
+
timeZone
|
|
101
|
+
});
|
|
102
|
+
return (ts)=>{
|
|
103
|
+
const parts = formatter.formatToParts(ts.toDate());
|
|
104
|
+
const get = (type)=>parts.find((p)=>p.type === type)?.value ?? "";
|
|
105
|
+
return `${get("year")}-${get("month")}-${get("day")}`;
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
const dateFormatter = (pattern, timeZone, localeOverride)=>{
|
|
109
|
+
const { locale, options } = formatConfigByDatePatterns[pattern];
|
|
110
|
+
const formatter = getIntlFormatter(localeOverride ?? locale, {
|
|
111
|
+
...options,
|
|
112
|
+
timeZone
|
|
113
|
+
});
|
|
114
|
+
return (ts)=>formatter.format(ts.toDate());
|
|
115
|
+
};
|
|
116
|
+
const timeFormatter = (pattern, timeZone, fractionalSecondDigits, localeOverride)=>{
|
|
117
|
+
const { locale, options } = formatConfigByTimePatterns[pattern];
|
|
118
|
+
const formatter = getIntlFormatter(localeOverride ?? locale, {
|
|
119
|
+
...options,
|
|
120
|
+
timeZone
|
|
121
|
+
});
|
|
122
|
+
return (ts)=>formatter.formatToParts(ts.toDate()).map(({ type, value })=>"second" === type && fractionalSecondDigits > 0 ? `${value}.${ts.fractionalSecond(fractionalSecondDigits)}` : value.replace(NARROW_NBSP, " ")).join("");
|
|
123
|
+
};
|
|
124
|
+
function formatTimestamp({ date, time }, { fractionalSecondDigits = "hh:mm:ss.ms" === time ? 3 : 0, locale, timeZone } = {}) {
|
|
125
|
+
const tz = resolveTimeZone(timeZone);
|
|
126
|
+
const formatters = [];
|
|
127
|
+
if ("yyyy-mm-dd" === date) formatters.push(isoDateFormatter(tz));
|
|
128
|
+
else if (date) formatters.push(dateFormatter(date, tz, locale));
|
|
129
|
+
if (time) formatters.push(timeFormatter(time, tz, fractionalSecondDigits, locale));
|
|
130
|
+
return (ts)=>formatters.map((f)=>f(ts)).join(" ");
|
|
89
131
|
}
|
|
90
|
-
function
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
else if (date) out.push(getDateFormatter(formatConfigByDatePatterns[date]));
|
|
94
|
-
if (time) out.push(getDateFormatter(formatConfigByTimePatterns[time]));
|
|
95
|
-
return out;
|
|
132
|
+
function formatDate(pattern, options) {
|
|
133
|
+
const formatter = formatTimestamp(pattern, options);
|
|
134
|
+
return (d)=>formatter(EpochTimestamp.fromDate(d));
|
|
96
135
|
}
|
|
97
|
-
function
|
|
98
|
-
|
|
99
|
-
return (d)=>formatters.map((f)=>f.format(d)).join(" ");
|
|
136
|
+
function getDateFormatter({ locale, options }) {
|
|
137
|
+
return new DateFormatter(locale, options);
|
|
100
138
|
}
|
|
101
|
-
export { formatDate, getDateFormatter };
|
|
139
|
+
export { formatDate, formatTimestamp, getDateFormatter };
|
package/src/date/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export * from "./formatter.js";
|
|
2
|
-
export
|
|
3
|
-
export
|
|
2
|
+
export * from "./temporal.js";
|
|
3
|
+
export * from "./time-zone.js";
|
|
4
|
+
export { Time, asTimeString, asTimeStringMillis, decrementTimeUnitValue, incrementTimeUnitValue, isValidTimeString, isValidTimeStringMillis, normaliseTimeString, toCalendarDate, updateTimeString, zeroTime, zeroTimeMillis, zeroTimeUnit } from "./date-utils.js";
|
|
5
|
+
export { dateTimePattern, defaultDateTimePatternByKind, defaultPatternsByType, fallbackDateTimePattern, withDateTimePattern } from "./dateTimePattern.js";
|
|
4
6
|
export { dateTimeLabelByType, isDatePattern, isTimePattern, supportedDateTimePatterns } from "./types.js";
|
|
7
|
+
export { EpochTimestamp } from "./EpochTimestamp.js";
|