@gtkx/react 0.10.1 → 0.10.3

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 (38) hide show
  1. package/dist/generated/jsx.d.ts +14 -5
  2. package/dist/host-config.d.ts +0 -1
  3. package/dist/host-config.js +3 -6
  4. package/dist/node.d.ts +0 -2
  5. package/dist/node.js +2 -4
  6. package/dist/nodes/column-view-column.js +1 -1
  7. package/dist/nodes/column-view.js +2 -1
  8. package/dist/nodes/index.d.ts +0 -3
  9. package/dist/nodes/index.js +0 -3
  10. package/dist/nodes/internal/list-item-renderer.d.ts +1 -3
  11. package/dist/nodes/internal/list-item-renderer.js +6 -7
  12. package/dist/nodes/internal/predicates.d.ts +3 -0
  13. package/dist/nodes/internal/predicates.js +3 -0
  14. package/dist/nodes/internal/signal-store.d.ts +11 -5
  15. package/dist/nodes/internal/signal-store.js +50 -31
  16. package/dist/nodes/internal/tree-list-item-renderer.d.ts +1 -3
  17. package/dist/nodes/internal/tree-list-item-renderer.js +6 -7
  18. package/dist/nodes/list-view.js +1 -1
  19. package/dist/nodes/models/list.js +3 -2
  20. package/dist/nodes/models/menu.js +5 -4
  21. package/dist/nodes/models/tree-list.js +3 -2
  22. package/dist/nodes/notebook-page-tab.js +0 -3
  23. package/dist/nodes/notebook-page.js +0 -3
  24. package/dist/nodes/simple-list-view.js +2 -1
  25. package/dist/nodes/toast.js +3 -2
  26. package/dist/nodes/toolbar-child.d.ts +1 -9
  27. package/dist/nodes/toolbar-child.js +1 -1
  28. package/dist/nodes/tree-list-view.js +1 -1
  29. package/dist/nodes/widget.d.ts +1 -0
  30. package/dist/nodes/widget.js +30 -14
  31. package/dist/nodes/window.js +0 -10
  32. package/package.json +3 -3
  33. package/dist/nodes/navigation-page.d.ts +0 -21
  34. package/dist/nodes/navigation-page.js +0 -95
  35. package/dist/nodes/navigation-view.d.ts +0 -1
  36. package/dist/nodes/navigation-view.js +0 -29
  37. package/dist/nodes/toolbar.d.ts +0 -1
  38. package/dist/nodes/toolbar.js +0 -42
@@ -3186,8 +3186,6 @@ export interface GtkGLAreaProps extends WidgetProps {
3186
3186
  export interface GtkGraphicsOffloadProps extends WidgetProps {
3187
3187
  /** Whether to draw a black background. */
3188
3188
  blackBackground?: boolean;
3189
- /** The child widget. */
3190
- child?: Gtk.Widget;
3191
3189
  /** Whether graphics offload is enabled. */
3192
3190
  enabled?: Gtk.GraphicsOffloadEnabled;
3193
3191
  children?: ReactNode;
@@ -12328,7 +12326,6 @@ export type WidgetSlotNames = {
12328
12326
  GtkExpander: "child" | "labelWidget";
12329
12327
  GtkFlowBoxChild: "child";
12330
12328
  GtkFrame: "child" | "labelWidget";
12331
- GtkGraphicsOffload: "child";
12332
12329
  GtkHeaderBar: "titleWidget";
12333
12330
  GtkLabel: "mnemonicWidget";
12334
12331
  GtkListBoxRow: "child";
@@ -12353,26 +12350,38 @@ export type WidgetSlotNames = {
12353
12350
  AdwBin: "child";
12354
12351
  AdwBottomSheet: "bottomBar" | "content" | "sheet";
12355
12352
  AdwBreakpointBin: "child";
12353
+ AdwCarouselIndicatorDots: "carousel";
12354
+ AdwCarouselIndicatorLines: "carousel";
12356
12355
  AdwClamp: "child";
12357
12356
  AdwClampScrollable: "child";
12358
12357
  AdwDialog: "child" | "defaultWidget" | "focusWidget";
12359
12358
  AdwFlap: "content" | "flap" | "separator";
12360
12359
  AdwHeaderBar: "titleWidget";
12360
+ AdwInlineViewSwitcher: "stack";
12361
12361
  AdwLeaflet: "visibleChild";
12362
12362
  AdwMessageDialog: "extraChild";
12363
+ AdwNavigationSplitView: "content" | "sidebar";
12363
12364
  AdwOverlaySplitView: "content" | "sidebar";
12364
12365
  AdwPreferencesDialog: "visiblePage";
12365
12366
  AdwPreferencesGroup: "headerSuffix";
12367
+ AdwPreferencesPage: "banner";
12366
12368
  AdwPreferencesWindow: "visiblePage";
12367
12369
  AdwSplitButton: "child" | "popover";
12368
12370
  AdwStatusPage: "child";
12369
- AdwTabBar: "endActionWidget" | "startActionWidget";
12370
- AdwTabOverview: "child";
12371
+ AdwTabBar: "endActionWidget" | "startActionWidget" | "view";
12372
+ AdwTabButton: "view";
12373
+ AdwTabOverview: "child" | "view";
12371
12374
  AdwToastOverlay: "child";
12372
12375
  AdwToolbarView: "content";
12373
12376
  AdwViewStack: "visibleChild";
12377
+ AdwViewSwitcher: "stack";
12378
+ AdwViewSwitcherBar: "stack";
12379
+ AdwViewSwitcherTitle: "stack";
12374
12380
  GtkSourceCompletionCell: "widget";
12381
+ GtkSourceGutter: "view";
12382
+ GtkSourceMap: "view";
12375
12383
  VteTerminal: "contextMenu";
12384
+ WebKitWebView: "relatedView";
12376
12385
  };
12377
12386
  /**
12378
12387
  * The base class for all widgets.
@@ -5,7 +5,6 @@ import type { Container, Props } from "./types.js";
5
5
  declare global {
6
6
  var __GTKX_CONTAINER_NODE_CACHE__: Map<number, Node> | undefined;
7
7
  }
8
- export declare const isCommitting: () => boolean;
9
8
  type TextInstance = Node;
10
9
  type SuspenseInstance = never;
11
10
  type HydratableInstance = never;
@@ -1,13 +1,11 @@
1
1
  import { beginBatch, endBatch, getObjectId } from "@gtkx/ffi";
2
2
  import React from "react";
3
3
  import { createNode } from "./factory.js";
4
- import { clearFiredSignals } from "./nodes/internal/signal-store.js";
4
+ import { signalStore } from "./nodes/internal/signal-store.js";
5
5
  import { flushAfterCommit } from "./scheduler.js";
6
6
  if (!globalThis.__GTKX_CONTAINER_NODE_CACHE__) {
7
7
  globalThis.__GTKX_CONTAINER_NODE_CACHE__ = new Map();
8
8
  }
9
- let committing = false;
10
- export const isCommitting = () => committing;
11
9
  const containerNodeCache = globalThis.__GTKX_CONTAINER_NODE_CACHE__;
12
10
  const getOrCreateContainerNode = (container) => {
13
11
  const id = getObjectId(container.id);
@@ -73,15 +71,14 @@ export function createHostConfig() {
73
71
  parent.insertBefore(child, beforeChild);
74
72
  },
75
73
  prepareForCommit: () => {
76
- committing = true;
74
+ signalStore.blockAll();
77
75
  beginBatch();
78
76
  return null;
79
77
  },
80
78
  resetAfterCommit: () => {
81
79
  endBatch();
82
- clearFiredSignals();
80
+ signalStore.unblockAll();
83
81
  flushAfterCommit();
84
- committing = false;
85
82
  },
86
83
  commitTextUpdate: (textInstance, oldText, newText) => {
87
84
  textInstance.updateProps({ label: oldText }, { label: newText });
package/dist/node.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { SignalStore } from "./nodes/internal/signal-store.js";
2
1
  import type { Container, ContainerClass, Props } from "./types.js";
3
2
  export declare class Node<T = unknown, P = Props> {
4
3
  static priority: number;
@@ -6,7 +5,6 @@ export declare class Node<T = unknown, P = Props> {
6
5
  static createContainer(_props: Props, _containerClass: ContainerClass, _rootContainer?: Container): unknown;
7
6
  container: T;
8
7
  typeName: string;
9
- protected signalStore: SignalStore;
10
8
  constructor(typeName: string, _props: P | undefined, container: T, _rootContainer?: Container);
11
9
  appendChild(_child: Node): void;
12
10
  removeChild(_child: Node): void;
package/dist/node.js CHANGED
@@ -1,4 +1,4 @@
1
- import { SignalStore } from "./nodes/internal/signal-store.js";
1
+ import { signalStore } from "./nodes/internal/signal-store.js";
2
2
  export class Node {
3
3
  static priority = 0;
4
4
  static matches(_type, _containerOrClass) {
@@ -9,11 +9,9 @@ export class Node {
9
9
  }
10
10
  container;
11
11
  typeName;
12
- signalStore;
13
12
  constructor(typeName, _props = {}, container, _rootContainer) {
14
13
  this.typeName = typeName;
15
14
  this.container = container;
16
- this.signalStore = new SignalStore();
17
15
  }
18
16
  appendChild(_child) { }
19
17
  removeChild(_child) { }
@@ -21,6 +19,6 @@ export class Node {
21
19
  updateProps(_oldProps, _newProps) { }
22
20
  mount() { }
23
21
  unmount() {
24
- this.signalStore.clear();
22
+ signalStore.clear(this);
25
23
  }
26
24
  }
@@ -11,7 +11,7 @@ export class ColumnViewColumnNode extends VirtualNode {
11
11
  itemRenderer;
12
12
  constructor(typeName, props, container, rootContainer) {
13
13
  super(typeName, props, container, rootContainer);
14
- this.itemRenderer = new ListItemRenderer(this.signalStore);
14
+ this.itemRenderer = new ListItemRenderer();
15
15
  this.column = new Gtk.ColumnViewColumn();
16
16
  this.column.setFactory(this.itemRenderer.getFactory());
17
17
  }
@@ -1,6 +1,7 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
2
  import { registerNodeClass } from "../registry.js";
3
3
  import { ColumnViewColumnNode } from "./column-view-column.js";
4
+ import { signalStore } from "./internal/signal-store.js";
4
5
  import { filterProps, isContainerType } from "./internal/utils.js";
5
6
  import { ListItemNode } from "./list-item.js";
6
7
  import { List } from "./models/list.js";
@@ -79,7 +80,7 @@ class ColumnViewNode extends WidgetNode {
79
80
  this.handleSortChange = () => {
80
81
  onSortChange?.(sorter.getPrimarySortColumn()?.getId() ?? null, sorter.getPrimarySortOrder());
81
82
  };
82
- this.signalStore.set(sorter, "changed", this.handleSortChange);
83
+ signalStore.set(this, sorter, "changed", this.handleSortChange);
83
84
  }
84
85
  }
85
86
  if (!oldProps || oldProps.sortColumn !== newProps.sortColumn || oldProps.sortOrder !== newProps.sortOrder) {
@@ -9,8 +9,6 @@ import "./grid-child.js";
9
9
  import "./list-item.js";
10
10
  import "./list-view.js";
11
11
  import "./menu.js";
12
- import "./navigation-page.js";
13
- import "./navigation-view.js";
14
12
  import "./notebook-page-tab.js";
15
13
  import "./notebook-page.js";
16
14
  import "./notebook.js";
@@ -26,7 +24,6 @@ import "./stack.js";
26
24
  import "./toast-overlay.js";
27
25
  import "./toast.js";
28
26
  import "./toolbar-child.js";
29
- import "./toolbar.js";
30
27
  import "./tree-list-item.js";
31
28
  import "./tree-list-view.js";
32
29
  import "./virtual.js";
@@ -9,8 +9,6 @@ import "./grid-child.js";
9
9
  import "./list-item.js";
10
10
  import "./list-view.js";
11
11
  import "./menu.js";
12
- import "./navigation-page.js";
13
- import "./navigation-view.js";
14
12
  import "./notebook-page-tab.js";
15
13
  import "./notebook-page.js";
16
14
  import "./notebook.js";
@@ -26,7 +24,6 @@ import "./stack.js";
26
24
  import "./toast-overlay.js";
27
25
  import "./toast.js";
28
26
  import "./toolbar-child.js";
29
- import "./toolbar.js";
30
27
  import "./tree-list-item.js";
31
28
  import "./tree-list-view.js";
32
29
  import "./virtual.js";
@@ -1,15 +1,13 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
2
  import type { ReactNode } from "react";
3
3
  import type { ListStore } from "./list-store.js";
4
- import type { SignalStore } from "./signal-store.js";
5
4
  export type RenderItemFn<T> = (item: T | null) => ReactNode;
6
5
  export declare class ListItemRenderer {
7
6
  private factory;
8
7
  private store?;
9
8
  private fiberRoots;
10
9
  private renderFn?;
11
- private signalStore;
12
- constructor(signalStore: SignalStore);
10
+ constructor();
13
11
  getFactory(): Gtk.SignalListItemFactory;
14
12
  setRenderFn(renderFn?: RenderItemFn<unknown>): void;
15
13
  setStore(store?: ListStore): void;
@@ -2,14 +2,13 @@ import { getObjectId } from "@gtkx/ffi";
2
2
  import * as Gtk from "@gtkx/ffi/gtk";
3
3
  import { createFiberRoot } from "../../fiber-root.js";
4
4
  import { reconciler } from "../../reconciler.js";
5
+ import { signalStore } from "./signal-store.js";
5
6
  export class ListItemRenderer {
6
7
  factory;
7
8
  store;
8
9
  fiberRoots = new Map();
9
10
  renderFn = () => null;
10
- signalStore;
11
- constructor(signalStore) {
12
- this.signalStore = signalStore;
11
+ constructor() {
13
12
  this.factory = new Gtk.SignalListItemFactory();
14
13
  this.initialize();
15
14
  }
@@ -29,7 +28,7 @@ export class ListItemRenderer {
29
28
  return this.store;
30
29
  }
31
30
  initialize() {
32
- this.signalStore.set(this.factory, "setup", (_self, listItem) => {
31
+ signalStore.set(this, this.factory, "setup", (_self, listItem) => {
33
32
  const ptr = getObjectId(listItem.id);
34
33
  const box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
35
34
  listItem.setChild(box);
@@ -38,7 +37,7 @@ export class ListItemRenderer {
38
37
  const element = this.renderFn?.(null);
39
38
  reconciler.getInstance().updateContainer(element, fiberRoot, null, () => { });
40
39
  });
41
- this.signalStore.set(this.factory, "bind", (_self, listItem) => {
40
+ signalStore.set(this, this.factory, "bind", (_self, listItem) => {
42
41
  const ptr = getObjectId(listItem.id);
43
42
  const fiberRoot = this.fiberRoots.get(ptr);
44
43
  if (!fiberRoot)
@@ -48,14 +47,14 @@ export class ListItemRenderer {
48
47
  const element = this.renderFn?.(item);
49
48
  reconciler.getInstance().updateContainer(element, fiberRoot, null, () => { });
50
49
  });
51
- this.signalStore.set(this.factory, "unbind", (_self, listItem) => {
50
+ signalStore.set(this, this.factory, "unbind", (_self, listItem) => {
52
51
  const ptr = getObjectId(listItem.id);
53
52
  const fiberRoot = this.fiberRoots.get(ptr);
54
53
  if (!fiberRoot)
55
54
  return;
56
55
  reconciler.getInstance().updateContainer(null, fiberRoot, null, () => { });
57
56
  });
58
- this.signalStore.set(this.factory, "teardown", (_self, listItem) => {
57
+ signalStore.set(this, this.factory, "teardown", (_self, listItem) => {
59
58
  const ptr = getObjectId(listItem.id);
60
59
  const fiberRoot = this.fiberRoots.get(ptr);
61
60
  if (fiberRoot) {
@@ -5,6 +5,9 @@ export declare const isAppendable: (obj: unknown) => obj is Gtk.Widget & {
5
5
  export declare const isAddable: (obj: unknown) => obj is Gtk.Widget & {
6
6
  add: (child: Gtk.Widget) => void;
7
7
  };
8
+ export declare const hasSingleContent: (obj: unknown) => obj is Gtk.Widget & {
9
+ setContent: (content: Gtk.Widget | undefined) => void;
10
+ };
8
11
  export declare const isSingleChild: (obj: unknown) => obj is Gtk.Widget & {
9
12
  setChild: (child: Gtk.Widget | null) => void;
10
13
  };
@@ -5,6 +5,9 @@ export const isAppendable = (obj) => {
5
5
  export const isAddable = (obj) => {
6
6
  return obj instanceof Gtk.Widget && "add" in obj && typeof obj.add === "function";
7
7
  };
8
+ export const hasSingleContent = (obj) => {
9
+ return obj instanceof Gtk.Widget && "setContent" in obj && typeof obj.setContent === "function";
10
+ };
8
11
  export const isSingleChild = (obj) => {
9
12
  return obj instanceof Gtk.Widget && "setChild" in obj && typeof obj.setChild === "function";
10
13
  };
@@ -1,10 +1,16 @@
1
1
  import * as GObject from "@gtkx/ffi/gobject";
2
+ type SignalOwner = object;
2
3
  export type SignalHandler = (...args: any[]) => any;
3
- export declare const clearFiredSignals: () => void;
4
- export declare class SignalStore {
5
- private signalHandlers;
4
+ declare class SignalStore {
5
+ private ownerHandlers;
6
+ private blockedHandlers;
7
+ private getOwnerMap;
6
8
  private disconnect;
7
9
  private connect;
8
- set(obj: GObject.GObject, signal: string, handler?: SignalHandler): void;
9
- clear(): void;
10
+ set(owner: SignalOwner, obj: GObject.GObject, signal: string, handler?: SignalHandler): void;
11
+ clear(owner: SignalOwner): void;
12
+ blockAll(): void;
13
+ unblockAll(): void;
10
14
  }
15
+ export declare const signalStore: SignalStore;
16
+ export {};
@@ -1,6 +1,5 @@
1
1
  import { getObjectId } from "@gtkx/ffi";
2
2
  import * as GObject from "@gtkx/ffi/gobject";
3
- import { isCommitting } from "../../host-config.js";
4
3
  const LIFECYCLE_SIGNALS = new Set([
5
4
  "realize",
6
5
  "unrealize",
@@ -16,49 +15,69 @@ const LIFECYCLE_SIGNALS = new Set([
16
15
  "unbind",
17
16
  "teardown",
18
17
  ]);
19
- const firedThisCommit = new Set();
20
- export const clearFiredSignals = () => {
21
- firedThisCommit.clear();
22
- };
23
- export class SignalStore {
24
- signalHandlers = new Map();
25
- disconnect(obj, signal) {
18
+ class SignalStore {
19
+ ownerHandlers = new Map();
20
+ blockedHandlers = new Set();
21
+ getOwnerMap(owner) {
22
+ let map = this.ownerHandlers.get(owner);
23
+ if (!map) {
24
+ map = new Map();
25
+ this.ownerHandlers.set(owner, map);
26
+ }
27
+ return map;
28
+ }
29
+ disconnect(owner, obj, signal) {
26
30
  const objectId = getObjectId(obj.id);
27
31
  const key = `${objectId}:${signal}`;
28
- const existing = this.signalHandlers.get(key);
32
+ const ownerMap = this.ownerHandlers.get(owner);
33
+ const existing = ownerMap?.get(key);
29
34
  if (existing) {
30
35
  GObject.signalHandlerDisconnect(existing.obj, existing.handlerId);
31
- this.signalHandlers.delete(key);
36
+ ownerMap?.delete(key);
32
37
  }
33
38
  }
34
- connect(obj, signal, handler) {
39
+ connect(owner, obj, signal, handler) {
35
40
  const objectId = getObjectId(obj.id);
36
41
  const key = `${objectId}:${signal}`;
37
- const wrappedHandler = (...args) => {
38
- if (LIFECYCLE_SIGNALS.has(signal)) {
39
- return handler(...args);
42
+ const handlerId = obj.connect(signal, handler);
43
+ this.getOwnerMap(owner).set(key, { obj, handlerId });
44
+ }
45
+ set(owner, obj, signal, handler) {
46
+ this.disconnect(owner, obj, signal);
47
+ if (handler) {
48
+ this.connect(owner, obj, signal, handler);
49
+ }
50
+ }
51
+ clear(owner) {
52
+ const ownerMap = this.ownerHandlers.get(owner);
53
+ if (ownerMap) {
54
+ for (const { obj, handlerId } of ownerMap.values()) {
55
+ GObject.signalHandlerDisconnect(obj, handlerId);
40
56
  }
41
- if (isCommitting()) {
42
- if (firedThisCommit.has(key)) {
43
- return;
57
+ this.ownerHandlers.delete(owner);
58
+ }
59
+ }
60
+ blockAll() {
61
+ this.blockedHandlers.clear();
62
+ for (const ownerMap of this.ownerHandlers.values()) {
63
+ for (const [key, { obj, handlerId }] of ownerMap.entries()) {
64
+ if (LIFECYCLE_SIGNALS.has(key.split(":")[1] ?? "")) {
65
+ continue;
44
66
  }
45
- firedThisCommit.add(key);
67
+ GObject.signalHandlerBlock(obj, handlerId);
68
+ this.blockedHandlers.add(handlerId);
46
69
  }
47
- return handler(...args);
48
- };
49
- const handlerId = obj.connect(signal, wrappedHandler);
50
- this.signalHandlers.set(key, { obj, handlerId });
51
- }
52
- set(obj, signal, handler) {
53
- this.disconnect(obj, signal);
54
- if (handler) {
55
- this.connect(obj, signal, handler);
56
70
  }
57
71
  }
58
- clear() {
59
- for (const [_, { obj, handlerId }] of this.signalHandlers) {
60
- GObject.signalHandlerDisconnect(obj, handlerId);
72
+ unblockAll() {
73
+ for (const ownerMap of this.ownerHandlers.values()) {
74
+ for (const { obj, handlerId } of ownerMap.values()) {
75
+ if (this.blockedHandlers.has(handlerId)) {
76
+ GObject.signalHandlerUnblock(obj, handlerId);
77
+ }
78
+ }
61
79
  }
62
- this.signalHandlers.clear();
80
+ this.blockedHandlers.clear();
63
81
  }
64
82
  }
83
+ export const signalStore = new SignalStore();
@@ -1,6 +1,5 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
2
  import type { ReactNode } from "react";
3
- import type { SignalStore } from "./signal-store.js";
4
3
  import type { TreeStore } from "./tree-store.js";
5
4
  export type TreeRenderItemFn<T> = (item: T | null, row: Gtk.TreeListRow | null) => ReactNode;
6
5
  export declare class TreeListItemRenderer {
@@ -8,8 +7,7 @@ export declare class TreeListItemRenderer {
8
7
  private store?;
9
8
  private fiberRoots;
10
9
  private renderFn?;
11
- private signalStore;
12
- constructor(signalStore: SignalStore);
10
+ constructor();
13
11
  getFactory(): Gtk.SignalListItemFactory;
14
12
  setRenderFn(renderFn?: TreeRenderItemFn<unknown>): void;
15
13
  setStore(store?: TreeStore): void;
@@ -2,14 +2,13 @@ import { getObjectId } from "@gtkx/ffi";
2
2
  import * as Gtk from "@gtkx/ffi/gtk";
3
3
  import { createFiberRoot } from "../../fiber-root.js";
4
4
  import { reconciler } from "../../reconciler.js";
5
+ import { signalStore } from "./signal-store.js";
5
6
  export class TreeListItemRenderer {
6
7
  factory;
7
8
  store;
8
9
  fiberRoots = new Map();
9
10
  renderFn = () => null;
10
- signalStore;
11
- constructor(signalStore) {
12
- this.signalStore = signalStore;
11
+ constructor() {
13
12
  this.factory = new Gtk.SignalListItemFactory();
14
13
  this.initialize();
15
14
  }
@@ -29,7 +28,7 @@ export class TreeListItemRenderer {
29
28
  return this.store;
30
29
  }
31
30
  initialize() {
32
- this.signalStore.set(this.factory, "setup", (_self, listItem) => {
31
+ signalStore.set(this, this.factory, "setup", (_self, listItem) => {
33
32
  const ptr = getObjectId(listItem.id);
34
33
  const expander = new Gtk.TreeExpander();
35
34
  const box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
@@ -40,7 +39,7 @@ export class TreeListItemRenderer {
40
39
  const element = this.renderFn?.(null, null);
41
40
  reconciler.getInstance().updateContainer(element, fiberRoot, null, () => { });
42
41
  });
43
- this.signalStore.set(this.factory, "bind", (_self, listItem) => {
42
+ signalStore.set(this, this.factory, "bind", (_self, listItem) => {
44
43
  const ptr = getObjectId(listItem.id);
45
44
  const fiberRoot = this.fiberRoots.get(ptr);
46
45
  if (!fiberRoot)
@@ -69,7 +68,7 @@ export class TreeListItemRenderer {
69
68
  const element = this.renderFn?.(itemData?.value ?? null, treeListRow);
70
69
  reconciler.getInstance().updateContainer(element, fiberRoot, null, () => { });
71
70
  });
72
- this.signalStore.set(this.factory, "unbind", (_self, listItem) => {
71
+ signalStore.set(this, this.factory, "unbind", (_self, listItem) => {
73
72
  const ptr = getObjectId(listItem.id);
74
73
  const fiberRoot = this.fiberRoots.get(ptr);
75
74
  if (!fiberRoot)
@@ -78,7 +77,7 @@ export class TreeListItemRenderer {
78
77
  expander.setListRow(undefined);
79
78
  reconciler.getInstance().updateContainer(null, fiberRoot, null, () => { });
80
79
  });
81
- this.signalStore.set(this.factory, "teardown", (_self, listItem) => {
80
+ signalStore.set(this, this.factory, "teardown", (_self, listItem) => {
82
81
  const ptr = getObjectId(listItem.id);
83
82
  const fiberRoot = this.fiberRoots.get(ptr);
84
83
  if (fiberRoot) {
@@ -16,7 +16,7 @@ class ListViewNode extends WidgetNode {
16
16
  constructor(typeName, props, container, rootContainer) {
17
17
  super(typeName, props, container, rootContainer);
18
18
  this.list = new List();
19
- this.itemRenderer = new ListItemRenderer(this.signalStore);
19
+ this.itemRenderer = new ListItemRenderer();
20
20
  this.itemRenderer.setStore(this.list.getStore());
21
21
  this.container.setFactory(this.itemRenderer.getFactory());
22
22
  }
@@ -1,5 +1,6 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
2
  import { ListStore } from "../internal/list-store.js";
3
+ import { signalStore } from "../internal/signal-store.js";
3
4
  import { ListItemNode } from "../list-item.js";
4
5
  import { VirtualNode } from "../virtual.js";
5
6
  export class List extends VirtualNode {
@@ -42,7 +43,7 @@ export class List extends VirtualNode {
42
43
  updateProps(oldProps, newProps) {
43
44
  super.updateProps(oldProps, newProps);
44
45
  if (!oldProps || oldProps.selectionMode !== newProps.selectionMode) {
45
- this.signalStore.set(this.selectionModel, "selection-changed", undefined);
46
+ signalStore.set(this, this.selectionModel, "selection-changed", undefined);
46
47
  this.selectionModel = this.createSelectionModel(newProps.selectionMode);
47
48
  }
48
49
  if (!oldProps ||
@@ -52,7 +53,7 @@ export class List extends VirtualNode {
52
53
  this.handleSelectionChange = () => {
53
54
  onSelectionChanged?.(this.getSelection());
54
55
  };
55
- this.signalStore.set(this.selectionModel, "selection-changed", newProps.onSelectionChanged ? this.handleSelectionChange : undefined);
56
+ signalStore.set(this, this.selectionModel, "selection-changed", newProps.onSelectionChanged ? this.handleSelectionChange : undefined);
56
57
  }
57
58
  if (!oldProps || oldProps.selected !== newProps.selected || oldProps.selectionMode !== newProps.selectionMode) {
58
59
  this.setSelection(newProps.selected);
@@ -1,6 +1,7 @@
1
1
  import { batch } from "@gtkx/ffi";
2
2
  import * as Gio from "@gtkx/ffi/gio";
3
3
  import { scheduleAfterCommit } from "../../scheduler.js";
4
+ import { signalStore } from "../internal/signal-store.js";
4
5
  import { VirtualNode } from "../virtual.js";
5
6
  export class Menu extends VirtualNode {
6
7
  actionMap;
@@ -66,10 +67,10 @@ export class Menu extends VirtualNode {
66
67
  createAction() {
67
68
  batch(() => {
68
69
  if (this.action) {
69
- this.signalStore.set(this.action, "activate", undefined);
70
+ signalStore.set(this, this.action, "activate", undefined);
70
71
  }
71
72
  this.action = new Gio.SimpleAction(this.getId());
72
- this.signalStore.set(this.action, "activate", this.getOnActivate());
73
+ signalStore.set(this, this.action, "activate", this.getOnActivate());
73
74
  this.getActionMap().addAction(this.action);
74
75
  if (this.application && this.props.accels) {
75
76
  this.application.setAccelsForAction(this.getActionName(), this.getAccels());
@@ -83,7 +84,7 @@ export class Menu extends VirtualNode {
83
84
  }
84
85
  if (this.action) {
85
86
  this.getActionMap().removeAction(this.getId());
86
- this.signalStore.set(this.action, "activate", undefined);
87
+ signalStore.set(this, this.action, "activate", undefined);
87
88
  this.action = undefined;
88
89
  }
89
90
  });
@@ -230,7 +231,7 @@ export class Menu extends VirtualNode {
230
231
  return;
231
232
  }
232
233
  if (oldProps.onActivate !== newProps.onActivate) {
233
- this.signalStore.set(this.getAction(), "activate", newProps.onActivate);
234
+ signalStore.set(this, this.getAction(), "activate", newProps.onActivate);
234
235
  }
235
236
  if (oldProps.accels !== newProps.accels) {
236
237
  if (this.application) {
@@ -1,4 +1,5 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
+ import { signalStore } from "../internal/signal-store.js";
2
3
  import { TreeStore } from "../internal/tree-store.js";
3
4
  import { TreeListItemNode } from "../tree-list-item.js";
4
5
  import { VirtualNode } from "../virtual.js";
@@ -77,7 +78,7 @@ export class TreeList extends VirtualNode {
77
78
  this.treeListModel.setAutoexpand(newProps.autoexpand ?? false);
78
79
  }
79
80
  if (!oldProps || oldProps.selectionMode !== newProps.selectionMode) {
80
- this.signalStore.set(this.selectionModel, "selection-changed", undefined);
81
+ signalStore.set(this, this.selectionModel, "selection-changed", undefined);
81
82
  this.selectionModel = this.createSelectionModel(newProps.selectionMode);
82
83
  this.selectionModel.setModel(this.treeListModel);
83
84
  }
@@ -88,7 +89,7 @@ export class TreeList extends VirtualNode {
88
89
  this.handleSelectionChange = () => {
89
90
  onSelectionChanged?.(this.getSelection());
90
91
  };
91
- this.signalStore.set(this.selectionModel, "selection-changed", newProps.onSelectionChanged ? this.handleSelectionChange : undefined);
92
+ signalStore.set(this, this.selectionModel, "selection-changed", newProps.onSelectionChanged ? this.handleSelectionChange : undefined);
92
93
  }
93
94
  if (!oldProps || oldProps.selected !== newProps.selected || oldProps.selectionMode !== newProps.selectionMode) {
94
95
  this.setSelection(newProps.selected);
@@ -30,12 +30,9 @@ export class NotebookPageTabNode extends SlotNode {
30
30
  }
31
31
  const notebook = this.getNotebook();
32
32
  const page = this.getPage();
33
- // Only call setTabLabel if the page is actually in the notebook
34
- // (pageNum returns -1 if not found)
35
33
  if (notebook.pageNum(page) === -1) {
36
34
  return;
37
35
  }
38
- // setTabLabel accepts undefined to reset to default
39
36
  notebook.setTabLabel(page, this.child);
40
37
  }
41
38
  }
@@ -54,7 +54,6 @@ export class NotebookPageNode extends SlotNode {
54
54
  this.tabNode = undefined;
55
55
  return;
56
56
  }
57
- // For content widget, use SlotNode's removeChild logic
58
57
  super.removeChild();
59
58
  }
60
59
  unmount() {
@@ -63,7 +62,6 @@ export class NotebookPageNode extends SlotNode {
63
62
  }
64
63
  updateProps(oldProps, newProps) {
65
64
  if (!oldProps || oldProps.label !== newProps.label) {
66
- // Only update if using text label (no custom tab node)
67
65
  if (this.child && this.parent && !this.tabNode?.child) {
68
66
  const tabLabel = this.getNotebook().getTabLabel(this.child);
69
67
  tabLabel.setLabel(newProps.label ?? "");
@@ -73,7 +71,6 @@ export class NotebookPageNode extends SlotNode {
73
71
  attachPage() {
74
72
  const child = this.getChild();
75
73
  const notebook = this.getNotebook();
76
- // Use custom tab widget if provided, otherwise create a Label
77
74
  let tabLabel;
78
75
  if (this.tabNode?.child) {
79
76
  tabLabel = this.tabNode.child;
@@ -1,6 +1,7 @@
1
1
  import * as Adw from "@gtkx/ffi/adw";
2
2
  import * as Gtk from "@gtkx/ffi/gtk";
3
3
  import { registerNodeClass } from "../registry.js";
4
+ import { signalStore } from "./internal/signal-store.js";
4
5
  import { SimpleListStore } from "./internal/simple-list-store.js";
5
6
  import { filterProps, isContainerType } from "./internal/utils.js";
6
7
  import { SimpleListItemNode } from "./simple-list-item.js";
@@ -28,7 +29,7 @@ class SimpleListViewNode extends WidgetNode {
28
29
  }
29
30
  }
30
31
  : undefined;
31
- this.signalStore.set(this.container, "notify::selected", handleSelectionChange);
32
+ signalStore.set(this, this.container, "notify::selected", handleSelectionChange);
32
33
  }
33
34
  if (!oldProps || oldProps.selectedId !== newProps.selectedId) {
34
35
  const index = newProps.selectedId !== undefined ? this.store.getIndexById(newProps.selectedId) : undefined;
@@ -1,5 +1,6 @@
1
1
  import * as Adw from "@gtkx/ffi/adw";
2
2
  import { registerNodeClass } from "../registry.js";
3
+ import { signalStore } from "./internal/signal-store.js";
3
4
  import { VirtualNode } from "./virtual.js";
4
5
  export class ToastNode extends VirtualNode {
5
6
  static priority = 1;
@@ -35,11 +36,11 @@ export class ToastNode extends VirtualNode {
35
36
  return;
36
37
  this.toast = this.createToast();
37
38
  if (this.props.onButtonClicked) {
38
- this.signalStore.set(this.toast, "button-clicked", () => {
39
+ signalStore.set(this, this.toast, "button-clicked", () => {
39
40
  this.props.onButtonClicked?.();
40
41
  });
41
42
  }
42
- this.signalStore.set(this.toast, "dismissed", () => {
43
+ signalStore.set(this, this.toast, "dismissed", () => {
43
44
  this.props.onDismissed?.();
44
45
  });
45
46
  this.parent.addToast(this.toast);
@@ -1,9 +1 @@
1
- import type * as Gtk from "@gtkx/ffi/gtk";
2
- import { SlotNode } from "./slot.js";
3
- export declare class ToolbarChildNode extends SlotNode {
4
- static priority: number;
5
- static matches(type: string): boolean;
6
- private getToolbar;
7
- private getPosition;
8
- protected onChildChange(oldChild: Gtk.Widget | undefined): void;
9
- }
1
+ export {};
@@ -1,6 +1,6 @@
1
1
  import { registerNodeClass } from "../registry.js";
2
2
  import { SlotNode } from "./slot.js";
3
- export class ToolbarChildNode extends SlotNode {
3
+ class ToolbarChildNode extends SlotNode {
4
4
  static priority = 1;
5
5
  static matches(type) {
6
6
  return type === "Toolbar.Top" || type === "Toolbar.Bottom";
@@ -20,7 +20,7 @@ class TreeListViewNode extends WidgetNode {
20
20
  const listView = container ?? new Gtk.ListView();
21
21
  super(typeName, props, listView, rootContainer);
22
22
  this.treeList = new TreeList(props.autoexpand, props.selectionMode);
23
- this.itemRenderer = new TreeListItemRenderer(this.signalStore);
23
+ this.itemRenderer = new TreeListItemRenderer();
24
24
  this.itemRenderer.setStore(this.treeList.getStore());
25
25
  this.container.setFactory(this.itemRenderer.getFactory());
26
26
  }
@@ -15,5 +15,6 @@ export declare class WidgetNode<T extends Gtk.Widget = Gtk.Widget, P extends Pro
15
15
  updateProps(oldProps: P | null, newProps: P): void;
16
16
  private updateEventControllerProp;
17
17
  private propNameToSignalName;
18
+ private getProperty;
18
19
  private setProperty;
19
20
  }
@@ -3,7 +3,8 @@ import * as Gtk from "@gtkx/ffi/gtk";
3
3
  import { CONSTRUCTOR_PROPS, PROPS, SIGNALS } from "../generated/internal.js";
4
4
  import { Node } from "../node.js";
5
5
  import { registerNodeClass } from "../registry.js";
6
- import { isAddable, isAppendable, isEditable, isInsertable, isRemovable, isReorderable, isSingleChild, } from "./internal/predicates.js";
6
+ import { hasSingleContent, isAddable, isAppendable, isEditable, isInsertable, isRemovable, isReorderable, isSingleChild, } from "./internal/predicates.js";
7
+ import { signalStore } from "./internal/signal-store.js";
7
8
  import { filterProps, isContainerType } from "./internal/utils.js";
8
9
  import { SlotNode } from "./slot.js";
9
10
  const EVENT_CONTROLLER_PROPS = new Set([
@@ -58,6 +59,9 @@ export class WidgetNode extends Node {
58
59
  }
59
60
  this.container.add(child.container);
60
61
  }
62
+ else if (hasSingleContent(this.container)) {
63
+ this.container.setContent(child.container);
64
+ }
61
65
  else if (isSingleChild(this.container)) {
62
66
  this.container.setChild(child.container);
63
67
  }
@@ -80,6 +84,9 @@ export class WidgetNode extends Node {
80
84
  if (isRemovable(this.container)) {
81
85
  this.container.remove(child.container);
82
86
  }
87
+ else if (hasSingleContent(this.container)) {
88
+ this.container.setContent(undefined);
89
+ }
83
90
  else if (isSingleChild(this.container)) {
84
91
  this.container.setChild(null);
85
92
  }
@@ -167,9 +174,16 @@ export class WidgetNode extends Node {
167
174
  const signalName = this.propNameToSignalName(name);
168
175
  if (signals.has(signalName)) {
169
176
  const handler = typeof newValue === "function" ? newValue : undefined;
170
- this.signalStore.set(this.container, signalName, handler);
177
+ signalStore.set(this, this.container, signalName, handler);
171
178
  }
172
179
  else if (newValue !== undefined) {
180
+ const isEditableText = name === "text" && isEditable(this.container);
181
+ if (isEditableText && oldValue !== undefined) {
182
+ const currentValue = this.getProperty(name);
183
+ if (oldValue !== currentValue) {
184
+ continue;
185
+ }
186
+ }
173
187
  this.setProperty(name, newValue);
174
188
  }
175
189
  }
@@ -184,7 +198,7 @@ export class WidgetNode extends Node {
184
198
  this.container.addController(this.motionController);
185
199
  }
186
200
  const signalName = propName === "onEnter" ? "enter" : propName === "onLeave" ? "leave" : "motion";
187
- this.signalStore.set(this.motionController, signalName, handler);
201
+ signalStore.set(this, this.motionController, signalName, handler);
188
202
  break;
189
203
  }
190
204
  case "onPressed":
@@ -194,7 +208,7 @@ export class WidgetNode extends Node {
194
208
  this.container.addController(this.clickController);
195
209
  }
196
210
  const signalName = propName === "onPressed" ? "pressed" : "released";
197
- this.signalStore.set(this.clickController, signalName, handler);
211
+ signalStore.set(this, this.clickController, signalName, handler);
198
212
  break;
199
213
  }
200
214
  case "onKeyPressed":
@@ -204,7 +218,7 @@ export class WidgetNode extends Node {
204
218
  this.container.addController(this.keyController);
205
219
  }
206
220
  const signalName = propName === "onKeyPressed" ? "key-pressed" : "key-released";
207
- this.signalStore.set(this.keyController, signalName, handler);
221
+ signalStore.set(this, this.keyController, signalName, handler);
208
222
  break;
209
223
  }
210
224
  case "onScroll": {
@@ -212,7 +226,7 @@ export class WidgetNode extends Node {
212
226
  this.scrollController = new Gtk.EventControllerScroll(Gtk.EventControllerScrollFlags.BOTH_AXES);
213
227
  this.container.addController(this.scrollController);
214
228
  }
215
- this.signalStore.set(this.scrollController, "scroll", handler);
229
+ signalStore.set(this, this.scrollController, "scroll", handler);
216
230
  break;
217
231
  }
218
232
  case "onNotify": {
@@ -221,7 +235,7 @@ export class WidgetNode extends Node {
221
235
  handler(obj, pspec.getName());
222
236
  }
223
237
  : undefined;
224
- this.signalStore.set(this.container, "notify", wrappedHandler);
238
+ signalStore.set(this, this.container, "notify", wrappedHandler);
225
239
  break;
226
240
  }
227
241
  }
@@ -233,6 +247,15 @@ export class WidgetNode extends Node {
233
247
  .toLowerCase()
234
248
  .replace(/^-/, "");
235
249
  }
250
+ getProperty(key) {
251
+ const WidgetClass = this.container.constructor;
252
+ const [getterName] = PROPS[WidgetClass.glibTypeName]?.[key] || [];
253
+ const getter = getterName ? this.container[getterName] : undefined;
254
+ if (getter && typeof getter === "function") {
255
+ return getter.call(this.container);
256
+ }
257
+ return undefined;
258
+ }
236
259
  setProperty(key, value) {
237
260
  const WidgetClass = this.container.constructor;
238
261
  const [getterName, setterName] = PROPS[WidgetClass.glibTypeName]?.[key] || [];
@@ -248,14 +271,7 @@ export class WidgetNode extends Node {
248
271
  }
249
272
  }
250
273
  if (setter && typeof setter === "function") {
251
- const editable = isEditable(this.container) ? this.container : null;
252
- const shouldPreserveCursor = key === "text" && editable !== null;
253
- const cursorPosition = shouldPreserveCursor ? editable.getPosition() : 0;
254
274
  setter.call(this.container, value);
255
- if (shouldPreserveCursor && editable !== null) {
256
- const textLength = editable.getText().length;
257
- editable.setPosition(Math.min(cursorPosition, textLength));
258
- }
259
275
  }
260
276
  }
261
277
  }
@@ -37,11 +37,6 @@ class WindowNode extends WidgetNode {
37
37
  return;
38
38
  }
39
39
  this.menu.appendChild(child);
40
- if (child instanceof WidgetNode &&
41
- (this.container instanceof Adw.ApplicationWindow || this.container instanceof Adw.Window)) {
42
- this.container.setContent(child.container);
43
- return;
44
- }
45
40
  super.appendChild(child);
46
41
  }
47
42
  removeChild(child) {
@@ -50,11 +45,6 @@ class WindowNode extends WidgetNode {
50
45
  return;
51
46
  }
52
47
  this.menu.removeChild(child);
53
- if (child instanceof WidgetNode &&
54
- (this.container instanceof Adw.ApplicationWindow || this.container instanceof Adw.Window)) {
55
- this.container.setContent(undefined);
56
- return;
57
- }
58
48
  super.removeChild(child);
59
49
  }
60
50
  insertBefore(child, before) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gtkx/react",
3
- "version": "0.10.1",
3
+ "version": "0.10.3",
4
4
  "description": "Build GTK4 desktop applications with React and TypeScript",
5
5
  "keywords": [
6
6
  "gtk",
@@ -36,8 +36,8 @@
36
36
  ],
37
37
  "dependencies": {
38
38
  "react-reconciler": "^0.33.0",
39
- "@gtkx/ffi": "0.10.1",
40
- "@gtkx/gir": "0.10.1"
39
+ "@gtkx/ffi": "0.10.3",
40
+ "@gtkx/gir": "0.10.3"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/react-reconciler": "^0.32.3",
@@ -1,21 +0,0 @@
1
- import * as Adw from "@gtkx/ffi/adw";
2
- import type { AdwNavigationPageProps } from "../jsx.js";
3
- import type { Node } from "../node.js";
4
- import { VirtualNode } from "./virtual.js";
5
- type Props = Partial<AdwNavigationPageProps>;
6
- export declare class NavigationPageNode extends VirtualNode<Props> {
7
- static priority: number;
8
- private parent?;
9
- private child?;
10
- private page?;
11
- static matches(type: string): boolean;
12
- setParent(parent?: Adw.NavigationView): void;
13
- appendChild(child: Node): void;
14
- removeChild(): void;
15
- unmount(): void;
16
- updateProps(oldProps: Props | null, newProps: Props): void;
17
- private onChildChange;
18
- private addPage;
19
- private removePage;
20
- }
21
- export {};
@@ -1,95 +0,0 @@
1
- import * as Adw from "@gtkx/ffi/adw";
2
- import { registerNodeClass } from "../registry.js";
3
- import { scheduleAfterCommit } from "../scheduler.js";
4
- import { VirtualNode } from "./virtual.js";
5
- import { WidgetNode } from "./widget.js";
6
- export class NavigationPageNode extends VirtualNode {
7
- static priority = -1;
8
- parent;
9
- child;
10
- page;
11
- static matches(type) {
12
- return type === "AdwNavigationPage";
13
- }
14
- setParent(parent) {
15
- this.parent = parent;
16
- }
17
- appendChild(child) {
18
- if (!(child instanceof WidgetNode)) {
19
- throw new Error(`Cannot append '${child.typeName}' to 'NavigationPage': expected Widget`);
20
- }
21
- const oldChild = this.child;
22
- this.child = child.container;
23
- scheduleAfterCommit(() => {
24
- if (this.parent) {
25
- this.onChildChange(oldChild);
26
- }
27
- });
28
- }
29
- removeChild() {
30
- const oldChild = this.child;
31
- scheduleAfterCommit(() => {
32
- if (oldChild === this.child) {
33
- this.child = undefined;
34
- }
35
- if (this.parent) {
36
- this.onChildChange(oldChild);
37
- }
38
- });
39
- }
40
- unmount() {
41
- if (this.parent && this.child) {
42
- const oldChild = this.child;
43
- this.child = undefined;
44
- this.onChildChange(oldChild);
45
- }
46
- this.parent = undefined;
47
- super.unmount();
48
- }
49
- updateProps(oldProps, newProps) {
50
- super.updateProps(oldProps, newProps);
51
- if (!this.page) {
52
- return;
53
- }
54
- if (newProps.title && (!oldProps || oldProps.title !== newProps.title)) {
55
- this.page.setTitle(newProps.title);
56
- }
57
- if (!oldProps || oldProps.tag !== newProps.tag) {
58
- this.page.setTag(newProps.tag);
59
- }
60
- if (!oldProps || oldProps.canPop !== newProps.canPop) {
61
- this.page.setCanPop(newProps.canPop ?? true);
62
- }
63
- }
64
- onChildChange(oldChild) {
65
- if (oldChild) {
66
- this.removePage();
67
- }
68
- if (this.child) {
69
- this.addPage();
70
- }
71
- }
72
- addPage() {
73
- if (!this.child || !this.parent) {
74
- return;
75
- }
76
- let page;
77
- if (this.props.tag) {
78
- page = Adw.NavigationPage.pageNewWithTag(this.child, this.props.title ?? "", this.props.tag);
79
- }
80
- else {
81
- page = new Adw.NavigationPage(this.child, this.props.title ?? "");
82
- }
83
- this.page = page;
84
- this.parent.add(page);
85
- this.updateProps(null, this.props);
86
- }
87
- removePage() {
88
- if (!this.page || !this.parent) {
89
- return;
90
- }
91
- this.parent.remove(this.page);
92
- this.page = undefined;
93
- }
94
- }
95
- registerNodeClass(NavigationPageNode);
@@ -1 +0,0 @@
1
- export {};
@@ -1,29 +0,0 @@
1
- import * as Adw from "@gtkx/ffi/adw";
2
- import { registerNodeClass } from "../registry.js";
3
- import { isContainerType } from "./internal/utils.js";
4
- import { NavigationPageNode } from "./navigation-page.js";
5
- import { WidgetNode } from "./widget.js";
6
- class NavigationViewNode extends WidgetNode {
7
- static priority = -1;
8
- static matches(_type, containerOrClass) {
9
- return isContainerType(Adw.NavigationView, containerOrClass);
10
- }
11
- appendChild(child) {
12
- if (child instanceof NavigationPageNode) {
13
- child.setParent(this.container);
14
- return;
15
- }
16
- super.appendChild(child);
17
- }
18
- insertBefore(child, _before) {
19
- this.appendChild(child);
20
- }
21
- removeChild(child) {
22
- if (child instanceof NavigationPageNode) {
23
- child.unmount();
24
- return;
25
- }
26
- super.removeChild(child);
27
- }
28
- }
29
- registerNodeClass(NavigationViewNode);
@@ -1 +0,0 @@
1
- export {};
@@ -1,42 +0,0 @@
1
- import * as Adw from "@gtkx/ffi/adw";
2
- import { registerNodeClass } from "../registry.js";
3
- import { isContainerType } from "./internal/utils.js";
4
- import { ToolbarChildNode } from "./toolbar-child.js";
5
- import { WidgetNode } from "./widget.js";
6
- class ToolbarNode extends WidgetNode {
7
- static priority = 0;
8
- static matches(_type, containerOrClass) {
9
- return isContainerType(Adw.ToolbarView, containerOrClass);
10
- }
11
- appendChild(child) {
12
- if (child instanceof ToolbarChildNode) {
13
- child.setParent(this.container);
14
- return;
15
- }
16
- if (!(child instanceof WidgetNode)) {
17
- throw new Error(`Cannot append '${child.typeName}' to 'ToolbarView': expected Widget`);
18
- }
19
- this.container.setContent(child.container);
20
- }
21
- insertBefore(child) {
22
- if (child instanceof ToolbarChildNode) {
23
- child.setParent(this.container);
24
- return;
25
- }
26
- if (!(child instanceof WidgetNode)) {
27
- throw new Error(`Cannot insert '${child.typeName}' to 'ToolbarView': expected Widget`);
28
- }
29
- this.container.setContent(child.container);
30
- }
31
- removeChild(child) {
32
- if (child instanceof ToolbarChildNode) {
33
- child.unmount();
34
- return;
35
- }
36
- if (!(child instanceof WidgetNode)) {
37
- throw new Error(`Cannot remove '${child.typeName}' from 'ToolbarView': expected Widget`);
38
- }
39
- this.container.setContent(undefined);
40
- }
41
- }
42
- registerNodeClass(ToolbarNode);