@gtkx/react 0.6.0 → 0.7.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 (84) hide show
  1. package/dist/batch.d.ts +4 -1
  2. package/dist/batch.js +19 -10
  3. package/dist/codegen/jsx-generator.d.ts +4 -4
  4. package/dist/codegen/jsx-generator.js +24 -27
  5. package/dist/container-interfaces.d.ts +19 -6
  6. package/dist/container-interfaces.js +26 -6
  7. package/dist/errors.d.ts +8 -0
  8. package/dist/errors.js +38 -0
  9. package/dist/factory.js +9 -3
  10. package/dist/generated/jsx.d.ts +38 -26
  11. package/dist/generated/jsx.js +12 -2
  12. package/dist/index.js +3 -1
  13. package/dist/node.d.ts +5 -0
  14. package/dist/node.js +62 -6
  15. package/dist/nodes/action-bar.d.ts +2 -6
  16. package/dist/nodes/action-bar.js +3 -12
  17. package/dist/nodes/column-view.d.ts +19 -44
  18. package/dist/nodes/column-view.js +70 -243
  19. package/dist/nodes/combo-row.d.ts +5 -0
  20. package/dist/nodes/combo-row.js +6 -0
  21. package/dist/nodes/drop-down.d.ts +9 -0
  22. package/dist/nodes/drop-down.js +12 -0
  23. package/dist/nodes/flow-box.d.ts +4 -6
  24. package/dist/nodes/flow-box.js +8 -16
  25. package/dist/nodes/grid.d.ts +15 -15
  26. package/dist/nodes/grid.js +21 -64
  27. package/dist/nodes/header-bar.d.ts +34 -11
  28. package/dist/nodes/header-bar.js +52 -24
  29. package/dist/nodes/indexed-child-container.d.ts +16 -0
  30. package/dist/nodes/indexed-child-container.js +22 -0
  31. package/dist/nodes/list-box.d.ts +3 -6
  32. package/dist/nodes/list-box.js +6 -14
  33. package/dist/nodes/list-item-factory.d.ts +19 -0
  34. package/dist/nodes/list-item-factory.js +58 -0
  35. package/dist/nodes/list-view.d.ts +24 -0
  36. package/dist/nodes/list-view.js +46 -0
  37. package/dist/nodes/menu.d.ts +25 -19
  38. package/dist/nodes/menu.js +30 -59
  39. package/dist/nodes/notebook.d.ts +13 -14
  40. package/dist/nodes/notebook.js +18 -56
  41. package/dist/nodes/paged-stack.d.ts +39 -0
  42. package/dist/nodes/paged-stack.js +54 -0
  43. package/dist/nodes/selectable-list.d.ts +41 -0
  44. package/dist/nodes/selectable-list.js +228 -0
  45. package/dist/nodes/stack-page-props.d.ts +11 -0
  46. package/dist/nodes/stack-page-props.js +23 -0
  47. package/dist/nodes/stack.d.ts +14 -28
  48. package/dist/nodes/stack.js +30 -142
  49. package/dist/nodes/string-list-container.d.ts +41 -0
  50. package/dist/nodes/string-list-container.js +90 -0
  51. package/dist/nodes/string-list-item.d.ts +15 -0
  52. package/dist/nodes/string-list-item.js +48 -0
  53. package/dist/nodes/string-list-store.d.ts +13 -0
  54. package/dist/nodes/string-list-store.js +44 -0
  55. package/dist/nodes/text-view.d.ts +1 -1
  56. package/dist/nodes/text-view.js +1 -5
  57. package/dist/nodes/toggle-button.d.ts +1 -1
  58. package/dist/nodes/toggle-button.js +1 -3
  59. package/dist/nodes/view-stack.d.ts +9 -0
  60. package/dist/nodes/view-stack.js +28 -0
  61. package/dist/nodes/virtual-item.d.ts +20 -0
  62. package/dist/nodes/virtual-item.js +57 -0
  63. package/dist/nodes/virtual-slot.d.ts +25 -0
  64. package/dist/nodes/virtual-slot.js +71 -0
  65. package/dist/nodes/widget.d.ts +0 -3
  66. package/dist/nodes/widget.js +0 -28
  67. package/dist/nodes/window.d.ts +1 -1
  68. package/dist/nodes/window.js +9 -15
  69. package/dist/predicates.d.ts +8 -0
  70. package/dist/predicates.js +8 -0
  71. package/dist/props.d.ts +7 -5
  72. package/dist/props.js +11 -9
  73. package/dist/reconciler/host-config.d.ts +19 -0
  74. package/dist/reconciler/host-config.js +89 -0
  75. package/dist/reconciler.d.ts +2 -26
  76. package/dist/reconciler.js +15 -106
  77. package/dist/render.d.ts +1 -2
  78. package/dist/render.js +16 -4
  79. package/dist/types.d.ts +19 -16
  80. package/package.json +4 -4
  81. package/dist/nodes/dropdown.d.ts +0 -39
  82. package/dist/nodes/dropdown.js +0 -103
  83. package/dist/nodes/list.d.ts +0 -43
  84. package/dist/nodes/list.js +0 -153
@@ -1,19 +1,42 @@
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";
4
+ import type { Props } from "../factory.js";
3
5
  import { Node } from "../node.js";
4
- /**
5
- * Node for AdwHeaderBar that uses packStart for non-slot children.
6
- */
7
- export declare class AdwHeaderBarNode extends Node<Adw.HeaderBar> {
8
- static matches(type: string): boolean;
6
+ import { VirtualSlotNode } from "./virtual-slot.js";
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;
9
12
  appendChild(child: Node): void;
10
13
  removeChild(child: Node): void;
11
14
  }
12
- /**
13
- * Node for Gtk.HeaderBar that uses packStart for children.
14
- */
15
- export declare class HeaderBarNode extends Node<Gtk.HeaderBar> {
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
+ type PackPosition = "start" | "end";
22
+ type PackSlotProps = {
23
+ position: PackPosition;
24
+ };
25
+ declare abstract class PackSlotNode extends VirtualSlotNode<PackContainer, PackSlotProps> {
26
+ protected abstract readonly position: PackPosition;
27
+ protected isValidContainer(parent: Node): parent is Node & PackContainer;
28
+ protected extractSlotProps(_props: Props): PackSlotProps;
29
+ protected addToContainer(container: PackContainer, child: Gtk.Widget, props: PackSlotProps): void;
30
+ protected insertBeforeInContainer(container: PackContainer, child: Gtk.Widget, props: PackSlotProps, _before: Gtk.Widget): void;
31
+ protected removeFromContainer(container: PackContainer, child: Gtk.Widget): void;
32
+ protected updateInContainer(): void;
33
+ }
34
+ export declare class PackStartNode extends PackSlotNode {
35
+ protected readonly position: PackPosition;
36
+ static matches(type: string): boolean;
37
+ }
38
+ export declare class PackEndNode extends PackSlotNode {
39
+ protected readonly position: PackPosition;
16
40
  static matches(type: string): boolean;
17
- appendChild(child: Node): void;
18
- removeChild(child: Node): void;
19
41
  }
42
+ export {};
@@ -1,10 +1,15 @@
1
+ import { isPackContainer } from "../container-interfaces.js";
1
2
  import { Node } from "../node.js";
2
- /**
3
- * Node for AdwHeaderBar that uses packStart for non-slot children.
4
- */
5
- export class AdwHeaderBarNode extends Node {
6
- static matches(type) {
7
- return type === "AdwHeaderBar" || type === "AdwHeaderBar.Root";
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);
8
13
  }
9
14
  appendChild(child) {
10
15
  const childWidget = child.getWidget();
@@ -12,34 +17,57 @@ export class AdwHeaderBarNode extends Node {
12
17
  child.attachToParent(this);
13
18
  return;
14
19
  }
15
- this.widget.packStart(childWidget);
20
+ this.packStart(childWidget);
16
21
  }
17
22
  removeChild(child) {
18
23
  const childWidget = child.getWidget();
19
24
  if (childWidget) {
20
- this.widget.remove(childWidget);
25
+ this.removeFromPack(childWidget);
21
26
  }
22
27
  }
23
28
  }
24
- /**
25
- * Node for Gtk.HeaderBar that uses packStart for children.
26
- */
27
- export class HeaderBarNode extends Node {
29
+ export class AdwHeaderBarNode extends PackContainerNode {
28
30
  static matches(type) {
29
- return type === "HeaderBar";
31
+ return type === "AdwHeaderBar" || type === "AdwHeaderBar.Root";
30
32
  }
31
- appendChild(child) {
32
- const childWidget = child.getWidget();
33
- if (!childWidget) {
34
- child.attachToParent(this);
35
- return;
36
- }
37
- this.widget.packStart(childWidget);
33
+ }
34
+ export class HeaderBarNode extends PackContainerNode {
35
+ static matches(type) {
36
+ return type === "HeaderBar" || type === "HeaderBar.Root";
38
37
  }
39
- removeChild(child) {
40
- const childWidget = child.getWidget();
41
- if (childWidget) {
42
- this.widget.remove(childWidget);
38
+ }
39
+ class PackSlotNode extends VirtualSlotNode {
40
+ isValidContainer(parent) {
41
+ return isPackContainer(parent);
42
+ }
43
+ extractSlotProps(_props) {
44
+ return { position: this.position };
45
+ }
46
+ addToContainer(container, child, props) {
47
+ if (props.position === "start") {
48
+ container.packStart(child);
49
+ }
50
+ else {
51
+ container.packEnd(child);
43
52
  }
44
53
  }
54
+ insertBeforeInContainer(container, child, props, _before) {
55
+ this.addToContainer(container, child, props);
56
+ }
57
+ removeFromContainer(container, child) {
58
+ container.removeFromPack(child);
59
+ }
60
+ updateInContainer() { }
61
+ }
62
+ export class PackStartNode extends PackSlotNode {
63
+ position = "start";
64
+ static matches(type) {
65
+ return type === "HeaderBar.Start" || type === "AdwHeaderBar.Start" || type === "ActionBar.Start";
66
+ }
67
+ }
68
+ export class PackEndNode extends PackSlotNode {
69
+ position = "end";
70
+ static matches(type) {
71
+ return type === "HeaderBar.End" || type === "AdwHeaderBar.End" || type === "ActionBar.End";
72
+ }
45
73
  }
@@ -0,0 +1,16 @@
1
+ import type * as Gtk from "@gtkx/ffi/gtk";
2
+ import type { ChildContainer } from "../container-interfaces.js";
3
+ import { Node } from "../node.js";
4
+ type IndexedWidget = Gtk.Widget & {
5
+ append(child: Gtk.Widget): void;
6
+ insert(child: Gtk.Widget, position: number): void;
7
+ remove(child: Gtk.Widget): void;
8
+ };
9
+ export declare abstract class IndexedChildContainerNode<T extends IndexedWidget> extends Node<T> implements ChildContainer {
10
+ protected abstract getInsertionIndex(before: Gtk.Widget): number;
11
+ protected getWidgetToRemove(child: Gtk.Widget): Gtk.Widget;
12
+ attachChild(child: Gtk.Widget): void;
13
+ insertChildBefore(child: Gtk.Widget, before: Gtk.Widget): void;
14
+ detachChild(child: Gtk.Widget): void;
15
+ }
16
+ export {};
@@ -0,0 +1,22 @@
1
+ import { Node } from "../node.js";
2
+ export class IndexedChildContainerNode extends Node {
3
+ getWidgetToRemove(child) {
4
+ return child;
5
+ }
6
+ attachChild(child) {
7
+ this.widget.append(child);
8
+ }
9
+ insertChildBefore(child, before) {
10
+ const index = this.getInsertionIndex(before);
11
+ if (index >= 0) {
12
+ this.widget.insert(child, index);
13
+ }
14
+ else {
15
+ this.widget.append(child);
16
+ }
17
+ }
18
+ detachChild(child) {
19
+ const toRemove = this.getWidgetToRemove(child);
20
+ this.widget.remove(toRemove);
21
+ }
22
+ }
@@ -1,9 +1,6 @@
1
1
  import type * as Gtk from "@gtkx/ffi/gtk";
2
- import type { ChildContainer } from "../container-interfaces.js";
3
- import { Node } from "../node.js";
4
- export declare class ListBoxNode extends Node<Gtk.ListBox> implements ChildContainer {
2
+ import { IndexedChildContainerNode } from "./indexed-child-container.js";
3
+ export declare class ListBoxNode extends IndexedChildContainerNode<Gtk.ListBox> {
5
4
  static matches(type: string): boolean;
6
- attachChild(child: Gtk.Widget): void;
7
- insertChildBefore(child: Gtk.Widget, before: Gtk.Widget): void;
8
- detachChild(child: Gtk.Widget): void;
5
+ protected getInsertionIndex(before: Gtk.Widget): number;
9
6
  }
@@ -1,21 +1,13 @@
1
- import { Node } from "../node.js";
2
- const isListBoxRow = (widget) => "getIndex" in widget && "isSelected" in widget && typeof widget.getIndex === "function";
3
- export class ListBoxNode extends Node {
1
+ import { isListBoxRow } from "../predicates.js";
2
+ import { IndexedChildContainerNode } from "./indexed-child-container.js";
3
+ export class ListBoxNode extends IndexedChildContainerNode {
4
4
  static matches(type) {
5
5
  return type === "ListBox";
6
6
  }
7
- attachChild(child) {
8
- this.widget.append(child);
9
- }
10
- insertChildBefore(child, before) {
7
+ getInsertionIndex(before) {
11
8
  if (isListBoxRow(before)) {
12
- this.widget.insert(child, before.getIndex());
13
- }
14
- else {
15
- this.widget.append(child);
9
+ return before.getIndex();
16
10
  }
17
- }
18
- detachChild(child) {
19
- this.widget.remove(child);
11
+ return -1;
20
12
  }
21
13
  }
@@ -0,0 +1,19 @@
1
+ import * as Gtk from "@gtkx/ffi/gtk";
2
+ import type Reconciler from "react-reconciler";
3
+ import type { RenderItemFn } from "../types.js";
4
+ export type ListItemInfo = {
5
+ box: Gtk.Box;
6
+ fiberRoot: Reconciler.FiberRoot;
7
+ };
8
+ type ListItemFactoryConfig = {
9
+ factory: Gtk.SignalListItemFactory;
10
+ listItemCache: Map<number, ListItemInfo>;
11
+ getRenderFn: () => RenderItemFn<unknown>;
12
+ getItemAtPosition: (position: number) => unknown;
13
+ };
14
+ export type ListItemFactoryHandlers = {
15
+ handlerIds: number[];
16
+ disconnect: () => void;
17
+ };
18
+ export declare function connectListItemFactorySignals(config: ListItemFactoryConfig): ListItemFactoryHandlers;
19
+ export {};
@@ -0,0 +1,58 @@
1
+ import { getObject, getObjectId } from "@gtkx/ffi";
2
+ import * as GObject from "@gtkx/ffi/gobject";
3
+ import * as Gtk from "@gtkx/ffi/gtk";
4
+ import { createFiberRoot } from "../fiber-root.js";
5
+ import { reconciler } from "../reconciler.js";
6
+ export function connectListItemFactorySignals(config) {
7
+ const { factory, listItemCache, getRenderFn, getItemAtPosition } = config;
8
+ const handlerIds = [];
9
+ const setupId = factory.connect("setup", (_self, listItemObj) => {
10
+ const listItem = getObject(listItemObj.id);
11
+ const id = getObjectId(listItemObj.id);
12
+ const box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
13
+ listItem.setChild(box);
14
+ const fiberRoot = createFiberRoot(box);
15
+ listItemCache.set(id, { box, fiberRoot });
16
+ const element = getRenderFn()(null);
17
+ reconciler.getInstance().updateContainer(element, fiberRoot, null, () => { });
18
+ });
19
+ handlerIds.push(setupId);
20
+ const bindId = factory.connect("bind", (_self, listItemObj) => {
21
+ const listItem = getObject(listItemObj.id);
22
+ const id = getObjectId(listItemObj.id);
23
+ const info = listItemCache.get(id);
24
+ if (!info)
25
+ return;
26
+ const position = listItem.getPosition();
27
+ const item = getItemAtPosition(position);
28
+ const element = getRenderFn()(item ?? null);
29
+ reconciler.getInstance().updateContainer(element, info.fiberRoot, null, () => { });
30
+ });
31
+ handlerIds.push(bindId);
32
+ const unbindId = factory.connect("unbind", (_self, listItemObj) => {
33
+ const id = getObjectId(listItemObj.id);
34
+ const info = listItemCache.get(id);
35
+ if (!info)
36
+ return;
37
+ reconciler.getInstance().updateContainer(null, info.fiberRoot, null, () => { });
38
+ });
39
+ handlerIds.push(unbindId);
40
+ const teardownId = factory.connect("teardown", (_self, listItemObj) => {
41
+ const id = getObjectId(listItemObj.id);
42
+ const info = listItemCache.get(id);
43
+ if (info) {
44
+ reconciler.getInstance().updateContainer(null, info.fiberRoot, null, () => { });
45
+ queueMicrotask(() => listItemCache.delete(id));
46
+ }
47
+ });
48
+ handlerIds.push(teardownId);
49
+ return {
50
+ handlerIds,
51
+ disconnect: () => {
52
+ for (const handlerId of handlerIds) {
53
+ GObject.signalHandlerDisconnect(factory, handlerId);
54
+ }
55
+ handlerIds.length = 0;
56
+ },
57
+ };
58
+ }
@@ -0,0 +1,24 @@
1
+ import * as Gtk from "@gtkx/ffi/gtk";
2
+ import type { Props } from "../factory.js";
3
+ import type { Node } from "../node.js";
4
+ import type { RenderItemFn } from "../types.js";
5
+ import { type ListItemFactoryHandlers, type ListItemInfo } from "./list-item-factory.js";
6
+ import { SelectableListNode, type SelectableListState } from "./selectable-list.js";
7
+ import { VirtualItemNode } from "./virtual-item.js";
8
+ type ListViewState = SelectableListState & {
9
+ factory: Gtk.SignalListItemFactory;
10
+ factoryHandlers: ListItemFactoryHandlers | null;
11
+ renderItem: RenderItemFn<unknown>;
12
+ listItemCache: Map<number, ListItemInfo>;
13
+ };
14
+ export declare class ListViewNode extends SelectableListNode<Gtk.ListView | Gtk.GridView, ListViewState> {
15
+ static consumedPropNames: string[];
16
+ static matches(type: string): boolean;
17
+ initialize(props: Props): void;
18
+ detachFromParent(parent: Node): void;
19
+ updateProps(oldProps: Props, newProps: Props): void;
20
+ }
21
+ export declare class ListItemNode extends VirtualItemNode {
22
+ static matches(type: string): boolean;
23
+ }
24
+ export {};
@@ -0,0 +1,46 @@
1
+ import * as Gtk from "@gtkx/ffi/gtk";
2
+ import { connectListItemFactorySignals } from "./list-item-factory.js";
3
+ import { SelectableListNode } from "./selectable-list.js";
4
+ import { VirtualItemNode } from "./virtual-item.js";
5
+ export class ListViewNode extends SelectableListNode {
6
+ static consumedPropNames = ["renderItem", "selected", "onSelectionChanged", "selectionMode"];
7
+ static matches(type) {
8
+ return type === "ListView.Root" || type === "GridView.Root";
9
+ }
10
+ initialize(props) {
11
+ const selectionState = this.initializeSelectionState(props);
12
+ this.state = {
13
+ ...selectionState,
14
+ factory: new Gtk.SignalListItemFactory(),
15
+ factoryHandlers: null,
16
+ renderItem: props.renderItem,
17
+ listItemCache: new Map(),
18
+ };
19
+ super.initialize(props);
20
+ this.state.factoryHandlers = connectListItemFactorySignals({
21
+ factory: this.state.factory,
22
+ listItemCache: this.state.listItemCache,
23
+ getRenderFn: () => this.state.renderItem,
24
+ getItemAtPosition: (position) => this.getItems()[position] ?? null,
25
+ });
26
+ this.applySelectionModel();
27
+ this.widget.setFactory(this.state.factory);
28
+ }
29
+ detachFromParent(parent) {
30
+ this.state.factoryHandlers?.disconnect();
31
+ this.cleanupSelection();
32
+ super.detachFromParent(parent);
33
+ }
34
+ updateProps(oldProps, newProps) {
35
+ if (oldProps.renderItem !== newProps.renderItem) {
36
+ this.state.renderItem = newProps.renderItem;
37
+ }
38
+ this.updateSelectionProps(oldProps, newProps);
39
+ super.updateProps(oldProps, newProps);
40
+ }
41
+ }
42
+ export class ListItemNode extends VirtualItemNode {
43
+ static matches(type) {
44
+ return type === "ListView.Item" || type === "GridView.Item";
45
+ }
46
+ }
@@ -2,12 +2,12 @@ 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
4
  import { Node } from "../node.js";
5
- interface MenuEntry {
5
+ type MenuEntry = {
6
6
  type: "item" | "section" | "submenu";
7
7
  label?: string;
8
8
  action?: string;
9
9
  menu?: Gio.Menu;
10
- }
10
+ };
11
11
  interface MenuContainer {
12
12
  getMenu(): Gio.Menu;
13
13
  addMenuEntry(entry: MenuEntry): void;
@@ -24,15 +24,21 @@ declare abstract class MenuContainerNode<T extends Gtk.Widget | undefined> exten
24
24
  protected rebuildMenu(): void;
25
25
  protected onMenuRebuilt(): void;
26
26
  }
27
- export declare class PopoverMenuRootNode extends MenuContainerNode<Gtk.PopoverMenu> {
28
- static matches(type: string): boolean;
27
+ type MenuWidget = Gtk.Widget & {
28
+ setMenuModel(model: Gio.MenuModel | null): void;
29
+ };
30
+ declare abstract class MenuWidgetNode<T extends MenuWidget> extends MenuContainerNode<T> {
31
+ protected abstract createMenuWidget(menu: Gio.Menu): T;
29
32
  initialize(props: Props): void;
30
33
  protected onMenuRebuilt(): void;
31
34
  }
32
- export declare class PopoverMenuBarNode extends MenuContainerNode<Gtk.PopoverMenuBar> {
35
+ export declare class PopoverMenuRootNode extends MenuWidgetNode<Gtk.PopoverMenu> {
33
36
  static matches(type: string): boolean;
34
- initialize(props: Props): void;
35
- protected onMenuRebuilt(): void;
37
+ protected createMenuWidget(menu: Gio.Menu): Gtk.PopoverMenu;
38
+ }
39
+ export declare class PopoverMenuBarNode extends MenuWidgetNode<Gtk.PopoverMenuBar> {
40
+ static matches(type: string): boolean;
41
+ protected createMenuWidget(menu: Gio.Menu): Gtk.PopoverMenuBar;
36
42
  }
37
43
  export declare class ApplicationMenuNode extends MenuContainerNode<never> {
38
44
  static matches(type: string): boolean;
@@ -43,6 +49,7 @@ export declare class ApplicationMenuNode extends MenuContainerNode<never> {
43
49
  protected onMenuRebuilt(): void;
44
50
  }
45
51
  export declare class MenuItemNode extends Node<never> {
52
+ static consumedPropNames: string[];
46
53
  static matches(type: string): boolean;
47
54
  protected isVirtual(): boolean;
48
55
  private entry;
@@ -55,7 +62,6 @@ export declare class MenuItemNode extends Node<never> {
55
62
  initialize(props: Props): void;
56
63
  attachToParent(parent: Node): void;
57
64
  detachFromParent(parent: Node): void;
58
- protected consumedProps(): Set<string>;
59
65
  private isFieldInitializationIncomplete;
60
66
  updateProps(oldProps: Props, newProps: Props): void;
61
67
  private invokeCurrentCallback;
@@ -63,24 +69,24 @@ export declare class MenuItemNode extends Node<never> {
63
69
  private cleanupAction;
64
70
  private updateAccels;
65
71
  }
66
- export declare class MenuSectionNode extends MenuContainerNode<never> {
67
- static matches(type: string): boolean;
72
+ declare class MenuContainerItemNode extends MenuContainerNode<never> {
73
+ static consumedPropNames: string[];
74
+ protected entryType: "section" | "submenu";
75
+ protected matchType: string;
76
+ static matches(_type: string): boolean;
68
77
  protected isVirtual(): boolean;
69
78
  private entry;
70
79
  initialize(props: Props): void;
71
80
  attachToParent(parent: Node): void;
72
81
  detachFromParent(parent: Node): void;
73
- protected consumedProps(): Set<string>;
74
82
  updateProps(oldProps: Props, newProps: Props): void;
75
83
  }
76
- export declare class MenuSubmenuNode extends MenuContainerNode<never> {
84
+ export declare class MenuSectionNode extends MenuContainerItemNode {
85
+ protected entryType: "section" | "submenu";
86
+ static matches(type: string): boolean;
87
+ }
88
+ export declare class MenuSubmenuNode extends MenuContainerItemNode {
89
+ protected entryType: "section" | "submenu";
77
90
  static matches(type: string): boolean;
78
- protected isVirtual(): boolean;
79
- private entry;
80
- initialize(props: Props): void;
81
- attachToParent(parent: Node): void;
82
- detachFromParent(parent: Node): void;
83
- protected consumedProps(): Set<string>;
84
- updateProps(oldProps: Props, newProps: Props): void;
85
91
  }
86
92
  export {};
@@ -51,28 +51,29 @@ class MenuContainerNode extends Node {
51
51
  }
52
52
  onMenuRebuilt() { }
53
53
  }
54
- export class PopoverMenuRootNode extends MenuContainerNode {
55
- static matches(type) {
56
- return type === "PopoverMenu.Root";
57
- }
54
+ class MenuWidgetNode extends MenuContainerNode {
58
55
  initialize(props) {
59
- this.widget = new Gtk.PopoverMenu(this.menu);
56
+ this.widget = this.createMenuWidget(this.menu);
60
57
  super.initialize(props);
61
58
  }
62
59
  onMenuRebuilt() {
63
60
  this.widget.setMenuModel(this.menu);
64
61
  }
65
62
  }
66
- export class PopoverMenuBarNode extends MenuContainerNode {
63
+ export class PopoverMenuRootNode extends MenuWidgetNode {
67
64
  static matches(type) {
68
- return type === "PopoverMenuBar";
65
+ return type === "PopoverMenu.Root";
69
66
  }
70
- initialize(props) {
71
- this.widget = new Gtk.PopoverMenuBar(this.menu);
72
- super.initialize(props);
67
+ createMenuWidget(menu) {
68
+ return new Gtk.PopoverMenu(menu);
73
69
  }
74
- onMenuRebuilt() {
75
- this.widget.setMenuModel(this.menu);
70
+ }
71
+ export class PopoverMenuBarNode extends MenuWidgetNode {
72
+ static matches(type) {
73
+ return type === "PopoverMenuBar";
74
+ }
75
+ createMenuWidget(menu) {
76
+ return new Gtk.PopoverMenuBar(menu);
76
77
  }
77
78
  }
78
79
  export class ApplicationMenuNode extends MenuContainerNode {
@@ -98,6 +99,7 @@ export class ApplicationMenuNode extends MenuContainerNode {
98
99
  }
99
100
  }
100
101
  export class MenuItemNode extends Node {
102
+ static consumedPropNames = ["label", "onActivate", "accels"];
101
103
  static matches(type) {
102
104
  return type === "Menu.Item";
103
105
  }
@@ -131,13 +133,6 @@ export class MenuItemNode extends Node {
131
133
  this.cleanupAction();
132
134
  this.isAttached = false;
133
135
  }
134
- consumedProps() {
135
- const consumed = super.consumedProps();
136
- consumed.add("label");
137
- consumed.add("onActivate");
138
- consumed.add("accels");
139
- return consumed;
140
- }
141
136
  isFieldInitializationIncomplete() {
142
137
  return !this.entry;
143
138
  }
@@ -173,7 +168,7 @@ export class MenuItemNode extends Node {
173
168
  this.action = new Gio.SimpleAction(this.actionName);
174
169
  this.signalHandlerId = this.action.connect("activate", () => this.invokeCurrentCallback());
175
170
  const app = getCurrentApp();
176
- const action = getInterface(this.action, Gio.Action);
171
+ const action = getInterface(this.action.id, Gio.Action);
177
172
  if (!action) {
178
173
  throw new Error("Failed to get Gio.Action interface from SimpleAction");
179
174
  }
@@ -207,15 +202,19 @@ export class MenuItemNode extends Node {
207
202
  app.setAccelsForAction(`app.${this.actionName}`, accelArray);
208
203
  }
209
204
  }
210
- export class MenuSectionNode extends MenuContainerNode {
211
- static matches(type) {
212
- return type === "Menu.Section";
205
+ class MenuContainerItemNode extends MenuContainerNode {
206
+ static consumedPropNames = ["label"];
207
+ entryType = "section";
208
+ matchType = "";
209
+ static matches(_type) {
210
+ return false;
213
211
  }
214
212
  isVirtual() {
215
213
  return true;
216
214
  }
217
215
  entry = { type: "section" };
218
216
  initialize(props) {
217
+ this.entry = { type: this.entryType };
219
218
  this.entry.menu = this.menu;
220
219
  this.entry.label = props.label;
221
220
  super.initialize(props);
@@ -230,11 +229,6 @@ export class MenuSectionNode extends MenuContainerNode {
230
229
  return;
231
230
  parent.removeMenuEntry(this.entry);
232
231
  }
233
- consumedProps() {
234
- const consumed = super.consumedProps();
235
- consumed.add("label");
236
- return consumed;
237
- }
238
232
  updateProps(oldProps, newProps) {
239
233
  if (oldProps.label !== newProps.label && this.entry) {
240
234
  this.entry.label = newProps.label;
@@ -242,38 +236,15 @@ export class MenuSectionNode extends MenuContainerNode {
242
236
  super.updateProps(oldProps, newProps);
243
237
  }
244
238
  }
245
- export class MenuSubmenuNode extends MenuContainerNode {
239
+ export class MenuSectionNode extends MenuContainerItemNode {
240
+ entryType = "section";
246
241
  static matches(type) {
247
- return type === "Menu.Submenu";
248
- }
249
- isVirtual() {
250
- return true;
251
- }
252
- entry = { type: "submenu" };
253
- initialize(props) {
254
- this.entry.menu = this.menu;
255
- this.entry.label = props.label;
256
- super.initialize(props);
257
- }
258
- attachToParent(parent) {
259
- if (!isMenuContainer(parent))
260
- return;
261
- parent.addMenuEntry(this.entry);
262
- }
263
- detachFromParent(parent) {
264
- if (!isMenuContainer(parent))
265
- return;
266
- parent.removeMenuEntry(this.entry);
267
- }
268
- consumedProps() {
269
- const consumed = super.consumedProps();
270
- consumed.add("label");
271
- return consumed;
242
+ return type === "Menu.Section";
272
243
  }
273
- updateProps(oldProps, newProps) {
274
- if (oldProps.label !== newProps.label && this.entry) {
275
- this.entry.label = newProps.label;
276
- }
277
- super.updateProps(oldProps, newProps);
244
+ }
245
+ export class MenuSubmenuNode extends MenuContainerItemNode {
246
+ entryType = "submenu";
247
+ static matches(type) {
248
+ return type === "Menu.Submenu";
278
249
  }
279
250
  }