@tipolox/litgrid-web 1.0.3 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,102 @@
1
+ import type { GridColumn } from '../types.js'
2
+ import { normalizeColumnWidth } from '../sizing/columnSizing.js'
3
+
4
+ export type GridColumnStateColumn = {
5
+ key: string
6
+ width?: number
7
+ visible: boolean
8
+ }
9
+
10
+ export type GridColumnState = {
11
+ version: 1
12
+ columns: GridColumnStateColumn[]
13
+ }
14
+
15
+ export type ColumnStateChangeDetail = {
16
+ reason: 'resize' | 'reorder' | 'visibility' | 'restore' | 'reset' | 'set'
17
+ state: GridColumnState
18
+ }
19
+
20
+ export type ResolvedColumnState = {
21
+ columns: GridColumn[]
22
+ widths: Map<string, number>
23
+ hiddenKeys: Set<string>
24
+ }
25
+
26
+ export function createColumnState(
27
+ columns: GridColumn[],
28
+ widths: Map<string, number>,
29
+ hiddenKeys: Set<string>
30
+ ): GridColumnState {
31
+ return {
32
+ version: 1,
33
+ columns: columns.map((column) => {
34
+ const width = widths.get(column.key)
35
+ return {
36
+ key: column.key,
37
+ ...(width === undefined ? {} : { width }),
38
+ visible: !hiddenKeys.has(column.key)
39
+ }
40
+ })
41
+ }
42
+ }
43
+
44
+ export function resolveColumnState(
45
+ state: unknown,
46
+ sourceColumns: GridColumn[]
47
+ ): ResolvedColumnState | null {
48
+ if (!isGridColumnState(state)) return null
49
+
50
+ const sourceByKey = new Map(sourceColumns.map((column) => [column.key, column]))
51
+ const consumedKeys = new Set<string>()
52
+ const columns: GridColumn[] = []
53
+ const widths = new Map<string, number>()
54
+ const hiddenKeys = new Set<string>()
55
+
56
+ for (const entry of state.columns) {
57
+ const column = sourceByKey.get(entry.key)
58
+ if (!column || consumedKeys.has(entry.key)) continue
59
+
60
+ consumedKeys.add(entry.key)
61
+ columns.push(column)
62
+ if (!entry.visible) hiddenKeys.add(entry.key)
63
+ if (typeof entry.width === 'number' && Number.isFinite(entry.width)) {
64
+ widths.set(entry.key, normalizeColumnWidth(entry.width))
65
+ }
66
+ }
67
+
68
+ for (const column of sourceColumns) {
69
+ if (consumedKeys.has(column.key)) continue
70
+
71
+ columns.push(column)
72
+ if (column.hidden) hiddenKeys.add(column.key)
73
+ }
74
+
75
+ return { columns, widths, hiddenKeys }
76
+ }
77
+
78
+ export function parseColumnState(value: string | null): GridColumnState | null {
79
+ if (!value) return null
80
+
81
+ try {
82
+ const state: unknown = JSON.parse(value)
83
+ return isGridColumnState(state) ? state : null
84
+ } catch {
85
+ return null
86
+ }
87
+ }
88
+
89
+ function isGridColumnState(value: unknown): value is GridColumnState {
90
+ if (!value || typeof value !== 'object') return false
91
+
92
+ const state = value as { version?: unknown; columns?: unknown }
93
+ if (state.version !== 1 || !Array.isArray(state.columns)) return false
94
+
95
+ return state.columns.every((column) => {
96
+ if (!column || typeof column !== 'object') return false
97
+ const entry = column as { key?: unknown; width?: unknown; visible?: unknown }
98
+ return typeof entry.key === 'string' &&
99
+ typeof entry.visible === 'boolean' &&
100
+ (entry.width === undefined || typeof entry.width === 'number')
101
+ })
102
+ }