@gtkx/react 0.19.0 → 0.21.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 (289) hide show
  1. package/README.md +26 -62
  2. package/dist/components/compound.d.ts +40 -0
  3. package/dist/components/compound.d.ts.map +1 -0
  4. package/dist/components/compound.js +46 -0
  5. package/dist/components/compound.js.map +1 -0
  6. package/dist/components/list.d.ts +75 -0
  7. package/dist/components/list.d.ts.map +1 -0
  8. package/dist/components/list.js +81 -0
  9. package/dist/components/list.js.map +1 -0
  10. package/dist/components/slot-widget.d.ts +15 -0
  11. package/dist/components/slot-widget.d.ts.map +1 -0
  12. package/dist/components/slot-widget.js +37 -0
  13. package/dist/components/slot-widget.js.map +1 -0
  14. package/dist/errors.d.ts +6 -0
  15. package/dist/errors.d.ts.map +1 -1
  16. package/dist/errors.js +8 -6
  17. package/dist/errors.js.map +1 -1
  18. package/dist/generated/compounds.d.ts +2672 -0
  19. package/dist/generated/compounds.d.ts.map +1 -0
  20. package/dist/generated/compounds.js +2624 -0
  21. package/dist/generated/compounds.js.map +1 -0
  22. package/dist/generated/internal.d.ts +6 -7
  23. package/dist/generated/internal.d.ts.map +1 -1
  24. package/dist/generated/internal.js +3054 -1838
  25. package/dist/generated/internal.js.map +1 -1
  26. package/dist/generated/jsx.d.ts +2096 -4970
  27. package/dist/generated/jsx.d.ts.map +1 -1
  28. package/dist/generated/jsx.js +979 -3862
  29. package/dist/generated/jsx.js.map +1 -1
  30. package/dist/generated/registry.d.ts +1 -0
  31. package/dist/generated/registry.d.ts.map +1 -1
  32. package/dist/generated/registry.js +0 -1
  33. package/dist/generated/registry.js.map +1 -1
  34. package/dist/host-config.d.ts.map +1 -1
  35. package/dist/host-config.js +2 -0
  36. package/dist/host-config.js.map +1 -1
  37. package/dist/index.d.ts +2 -0
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +2 -0
  40. package/dist/index.js.map +1 -1
  41. package/dist/jsx.d.ts +157 -518
  42. package/dist/jsx.d.ts.map +1 -1
  43. package/dist/jsx.js +6 -393
  44. package/dist/jsx.js.map +1 -1
  45. package/dist/metadata.d.ts +1 -1
  46. package/dist/metadata.d.ts.map +1 -1
  47. package/dist/metadata.js +7 -3
  48. package/dist/metadata.js.map +1 -1
  49. package/dist/node.d.ts +0 -4
  50. package/dist/node.d.ts.map +1 -1
  51. package/dist/node.js +19 -41
  52. package/dist/node.js.map +1 -1
  53. package/dist/nodes/alert-dialog.d.ts +14 -0
  54. package/dist/nodes/alert-dialog.d.ts.map +1 -0
  55. package/dist/nodes/alert-dialog.js +41 -0
  56. package/dist/nodes/alert-dialog.js.map +1 -0
  57. package/dist/nodes/animation.d.ts +5 -4
  58. package/dist/nodes/animation.d.ts.map +1 -1
  59. package/dist/nodes/animation.js +65 -49
  60. package/dist/nodes/animation.js.map +1 -1
  61. package/dist/nodes/application.d.ts.map +1 -1
  62. package/dist/nodes/application.js +4 -0
  63. package/dist/nodes/application.js.map +1 -1
  64. package/dist/nodes/column-view-column.d.ts +19 -19
  65. package/dist/nodes/column-view-column.d.ts.map +1 -1
  66. package/dist/nodes/column-view-column.js +130 -119
  67. package/dist/nodes/column-view-column.js.map +1 -1
  68. package/dist/nodes/container-slot.d.ts +3 -1
  69. package/dist/nodes/container-slot.d.ts.map +1 -1
  70. package/dist/nodes/container-slot.js +28 -16
  71. package/dist/nodes/container-slot.js.map +1 -1
  72. package/dist/nodes/drawing-area.d.ts +3 -1
  73. package/dist/nodes/drawing-area.d.ts.map +1 -1
  74. package/dist/nodes/drawing-area.js +20 -22
  75. package/dist/nodes/drawing-area.js.map +1 -1
  76. package/dist/nodes/event-controller.d.ts.map +1 -1
  77. package/dist/nodes/event-controller.js +6 -16
  78. package/dist/nodes/event-controller.js.map +1 -1
  79. package/dist/nodes/fixed-child.d.ts +1 -0
  80. package/dist/nodes/fixed-child.d.ts.map +1 -1
  81. package/dist/nodes/fixed-child.js +13 -0
  82. package/dist/nodes/fixed-child.js.map +1 -1
  83. package/dist/nodes/grid-child.d.ts +1 -0
  84. package/dist/nodes/grid-child.d.ts.map +1 -1
  85. package/dist/nodes/grid-child.js +13 -0
  86. package/dist/nodes/grid-child.js.map +1 -1
  87. package/dist/nodes/internal/accessible.d.ts.map +1 -1
  88. package/dist/nodes/internal/accessible.js.map +1 -1
  89. package/dist/nodes/internal/bound-item.d.ts +4 -0
  90. package/dist/nodes/internal/bound-item.d.ts.map +1 -0
  91. package/dist/nodes/internal/bound-item.js +2 -0
  92. package/dist/nodes/internal/bound-item.js.map +1 -0
  93. package/dist/nodes/internal/construct.d.ts +1 -8
  94. package/dist/nodes/internal/construct.d.ts.map +1 -1
  95. package/dist/nodes/internal/construct.js +30 -54
  96. package/dist/nodes/internal/construct.js.map +1 -1
  97. package/dist/nodes/internal/widget.d.ts.map +1 -1
  98. package/dist/nodes/internal/widget.js +9 -10
  99. package/dist/nodes/internal/widget.js.map +1 -1
  100. package/dist/nodes/list-item-node.d.ts +12 -0
  101. package/dist/nodes/list-item-node.d.ts.map +1 -0
  102. package/dist/nodes/list-item-node.js +45 -0
  103. package/dist/nodes/list-item-node.js.map +1 -0
  104. package/dist/nodes/list.d.ts +100 -0
  105. package/dist/nodes/list.d.ts.map +1 -0
  106. package/dist/nodes/list.js +950 -0
  107. package/dist/nodes/list.js.map +1 -0
  108. package/dist/nodes/notebook-page.d.ts.map +1 -1
  109. package/dist/nodes/notebook-page.js +6 -2
  110. package/dist/nodes/notebook-page.js.map +1 -1
  111. package/dist/nodes/overlay-child.d.ts +2 -0
  112. package/dist/nodes/overlay-child.d.ts.map +1 -1
  113. package/dist/nodes/overlay-child.js +29 -8
  114. package/dist/nodes/overlay-child.js.map +1 -1
  115. package/dist/nodes/spin-row.d.ts +14 -0
  116. package/dist/nodes/spin-row.d.ts.map +1 -0
  117. package/dist/nodes/spin-row.js +46 -0
  118. package/dist/nodes/spin-row.js.map +1 -0
  119. package/dist/nodes/switch-row.d.ts +11 -0
  120. package/dist/nodes/switch-row.d.ts.map +1 -0
  121. package/dist/nodes/switch-row.js +15 -0
  122. package/dist/nodes/switch-row.js.map +1 -0
  123. package/dist/nodes/text-anchor.d.ts.map +1 -1
  124. package/dist/nodes/text-anchor.js +10 -0
  125. package/dist/nodes/text-anchor.js.map +1 -1
  126. package/dist/nodes/text-tag.d.ts.map +1 -1
  127. package/dist/nodes/text-tag.js +45 -39
  128. package/dist/nodes/text-tag.js.map +1 -1
  129. package/dist/nodes/toggle-group.d.ts +12 -6
  130. package/dist/nodes/toggle-group.d.ts.map +1 -1
  131. package/dist/nodes/toggle-group.js +53 -4
  132. package/dist/nodes/toggle-group.js.map +1 -1
  133. package/dist/nodes/widget.d.ts.map +1 -1
  134. package/dist/nodes/widget.js +16 -22
  135. package/dist/nodes/widget.js.map +1 -1
  136. package/dist/nodes/window.d.ts.map +1 -1
  137. package/dist/nodes/window.js +2 -2
  138. package/dist/nodes/window.js.map +1 -1
  139. package/dist/registry.d.ts +0 -2
  140. package/dist/registry.d.ts.map +1 -1
  141. package/dist/registry.js +11 -18
  142. package/dist/registry.js.map +1 -1
  143. package/dist/types.d.ts +3 -2
  144. package/dist/types.d.ts.map +1 -1
  145. package/dist/use-property.d.ts +29 -0
  146. package/dist/use-property.d.ts.map +1 -0
  147. package/dist/use-property.js +44 -0
  148. package/dist/use-property.js.map +1 -0
  149. package/dist/use-setting.d.ts +36 -0
  150. package/dist/use-setting.d.ts.map +1 -0
  151. package/dist/use-setting.js +68 -0
  152. package/dist/use-setting.js.map +1 -0
  153. package/package.json +5 -4
  154. package/src/components/compound.tsx +57 -0
  155. package/src/components/list.tsx +140 -0
  156. package/src/components/slot-widget.tsx +46 -0
  157. package/src/errors.ts +8 -7
  158. package/src/generated/compounds.ts +2741 -0
  159. package/src/generated/internal.ts +3059 -1840
  160. package/src/generated/jsx.ts +2509 -5350
  161. package/src/generated/registry.ts +2 -1
  162. package/src/host-config.ts +2 -0
  163. package/src/index.ts +2 -0
  164. package/src/jsx.ts +167 -581
  165. package/src/metadata.ts +7 -4
  166. package/src/node.ts +23 -39
  167. package/src/nodes/alert-dialog.ts +55 -0
  168. package/src/nodes/animation.ts +67 -60
  169. package/src/nodes/application.ts +5 -0
  170. package/src/nodes/column-view-column.ts +125 -128
  171. package/src/nodes/container-slot.ts +30 -17
  172. package/src/nodes/drawing-area.ts +23 -32
  173. package/src/nodes/event-controller.ts +6 -18
  174. package/src/nodes/fixed-child.ts +13 -0
  175. package/src/nodes/grid-child.ts +13 -0
  176. package/src/nodes/internal/accessible.ts +0 -1
  177. package/src/nodes/internal/bound-item.ts +4 -0
  178. package/src/nodes/internal/construct.ts +38 -68
  179. package/src/nodes/internal/widget.ts +9 -13
  180. package/src/nodes/list-item-node.ts +53 -0
  181. package/src/nodes/list.ts +1082 -0
  182. package/src/nodes/notebook-page.ts +6 -2
  183. package/src/nodes/overlay-child.ts +30 -9
  184. package/src/nodes/spin-row.ts +72 -0
  185. package/src/nodes/switch-row.ts +26 -0
  186. package/src/nodes/text-anchor.ts +9 -0
  187. package/src/nodes/text-tag.ts +45 -40
  188. package/src/nodes/toggle-group.ts +63 -9
  189. package/src/nodes/widget.ts +14 -26
  190. package/src/nodes/window.ts +2 -2
  191. package/src/registry.ts +18 -24
  192. package/src/types.ts +8 -2
  193. package/src/use-property.ts +58 -0
  194. package/src/use-setting.ts +96 -0
  195. package/dist/fiber-root.d.ts +0 -4
  196. package/dist/fiber-root.d.ts.map +0 -1
  197. package/dist/fiber-root.js +0 -6
  198. package/dist/fiber-root.js.map +0 -1
  199. package/dist/nodes/column-view.d.ts +0 -37
  200. package/dist/nodes/column-view.d.ts.map +0 -1
  201. package/dist/nodes/column-view.js +0 -205
  202. package/dist/nodes/column-view.js.map +0 -1
  203. package/dist/nodes/drop-down.d.ts +0 -37
  204. package/dist/nodes/drop-down.d.ts.map +0 -1
  205. package/dist/nodes/drop-down.js +0 -231
  206. package/dist/nodes/drop-down.js.map +0 -1
  207. package/dist/nodes/grid-view.d.ts +0 -30
  208. package/dist/nodes/grid-view.d.ts.map +0 -1
  209. package/dist/nodes/grid-view.js +0 -90
  210. package/dist/nodes/grid-view.js.map +0 -1
  211. package/dist/nodes/internal/base-item-renderer.d.ts +0 -28
  212. package/dist/nodes/internal/base-item-renderer.d.ts.map +0 -1
  213. package/dist/nodes/internal/base-item-renderer.js +0 -85
  214. package/dist/nodes/internal/base-item-renderer.js.map +0 -1
  215. package/dist/nodes/internal/grid-item-renderer.d.ts +0 -20
  216. package/dist/nodes/internal/grid-item-renderer.d.ts.map +0 -1
  217. package/dist/nodes/internal/grid-item-renderer.js +0 -66
  218. package/dist/nodes/internal/grid-item-renderer.js.map +0 -1
  219. package/dist/nodes/internal/header-item-renderer.d.ts +0 -23
  220. package/dist/nodes/internal/header-item-renderer.d.ts.map +0 -1
  221. package/dist/nodes/internal/header-item-renderer.js +0 -87
  222. package/dist/nodes/internal/header-item-renderer.js.map +0 -1
  223. package/dist/nodes/internal/header-renderer-manager.d.ts +0 -13
  224. package/dist/nodes/internal/header-renderer-manager.d.ts.map +0 -1
  225. package/dist/nodes/internal/header-renderer-manager.js +0 -20
  226. package/dist/nodes/internal/header-renderer-manager.js.map +0 -1
  227. package/dist/nodes/internal/list-item-renderer.d.ts +0 -27
  228. package/dist/nodes/internal/list-item-renderer.d.ts.map +0 -1
  229. package/dist/nodes/internal/list-item-renderer.js +0 -131
  230. package/dist/nodes/internal/list-item-renderer.js.map +0 -1
  231. package/dist/nodes/internal/list-store.d.ts +0 -21
  232. package/dist/nodes/internal/list-store.d.ts.map +0 -1
  233. package/dist/nodes/internal/list-store.js +0 -90
  234. package/dist/nodes/internal/list-store.js.map +0 -1
  235. package/dist/nodes/internal/sectioned-list-store.d.ts +0 -50
  236. package/dist/nodes/internal/sectioned-list-store.d.ts.map +0 -1
  237. package/dist/nodes/internal/sectioned-list-store.js +0 -250
  238. package/dist/nodes/internal/sectioned-list-store.js.map +0 -1
  239. package/dist/nodes/internal/selection-helpers.d.ts +0 -12
  240. package/dist/nodes/internal/selection-helpers.d.ts.map +0 -1
  241. package/dist/nodes/internal/selection-helpers.js +0 -25
  242. package/dist/nodes/internal/selection-helpers.js.map +0 -1
  243. package/dist/nodes/internal/selection-model-controller.d.ts +0 -26
  244. package/dist/nodes/internal/selection-model-controller.d.ts.map +0 -1
  245. package/dist/nodes/internal/selection-model-controller.js +0 -82
  246. package/dist/nodes/internal/selection-model-controller.js.map +0 -1
  247. package/dist/nodes/internal/simple-list-store.d.ts +0 -15
  248. package/dist/nodes/internal/simple-list-store.d.ts.map +0 -1
  249. package/dist/nodes/internal/simple-list-store.js +0 -110
  250. package/dist/nodes/internal/simple-list-store.js.map +0 -1
  251. package/dist/nodes/internal/tree-store.d.ts +0 -37
  252. package/dist/nodes/internal/tree-store.d.ts.map +0 -1
  253. package/dist/nodes/internal/tree-store.js +0 -253
  254. package/dist/nodes/internal/tree-store.js.map +0 -1
  255. package/dist/nodes/list-item.d.ts +0 -24
  256. package/dist/nodes/list-item.d.ts.map +0 -1
  257. package/dist/nodes/list-item.js +0 -83
  258. package/dist/nodes/list-item.js.map +0 -1
  259. package/dist/nodes/list-section.d.ts +0 -27
  260. package/dist/nodes/list-section.d.ts.map +0 -1
  261. package/dist/nodes/list-section.js +0 -43
  262. package/dist/nodes/list-section.js.map +0 -1
  263. package/dist/nodes/list-view.d.ts +0 -32
  264. package/dist/nodes/list-view.d.ts.map +0 -1
  265. package/dist/nodes/list-view.js +0 -123
  266. package/dist/nodes/list-view.js.map +0 -1
  267. package/dist/nodes/models/list.d.ts +0 -39
  268. package/dist/nodes/models/list.d.ts.map +0 -1
  269. package/dist/nodes/models/list.js +0 -207
  270. package/dist/nodes/models/list.js.map +0 -1
  271. package/src/fiber-root.ts +0 -20
  272. package/src/nodes/column-view.ts +0 -262
  273. package/src/nodes/drop-down.ts +0 -284
  274. package/src/nodes/grid-view.ts +0 -119
  275. package/src/nodes/internal/base-item-renderer.ts +0 -107
  276. package/src/nodes/internal/grid-item-renderer.ts +0 -78
  277. package/src/nodes/internal/header-item-renderer.ts +0 -105
  278. package/src/nodes/internal/header-renderer-manager.ts +0 -33
  279. package/src/nodes/internal/list-item-renderer.ts +0 -162
  280. package/src/nodes/internal/list-store.ts +0 -107
  281. package/src/nodes/internal/sectioned-list-store.ts +0 -287
  282. package/src/nodes/internal/selection-helpers.ts +0 -35
  283. package/src/nodes/internal/selection-model-controller.ts +0 -119
  284. package/src/nodes/internal/simple-list-store.ts +0 -116
  285. package/src/nodes/internal/tree-store.ts +0 -289
  286. package/src/nodes/list-item.ts +0 -107
  287. package/src/nodes/list-section.ts +0 -64
  288. package/src/nodes/list-view.ts +0 -164
  289. package/src/nodes/models/list.ts +0 -250
@@ -1,33 +0,0 @@
1
- import type * as Gtk from "@gtkx/ffi/gtk";
2
- import type { ReactNode } from "react";
3
- import { HeaderItemRenderer } from "./header-item-renderer.js";
4
- import type { SignalStore } from "./signal-store.js";
5
-
6
- type HeaderRendererConfig = {
7
- signalStore: SignalStore;
8
- isEnabled: () => boolean;
9
- resolveItem: (id: string) => unknown;
10
- setFactory: (factory: Gtk.SignalListItemFactory | null) => void;
11
- };
12
-
13
- export function updateHeaderRenderer(
14
- current: HeaderItemRenderer | null,
15
- config: HeaderRendererConfig,
16
- renderFn: ((item: unknown) => ReactNode) | null | undefined,
17
- ): HeaderItemRenderer | null {
18
- if (renderFn) {
19
- if (!current && config.isEnabled()) {
20
- current = new HeaderItemRenderer(config.signalStore);
21
- current.setResolveItem(config.resolveItem);
22
- config.setFactory(current.getFactory());
23
- }
24
- if (current) {
25
- current.setRenderFn(renderFn);
26
- }
27
- } else if (current) {
28
- config.setFactory(null);
29
- current.dispose();
30
- current = null;
31
- }
32
- return current;
33
- }
@@ -1,162 +0,0 @@
1
- import * as Gtk from "@gtkx/ffi/gtk";
2
- import type { ReactNode } from "react";
3
- import type Reconciler from "react-reconciler";
4
- import { reconciler } from "../../reconciler.js";
5
- import { BaseItemRenderer } from "./base-item-renderer.js";
6
- import type { TreeStore } from "./tree-store.js";
7
-
8
- type RenderItemFn<T> = (item: T | null, row: Gtk.TreeListRow | null) => ReactNode;
9
-
10
- type PendingBind = {
11
- treeListRow: Gtk.TreeListRow;
12
- expander: Gtk.TreeExpander;
13
- id: string;
14
- };
15
-
16
- export class ListItemRenderer extends BaseItemRenderer<TreeStore> {
17
- private expanders = new Map<Gtk.ListItem, Gtk.TreeExpander>();
18
- private setupComplete = new Set<Gtk.ListItem>();
19
- private pendingBinds = new Map<Gtk.ListItem, PendingBind>();
20
- private renderFn: RenderItemFn<unknown> | null = () => null;
21
- private boundItems = new Map<string, { listItem: Gtk.ListItem; treeListRow: Gtk.TreeListRow }>();
22
-
23
- public setRenderFn(renderFn: RenderItemFn<unknown> | null): void {
24
- this.renderFn = renderFn;
25
- this.rebindAllItems();
26
- }
27
-
28
- public rebindAllItems(): void {
29
- for (const id of this.boundItems.keys()) {
30
- this.rebindItem(id);
31
- }
32
- }
33
-
34
- public rebindItem(id: string): void {
35
- const binding = this.boundItems.get(id);
36
- if (!binding) return;
37
-
38
- const fiberRoot = this.fiberRoots.get(binding.listItem);
39
- if (!fiberRoot) return;
40
-
41
- const expander = this.expanders.get(binding.listItem);
42
- if (!expander) return;
43
-
44
- this.renderBind(binding.listItem, expander, binding.treeListRow, id, fiberRoot);
45
- }
46
-
47
- public override dispose(): void {
48
- super.dispose();
49
- this.expanders.clear();
50
- this.setupComplete.clear();
51
- this.pendingBinds.clear();
52
- this.boundItems.clear();
53
- }
54
-
55
- protected override renderItem(_listItem: Gtk.ListItem): ReactNode {
56
- return this.renderFn?.(null, null);
57
- }
58
-
59
- protected override onSetup(listItem: Gtk.ListItem): Gtk.Widget {
60
- const expander = new Gtk.TreeExpander();
61
- const box = this.createBox();
62
- expander.setChild(box);
63
- listItem.setChild(expander);
64
- this.expanders.set(listItem, expander);
65
- return box;
66
- }
67
-
68
- protected override onSetupComplete(listItem: Gtk.ListItem): void {
69
- this.setupComplete.add(listItem);
70
- this.processPendingBind(listItem);
71
- }
72
-
73
- protected override onBind(listItem: Gtk.ListItem, fiberRoot: Reconciler.FiberRoot): void {
74
- const expander = this.expanders.get(listItem);
75
- if (!expander) return;
76
-
77
- const treeListRow = listItem.getItem();
78
- if (!(treeListRow instanceof Gtk.TreeListRow)) return;
79
-
80
- expander.setListRow(treeListRow);
81
-
82
- const stringObject = treeListRow.getItem();
83
- if (!(stringObject instanceof Gtk.StringObject)) return;
84
-
85
- const id = stringObject.getString();
86
- this.boundItems.set(id, { listItem, treeListRow });
87
-
88
- if (!this.setupComplete.has(listItem)) {
89
- this.pendingBinds.set(listItem, { treeListRow, expander, id });
90
- return;
91
- }
92
-
93
- this.renderBind(listItem, expander, treeListRow, id, fiberRoot);
94
- }
95
-
96
- protected override onUnbind(listItem: Gtk.ListItem): void {
97
- const expander = listItem.getChild();
98
- if (expander instanceof Gtk.TreeExpander) {
99
- expander.setListRow(null);
100
- const treeListRow = listItem.getItem();
101
- if (treeListRow instanceof Gtk.TreeListRow) {
102
- const stringObject = treeListRow.getItem();
103
- if (stringObject instanceof Gtk.StringObject) {
104
- this.boundItems.delete(stringObject.getString());
105
- }
106
- }
107
- }
108
- }
109
-
110
- protected override onTeardown(listItem: Gtk.ListItem): void {
111
- this.expanders.delete(listItem);
112
- this.setupComplete.delete(listItem);
113
- this.pendingBinds.delete(listItem);
114
- }
115
-
116
- private processPendingBind(listItem: Gtk.ListItem): void {
117
- const pending = this.pendingBinds.get(listItem);
118
- if (!pending) return;
119
-
120
- this.pendingBinds.delete(listItem);
121
- const fiberRoot = this.fiberRoots.get(listItem);
122
- if (fiberRoot) {
123
- this.renderBind(listItem, pending.expander, pending.treeListRow, pending.id, fiberRoot);
124
- }
125
- }
126
-
127
- private renderBind(
128
- listItem: Gtk.ListItem,
129
- expander: Gtk.TreeExpander,
130
- treeListRow: Gtk.TreeListRow,
131
- id: string,
132
- fiberRoot: Reconciler.FiberRoot,
133
- ): void {
134
- const itemData = this.getStore().getItem(id);
135
-
136
- if (itemData) {
137
- expander.setIndentForDepth(itemData.indentForDepth ?? true);
138
- expander.setHideExpander(itemData.hideExpander ?? false);
139
-
140
- if (itemData.indentForIcon !== undefined) {
141
- expander.setIndentForIcon(itemData.indentForIcon);
142
- } else {
143
- expander.setIndentForIcon(treeListRow.isExpandable());
144
- }
145
- } else {
146
- expander.setIndentForIcon(treeListRow.isExpandable());
147
- }
148
-
149
- const element = this.renderFn?.(itemData?.value ?? null, treeListRow);
150
-
151
- reconciler.getInstance().updateContainer(element, fiberRoot, null, () => {
152
- if (this.tornDown.has(listItem)) return;
153
- if (this.estimatedItemHeight !== null) return;
154
- const currentExpander = this.expanders.get(listItem);
155
- if (!currentExpander) return;
156
- const box = currentExpander.getChild();
157
- if (box) {
158
- this.clearBoxSizeRequest(box);
159
- }
160
- });
161
- }
162
- }
@@ -1,107 +0,0 @@
1
- import { SectionedListStore } from "./sectioned-list-store.js";
2
-
3
- type ItemUpdatedCallback = (id: string) => void;
4
-
5
- export class ListStore extends SectionedListStore {
6
- private items = new Map<string, unknown>();
7
- private onItemUpdated: ItemUpdatedCallback | null = null;
8
-
9
- public setOnItemUpdated(callback: ItemUpdatedCallback | null): void {
10
- this.onItemUpdated = callback;
11
- }
12
-
13
- protected override getInitialPendingBatch(): string[] | null {
14
- return null;
15
- }
16
-
17
- protected override getModelString(itemId: string, _item: unknown): string {
18
- return itemId;
19
- }
20
-
21
- protected override onItemAdded(itemId: string, item: unknown): void {
22
- this.items.set(itemId, item);
23
- }
24
-
25
- protected override onItemRemoved(itemId: string): void {
26
- this.items.delete(itemId);
27
- }
28
-
29
- public addItem(id: string, item: unknown): void {
30
- this.flushRemovals();
31
- this.items.set(id, item);
32
-
33
- const existingIndex = this.idToIndex.get(id);
34
- if (existingIndex !== undefined) {
35
- this.model.remove(existingIndex);
36
- this.ids.splice(existingIndex, 1);
37
- this.rebuildIndices(existingIndex);
38
- }
39
-
40
- this.idToIndex.set(id, this.ids.length);
41
- this.ids.push(id);
42
-
43
- if (this.pendingBatch) {
44
- this.pendingBatch.push(id);
45
- } else {
46
- this.model.append(id);
47
- }
48
- }
49
-
50
- public insertItemBefore(id: string, beforeId: string, item: unknown): void {
51
- this.flushRemovals();
52
- this.items.set(id, item);
53
-
54
- const existingIndex = this.idToIndex.get(id);
55
- if (existingIndex !== undefined) {
56
- this.model.remove(existingIndex);
57
- this.ids.splice(existingIndex, 1);
58
- this.idToIndex.delete(id);
59
- this.rebuildIndices(existingIndex);
60
- }
61
-
62
- const beforeIndex = this.idToIndex.get(beforeId);
63
- if (beforeIndex === undefined) {
64
- this.idToIndex.set(id, this.ids.length);
65
- this.ids.push(id);
66
- this.model.append(id);
67
- } else {
68
- this.ids.splice(beforeIndex, 0, id);
69
- this.rebuildIndices(beforeIndex);
70
- this.model.splice(beforeIndex, 0, [id]);
71
- }
72
- }
73
-
74
- public updateItem(id: string, item: unknown): void {
75
- if (this.items.has(id)) {
76
- this.items.set(id, item);
77
- this.onItemUpdated?.(id);
78
- } else {
79
- this.addItem(id, item);
80
- }
81
- }
82
-
83
- public getItem(id: string): unknown {
84
- return this.items.get(id);
85
- }
86
-
87
- public getHeaderValue(itemId: string): unknown {
88
- const sectionId = this.itemToSection.get(itemId);
89
- if (sectionId) {
90
- return this.headerValues.get(sectionId);
91
- }
92
- return undefined;
93
- }
94
-
95
- public getHeaderValueById(sectionId: string): unknown {
96
- return this.headerValues.get(sectionId);
97
- }
98
-
99
- public getStringList(): import("@gtkx/ffi/gtk").StringList {
100
- return this.model;
101
- }
102
-
103
- public getNItems(): number {
104
- this.flushRemovals();
105
- return this.ids.length;
106
- }
107
- }
@@ -1,287 +0,0 @@
1
- import * as Gio from "@gtkx/ffi/gio";
2
- import * as GObject from "@gtkx/ffi/gobject";
3
- import * as Gtk from "@gtkx/ffi/gtk";
4
-
5
- interface SectionData {
6
- id: string;
7
- model: Gtk.StringList;
8
- itemIds: string[];
9
- pendingBatch: string[] | null;
10
- }
11
-
12
- export abstract class SectionedListStore {
13
- protected ids: string[] = [];
14
- protected idToIndex = new Map<string, number>();
15
- protected model = new Gtk.StringList();
16
- protected pendingBatch: string[] | null = null;
17
- private pendingRemovals: Set<string> | null = null;
18
- private flushScheduled = false;
19
-
20
- protected sectioned = false;
21
- protected sections: SectionData[] = [];
22
- protected sectionById = new Map<string, SectionData>();
23
- protected itemToSection = new Map<string, string>();
24
- protected headerValues = new Map<string, unknown>();
25
- protected sectionContainer: Gio.ListStore | null = null;
26
- protected flatModel: Gtk.FlattenListModel | null = null;
27
-
28
- public enableSections(): void {
29
- if (this.sectioned) return;
30
- this.sectioned = true;
31
- this.sectionContainer = new Gio.ListStore(GObject.typeFromName("GtkStringList"));
32
- this.flatModel = new Gtk.FlattenListModel(this.sectionContainer);
33
- }
34
-
35
- public beginBatch(): void {
36
- if (this.sectioned) {
37
- for (const section of this.sections) {
38
- section.pendingBatch = [];
39
- }
40
- } else {
41
- this.pendingBatch = [];
42
- }
43
- }
44
-
45
- public flushBatch(): void {
46
- if (this.sectioned) {
47
- for (const section of this.sections) {
48
- const batch = section.pendingBatch;
49
- section.pendingBatch = null;
50
- if (batch && batch.length > 0) {
51
- section.model.splice(0, 0, batch);
52
- }
53
- }
54
- } else {
55
- const batch = this.pendingBatch;
56
- this.pendingBatch = null;
57
- if (batch && batch.length > 0) {
58
- this.model.splice(0, 0, batch);
59
- }
60
- }
61
- }
62
-
63
- public addSection(id: string, value: unknown): void {
64
- if (!this.sectioned) this.enableSections();
65
-
66
- this.headerValues.set(id, value);
67
- if (this.sectionById.has(id)) return;
68
-
69
- const sectionModel = new Gtk.StringList();
70
- const section: SectionData = {
71
- id,
72
- model: sectionModel,
73
- itemIds: [],
74
- pendingBatch: this.getInitialPendingBatch(),
75
- };
76
- this.sections.push(section);
77
- this.sectionById.set(id, section);
78
- this.sectionContainer?.append(sectionModel);
79
- }
80
-
81
- public removeSection(id: string): void {
82
- const section = this.sectionById.get(id);
83
- if (!section) return;
84
-
85
- for (const itemId of [...section.itemIds]) {
86
- this.removeItemFromSection(itemId);
87
- }
88
-
89
- const sectionIndex = this.sections.indexOf(section);
90
- if (sectionIndex >= 0) {
91
- this.sections.splice(sectionIndex, 1);
92
- this.sectionContainer?.remove(sectionIndex);
93
- }
94
- this.sectionById.delete(id);
95
- this.headerValues.delete(id);
96
- }
97
-
98
- public removeItemFromSection(itemId: string): void {
99
- const sectionId = this.itemToSection.get(itemId);
100
- if (!sectionId) return;
101
-
102
- const section = this.sectionById.get(sectionId);
103
- if (!section) return;
104
-
105
- const indexInSection = section.itemIds.indexOf(itemId);
106
- if (indexInSection >= 0) {
107
- section.itemIds.splice(indexInSection, 1);
108
- section.model.remove(indexInSection);
109
- }
110
-
111
- this.itemToSection.delete(itemId);
112
- this.onItemRemoved(itemId);
113
- this.rebuildGlobalIndices();
114
- }
115
-
116
- public removeItem(id: string): void {
117
- if (this.sectioned) {
118
- this.removeItemFromSection(id);
119
- return;
120
- }
121
-
122
- if (!this.idToIndex.has(id)) return;
123
-
124
- if (!this.pendingRemovals) {
125
- this.pendingRemovals = new Set();
126
- if (!this.flushScheduled) {
127
- this.flushScheduled = true;
128
- queueMicrotask(() => this.flushRemovals());
129
- }
130
- }
131
- this.pendingRemovals.add(id);
132
- this.onItemRemoved(id);
133
- }
134
-
135
- public flushRemovals(): void {
136
- this.flushScheduled = false;
137
- const removals = this.pendingRemovals;
138
- if (!removals || removals.size === 0) {
139
- this.pendingRemovals = null;
140
- return;
141
- }
142
- this.pendingRemovals = null;
143
-
144
- const indices: number[] = [];
145
- for (const id of removals) {
146
- const index = this.idToIndex.get(id);
147
- if (index !== undefined) {
148
- indices.push(index);
149
- this.idToIndex.delete(id);
150
- }
151
- }
152
-
153
- if (indices.length === 0) return;
154
-
155
- indices.sort((a, b) => a - b);
156
-
157
- let i = indices.length - 1;
158
- while (i >= 0) {
159
- let rangeStart = indices[i] ?? 0;
160
- const rangeEnd = rangeStart;
161
-
162
- while (i > 0) {
163
- const prev = indices[i - 1];
164
- if (prev !== rangeStart - 1) break;
165
- i--;
166
- rangeStart = prev ?? 0;
167
- }
168
-
169
- const count = rangeEnd - rangeStart + 1;
170
- this.model.splice(rangeStart, count);
171
- this.ids.splice(rangeStart, count);
172
-
173
- i--;
174
- }
175
-
176
- this.rebuildIndices(0);
177
- }
178
-
179
- public addItemToSection(sectionId: string, itemId: string, item: unknown): void {
180
- const section = this.sectionById.get(sectionId);
181
- if (!section) return;
182
-
183
- this.onItemAdded(itemId, item);
184
- this.itemToSection.set(itemId, sectionId);
185
- section.itemIds.push(itemId);
186
- this.rebuildGlobalIndices();
187
-
188
- const modelString = this.getModelString(itemId, item);
189
- if (section.pendingBatch) {
190
- section.pendingBatch.push(modelString);
191
- } else {
192
- section.model.append(modelString);
193
- }
194
- }
195
-
196
- public addItemsToSection(sectionId: string, items: { itemId: string; item: unknown }[]): void {
197
- const section = this.sectionById.get(sectionId);
198
- if (!section) return;
199
- if (items.length === 0) return;
200
-
201
- const modelStrings: string[] = [];
202
- for (const { itemId, item } of items) {
203
- this.onItemAdded(itemId, item);
204
- this.itemToSection.set(itemId, sectionId);
205
- section.itemIds.push(itemId);
206
- modelStrings.push(this.getModelString(itemId, item));
207
- }
208
-
209
- this.rebuildGlobalIndices();
210
-
211
- if (section.pendingBatch) {
212
- for (const s of modelStrings) {
213
- section.pendingBatch.push(s);
214
- }
215
- } else {
216
- section.model.splice(section.model.getNItems(), 0, modelStrings);
217
- }
218
- }
219
-
220
- public insertItemToSectionBefore(sectionId: string, itemId: string, beforeId: string, item: unknown): void {
221
- const section = this.sectionById.get(sectionId);
222
- if (!section) return;
223
-
224
- this.onItemAdded(itemId, item);
225
- this.itemToSection.set(itemId, sectionId);
226
-
227
- const modelString = this.getModelString(itemId, item);
228
- const beforeIndex = section.itemIds.indexOf(beforeId);
229
- if (beforeIndex >= 0) {
230
- section.itemIds.splice(beforeIndex, 0, itemId);
231
- this.rebuildGlobalIndices();
232
- section.model.splice(beforeIndex, 0, [modelString]);
233
- } else {
234
- section.itemIds.push(itemId);
235
- this.rebuildGlobalIndices();
236
- section.model.append(modelString);
237
- }
238
- }
239
-
240
- public updateHeaderValue(sectionId: string, value: unknown): void {
241
- this.headerValues.set(sectionId, value);
242
- }
243
-
244
- public isSectioned(): boolean {
245
- return this.sectioned;
246
- }
247
-
248
- public getModel(): Gio.ListModel {
249
- if (this.sectioned && this.flatModel) return this.flatModel;
250
- return this.model;
251
- }
252
-
253
- public getIdAtIndex(index: number): string | null {
254
- this.flushRemovals();
255
- return this.ids[index] ?? null;
256
- }
257
-
258
- public getIndexById(id: string): number | null {
259
- this.flushRemovals();
260
- return this.idToIndex.get(id) ?? null;
261
- }
262
-
263
- protected rebuildGlobalIndices(): void {
264
- this.ids = [];
265
- this.idToIndex.clear();
266
- for (const section of this.sections) {
267
- for (const itemId of section.itemIds) {
268
- this.idToIndex.set(itemId, this.ids.length);
269
- this.ids.push(itemId);
270
- }
271
- }
272
- }
273
-
274
- protected rebuildIndices(fromIndex: number): void {
275
- for (let i = fromIndex; i < this.ids.length; i++) {
276
- this.idToIndex.set(this.ids[i] as string, i);
277
- }
278
- }
279
-
280
- protected abstract getInitialPendingBatch(): string[] | null;
281
-
282
- protected abstract getModelString(itemId: string, item: unknown): string;
283
-
284
- protected onItemAdded(_itemId: string, _item: unknown): void {}
285
-
286
- protected onItemRemoved(_itemId: string): void {}
287
- }
@@ -1,35 +0,0 @@
1
- import * as Gtk from "@gtkx/ffi/gtk";
2
-
3
- type StoreWithIdLookup = {
4
- getIdAtIndex(index: number): string | null;
5
- };
6
-
7
- type StoreWithIndexLookup = {
8
- getIndexById(id: string): number | null;
9
- getNItems(): number;
10
- };
11
-
12
- export function getSelectionFromStore(selection: Gtk.Bitset, store: StoreWithIdLookup): string[] {
13
- const size = selection.getSize();
14
- const ids: string[] = [];
15
- for (let i = 0; i < size; i++) {
16
- const index = selection.getNth(i);
17
- const id = store.getIdAtIndex(index);
18
- if (id !== null) {
19
- ids.push(id);
20
- }
21
- }
22
- return ids;
23
- }
24
-
25
- export function resolveSelectionIndices(ids: string[], store: StoreWithIndexLookup): Gtk.Bitset {
26
- const nItems = store.getNItems();
27
- const selected = new Gtk.Bitset();
28
- for (const id of ids) {
29
- const index = store.getIndexById(id);
30
- if (index !== null && index < nItems) {
31
- selected.add(index);
32
- }
33
- }
34
- return selected;
35
- }