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