@gtkx/react 0.12.1 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.md +1 -1
  2. package/dist/generated/internal.js +2 -0
  3. package/dist/generated/jsx.d.ts +32 -18
  4. package/dist/host-config.js +3 -3
  5. package/dist/jsx.d.ts +524 -366
  6. package/dist/jsx.js +401 -353
  7. package/dist/nodes/action-row-child.d.ts +4 -11
  8. package/dist/nodes/action-row-child.js +10 -66
  9. package/dist/nodes/action-row.js +21 -4
  10. package/dist/nodes/application.js +22 -3
  11. package/dist/nodes/autowrapped.js +13 -3
  12. package/dist/nodes/calendar-mark.d.ts +15 -0
  13. package/dist/nodes/calendar-mark.js +29 -0
  14. package/dist/nodes/calendar.d.ts +1 -0
  15. package/dist/nodes/calendar.js +70 -0
  16. package/dist/nodes/column-view-column.d.ts +1 -0
  17. package/dist/nodes/column-view-column.js +4 -0
  18. package/dist/nodes/column-view.js +24 -7
  19. package/dist/nodes/expander-row-child.d.ts +15 -0
  20. package/dist/nodes/expander-row-child.js +20 -0
  21. package/dist/nodes/expander-row.d.ts +1 -0
  22. package/dist/nodes/expander-row.js +54 -0
  23. package/dist/nodes/fixed-child.js +10 -8
  24. package/dist/nodes/grid-child.js +10 -8
  25. package/dist/nodes/index.d.ts +12 -0
  26. package/dist/nodes/index.js +12 -0
  27. package/dist/nodes/internal/list-item-renderer.d.ts +3 -0
  28. package/dist/nodes/internal/list-item-renderer.js +25 -9
  29. package/dist/nodes/internal/list-store.js +2 -2
  30. package/dist/nodes/internal/tree-list-item-renderer.d.ts +8 -0
  31. package/dist/nodes/internal/tree-list-item-renderer.js +68 -24
  32. package/dist/nodes/internal/tree-store.js +3 -4
  33. package/dist/nodes/level-bar-offset.d.ts +13 -0
  34. package/dist/nodes/level-bar-offset.js +35 -0
  35. package/dist/nodes/level-bar.d.ts +1 -0
  36. package/dist/nodes/level-bar.js +82 -0
  37. package/dist/nodes/list-view.js +14 -7
  38. package/dist/nodes/menu.js +4 -4
  39. package/dist/nodes/models/list.d.ts +2 -1
  40. package/dist/nodes/models/list.js +21 -12
  41. package/dist/nodes/models/menu.d.ts +1 -0
  42. package/dist/nodes/models/menu.js +24 -17
  43. package/dist/nodes/models/tree-list.d.ts +2 -1
  44. package/dist/nodes/models/tree-list.js +43 -24
  45. package/dist/nodes/navigation-page.d.ts +16 -0
  46. package/dist/nodes/navigation-page.js +58 -0
  47. package/dist/nodes/navigation-view.d.ts +1 -0
  48. package/dist/nodes/navigation-view.js +105 -0
  49. package/dist/nodes/notebook-page-tab.js +1 -1
  50. package/dist/nodes/notebook-page.js +3 -2
  51. package/dist/nodes/notebook.js +3 -3
  52. package/dist/nodes/overlay-child.js +29 -14
  53. package/dist/nodes/pack-child.d.ts +4 -11
  54. package/dist/nodes/pack-child.js +10 -66
  55. package/dist/nodes/pack.js +21 -4
  56. package/dist/nodes/popover-menu.js +15 -12
  57. package/dist/nodes/scale-mark.d.ts +17 -0
  58. package/dist/nodes/scale-mark.js +38 -0
  59. package/dist/nodes/scale.d.ts +1 -0
  60. package/dist/nodes/scale.js +70 -0
  61. package/dist/nodes/simple-list-view.js +3 -3
  62. package/dist/nodes/slot.js +2 -2
  63. package/dist/nodes/stack-page.js +7 -7
  64. package/dist/nodes/stack.js +5 -5
  65. package/dist/nodes/toggle-group.d.ts +1 -0
  66. package/dist/nodes/toggle-group.js +48 -0
  67. package/dist/nodes/toggle.d.ts +15 -0
  68. package/dist/nodes/toggle.js +70 -0
  69. package/dist/nodes/toolbar-child.js +18 -16
  70. package/dist/nodes/tree-list-view.js +16 -7
  71. package/dist/nodes/virtual-child.d.ts +18 -0
  72. package/dist/nodes/virtual-child.js +62 -0
  73. package/dist/nodes/widget.js +22 -8
  74. package/dist/nodes/window.d.ts +22 -0
  75. package/dist/nodes/window.js +11 -2
  76. package/dist/render.d.ts +3 -5
  77. package/dist/render.js +3 -5
  78. package/dist/scheduler.d.ts +13 -1
  79. package/dist/scheduler.js +26 -6
  80. package/dist/types.d.ts +25 -0
  81. package/package.json +3 -3
@@ -1,21 +1,14 @@
1
1
  import type * as Gtk from "@gtkx/ffi/gtk";
2
- import type { Node } from "../node.js";
3
- import { VirtualNode } from "./virtual.js";
2
+ import { VirtualChildNode } from "./virtual-child.js";
4
3
  type PrefixSuffixWidget = Gtk.Widget & {
5
4
  addPrefix(child: Gtk.Widget): void;
6
5
  addSuffix(child: Gtk.Widget): void;
7
6
  remove(child: Gtk.Widget): void;
8
7
  };
9
- export declare class ActionRowChild extends VirtualNode {
8
+ export declare class ActionRowChild extends VirtualChildNode<PrefixSuffixWidget> {
10
9
  static priority: number;
11
10
  static matches(type: string): boolean;
12
- private parent?;
13
- private children;
14
- private getPosition;
15
- setParent(newParent?: PrefixSuffixWidget): void;
16
- appendChild(child: Node): void;
17
- insertBefore(child: Node): void;
18
- removeChild(child: Node): void;
19
- unmount(): void;
11
+ protected getPositionLabel(): string;
12
+ protected attachChild(parent: PrefixSuffixWidget, widget: Gtk.Widget): void;
20
13
  }
21
14
  export {};
@@ -1,76 +1,20 @@
1
- import { isObjectEqual } from "@gtkx/ffi";
2
1
  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 ActionRowChild extends VirtualNode {
2
+ import { VirtualChildNode } from "./virtual-child.js";
3
+ export class ActionRowChild extends VirtualChildNode {
7
4
  static priority = 1;
8
5
  static matches(type) {
9
- return type === "ActionRow.Prefix" || type === "ActionRow.Suffix";
6
+ return type === "ActionRowPrefix" || type === "ActionRowSuffix";
10
7
  }
11
- parent;
12
- children = [];
13
- getPosition() {
14
- return this.typeName === "ActionRow.Prefix" ? "prefix" : "suffix";
8
+ getPositionLabel() {
9
+ return this.typeName === "ActionRowPrefix" ? "prefix" : "suffix";
15
10
  }
16
- setParent(newParent) {
17
- this.parent = newParent;
18
- }
19
- appendChild(child) {
20
- if (!(child instanceof WidgetNode)) {
21
- throw new Error(`Cannot append '${child.typeName}' to '${this.typeName}': expected Widget`);
22
- }
23
- const widget = child.container;
24
- this.children.push(widget);
25
- scheduleAfterCommit(() => {
26
- if (this.parent) {
27
- if (this.getPosition() === "prefix") {
28
- this.parent.addPrefix(widget);
29
- }
30
- else {
31
- this.parent.addSuffix(widget);
32
- }
33
- }
34
- });
35
- }
36
- insertBefore(child) {
37
- this.appendChild(child);
38
- }
39
- removeChild(child) {
40
- if (!(child instanceof WidgetNode)) {
41
- throw new Error(`Cannot remove '${child.typeName}' from '${this.typeName}': expected Widget`);
42
- }
43
- const widget = child.container;
44
- const parent = this.parent;
45
- const index = this.children.indexOf(widget);
46
- if (index !== -1) {
47
- this.children.splice(index, 1);
11
+ attachChild(parent, widget) {
12
+ if (this.getPositionLabel() === "prefix") {
13
+ parent.addPrefix(widget);
48
14
  }
49
- scheduleAfterCommit(() => {
50
- if (parent) {
51
- const currentParent = widget.getParent();
52
- if (currentParent && isObjectEqual(currentParent, parent)) {
53
- parent.remove(widget);
54
- }
55
- }
56
- });
57
- }
58
- unmount() {
59
- const parent = this.parent;
60
- const childrenToRemove = [...this.children];
61
- if (parent && childrenToRemove.length > 0) {
62
- scheduleAfterCommit(() => {
63
- for (const widget of childrenToRemove) {
64
- const currentParent = widget.getParent();
65
- if (currentParent && isObjectEqual(currentParent, parent)) {
66
- parent.remove(widget);
67
- }
68
- }
69
- });
15
+ else {
16
+ parent.addSuffix(widget);
70
17
  }
71
- this.children = [];
72
- this.parent = undefined;
73
- super.unmount();
74
18
  }
75
19
  }
76
20
  registerNodeClass(ActionRowChild);
@@ -2,6 +2,7 @@ import { PREFIX_SUFFIX_INTERFACE_METHODS } from "../generated/internal.js";
2
2
  import { registerNodeClass } from "../registry.js";
3
3
  import { ActionRowChild } from "./action-row-child.js";
4
4
  import { matchesInterface } from "./internal/utils.js";
5
+ import { SlotNode } from "./slot.js";
5
6
  import { WidgetNode } from "./widget.js";
6
7
  class ActionRowNode extends WidgetNode {
7
8
  static priority = 0;
@@ -13,17 +14,33 @@ class ActionRowNode extends WidgetNode {
13
14
  child.setParent(this.container);
14
15
  return;
15
16
  }
16
- super.appendChild(child);
17
+ if (child instanceof SlotNode || child instanceof WidgetNode) {
18
+ super.appendChild(child);
19
+ return;
20
+ }
21
+ throw new Error(`Cannot append '${child.typeName}' to 'ActionRow': expected x.ActionRowPrefix, x.ActionRowSuffix, or Widget`);
17
22
  }
18
- insertBefore(child) {
19
- this.appendChild(child);
23
+ insertBefore(child, before) {
24
+ if (child instanceof ActionRowChild) {
25
+ child.setParent(this.container);
26
+ return;
27
+ }
28
+ if (child instanceof SlotNode || child instanceof WidgetNode) {
29
+ super.insertBefore(child, before);
30
+ return;
31
+ }
32
+ throw new Error(`Cannot insert '${child.typeName}' into 'ActionRow': expected x.ActionRowPrefix, x.ActionRowSuffix, or Widget`);
20
33
  }
21
34
  removeChild(child) {
22
35
  if (child instanceof ActionRowChild) {
23
36
  child.unmount();
24
37
  return;
25
38
  }
26
- super.removeChild(child);
39
+ if (child instanceof SlotNode || child instanceof WidgetNode) {
40
+ super.removeChild(child);
41
+ return;
42
+ }
43
+ throw new Error(`Cannot remove '${child.typeName}' from 'ActionRow': expected x.ActionRowPrefix, x.ActionRowSuffix, or Widget`);
27
44
  }
28
45
  }
29
46
  registerNodeClass(ActionRowNode);
@@ -1,9 +1,11 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
2
  import { Node } from "../node.js";
3
3
  import { registerNodeClass } from "../registry.js";
4
+ import { CommitPriority, scheduleAfterCommit } from "../scheduler.js";
4
5
  import { isContainerType } from "./internal/utils.js";
5
6
  import { MenuNode } from "./menu.js";
6
7
  import { Menu } from "./models/menu.js";
8
+ import { WindowNode } from "./window.js";
7
9
  class ApplicationNode extends Node {
8
10
  static priority = 0;
9
11
  menu;
@@ -19,20 +21,37 @@ class ApplicationNode extends Node {
19
21
  if (child instanceof MenuNode) {
20
22
  this.menu.appendChild(child);
21
23
  this.container.setMenubar(this.menu.getMenu());
24
+ return;
22
25
  }
26
+ if (child instanceof WindowNode) {
27
+ return;
28
+ }
29
+ throw new Error(`Cannot append '${child.typeName}' to 'Application': expected Window or MenuItem`);
23
30
  }
24
31
  insertBefore(child, before) {
25
32
  if (child instanceof MenuNode) {
26
33
  this.menu.insertBefore(child, before);
34
+ return;
35
+ }
36
+ if (child instanceof WindowNode) {
37
+ return;
27
38
  }
39
+ throw new Error(`Cannot insert '${child.typeName}' into 'Application': expected Window or MenuItem`);
28
40
  }
29
41
  removeChild(child) {
30
42
  if (child instanceof MenuNode) {
31
43
  this.menu.removeChild(child);
32
- if (this.menu.getMenu().getNItems() === 0) {
33
- this.container.setMenubar(null);
34
- }
44
+ scheduleAfterCommit(() => {
45
+ if (this.menu.getMenu().getNItems() === 0) {
46
+ this.container.setMenubar(null);
47
+ }
48
+ }, CommitPriority.LOW);
49
+ return;
50
+ }
51
+ if (child instanceof WindowNode) {
52
+ return;
35
53
  }
54
+ throw new Error(`Cannot remove '${child.typeName}' from 'Application': expected Window or MenuItem`);
36
55
  }
37
56
  }
38
57
  registerNodeClass(ApplicationNode);
@@ -4,6 +4,7 @@ import { AUTOWRAP_CLASSES } from "../generated/internal.js";
4
4
  import { registerNodeClass } from "../registry.js";
5
5
  import { isRemovable, isSingleChild } from "./internal/predicates.js";
6
6
  import { matchesAnyClass } from "./internal/utils.js";
7
+ import { SlotNode } from "./slot.js";
7
8
  import { WidgetNode } from "./widget.js";
8
9
  const isAutowrappedChild = (obj) => {
9
10
  return obj instanceof Gtk.ListBoxRow || obj instanceof Gtk.FlowBoxChild;
@@ -14,10 +15,13 @@ class AutowrappedNode extends WidgetNode {
14
15
  return matchesAnyClass(AUTOWRAP_CLASSES, containerOrClass);
15
16
  }
16
17
  appendChild(child) {
17
- if (!(child instanceof WidgetNode)) {
18
+ if (child instanceof SlotNode) {
18
19
  super.appendChild(child);
19
20
  return;
20
21
  }
22
+ if (!(child instanceof WidgetNode)) {
23
+ throw new Error(`Cannot append '${child.typeName}' to 'ListBox/FlowBox': expected Widget`);
24
+ }
21
25
  batch(() => {
22
26
  if (isAutowrappedChild(child.container)) {
23
27
  const currentParent = child.container.getParent();
@@ -32,10 +36,13 @@ class AutowrappedNode extends WidgetNode {
32
36
  });
33
37
  }
34
38
  removeChild(child) {
35
- if (!(child instanceof WidgetNode)) {
39
+ if (child instanceof SlotNode) {
36
40
  super.removeChild(child);
37
41
  return;
38
42
  }
43
+ if (!(child instanceof WidgetNode)) {
44
+ throw new Error(`Cannot remove '${child.typeName}' from 'ListBox/FlowBox': expected Widget`);
45
+ }
39
46
  batch(() => {
40
47
  if (!isAutowrappedChild(child.container)) {
41
48
  const wrapper = child.container.getParent();
@@ -49,10 +56,13 @@ class AutowrappedNode extends WidgetNode {
49
56
  });
50
57
  }
51
58
  insertBefore(child, before) {
52
- if (!(child instanceof WidgetNode) || !(before instanceof WidgetNode)) {
59
+ if (child instanceof SlotNode) {
53
60
  super.insertBefore(child, before);
54
61
  return;
55
62
  }
63
+ if (!(child instanceof WidgetNode) || !(before instanceof WidgetNode)) {
64
+ throw new Error(`Cannot insert '${child.typeName}' before '${before.typeName}' in 'ListBox/FlowBox': expected Widget`);
65
+ }
56
66
  batch(() => {
57
67
  const currentParent = child.container.getParent();
58
68
  if (currentParent !== null) {
@@ -0,0 +1,15 @@
1
+ import type * as Gtk from "@gtkx/ffi/gtk";
2
+ import { VirtualNode } from "./virtual.js";
3
+ export type CalendarMarkProps = {
4
+ day: number;
5
+ };
6
+ export declare class CalendarMarkNode extends VirtualNode<CalendarMarkProps> {
7
+ static priority: number;
8
+ private calendar?;
9
+ private onRebuild?;
10
+ static matches(type: string): boolean;
11
+ setCalendar(calendar: Gtk.Calendar, onRebuild: () => void): void;
12
+ addMark(): void;
13
+ updateProps(oldProps: CalendarMarkProps | null, newProps: CalendarMarkProps): void;
14
+ unmount(): void;
15
+ }
@@ -0,0 +1,29 @@
1
+ import { registerNodeClass } from "../registry.js";
2
+ import { VirtualNode } from "./virtual.js";
3
+ export class CalendarMarkNode extends VirtualNode {
4
+ static priority = 1;
5
+ calendar;
6
+ onRebuild;
7
+ static matches(type) {
8
+ return type === "CalendarMark";
9
+ }
10
+ setCalendar(calendar, onRebuild) {
11
+ this.calendar = calendar;
12
+ this.onRebuild = onRebuild;
13
+ }
14
+ addMark() {
15
+ this.calendar?.markDay(this.props.day);
16
+ }
17
+ updateProps(oldProps, newProps) {
18
+ super.updateProps(oldProps, newProps);
19
+ if (oldProps && this.calendar && oldProps.day !== newProps.day) {
20
+ this.onRebuild?.();
21
+ }
22
+ }
23
+ unmount() {
24
+ this.calendar = undefined;
25
+ this.onRebuild = undefined;
26
+ super.unmount();
27
+ }
28
+ }
29
+ registerNodeClass(CalendarMarkNode);
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,70 @@
1
+ import * as Gtk from "@gtkx/ffi/gtk";
2
+ import { registerNodeClass } from "../registry.js";
3
+ import { CommitPriority, scheduleAfterCommit } from "../scheduler.js";
4
+ import { CalendarMarkNode } from "./calendar-mark.js";
5
+ import { isContainerType } from "./internal/utils.js";
6
+ import { SlotNode } from "./slot.js";
7
+ import { WidgetNode } from "./widget.js";
8
+ class CalendarNode extends WidgetNode {
9
+ static priority = 1;
10
+ markChildren = [];
11
+ static matches(_type, containerOrClass) {
12
+ return isContainerType(Gtk.Calendar, containerOrClass);
13
+ }
14
+ appendChild(child) {
15
+ if (child instanceof CalendarMarkNode) {
16
+ child.setCalendar(this.container, () => this.scheduleRebuildAllMarks());
17
+ this.markChildren.push(child);
18
+ scheduleAfterCommit(() => child.addMark());
19
+ return;
20
+ }
21
+ if (child instanceof SlotNode || child instanceof WidgetNode) {
22
+ super.appendChild(child);
23
+ return;
24
+ }
25
+ throw new Error(`Cannot append '${child.typeName}' to 'Calendar': expected x.CalendarMark or Widget`);
26
+ }
27
+ insertBefore(child, before) {
28
+ if (child instanceof CalendarMarkNode) {
29
+ child.setCalendar(this.container, () => this.scheduleRebuildAllMarks());
30
+ const beforeIndex = this.markChildren.indexOf(before);
31
+ if (beforeIndex >= 0) {
32
+ this.markChildren.splice(beforeIndex, 0, child);
33
+ }
34
+ else {
35
+ this.markChildren.push(child);
36
+ }
37
+ this.scheduleRebuildAllMarks();
38
+ return;
39
+ }
40
+ if (child instanceof SlotNode || child instanceof WidgetNode) {
41
+ super.insertBefore(child, before);
42
+ return;
43
+ }
44
+ throw new Error(`Cannot insert '${child.typeName}' into 'Calendar': expected x.CalendarMark or Widget`);
45
+ }
46
+ removeChild(child) {
47
+ if (child instanceof CalendarMarkNode) {
48
+ const index = this.markChildren.indexOf(child);
49
+ if (index >= 0) {
50
+ this.markChildren.splice(index, 1);
51
+ }
52
+ this.scheduleRebuildAllMarks(CommitPriority.HIGH);
53
+ return;
54
+ }
55
+ if (child instanceof SlotNode || child instanceof WidgetNode) {
56
+ super.removeChild(child);
57
+ return;
58
+ }
59
+ throw new Error(`Cannot remove '${child.typeName}' from 'Calendar': expected x.CalendarMark or Widget`);
60
+ }
61
+ scheduleRebuildAllMarks(priority = CommitPriority.NORMAL) {
62
+ scheduleAfterCommit(() => {
63
+ this.container.clearMarks();
64
+ for (const mark of this.markChildren) {
65
+ mark.addMark();
66
+ }
67
+ }, priority);
68
+ }
69
+ }
70
+ registerNodeClass(CalendarNode);
@@ -11,6 +11,7 @@ export declare class ColumnViewColumnNode extends VirtualNode<Props> {
11
11
  private itemRenderer;
12
12
  constructor(typeName: string, props: Props, container: undefined, rootContainer?: Container);
13
13
  setStore(model?: ListStore): void;
14
+ setEstimatedRowHeight(height?: number): void;
14
15
  updateProps(oldProps: Props | null, newProps: Props): void;
15
16
  }
16
17
  export {};
@@ -18,6 +18,9 @@ export class ColumnViewColumnNode extends VirtualNode {
18
18
  setStore(model) {
19
19
  this.itemRenderer.setStore(model);
20
20
  }
21
+ setEstimatedRowHeight(height) {
22
+ this.itemRenderer.setEstimatedItemHeight(height);
23
+ }
21
24
  updateProps(oldProps, newProps) {
22
25
  if (!oldProps || oldProps.renderCell !== newProps.renderCell) {
23
26
  if (newProps.renderCell) {
@@ -49,6 +52,7 @@ export class ColumnViewColumnNode extends VirtualNode {
49
52
  this.column.setSorter(null);
50
53
  }
51
54
  }
55
+ super.updateProps(oldProps, newProps);
52
56
  }
53
57
  }
54
58
  registerNodeClass(ColumnViewColumnNode);
@@ -7,17 +7,23 @@ import { filterProps, matchesAnyClass } from "./internal/utils.js";
7
7
  import { ListItemNode } from "./list-item.js";
8
8
  import { List } from "./models/list.js";
9
9
  import { WidgetNode } from "./widget.js";
10
- const PROP_NAMES = ["sortColumn", "sortOrder", "onSortChange"];
10
+ const PROP_NAMES = ["sortColumn", "sortOrder", "onSortChange", "estimatedRowHeight"];
11
11
  class ColumnViewNode extends WidgetNode {
12
12
  static priority = 1;
13
13
  handleSortChange;
14
14
  list;
15
+ columnNodes = new Set();
16
+ estimatedRowHeight;
15
17
  static matches(_type, containerOrClass) {
16
18
  return matchesAnyClass(COLUMN_VIEW_CLASSES, containerOrClass);
17
19
  }
18
20
  constructor(typeName, props, container, rootContainer) {
19
21
  super(typeName, props, container, rootContainer);
20
- this.list = new List(props.selectionMode);
22
+ this.list = new List({
23
+ selectionMode: props.selectionMode,
24
+ selected: props.selected,
25
+ onSelectionChanged: props.onSelectionChanged,
26
+ });
21
27
  }
22
28
  mount() {
23
29
  super.mount();
@@ -29,7 +35,7 @@ class ColumnViewNode extends WidgetNode {
29
35
  return;
30
36
  }
31
37
  if (!(child instanceof ColumnViewColumnNode)) {
32
- throw new Error(`Cannot append '${child.typeName}' to 'ColumnView': expected ColumnViewColumn`);
38
+ throw new Error(`Cannot append '${child.typeName}' to 'ColumnView': expected x.ColumnViewColumn or x.ListItem`);
33
39
  }
34
40
  const existingColumn = this.findColumnInView(child.column);
35
41
  if (existingColumn) {
@@ -37,6 +43,8 @@ class ColumnViewNode extends WidgetNode {
37
43
  }
38
44
  this.container.appendColumn(child.column);
39
45
  child.setStore(this.list.getStore());
46
+ child.setEstimatedRowHeight(this.estimatedRowHeight);
47
+ this.columnNodes.add(child);
40
48
  }
41
49
  insertBefore(child, before) {
42
50
  if (child instanceof ListItemNode) {
@@ -44,7 +52,7 @@ class ColumnViewNode extends WidgetNode {
44
52
  return;
45
53
  }
46
54
  if (!(child instanceof ColumnViewColumnNode)) {
47
- throw new Error(`Cannot insert '${child.typeName}' to 'ColumnView': expected ColumnViewColumn`);
55
+ throw new Error(`Cannot insert '${child.typeName}' into 'ColumnView': expected x.ColumnViewColumn or x.ListItem`);
48
56
  }
49
57
  const existingColumn = this.findColumnInView(child.column);
50
58
  if (existingColumn) {
@@ -58,6 +66,8 @@ class ColumnViewNode extends WidgetNode {
58
66
  this.container.appendColumn(child.column);
59
67
  }
60
68
  child.setStore(this.list.getStore());
69
+ child.setEstimatedRowHeight(this.estimatedRowHeight);
70
+ this.columnNodes.add(child);
61
71
  }
62
72
  removeChild(child) {
63
73
  if (child instanceof ListItemNode) {
@@ -65,13 +75,14 @@ class ColumnViewNode extends WidgetNode {
65
75
  return;
66
76
  }
67
77
  if (!(child instanceof ColumnViewColumnNode)) {
68
- throw new Error(`Cannot remove '${child.typeName}' from 'ColumnView': expected ColumnViewColumn`);
78
+ throw new Error(`Cannot remove '${child.typeName}' from 'ColumnView': expected x.ColumnViewColumn or x.ListItem`);
69
79
  }
70
80
  const existingColumn = this.findColumnInView(child.column);
71
81
  if (existingColumn) {
72
82
  this.container.removeColumn(existingColumn);
73
83
  }
74
84
  child.setStore(undefined);
85
+ this.columnNodes.delete(child);
75
86
  }
76
87
  updateProps(oldProps, newProps) {
77
88
  if (!oldProps || oldProps.onSortChange !== newProps.onSortChange) {
@@ -94,8 +105,14 @@ class ColumnViewNode extends WidgetNode {
94
105
  this.container.sortByColumn(sortOrder, this.getColumn(sortColumn));
95
106
  }
96
107
  }
97
- this.list.updateProps(filterProps(oldProps ?? {}, PROP_NAMES), filterProps(newProps, PROP_NAMES));
98
- super.updateProps(filterProps(oldProps ?? {}, PROP_NAMES), filterProps(newProps, PROP_NAMES));
108
+ if (!oldProps || oldProps.estimatedRowHeight !== newProps.estimatedRowHeight) {
109
+ this.estimatedRowHeight = newProps.estimatedRowHeight;
110
+ for (const column of this.columnNodes) {
111
+ column.setEstimatedRowHeight(this.estimatedRowHeight);
112
+ }
113
+ }
114
+ this.list.updateProps(oldProps ? filterProps(oldProps, PROP_NAMES) : null, filterProps(newProps, PROP_NAMES));
115
+ super.updateProps(oldProps ? filterProps(oldProps, PROP_NAMES) : null, filterProps(newProps, PROP_NAMES));
99
116
  }
100
117
  getColumn(columnId) {
101
118
  const columns = this.container.getColumns();
@@ -0,0 +1,15 @@
1
+ import type * as Adw from "@gtkx/ffi/adw";
2
+ import type * as Gtk from "@gtkx/ffi/gtk";
3
+ import { VirtualChildNode } from "./virtual-child.js";
4
+ type ExpanderRowWidget = Adw.ExpanderRow & {
5
+ addRow(child: Gtk.Widget): void;
6
+ addAction(widget: Gtk.Widget): void;
7
+ remove(child: Gtk.Widget): void;
8
+ };
9
+ export declare class ExpanderRowChild extends VirtualChildNode<ExpanderRowWidget> {
10
+ static priority: number;
11
+ static matches(type: string): boolean;
12
+ protected getPositionLabel(): string;
13
+ protected attachChild(parent: ExpanderRowWidget, widget: Gtk.Widget): void;
14
+ }
15
+ export {};
@@ -0,0 +1,20 @@
1
+ import { registerNodeClass } from "../registry.js";
2
+ import { VirtualChildNode } from "./virtual-child.js";
3
+ export class ExpanderRowChild extends VirtualChildNode {
4
+ static priority = 1;
5
+ static matches(type) {
6
+ return type === "ExpanderRowRow" || type === "ExpanderRowAction";
7
+ }
8
+ getPositionLabel() {
9
+ return this.typeName === "ExpanderRowRow" ? "row" : "action";
10
+ }
11
+ attachChild(parent, widget) {
12
+ if (this.getPositionLabel() === "row") {
13
+ parent.addRow(widget);
14
+ }
15
+ else {
16
+ parent.addAction(widget);
17
+ }
18
+ }
19
+ }
20
+ registerNodeClass(ExpanderRowChild);
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,54 @@
1
+ import * as Adw from "@gtkx/ffi/adw";
2
+ import { registerNodeClass } from "../registry.js";
3
+ import { ActionRowChild } from "./action-row-child.js";
4
+ import { ExpanderRowChild } from "./expander-row-child.js";
5
+ import { isContainerType } from "./internal/utils.js";
6
+ import { SlotNode } from "./slot.js";
7
+ import { WidgetNode } from "./widget.js";
8
+ class ExpanderRowNode extends WidgetNode {
9
+ static priority = -1;
10
+ static matches(_type, containerOrClass) {
11
+ return isContainerType(Adw.ExpanderRow, containerOrClass);
12
+ }
13
+ appendChild(child) {
14
+ if (child instanceof ExpanderRowChild) {
15
+ child.setParent(this.container);
16
+ return;
17
+ }
18
+ if (child instanceof ActionRowChild) {
19
+ child.setParent(this.container);
20
+ return;
21
+ }
22
+ if (child instanceof SlotNode || child instanceof WidgetNode) {
23
+ super.appendChild(child);
24
+ return;
25
+ }
26
+ throw new Error(`Cannot append '${child.typeName}' to 'ExpanderRow': expected x.ExpanderRowRow, x.ExpanderRowAction, x.ActionRowPrefix, x.ActionRowSuffix, or Widget`);
27
+ }
28
+ insertBefore(child, before) {
29
+ if (child instanceof ExpanderRowChild) {
30
+ child.setParent(this.container);
31
+ return;
32
+ }
33
+ if (child instanceof ActionRowChild) {
34
+ child.setParent(this.container);
35
+ return;
36
+ }
37
+ if (child instanceof SlotNode || child instanceof WidgetNode) {
38
+ super.insertBefore(child, before);
39
+ return;
40
+ }
41
+ throw new Error(`Cannot insert '${child.typeName}' into 'ExpanderRow': expected x.ExpanderRowRow, x.ExpanderRowAction, x.ActionRowPrefix, x.ActionRowSuffix, or Widget`);
42
+ }
43
+ removeChild(child) {
44
+ if (child instanceof ExpanderRowChild || child instanceof ActionRowChild) {
45
+ return;
46
+ }
47
+ if (child instanceof SlotNode || child instanceof WidgetNode) {
48
+ super.removeChild(child);
49
+ return;
50
+ }
51
+ throw new Error(`Cannot remove '${child.typeName}' from 'ExpanderRow': expected x.ExpanderRowRow, x.ExpanderRowAction, x.ActionRowPrefix, x.ActionRowSuffix, or Widget`);
52
+ }
53
+ }
54
+ registerNodeClass(ExpanderRowNode);
@@ -37,15 +37,17 @@ class FixedChildNode extends SlotNode {
37
37
  }
38
38
  onChildChange(oldChild) {
39
39
  const fixed = this.getFixed();
40
- if (oldChild) {
41
- const parent = oldChild.getParent();
42
- if (parent && isObjectEqual(parent, fixed)) {
43
- fixed.remove(oldChild);
40
+ batch(() => {
41
+ if (oldChild) {
42
+ const parent = oldChild.getParent();
43
+ if (parent && isObjectEqual(parent, fixed)) {
44
+ fixed.remove(oldChild);
45
+ }
44
46
  }
45
- }
46
- if (this.child) {
47
- this.positionChild();
48
- }
47
+ if (this.child) {
48
+ this.positionChild();
49
+ }
50
+ });
49
51
  }
50
52
  }
51
53
  registerNodeClass(FixedChildNode);
@@ -46,15 +46,17 @@ class GridChildNode extends SlotNode {
46
46
  }
47
47
  onChildChange(oldChild) {
48
48
  const grid = this.getGrid();
49
- if (oldChild) {
50
- const parent = oldChild.getParent();
51
- if (parent && isObjectEqual(parent, grid)) {
52
- grid.remove(oldChild);
49
+ batch(() => {
50
+ if (oldChild) {
51
+ const parent = oldChild.getParent();
52
+ if (parent && isObjectEqual(parent, grid)) {
53
+ grid.remove(oldChild);
54
+ }
53
55
  }
54
- }
55
- if (this.child) {
56
- this.attachChild();
57
- }
56
+ if (this.child) {
57
+ this.attachChild();
58
+ }
59
+ });
58
60
  }
59
61
  }
60
62
  registerNodeClass(GridChildNode);