@gtkx/components 1.0.0-rc.1 → 1.0.0-rc.3

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 (220) hide show
  1. package/dist/adw/combo-row.d.ts +11 -0
  2. package/dist/adw/combo-row.d.ts.map +1 -0
  3. package/dist/adw/combo-row.js +14 -0
  4. package/dist/adw/combo-row.js.map +1 -0
  5. package/dist/adw/index.d.ts +4 -0
  6. package/dist/adw/index.d.ts.map +1 -0
  7. package/dist/adw/index.js +3 -0
  8. package/dist/adw/index.js.map +1 -0
  9. package/dist/adw/toast.d.ts +10 -0
  10. package/dist/adw/toast.d.ts.map +1 -0
  11. package/dist/adw/toast.js +51 -0
  12. package/dist/adw/toast.js.map +1 -0
  13. package/dist/adw/types.d.ts +35 -0
  14. package/dist/adw/types.d.ts.map +1 -0
  15. package/dist/adw/types.js +2 -0
  16. package/dist/adw/types.js.map +1 -0
  17. package/dist/column-view.d.ts +7 -29
  18. package/dist/column-view.d.ts.map +1 -1
  19. package/dist/column-view.js +98 -70
  20. package/dist/column-view.js.map +1 -1
  21. package/dist/drop-down.d.ts +7 -28
  22. package/dist/drop-down.d.ts.map +1 -1
  23. package/dist/drop-down.js +10 -86
  24. package/dist/drop-down.js.map +1 -1
  25. package/dist/grid-view.d.ts +6 -16
  26. package/dist/grid-view.d.ts.map +1 -1
  27. package/dist/grid-view.js +25 -33
  28. package/dist/grid-view.js.map +1 -1
  29. package/dist/index.d.ts +6 -12
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +1 -6
  32. package/dist/index.js.map +1 -1
  33. package/dist/internal/cells.d.ts +50 -0
  34. package/dist/internal/cells.d.ts.map +1 -0
  35. package/dist/internal/cells.js +185 -0
  36. package/dist/internal/cells.js.map +1 -0
  37. package/dist/internal/collection-index.d.ts +21 -0
  38. package/dist/internal/collection-index.d.ts.map +1 -0
  39. package/dist/internal/collection-index.js +106 -0
  40. package/dist/internal/collection-index.js.map +1 -0
  41. package/dist/internal/collection-model.d.ts +12 -0
  42. package/dist/internal/collection-model.d.ts.map +1 -0
  43. package/dist/internal/collection-model.js +164 -0
  44. package/dist/internal/collection-model.js.map +1 -0
  45. package/dist/internal/collection.d.ts +18 -0
  46. package/dist/internal/collection.d.ts.map +1 -0
  47. package/dist/internal/collection.js +64 -0
  48. package/dist/internal/collection.js.map +1 -0
  49. package/dist/internal/drop-down.d.ts +16 -0
  50. package/dist/internal/drop-down.d.ts.map +1 -0
  51. package/dist/internal/drop-down.js +110 -0
  52. package/dist/internal/drop-down.js.map +1 -0
  53. package/dist/internal/expansion.d.ts +9 -0
  54. package/dist/internal/expansion.d.ts.map +1 -0
  55. package/dist/internal/expansion.js +74 -0
  56. package/dist/internal/expansion.js.map +1 -0
  57. package/dist/internal/selection.d.ts +13 -0
  58. package/dist/internal/selection.d.ts.map +1 -0
  59. package/dist/internal/selection.js +100 -0
  60. package/dist/internal/selection.js.map +1 -0
  61. package/dist/internal/use-collection.d.ts +17 -0
  62. package/dist/internal/use-collection.d.ts.map +1 -0
  63. package/dist/internal/use-collection.js +34 -0
  64. package/dist/internal/use-collection.js.map +1 -0
  65. package/dist/internal/use-widget-ref.d.ts +4 -0
  66. package/dist/internal/use-widget-ref.d.ts.map +1 -0
  67. package/dist/internal/use-widget-ref.js +8 -0
  68. package/dist/internal/use-widget-ref.js.map +1 -0
  69. package/dist/list-view.d.ts +5 -20
  70. package/dist/list-view.d.ts.map +1 -1
  71. package/dist/list-view.js +32 -53
  72. package/dist/list-view.js.map +1 -1
  73. package/dist/size-group.d.ts +8 -16
  74. package/dist/size-group.d.ts.map +1 -1
  75. package/dist/size-group.js +35 -51
  76. package/dist/size-group.js.map +1 -1
  77. package/dist/types.d.ts +98 -27
  78. package/dist/types.d.ts.map +1 -1
  79. package/dist/types.js.map +1 -1
  80. package/package.json +17 -6
  81. package/src/adw/combo-row.tsx +20 -0
  82. package/src/adw/index.ts +9 -0
  83. package/src/adw/toast.tsx +74 -0
  84. package/src/adw/types.ts +45 -0
  85. package/src/column-view.tsx +176 -160
  86. package/src/drop-down.tsx +12 -185
  87. package/src/grid-view.tsx +29 -73
  88. package/src/index.ts +18 -26
  89. package/src/internal/cells.tsx +345 -0
  90. package/src/internal/collection-index.ts +168 -0
  91. package/src/internal/collection-model.ts +246 -0
  92. package/src/internal/collection.ts +104 -0
  93. package/src/internal/drop-down.tsx +186 -0
  94. package/src/internal/expansion.ts +122 -0
  95. package/src/internal/selection.tsx +162 -0
  96. package/src/internal/use-collection.tsx +57 -0
  97. package/src/internal/use-widget-ref.ts +11 -0
  98. package/src/list-view.tsx +43 -139
  99. package/src/size-group.tsx +63 -82
  100. package/src/types.ts +158 -28
  101. package/dist/cell.d.ts +0 -30
  102. package/dist/cell.d.ts.map +0 -1
  103. package/dist/cell.js +0 -45
  104. package/dist/cell.js.map +0 -1
  105. package/dist/column-view-column.d.ts +0 -27
  106. package/dist/column-view-column.d.ts.map +0 -1
  107. package/dist/column-view-column.js +0 -30
  108. package/dist/column-view-column.js.map +0 -1
  109. package/dist/constraint-layout-apply.d.ts +0 -55
  110. package/dist/constraint-layout-apply.d.ts.map +0 -1
  111. package/dist/constraint-layout-apply.js +0 -107
  112. package/dist/constraint-layout-apply.js.map +0 -1
  113. package/dist/constraint-layout.d.ts +0 -20
  114. package/dist/constraint-layout.d.ts.map +0 -1
  115. package/dist/constraint-layout.js +0 -88
  116. package/dist/constraint-layout.js.map +0 -1
  117. package/dist/fixed.d.ts +0 -26
  118. package/dist/fixed.d.ts.map +0 -1
  119. package/dist/fixed.js +0 -40
  120. package/dist/fixed.js.map +0 -1
  121. package/dist/grid.d.ts +0 -27
  122. package/dist/grid.d.ts.map +0 -1
  123. package/dist/grid.js +0 -48
  124. package/dist/grid.js.map +0 -1
  125. package/dist/hooks/use-cell-containers.d.ts +0 -18
  126. package/dist/hooks/use-cell-containers.d.ts.map +0 -1
  127. package/dist/hooks/use-cell-containers.js +0 -67
  128. package/dist/hooks/use-cell-containers.js.map +0 -1
  129. package/dist/hooks/use-collection-model.d.ts +0 -26
  130. package/dist/hooks/use-collection-model.d.ts.map +0 -1
  131. package/dist/hooks/use-collection-model.js +0 -35
  132. package/dist/hooks/use-collection-model.js.map +0 -1
  133. package/dist/hooks/use-collection-widget.d.ts +0 -28
  134. package/dist/hooks/use-collection-widget.d.ts.map +0 -1
  135. package/dist/hooks/use-collection-widget.js +0 -21
  136. package/dist/hooks/use-collection-widget.js.map +0 -1
  137. package/dist/hooks/use-drop-down-selection.d.ts +0 -16
  138. package/dist/hooks/use-drop-down-selection.d.ts.map +0 -1
  139. package/dist/hooks/use-drop-down-selection.js +0 -35
  140. package/dist/hooks/use-drop-down-selection.js.map +0 -1
  141. package/dist/hooks/use-expansion-model.d.ts +0 -12
  142. package/dist/hooks/use-expansion-model.d.ts.map +0 -1
  143. package/dist/hooks/use-expansion-model.js +0 -71
  144. package/dist/hooks/use-expansion-model.js.map +0 -1
  145. package/dist/hooks/use-header-menu.d.ts +0 -4
  146. package/dist/hooks/use-header-menu.d.ts.map +0 -1
  147. package/dist/hooks/use-header-menu.js +0 -20
  148. package/dist/hooks/use-header-menu.js.map +0 -1
  149. package/dist/hooks/use-installed-model.d.ts +0 -4
  150. package/dist/hooks/use-installed-model.d.ts.map +0 -1
  151. package/dist/hooks/use-installed-model.js +0 -15
  152. package/dist/hooks/use-installed-model.js.map +0 -1
  153. package/dist/hooks/use-list-model.d.ts +0 -19
  154. package/dist/hooks/use-list-model.d.ts.map +0 -1
  155. package/dist/hooks/use-list-model.js +0 -97
  156. package/dist/hooks/use-list-model.js.map +0 -1
  157. package/dist/hooks/use-placed-child.d.ts +0 -18
  158. package/dist/hooks/use-placed-child.d.ts.map +0 -1
  159. package/dist/hooks/use-placed-child.js +0 -47
  160. package/dist/hooks/use-placed-child.js.map +0 -1
  161. package/dist/hooks/use-selection-model.d.ts +0 -13
  162. package/dist/hooks/use-selection-model.d.ts.map +0 -1
  163. package/dist/hooks/use-selection-model.js +0 -103
  164. package/dist/hooks/use-selection-model.js.map +0 -1
  165. package/dist/hooks/use-sort-handler.d.ts +0 -17
  166. package/dist/hooks/use-sort-handler.d.ts.map +0 -1
  167. package/dist/hooks/use-sort-handler.js +0 -87
  168. package/dist/hooks/use-sort-handler.js.map +0 -1
  169. package/dist/menu-items.d.ts +0 -5
  170. package/dist/menu-items.d.ts.map +0 -1
  171. package/dist/menu-items.js +0 -48
  172. package/dist/menu-items.js.map +0 -1
  173. package/dist/menu.d.ts +0 -14
  174. package/dist/menu.d.ts.map +0 -1
  175. package/dist/menu.js +0 -24
  176. package/dist/menu.js.map +0 -1
  177. package/dist/overlay.d.ts +0 -24
  178. package/dist/overlay.d.ts.map +0 -1
  179. package/dist/overlay.js +0 -49
  180. package/dist/overlay.js.map +0 -1
  181. package/dist/utils/cell-container-store.d.ts +0 -28
  182. package/dist/utils/cell-container-store.d.ts.map +0 -1
  183. package/dist/utils/cell-container-store.js +0 -98
  184. package/dist/utils/cell-container-store.js.map +0 -1
  185. package/dist/utils/item-models.d.ts +0 -10
  186. package/dist/utils/item-models.d.ts.map +0 -1
  187. package/dist/utils/item-models.js +0 -82
  188. package/dist/utils/item-models.js.map +0 -1
  189. package/dist/utils/item-resolver.d.ts +0 -25
  190. package/dist/utils/item-resolver.d.ts.map +0 -1
  191. package/dist/utils/item-resolver.js +0 -102
  192. package/dist/utils/item-resolver.js.map +0 -1
  193. package/dist/utils/list-item-flatten.d.ts +0 -24
  194. package/dist/utils/list-item-flatten.d.ts.map +0 -1
  195. package/dist/utils/list-item-flatten.js +0 -68
  196. package/dist/utils/list-item-flatten.js.map +0 -1
  197. package/src/cell.tsx +0 -144
  198. package/src/column-view-column.tsx +0 -82
  199. package/src/constraint-layout-apply.ts +0 -173
  200. package/src/constraint-layout.tsx +0 -135
  201. package/src/fixed.tsx +0 -86
  202. package/src/grid.tsx +0 -88
  203. package/src/hooks/use-cell-containers.ts +0 -93
  204. package/src/hooks/use-collection-model.ts +0 -60
  205. package/src/hooks/use-collection-widget.ts +0 -47
  206. package/src/hooks/use-drop-down-selection.ts +0 -52
  207. package/src/hooks/use-expansion-model.ts +0 -82
  208. package/src/hooks/use-header-menu.ts +0 -34
  209. package/src/hooks/use-installed-model.ts +0 -20
  210. package/src/hooks/use-list-model.ts +0 -161
  211. package/src/hooks/use-placed-child.ts +0 -79
  212. package/src/hooks/use-selection-model.ts +0 -114
  213. package/src/hooks/use-sort-handler.ts +0 -107
  214. package/src/menu-items.ts +0 -48
  215. package/src/menu.tsx +0 -32
  216. package/src/overlay.tsx +0 -88
  217. package/src/utils/cell-container-store.ts +0 -114
  218. package/src/utils/item-models.ts +0 -113
  219. package/src/utils/item-resolver.ts +0 -138
  220. package/src/utils/list-item-flatten.ts +0 -90
@@ -1,114 +0,0 @@
1
- import type * as GObject from "@gtkx/gi/gobject";
2
- import type * as Gtk from "@gtkx/gi/gtk";
3
-
4
- export type CellEntry = {
5
- position: number;
6
- treeRow: Gtk.TreeListRow | null;
7
- };
8
-
9
- let nextKey = 0;
10
-
11
- export class CellContainerStore {
12
- private entries = new Map<GObject.Object, CellEntry>();
13
-
14
- private published = new Map<GObject.Object, CellEntry>();
15
-
16
- private setListeners = new Set<() => void>();
17
-
18
- private positionListeners = new Map<GObject.Object, Set<() => void>>();
19
-
20
- private positionFlushers = new Map<GObject.Object, () => void>();
21
-
22
- private keys = new WeakMap<GObject.Object, string>();
23
-
24
- private snapshot: GObject.Object[] = [];
25
-
26
- subscribeSet = (onChange: () => void): (() => void) => {
27
- this.setListeners.add(onChange);
28
- return () => {
29
- this.setListeners.delete(onChange);
30
- };
31
- };
32
-
33
- getContainersSnapshot = (): GObject.Object[] => this.snapshot;
34
-
35
- subscribePosition = (container: GObject.Object, onChange: () => void): (() => void) => {
36
- let listeners = this.positionListeners.get(container);
37
- if (listeners === undefined) {
38
- listeners = new Set();
39
- this.positionListeners.set(container, listeners);
40
- }
41
- listeners.add(onChange);
42
- return () => {
43
- const current = this.positionListeners.get(container);
44
- if (current === undefined) return;
45
- current.delete(onChange);
46
- if (current.size === 0) this.positionListeners.delete(container);
47
- };
48
- };
49
-
50
- getPosition = (container: GObject.Object): CellEntry => {
51
- let entry = this.published.get(container);
52
- if (entry === undefined) {
53
- entry = { position: -1, treeRow: null };
54
- this.published.set(container, entry);
55
- }
56
- return entry;
57
- };
58
-
59
- keyFor = (container: GObject.Object): string => {
60
- const existing = this.keys.get(container);
61
- if (existing !== undefined) return existing;
62
- const key = `cell-${nextKey++}`;
63
- this.keys.set(container, key);
64
- return key;
65
- };
66
-
67
- addContainer = (container: GObject.Object): void => {
68
- if (this.entries.has(container)) return;
69
- this.entries.set(container, { position: -1, treeRow: null });
70
- this.notifySet();
71
- };
72
-
73
- bind = (container: GObject.Object, position: number, treeRow: Gtk.TreeListRow | null): void => {
74
- this.entries.set(container, { position, treeRow });
75
- this.notifyPosition(container);
76
- };
77
-
78
- unbind = (container: GObject.Object): void => {
79
- if (!this.entries.has(container)) return;
80
- this.entries.set(container, { position: -1, treeRow: null });
81
- this.notifyPosition(container);
82
- };
83
-
84
- removeContainer = (container: GObject.Object): void => {
85
- if (!this.entries.delete(container)) return;
86
- this.published.delete(container);
87
- this.positionFlushers.delete(container);
88
- this.notifySet();
89
- };
90
-
91
- private flushSet = (): void => {
92
- this.snapshot = [...this.entries.keys()];
93
- for (const listener of [...this.setListeners]) listener();
94
- };
95
-
96
- private notifySet(): void {
97
- this.flushSet();
98
- }
99
-
100
- private notifyPosition(container: GObject.Object): void {
101
- let flush = this.positionFlushers.get(container);
102
- if (flush === undefined) {
103
- flush = (): void => {
104
- const live = this.entries.get(container);
105
- if (live !== undefined) this.published.set(container, live);
106
- const listeners = this.positionListeners.get(container);
107
- if (listeners === undefined) return;
108
- for (const listener of [...listeners]) listener();
109
- };
110
- this.positionFlushers.set(container, flush);
111
- }
112
- flush();
113
- }
114
- }
@@ -1,113 +0,0 @@
1
- import * as Gio from "@gtkx/gi/gio";
2
- import type * as GObject from "@gtkx/gi/gobject";
3
- import * as Gtk from "@gtkx/gi/gtk";
4
- import type { ItemNode, SectionNode } from "../types.js";
5
- import type { RowValue } from "./item-resolver.js";
6
- import { countDescendants, treeItemMetadata } from "./list-item-flatten.js";
7
-
8
- const emptyStrings = (count: number): string[] => new Array<string>(Math.max(0, count)).fill("");
9
-
10
- export const retagRows = <T>(
11
- items: ItemNode<T>[],
12
- rowValues: WeakMap<GObject.Object, RowValue<T>>,
13
- placeholdersById: Map<string, GObject.Object>,
14
- ): void => {
15
- const walk = (list: ItemNode<T>[]): void => {
16
- for (const item of list) {
17
- const placeholder = placeholdersById.get(item.id);
18
- if (placeholder !== undefined) {
19
- rowValues.set(placeholder, {
20
- id: item.id,
21
- value: item.value,
22
- metadata: treeItemMetadata(item),
23
- });
24
- }
25
- if (item.children !== undefined && item.children.length > 0) walk(item.children);
26
- }
27
- };
28
- walk(items);
29
- };
30
-
31
- export const createFlatModel = (count: number): Gtk.StringList => Gtk.StringList.new(emptyStrings(count));
32
-
33
- export const resizeFlatModel = (model: Gtk.StringList, count: number): void => {
34
- const target = Math.max(0, count);
35
- const current = model.getNItems();
36
- if (current === target) return;
37
- if (target > current) {
38
- model.splice(current, 0, emptyStrings(target - current));
39
- return;
40
- }
41
- model.splice(target, current - target, null);
42
- };
43
-
44
- const createTaggedRow = <T>(
45
- row: RowValue<T>,
46
- rowValues: WeakMap<GObject.Object, RowValue<T>>,
47
- placeholdersById?: Map<string, GObject.Object>,
48
- ): GObject.Object => {
49
- const placeholder = Gtk.StringObject.new("");
50
- rowValues.set(placeholder, row);
51
- if (placeholdersById !== undefined) placeholdersById.set(row.id, placeholder);
52
- return placeholder;
53
- };
54
-
55
- const childModelOf = <T>(
56
- children: ItemNode<T>[],
57
- rowValues: WeakMap<GObject.Object, RowValue<T>>,
58
- placeholdersById: Map<string, GObject.Object>,
59
- ): Gio.ListStore => {
60
- const store = Gio.ListStore.new(Gtk.StringObject.prototype.__type__);
61
- for (const child of children) {
62
- store.append(
63
- createTaggedRow(
64
- { id: child.id, value: child.value, metadata: treeItemMetadata(child) },
65
- rowValues,
66
- placeholdersById,
67
- ),
68
- );
69
- }
70
- return store;
71
- };
72
-
73
- export const createTreeModel = <T>(
74
- items: ItemNode<T>[],
75
- rowValues: WeakMap<GObject.Object, RowValue<T>>,
76
- placeholdersById: Map<string, GObject.Object>,
77
- ): Gtk.TreeListModel => {
78
- const childrenByRow = new WeakMap<GObject.Object, ItemNode<T>[]>();
79
- const root = Gio.ListStore.new(Gtk.StringObject.prototype.__type__);
80
- for (const item of items) {
81
- const placeholder = createTaggedRow(
82
- { id: item.id, value: item.value, metadata: treeItemMetadata(item) },
83
- rowValues,
84
- placeholdersById,
85
- );
86
- if (item.children !== undefined && item.children.length > 0) {
87
- childrenByRow.set(placeholder, item.children);
88
- }
89
- root.append(placeholder);
90
- }
91
- const createFunc = (rowItem: GObject.Object): Gio.ListModel | null => {
92
- const children = childrenByRow.get(rowItem);
93
- if (children === undefined) return null;
94
- const store = childModelOf(children, rowValues, placeholdersById);
95
- for (let index = 0; index < children.length; index++) {
96
- const child = children[index];
97
- if (child !== undefined && child.children !== undefined && child.children.length > 0) {
98
- const placeholder = store.getItem(index);
99
- if (placeholder !== null) childrenByRow.set(placeholder, child.children);
100
- }
101
- }
102
- return store;
103
- };
104
- return Gtk.TreeListModel.new(root, false, false, createFunc);
105
- };
106
-
107
- export const createSectionModel = <S, T>(sections: SectionNode<S, T>[]): Gtk.FlattenListModel => {
108
- const store = Gio.ListStore.new(Gtk.StringList.prototype.__type__);
109
- for (const section of sections) {
110
- store.append(Gtk.StringList.new(emptyStrings(countDescendants(section.data))));
111
- }
112
- return Gtk.FlattenListModel.new(store);
113
- };
@@ -1,138 +0,0 @@
1
- import type * as GObject from "@gtkx/gi/gobject";
2
- import type * as Gtk from "@gtkx/gi/gtk";
3
- import type { ItemNode, SectionNode } from "../types.js";
4
- import { countDescendants, flattenListItems, type TreeItemMetadata } from "./list-item-flatten.js";
5
-
6
- const NO_TREE_METADATA: TreeItemMetadata = { hideExpander: false, indentForDepth: true, indentForIcon: true };
7
-
8
- const treeItemCache = new WeakMap<Gtk.TreeListRow, GObject.Object>();
9
-
10
- const treeRowItem = (treeRow: Gtk.TreeListRow): GObject.Object | null => {
11
- const cached = treeItemCache.get(treeRow);
12
- if (cached !== undefined) return cached;
13
- const item = treeRow.getItem();
14
- if (item !== null) treeItemCache.set(treeRow, item);
15
- return item;
16
- };
17
-
18
- export type Resolved<T = unknown, S = unknown> = {
19
- value: T | S | undefined;
20
- present: boolean;
21
- isHeader: boolean;
22
- metadata: TreeItemMetadata;
23
- };
24
-
25
- export type ItemResolver<T = unknown, S = unknown> = {
26
- resolve(position: number, treeRow: Gtk.TreeListRow | null): Resolved<T, S>;
27
- positionOfId(id: string): number;
28
- idOf(position: number): string | undefined;
29
- };
30
-
31
- export type RowValue<T = unknown> = {
32
- id: string;
33
- value: T;
34
- metadata: TreeItemMetadata;
35
- };
36
-
37
- export const rowIdOf = <T>(
38
- rowValues: WeakMap<GObject.Object, RowValue<T>>,
39
- row: Gtk.TreeListRow,
40
- ): string | undefined => {
41
- const item = row.getItem();
42
- return item === null ? undefined : rowValues.get(item)?.id;
43
- };
44
-
45
- export const createItemResolver = <T, S>(
46
- items: ItemNode<T>[] | undefined,
47
- flattenTreeChildren: boolean,
48
- rowValues: WeakMap<GObject.Object, RowValue<T>>,
49
- ): ItemResolver<T, S> => {
50
- const flattened = flattenListItems(items, flattenTreeChildren);
51
- return {
52
- positionOfId(id: string): number {
53
- const position = flattened.idToPosition.get(id);
54
- return position === undefined ? -1 : position;
55
- },
56
- idOf(position: number): string | undefined {
57
- return flattened.positionToId.get(position);
58
- },
59
- resolve(position: number, treeRow: Gtk.TreeListRow | null): Resolved<T, S> {
60
- if (treeRow !== null && !flattenTreeChildren) {
61
- const rowItem = treeRowItem(treeRow);
62
- if (rowItem !== null) {
63
- const tagged = rowValues.get(rowItem);
64
- if (tagged !== undefined) {
65
- return {
66
- value: tagged.value,
67
- present: true,
68
- isHeader: false,
69
- metadata: tagged.metadata,
70
- };
71
- }
72
- }
73
- }
74
- const record = flattened.records[position];
75
- if (record === undefined) {
76
- return {
77
- value: undefined,
78
- present: false,
79
- isHeader: false,
80
- metadata: NO_TREE_METADATA,
81
- };
82
- }
83
- return {
84
- value: record.value,
85
- present: true,
86
- isHeader: false,
87
- metadata: record.metadata,
88
- };
89
- },
90
- };
91
- };
92
-
93
- export const createSectionHeaderResolver = <T, S>(sections: SectionNode<S, T>[] | undefined): ItemResolver<T, S> => {
94
- const valueByStart = new Map<number, S>();
95
- let start = 0;
96
- for (const section of sections ?? []) {
97
- valueByStart.set(start, section.value);
98
- start += countDescendants(section.data);
99
- }
100
- return {
101
- positionOfId: () => -1,
102
- idOf: () => undefined,
103
- resolve(position: number): Resolved<T, S> {
104
- if (!valueByStart.has(position)) {
105
- return { value: undefined, present: false, isHeader: true, metadata: NO_TREE_METADATA };
106
- }
107
- return {
108
- value: valueByStart.get(position),
109
- present: true,
110
- isHeader: true,
111
- metadata: NO_TREE_METADATA,
112
- };
113
- },
114
- };
115
- };
116
-
117
- export const createTreeResolver = <T, S>(
118
- items: ItemNode<T>[] | undefined,
119
- rowValues: WeakMap<GObject.Object, RowValue<T>>,
120
- model: Gtk.TreeListModel,
121
- ): ItemResolver<T, S> => {
122
- const base = createItemResolver<T, S>(items, false, rowValues);
123
- return {
124
- resolve: base.resolve,
125
- idOf: (position: number): string | undefined => {
126
- const row = model.getRow(position);
127
- return row === null ? undefined : rowIdOf(rowValues, row);
128
- },
129
- positionOfId: (id: string): number => {
130
- const count = model.getNItems();
131
- for (let position = 0; position < count; position++) {
132
- const row = model.getRow(position);
133
- if (row !== null && rowIdOf(rowValues, row) === id) return position;
134
- }
135
- return -1;
136
- },
137
- };
138
- };
@@ -1,90 +0,0 @@
1
- import type { ItemNode } from "../types.js";
2
-
3
- export type TreeItemMetadata = {
4
- hideExpander: boolean;
5
- indentForDepth: boolean;
6
- indentForIcon: boolean;
7
- };
8
-
9
- type FlattenedRecord<T = unknown> = {
10
- id: string;
11
- value: T;
12
- metadata: TreeItemMetadata;
13
- };
14
-
15
- type FlattenResult<T = unknown> = {
16
- records: FlattenedRecord<T>[];
17
- idToPosition: Map<string, number>;
18
- positionToId: Map<number, string>;
19
- };
20
-
21
- export type ListStructure = "flat" | "tree";
22
-
23
- export const detectStructure = <T>(items: ItemNode<T>[] | undefined): ListStructure => {
24
- if (items === undefined) return "flat";
25
- for (const item of items) {
26
- if (item.children !== undefined && item.children.length > 0) return "tree";
27
- }
28
- return "flat";
29
- };
30
-
31
- export const structuralSignature = <T>(items: ItemNode<T>[] | undefined): string => {
32
- if (items === undefined) return "";
33
- const parts: string[] = [];
34
- const walk = (list: ItemNode<T>[]): void => {
35
- parts.push("[");
36
- for (const item of list) {
37
- const hidden = item.hideExpander === true;
38
- parts.push(`${item.id}|${hidden ? 1 : 0}`);
39
- if (item.children !== undefined && item.children.length > 0) walk(item.children);
40
- }
41
- parts.push("]");
42
- };
43
- walk(items);
44
- return parts.join(",");
45
- };
46
-
47
- export const countDescendants = <T>(items: ItemNode<T>[]): number => {
48
- let total = 0;
49
- for (const item of items) {
50
- total += 1;
51
- if (item.children !== undefined && item.children.length > 0) total += countDescendants(item.children);
52
- }
53
- return total;
54
- };
55
-
56
- export const treeItemMetadata = <T>(item: ItemNode<T>): TreeItemMetadata => ({
57
- hideExpander: item.hideExpander ?? false,
58
- indentForDepth: item.indentForDepth ?? true,
59
- indentForIcon: item.indentForIcon ?? true,
60
- });
61
-
62
- const appendRecord = <T>(item: ItemNode<T>, result: FlattenResult<T>, includeChildren: boolean): void => {
63
- const position = result.records.length;
64
- result.idToPosition.set(item.id, position);
65
- result.positionToId.set(position, item.id);
66
- result.records.push({
67
- id: item.id,
68
- value: item.value,
69
- metadata: treeItemMetadata(item),
70
- });
71
- if (includeChildren && item.children !== undefined) {
72
- for (const child of item.children) appendRecord(child, result, includeChildren);
73
- }
74
- };
75
-
76
- export const flattenListItems = <T>(
77
- items: ItemNode<T>[] | undefined,
78
- flattenTreeChildren: boolean,
79
- ): FlattenResult<T> => {
80
- const result: FlattenResult<T> = {
81
- records: [],
82
- idToPosition: new Map(),
83
- positionToId: new Map(),
84
- };
85
- if (items === undefined) return result;
86
- for (const item of items) {
87
- appendRecord(item, result, flattenTreeChildren);
88
- }
89
- return result;
90
- };