@gtkx/react 0.8.0 → 0.9.1

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 (62) hide show
  1. package/dist/{container-interfaces.d.ts → containers.d.ts} +10 -37
  2. package/dist/containers.js +1 -0
  3. package/dist/factory.d.ts +1 -1
  4. package/dist/factory.js +3 -3
  5. package/dist/{reconciler/host-config.d.ts → host-config.d.ts} +2 -2
  6. package/dist/{reconciler/host-config.js → host-config.js} +2 -2
  7. package/dist/node.d.ts +5 -6
  8. package/dist/node.js +54 -72
  9. package/dist/nodes/about-dialog.d.ts +2 -3
  10. package/dist/nodes/about-dialog.js +6 -4
  11. package/dist/nodes/column-view.d.ts +10 -9
  12. package/dist/nodes/column-view.js +53 -40
  13. package/dist/nodes/flow-box.js +1 -1
  14. package/dist/nodes/grid.d.ts +4 -1
  15. package/dist/nodes/grid.js +39 -1
  16. package/dist/nodes/header-bar.d.ts +15 -14
  17. package/dist/nodes/header-bar.js +79 -39
  18. package/dist/nodes/indexed-child-container.d.ts +1 -1
  19. package/dist/nodes/list-box.js +2 -2
  20. package/dist/nodes/list-item-factory.js +3 -3
  21. package/dist/nodes/list-view.d.ts +1 -2
  22. package/dist/nodes/list-view.js +2 -2
  23. package/dist/nodes/menu.d.ts +28 -12
  24. package/dist/nodes/menu.js +64 -37
  25. package/dist/nodes/notebook.d.ts +4 -1
  26. package/dist/nodes/notebook.js +48 -4
  27. package/dist/nodes/overlay.d.ts +1 -1
  28. package/dist/nodes/overlay.js +1 -1
  29. package/dist/nodes/paged-stack.d.ts +7 -3
  30. package/dist/nodes/paged-stack.js +47 -2
  31. package/dist/nodes/root.d.ts +1 -1
  32. package/dist/nodes/root.js +2 -2
  33. package/dist/nodes/selectable-list.d.ts +7 -3
  34. package/dist/nodes/selectable-list.js +37 -5
  35. package/dist/nodes/slot.d.ts +3 -4
  36. package/dist/nodes/slot.js +11 -10
  37. package/dist/nodes/stack-page-props.d.ts +1 -1
  38. package/dist/nodes/stack.d.ts +1 -1
  39. package/dist/nodes/stack.js +2 -2
  40. package/dist/nodes/string-list-container.d.ts +5 -12
  41. package/dist/nodes/string-list-container.js +34 -6
  42. package/dist/nodes/string-list-item.d.ts +10 -6
  43. package/dist/nodes/string-list-item.js +19 -17
  44. package/dist/nodes/toggle-button.d.ts +0 -3
  45. package/dist/nodes/toggle-button.js +0 -28
  46. package/dist/nodes/toolbar-view.d.ts +2 -3
  47. package/dist/nodes/toolbar-view.js +10 -9
  48. package/dist/nodes/view-stack.d.ts +1 -1
  49. package/dist/nodes/view-stack.js +2 -2
  50. package/dist/nodes/virtual-item.d.ts +9 -5
  51. package/dist/nodes/virtual-item.js +16 -20
  52. package/dist/nodes/virtual-slot.d.ts +4 -4
  53. package/dist/nodes/virtual-slot.js +12 -26
  54. package/dist/nodes/window.d.ts +2 -1
  55. package/dist/nodes/window.js +7 -3
  56. package/dist/predicates.d.ts +9 -18
  57. package/dist/predicates.js +31 -18
  58. package/dist/reconciler.d.ts +1 -1
  59. package/dist/reconciler.js +1 -1
  60. package/dist/types.d.ts +2 -0
  61. package/package.json +5 -5
  62. package/dist/container-interfaces.js +0 -26
@@ -1,23 +1,10 @@
1
1
  import type * as Adw from "@gtkx/ffi/adw";
2
2
  import type * as Gtk from "@gtkx/ffi/gtk";
3
- import { type PackContainer } from "../container-interfaces.js";
3
+ import type { PackContainer } from "../containers.js";
4
4
  import type { Props } from "../factory.js";
5
5
  import { Node } from "../node.js";
6
6
  import { VirtualSlotNode } from "./virtual-slot.js";
7
7
  type HeaderBarWidget = Gtk.HeaderBar | Adw.HeaderBar | Gtk.ActionBar;
8
- export declare class PackContainerNode<T extends HeaderBarWidget> extends Node<T> implements PackContainer {
9
- packStart(child: Gtk.Widget): void;
10
- packEnd(child: Gtk.Widget): void;
11
- removeFromPack(child: Gtk.Widget): void;
12
- appendChild(child: Node): void;
13
- removeChild(child: Node): void;
14
- }
15
- export declare class AdwHeaderBarNode extends PackContainerNode<Adw.HeaderBar> {
16
- static matches(type: string): boolean;
17
- }
18
- export declare class HeaderBarNode extends PackContainerNode<Gtk.HeaderBar> {
19
- static matches(type: string): boolean;
20
- }
21
8
  type PackPosition = "start" | "end";
22
9
  type PackSlotProps = {
23
10
  position: PackPosition;
@@ -39,4 +26,18 @@ export declare class PackEndNode extends PackSlotNode {
39
26
  protected readonly position: PackPosition;
40
27
  static matches(type: string): boolean;
41
28
  }
29
+ export declare class PackContainerNode<T extends HeaderBarWidget> extends Node<T> implements PackContainer {
30
+ packStart(child: Gtk.Widget): void;
31
+ packEnd(child: Gtk.Widget): void;
32
+ removeFromPack(child: Gtk.Widget): void;
33
+ appendChild(child: Node): void;
34
+ insertBefore(child: Node, before: Node): void;
35
+ removeChild(child: Node): void;
36
+ }
37
+ export declare class AdwHeaderBarNode extends PackContainerNode<Adw.HeaderBar> {
38
+ static matches(type: string): boolean;
39
+ }
40
+ export declare class HeaderBarNode extends PackContainerNode<Gtk.HeaderBar> {
41
+ static matches(type: string): boolean;
42
+ }
42
43
  export {};
@@ -1,44 +1,6 @@
1
- import { isPackContainer } from "../container-interfaces.js";
2
1
  import { Node } from "../node.js";
2
+ import { isPackContainer } from "../predicates.js";
3
3
  import { VirtualSlotNode } from "./virtual-slot.js";
4
- export class PackContainerNode extends Node {
5
- packStart(child) {
6
- this.widget.packStart(child);
7
- }
8
- packEnd(child) {
9
- this.widget.packEnd(child);
10
- }
11
- removeFromPack(child) {
12
- this.widget.remove(child);
13
- }
14
- appendChild(child) {
15
- const childWidget = child.getWidget();
16
- if (!childWidget) {
17
- child.attachToParent(this);
18
- return;
19
- }
20
- this.packStart(childWidget);
21
- }
22
- removeChild(child) {
23
- const childWidget = child.getWidget();
24
- if (childWidget) {
25
- this.removeFromPack(childWidget);
26
- }
27
- else {
28
- child.detachFromParent(this);
29
- }
30
- }
31
- }
32
- export class AdwHeaderBarNode extends PackContainerNode {
33
- static matches(type) {
34
- return type === "AdwHeaderBar" || type === "AdwHeaderBar.Root";
35
- }
36
- }
37
- export class HeaderBarNode extends PackContainerNode {
38
- static matches(type) {
39
- return type === "HeaderBar" || type === "HeaderBar.Root";
40
- }
41
- }
42
4
  class PackSlotNode extends VirtualSlotNode {
43
5
  isValidContainer(parent) {
44
6
  return isPackContainer(parent);
@@ -74,3 +36,81 @@ export class PackEndNode extends PackSlotNode {
74
36
  return type === "HeaderBar.End" || type === "AdwHeaderBar.End" || type === "ActionBar.End";
75
37
  }
76
38
  }
39
+ export class PackContainerNode extends Node {
40
+ packStart(child) {
41
+ this.widget.packStart(child);
42
+ }
43
+ packEnd(child) {
44
+ this.widget.packEnd(child);
45
+ }
46
+ removeFromPack(child) {
47
+ this.widget.remove(child);
48
+ }
49
+ appendChild(child) {
50
+ if (child instanceof PackSlotNode) {
51
+ child.parent = this;
52
+ const childWidget = child.getChildWidget();
53
+ const props = child.getSlotProps();
54
+ if (childWidget) {
55
+ if (props.position === "start") {
56
+ this.packStart(childWidget);
57
+ }
58
+ else {
59
+ this.packEnd(childWidget);
60
+ }
61
+ child.setParentContainer(this);
62
+ }
63
+ return;
64
+ }
65
+ child.parent = this;
66
+ const childWidget = child.getWidget();
67
+ if (childWidget) {
68
+ this.packStart(childWidget);
69
+ }
70
+ }
71
+ insertBefore(child, before) {
72
+ if (child instanceof PackSlotNode) {
73
+ child.parent = this;
74
+ const childWidget = child.getChildWidget();
75
+ const props = child.getSlotProps();
76
+ if (childWidget) {
77
+ if (props.position === "start") {
78
+ this.packStart(childWidget);
79
+ }
80
+ else {
81
+ this.packEnd(childWidget);
82
+ }
83
+ child.setParentContainer(this);
84
+ }
85
+ return;
86
+ }
87
+ super.insertBefore(child, before);
88
+ }
89
+ removeChild(child) {
90
+ if (child instanceof PackSlotNode) {
91
+ const childWidget = child.getChildWidget();
92
+ if (childWidget) {
93
+ this.removeFromPack(childWidget);
94
+ }
95
+ child.unmount();
96
+ child.parent = null;
97
+ return;
98
+ }
99
+ child.unmount();
100
+ const childWidget = child.getWidget();
101
+ if (childWidget) {
102
+ this.removeFromPack(childWidget);
103
+ }
104
+ child.parent = null;
105
+ }
106
+ }
107
+ export class AdwHeaderBarNode extends PackContainerNode {
108
+ static matches(type) {
109
+ return type === "AdwHeaderBar" || type === "AdwHeaderBar.Root";
110
+ }
111
+ }
112
+ export class HeaderBarNode extends PackContainerNode {
113
+ static matches(type) {
114
+ return type === "HeaderBar" || type === "HeaderBar.Root";
115
+ }
116
+ }
@@ -1,5 +1,5 @@
1
1
  import type * as Gtk from "@gtkx/ffi/gtk";
2
- import type { ChildContainer } from "../container-interfaces.js";
2
+ import type { ChildContainer } from "../containers.js";
3
3
  import { Node } from "../node.js";
4
4
  type IndexedWidget = Gtk.Widget & {
5
5
  append(child: Gtk.Widget): void;
@@ -16,7 +16,7 @@ export class ListBoxNode extends IndexedChildContainerNode {
16
16
  const parent = child.getParent();
17
17
  if (parent && isListBoxRow(parent)) {
18
18
  beginBatch();
19
- parent.setChild(null);
19
+ parent.setChild(undefined);
20
20
  this.widget.remove(parent);
21
21
  endBatch();
22
22
  }
@@ -38,7 +38,7 @@ export class ListBoxNode extends IndexedChildContainerNode {
38
38
  detachChild(child) {
39
39
  if (isListBoxRow(child)) {
40
40
  beginBatch();
41
- child.setChild(null);
41
+ child.setChild(undefined);
42
42
  this.widget.remove(child);
43
43
  endBatch();
44
44
  return;
@@ -1,4 +1,4 @@
1
- import { getObject, getObjectId } from "@gtkx/ffi";
1
+ import { getObjectId } from "@gtkx/ffi";
2
2
  import * as GObject from "@gtkx/ffi/gobject";
3
3
  import * as Gtk from "@gtkx/ffi/gtk";
4
4
  import { createFiberRoot } from "../fiber-root.js";
@@ -7,7 +7,7 @@ export function connectListItemFactorySignals(config) {
7
7
  const { factory, listItemCache, getRenderFn, getItemAtPosition } = config;
8
8
  const handlerIds = [];
9
9
  const setupId = factory.connect("setup", (_self, listItemObj) => {
10
- const listItem = getObject(listItemObj.id);
10
+ const listItem = listItemObj;
11
11
  const id = getObjectId(listItemObj.id);
12
12
  const box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
13
13
  listItem.setChild(box);
@@ -18,7 +18,7 @@ export function connectListItemFactorySignals(config) {
18
18
  });
19
19
  handlerIds.push(setupId);
20
20
  const bindId = factory.connect("bind", (_self, listItemObj) => {
21
- const listItem = getObject(listItemObj.id);
21
+ const listItem = listItemObj;
22
22
  const id = getObjectId(listItemObj.id);
23
23
  const info = listItemCache.get(id);
24
24
  if (!info)
@@ -1,6 +1,5 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
2
  import type { Props } from "../factory.js";
3
- import type { Node } from "../node.js";
4
3
  import type { RenderItemFn } from "../types.js";
5
4
  import { type ListItemFactoryHandlers, type ListItemInfo } from "./list-item-factory.js";
6
5
  import { SelectableListNode, type SelectableListState } from "./selectable-list.js";
@@ -15,7 +14,7 @@ export declare class ListViewNode extends SelectableListNode<Gtk.ListView | Gtk.
15
14
  static consumedPropNames: string[];
16
15
  static matches(type: string): boolean;
17
16
  initialize(props: Props): void;
18
- detachFromParent(parent: Node): void;
17
+ unmount(): void;
19
18
  updateProps(oldProps: Props, newProps: Props): void;
20
19
  }
21
20
  export declare class ListItemNode extends VirtualItemNode {
@@ -26,10 +26,10 @@ export class ListViewNode extends SelectableListNode {
26
26
  this.applySelectionModel();
27
27
  this.widget.setFactory(this.state.factory);
28
28
  }
29
- detachFromParent(parent) {
29
+ unmount() {
30
30
  this.state.factoryHandlers?.disconnect();
31
31
  this.cleanupSelection();
32
- super.detachFromParent(parent);
32
+ super.unmount();
33
33
  }
34
34
  updateProps(oldProps, newProps) {
35
35
  if (oldProps.renderItem !== newProps.renderItem) {
@@ -1,7 +1,8 @@
1
1
  import * as Gio from "@gtkx/ffi/gio";
2
2
  import * as Gtk from "@gtkx/ffi/gtk";
3
3
  import type { Props } from "../factory.js";
4
- import { Node } from "../node.js";
4
+ import type { Node } from "../node.js";
5
+ import { Node as NodeClass } from "../node.js";
5
6
  type MenuEntry = {
6
7
  type: "item" | "section" | "submenu";
7
8
  label?: string;
@@ -13,19 +14,30 @@ interface MenuContainer {
13
14
  addMenuEntry(entry: MenuEntry): void;
14
15
  removeMenuEntry(entry: MenuEntry): void;
15
16
  }
16
- declare abstract class MenuContainerNode<T extends Gtk.Widget | undefined> extends Node<T> implements MenuContainer {
17
+ interface MenuEntryNode {
18
+ parent: Node | null;
19
+ getMenuEntry(): MenuEntry;
20
+ setParentContainer(container: Node & MenuContainer): void;
21
+ onAttach(): void;
22
+ onDetach(): void;
23
+ unmount(): void;
24
+ }
25
+ declare abstract class MenuContainerNode<T extends Gtk.Widget | undefined> extends NodeClass<T> implements MenuContainer {
17
26
  protected menu: Gio.Menu;
18
27
  protected entries: MenuEntry[];
19
28
  private rebuildScheduled;
20
29
  getMenu(): Gio.Menu;
21
30
  addMenuEntry(entry: MenuEntry): void;
22
31
  removeMenuEntry(entry: MenuEntry): void;
32
+ appendChild(child: Node): void;
33
+ insertBefore(child: Node, before: Node): void;
34
+ removeChild(child: Node): void;
23
35
  private scheduleRebuild;
24
36
  protected rebuildMenu(): void;
25
37
  protected onMenuRebuilt(): void;
26
38
  }
27
39
  type MenuWidget = Gtk.Widget & {
28
- setMenuModel(model: Gio.MenuModel | null): void;
40
+ setMenuModel(model?: Gio.MenuModel): void;
29
41
  };
30
42
  declare abstract class MenuWidgetNode<T extends MenuWidget> extends MenuContainerNode<T> {
31
43
  protected abstract createMenuWidget(menu: Gio.Menu): T;
@@ -43,12 +55,11 @@ export declare class PopoverMenuBarNode extends MenuWidgetNode<Gtk.PopoverMenuBa
43
55
  export declare class ApplicationMenuNode extends MenuContainerNode<never> {
44
56
  static matches(type: string): boolean;
45
57
  protected isVirtual(): boolean;
46
- detachFromParent(_parent: Node): void;
47
- attachToParent(parent: Node): void;
48
58
  mount(): void;
59
+ unmount(): void;
49
60
  protected onMenuRebuilt(): void;
50
61
  }
51
- export declare class MenuItemNode extends Node<never> {
62
+ export declare class MenuItemNode extends NodeClass<never> implements MenuEntryNode {
52
63
  static consumedPropNames: string[];
53
64
  static matches(type: string): boolean;
54
65
  protected isVirtual(): boolean;
@@ -58,10 +69,13 @@ export declare class MenuItemNode extends Node<never> {
58
69
  private signalHandlerId;
59
70
  private onActivateCallback;
60
71
  private currentAccels;
61
- private isAttached;
72
+ private parentContainer;
62
73
  initialize(props: Props): void;
63
- attachToParent(parent: Node): void;
64
- detachFromParent(parent: Node): void;
74
+ getMenuEntry(): MenuEntry;
75
+ setParentContainer(container: Node & MenuContainer): void;
76
+ onAttach(): void;
77
+ onDetach(): void;
78
+ unmount(): void;
65
79
  private isFieldInitializationIncomplete;
66
80
  updateProps(oldProps: Props, newProps: Props): void;
67
81
  private invokeCurrentCallback;
@@ -69,7 +83,7 @@ export declare class MenuItemNode extends Node<never> {
69
83
  private cleanupAction;
70
84
  private updateAccels;
71
85
  }
72
- declare class MenuContainerItemNode extends MenuContainerNode<never> {
86
+ declare class MenuContainerItemNode extends MenuContainerNode<never> implements MenuEntryNode {
73
87
  static consumedPropNames: string[];
74
88
  protected entryType: "section" | "submenu";
75
89
  protected matchType: string;
@@ -77,8 +91,10 @@ declare class MenuContainerItemNode extends MenuContainerNode<never> {
77
91
  protected isVirtual(): boolean;
78
92
  private entry;
79
93
  initialize(props: Props): void;
80
- attachToParent(parent: Node): void;
81
- detachFromParent(parent: Node): void;
94
+ getMenuEntry(): MenuEntry;
95
+ setParentContainer(_container: Node & MenuContainer): void;
96
+ onAttach(): void;
97
+ onDetach(): void;
82
98
  updateProps(oldProps: Props, newProps: Props): void;
83
99
  }
84
100
  export declare class MenuSectionNode extends MenuContainerItemNode {
@@ -1,13 +1,13 @@
1
- import { getCurrentApp, getInterface } from "@gtkx/ffi";
1
+ import { getCurrentApp, getObject } from "@gtkx/ffi";
2
2
  import * as Gio from "@gtkx/ffi/gio";
3
3
  import * as GObject from "@gtkx/ffi/gobject";
4
4
  import * as Gtk from "@gtkx/ffi/gtk";
5
- import { Node } from "../node.js";
5
+ import { Node as NodeClass } from "../node.js";
6
6
  import { RootNode } from "./root.js";
7
7
  let actionCounter = 0;
8
8
  const generateActionName = () => `gtkx_menu_action_${actionCounter++}`;
9
- const isMenuContainer = (node) => "getMenu" in node && "addMenuEntry" in node && "removeMenuEntry" in node;
10
- class MenuContainerNode extends Node {
9
+ const isMenuEntryNode = (node) => "getMenuEntry" in node && "setParentContainer" in node;
10
+ class MenuContainerNode extends NodeClass {
11
11
  menu = new Gio.Menu();
12
12
  entries = [];
13
13
  rebuildScheduled = false;
@@ -25,6 +25,35 @@ class MenuContainerNode extends Node {
25
25
  this.scheduleRebuild();
26
26
  }
27
27
  }
28
+ appendChild(child) {
29
+ if (isMenuEntryNode(child)) {
30
+ child.parent = this;
31
+ child.onAttach();
32
+ this.addMenuEntry(child.getMenuEntry());
33
+ child.setParentContainer(this);
34
+ return;
35
+ }
36
+ super.appendChild(child);
37
+ }
38
+ insertBefore(child, before) {
39
+ if (isMenuEntryNode(child)) {
40
+ child.parent = this;
41
+ child.onAttach();
42
+ this.addMenuEntry(child.getMenuEntry());
43
+ child.setParentContainer(this);
44
+ return;
45
+ }
46
+ super.insertBefore(child, before);
47
+ }
48
+ removeChild(child) {
49
+ if (isMenuEntryNode(child)) {
50
+ this.removeMenuEntry(child.getMenuEntry());
51
+ child.unmount();
52
+ child.parent = null;
53
+ return;
54
+ }
55
+ super.removeChild(child);
56
+ }
28
57
  scheduleRebuild() {
29
58
  if (this.rebuildScheduled)
30
59
  return;
@@ -38,13 +67,13 @@ class MenuContainerNode extends Node {
38
67
  this.menu.removeAll();
39
68
  for (const entry of this.entries) {
40
69
  if (entry.type === "item") {
41
- this.menu.append(entry.label ?? null, entry.action ?? null);
70
+ this.menu.append(entry.label, entry.action);
42
71
  }
43
72
  else if (entry.type === "section" && entry.menu) {
44
- this.menu.appendSection(entry.menu, entry.label ?? null);
73
+ this.menu.appendSection(entry.menu, entry.label);
45
74
  }
46
75
  else if (entry.type === "submenu" && entry.menu) {
47
- this.menu.appendSubmenu(entry.menu, entry.label ?? null);
76
+ this.menu.appendSubmenu(entry.menu, entry.label);
48
77
  }
49
78
  }
50
79
  this.onMenuRebuilt();
@@ -83,22 +112,21 @@ export class ApplicationMenuNode extends MenuContainerNode {
83
112
  isVirtual() {
84
113
  return true;
85
114
  }
86
- detachFromParent(_parent) {
87
- getCurrentApp().setMenubar(null);
88
- }
89
- attachToParent(parent) {
90
- if (!(parent instanceof RootNode)) {
115
+ mount() {
116
+ if (!(this.parent instanceof RootNode)) {
91
117
  throw new Error("ApplicationMenu must be a direct child of a fragment at the root level");
92
118
  }
93
- }
94
- mount() {
95
119
  getCurrentApp().setMenubar(this.menu);
96
120
  }
121
+ unmount() {
122
+ getCurrentApp().setMenubar(undefined);
123
+ super.unmount();
124
+ }
97
125
  onMenuRebuilt() {
98
126
  getCurrentApp().setMenubar(this.menu);
99
127
  }
100
128
  }
101
- export class MenuItemNode extends Node {
129
+ export class MenuItemNode extends NodeClass {
102
130
  static consumedPropNames = ["label", "onActivate", "accels"];
103
131
  static matches(type) {
104
132
  return type === "Menu.Item";
@@ -112,26 +140,29 @@ export class MenuItemNode extends Node {
112
140
  signalHandlerId = null;
113
141
  onActivateCallback;
114
142
  currentAccels;
115
- isAttached = false;
143
+ parentContainer = null;
116
144
  initialize(props) {
117
145
  this.onActivateCallback = props.onActivate;
118
146
  this.currentAccels = props.accels;
119
147
  this.entry.label = props.label;
120
148
  super.initialize(props);
121
149
  }
122
- attachToParent(parent) {
123
- if (!isMenuContainer(parent))
124
- return;
125
- this.isAttached = true;
150
+ getMenuEntry() {
151
+ return this.entry;
152
+ }
153
+ setParentContainer(container) {
154
+ this.parentContainer = container;
155
+ }
156
+ onAttach() {
126
157
  this.setupAction();
127
- parent.addMenuEntry(this.entry);
128
158
  }
129
- detachFromParent(parent) {
130
- if (!isMenuContainer(parent))
131
- return;
132
- parent.removeMenuEntry(this.entry);
159
+ onDetach() {
133
160
  this.cleanupAction();
134
- this.isAttached = false;
161
+ }
162
+ unmount() {
163
+ this.cleanupAction();
164
+ this.parentContainer = null;
165
+ super.unmount();
135
166
  }
136
167
  isFieldInitializationIncomplete() {
137
168
  return !this.entry;
@@ -149,7 +180,7 @@ export class MenuItemNode extends Node {
149
180
  if (labelChanged) {
150
181
  this.entry.label = newProps.label;
151
182
  }
152
- if (this.isAttached && callbackPresenceChanged) {
183
+ if (this.parentContainer && callbackPresenceChanged) {
153
184
  this.cleanupAction();
154
185
  this.setupAction();
155
186
  }
@@ -168,7 +199,7 @@ export class MenuItemNode extends Node {
168
199
  this.action = new Gio.SimpleAction(this.actionName);
169
200
  this.signalHandlerId = this.action.connect("activate", () => this.invokeCurrentCallback());
170
201
  const app = getCurrentApp();
171
- const action = getInterface(this.action.id, Gio.Action);
202
+ const action = getObject(this.action.id, Gio.Action);
172
203
  if (!action) {
173
204
  throw new Error("Failed to get Gio.Action interface from SimpleAction");
174
205
  }
@@ -219,16 +250,12 @@ class MenuContainerItemNode extends MenuContainerNode {
219
250
  this.entry.label = props.label;
220
251
  super.initialize(props);
221
252
  }
222
- attachToParent(parent) {
223
- if (!isMenuContainer(parent))
224
- return;
225
- parent.addMenuEntry(this.entry);
226
- }
227
- detachFromParent(parent) {
228
- if (!isMenuContainer(parent))
229
- return;
230
- parent.removeMenuEntry(this.entry);
253
+ getMenuEntry() {
254
+ return this.entry;
231
255
  }
256
+ setParentContainer(_container) { }
257
+ onAttach() { }
258
+ onDetach() { }
232
259
  updateProps(oldProps, newProps) {
233
260
  if (oldProps.label !== newProps.label && this.entry) {
234
261
  this.entry.label = newProps.label;
@@ -1,5 +1,5 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
- import { type ChildContainer, type PageContainer } from "../container-interfaces.js";
2
+ import type { ChildContainer, PageContainer } from "../containers.js";
3
3
  import type { Props } from "../factory.js";
4
4
  import { Node } from "../node.js";
5
5
  import { VirtualSlotNode } from "./virtual-slot.js";
@@ -12,6 +12,9 @@ export declare class NotebookNode extends Node<Gtk.Notebook> implements PageCont
12
12
  attachChild(child: Gtk.Widget): void;
13
13
  insertChildBefore(child: Gtk.Widget, before: Gtk.Widget): void;
14
14
  detachChild(child: Gtk.Widget): void;
15
+ appendChild(child: Node): void;
16
+ insertBefore(child: Node, before: Node): void;
17
+ removeChild(child: Node): void;
15
18
  }
16
19
  type NotebookPageProps = {
17
20
  label: string;
@@ -1,6 +1,6 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
- import { isPageContainer } from "../container-interfaces.js";
3
2
  import { Node } from "../node.js";
3
+ import { isPageContainer } from "../predicates.js";
4
4
  import { VirtualSlotNode } from "./virtual-slot.js";
5
5
  export class NotebookNode extends Node {
6
6
  static matches(type) {
@@ -34,20 +34,64 @@ export class NotebookNode extends Node {
34
34
  this.widget.setTabLabel(child, tabLabel);
35
35
  }
36
36
  attachChild(child) {
37
- this.widget.appendPage(child, null);
37
+ this.widget.appendPage(child);
38
38
  }
39
39
  insertChildBefore(child, before) {
40
40
  const beforePageNum = this.widget.pageNum(before);
41
41
  if (beforePageNum >= 0) {
42
- this.widget.insertPage(child, beforePageNum, null);
42
+ this.widget.insertPage(child, beforePageNum);
43
43
  }
44
44
  else {
45
- this.widget.appendPage(child, null);
45
+ this.widget.appendPage(child);
46
46
  }
47
47
  }
48
48
  detachChild(child) {
49
49
  this.removePage(child);
50
50
  }
51
+ appendChild(child) {
52
+ if (child instanceof NotebookPageNode) {
53
+ child.parent = this;
54
+ const childWidget = child.getChildWidget();
55
+ const props = child.getSlotProps();
56
+ if (childWidget) {
57
+ this.addPage(childWidget, props.label);
58
+ child.setParentContainer(this);
59
+ }
60
+ return;
61
+ }
62
+ super.appendChild(child);
63
+ }
64
+ insertBefore(child, before) {
65
+ if (child instanceof NotebookPageNode) {
66
+ child.parent = this;
67
+ const childWidget = child.getChildWidget();
68
+ const props = child.getSlotProps();
69
+ if (childWidget) {
70
+ const beforeWidget = child.getBeforeWidget(before);
71
+ if (beforeWidget) {
72
+ this.insertPageBefore(childWidget, props.label, beforeWidget);
73
+ }
74
+ else {
75
+ this.addPage(childWidget, props.label);
76
+ }
77
+ child.setParentContainer(this);
78
+ }
79
+ return;
80
+ }
81
+ super.insertBefore(child, before);
82
+ }
83
+ removeChild(child) {
84
+ if (child instanceof NotebookPageNode) {
85
+ const childWidget = child.getChildWidget();
86
+ if (childWidget) {
87
+ this.removePage(childWidget);
88
+ }
89
+ child.unmount();
90
+ child.parent = null;
91
+ return;
92
+ }
93
+ super.removeChild(child);
94
+ }
51
95
  }
52
96
  export class NotebookPageNode extends VirtualSlotNode {
53
97
  static consumedPropNames = ["label"];
@@ -1,5 +1,5 @@
1
1
  import type * as Gtk from "@gtkx/ffi/gtk";
2
- import type { ChildContainer } from "../container-interfaces.js";
2
+ import type { ChildContainer } from "../containers.js";
3
3
  import { Node } from "../node.js";
4
4
  export declare class OverlayNode extends Node<Gtk.Overlay> implements ChildContainer {
5
5
  static matches(type: string): boolean;
@@ -36,7 +36,7 @@ export class OverlayNode extends Node {
36
36
  }
37
37
  detachChild(childWidget) {
38
38
  if (this.mainChild === childWidget) {
39
- this.widget.setChild(null);
39
+ this.widget.setChild(undefined);
40
40
  this.mainChild = null;
41
41
  }
42
42
  else {
@@ -1,7 +1,8 @@
1
1
  import type * as Gtk from "@gtkx/ffi/gtk";
2
- import type { ChildContainer, StackPageContainer, StackPageProps } from "../container-interfaces.js";
2
+ import type { ChildContainer, StackPageContainer, StackPageProps } from "../containers.js";
3
3
  import type { Props } from "../factory.js";
4
- import { Node } from "../node.js";
4
+ import type { Node } from "../node.js";
5
+ import { Node as NodeClass } from "../node.js";
5
6
  import { type StackPageLike } from "./stack-page-props.js";
6
7
  type StackWidget = Gtk.Widget & {
7
8
  getChildByName(name: string): Gtk.Widget | null;
@@ -13,7 +14,7 @@ type StackWidget = Gtk.Widget & {
13
14
  * Abstract node for paged stack widgets (Gtk.Stack, Adw.ViewStack).
14
15
  * Handles visible child deferral and common page operations.
15
16
  */
16
- export declare abstract class PagedStackNode<T extends StackWidget> extends Node<T> implements StackPageContainer, ChildContainer {
17
+ export declare abstract class PagedStackNode<T extends StackWidget> extends NodeClass<T> implements StackPageContainer, ChildContainer {
17
18
  static consumedPropNames: string[];
18
19
  private pendingVisibleChildName;
19
20
  /**
@@ -34,6 +35,9 @@ export declare abstract class PagedStackNode<T extends StackWidget> extends Node
34
35
  insertChildBefore(child: Gtk.Widget, _before: Gtk.Widget): void;
35
36
  detachChild(child: Gtk.Widget): void;
36
37
  private setVisibleChildOrDefer;
38
+ appendChild(child: Node): void;
39
+ insertBefore(child: Node, before: Node): void;
40
+ removeChild(child: Node): void;
37
41
  updateProps(oldProps: Props, newProps: Props): void;
38
42
  }
39
43
  export {};