@gtkx/react 1.3.0 → 1.5.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.
- package/README.md +5 -4
- package/dist/adw/dialog.js +2 -2
- package/dist/adw/dialog.js.map +1 -1
- package/dist/adw/element-behaviors.js +19 -107
- package/dist/adw/element-behaviors.js.map +1 -1
- package/dist/components/application.d.ts.map +1 -1
- package/dist/components/application.js +3 -3
- package/dist/components/application.js.map +1 -1
- package/dist/components/window.js +3 -3
- package/dist/components/window.js.map +1 -1
- package/dist/element-behaviors.js +55 -60
- package/dist/element-behaviors.js.map +1 -1
- package/dist/element-config.js +1 -1
- package/dist/element-config.js.map +1 -1
- package/dist/hooks/use-bind-setting.d.ts.map +1 -1
- package/dist/hooks/use-bind-setting.js +3 -2
- package/dist/hooks/use-bind-setting.js.map +1 -1
- package/dist/hooks/use-property.d.ts +1 -1
- package/dist/hooks/use-property.d.ts.map +1 -1
- package/dist/hooks/use-property.js +5 -1
- package/dist/hooks/use-property.js.map +1 -1
- package/dist/prop-types.d.ts +9 -1
- package/dist/prop-types.d.ts.map +1 -1
- package/dist/prop-types.js.map +1 -1
- package/dist/reconciler/apply-props.d.ts +2 -1
- package/dist/reconciler/apply-props.d.ts.map +1 -1
- package/dist/reconciler/apply-props.js +59 -24
- package/dist/reconciler/apply-props.js.map +1 -1
- package/dist/reconciler/behaviors.d.ts +19 -3
- package/dist/reconciler/behaviors.d.ts.map +1 -1
- package/dist/reconciler/behaviors.js +73 -17
- package/dist/reconciler/behaviors.js.map +1 -1
- package/dist/reconciler/host-config.d.ts.map +1 -1
- package/dist/reconciler/host-config.js +2 -1
- package/dist/reconciler/host-config.js.map +1 -1
- package/dist/reconciler/metadata.d.ts +6 -1
- package/dist/reconciler/metadata.d.ts.map +1 -1
- package/dist/reconciler/metadata.js +39 -6
- package/dist/reconciler/metadata.js.map +1 -1
- package/dist/reconciler/placement.js +4 -4
- package/dist/reconciler/placement.js.map +1 -1
- package/dist/reconciler/registry.d.ts +2 -0
- package/dist/reconciler/registry.d.ts.map +1 -1
- package/dist/reconciler/registry.js.map +1 -1
- package/dist/reconciler/root.d.ts.map +1 -1
- package/dist/reconciler/root.js.map +1 -1
- package/dist/reconciler/signals.d.ts +3 -2
- package/dist/reconciler/signals.d.ts.map +1 -1
- package/dist/reconciler/signals.js +49 -16
- package/dist/reconciler/signals.js.map +1 -1
- package/dist/reconciler/style.d.ts +2 -1
- package/dist/reconciler/style.d.ts.map +1 -1
- package/dist/reconciler/style.js +4 -3
- package/dist/reconciler/style.js.map +1 -1
- package/dist/reconciler/text.js +3 -3
- package/dist/reconciler/text.js.map +1 -1
- package/env.d.ts +10 -7
- package/package.json +6 -6
- package/src/adw/dialog.tsx +2 -2
- package/src/adw/element-behaviors.ts +22 -162
- package/src/components/application.tsx +18 -3
- package/src/components/window.tsx +3 -3
- package/src/element-behaviors.ts +75 -96
- package/src/element-config.ts +1 -1
- package/src/hooks/use-bind-setting.ts +3 -2
- package/src/hooks/use-property.ts +6 -2
- package/src/prop-types.ts +10 -0
- package/src/reconciler/apply-props.ts +73 -26
- package/src/reconciler/behaviors.ts +130 -33
- package/src/reconciler/host-config.ts +3 -1
- package/src/reconciler/metadata.ts +62 -6
- package/src/reconciler/placement.ts +4 -4
- package/src/reconciler/registry.ts +2 -0
- package/src/reconciler/root.ts +1 -1
- package/src/reconciler/signals.ts +62 -17
- package/src/reconciler/style.ts +4 -3
- package/src/reconciler/text.ts +3 -3
|
@@ -2,8 +2,6 @@ import type * as Gtk from "@gtkx/gi/gtk";
|
|
|
2
2
|
import * as Adw from "@gtkx/gi/adw";
|
|
3
3
|
import type { AlertDialogResponse } from "./prop-types.js";
|
|
4
4
|
import {
|
|
5
|
-
addRemoveSlot,
|
|
6
|
-
adoptedChildrenSlot,
|
|
7
5
|
applicationCreator,
|
|
8
6
|
boxSlot,
|
|
9
7
|
childMatcher,
|
|
@@ -12,6 +10,8 @@ import {
|
|
|
12
10
|
deferred,
|
|
13
11
|
indexedSlot,
|
|
14
12
|
list,
|
|
13
|
+
methodSlot,
|
|
14
|
+
setterSlot,
|
|
15
15
|
slot,
|
|
16
16
|
} from "../reconciler/behaviors.js";
|
|
17
17
|
import { type ElementBehavior, type ElementConfig, forTypes, registerElements } from "../reconciler/registry.js";
|
|
@@ -36,56 +36,18 @@ type PrefixSuffixRow = Adw.ActionRow | Adw.EntryRow | Adw.ExpanderRow;
|
|
|
36
36
|
const SLOT_SUFFIX = "Slot";
|
|
37
37
|
const childSetter = childSetterSlot<AdwChildSetter>();
|
|
38
38
|
const contentSetter = contentSetterSlot<AdwContentSetter>();
|
|
39
|
-
|
|
40
|
-
const breakpoints = slot<BreakpointHost, Adw.Breakpoint>("breakpoints", "AdwBreakpoint", {
|
|
41
|
-
attach: (host, breakpoint) => {
|
|
42
|
-
host.addBreakpoint(breakpoint);
|
|
43
|
-
},
|
|
44
|
-
});
|
|
39
|
+
const breakpoints = methodSlot<BreakpointHost, Adw.Breakpoint>("breakpoints", "AdwBreakpoint", "addBreakpoint");
|
|
45
40
|
|
|
46
41
|
const prefixSuffix = [
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"GtkWidget",
|
|
50
|
-
(row, child) => {
|
|
51
|
-
row.addPrefix(child);
|
|
52
|
-
},
|
|
53
|
-
(row, child) => {
|
|
54
|
-
row.remove(child);
|
|
55
|
-
},
|
|
56
|
-
),
|
|
57
|
-
addRemoveSlot<Gtk.Widget, PrefixSuffixRow>(
|
|
58
|
-
"suffix",
|
|
59
|
-
"GtkWidget",
|
|
60
|
-
(row, child) => {
|
|
61
|
-
row.addSuffix(child);
|
|
62
|
-
},
|
|
63
|
-
(row, child) => {
|
|
64
|
-
row.remove(child);
|
|
65
|
-
},
|
|
66
|
-
),
|
|
42
|
+
methodSlot<PrefixSuffixRow, Gtk.Widget>("prefix", "GtkWidget", "addPrefix", "remove"),
|
|
43
|
+
methodSlot<PrefixSuffixRow, Gtk.Widget>("suffix", "GtkWidget", "addSuffix", "remove"),
|
|
67
44
|
];
|
|
68
45
|
|
|
69
|
-
const preferencesDialogChildren =
|
|
70
|
-
"children",
|
|
71
|
-
"AdwPreferencesPage",
|
|
72
|
-
(dialog, page) => {
|
|
73
|
-
dialog.add(page);
|
|
74
|
-
},
|
|
75
|
-
(dialog, page) => {
|
|
76
|
-
dialog.remove(page);
|
|
77
|
-
},
|
|
46
|
+
const preferencesDialogChildren = methodSlot<Adw.PreferencesDialog, Adw.PreferencesPage>(
|
|
47
|
+
"children", "AdwPreferencesPage", "add", "remove",
|
|
78
48
|
);
|
|
79
49
|
|
|
80
|
-
const alertDialogExtraChild =
|
|
81
|
-
attach: (dialog, child) => {
|
|
82
|
-
dialog.setExtraChild(child);
|
|
83
|
-
},
|
|
84
|
-
detach: (dialog) => {
|
|
85
|
-
dialog.setExtraChild(null);
|
|
86
|
-
},
|
|
87
|
-
});
|
|
88
|
-
|
|
50
|
+
const alertDialogExtraChild = setterSlot<Adw.AlertDialog, Gtk.Widget>("children", "GtkWidget", "setExtraChild");
|
|
89
51
|
const sidebarSections = indexedSlot<Adw.Sidebar, Adw.SidebarSection>("children", "AdwSidebarSection");
|
|
90
52
|
const sidebarItems = indexedSlot<Adw.SidebarSection, Adw.SidebarItem>("children", "AdwSidebarItem");
|
|
91
53
|
const isWidget = childMatcher("GtkWidget");
|
|
@@ -151,14 +113,7 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
151
113
|
},
|
|
152
114
|
AdwClampScrollable: {
|
|
153
115
|
behaviors: [
|
|
154
|
-
|
|
155
|
-
attach: (clamp, child) => {
|
|
156
|
-
clamp.setChild(child);
|
|
157
|
-
},
|
|
158
|
-
detach: (clamp) => {
|
|
159
|
-
clamp.setChild(null);
|
|
160
|
-
},
|
|
161
|
-
}),
|
|
116
|
+
setterSlot<Adw.ClampScrollable, Gtk.Scrollable & Gtk.Widget>("children", "GtkScrollable", "setChild"),
|
|
162
117
|
],
|
|
163
118
|
},
|
|
164
119
|
...forTypes(CHILD_SETTER_TYPES, {
|
|
@@ -179,15 +134,8 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
179
134
|
AdwBreakpointBin: {
|
|
180
135
|
behaviors: [
|
|
181
136
|
childSetter,
|
|
182
|
-
|
|
183
|
-
"breakpoints",
|
|
184
|
-
"AdwBreakpoint",
|
|
185
|
-
(bin, breakpoint) => {
|
|
186
|
-
bin.addBreakpoint(breakpoint);
|
|
187
|
-
},
|
|
188
|
-
(bin, breakpoint) => {
|
|
189
|
-
bin.removeBreakpoint(breakpoint);
|
|
190
|
-
},
|
|
137
|
+
methodSlot<Adw.BreakpointBin, Adw.Breakpoint>(
|
|
138
|
+
"breakpoints", "AdwBreakpoint", "addBreakpoint", "removeBreakpoint",
|
|
191
139
|
),
|
|
192
140
|
],
|
|
193
141
|
},
|
|
@@ -200,16 +148,7 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
200
148
|
AdwExpanderRow: {
|
|
201
149
|
behaviors: [
|
|
202
150
|
...prefixSuffix,
|
|
203
|
-
|
|
204
|
-
"rows",
|
|
205
|
-
"GtkWidget",
|
|
206
|
-
(row, child) => {
|
|
207
|
-
row.addRow(child);
|
|
208
|
-
},
|
|
209
|
-
(row, child) => {
|
|
210
|
-
row.remove(child);
|
|
211
|
-
},
|
|
212
|
-
),
|
|
151
|
+
methodSlot<Adw.ExpanderRow, Gtk.Widget>("rows", "GtkWidget", "addRow", "remove"),
|
|
213
152
|
],
|
|
214
153
|
},
|
|
215
154
|
AdwNavigationSplitView: {
|
|
@@ -249,18 +188,7 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
249
188
|
behaviors: [preferencesDialogChildren],
|
|
250
189
|
},
|
|
251
190
|
AdwPreferencesGroup: {
|
|
252
|
-
behaviors: [
|
|
253
|
-
addRemoveSlot<Gtk.Widget, Adw.PreferencesGroup>(
|
|
254
|
-
"children",
|
|
255
|
-
"GtkWidget",
|
|
256
|
-
(group, child) => {
|
|
257
|
-
group.add(child);
|
|
258
|
-
},
|
|
259
|
-
(group, child) => {
|
|
260
|
-
group.remove(child);
|
|
261
|
-
},
|
|
262
|
-
),
|
|
263
|
-
],
|
|
191
|
+
behaviors: [methodSlot<Adw.PreferencesGroup, Gtk.Widget>("children", "GtkWidget", "add", "remove")],
|
|
264
192
|
},
|
|
265
193
|
AdwTabView: {
|
|
266
194
|
behaviors: [
|
|
@@ -282,105 +210,37 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
282
210
|
},
|
|
283
211
|
AdwNavigationView: {
|
|
284
212
|
behaviors: [
|
|
285
|
-
|
|
286
|
-
"children",
|
|
287
|
-
"AdwNavigationPage",
|
|
288
|
-
(view, page) => {
|
|
289
|
-
view.add(page);
|
|
290
|
-
},
|
|
291
|
-
(view, page) => {
|
|
292
|
-
view.remove(page);
|
|
293
|
-
},
|
|
294
|
-
),
|
|
213
|
+
methodSlot<Adw.NavigationView, Adw.NavigationPage>("children", "AdwNavigationPage", "add", "remove"),
|
|
295
214
|
],
|
|
296
215
|
},
|
|
297
216
|
AdwViewStack: {
|
|
298
217
|
behaviors: [
|
|
299
|
-
|
|
300
|
-
"GtkWidget",
|
|
301
|
-
(stack, child) => stack.add(child),
|
|
302
|
-
(stack, child) => {
|
|
303
|
-
stack.remove(child);
|
|
304
|
-
},
|
|
305
|
-
),
|
|
218
|
+
methodSlot<Adw.ViewStack, Gtk.Widget>("children", "GtkWidget", "add", "remove"),
|
|
306
219
|
deferred<Adw.ViewStack, string>("visibleChildName", (stack, name) => stack.getChildByName(name) !== null),
|
|
307
220
|
],
|
|
308
221
|
},
|
|
309
222
|
AdwToolbarView: {
|
|
310
223
|
behaviors: [
|
|
311
224
|
contentSetterSlot<Adw.ToolbarView>(),
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
"GtkWidget",
|
|
315
|
-
(view, child) => {
|
|
316
|
-
view.addTopBar(child);
|
|
317
|
-
},
|
|
318
|
-
(view, child) => {
|
|
319
|
-
view.remove(child);
|
|
320
|
-
},
|
|
321
|
-
),
|
|
322
|
-
addRemoveSlot<Gtk.Widget, Adw.ToolbarView>(
|
|
323
|
-
"bottomBar",
|
|
324
|
-
"GtkWidget",
|
|
325
|
-
(view, child) => {
|
|
326
|
-
view.addBottomBar(child);
|
|
327
|
-
},
|
|
328
|
-
(view, child) => {
|
|
329
|
-
view.remove(child);
|
|
330
|
-
},
|
|
331
|
-
),
|
|
225
|
+
methodSlot<Adw.ToolbarView, Gtk.Widget>("topBar", "GtkWidget", "addTopBar", "remove"),
|
|
226
|
+
methodSlot<Adw.ToolbarView, Gtk.Widget>("bottomBar", "GtkWidget", "addBottomBar", "remove"),
|
|
332
227
|
],
|
|
333
228
|
},
|
|
334
229
|
AdwHeaderBar: {
|
|
335
230
|
behaviors: [
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
bar.packStart(child);
|
|
339
|
-
},
|
|
340
|
-
detach: (bar, child) => {
|
|
341
|
-
bar.remove(child);
|
|
342
|
-
},
|
|
343
|
-
}),
|
|
344
|
-
slot<Adw.HeaderBar, Gtk.Widget>("end", "GtkWidget", {
|
|
345
|
-
attach: (bar, child) => {
|
|
346
|
-
bar.packEnd(child);
|
|
347
|
-
},
|
|
348
|
-
detach: (bar, child) => {
|
|
349
|
-
bar.remove(child);
|
|
350
|
-
},
|
|
351
|
-
}),
|
|
231
|
+
methodSlot<Adw.HeaderBar, Gtk.Widget>("start", "GtkWidget", "packStart", "remove"),
|
|
232
|
+
methodSlot<Adw.HeaderBar, Gtk.Widget>("end", "GtkWidget", "packEnd", "remove"),
|
|
352
233
|
],
|
|
353
234
|
},
|
|
354
235
|
AdwShortcutsDialog: {
|
|
355
|
-
behaviors: [
|
|
356
|
-
slot<Adw.ShortcutsDialog, Adw.ShortcutsSection>("children", "AdwShortcutsSection", {
|
|
357
|
-
attach: (dialog, section) => {
|
|
358
|
-
dialog.add(section);
|
|
359
|
-
},
|
|
360
|
-
}),
|
|
361
|
-
],
|
|
236
|
+
behaviors: [methodSlot<Adw.ShortcutsDialog, Adw.ShortcutsSection>("children", "AdwShortcutsSection", "add")],
|
|
362
237
|
},
|
|
363
238
|
AdwShortcutsSection: {
|
|
364
|
-
behaviors: [
|
|
365
|
-
slot<Adw.ShortcutsSection, Adw.ShortcutsItem>("children", "AdwShortcutsItem", {
|
|
366
|
-
attach: (section, item) => {
|
|
367
|
-
section.add(item);
|
|
368
|
-
},
|
|
369
|
-
}),
|
|
370
|
-
],
|
|
239
|
+
behaviors: [methodSlot<Adw.ShortcutsSection, Adw.ShortcutsItem>("children", "AdwShortcutsItem", "add")],
|
|
371
240
|
},
|
|
372
241
|
AdwToggleGroup: {
|
|
373
242
|
behaviors: [
|
|
374
|
-
|
|
375
|
-
"children",
|
|
376
|
-
"AdwToggle",
|
|
377
|
-
(group, toggle) => {
|
|
378
|
-
group.add(toggle);
|
|
379
|
-
},
|
|
380
|
-
(group, toggle) => {
|
|
381
|
-
group.remove(toggle);
|
|
382
|
-
},
|
|
383
|
-
),
|
|
243
|
+
methodSlot<Adw.ToggleGroup, Adw.Toggle>("children", "AdwToggle", "add", "remove"),
|
|
384
244
|
deferred<Adw.ToggleGroup, string>("activeName", (group, name) => group.getToggleByName(name) !== null),
|
|
385
245
|
deferred("active"),
|
|
386
246
|
],
|
|
@@ -3,7 +3,10 @@ import { quitApplication, runApplication } from "@gtkx/runtime";
|
|
|
3
3
|
import { pickBy, warn } from "@gtkx/utils";
|
|
4
4
|
import process from "node:process";
|
|
5
5
|
import { type ElementType, type ReactNode, type Ref, useLayoutEffect, useState } from "react";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
applicationId as defaultApplicationId,
|
|
8
|
+
resourceBasePath as defaultResourceBasePath,
|
|
9
|
+
} from "virtual:gtkx-config";
|
|
7
10
|
import { ApplicationContext } from "../hooks/use-application.js";
|
|
8
11
|
import { useMergedRef } from "../hooks/use-merged-refs.js";
|
|
9
12
|
import { createPortaledComponent } from "./portaled.js";
|
|
@@ -12,6 +15,7 @@ type ApplicationComponentProps = {
|
|
|
12
15
|
applicationId?: string | null | undefined;
|
|
13
16
|
children?: ReactNode | undefined;
|
|
14
17
|
ref?: Ref<Gtk.Application | null> | undefined;
|
|
18
|
+
resourceBasePath?: string | null | undefined;
|
|
15
19
|
};
|
|
16
20
|
|
|
17
21
|
const POST_ACTIVATE_PROPS = new Set(["menubar"]);
|
|
@@ -80,7 +84,13 @@ const applicationChildren = (application: Gtk.Application | null, children: Reac
|
|
|
80
84
|
const createApplicationElement = (
|
|
81
85
|
Component: ElementType,
|
|
82
86
|
): ((props: ApplicationComponentProps) => ReactNode) => {
|
|
83
|
-
return ({
|
|
87
|
+
return ({
|
|
88
|
+
applicationId = defaultApplicationId,
|
|
89
|
+
children,
|
|
90
|
+
ref,
|
|
91
|
+
resourceBasePath = defaultResourceBasePath,
|
|
92
|
+
...rest
|
|
93
|
+
}: ApplicationComponentProps): ReactNode => {
|
|
84
94
|
const [application, setApplication] = useState<Gtk.Application | null>(null);
|
|
85
95
|
const [activated, setActivated] = useState(false);
|
|
86
96
|
useApplicationLifecycle(application, setActivated, applicationId);
|
|
@@ -88,7 +98,12 @@ const createApplicationElement = (
|
|
|
88
98
|
const appliedProps = activated ? rest : pickBy(rest, (_value, key) => !POST_ACTIVATE_PROPS.has(key));
|
|
89
99
|
|
|
90
100
|
return (
|
|
91
|
-
<Component
|
|
101
|
+
<Component
|
|
102
|
+
ref={mergedRef}
|
|
103
|
+
applicationId={applicationId}
|
|
104
|
+
{...appliedProps}
|
|
105
|
+
resourceBasePath={resourceBasePath}
|
|
106
|
+
>
|
|
92
107
|
{activated ? applicationChildren(application, children) : null}
|
|
93
108
|
</Component>
|
|
94
109
|
);
|
|
@@ -2,7 +2,7 @@ import type * as Gtk from "@gtkx/gi/gtk";
|
|
|
2
2
|
import { type ElementType, type ReactElement, type ReactNode, use } from "react";
|
|
3
3
|
import { ParentWindowContext } from "../hooks/use-parent-window.js";
|
|
4
4
|
import { createPresentedComponent, type PresentedProps } from "../hooks/use-presented-instance.js";
|
|
5
|
-
import {
|
|
5
|
+
import { applyMutation } from "../reconciler/signals.js";
|
|
6
6
|
import { createPortaledComponent } from "./portaled.js";
|
|
7
7
|
|
|
8
8
|
type WindowComponentProps = PresentedProps<Gtk.Window> & {
|
|
@@ -11,13 +11,13 @@ type WindowComponentProps = PresentedProps<Gtk.Window> & {
|
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
const presentWindow = (window: Gtk.Window): void => {
|
|
14
|
-
|
|
14
|
+
applyMutation(() => {
|
|
15
15
|
window.present();
|
|
16
16
|
});
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
const destroyWindow = (window: Gtk.Window): void => {
|
|
20
|
-
|
|
20
|
+
applyMutation(() => {
|
|
21
21
|
window.destroy();
|
|
22
22
|
});
|
|
23
23
|
};
|
package/src/element-behaviors.ts
CHANGED
|
@@ -14,14 +14,15 @@ import type {
|
|
|
14
14
|
} from "./prop-types.js";
|
|
15
15
|
import { BUILTIN_ELEMENTS, SINGLE_CHILD_TYPES } from "./element-config.js";
|
|
16
16
|
import {
|
|
17
|
-
addRemoveSlot,
|
|
18
|
-
adoptedChildrenSlot,
|
|
19
17
|
applicationCreator,
|
|
20
18
|
boxSlot,
|
|
21
19
|
childSetterSlot,
|
|
22
20
|
controlledText,
|
|
23
21
|
deferred,
|
|
22
|
+
deferredWith,
|
|
24
23
|
list,
|
|
24
|
+
methodSlot,
|
|
25
|
+
setterSlot,
|
|
25
26
|
slot,
|
|
26
27
|
value,
|
|
27
28
|
wrappingIndexedSlot,
|
|
@@ -34,7 +35,11 @@ import {
|
|
|
34
35
|
registerElements,
|
|
35
36
|
} from "./reconciler/registry.js";
|
|
36
37
|
import { applyWrite } from "./reconciler/signals.js";
|
|
37
|
-
import { applyStyle, styleClass } from "./reconciler/style.js";
|
|
38
|
+
import { applyStyle, CSS_CLASSES_PROP, styleClass } from "./reconciler/style.js";
|
|
39
|
+
|
|
40
|
+
const SELECTED_INDEX_PROP = "selectedIndex";
|
|
41
|
+
const SELECTION_SIGNAL = "selected-rows-changed";
|
|
42
|
+
const NO_SELECTION = -1;
|
|
38
43
|
|
|
39
44
|
const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
40
45
|
...forTypes(SINGLE_CHILD_TYPES, {
|
|
@@ -42,26 +47,8 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
42
47
|
}),
|
|
43
48
|
...forTypes(["GtkHeaderBar", "GtkActionBar"], {
|
|
44
49
|
behaviors: [
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"GtkWidget",
|
|
48
|
-
(bar, child) => {
|
|
49
|
-
bar.packStart(child);
|
|
50
|
-
},
|
|
51
|
-
(bar, child) => {
|
|
52
|
-
bar.remove(child);
|
|
53
|
-
},
|
|
54
|
-
),
|
|
55
|
-
addRemoveSlot<Gtk.Widget, Gtk.HeaderBar | Gtk.ActionBar>(
|
|
56
|
-
"end",
|
|
57
|
-
"GtkWidget",
|
|
58
|
-
(bar, child) => {
|
|
59
|
-
bar.packEnd(child);
|
|
60
|
-
},
|
|
61
|
-
(bar, child) => {
|
|
62
|
-
bar.remove(child);
|
|
63
|
-
},
|
|
64
|
-
),
|
|
50
|
+
methodSlot<Gtk.HeaderBar | Gtk.ActionBar, Gtk.Widget>("start", "GtkWidget", "packStart", "remove"),
|
|
51
|
+
methodSlot<Gtk.HeaderBar | Gtk.ActionBar, Gtk.Widget>("end", "GtkWidget", "packEnd", "remove"),
|
|
65
52
|
],
|
|
66
53
|
}),
|
|
67
54
|
GtkWindow: {
|
|
@@ -77,24 +64,10 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
77
64
|
popover.unparent();
|
|
78
65
|
},
|
|
79
66
|
}),
|
|
80
|
-
|
|
81
|
-
"controllers",
|
|
82
|
-
"GtkEventController",
|
|
83
|
-
(widget, controller) => {
|
|
84
|
-
widget.addController(controller);
|
|
85
|
-
},
|
|
86
|
-
(widget, controller) => {
|
|
87
|
-
widget.removeController(controller);
|
|
88
|
-
},
|
|
67
|
+
methodSlot<Gtk.Widget, Gtk.EventController>(
|
|
68
|
+
"controllers", "GtkEventController", "addController", "removeController",
|
|
89
69
|
),
|
|
90
|
-
|
|
91
|
-
attach: (widget, manager) => {
|
|
92
|
-
widget.setLayoutManager(manager);
|
|
93
|
-
},
|
|
94
|
-
detach: (widget) => {
|
|
95
|
-
widget.setLayoutManager(null);
|
|
96
|
-
},
|
|
97
|
-
}),
|
|
70
|
+
setterSlot<Gtk.Widget, Gtk.LayoutManager>("layoutManager", "GtkLayoutManager", "setLayoutManager"),
|
|
98
71
|
slot<Gtk.Widget, Gio.ActionGroup>("actionGroups", "GActionGroup", {
|
|
99
72
|
attach: (widget, group, info) => {
|
|
100
73
|
widget.insertActionGroup((info.props.prefix as string | null) ?? "", group);
|
|
@@ -114,6 +87,7 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
114
87
|
wrappingIndexedSlot(Gtk.ListBoxRow, (row, inner) => {
|
|
115
88
|
row.setChild(inner);
|
|
116
89
|
}),
|
|
90
|
+
selectedIndexBehavior(),
|
|
117
91
|
],
|
|
118
92
|
},
|
|
119
93
|
GtkFlowBox: {
|
|
@@ -139,15 +113,8 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
139
113
|
},
|
|
140
114
|
GtkShortcutController: {
|
|
141
115
|
behaviors: [
|
|
142
|
-
|
|
143
|
-
"shortcuts",
|
|
144
|
-
"GtkShortcut",
|
|
145
|
-
(controller, shortcut) => {
|
|
146
|
-
controller.addShortcut(shortcut);
|
|
147
|
-
},
|
|
148
|
-
(controller, shortcut) => {
|
|
149
|
-
controller.removeShortcut(shortcut);
|
|
150
|
-
},
|
|
116
|
+
methodSlot<Gtk.ShortcutController, Gtk.Shortcut>(
|
|
117
|
+
"shortcuts", "GtkShortcut", "addShortcut", "removeShortcut",
|
|
151
118
|
),
|
|
152
119
|
],
|
|
153
120
|
},
|
|
@@ -155,16 +122,7 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
155
122
|
behaviors: [{ create: () => Gtk.TextChildAnchor.new() }],
|
|
156
123
|
},
|
|
157
124
|
GtkTextView: {
|
|
158
|
-
behaviors: [
|
|
159
|
-
slot<Gtk.TextView, Gtk.TextBuffer>("children", "GtkTextBuffer", {
|
|
160
|
-
attach: (view, buffer) => {
|
|
161
|
-
view.setBuffer(buffer);
|
|
162
|
-
},
|
|
163
|
-
detach: (view) => {
|
|
164
|
-
view.setBuffer(null);
|
|
165
|
-
},
|
|
166
|
-
}),
|
|
167
|
-
],
|
|
125
|
+
behaviors: [setterSlot<Gtk.TextView, Gtk.TextBuffer>("children", "GtkTextBuffer", "setBuffer")],
|
|
168
126
|
},
|
|
169
127
|
GActionMap: {
|
|
170
128
|
behaviors: [
|
|
@@ -242,25 +200,11 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
242
200
|
},
|
|
243
201
|
GtkConstraintLayout: {
|
|
244
202
|
behaviors: [
|
|
245
|
-
|
|
246
|
-
"constraints",
|
|
247
|
-
"GtkConstraint",
|
|
248
|
-
(layout, constraint) => {
|
|
249
|
-
layout.addConstraint(constraint);
|
|
250
|
-
},
|
|
251
|
-
(layout, constraint) => {
|
|
252
|
-
layout.removeConstraint(constraint);
|
|
253
|
-
},
|
|
203
|
+
methodSlot<Gtk.ConstraintLayout, Gtk.Constraint>(
|
|
204
|
+
"constraints", "GtkConstraint", "addConstraint", "removeConstraint",
|
|
254
205
|
),
|
|
255
|
-
|
|
256
|
-
"guides",
|
|
257
|
-
"GtkConstraintGuide",
|
|
258
|
-
(layout, guide) => {
|
|
259
|
-
layout.addGuide(guide);
|
|
260
|
-
},
|
|
261
|
-
(layout, guide) => {
|
|
262
|
-
layout.removeGuide(guide);
|
|
263
|
-
},
|
|
206
|
+
methodSlot<Gtk.ConstraintLayout, Gtk.ConstraintGuide>(
|
|
207
|
+
"guides", "GtkConstraintGuide", "addGuide", "removeGuide",
|
|
264
208
|
),
|
|
265
209
|
list<Gtk.ConstraintLayout, VflConstraints, Gtk.Constraint[]>("vfl", {
|
|
266
210
|
add: (layout, item) => [
|
|
@@ -281,13 +225,7 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
281
225
|
},
|
|
282
226
|
GtkStack: {
|
|
283
227
|
behaviors: [
|
|
284
|
-
|
|
285
|
-
"GtkWidget",
|
|
286
|
-
(stack, child) => stack.addChild(child),
|
|
287
|
-
(stack, child) => {
|
|
288
|
-
stack.remove(child);
|
|
289
|
-
},
|
|
290
|
-
),
|
|
228
|
+
methodSlot<Gtk.Stack, Gtk.Widget>("children", "GtkWidget", "addChild", "remove"),
|
|
291
229
|
deferred<Gtk.Stack, string>("visibleChildName", (stack, name) => stack.getChildByName(name) !== null),
|
|
292
230
|
],
|
|
293
231
|
},
|
|
@@ -308,16 +246,7 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
308
246
|
GtkApplication: {
|
|
309
247
|
behaviors: [
|
|
310
248
|
applicationCreator(Gtk.Application),
|
|
311
|
-
|
|
312
|
-
"children",
|
|
313
|
-
"GtkWindow",
|
|
314
|
-
(application, window) => {
|
|
315
|
-
application.addWindow(window);
|
|
316
|
-
},
|
|
317
|
-
(application, window) => {
|
|
318
|
-
application.removeWindow(window);
|
|
319
|
-
},
|
|
320
|
-
),
|
|
249
|
+
methodSlot<Gtk.Application, Gtk.Window>("children", "GtkWindow", "addWindow", "removeWindow"),
|
|
321
250
|
list<Gtk.Application, ActionAccel>("actionAccels", {
|
|
322
251
|
add: (application, item) => {
|
|
323
252
|
application.setAccelsForAction(item.detailedActionName, item.accels);
|
|
@@ -430,8 +359,8 @@ const didWriteCssClasses = (widget: Gtk.Widget, prev: Props, next: Props, classN
|
|
|
430
359
|
return false;
|
|
431
360
|
}
|
|
432
361
|
|
|
433
|
-
applyWrite(() => {
|
|
434
|
-
Reflect.set(widget,
|
|
362
|
+
applyWrite(CSS_CLASSES_PROP, () => {
|
|
363
|
+
Reflect.set(widget, CSS_CLASSES_PROP, withStyleClass(next.cssClasses, className));
|
|
435
364
|
});
|
|
436
365
|
|
|
437
366
|
return true;
|
|
@@ -460,6 +389,56 @@ function styleBehavior(): ElementBehavior<Gtk.Widget> {
|
|
|
460
389
|
return { update: updateStyle };
|
|
461
390
|
}
|
|
462
391
|
|
|
392
|
+
function selectedRowIndex(box: Gtk.ListBox): number {
|
|
393
|
+
return box.getSelectedRow()?.getIndex() ?? NO_SELECTION;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
function selectedIndexError(value: number): Error {
|
|
397
|
+
return new Error(
|
|
398
|
+
"The 'selectedIndex' of a <GtkListBox> must be a whole number, or -1 to select no row; " +
|
|
399
|
+
`received ${String(value)}.`,
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
function desiredIndex(value: unknown): number | undefined {
|
|
404
|
+
if (value === null) {
|
|
405
|
+
return NO_SELECTION;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
if (typeof value !== "number") {
|
|
409
|
+
return undefined;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (!Number.isSafeInteger(value)) {
|
|
413
|
+
throw selectedIndexError(value);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
return value;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
function applySelectedIndex(box: Gtk.ListBox, index: number): void {
|
|
420
|
+
if (index < 0) {
|
|
421
|
+
box.unselectAll();
|
|
422
|
+
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
const row = box.getRowAtIndex(index);
|
|
427
|
+
|
|
428
|
+
if (row !== null) {
|
|
429
|
+
box.selectRow(row);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
function selectedIndexBehavior(): ElementBehavior<Gtk.ListBox> {
|
|
434
|
+
return deferredWith<Gtk.ListBox, number>(SELECTED_INDEX_PROP, {
|
|
435
|
+
parse: desiredIndex,
|
|
436
|
+
read: selectedRowIndex,
|
|
437
|
+
write: applySelectedIndex,
|
|
438
|
+
signal: SELECTION_SIGNAL,
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
|
|
463
442
|
const addMainOption = (application: Gtk.Application, option: MainOption): void => {
|
|
464
443
|
application.addMainOption(
|
|
465
444
|
option.longName,
|
package/src/element-config.ts
CHANGED
|
@@ -3,6 +3,7 @@ import * as Gio from "@gtkx/gi/gio";
|
|
|
3
3
|
import { kebabCase } from "@gtkx/utils";
|
|
4
4
|
import { useLayoutEffect } from "react";
|
|
5
5
|
import type { SettingsSchema, SettingsSchemaKeys } from "../utils/settings.js";
|
|
6
|
+
import { getPropertyName } from "../reconciler/metadata.js";
|
|
6
7
|
import { type RefProp, resolveRefProp } from "../utils/ref-prop.js";
|
|
7
8
|
import { useSettings } from "./use-setting.js";
|
|
8
9
|
|
|
@@ -32,7 +33,6 @@ function useBindSetting<K extends SettingsSchemaKeys>({
|
|
|
32
33
|
flags = Gio.SettingsBindFlags.DEFAULT,
|
|
33
34
|
}: UseBindSettingOptions<K>): void {
|
|
34
35
|
const settings = useSettings(schema);
|
|
35
|
-
const propertyName = kebabCase(property);
|
|
36
36
|
|
|
37
37
|
useLayoutEffect(() => {
|
|
38
38
|
const resolved = resolveRefProp(object);
|
|
@@ -41,12 +41,13 @@ function useBindSetting<K extends SettingsSchemaKeys>({
|
|
|
41
41
|
return;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
const propertyName = getPropertyName(resolved, property) ?? kebabCase(property);
|
|
44
45
|
settings.bind(key, resolved, propertyName, flags);
|
|
45
46
|
|
|
46
47
|
return () => {
|
|
47
48
|
Gio.Settings.unbind(resolved, propertyName);
|
|
48
49
|
};
|
|
49
|
-
}, [settings, key, object,
|
|
50
|
+
}, [settings, key, object, property, flags]);
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
export { useBindSetting };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type * as GObject from "@gtkx/gi/gobject";
|
|
2
2
|
import { kebabCase } from "@gtkx/utils";
|
|
3
|
-
import
|
|
3
|
+
import { getPropertyName } from "../reconciler/metadata.js";
|
|
4
|
+
import { type RefProp, resolveRefProp } from "../utils/ref-prop.js";
|
|
4
5
|
import { useObjectValue } from "./use-object-value.js";
|
|
5
6
|
|
|
6
7
|
/** The property map `T` declares, from camelCase property name to value type. */
|
|
@@ -18,7 +19,10 @@ function useProperty<T extends GObject.Object, P extends PropertyName<T>>(
|
|
|
18
19
|
object: RefProp<T>,
|
|
19
20
|
propertyName: P & string,
|
|
20
21
|
): T[P] | undefined {
|
|
21
|
-
|
|
22
|
+
const resolved = resolveRefProp(object);
|
|
23
|
+
const name = (resolved === null ? undefined : getPropertyName(resolved, propertyName)) ?? kebabCase(propertyName);
|
|
24
|
+
|
|
25
|
+
return useObjectValue(object, `notify::${name}`, (obj) => obj?.[propertyName]);
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
export { useProperty };
|