@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
package/src/metadata.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { NativeClass } from "@gtkx/ffi";
2
- import { CONSTRUCT_ONLY_PROPS, PROPS, SIGNALS } from "./generated/internal.js";
2
+ import { CONSTRUCTION_META, PROPS, SIGNALS } from "./generated/internal.js";
3
3
  import type { Container } from "./types.js";
4
4
 
5
5
  const walkPrototypeChain = <T>(instance: Container, lookup: (typeName: string) => T | null): T | null => {
@@ -27,12 +27,15 @@ const walkPrototypeChain = <T>(instance: Container, lookup: (typeName: string) =
27
27
  return null;
28
28
  };
29
29
 
30
- export const resolvePropMeta = (instance: Container, key: string): [string | null, string] | null =>
30
+ export const resolvePropMeta = (instance: Container, key: string): string | null =>
31
31
  walkPrototypeChain(instance, (typeName) => PROPS[typeName]?.[key] ?? null);
32
32
 
33
33
  export const isConstructOnlyProp = (instance: Container, key: string): boolean =>
34
- walkPrototypeChain(instance, (typeName) => (CONSTRUCT_ONLY_PROPS[typeName]?.[key] !== undefined ? true : null)) ??
35
- false;
34
+ walkPrototypeChain(instance, (typeName) => {
35
+ const meta = CONSTRUCTION_META[typeName];
36
+ if (!meta || !(key in meta)) return null;
37
+ return meta[key]?.constructOnly === true;
38
+ }) ?? false;
36
39
 
37
40
  export const resolveSignal = (instance: Container, propName: string): string | null => {
38
41
  if (propName === "onNotify") return "notify";
package/src/node.ts CHANGED
@@ -14,8 +14,6 @@ export class Node<TContainer = any, TProps = any, TParent extends Node = any, TC
14
14
  rootContainer: Container;
15
15
  parent: TParent | null = null;
16
16
  children: TChild[] = [];
17
- private childIndices = new Map<TChild, number>();
18
- private childrenDirty = false;
19
17
 
20
18
  constructor(typeName: string, props: TProps, container: TContainer, rootContainer: Container) {
21
19
  this.typeName = typeName;
@@ -37,6 +35,7 @@ export class Node<TContainer = any, TProps = any, TParent extends Node = any, TC
37
35
  if (parent !== null && !this.isValidParent(parent)) {
38
36
  throw new Error(`Cannot add '${this.typeName}' to '${parent.typeName}'`);
39
37
  }
38
+
40
39
  this.parent = parent;
41
40
  }
42
41
 
@@ -45,64 +44,49 @@ export class Node<TContainer = any, TProps = any, TParent extends Node = any, TC
45
44
  }
46
45
 
47
46
  public appendChild(child: TChild): void {
48
- if (this.childrenDirty) this.flushChildRemovals();
49
47
  if (!this.isValidChild(child)) {
50
48
  throw new Error(`Cannot append '${child.typeName}' to '${this.typeName}'`);
51
49
  }
52
- this.childIndices.set(child, this.children.length);
50
+
51
+ const existingIndex = this.children.indexOf(child);
52
+ if (existingIndex !== -1) {
53
+ this.children.splice(existingIndex, 1);
54
+ }
53
55
  this.children.push(child);
54
- child.setParent(this);
56
+
57
+ if (child.parent !== this) {
58
+ child.setParent(this);
59
+ }
55
60
  }
56
61
 
57
62
  public removeChild(child: TChild): void {
58
- if (!this.childIndices.has(child)) return;
59
63
  child.setParent(null);
60
- this.childIndices.delete(child);
61
- if (!this.childrenDirty) {
62
- this.childrenDirty = true;
63
- queueMicrotask(() => this.flushChildRemovals());
64
+ const index = this.children.indexOf(child);
65
+
66
+ if (index !== -1) {
67
+ this.children.splice(index, 1);
64
68
  }
65
69
  }
66
70
 
67
71
  public insertBefore(child: TChild, before: TChild): void {
68
- if (this.childrenDirty) this.flushChildRemovals();
69
-
70
- const beforeIndex = this.childIndices.get(before);
71
- if (beforeIndex === undefined) {
72
- throw new Error(`Cannot find 'before' child '${before.typeName}' in '${this.typeName}'`);
72
+ if (!this.isValidChild(child)) {
73
+ throw new Error(`Cannot insert '${child.typeName}' into '${this.typeName}'`);
73
74
  }
74
75
 
75
- const existingIndex = this.childIndices.get(child);
76
- if (existingIndex !== undefined) {
76
+ const existingIndex = this.children.indexOf(child);
77
+ if (existingIndex !== -1) {
77
78
  this.children.splice(existingIndex, 1);
78
- const adjustedIndex = existingIndex < beforeIndex ? beforeIndex - 1 : beforeIndex;
79
- this.children.splice(adjustedIndex, 0, child);
80
- this.rebuildChildIndices(Math.min(existingIndex, adjustedIndex));
81
- return;
82
79
  }
83
80
 
84
- if (!this.isValidChild(child)) {
85
- throw new Error(`Cannot insert '${child.typeName}' into '${this.typeName}'`);
81
+ const beforeIndex = this.children.indexOf(before);
82
+ if (beforeIndex === -1) {
83
+ throw new Error(`Cannot find 'before' child '${before.typeName}' in '${this.typeName}'`);
86
84
  }
87
85
 
88
86
  this.children.splice(beforeIndex, 0, child);
89
- this.rebuildChildIndices(beforeIndex);
90
- child.setParent(this);
91
- }
92
-
93
- private flushChildRemovals(): void {
94
- if (!this.childrenDirty) return;
95
- this.childrenDirty = false;
96
- this.children = this.children.filter((c) => this.childIndices.has(c));
97
- this.childIndices.clear();
98
- for (let i = 0; i < this.children.length; i++) {
99
- this.childIndices.set(this.children[i] as TChild, i);
100
- }
101
- }
102
87
 
103
- private rebuildChildIndices(fromIndex: number): void {
104
- for (let i = fromIndex; i < this.children.length; i++) {
105
- this.childIndices.set(this.children[i] as TChild, i);
88
+ if (child.parent !== this) {
89
+ child.setParent(this);
106
90
  }
107
91
  }
108
92
 
@@ -0,0 +1,55 @@
1
+ import type * as Adw from "@gtkx/ffi/adw";
2
+ import type { AdwAlertDialogProps, AlertDialogResponseProps } from "../jsx.js";
3
+ import { DialogNode } from "./dialog.js";
4
+ import { filterProps, hasChanged } from "./internal/props.js";
5
+
6
+ const OWN_PROPS = ["responses"] as const;
7
+
8
+ type Props = Pick<AdwAlertDialogProps, (typeof OWN_PROPS)[number]>;
9
+
10
+ export class AlertDialogNode extends DialogNode {
11
+ private managedResponseIds: string[] = [];
12
+
13
+ public override commitUpdate(oldProps: Props | null, newProps: Props): void {
14
+ super.commitUpdate(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
15
+ this.applyOwnProps(oldProps, newProps);
16
+ }
17
+
18
+ public override detachDeletedInstance(): void {
19
+ this.clearResponses();
20
+ super.detachDeletedInstance();
21
+ }
22
+
23
+ private applyOwnProps(oldProps: Props | null, newProps: Props): void {
24
+ if (hasChanged(oldProps, newProps, "responses")) {
25
+ this.syncResponses(newProps.responses ?? []);
26
+ }
27
+ }
28
+
29
+ private syncResponses(newResponses: AlertDialogResponseProps[]): void {
30
+ const dialog = this.container as Adw.AlertDialog;
31
+ this.clearResponses();
32
+
33
+ for (const response of newResponses) {
34
+ dialog.addResponse(response.id, response.label);
35
+
36
+ if (response.appearance !== undefined) {
37
+ dialog.setResponseAppearance(response.id, response.appearance);
38
+ }
39
+
40
+ if (response.enabled !== undefined) {
41
+ dialog.setResponseEnabled(response.id, response.enabled);
42
+ }
43
+
44
+ this.managedResponseIds.push(response.id);
45
+ }
46
+ }
47
+
48
+ private clearResponses(): void {
49
+ const dialog = this.container as Adw.AlertDialog;
50
+ for (const id of this.managedResponseIds) {
51
+ dialog.removeResponse(id);
52
+ }
53
+ this.managedResponseIds = [];
54
+ }
55
+ }
@@ -1,13 +1,19 @@
1
1
  import * as Adw from "@gtkx/ffi/adw";
2
2
  import * as Gdk from "@gtkx/ffi/gdk";
3
3
  import * as Gtk from "@gtkx/ffi/gtk";
4
- import type { AnimatableProperties, AnimationProps, SpringTransition, TimedTransition } from "../jsx.js";
4
+ import type { AdwSpringAnimationProps, AdwTimedAnimationProps, AnimatableProperties, AnimationProps } from "../jsx.js";
5
5
  import type { Node } from "../node.js";
6
6
  import type { Container } from "../types.js";
7
7
  import { attachChild, detachChild, isAttachedTo } from "./internal/widget.js";
8
8
  import { VirtualNode } from "./virtual.js";
9
9
  import { WidgetNode } from "./widget.js";
10
10
 
11
+ type SetChildContainer = { setChild: (child: Gtk.Widget | null) => void };
12
+
13
+ function hasSetChild(obj: unknown): obj is SetChildContainer {
14
+ return obj !== null && typeof obj === "object" && "setChild" in obj && typeof obj.setChild === "function";
15
+ }
16
+
11
17
  let animationCounter = 0;
12
18
 
13
19
  const DEFAULT_TIMED_DURATION = 300;
@@ -15,14 +21,14 @@ const DEFAULT_SPRING_DAMPING = 1;
15
21
  const DEFAULT_SPRING_MASS = 1;
16
22
  const DEFAULT_SPRING_STIFFNESS = 100;
17
23
 
18
- export class AnimationNode extends VirtualNode<AnimationProps, WidgetNode, WidgetNode> {
24
+ export class AnimationNode extends VirtualNode<AnimationProps, Node, WidgetNode> {
19
25
  private className: string;
20
26
  private provider: Gtk.CssProvider | null = null;
21
27
  private display: Gdk.Display | null = null;
22
28
  private currentAnimation: Adw.Animation | null = null;
23
29
  private currentValues: AnimatableProperties = {};
24
30
  private isExiting = false;
25
- private detachedParentWidget: Gtk.Widget | null = null;
31
+ private detachedParentContainer: unknown = null;
26
32
 
27
33
  constructor(typeName: string, props: AnimationProps, container: undefined, rootContainer: Container) {
28
34
  super(typeName, props, container, rootContainer);
@@ -33,13 +39,13 @@ export class AnimationNode extends VirtualNode<AnimationProps, WidgetNode, Widge
33
39
  return child instanceof WidgetNode;
34
40
  }
35
41
 
36
- public override isValidParent(parent: Node): boolean {
37
- return parent instanceof WidgetNode;
42
+ public override isValidParent(_parent: Node): boolean {
43
+ return true;
38
44
  }
39
45
 
40
- public override setParent(parent: WidgetNode | null): void {
46
+ public override setParent(parent: Node | null): void {
41
47
  if (!parent && this.parent) {
42
- this.detachedParentWidget = this.parent.container;
48
+ this.detachedParentContainer = this.parent.container;
43
49
  }
44
50
 
45
51
  super.setParent(parent);
@@ -118,45 +124,55 @@ export class AnimationNode extends VirtualNode<AnimationProps, WidgetNode, Widge
118
124
  }
119
125
 
120
126
  private onChildChange(oldChild: Gtk.Widget | null): void {
121
- const parentWidget = this.parent?.container ?? null;
127
+ const parentContainer = this.parent?.container ?? null;
122
128
  const childWidget = this.children[0]?.container ?? null;
123
129
 
124
130
  if (oldChild && this.provider) {
125
131
  oldChild.removeCssClass(this.className);
126
132
  }
127
133
 
128
- if (oldChild && parentWidget && isAttachedTo(oldChild, parentWidget)) {
129
- detachChild(oldChild, parentWidget);
134
+ if (oldChild && parentContainer instanceof Gtk.Widget && isAttachedTo(oldChild, parentContainer)) {
135
+ detachChild(oldChild, parentContainer);
136
+ } else if (oldChild && parentContainer && hasSetChild(parentContainer)) {
137
+ parentContainer.setChild(null);
130
138
  }
131
139
 
132
- if (childWidget && parentWidget) {
133
- attachChild(childWidget, parentWidget);
140
+ if (childWidget && parentContainer instanceof Gtk.Widget) {
141
+ attachChild(childWidget, parentContainer);
142
+ this.setupAnimatedChild(childWidget);
143
+ } else if (childWidget && parentContainer && hasSetChild(parentContainer)) {
144
+ parentContainer.setChild(childWidget);
145
+ this.setupAnimatedChild(childWidget);
146
+ }
147
+ }
134
148
 
135
- this.setupCssProvider();
136
- childWidget.addCssClass(this.className);
149
+ private setupAnimatedChild(childWidget: Gtk.Widget): void {
150
+ this.setupCssProvider();
151
+ childWidget.addCssClass(this.className);
137
152
 
138
- const initial = this.props.initial;
139
- const animate = this.props.animate;
153
+ const initial = this.props.initial;
154
+ const animate = this.props.animate;
140
155
 
141
- if (initial === false || !this.props.animateOnMount) {
142
- if (animate) {
143
- this.currentValues = { ...animate };
144
- this.applyValues(this.currentValues);
145
- }
146
- } else {
147
- const initialValues = initial ?? animate ?? {};
148
- this.currentValues = { ...initialValues };
156
+ if (initial === false || !this.props.animateOnMount) {
157
+ if (animate) {
158
+ this.currentValues = { ...animate };
149
159
  this.applyValues(this.currentValues);
150
160
  }
161
+ } else {
162
+ const initialValues = initial ?? animate ?? {};
163
+ this.currentValues = { ...initialValues };
164
+ this.applyValues(this.currentValues);
151
165
  }
152
166
  }
153
167
 
154
168
  private detachChildFromParentWidget(): void {
155
- const parentWidget = this.parent?.container ?? this.detachedParentWidget;
169
+ const parentContainer = this.parent?.container ?? this.detachedParentContainer;
156
170
  const childWidget = this.children[0]?.container ?? null;
157
171
 
158
- if (childWidget && parentWidget && isAttachedTo(childWidget, parentWidget)) {
159
- detachChild(childWidget, parentWidget);
172
+ if (childWidget && parentContainer instanceof Gtk.Widget && isAttachedTo(childWidget, parentContainer)) {
173
+ detachChild(childWidget, parentContainer);
174
+ } else if (childWidget && parentContainer && hasSetChild(parentContainer)) {
175
+ parentContainer.setChild(null);
160
176
  }
161
177
  }
162
178
 
@@ -227,8 +243,7 @@ export class AnimationNode extends VirtualNode<AnimationProps, WidgetNode, Widge
227
243
 
228
244
  this.currentAnimation = animation;
229
245
 
230
- const transition = this.props.transition;
231
- const delay = transition?.delay ?? 0;
246
+ const delay = (this.props as AdwTimedAnimationProps | AdwSpringAnimationProps).delay ?? 0;
232
247
 
233
248
  if (delay > 0) {
234
249
  setTimeout(() => {
@@ -242,61 +257,53 @@ export class AnimationNode extends VirtualNode<AnimationProps, WidgetNode, Widge
242
257
  }
243
258
 
244
259
  private createAnimation(widget: Gtk.Widget, target: Adw.CallbackAnimationTarget): Adw.Animation {
245
- const transition = this.props.transition;
246
-
247
- if (transition?.mode === "spring") {
248
- return this.createSpringAnimation(widget, target, transition);
260
+ if (this.typeName === "AdwSpringAnimation") {
261
+ return this.createSpringAnimation(widget, target);
249
262
  }
250
263
 
251
- return this.createTimedAnimation(widget, target, transition);
264
+ return this.createTimedAnimation(widget, target);
252
265
  }
253
266
 
254
- private createTimedAnimation(
255
- widget: Gtk.Widget,
256
- target: Adw.CallbackAnimationTarget,
257
- transition: TimedTransition | undefined,
258
- ): Adw.TimedAnimation {
259
- const duration = transition?.duration ?? DEFAULT_TIMED_DURATION;
267
+ private createTimedAnimation(widget: Gtk.Widget, target: Adw.CallbackAnimationTarget): Adw.TimedAnimation {
268
+ const props = this.props as AdwTimedAnimationProps;
269
+ const duration = props.duration ?? DEFAULT_TIMED_DURATION;
260
270
 
261
271
  const animation = new Adw.TimedAnimation(widget, 0, 1, duration, target);
262
272
 
263
- if (transition?.easing !== undefined) {
264
- animation.setEasing(transition.easing);
273
+ if (props.easing !== undefined) {
274
+ animation.setEasing(props.easing);
265
275
  }
266
276
 
267
- if (transition?.repeat !== undefined) {
268
- animation.setRepeatCount(transition.repeat);
277
+ if (props.repeat !== undefined) {
278
+ animation.setRepeatCount(props.repeat);
269
279
  }
270
280
 
271
- if (transition?.reverse !== undefined) {
272
- animation.setReverse(transition.reverse);
281
+ if (props.reverse !== undefined) {
282
+ animation.setReverse(props.reverse);
273
283
  }
274
284
 
275
- if (transition?.alternate !== undefined) {
276
- animation.setAlternate(transition.alternate);
285
+ if (props.alternate !== undefined) {
286
+ animation.setAlternate(props.alternate);
277
287
  }
278
288
 
279
289
  return animation;
280
290
  }
281
291
 
282
- private createSpringAnimation(
283
- widget: Gtk.Widget,
284
- target: Adw.CallbackAnimationTarget,
285
- transition: SpringTransition,
286
- ): Adw.SpringAnimation {
287
- const damping = transition.damping ?? DEFAULT_SPRING_DAMPING;
288
- const mass = transition.mass ?? DEFAULT_SPRING_MASS;
289
- const stiffness = transition.stiffness ?? DEFAULT_SPRING_STIFFNESS;
292
+ private createSpringAnimation(widget: Gtk.Widget, target: Adw.CallbackAnimationTarget): Adw.SpringAnimation {
293
+ const props = this.props as AdwSpringAnimationProps;
294
+ const damping = props.damping ?? DEFAULT_SPRING_DAMPING;
295
+ const mass = props.mass ?? DEFAULT_SPRING_MASS;
296
+ const stiffness = props.stiffness ?? DEFAULT_SPRING_STIFFNESS;
290
297
 
291
298
  const springParams = new Adw.SpringParams(damping, mass, stiffness);
292
299
  const animation = new Adw.SpringAnimation(widget, 0, 1, springParams, target);
293
300
 
294
- if (transition.initialVelocity !== undefined) {
295
- animation.setInitialVelocity(transition.initialVelocity);
301
+ if (props.initialVelocity !== undefined) {
302
+ animation.setInitialVelocity(props.initialVelocity);
296
303
  }
297
304
 
298
- if (transition.clamp !== undefined) {
299
- animation.setClamp(transition.clamp);
305
+ if (props.clamp !== undefined) {
306
+ animation.setClamp(props.clamp);
300
307
  }
301
308
 
302
309
  return animation;
@@ -3,6 +3,7 @@ import { Node } from "../node.js";
3
3
  import type { Container, Props } from "../types.js";
4
4
  import { MenuNode } from "./menu.js";
5
5
  import { MenuModel } from "./models/menu.js";
6
+ import { WindowNode } from "./window.js";
6
7
 
7
8
  export class ApplicationNode extends Node<Gtk.Application, Props, Node, Node> {
8
9
  private menu: MenuModel;
@@ -51,6 +52,10 @@ export class ApplicationNode extends Node<Gtk.Application, Props, Node, Node> {
51
52
  return;
52
53
  }
53
54
 
55
+ if (child instanceof WindowNode) {
56
+ child.container.setVisible(false);
57
+ }
58
+
54
59
  super.removeChild(child);
55
60
  }
56
61
  }