@gtkx/react 0.17.2 → 0.18.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 (194) hide show
  1. package/README.md +7 -7
  2. package/dist/factory.d.ts +0 -1
  3. package/dist/factory.js +21 -8
  4. package/dist/generated/internal.d.ts +4 -51
  5. package/dist/generated/internal.js +626 -412
  6. package/dist/generated/jsx.d.ts +453 -958
  7. package/dist/host-config.d.ts +1 -1
  8. package/dist/host-config.js +18 -23
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.js +1 -1
  11. package/dist/jsx.d.ts +579 -302
  12. package/dist/jsx.js +37 -179
  13. package/dist/metadata.d.ts +3 -0
  14. package/dist/metadata.js +26 -0
  15. package/dist/node.d.ts +20 -12
  16. package/dist/node.js +72 -17
  17. package/dist/nodes/adjustable.d.ts +3 -16
  18. package/dist/nodes/adjustable.js +5 -22
  19. package/dist/nodes/alert-dialog-response.d.ts +14 -1
  20. package/dist/nodes/alert-dialog-response.js +36 -62
  21. package/dist/nodes/animation.d.ts +37 -1
  22. package/dist/nodes/animation.js +162 -105
  23. package/dist/nodes/application.d.ts +11 -1
  24. package/dist/nodes/application.js +17 -38
  25. package/dist/nodes/calendar.d.ts +13 -0
  26. package/dist/nodes/calendar.js +10 -16
  27. package/dist/nodes/color-dialog-button.d.ts +13 -0
  28. package/dist/nodes/color-dialog-button.js +10 -38
  29. package/dist/nodes/column-view-column.d.ts +13 -11
  30. package/dist/nodes/column-view-column.js +27 -23
  31. package/dist/nodes/column-view.d.ts +31 -0
  32. package/dist/nodes/column-view.js +44 -44
  33. package/dist/nodes/container-slot.d.ts +15 -0
  34. package/dist/nodes/container-slot.js +68 -0
  35. package/dist/nodes/dialog.d.ts +6 -8
  36. package/dist/nodes/dialog.js +12 -13
  37. package/dist/nodes/drawing-area.d.ts +12 -0
  38. package/dist/nodes/drawing-area.js +24 -24
  39. package/dist/nodes/drop-down.d.ts +22 -0
  40. package/dist/nodes/drop-down.js +72 -0
  41. package/dist/nodes/event-controller.d.ts +8 -17
  42. package/dist/nodes/event-controller.js +20 -42
  43. package/dist/nodes/fixed-child.d.ts +18 -1
  44. package/dist/nodes/fixed-child.js +52 -36
  45. package/dist/nodes/font-dialog-button.d.ts +13 -0
  46. package/dist/nodes/font-dialog-button.js +12 -35
  47. package/dist/nodes/grid-child.d.ts +17 -1
  48. package/dist/nodes/grid-child.js +57 -37
  49. package/dist/nodes/grid-view.d.ts +24 -0
  50. package/dist/nodes/grid-view.js +73 -0
  51. package/dist/nodes/internal/base-item-renderer.d.ts +7 -9
  52. package/dist/nodes/internal/base-item-renderer.js +15 -18
  53. package/dist/nodes/internal/grid-item-renderer.d.ts +17 -0
  54. package/dist/nodes/internal/grid-item-renderer.js +59 -0
  55. package/dist/nodes/internal/list-item-renderer.d.ts +14 -9
  56. package/dist/nodes/internal/list-item-renderer.js +96 -35
  57. package/dist/nodes/internal/list-store.d.ts +5 -0
  58. package/dist/nodes/internal/list-store.js +39 -9
  59. package/dist/nodes/internal/predicates.d.ts +4 -19
  60. package/dist/nodes/internal/predicates.js +1 -20
  61. package/dist/nodes/internal/props.d.ts +5 -0
  62. package/dist/nodes/internal/props.js +42 -0
  63. package/dist/nodes/internal/{selection-model.d.ts → selection-model-controller.d.ts} +4 -9
  64. package/dist/nodes/internal/{selection-model.js → selection-model-controller.js} +6 -15
  65. package/dist/nodes/internal/signal-store.js +12 -5
  66. package/dist/nodes/internal/simple-list-store.d.ts +5 -0
  67. package/dist/nodes/internal/simple-list-store.js +42 -13
  68. package/dist/nodes/internal/text-buffer-controller.d.ts +4 -12
  69. package/dist/nodes/internal/text-buffer-controller.js +32 -33
  70. package/dist/nodes/internal/tree-store.d.ts +7 -0
  71. package/dist/nodes/internal/tree-store.js +75 -18
  72. package/dist/nodes/internal/widget.d.ts +7 -0
  73. package/dist/nodes/internal/widget.js +68 -0
  74. package/dist/nodes/level-bar.d.ts +10 -0
  75. package/dist/nodes/level-bar.js +11 -22
  76. package/dist/nodes/list-item.d.ts +17 -9
  77. package/dist/nodes/list-item.js +67 -12
  78. package/dist/nodes/list-view.d.ts +23 -0
  79. package/dist/nodes/list-view.js +27 -31
  80. package/dist/nodes/menu.d.ts +2 -4
  81. package/dist/nodes/menu.js +0 -6
  82. package/dist/nodes/models/grid.d.ts +27 -0
  83. package/dist/nodes/models/grid.js +68 -0
  84. package/dist/nodes/models/list.d.ts +15 -13
  85. package/dist/nodes/models/list.js +48 -26
  86. package/dist/nodes/models/menu.d.ts +15 -16
  87. package/dist/nodes/models/menu.js +63 -93
  88. package/dist/nodes/navigation-page.d.ts +16 -10
  89. package/dist/nodes/navigation-page.js +108 -31
  90. package/dist/nodes/navigation-view.d.ts +15 -0
  91. package/dist/nodes/navigation-view.js +15 -65
  92. package/dist/nodes/notebook-page-tab.d.ts +10 -12
  93. package/dist/nodes/notebook-page-tab.js +24 -27
  94. package/dist/nodes/notebook-page.d.ts +19 -16
  95. package/dist/nodes/notebook-page.js +75 -56
  96. package/dist/nodes/notebook.d.ts +10 -1
  97. package/dist/nodes/notebook.js +10 -22
  98. package/dist/nodes/overlay-child.d.ts +17 -1
  99. package/dist/nodes/overlay-child.js +53 -75
  100. package/dist/nodes/popover-menu.d.ts +15 -0
  101. package/dist/nodes/popover-menu.js +13 -26
  102. package/dist/nodes/scale.d.ts +8 -0
  103. package/dist/nodes/scale.js +2 -11
  104. package/dist/nodes/scrolled-window.d.ts +9 -0
  105. package/dist/nodes/scrolled-window.js +5 -11
  106. package/dist/nodes/search-bar.d.ts +9 -0
  107. package/dist/nodes/search-bar.js +8 -33
  108. package/dist/nodes/shortcut-controller.d.ts +9 -1
  109. package/dist/nodes/shortcut-controller.js +12 -25
  110. package/dist/nodes/shortcut.d.ts +11 -33
  111. package/dist/nodes/shortcut.js +19 -15
  112. package/dist/nodes/slot.d.ts +16 -15
  113. package/dist/nodes/slot.js +63 -57
  114. package/dist/nodes/source-view.d.ts +16 -0
  115. package/dist/nodes/source-view.js +44 -44
  116. package/dist/nodes/stack-page.d.ts +21 -1
  117. package/dist/nodes/stack-page.js +68 -17
  118. package/dist/nodes/stack.d.ts +11 -0
  119. package/dist/nodes/stack.js +8 -26
  120. package/dist/nodes/text-anchor.d.ts +11 -30
  121. package/dist/nodes/text-anchor.js +20 -22
  122. package/dist/nodes/text-content.d.ts +1 -0
  123. package/dist/nodes/text-content.js +1 -1
  124. package/dist/nodes/text-paintable.d.ts +10 -15
  125. package/dist/nodes/text-paintable.js +16 -9
  126. package/dist/nodes/text-segment.d.ts +12 -10
  127. package/dist/nodes/text-segment.js +19 -11
  128. package/dist/nodes/text-tag.d.ts +20 -119
  129. package/dist/nodes/text-tag.js +153 -119
  130. package/dist/nodes/text-view.d.ts +13 -18
  131. package/dist/nodes/text-view.js +17 -17
  132. package/dist/nodes/toggle-group.d.ts +9 -0
  133. package/dist/nodes/toggle-group.js +8 -33
  134. package/dist/nodes/toggle.d.ts +15 -1
  135. package/dist/nodes/toggle.js +34 -52
  136. package/dist/nodes/virtual.d.ts +3 -10
  137. package/dist/nodes/virtual.js +1 -14
  138. package/dist/nodes/web-view.d.ts +9 -0
  139. package/dist/nodes/web-view.js +10 -24
  140. package/dist/nodes/widget.d.ts +17 -13
  141. package/dist/nodes/widget.js +185 -112
  142. package/dist/nodes/window.d.ts +20 -21
  143. package/dist/nodes/window.js +54 -35
  144. package/dist/registry.d.ts +17 -6
  145. package/dist/registry.js +104 -5
  146. package/dist/render.d.ts +1 -10
  147. package/dist/render.js +1 -13
  148. package/package.json +6 -6
  149. package/dist/animation/css-builder.d.ts +0 -3
  150. package/dist/animation/css-builder.js +0 -53
  151. package/dist/animation/types.d.ts +0 -120
  152. package/dist/animation/types.js +0 -1
  153. package/dist/nodes/abstract/positional-child.d.ts +0 -9
  154. package/dist/nodes/abstract/positional-child.js +0 -29
  155. package/dist/nodes/abstract/virtual-container.d.ts +0 -21
  156. package/dist/nodes/abstract/virtual-container.js +0 -68
  157. package/dist/nodes/abstract/virtual-single-child.d.ts +0 -18
  158. package/dist/nodes/abstract/virtual-single-child.js +0 -55
  159. package/dist/nodes/action-row-child.d.ts +0 -1
  160. package/dist/nodes/action-row-child.js +0 -30
  161. package/dist/nodes/autowrapped.d.ts +0 -1
  162. package/dist/nodes/autowrapped.js +0 -115
  163. package/dist/nodes/expander-row-child.d.ts +0 -1
  164. package/dist/nodes/expander-row-child.js +0 -30
  165. package/dist/nodes/grid.d.ts +0 -1
  166. package/dist/nodes/grid.js +0 -41
  167. package/dist/nodes/index.d.ts +0 -56
  168. package/dist/nodes/index.js +0 -56
  169. package/dist/nodes/internal/child-attachment.d.ts +0 -26
  170. package/dist/nodes/internal/child-attachment.js +0 -48
  171. package/dist/nodes/internal/deferred-action.d.ts +0 -9
  172. package/dist/nodes/internal/deferred-action.js +0 -22
  173. package/dist/nodes/internal/text-tag-styles.d.ts +0 -43
  174. package/dist/nodes/internal/text-tag-styles.js +0 -52
  175. package/dist/nodes/internal/tree-list-item-renderer.d.ts +0 -26
  176. package/dist/nodes/internal/tree-list-item-renderer.js +0 -134
  177. package/dist/nodes/internal/utils.d.ts +0 -12
  178. package/dist/nodes/internal/utils.js +0 -92
  179. package/dist/nodes/models/tree-list.d.ts +0 -28
  180. package/dist/nodes/models/tree-list.js +0 -113
  181. package/dist/nodes/pack-child.d.ts +0 -1
  182. package/dist/nodes/pack-child.js +0 -30
  183. package/dist/nodes/simple-list-item.d.ts +0 -9
  184. package/dist/nodes/simple-list-item.js +0 -9
  185. package/dist/nodes/simple-list-view.d.ts +0 -1
  186. package/dist/nodes/simple-list-view.js +0 -74
  187. package/dist/nodes/toolbar-child.d.ts +0 -1
  188. package/dist/nodes/toolbar-child.js +0 -30
  189. package/dist/nodes/tree-list-item.d.ts +0 -22
  190. package/dist/nodes/tree-list-item.js +0 -90
  191. package/dist/nodes/tree-list-view.d.ts +0 -1
  192. package/dist/nodes/tree-list-view.js +0 -77
  193. package/dist/scheduler.d.ts +0 -26
  194. package/dist/scheduler.js +0 -42
@@ -1,18 +1,10 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
- import { registerNodeClass } from "../registry.js";
3
2
  import { AdjustableNode } from "./adjustable.js";
4
- import { matchesAnyClass, shallowArrayEqual } from "./internal/utils.js";
5
- class ScaleNode extends AdjustableNode {
6
- static priority = 1;
3
+ import { shallowArrayEqual } from "./internal/props.js";
4
+ export class ScaleNode extends AdjustableNode {
7
5
  appliedMarks = [];
8
- static matches(_type, containerOrClass) {
9
- return matchesAnyClass([Gtk.Scale], containerOrClass);
10
- }
11
6
  applyOwnProps(oldProps, newProps) {
12
7
  super.applyOwnProps(oldProps, newProps);
13
- this.applyMarks(newProps);
14
- }
15
- applyMarks(newProps) {
16
8
  const newMarks = newProps.marks ?? [];
17
9
  if (shallowArrayEqual(this.appliedMarks, newMarks)) {
18
10
  return;
@@ -24,4 +16,3 @@ class ScaleNode extends AdjustableNode {
24
16
  this.appliedMarks = [...newMarks];
25
17
  }
26
18
  }
27
- registerNodeClass(ScaleNode);
@@ -1 +1,10 @@
1
+ import * as Gtk from "@gtkx/ffi/gtk";
2
+ import type { GtkScrolledWindowProps } from "../jsx.js";
3
+ import { WidgetNode } from "./widget.js";
4
+ declare const OWN_PROPS: readonly ["hscrollbarPolicy", "vscrollbarPolicy"];
5
+ type ScrolledWindowProps = Pick<GtkScrolledWindowProps, (typeof OWN_PROPS)[number]>;
6
+ export declare class ScrolledWindowNode extends WidgetNode<Gtk.ScrolledWindow, ScrolledWindowProps> {
7
+ commitUpdate(oldProps: ScrolledWindowProps | null, newProps: ScrolledWindowProps): void;
8
+ private applyOwnProps;
9
+ }
1
10
  export {};
@@ -1,15 +1,10 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
- import { registerNodeClass } from "../registry.js";
3
- import { filterProps, hasChanged, matchesAnyClass } from "./internal/utils.js";
2
+ import { filterProps, hasChanged } from "./internal/props.js";
4
3
  import { WidgetNode } from "./widget.js";
5
- const PROPS = ["hscrollbarPolicy", "vscrollbarPolicy"];
6
- class ScrolledWindowNode extends WidgetNode {
7
- static priority = 2;
8
- static matches(_type, containerOrClass) {
9
- return matchesAnyClass([Gtk.ScrolledWindow], containerOrClass);
10
- }
11
- updateProps(oldProps, newProps) {
12
- super.updateProps(oldProps ? filterProps(oldProps, PROPS) : null, filterProps(newProps, PROPS));
4
+ const OWN_PROPS = ["hscrollbarPolicy", "vscrollbarPolicy"];
5
+ export class ScrolledWindowNode extends WidgetNode {
6
+ commitUpdate(oldProps, newProps) {
7
+ super.commitUpdate(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
13
8
  this.applyOwnProps(oldProps, newProps);
14
9
  }
15
10
  applyOwnProps(oldProps, newProps) {
@@ -20,4 +15,3 @@ class ScrolledWindowNode extends WidgetNode {
20
15
  }
21
16
  }
22
17
  }
23
- registerNodeClass(ScrolledWindowNode);
@@ -1 +1,10 @@
1
+ import type * as Gtk from "@gtkx/ffi/gtk";
2
+ import type { GtkSearchBarProps } from "../jsx.js";
3
+ import { WidgetNode } from "./widget.js";
4
+ declare const OWN_PROPS: readonly ["onSearchModeChanged"];
5
+ type SearchBarProps = Pick<GtkSearchBarProps, (typeof OWN_PROPS)[number]>;
6
+ export declare class SearchBarNode extends WidgetNode<Gtk.SearchBar, SearchBarProps> {
7
+ commitUpdate(oldProps: SearchBarProps | null, newProps: SearchBarProps): void;
8
+ private applyOwnProps;
9
+ }
1
10
  export {};
@@ -1,40 +1,15 @@
1
- import * as Gtk from "@gtkx/ffi/gtk";
2
- import { registerNodeClass } from "../registry.js";
3
- import { filterProps, hasChanged, matchesAnyClass } from "./internal/utils.js";
1
+ import { filterProps, hasChanged } from "./internal/props.js";
4
2
  import { WidgetNode } from "./widget.js";
5
3
  const OWN_PROPS = ["onSearchModeChanged"];
6
- class SearchBarNode extends WidgetNode {
7
- static priority = 1;
8
- notifyHandler = null;
9
- static matches(_type, containerOrClass) {
10
- return matchesAnyClass([Gtk.SearchBar], containerOrClass);
4
+ export class SearchBarNode extends WidgetNode {
5
+ commitUpdate(oldProps, newProps) {
6
+ super.commitUpdate(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
7
+ this.applyOwnProps(oldProps, newProps);
11
8
  }
12
- updateProps(oldProps, newProps) {
13
- super.updateProps(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
9
+ applyOwnProps(oldProps, newProps) {
14
10
  if (hasChanged(oldProps, newProps, "onSearchModeChanged")) {
15
- this.setupNotifyHandler(newProps.onSearchModeChanged);
11
+ const callback = newProps.onSearchModeChanged;
12
+ this.signalStore.set(this, this.container, "notify::search-mode-enabled", callback ? () => callback(this.container.getSearchMode()) : undefined);
16
13
  }
17
14
  }
18
- setupNotifyHandler(callback) {
19
- if (this.notifyHandler) {
20
- this.signalStore.set(this, this.container, "notify", undefined);
21
- this.notifyHandler = null;
22
- }
23
- if (callback) {
24
- this.notifyHandler = (_searchBar, pspec) => {
25
- if (pspec.getName() === "search-mode-enabled") {
26
- callback(this.container.getSearchMode());
27
- }
28
- };
29
- this.signalStore.set(this, this.container, "notify", this.notifyHandler);
30
- }
31
- }
32
- unmount() {
33
- if (this.notifyHandler) {
34
- this.signalStore.set(this, this.container, "notify", undefined);
35
- this.notifyHandler = null;
36
- }
37
- super.unmount();
38
- }
39
15
  }
40
- registerNodeClass(SearchBarNode);
@@ -1 +1,9 @@
1
- export {};
1
+ import type * as Gtk from "@gtkx/ffi/gtk";
2
+ import type { Node } from "../node.js";
3
+ import { EventControllerNode } from "./event-controller.js";
4
+ import { ShortcutNode } from "./shortcut.js";
5
+ export declare class ShortcutControllerNode extends EventControllerNode<Gtk.ShortcutController, ShortcutNode> {
6
+ isValidChild(child: Node): boolean;
7
+ appendChild(child: ShortcutNode): void;
8
+ removeChild(child: ShortcutNode): void;
9
+ }
@@ -1,35 +1,22 @@
1
- import { registerNodeClass } from "../registry.js";
2
1
  import { EventControllerNode } from "./event-controller.js";
3
2
  import { ShortcutNode } from "./shortcut.js";
4
- class ShortcutControllerNode extends EventControllerNode {
5
- static priority = 0;
6
- static matches(type) {
7
- return type === "GtkShortcutController";
3
+ export class ShortcutControllerNode extends EventControllerNode {
4
+ isValidChild(child) {
5
+ return child instanceof ShortcutNode;
8
6
  }
9
- shortcuts = [];
10
7
  appendChild(child) {
11
- if (!(child instanceof ShortcutNode)) {
12
- throw new Error(`ShortcutController only accepts Shortcut children, got '${child.typeName}'`);
8
+ super.appendChild(child);
9
+ child.createShortcut();
10
+ const shortcut = child.getShortcut();
11
+ if (shortcut) {
12
+ this.container.addShortcut(shortcut);
13
13
  }
14
- this.shortcuts.push(child);
15
- this.addShortcutToController(child);
16
14
  }
17
15
  removeChild(child) {
18
- if (!(child instanceof ShortcutNode))
19
- return;
20
- const index = this.shortcuts.indexOf(child);
21
- if (index !== -1) {
22
- this.shortcuts.splice(index, 1);
23
- if (child.shortcut) {
24
- this.container.removeShortcut(child.shortcut);
25
- }
26
- }
27
- }
28
- addShortcutToController(node) {
29
- node.createShortcut();
30
- if (node.shortcut) {
31
- this.container.addShortcut(node.shortcut);
16
+ const shortcut = child.getShortcut();
17
+ if (shortcut) {
18
+ this.container.removeShortcut(shortcut);
32
19
  }
20
+ super.removeChild(child);
33
21
  }
34
22
  }
35
- registerNodeClass(ShortcutControllerNode);
@@ -1,39 +1,17 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
- import type { Props } from "../types.js";
2
+ import type { ShortcutProps } from "../jsx.js";
3
+ import type { Node } from "../node.js";
4
+ import { EventControllerNode } from "./event-controller.js";
3
5
  import { VirtualNode } from "./virtual.js";
4
- /**
5
- * Props for the Shortcut virtual element.
6
- *
7
- * Defines a keyboard shortcut. Must be a child of `x.ShortcutController`.
8
- *
9
- * @example
10
- * ```tsx
11
- * <x.ShortcutController>
12
- * <x.Shortcut trigger="<Control>s" onActivate={save} />
13
- * <x.Shortcut trigger={["F5", "<Control>r"]} onActivate={refresh} />
14
- * <x.Shortcut trigger="Escape" onActivate={cancel} disabled={!canCancel} />
15
- * </x.ShortcutController>
16
- * ```
17
- */
18
- export type ShortcutProps = Props & {
19
- /** The trigger string(s) using GTK accelerator format (e.g., "\<Control\>s", "F1") */
20
- trigger: string | string[];
21
- /**
22
- * Called when the shortcut is activated.
23
- * Return false to indicate the shortcut was not handled; otherwise it is considered handled.
24
- */
25
- onActivate: () => boolean | void;
26
- /** Whether the shortcut is disabled */
27
- disabled?: boolean;
28
- };
29
- export declare class ShortcutNode extends VirtualNode<ShortcutProps> {
30
- static priority: number;
31
- static matches(type: string): boolean;
32
- shortcut: Gtk.Shortcut | null;
6
+ export declare class ShortcutNode extends VirtualNode<ShortcutProps, EventControllerNode<Gtk.ShortcutController>, never> {
7
+ isValidChild(_child: Node): boolean;
8
+ isValidParent(parent: Node): boolean;
9
+ private shortcut;
33
10
  private action;
11
+ commitUpdate(oldProps: ShortcutProps | null, newProps: ShortcutProps): void;
12
+ detachDeletedInstance(): void;
13
+ getShortcut(): Gtk.Shortcut | null;
34
14
  createShortcut(): void;
35
- updateProps(oldProps: ShortcutProps | null, newProps: ShortcutProps): void;
36
- protected applyOwnProps(oldProps: ShortcutProps | null, newProps: ShortcutProps): void;
37
- unmount(): void;
15
+ private applyOwnProps;
38
16
  private createTrigger;
39
17
  }
@@ -1,14 +1,28 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
- import { registerNodeClass } from "../registry.js";
3
- import { hasChanged } from "./internal/utils.js";
2
+ import { EventControllerNode } from "./event-controller.js";
3
+ import { hasChanged } from "./internal/props.js";
4
4
  import { VirtualNode } from "./virtual.js";
5
5
  export class ShortcutNode extends VirtualNode {
6
- static priority = 1;
7
- static matches(type) {
8
- return type === "Shortcut";
6
+ isValidChild(_child) {
7
+ return false;
8
+ }
9
+ isValidParent(parent) {
10
+ return parent instanceof EventControllerNode && parent.container instanceof Gtk.ShortcutController;
9
11
  }
10
12
  shortcut = null;
11
13
  action = null;
14
+ commitUpdate(oldProps, newProps) {
15
+ super.commitUpdate(oldProps, newProps);
16
+ this.applyOwnProps(oldProps, newProps);
17
+ }
18
+ detachDeletedInstance() {
19
+ this.shortcut = null;
20
+ this.action = null;
21
+ super.detachDeletedInstance();
22
+ }
23
+ getShortcut() {
24
+ return this.shortcut;
25
+ }
12
26
  createShortcut() {
13
27
  const trigger = this.createTrigger();
14
28
  this.action = new Gtk.CallbackAction(() => {
@@ -17,10 +31,6 @@ export class ShortcutNode extends VirtualNode {
17
31
  });
18
32
  this.shortcut = new Gtk.Shortcut(trigger, this.action);
19
33
  }
20
- updateProps(oldProps, newProps) {
21
- super.updateProps(oldProps, newProps);
22
- this.applyOwnProps(oldProps, newProps);
23
- }
24
34
  applyOwnProps(oldProps, newProps) {
25
35
  if (!this.shortcut)
26
36
  return;
@@ -28,11 +38,6 @@ export class ShortcutNode extends VirtualNode {
28
38
  this.shortcut.setTrigger(this.createTrigger());
29
39
  }
30
40
  }
31
- unmount() {
32
- this.shortcut = null;
33
- this.action = null;
34
- super.unmount();
35
- }
36
41
  createTrigger() {
37
42
  if (this.props.disabled) {
38
43
  return Gtk.NeverTrigger.get();
@@ -49,4 +54,3 @@ export class ShortcutNode extends VirtualNode {
49
54
  return result;
50
55
  }
51
56
  }
52
- registerNodeClass(ShortcutNode);
@@ -1,19 +1,20 @@
1
- import type * as Gtk from "@gtkx/ffi/gtk";
2
1
  import type { SlotProps } from "../jsx.js";
2
+ import type { Node } from "../node.js";
3
3
  import type { Props } from "../types.js";
4
- import { VirtualSingleChildNode } from "./abstract/virtual-single-child.js";
5
- type SlotNodeProps = Omit<SlotProps, "children">;
6
- export declare class SlotNode<P extends Props = SlotNodeProps> extends VirtualSingleChildNode<P> {
7
- static priority: number;
8
- static matches(type: string): boolean;
4
+ import { VirtualNode } from "./virtual.js";
5
+ import { WidgetNode } from "./widget.js";
6
+ export declare class SlotNode<P extends Props = SlotProps, TChild extends Node = WidgetNode> extends VirtualNode<P, WidgetNode, TChild> {
9
7
  private cachedSetter;
10
- setParent(parent: Gtk.Widget | null): void;
11
- unmount(): void;
12
- getChild(): Gtk.Widget;
13
- protected getId(): string;
14
- protected getParent(): Gtk.Widget;
15
- protected ensureChildSetter(): (child: Gtk.Widget | null) => void;
16
- protected onChildChange(oldChild: Gtk.Widget | null): void;
17
- private isDescendantOf;
8
+ private detachedParentWidget;
9
+ isValidChild(child: Node): boolean;
10
+ isValidParent(parent: Node): boolean;
11
+ setParent(parent: WidgetNode | null): void;
12
+ appendChild(child: TChild): void;
13
+ removeChild(child: TChild): void;
14
+ detachDeletedInstance(): void;
15
+ private getId;
16
+ private getParentWidget;
17
+ private ensureChildSetter;
18
+ private onChildChange;
19
+ private resolveChildSetter;
18
20
  }
19
- export {};
@@ -1,43 +1,62 @@
1
- import { isObjectEqual } from "@gtkx/ffi";
2
1
  import { toCamelCase } from "@gtkx/gir";
3
- import { registerNodeClass } from "../registry.js";
4
- import { VirtualSingleChildNode } from "./abstract/virtual-single-child.js";
5
- import { resolvePropMeta } from "./internal/utils.js";
6
- export class SlotNode extends VirtualSingleChildNode {
7
- static priority = 2;
8
- static matches(type) {
9
- return type === "Slot";
10
- }
2
+ import { getFocusWidget, isDescendantOf, resolvePropertySetter } from "./internal/widget.js";
3
+ import { VirtualNode } from "./virtual.js";
4
+ import { WidgetNode } from "./widget.js";
5
+ export class SlotNode extends VirtualNode {
11
6
  cachedSetter = null;
7
+ detachedParentWidget = null;
8
+ isValidChild(child) {
9
+ return child instanceof WidgetNode;
10
+ }
11
+ isValidParent(parent) {
12
+ return parent instanceof WidgetNode;
13
+ }
12
14
  setParent(parent) {
13
- if (!isObjectEqual(this.parent, parent)) {
15
+ const previousParent = this.parent;
16
+ if (previousParent !== parent) {
14
17
  this.cachedSetter = null;
15
18
  }
19
+ if (!parent && previousParent) {
20
+ this.detachedParentWidget = previousParent.container;
21
+ }
16
22
  super.setParent(parent);
23
+ if (parent && this.children[0]) {
24
+ this.onChildChange(null);
25
+ }
17
26
  }
18
- unmount() {
19
- if (this.parent && this.child) {
20
- const parent = this.parent;
21
- const oldChild = this.child;
22
- this.child = null;
23
- queueMicrotask(() => {
24
- if (parent.getRoot() !== null) {
25
- this.parent = parent;
26
- this.onChildChange(oldChild);
27
- }
28
- this.parent = null;
29
- });
27
+ appendChild(child) {
28
+ const firstChild = this.children[0];
29
+ const oldChildWidget = firstChild instanceof WidgetNode ? firstChild.container : null;
30
+ super.appendChild(child);
31
+ if (this.parent) {
32
+ this.onChildChange(oldChildWidget);
30
33
  }
31
- else {
32
- this.parent = null;
34
+ }
35
+ removeChild(child) {
36
+ const oldChildWidget = child instanceof WidgetNode ? child.container : null;
37
+ super.removeChild(child);
38
+ if (this.parent && oldChildWidget) {
39
+ this.onChildChange(oldChildWidget);
33
40
  }
34
- super.unmount();
35
41
  }
36
- getChild() {
37
- if (!this.child) {
38
- throw new Error(`Expected child widget to be set on '${this.getId()}' SlotNode`);
42
+ detachDeletedInstance() {
43
+ const parentWidget = this.detachedParentWidget;
44
+ if (parentWidget && this.children[0]) {
45
+ if (parentWidget.getRoot() !== null) {
46
+ this.cachedSetter = null;
47
+ const setter = this.resolveChildSetter(parentWidget);
48
+ if (setter) {
49
+ const oldChild = this.children[0].container;
50
+ const focus = getFocusWidget(oldChild);
51
+ if (focus && isDescendantOf(focus, oldChild)) {
52
+ parentWidget.grabFocus();
53
+ }
54
+ setter(null);
55
+ }
56
+ }
57
+ this.detachedParentWidget = null;
39
58
  }
40
- return this.child;
59
+ super.detachDeletedInstance();
41
60
  }
42
61
  getId() {
43
62
  const id = this.props.id;
@@ -46,50 +65,37 @@ export class SlotNode extends VirtualSingleChildNode {
46
65
  }
47
66
  return toCamelCase(id);
48
67
  }
49
- getParent() {
68
+ getParentWidget() {
50
69
  if (!this.parent) {
51
70
  throw new Error(`Expected parent widget to be set on '${this.getId()}' SlotNode`);
52
71
  }
53
- return this.parent;
72
+ return this.parent.container;
54
73
  }
55
74
  ensureChildSetter() {
56
75
  if (this.cachedSetter)
57
76
  return this.cachedSetter;
58
- const parent = this.getParent();
59
- const parentType = parent.constructor.glibTypeName;
60
- const propMeta = resolvePropMeta(parent, this.getId());
61
- if (!propMeta) {
77
+ const parent = this.getParentWidget();
78
+ const setter = this.resolveChildSetter(parent);
79
+ if (!setter) {
80
+ const parentType = parent.constructor.glibTypeName;
62
81
  throw new Error(`Unable to find property for Slot '${this.getId()}' on type '${parentType}'`);
63
82
  }
64
- const [, setterName] = propMeta;
65
- const setter = parent[setterName];
66
- if (typeof setter !== "function") {
67
- throw new Error(`Expected setter function for Slot '${this.getId()}' on type '${parentType}'`);
68
- }
69
- this.cachedSetter = setter.bind(parent);
83
+ this.cachedSetter = setter;
70
84
  return this.cachedSetter;
71
85
  }
72
86
  onChildChange(oldChild) {
73
87
  const setter = this.ensureChildSetter();
74
- if (oldChild && !this.child) {
75
- const parent = this.getParent();
76
- const root = oldChild.getRoot();
77
- const focusWidget = root?.getFocus?.();
78
- if (focusWidget && this.isDescendantOf(focusWidget, oldChild)) {
88
+ const childWidget = this.children[0]?.container ?? null;
89
+ if (oldChild && !childWidget) {
90
+ const parent = this.getParentWidget();
91
+ const focus = getFocusWidget(oldChild);
92
+ if (focus && isDescendantOf(focus, oldChild)) {
79
93
  parent.grabFocus();
80
94
  }
81
95
  }
82
- setter(this.child);
96
+ setter(childWidget);
83
97
  }
84
- isDescendantOf(widget, ancestor) {
85
- let current = widget;
86
- while (current) {
87
- if (isObjectEqual(current, ancestor)) {
88
- return true;
89
- }
90
- current = current.getParent();
91
- }
92
- return false;
98
+ resolveChildSetter(parent) {
99
+ return resolvePropertySetter(parent, this.getId());
93
100
  }
94
101
  }
95
- registerNodeClass(SlotNode);
@@ -1 +1,17 @@
1
+ import * as GtkSource from "@gtkx/ffi/gtksource";
2
+ import type { GtkSourceViewProps } from "../jsx.js";
3
+ import { TextBufferController } from "./internal/text-buffer-controller.js";
4
+ import { TextViewNode } from "./text-view.js";
5
+ declare const OWN_PROPS: readonly ["language", "styleScheme", "highlightSyntax", "highlightMatchingBrackets", "implicitTrailingNewline", "onCursorMoved", "onHighlightUpdated"];
6
+ type SourceViewProps = Pick<GtkSourceViewProps, "enableUndo" | "onBufferChanged" | "onTextInserted" | "onTextDeleted" | "onCanUndoChanged" | "onCanRedoChanged" | (typeof OWN_PROPS)[number]>;
7
+ export declare class SourceViewNode extends TextViewNode {
8
+ protected createBufferController(): TextBufferController<GtkSource.Buffer>;
9
+ protected ensureBufferController(): TextBufferController<GtkSource.Buffer>;
10
+ commitUpdate(oldProps: SourceViewProps | null, newProps: SourceViewProps): void;
11
+ private resolveLanguage;
12
+ private resolveStyleScheme;
13
+ private applyOwnProps;
14
+ private applyBufferProps;
15
+ private applySignalProps;
16
+ }
1
17
  export {};
@@ -1,22 +1,26 @@
1
1
  import * as GtkSource from "@gtkx/ffi/gtksource";
2
- import { registerNodeClass } from "../registry.js";
2
+ import { filterProps, hasChanged } from "./internal/props.js";
3
3
  import { TextBufferController } from "./internal/text-buffer-controller.js";
4
- import { hasChanged, matchesAnyClass } from "./internal/utils.js";
5
4
  import { TextViewNode } from "./text-view.js";
6
- class SourceViewNode extends TextViewNode {
7
- static priority = 1;
8
- static matches(_type, containerOrClass) {
9
- return matchesAnyClass([GtkSource.View], containerOrClass);
10
- }
5
+ const OWN_PROPS = [
6
+ "language",
7
+ "styleScheme",
8
+ "highlightSyntax",
9
+ "highlightMatchingBrackets",
10
+ "implicitTrailingNewline",
11
+ "onCursorMoved",
12
+ "onHighlightUpdated",
13
+ ];
14
+ export class SourceViewNode extends TextViewNode {
11
15
  createBufferController() {
12
16
  return new TextBufferController(this, this.container, () => new GtkSource.Buffer());
13
17
  }
14
18
  ensureBufferController() {
15
19
  return super.ensureBufferController();
16
20
  }
17
- applyOwnProps(oldProps, newProps) {
18
- super.applyOwnProps(oldProps, newProps);
19
- this.applySourceViewProps(oldProps, newProps);
21
+ commitUpdate(oldProps, newProps) {
22
+ super.commitUpdate(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
23
+ this.applyOwnProps(oldProps, newProps);
20
24
  }
21
25
  resolveLanguage(language) {
22
26
  if (typeof language === "string") {
@@ -32,62 +36,58 @@ class SourceViewNode extends TextViewNode {
32
36
  }
33
37
  return scheme;
34
38
  }
35
- applySourceViewProps(oldProps, newProps) {
36
- const hasSourceViewProps = newProps.language !== undefined ||
37
- newProps.styleScheme !== undefined ||
38
- newProps.highlightSyntax !== undefined ||
39
- newProps.highlightMatchingBrackets !== undefined ||
40
- newProps.implicitTrailingNewline !== undefined ||
41
- newProps.onCursorMoved !== undefined ||
42
- newProps.onHighlightUpdated !== undefined ||
43
- oldProps?.language !== undefined ||
44
- oldProps?.styleScheme !== undefined;
45
- if (!hasSourceViewProps) {
39
+ applyOwnProps(oldProps, newProps) {
40
+ if (hasChanged(oldProps, newProps, "onCursorMoved") || hasChanged(oldProps, newProps, "onHighlightUpdated")) {
41
+ this.applySignalProps(newProps);
42
+ }
43
+ this.applyBufferProps(oldProps, newProps);
44
+ }
45
+ applyBufferProps(oldProps, newProps) {
46
+ const languageChanged = hasChanged(oldProps, newProps, "language");
47
+ const styleSchemeChanged = hasChanged(oldProps, newProps, "styleScheme");
48
+ const highlightSyntaxChanged = hasChanged(oldProps, newProps, "highlightSyntax");
49
+ const highlightBracketsChanged = hasChanged(oldProps, newProps, "highlightMatchingBrackets");
50
+ const trailingNewlineChanged = hasChanged(oldProps, newProps, "implicitTrailingNewline");
51
+ if (!languageChanged &&
52
+ !styleSchemeChanged &&
53
+ !highlightSyntaxChanged &&
54
+ !highlightBracketsChanged &&
55
+ !trailingNewlineChanged) {
46
56
  return;
47
57
  }
48
58
  const buffer = this.ensureBufferController().ensureBuffer();
49
- if (hasChanged(oldProps, newProps, "language")) {
59
+ if (languageChanged) {
50
60
  if (newProps.language !== undefined) {
51
- const language = this.resolveLanguage(newProps.language);
52
- buffer.setLanguage(language);
61
+ buffer.setLanguage(this.resolveLanguage(newProps.language));
53
62
  }
54
63
  else if (oldProps?.language !== undefined) {
55
64
  buffer.setLanguage(null);
56
65
  }
57
66
  }
58
- if (hasChanged(oldProps, newProps, "styleScheme")) {
67
+ if (styleSchemeChanged) {
59
68
  if (newProps.styleScheme !== undefined) {
60
- const scheme = this.resolveStyleScheme(newProps.styleScheme);
61
- buffer.setStyleScheme(scheme);
69
+ buffer.setStyleScheme(this.resolveStyleScheme(newProps.styleScheme));
62
70
  }
63
71
  else if (oldProps?.styleScheme !== undefined) {
64
72
  buffer.setStyleScheme(null);
65
73
  }
66
74
  }
67
- if (hasChanged(oldProps, newProps, "highlightSyntax") || hasChanged(oldProps, newProps, "language")) {
68
- const highlightSyntax = newProps.highlightSyntax ?? newProps.language !== undefined;
69
- buffer.setHighlightSyntax(highlightSyntax);
70
- }
71
- if (hasChanged(oldProps, newProps, "highlightMatchingBrackets")) {
72
- const highlightMatchingBrackets = newProps.highlightMatchingBrackets ?? true;
73
- buffer.setHighlightMatchingBrackets(highlightMatchingBrackets);
75
+ if (highlightSyntaxChanged || languageChanged) {
76
+ buffer.setHighlightSyntax(newProps.highlightSyntax ?? newProps.language !== undefined);
74
77
  }
75
- if (hasChanged(oldProps, newProps, "implicitTrailingNewline")) {
76
- if (newProps.implicitTrailingNewline !== undefined) {
77
- buffer.setImplicitTrailingNewline(newProps.implicitTrailingNewline);
78
- }
78
+ if (highlightBracketsChanged) {
79
+ buffer.setHighlightMatchingBrackets(newProps.highlightMatchingBrackets ?? true);
79
80
  }
80
- if (hasChanged(oldProps, newProps, "onCursorMoved") || hasChanged(oldProps, newProps, "onHighlightUpdated")) {
81
- this.updateSourceViewSignalHandlers(newProps);
81
+ if (trailingNewlineChanged && newProps.implicitTrailingNewline !== undefined) {
82
+ buffer.setImplicitTrailingNewline(newProps.implicitTrailingNewline);
82
83
  }
83
84
  }
84
- updateSourceViewSignalHandlers(props) {
85
+ applySignalProps(props) {
85
86
  const buffer = this.ensureBufferController().getBuffer();
86
87
  if (!buffer)
87
88
  return;
88
89
  const { onCursorMoved, onHighlightUpdated } = props;
89
- this.signalStore.set(this, buffer, "cursor-moved", onCursorMoved ?? null);
90
- this.signalStore.set(this, buffer, "highlight-updated", onHighlightUpdated ? (start, end) => onHighlightUpdated(start, end) : null);
90
+ this.signalStore.set(this, buffer, "cursor-moved", onCursorMoved);
91
+ this.signalStore.set(this, buffer, "highlight-updated", onHighlightUpdated ? (start, end) => onHighlightUpdated(start, end) : undefined);
91
92
  }
92
93
  }
93
- registerNodeClass(SourceViewNode);