@gtkx/components 1.0.0-rc.4 → 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.
- package/README.md +5 -5
- package/dist/column-view.d.ts +2 -2
- package/dist/column-view.d.ts.map +1 -1
- package/dist/column-view.js +14 -12
- package/dist/column-view.js.map +1 -1
- package/dist/grid-view.js +1 -1
- package/dist/grid-view.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/cells.d.ts +31 -23
- package/dist/internal/cells.d.ts.map +1 -1
- package/dist/internal/cells.js +168 -77
- package/dist/internal/cells.js.map +1 -1
- package/dist/internal/collection-index.d.ts +8 -11
- package/dist/internal/collection-index.d.ts.map +1 -1
- package/dist/internal/collection-index.js +53 -73
- package/dist/internal/collection-index.js.map +1 -1
- package/dist/internal/collection-model.d.ts +24 -4
- package/dist/internal/collection-model.d.ts.map +1 -1
- package/dist/internal/collection-model.js +247 -96
- package/dist/internal/collection-model.js.map +1 -1
- package/dist/internal/collection.d.ts +8 -10
- package/dist/internal/collection.d.ts.map +1 -1
- package/dist/internal/collection.js +38 -48
- package/dist/internal/collection.js.map +1 -1
- package/dist/internal/controlled-sync.d.ts +11 -0
- package/dist/internal/controlled-sync.d.ts.map +1 -0
- package/dist/internal/controlled-sync.js +19 -0
- package/dist/internal/controlled-sync.js.map +1 -0
- package/dist/internal/drop-down.d.ts.map +1 -1
- package/dist/internal/drop-down.js +27 -15
- package/dist/internal/drop-down.js.map +1 -1
- package/dist/internal/expansion.d.ts +3 -2
- package/dist/internal/expansion.d.ts.map +1 -1
- package/dist/internal/expansion.js +73 -48
- package/dist/internal/expansion.js.map +1 -1
- package/dist/internal/keys.d.ts +5 -0
- package/dist/internal/keys.d.ts.map +1 -0
- package/dist/internal/keys.js +13 -0
- package/dist/internal/keys.js.map +1 -0
- package/dist/internal/selection.d.ts +3 -2
- package/dist/internal/selection.d.ts.map +1 -1
- package/dist/internal/selection.js +68 -35
- package/dist/internal/selection.js.map +1 -1
- package/dist/internal/slots.d.ts +10 -0
- package/dist/internal/slots.d.ts.map +1 -0
- package/dist/internal/slots.js +43 -0
- package/dist/internal/slots.js.map +1 -0
- package/dist/internal/tree-expansion.d.ts +19 -0
- package/dist/internal/tree-expansion.d.ts.map +1 -0
- package/dist/internal/tree-expansion.js +72 -0
- package/dist/internal/tree-expansion.js.map +1 -0
- package/dist/internal/tree-order.d.ts +26 -0
- package/dist/internal/tree-order.d.ts.map +1 -0
- package/dist/internal/tree-order.js +109 -0
- package/dist/internal/tree-order.js.map +1 -0
- package/dist/internal/use-collection.d.ts +1 -1
- package/dist/internal/use-collection.d.ts.map +1 -1
- package/dist/internal/use-collection.js +4 -4
- package/dist/internal/use-collection.js.map +1 -1
- package/dist/list-view.d.ts.map +1 -1
- package/dist/list-view.js +6 -6
- package/dist/list-view.js.map +1 -1
- package/dist/types.d.ts +72 -22
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +17 -9
- package/src/column-view.tsx +28 -25
- package/src/grid-view.tsx +1 -1
- package/src/index.ts +3 -0
- package/src/internal/cells.tsx +339 -117
- package/src/internal/collection-index.ts +68 -92
- package/src/internal/collection-model.ts +327 -112
- package/src/internal/collection.ts +45 -65
- package/src/internal/controlled-sync.ts +34 -0
- package/src/internal/drop-down.tsx +41 -20
- package/src/internal/expansion.ts +95 -70
- package/src/internal/keys.ts +18 -0
- package/src/internal/selection.tsx +100 -51
- package/src/internal/slots.ts +67 -0
- package/src/internal/tree-expansion.ts +115 -0
- package/src/internal/tree-order.ts +208 -0
- package/src/internal/use-collection.tsx +5 -5
- package/src/list-view.tsx +14 -10
- package/src/types.ts +78 -20
|
@@ -1,137 +1,118 @@
|
|
|
1
1
|
import type { ListItem, ListSection } from "../types.js";
|
|
2
|
+
import { decodePartAt, encodePart } from "./keys.js";
|
|
2
3
|
|
|
3
4
|
type Level = {
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
path: string;
|
|
6
|
+
items: ListItem[];
|
|
6
7
|
expandableFlags: boolean[];
|
|
7
8
|
};
|
|
8
9
|
|
|
9
10
|
type CollectionIndex = {
|
|
10
11
|
isTree: boolean;
|
|
11
|
-
size: number;
|
|
12
12
|
groups: Level[];
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
sectionFor: (
|
|
17
|
-
positionFor: (id: string) => number;
|
|
13
|
+
childLevel: (level: Level, slot: number) => Level | undefined;
|
|
14
|
+
levelFor: (levelPath: string) => Level | undefined;
|
|
15
|
+
itemAt: (levelPath: string, slot: number) => ListItem | undefined;
|
|
16
|
+
sectionFor: (levelPath: string) => unknown;
|
|
18
17
|
};
|
|
19
18
|
|
|
20
19
|
type IndexState = {
|
|
21
20
|
isTree: boolean;
|
|
22
21
|
groups: Level[];
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
sections: ListSection[] | undefined;
|
|
26
|
-
positions: Map<string, number> | null;
|
|
27
|
-
starts: number[] | null;
|
|
22
|
+
levels: Map<string, Level>;
|
|
23
|
+
sectionValues: Map<string, unknown>;
|
|
28
24
|
};
|
|
29
25
|
|
|
30
|
-
|
|
26
|
+
type ParentItem = ListItem & { children: ListItem[] };
|
|
31
27
|
|
|
32
|
-
const
|
|
33
|
-
const
|
|
28
|
+
const emptyLevel = (): Level => ({ path: "", items: [], expandableFlags: [] });
|
|
29
|
+
const hasChildren = (item: ListItem): item is ParentItem => item.children !== undefined && item.children.length > 0;
|
|
34
30
|
|
|
35
|
-
function
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const canExpand = hasChildren(item);
|
|
41
|
-
level.expandableFlags.push(canExpand);
|
|
42
|
-
|
|
43
|
-
if (!canExpand) {
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const key = childLevelKey(item.id);
|
|
48
|
-
state.children.set(key, collectLevel(state, key, item.children ?? []));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function collectLevel(state: IndexState, key: string, items: ListItem[]): Level {
|
|
52
|
-
const level: Level = { key, ids: [], expandableFlags: [] };
|
|
53
|
-
|
|
54
|
-
for (const item of items) {
|
|
55
|
-
level.ids.push(item.id);
|
|
56
|
-
state.itemsById.set(item.id, item);
|
|
57
|
-
collectChildren(state, level, item);
|
|
58
|
-
}
|
|
31
|
+
function newLevel(state: IndexState, path: string, items: ListItem[]): Level {
|
|
32
|
+
const expandableFlags = state.isTree ? items.map((item) => hasChildren(item)) : [];
|
|
33
|
+
const level: Level = { path, items, expandableFlags };
|
|
34
|
+
state.levels.set(path, level);
|
|
59
35
|
|
|
60
36
|
return level;
|
|
61
37
|
}
|
|
62
38
|
|
|
63
|
-
function
|
|
64
|
-
const
|
|
65
|
-
const
|
|
66
|
-
let offset = 0;
|
|
39
|
+
function slotItems(state: IndexState, parent: Level, slot: number): ListItem[] | undefined {
|
|
40
|
+
const owner = state.levels.get(parent.path) === parent ? parent : levelFor(state, parent.path);
|
|
41
|
+
const item = owner?.items[slot];
|
|
67
42
|
|
|
68
|
-
|
|
69
|
-
|
|
43
|
+
return item !== undefined && hasChildren(item) ? item.children : undefined;
|
|
44
|
+
}
|
|
70
45
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
46
|
+
function childLevel(state: IndexState, parent: Level, slot: number): Level | undefined {
|
|
47
|
+
if (!state.isTree) {
|
|
48
|
+
return undefined;
|
|
75
49
|
}
|
|
76
50
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
51
|
+
const path = parent.path + encodePart(String(slot));
|
|
52
|
+
const cached = state.levels.get(path);
|
|
80
53
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return -1;
|
|
54
|
+
if (cached !== undefined) {
|
|
55
|
+
return cached;
|
|
84
56
|
}
|
|
85
57
|
|
|
86
|
-
|
|
87
|
-
buildPositions(state);
|
|
88
|
-
}
|
|
58
|
+
const items = slotItems(state, parent, slot);
|
|
89
59
|
|
|
90
|
-
return state
|
|
60
|
+
return items === undefined ? undefined : newLevel(state, path, items);
|
|
91
61
|
}
|
|
92
62
|
|
|
93
|
-
function
|
|
94
|
-
let
|
|
95
|
-
let
|
|
63
|
+
function descendPath(state: IndexState, levelPath: string, group: string): Level | undefined {
|
|
64
|
+
let level = state.levels.get(encodePart(group));
|
|
65
|
+
let offset = encodePart(group).length;
|
|
96
66
|
|
|
97
|
-
while (
|
|
98
|
-
const
|
|
67
|
+
while (level !== undefined && offset < levelPath.length) {
|
|
68
|
+
const part = decodePartAt(levelPath, offset);
|
|
99
69
|
|
|
100
|
-
if (
|
|
101
|
-
|
|
102
|
-
} else {
|
|
103
|
-
high = middle - 1;
|
|
70
|
+
if (part === null) {
|
|
71
|
+
return undefined;
|
|
104
72
|
}
|
|
73
|
+
|
|
74
|
+
level = childLevel(state, level, Number(part));
|
|
75
|
+
offset += encodePart(part).length;
|
|
105
76
|
}
|
|
106
77
|
|
|
107
|
-
return
|
|
78
|
+
return level;
|
|
108
79
|
}
|
|
109
80
|
|
|
110
|
-
function
|
|
111
|
-
const
|
|
112
|
-
const position = positionFor(state, id);
|
|
81
|
+
function levelFor(state: IndexState, levelPath: string): Level | undefined {
|
|
82
|
+
const cached = state.levels.get(levelPath);
|
|
113
83
|
|
|
114
|
-
if (
|
|
115
|
-
return
|
|
84
|
+
if (cached !== undefined) {
|
|
85
|
+
return cached;
|
|
116
86
|
}
|
|
117
87
|
|
|
118
|
-
|
|
88
|
+
const group = decodePartAt(levelPath, 0);
|
|
89
|
+
|
|
90
|
+
return group === null ? undefined : descendPath(state, levelPath, group);
|
|
119
91
|
}
|
|
120
92
|
|
|
121
93
|
function buildGroups(state: IndexState, source: ListItem[], sections: ListSection[] | undefined): Level[] {
|
|
122
94
|
if (sections === undefined) {
|
|
123
|
-
return [
|
|
95
|
+
return [newLevel(state, encodePart("0"), source)];
|
|
124
96
|
}
|
|
125
97
|
|
|
126
|
-
return sections.map((section) =>
|
|
98
|
+
return sections.map((section, group) => {
|
|
99
|
+
const path = encodePart(String(group));
|
|
100
|
+
state.sectionValues.set(path, section.value);
|
|
101
|
+
|
|
102
|
+
return newLevel(state, path, section.data);
|
|
103
|
+
});
|
|
127
104
|
}
|
|
128
105
|
|
|
129
106
|
function isTreeSource(source: ListItem[], sections: ListSection[] | undefined, isFlat: boolean): boolean {
|
|
130
|
-
if (
|
|
107
|
+
if (isFlat) {
|
|
131
108
|
return false;
|
|
132
109
|
}
|
|
133
110
|
|
|
134
|
-
|
|
111
|
+
if (sections === undefined) {
|
|
112
|
+
return source.some((item) => hasChildren(item));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return sections.some((section) => section.data.some((item) => hasChildren(item)));
|
|
135
116
|
}
|
|
136
117
|
|
|
137
118
|
function createCollectionIndex(
|
|
@@ -144,25 +125,20 @@ function createCollectionIndex(
|
|
|
144
125
|
const state: IndexState = {
|
|
145
126
|
isTree: isTreeSource(source, sections, isFlat),
|
|
146
127
|
groups: [],
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
sections,
|
|
150
|
-
positions: null,
|
|
151
|
-
starts: null,
|
|
128
|
+
levels: new Map(),
|
|
129
|
+
sectionValues: new Map(),
|
|
152
130
|
};
|
|
153
131
|
|
|
154
132
|
state.groups = buildGroups(state, source, sections);
|
|
155
133
|
|
|
156
134
|
return {
|
|
157
135
|
isTree: state.isTree,
|
|
158
|
-
size: state.itemsById.size,
|
|
159
136
|
groups: state.groups,
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
sectionFor: (
|
|
164
|
-
positionFor: (id) => positionFor(state, id),
|
|
137
|
+
childLevel: (level, slot) => childLevel(state, level, slot),
|
|
138
|
+
levelFor: (levelPath) => levelFor(state, levelPath),
|
|
139
|
+
itemAt: (levelPath, slot) => levelFor(state, levelPath)?.items[slot],
|
|
140
|
+
sectionFor: (levelPath) => state.sectionValues.get(levelPath),
|
|
165
141
|
};
|
|
166
142
|
}
|
|
167
143
|
|
|
168
|
-
export { createCollectionIndex,
|
|
144
|
+
export { createCollectionIndex, emptyLevel, type CollectionIndex, type Level };
|