@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.
Files changed (86) hide show
  1. package/README.md +5 -5
  2. package/dist/column-view.d.ts +2 -2
  3. package/dist/column-view.d.ts.map +1 -1
  4. package/dist/column-view.js +14 -12
  5. package/dist/column-view.js.map +1 -1
  6. package/dist/grid-view.js +1 -1
  7. package/dist/grid-view.js.map +1 -1
  8. package/dist/index.d.ts +1 -1
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/internal/cells.d.ts +31 -23
  12. package/dist/internal/cells.d.ts.map +1 -1
  13. package/dist/internal/cells.js +168 -77
  14. package/dist/internal/cells.js.map +1 -1
  15. package/dist/internal/collection-index.d.ts +8 -11
  16. package/dist/internal/collection-index.d.ts.map +1 -1
  17. package/dist/internal/collection-index.js +53 -73
  18. package/dist/internal/collection-index.js.map +1 -1
  19. package/dist/internal/collection-model.d.ts +24 -4
  20. package/dist/internal/collection-model.d.ts.map +1 -1
  21. package/dist/internal/collection-model.js +247 -96
  22. package/dist/internal/collection-model.js.map +1 -1
  23. package/dist/internal/collection.d.ts +8 -10
  24. package/dist/internal/collection.d.ts.map +1 -1
  25. package/dist/internal/collection.js +38 -48
  26. package/dist/internal/collection.js.map +1 -1
  27. package/dist/internal/controlled-sync.d.ts +11 -0
  28. package/dist/internal/controlled-sync.d.ts.map +1 -0
  29. package/dist/internal/controlled-sync.js +19 -0
  30. package/dist/internal/controlled-sync.js.map +1 -0
  31. package/dist/internal/drop-down.d.ts.map +1 -1
  32. package/dist/internal/drop-down.js +27 -15
  33. package/dist/internal/drop-down.js.map +1 -1
  34. package/dist/internal/expansion.d.ts +3 -2
  35. package/dist/internal/expansion.d.ts.map +1 -1
  36. package/dist/internal/expansion.js +73 -48
  37. package/dist/internal/expansion.js.map +1 -1
  38. package/dist/internal/keys.d.ts +5 -0
  39. package/dist/internal/keys.d.ts.map +1 -0
  40. package/dist/internal/keys.js +13 -0
  41. package/dist/internal/keys.js.map +1 -0
  42. package/dist/internal/selection.d.ts +3 -2
  43. package/dist/internal/selection.d.ts.map +1 -1
  44. package/dist/internal/selection.js +68 -35
  45. package/dist/internal/selection.js.map +1 -1
  46. package/dist/internal/slots.d.ts +10 -0
  47. package/dist/internal/slots.d.ts.map +1 -0
  48. package/dist/internal/slots.js +43 -0
  49. package/dist/internal/slots.js.map +1 -0
  50. package/dist/internal/tree-expansion.d.ts +19 -0
  51. package/dist/internal/tree-expansion.d.ts.map +1 -0
  52. package/dist/internal/tree-expansion.js +72 -0
  53. package/dist/internal/tree-expansion.js.map +1 -0
  54. package/dist/internal/tree-order.d.ts +26 -0
  55. package/dist/internal/tree-order.d.ts.map +1 -0
  56. package/dist/internal/tree-order.js +109 -0
  57. package/dist/internal/tree-order.js.map +1 -0
  58. package/dist/internal/use-collection.d.ts +1 -1
  59. package/dist/internal/use-collection.d.ts.map +1 -1
  60. package/dist/internal/use-collection.js +4 -4
  61. package/dist/internal/use-collection.js.map +1 -1
  62. package/dist/list-view.d.ts.map +1 -1
  63. package/dist/list-view.js +6 -6
  64. package/dist/list-view.js.map +1 -1
  65. package/dist/types.d.ts +72 -22
  66. package/dist/types.d.ts.map +1 -1
  67. package/dist/types.js.map +1 -1
  68. package/package.json +17 -9
  69. package/src/column-view.tsx +28 -25
  70. package/src/grid-view.tsx +1 -1
  71. package/src/index.ts +3 -0
  72. package/src/internal/cells.tsx +339 -117
  73. package/src/internal/collection-index.ts +68 -92
  74. package/src/internal/collection-model.ts +327 -112
  75. package/src/internal/collection.ts +45 -65
  76. package/src/internal/controlled-sync.ts +34 -0
  77. package/src/internal/drop-down.tsx +41 -20
  78. package/src/internal/expansion.ts +95 -70
  79. package/src/internal/keys.ts +18 -0
  80. package/src/internal/selection.tsx +100 -51
  81. package/src/internal/slots.ts +67 -0
  82. package/src/internal/tree-expansion.ts +115 -0
  83. package/src/internal/tree-order.ts +208 -0
  84. package/src/internal/use-collection.tsx +5 -5
  85. package/src/list-view.tsx +14 -10
  86. package/src/types.ts +78 -20
@@ -1,106 +1,86 @@
1
- const ROOT_LEVEL_KEY = "";
1
+ import { decodePartAt, encodePart } from "./keys.js";
2
+ const emptyLevel = () => ({ path: "", items: [], expandableFlags: [] });
2
3
  const hasChildren = (item) => item.children !== undefined && item.children.length > 0;
3
- const childLevelKey = (id) => `child:${id}`;
4
- function collectChildren(state, level, item) {
5
- if (!state.isTree) {
6
- return;
7
- }
8
- const canExpand = hasChildren(item);
9
- level.expandableFlags.push(canExpand);
10
- if (!canExpand) {
11
- return;
12
- }
13
- const key = childLevelKey(item.id);
14
- state.children.set(key, collectLevel(state, key, item.children ?? []));
15
- }
16
- function collectLevel(state, key, items) {
17
- const level = { key, ids: [], expandableFlags: [] };
18
- for (const item of items) {
19
- level.ids.push(item.id);
20
- state.itemsById.set(item.id, item);
21
- collectChildren(state, level, item);
22
- }
4
+ function newLevel(state, path, items) {
5
+ const expandableFlags = state.isTree ? items.map((item) => hasChildren(item)) : [];
6
+ const level = { path, items, expandableFlags };
7
+ state.levels.set(path, level);
23
8
  return level;
24
9
  }
25
- function buildPositions(state) {
26
- const positions = new Map();
27
- const starts = [];
28
- let offset = 0;
29
- for (const level of state.groups) {
30
- starts.push(offset);
31
- for (const id of level.ids) {
32
- positions.set(id, offset);
33
- offset += 1;
34
- }
35
- }
36
- state.positions = positions;
37
- state.starts = starts;
10
+ function slotItems(state, parent, slot) {
11
+ const owner = state.levels.get(parent.path) === parent ? parent : levelFor(state, parent.path);
12
+ const item = owner?.items[slot];
13
+ return item !== undefined && hasChildren(item) ? item.children : undefined;
38
14
  }
39
- function positionFor(state, id) {
40
- if (state.isTree) {
41
- return -1;
15
+ function childLevel(state, parent, slot) {
16
+ if (!state.isTree) {
17
+ return undefined;
42
18
  }
43
- if (state.positions === null) {
44
- buildPositions(state);
19
+ const path = parent.path + encodePart(String(slot));
20
+ const cached = state.levels.get(path);
21
+ if (cached !== undefined) {
22
+ return cached;
45
23
  }
46
- return state.positions?.get(id) ?? -1;
24
+ const items = slotItems(state, parent, slot);
25
+ return items === undefined ? undefined : newLevel(state, path, items);
47
26
  }
48
- function sectionAt(starts, position) {
49
- let low = 0;
50
- let high = starts.length - 1;
51
- while (low < high) {
52
- const middle = Math.ceil((low + high) / 2);
53
- if ((starts[middle] ?? 0) <= position) {
54
- low = middle;
55
- }
56
- else {
57
- high = middle - 1;
27
+ function descendPath(state, levelPath, group) {
28
+ let level = state.levels.get(encodePart(group));
29
+ let offset = encodePart(group).length;
30
+ while (level !== undefined && offset < levelPath.length) {
31
+ const part = decodePartAt(levelPath, offset);
32
+ if (part === null) {
33
+ return undefined;
58
34
  }
35
+ level = childLevel(state, level, Number(part));
36
+ offset += encodePart(part).length;
59
37
  }
60
- return low;
38
+ return level;
61
39
  }
62
- function sectionFor(state, id) {
63
- const sections = state.sections;
64
- const position = positionFor(state, id);
65
- if (sections === undefined || position < 0 || state.starts === null) {
66
- return undefined;
40
+ function levelFor(state, levelPath) {
41
+ const cached = state.levels.get(levelPath);
42
+ if (cached !== undefined) {
43
+ return cached;
67
44
  }
68
- return sections[sectionAt(state.starts, position)]?.value;
45
+ const group = decodePartAt(levelPath, 0);
46
+ return group === null ? undefined : descendPath(state, levelPath, group);
69
47
  }
70
48
  function buildGroups(state, source, sections) {
71
49
  if (sections === undefined) {
72
- return [collectLevel(state, ROOT_LEVEL_KEY, source)];
50
+ return [newLevel(state, encodePart("0"), source)];
73
51
  }
74
- return sections.map((section) => collectLevel(state, section.id, section.data));
52
+ return sections.map((section, group) => {
53
+ const path = encodePart(String(group));
54
+ state.sectionValues.set(path, section.value);
55
+ return newLevel(state, path, section.data);
56
+ });
75
57
  }
76
58
  function isTreeSource(source, sections, isFlat) {
77
- if (sections !== undefined || isFlat) {
59
+ if (isFlat) {
78
60
  return false;
79
61
  }
80
- return source.some((item) => hasChildren(item));
62
+ if (sections === undefined) {
63
+ return source.some((item) => hasChildren(item));
64
+ }
65
+ return sections.some((section) => section.data.some((item) => hasChildren(item)));
81
66
  }
82
67
  function createCollectionIndex(items, sections, isFlat) {
83
68
  const source = items ?? [];
84
69
  const state = {
85
70
  isTree: isTreeSource(source, sections, isFlat),
86
71
  groups: [],
87
- children: new Map(),
88
- itemsById: new Map(),
89
- sections,
90
- positions: null,
91
- starts: null,
72
+ levels: new Map(),
73
+ sectionValues: new Map(),
92
74
  };
93
75
  state.groups = buildGroups(state, source, sections);
94
76
  return {
95
77
  isTree: state.isTree,
96
- size: state.itemsById.size,
97
78
  groups: state.groups,
98
- children: state.children,
99
- hasId: (id) => state.itemsById.has(id),
100
- itemFor: (id) => state.itemsById.get(id),
101
- sectionFor: (id) => sectionFor(state, id),
102
- positionFor: (id) => positionFor(state, id),
79
+ childLevel: (level, slot) => childLevel(state, level, slot),
80
+ levelFor: (levelPath) => levelFor(state, levelPath),
81
+ itemAt: (levelPath, slot) => levelFor(state, levelPath)?.items[slot],
82
+ sectionFor: (levelPath) => state.sectionValues.get(levelPath),
103
83
  };
104
84
  }
105
- export { createCollectionIndex, childLevelKey, ROOT_LEVEL_KEY };
85
+ export { createCollectionIndex, emptyLevel };
106
86
  //# sourceMappingURL=collection-index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"collection-index.js","sourceRoot":"","sources":["../../src/internal/collection-index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ListItem, ListSection } from \"../types.js\";\n\ntype Level = {\n key: string;\n ids: string[];\n expandableFlags: boolean[];\n};\n\ntype CollectionIndex = {\n isTree: boolean;\n size: number;\n groups: Level[];\n children: Map<string, Level>;\n hasId: (id: string) => boolean;\n itemFor: (id: string) => ListItem | undefined;\n sectionFor: (id: string) => unknown;\n positionFor: (id: string) => number;\n};\n\ntype IndexState = {\n isTree: boolean;\n groups: Level[];\n children: Map<string, Level>;\n itemsById: Map<string, ListItem>;\n sections: ListSection[] | undefined;\n positions: Map<string, number> | null;\n starts: number[] | null;\n};\n\nconst ROOT_LEVEL_KEY = \"\";\n\nconst hasChildren = (item: ListItem): boolean => item.children !== undefined && item.children.length > 0;\nconst childLevelKey = (id: string): string => `child:${id}`;\n\nfunction collectChildren(state: IndexState, level: Level, item: ListItem): void {\n if (!state.isTree) {\n return;\n }\n\n const canExpand = hasChildren(item);\n level.expandableFlags.push(canExpand);\n\n if (!canExpand) {\n return;\n }\n\n const key = childLevelKey(item.id);\n state.children.set(key, collectLevel(state, key, item.children ?? []));\n}\n\nfunction collectLevel(state: IndexState, key: string, items: ListItem[]): Level {\n const level: Level = { key, ids: [], expandableFlags: [] };\n\n for (const item of items) {\n level.ids.push(item.id);\n state.itemsById.set(item.id, item);\n collectChildren(state, level, item);\n }\n\n return level;\n}\n\nfunction buildPositions(state: IndexState): void {\n const positions: Map<string, number> = new Map();\n const starts: number[] = [];\n let offset = 0;\n\n for (const level of state.groups) {\n starts.push(offset);\n\n for (const id of level.ids) {\n positions.set(id, offset);\n offset += 1;\n }\n }\n\n state.positions = positions;\n state.starts = starts;\n}\n\nfunction positionFor(state: IndexState, id: string): number {\n if (state.isTree) {\n return -1;\n }\n\n if (state.positions === null) {\n buildPositions(state);\n }\n\n return state.positions?.get(id) ?? -1;\n}\n\nfunction sectionAt(starts: number[], position: number): number {\n let low = 0;\n let high = starts.length - 1;\n\n while (low < high) {\n const middle = Math.ceil((low + high) / 2);\n\n if ((starts[middle] ?? 0) <= position) {\n low = middle;\n } else {\n high = middle - 1;\n }\n }\n\n return low;\n}\n\nfunction sectionFor(state: IndexState, id: string): unknown {\n const sections = state.sections;\n const position = positionFor(state, id);\n\n if (sections === undefined || position < 0 || state.starts === null) {\n return undefined;\n }\n\n return sections[sectionAt(state.starts, position)]?.value;\n}\n\nfunction buildGroups(state: IndexState, source: ListItem[], sections: ListSection[] | undefined): Level[] {\n if (sections === undefined) {\n return [collectLevel(state, ROOT_LEVEL_KEY, source)];\n }\n\n return sections.map((section) => collectLevel(state, section.id, section.data));\n}\n\nfunction isTreeSource(source: ListItem[], sections: ListSection[] | undefined, isFlat: boolean): boolean {\n if (sections !== undefined || isFlat) {\n return false;\n }\n\n return source.some((item) => hasChildren(item));\n}\n\nfunction createCollectionIndex(\n items: ListItem[] | undefined,\n sections: ListSection[] | undefined,\n isFlat: boolean,\n): CollectionIndex {\n const source = items ?? [];\n\n const state: IndexState = {\n isTree: isTreeSource(source, sections, isFlat),\n groups: [],\n children: new Map(),\n itemsById: new Map(),\n sections,\n positions: null,\n starts: null,\n };\n\n state.groups = buildGroups(state, source, sections);\n\n return {\n isTree: state.isTree,\n size: state.itemsById.size,\n groups: state.groups,\n children: state.children,\n hasId: (id) => state.itemsById.has(id),\n itemFor: (id) => state.itemsById.get(id),\n sectionFor: (id) => sectionFor(state, id),\n positionFor: (id) => positionFor(state, id),\n };\n}\n\nexport { createCollectionIndex, childLevelKey, ROOT_LEVEL_KEY, type CollectionIndex, type Level };\n"]}
1
+ {"version":3,"file":"collection-index.js","sourceRoot":"","sources":["../../src/internal/collection-index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AA0BrD,MAAM,UAAU,GAAG,GAAU,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC,CAAC;AAC/E,MAAM,WAAW,GAAG,CAAC,IAAc,EAAsB,EAAE,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;AAEpH,SAAS,QAAQ,CAAC,KAAiB,EAAE,IAAY,EAAE,KAAiB;IAChE,MAAM,eAAe,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACnF,MAAM,KAAK,GAAU,EAAE,IAAI,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC;IACtD,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAE9B,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,SAAS,SAAS,CAAC,KAAiB,EAAE,MAAa,EAAE,IAAY;IAC7D,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/F,MAAM,IAAI,GAAG,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAEhC,OAAO,IAAI,KAAK,SAAS,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/E,CAAC;AAED,SAAS,UAAU,CAAC,KAAiB,EAAE,MAAa,EAAE,IAAY;IAC9D,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAChB,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAEtC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IAE7C,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AAC1E,CAAC;AAED,SAAS,WAAW,CAAC,KAAiB,EAAE,SAAiB,EAAE,KAAa;IACpE,IAAI,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IAChD,IAAI,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;IAEtC,OAAO,KAAK,KAAK,SAAS,IAAI,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;QACtD,MAAM,IAAI,GAAG,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAE7C,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAChB,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/C,MAAM,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IACtC,CAAC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,SAAS,QAAQ,CAAC,KAAiB,EAAE,SAAiB;IAClD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAE3C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,MAAM,KAAK,GAAG,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IAEzC,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,WAAW,CAAC,KAAiB,EAAE,MAAkB,EAAE,QAAmC;IAC3F,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;QACnC,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACvC,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAE7C,OAAO,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,YAAY,CAAC,MAAkB,EAAE,QAAmC,EAAE,MAAe;IAC1F,IAAI,MAAM,EAAE,CAAC;QACT,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACtF,CAAC;AAED,SAAS,qBAAqB,CAC1B,KAA6B,EAC7B,QAAmC,EACnC,MAAe;IAEf,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE,CAAC;IAE3B,MAAM,KAAK,GAAe;QACtB,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC;QAC9C,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,IAAI,GAAG,EAAE;QACjB,aAAa,EAAE,IAAI,GAAG,EAAE;KAC3B,CAAC;IAEF,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAEpD,OAAO;QACH,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,UAAU,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC;QAC3D,QAAQ,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;QACnD,MAAM,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC;QACpE,UAAU,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC;KAChE,CAAC;AACN,CAAC;AAED,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAoC,CAAC","sourcesContent":["import type { ListItem, ListSection } from \"../types.js\";\nimport { decodePartAt, encodePart } from \"./keys.js\";\n\ntype Level = {\n path: string;\n items: ListItem[];\n expandableFlags: boolean[];\n};\n\ntype CollectionIndex = {\n isTree: boolean;\n groups: Level[];\n childLevel: (level: Level, slot: number) => Level | undefined;\n levelFor: (levelPath: string) => Level | undefined;\n itemAt: (levelPath: string, slot: number) => ListItem | undefined;\n sectionFor: (levelPath: string) => unknown;\n};\n\ntype IndexState = {\n isTree: boolean;\n groups: Level[];\n levels: Map<string, Level>;\n sectionValues: Map<string, unknown>;\n};\n\ntype ParentItem = ListItem & { children: ListItem[] };\n\nconst emptyLevel = (): Level => ({ path: \"\", items: [], expandableFlags: [] });\nconst hasChildren = (item: ListItem): item is ParentItem => item.children !== undefined && item.children.length > 0;\n\nfunction newLevel(state: IndexState, path: string, items: ListItem[]): Level {\n const expandableFlags = state.isTree ? items.map((item) => hasChildren(item)) : [];\n const level: Level = { path, items, expandableFlags };\n state.levels.set(path, level);\n\n return level;\n}\n\nfunction slotItems(state: IndexState, parent: Level, slot: number): ListItem[] | undefined {\n const owner = state.levels.get(parent.path) === parent ? parent : levelFor(state, parent.path);\n const item = owner?.items[slot];\n\n return item !== undefined && hasChildren(item) ? item.children : undefined;\n}\n\nfunction childLevel(state: IndexState, parent: Level, slot: number): Level | undefined {\n if (!state.isTree) {\n return undefined;\n }\n\n const path = parent.path + encodePart(String(slot));\n const cached = state.levels.get(path);\n\n if (cached !== undefined) {\n return cached;\n }\n\n const items = slotItems(state, parent, slot);\n\n return items === undefined ? undefined : newLevel(state, path, items);\n}\n\nfunction descendPath(state: IndexState, levelPath: string, group: string): Level | undefined {\n let level = state.levels.get(encodePart(group));\n let offset = encodePart(group).length;\n\n while (level !== undefined && offset < levelPath.length) {\n const part = decodePartAt(levelPath, offset);\n\n if (part === null) {\n return undefined;\n }\n\n level = childLevel(state, level, Number(part));\n offset += encodePart(part).length;\n }\n\n return level;\n}\n\nfunction levelFor(state: IndexState, levelPath: string): Level | undefined {\n const cached = state.levels.get(levelPath);\n\n if (cached !== undefined) {\n return cached;\n }\n\n const group = decodePartAt(levelPath, 0);\n\n return group === null ? undefined : descendPath(state, levelPath, group);\n}\n\nfunction buildGroups(state: IndexState, source: ListItem[], sections: ListSection[] | undefined): Level[] {\n if (sections === undefined) {\n return [newLevel(state, encodePart(\"0\"), source)];\n }\n\n return sections.map((section, group) => {\n const path = encodePart(String(group));\n state.sectionValues.set(path, section.value);\n\n return newLevel(state, path, section.data);\n });\n}\n\nfunction isTreeSource(source: ListItem[], sections: ListSection[] | undefined, isFlat: boolean): boolean {\n if (isFlat) {\n return false;\n }\n\n if (sections === undefined) {\n return source.some((item) => hasChildren(item));\n }\n\n return sections.some((section) => section.data.some((item) => hasChildren(item)));\n}\n\nfunction createCollectionIndex(\n items: ListItem[] | undefined,\n sections: ListSection[] | undefined,\n isFlat: boolean,\n): CollectionIndex {\n const source = items ?? [];\n\n const state: IndexState = {\n isTree: isTreeSource(source, sections, isFlat),\n groups: [],\n levels: new Map(),\n sectionValues: new Map(),\n };\n\n state.groups = buildGroups(state, source, sections);\n\n return {\n isTree: state.isTree,\n groups: state.groups,\n childLevel: (level, slot) => childLevel(state, level, slot),\n levelFor: (levelPath) => levelFor(state, levelPath),\n itemAt: (levelPath, slot) => levelFor(state, levelPath)?.items[slot],\n sectionFor: (levelPath) => state.sectionValues.get(levelPath),\n };\n}\n\nexport { createCollectionIndex, emptyLevel, type CollectionIndex, type Level };\n"]}
@@ -1,12 +1,32 @@
1
+ import * as Gio from "@gtkx/gi/gio";
1
2
  import * as GObject from "@gtkx/gi/gobject";
2
3
  import * as Gtk from "@gtkx/gi/gtk";
3
- import type { CollectionIndex } from "./collection-index.js";
4
+ import type { CollectionIndex, Level } from "./collection-index.js";
5
+ import type { TreeExpansion } from "./tree-expansion.js";
6
+ type LevelStore = Gio.ListModel & LazyLevelStore;
7
+ type SlotRef = {
8
+ store: LevelStore;
9
+ slot: number;
10
+ };
4
11
  type CollectionModel = {
5
12
  model: Gtk.FlattenListModel;
6
- treeModel: () => Gtk.TreeListModel | null;
13
+ expansion: TreeExpansion;
14
+ rowAt: (position: number) => Gtk.TreeListRow | null;
7
15
  sync: (index: CollectionIndex) => void;
8
16
  };
9
- declare function getId(value: GObject.Object | null): string | null;
17
+ declare function slotRefFor(value: GObject.Object | null): SlotRef | null;
18
+ declare function slotPathAt(store: LevelStore, slot: number): string;
10
19
  declare function createCollectionModel(): CollectionModel;
11
- export { createCollectionModel, getId, type CollectionModel };
20
+ declare class LazyLevelStore extends GObject.Object implements Gio.ListModelImpl {
21
+ itemsChanged: Gio.ListModel["itemsChanged"];
22
+ level: Level;
23
+ refs: SlotRef[];
24
+ objects: (Gtk.StringObject | null)[];
25
+ childStores: (LevelStore | null)[];
26
+ private createItem;
27
+ vfuncGetItemType(): bigint;
28
+ vfuncGetNItems(): number;
29
+ vfuncGetItem(position: number): GObject.Object | null;
30
+ }
31
+ export { createCollectionModel, slotPathAt, slotRefFor, type CollectionModel, type SlotRef };
12
32
  //# sourceMappingURL=collection-model.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"collection-model.d.ts","sourceRoot":"","sources":["../../src/internal/collection-model.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,KAAK,EAAE,eAAe,EAAS,MAAM,uBAAuB,CAAC;AAwBpE,KAAK,eAAe,GAAG;IACnB,KAAK,EAAE,GAAG,CAAC,gBAAgB,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC;IAC1C,IAAI,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;CAC1C,CAAC;AAMF,iBAAS,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAI1D;AAoLD,iBAAS,qBAAqB,IAAI,eAAe,CAmBhD;AAED,OAAO,EAAE,qBAAqB,EAAE,KAAK,EAAE,KAAK,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"collection-model.d.ts","sourceRoot":"","sources":["../../src/internal/collection-model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AAEpC,OAAO,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKzD,KAAK,UAAU,GAAG,GAAG,CAAC,SAAS,GAAG,cAAc,CAAC;AAEjD,KAAK,OAAO,GAAG;IACX,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CAChB,CAAC;AA4BF,KAAK,eAAe,GAAG;IACnB,KAAK,EAAE,GAAG,CAAC,gBAAgB,CAAC;IAC5B,SAAS,EAAE,aAAa,CAAC;IACzB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC;IACpD,IAAI,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;CAC1C,CAAC;AAmCF,iBAAS,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,OAAO,GAAG,IAAI,CAUhE;AAED,iBAAS,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3D;AA6SD,iBAAS,qBAAqB,IAAI,eAAe,CAuBhD;AAED,cAAM,cAAe,SAAQ,OAAO,CAAC,MAAO,YAAW,GAAG,CAAC,aAAa;IAC5D,YAAY,EAAE,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IACpD,KAAK,EAAE,KAAK,CAAgB;IAC5B,IAAI,EAAE,OAAO,EAAE,CAAM;IACrB,OAAO,EAAE,CAAC,GAAG,CAAC,YAAY,GAAG,IAAI,CAAC,EAAE,CAAM;IAC1C,WAAW,EAAE,CAAC,UAAU,GAAG,IAAI,CAAC,EAAE,CAAM;IAExC,OAAO,CAAC,UAAU;IAQlB,gBAAgB,IAAI,MAAM;IAI1B,cAAc,IAAI,MAAM;IAIxB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI;CASxD;AAED,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,OAAO,EAAE,CAAC"}