@gtkx/react 0.8.0 → 0.9.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 (56) 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 +6 -7
  12. package/dist/nodes/column-view.js +29 -32
  13. package/dist/nodes/grid.d.ts +4 -1
  14. package/dist/nodes/grid.js +39 -1
  15. package/dist/nodes/header-bar.d.ts +15 -14
  16. package/dist/nodes/header-bar.js +79 -39
  17. package/dist/nodes/indexed-child-container.d.ts +1 -1
  18. package/dist/nodes/list-view.d.ts +1 -2
  19. package/dist/nodes/list-view.js +2 -2
  20. package/dist/nodes/menu.d.ts +27 -11
  21. package/dist/nodes/menu.js +59 -32
  22. package/dist/nodes/notebook.d.ts +4 -1
  23. package/dist/nodes/notebook.js +45 -1
  24. package/dist/nodes/overlay.d.ts +1 -1
  25. package/dist/nodes/paged-stack.d.ts +7 -3
  26. package/dist/nodes/paged-stack.js +47 -2
  27. package/dist/nodes/root.d.ts +1 -1
  28. package/dist/nodes/root.js +2 -2
  29. package/dist/nodes/selectable-list.d.ts +7 -3
  30. package/dist/nodes/selectable-list.js +34 -2
  31. package/dist/nodes/slot.d.ts +3 -4
  32. package/dist/nodes/slot.js +11 -10
  33. package/dist/nodes/stack-page-props.d.ts +1 -1
  34. package/dist/nodes/stack.d.ts +1 -1
  35. package/dist/nodes/stack.js +1 -1
  36. package/dist/nodes/string-list-container.d.ts +4 -11
  37. package/dist/nodes/string-list-container.js +32 -4
  38. package/dist/nodes/string-list-item.d.ts +10 -6
  39. package/dist/nodes/string-list-item.js +19 -17
  40. package/dist/nodes/toggle-button.d.ts +0 -3
  41. package/dist/nodes/toggle-button.js +0 -28
  42. package/dist/nodes/toolbar-view.d.ts +2 -3
  43. package/dist/nodes/toolbar-view.js +10 -9
  44. package/dist/nodes/view-stack.d.ts +1 -1
  45. package/dist/nodes/virtual-item.d.ts +9 -5
  46. package/dist/nodes/virtual-item.js +16 -20
  47. package/dist/nodes/virtual-slot.d.ts +4 -4
  48. package/dist/nodes/virtual-slot.js +12 -26
  49. package/dist/nodes/window.d.ts +2 -1
  50. package/dist/nodes/window.js +7 -3
  51. package/dist/predicates.d.ts +9 -18
  52. package/dist/predicates.js +31 -18
  53. package/dist/reconciler.d.ts +1 -1
  54. package/dist/reconciler.js +1 -1
  55. package/package.json +4 -4
  56. package/dist/container-interfaces.js +0 -26
@@ -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;
@@ -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,13 +14,24 @@ 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;
@@ -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 {
@@ -2,12 +2,12 @@ import { getCurrentApp, getInterface } 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;
@@ -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(null);
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() {
160
+ this.cleanupAction();
161
+ }
162
+ unmount() {
133
163
  this.cleanupAction();
134
- this.isAttached = false;
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
  }
@@ -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) {
@@ -48,6 +48,50 @@ export class NotebookNode extends Node {
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;
@@ -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 {};
@@ -1,10 +1,11 @@
1
- import { Node } from "../node.js";
1
+ import { Node as NodeClass } from "../node.js";
2
+ import { StackPageNode } from "./stack.js";
2
3
  import { applyStackPageProps } from "./stack-page-props.js";
3
4
  /**
4
5
  * Abstract node for paged stack widgets (Gtk.Stack, Adw.ViewStack).
5
6
  * Handles visible child deferral and common page operations.
6
7
  */
7
- export class PagedStackNode extends Node {
8
+ export class PagedStackNode extends NodeClass {
8
9
  static consumedPropNames = ["visibleChildName"];
9
10
  pendingVisibleChildName = null;
10
11
  applyPendingVisibleChild() {
@@ -45,6 +46,50 @@ export class PagedStackNode extends Node {
45
46
  this.pendingVisibleChildName = name;
46
47
  }
47
48
  }
49
+ appendChild(child) {
50
+ if (child instanceof StackPageNode) {
51
+ child.parent = this;
52
+ const childWidget = child.getChildWidget();
53
+ const props = child.getSlotProps();
54
+ if (childWidget) {
55
+ this.addStackPage(childWidget, props);
56
+ child.setParentContainer(this);
57
+ }
58
+ return;
59
+ }
60
+ super.appendChild(child);
61
+ }
62
+ insertBefore(child, before) {
63
+ if (child instanceof StackPageNode) {
64
+ child.parent = this;
65
+ const childWidget = child.getChildWidget();
66
+ const props = child.getSlotProps();
67
+ if (childWidget) {
68
+ const beforeWidget = child.getBeforeWidget(before);
69
+ if (beforeWidget) {
70
+ this.insertStackPageBefore(childWidget, props, beforeWidget);
71
+ }
72
+ else {
73
+ this.addStackPage(childWidget, props);
74
+ }
75
+ child.setParentContainer(this);
76
+ }
77
+ return;
78
+ }
79
+ super.insertBefore(child, before);
80
+ }
81
+ removeChild(child) {
82
+ if (child instanceof StackPageNode) {
83
+ const childWidget = child.getChildWidget();
84
+ if (childWidget) {
85
+ this.removeStackPage(childWidget);
86
+ }
87
+ child.unmount();
88
+ child.parent = null;
89
+ return;
90
+ }
91
+ super.removeChild(child);
92
+ }
48
93
  updateProps(oldProps, newProps) {
49
94
  if (newProps.visibleChildName !== undefined) {
50
95
  this.setVisibleChildOrDefer(newProps.visibleChildName);
@@ -2,7 +2,7 @@ import type * as Gtk from "@gtkx/ffi/gtk";
2
2
  import { Node } from "../node.js";
3
3
  export declare const ROOT_NODE_CONTAINER: unique symbol;
4
4
  export declare class RootNode extends Node<never> {
5
- static matches(_type: string, existingWidget?: Gtk.Widget | typeof ROOT_NODE_CONTAINER): boolean;
5
+ static matches(_type: string, widget?: Gtk.Widget | typeof ROOT_NODE_CONTAINER): boolean;
6
6
  protected isVirtual(): boolean;
7
7
  constructor();
8
8
  }
@@ -1,8 +1,8 @@
1
1
  import { Node } from "../node.js";
2
2
  export const ROOT_NODE_CONTAINER = Symbol.for("ROOT_NODE_CONTAINER");
3
3
  export class RootNode extends Node {
4
- static matches(_type, existingWidget) {
5
- return existingWidget === ROOT_NODE_CONTAINER;
4
+ static matches(_type, widget) {
5
+ return widget === ROOT_NODE_CONTAINER;
6
6
  }
7
7
  isVirtual() {
8
8
  return true;
@@ -1,7 +1,8 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
- import type { ItemContainer } from "../container-interfaces.js";
2
+ import type { ItemContainer } 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
  export type SelectableListState = {
6
7
  itemsById: Map<string, unknown>;
7
8
  itemOrder: string[];
@@ -18,7 +19,10 @@ export type SelectableListState = {
18
19
  type SelectableListWidget = Gtk.Widget & {
19
20
  setModel(model: Gtk.SelectionModel): void;
20
21
  };
21
- export declare abstract class SelectableListNode<T extends SelectableListWidget, S extends SelectableListState> extends Node<T, S> implements ItemContainer<unknown> {
22
+ export declare abstract class SelectableListNode<T extends SelectableListWidget, S extends SelectableListState> extends NodeClass<T, S> implements ItemContainer<unknown> {
23
+ appendChild(child: Node): void;
24
+ insertBefore(child: Node, before: Node): void;
25
+ removeChild(child: Node): void;
22
26
  protected initializeSelectionState(props: Props): SelectableListState;
23
27
  protected applySelectionModel(): void;
24
28
  protected cleanupSelection(): void;
@@ -3,9 +3,41 @@ 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
5
  import { scheduleFlush } from "../batch.js";
6
- import { Node } from "../node.js";
6
+ import { Node as NodeClass } from "../node.js";
7
7
  import { getCallbackChange } from "../props.js";
8
- export class SelectableListNode extends Node {
8
+ import { VirtualItemNode } from "./virtual-item.js";
9
+ export class SelectableListNode extends NodeClass {
10
+ appendChild(child) {
11
+ if (child instanceof VirtualItemNode) {
12
+ child.parent = this;
13
+ child.addToContainer(this);
14
+ child.setParentContainer(this);
15
+ return;
16
+ }
17
+ super.appendChild(child);
18
+ }
19
+ insertBefore(child, before) {
20
+ if (child instanceof VirtualItemNode) {
21
+ child.parent = this;
22
+ if (before instanceof VirtualItemNode) {
23
+ child.insertBeforeInContainer(this, before.getId());
24
+ }
25
+ else {
26
+ child.addToContainer(this);
27
+ }
28
+ child.setParentContainer(this);
29
+ return;
30
+ }
31
+ super.insertBefore(child, before);
32
+ }
33
+ removeChild(child) {
34
+ if (child instanceof VirtualItemNode) {
35
+ child.unmount();
36
+ child.parent = null;
37
+ return;
38
+ }
39
+ super.removeChild(child);
40
+ }
9
41
  initializeSelectionState(props) {
10
42
  const selectionMode = props.selectionMode ?? Gtk.SelectionMode.SINGLE;
11
43
  const stringList = new Gtk.StringList([]);