@gtkx/cli 0.13.0 → 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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gtkx/cli",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.1",
|
|
4
4
|
"description": "CLI for GTKX - create and develop GTK4 React applications",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"gtkx",
|
|
@@ -58,19 +58,19 @@
|
|
|
58
58
|
"ejs": "^3.1.10",
|
|
59
59
|
"react-refresh": "^0.18.0",
|
|
60
60
|
"vite": "^7.3.1",
|
|
61
|
-
"@gtkx/ffi": "0.13.
|
|
62
|
-
"@gtkx/mcp": "0.13.
|
|
63
|
-
"@gtkx/react": "0.13.
|
|
61
|
+
"@gtkx/ffi": "0.13.1",
|
|
62
|
+
"@gtkx/mcp": "0.13.1",
|
|
63
|
+
"@gtkx/react": "0.13.1"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@types/ejs": "^3.1.5",
|
|
67
67
|
"@types/react-refresh": "^0.14.7",
|
|
68
68
|
"memfs": "^4.51.1",
|
|
69
|
-
"@gtkx/testing": "0.13.
|
|
69
|
+
"@gtkx/testing": "0.13.1"
|
|
70
70
|
},
|
|
71
71
|
"peerDependencies": {
|
|
72
72
|
"react": "^19",
|
|
73
|
-
"@gtkx/testing": "0.13.
|
|
73
|
+
"@gtkx/testing": "0.13.1"
|
|
74
74
|
},
|
|
75
75
|
"peerDependenciesMeta": {
|
|
76
76
|
"@gtkx/testing": {
|
|
@@ -497,3 +497,144 @@ const CardDemo = () => (
|
|
|
497
497
|
</GtkBox>
|
|
498
498
|
);
|
|
499
499
|
```
|
|
500
|
+
|
|
501
|
+
---
|
|
502
|
+
|
|
503
|
+
## Navigation with AdwNavigationView
|
|
504
|
+
|
|
505
|
+
```tsx
|
|
506
|
+
import * as Gtk from "@gtkx/ffi/gtk";
|
|
507
|
+
import {
|
|
508
|
+
AdwApplicationWindow,
|
|
509
|
+
AdwHeaderBar,
|
|
510
|
+
AdwNavigationView,
|
|
511
|
+
AdwToolbarView,
|
|
512
|
+
GtkBox,
|
|
513
|
+
GtkButton,
|
|
514
|
+
GtkLabel,
|
|
515
|
+
quit,
|
|
516
|
+
x,
|
|
517
|
+
} from "@gtkx/react";
|
|
518
|
+
import { useState } from "react";
|
|
519
|
+
|
|
520
|
+
const NavigationDemo = () => {
|
|
521
|
+
const [history, setHistory] = useState(["home"]);
|
|
522
|
+
|
|
523
|
+
const push = (page: string) => setHistory([...history, page]);
|
|
524
|
+
const pop = () => setHistory(history.slice(0, -1));
|
|
525
|
+
|
|
526
|
+
return (
|
|
527
|
+
<AdwApplicationWindow title="Navigation Demo" defaultWidth={600} defaultHeight={400} onClose={quit}>
|
|
528
|
+
<AdwNavigationView history={history} onHistoryChanged={setHistory}>
|
|
529
|
+
<x.NavigationPage id="home" title="Home">
|
|
530
|
+
<AdwToolbarView>
|
|
531
|
+
<x.ToolbarTop><AdwHeaderBar /></x.ToolbarTop>
|
|
532
|
+
<GtkBox orientation={Gtk.Orientation.VERTICAL} spacing={12} halign={Gtk.Align.CENTER} valign={Gtk.Align.CENTER}>
|
|
533
|
+
<GtkLabel label="Welcome!" cssClasses={["title-1"]} />
|
|
534
|
+
<GtkButton label="Go to Settings" onClicked={() => push("settings")} cssClasses={["suggested-action"]} />
|
|
535
|
+
</GtkBox>
|
|
536
|
+
</AdwToolbarView>
|
|
537
|
+
</x.NavigationPage>
|
|
538
|
+
<x.NavigationPage id="settings" title="Settings" canPop>
|
|
539
|
+
<AdwToolbarView>
|
|
540
|
+
<x.ToolbarTop><AdwHeaderBar /></x.ToolbarTop>
|
|
541
|
+
<GtkLabel label="Settings page content" vexpand />
|
|
542
|
+
</AdwToolbarView>
|
|
543
|
+
</x.NavigationPage>
|
|
544
|
+
</AdwNavigationView>
|
|
545
|
+
</AdwApplicationWindow>
|
|
546
|
+
);
|
|
547
|
+
};
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
---
|
|
551
|
+
|
|
552
|
+
## File Browser with TreeListView
|
|
553
|
+
|
|
554
|
+
```tsx
|
|
555
|
+
import * as Gtk from "@gtkx/ffi/gtk";
|
|
556
|
+
import { GtkBox, GtkImage, GtkLabel, GtkScrolledWindow, x } from "@gtkx/react";
|
|
557
|
+
import { useState } from "react";
|
|
558
|
+
|
|
559
|
+
interface FileNode {
|
|
560
|
+
id: string;
|
|
561
|
+
name: string;
|
|
562
|
+
isDirectory: boolean;
|
|
563
|
+
children?: FileNode[];
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
const files: FileNode[] = [
|
|
567
|
+
{
|
|
568
|
+
id: "src",
|
|
569
|
+
name: "src",
|
|
570
|
+
isDirectory: true,
|
|
571
|
+
children: [
|
|
572
|
+
{ id: "src/app.tsx", name: "app.tsx", isDirectory: false },
|
|
573
|
+
{ id: "src/index.tsx", name: "index.tsx", isDirectory: false },
|
|
574
|
+
],
|
|
575
|
+
},
|
|
576
|
+
{ id: "package.json", name: "package.json", isDirectory: false },
|
|
577
|
+
];
|
|
578
|
+
|
|
579
|
+
const FileBrowser = () => {
|
|
580
|
+
const [selected, setSelected] = useState<string | null>(null);
|
|
581
|
+
|
|
582
|
+
return (
|
|
583
|
+
<GtkScrolledWindow vexpand cssClasses={["card"]}>
|
|
584
|
+
<x.TreeListView<FileNode>
|
|
585
|
+
estimatedItemHeight={36}
|
|
586
|
+
vexpand
|
|
587
|
+
autoexpand={false}
|
|
588
|
+
selectionMode={Gtk.SelectionMode.SINGLE}
|
|
589
|
+
selected={selected ? [selected] : []}
|
|
590
|
+
onSelectionChanged={(ids) => setSelected(ids[0] ?? null)}
|
|
591
|
+
renderItem={(item) => (
|
|
592
|
+
<GtkBox orientation={Gtk.Orientation.HORIZONTAL} spacing={8}>
|
|
593
|
+
<GtkImage iconName={item?.isDirectory ? "folder-symbolic" : "text-x-generic-symbolic"} />
|
|
594
|
+
<GtkLabel label={item?.name ?? ""} halign={Gtk.Align.START} />
|
|
595
|
+
</GtkBox>
|
|
596
|
+
)}
|
|
597
|
+
>
|
|
598
|
+
{files.map((file) => (
|
|
599
|
+
<x.TreeListItem key={file.id} id={file.id} value={file}>
|
|
600
|
+
{file.children?.map((child) => (
|
|
601
|
+
<x.TreeListItem key={child.id} id={child.id} value={child} />
|
|
602
|
+
))}
|
|
603
|
+
</x.TreeListItem>
|
|
604
|
+
))}
|
|
605
|
+
</x.TreeListView>
|
|
606
|
+
</GtkScrolledWindow>
|
|
607
|
+
);
|
|
608
|
+
};
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
---
|
|
612
|
+
|
|
613
|
+
## Toggle Group View Switcher
|
|
614
|
+
|
|
615
|
+
```tsx
|
|
616
|
+
import * as Gtk from "@gtkx/ffi/gtk";
|
|
617
|
+
import { AdwToggleGroup, GtkBox, GtkLabel, GtkStack, x } from "@gtkx/react";
|
|
618
|
+
import { useState } from "react";
|
|
619
|
+
|
|
620
|
+
const ViewSwitcher = () => {
|
|
621
|
+
const [view, setView] = useState("list");
|
|
622
|
+
|
|
623
|
+
return (
|
|
624
|
+
<GtkBox orientation={Gtk.Orientation.VERTICAL} spacing={12}>
|
|
625
|
+
<AdwToggleGroup active={view} onToggled={setView} halign={Gtk.Align.CENTER}>
|
|
626
|
+
<x.Toggle id="list" iconName="view-list-symbolic" tooltip="List view" />
|
|
627
|
+
<x.Toggle id="grid" iconName="view-grid-symbolic" tooltip="Grid view" />
|
|
628
|
+
</AdwToggleGroup>
|
|
629
|
+
<GtkStack page={view} vexpand>
|
|
630
|
+
<x.StackPage id="list">
|
|
631
|
+
<GtkLabel label="List View Content" />
|
|
632
|
+
</x.StackPage>
|
|
633
|
+
<x.StackPage id="grid">
|
|
634
|
+
<GtkLabel label="Grid View Content" />
|
|
635
|
+
</x.StackPage>
|
|
636
|
+
</GtkStack>
|
|
637
|
+
</GtkBox>
|
|
638
|
+
);
|
|
639
|
+
};
|
|
640
|
+
```
|
|
@@ -181,6 +181,36 @@ Selection dropdown.
|
|
|
181
181
|
</GtkDropDown>
|
|
182
182
|
```
|
|
183
183
|
|
|
184
|
+
### TreeListView
|
|
185
|
+
Hierarchical tree with expand/collapse.
|
|
186
|
+
|
|
187
|
+
```tsx
|
|
188
|
+
<x.TreeListView<FileNode>
|
|
189
|
+
estimatedItemHeight={48}
|
|
190
|
+
vexpand
|
|
191
|
+
autoexpand={false}
|
|
192
|
+
selectionMode={Gtk.SelectionMode.SINGLE}
|
|
193
|
+
selected={selectedId ? [selectedId] : []}
|
|
194
|
+
onSelectionChanged={(ids) => setSelectedId(ids[0])}
|
|
195
|
+
renderItem={(item, row) => (
|
|
196
|
+
<GtkBox orientation={Gtk.Orientation.HORIZONTAL} spacing={8}>
|
|
197
|
+
<GtkImage iconName={item?.isDirectory ? "folder-symbolic" : "text-x-generic-symbolic"} />
|
|
198
|
+
<GtkLabel label={item?.name ?? ""} />
|
|
199
|
+
</GtkBox>
|
|
200
|
+
)}
|
|
201
|
+
>
|
|
202
|
+
{files.map(file => (
|
|
203
|
+
<x.TreeListItem key={file.id} id={file.id} value={file}>
|
|
204
|
+
{file.children?.map(child => (
|
|
205
|
+
<x.TreeListItem key={child.id} id={child.id} value={child} />
|
|
206
|
+
))}
|
|
207
|
+
</x.TreeListItem>
|
|
208
|
+
))}
|
|
209
|
+
</x.TreeListView>
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
**TreeListItem props:** `id`, `value`, `indentForDepth`, `indentForIcon`, `hideExpander`, nested `children`
|
|
213
|
+
|
|
184
214
|
---
|
|
185
215
|
|
|
186
216
|
## Inputs
|
|
@@ -221,6 +251,44 @@ Numeric input with increment/decrement.
|
|
|
221
251
|
<GtkSpinButton value={count} onValueChanged={(sb) => setCount(sb.getValue())} />
|
|
222
252
|
```
|
|
223
253
|
|
|
254
|
+
### GtkScale
|
|
255
|
+
Slider with optional marks.
|
|
256
|
+
|
|
257
|
+
```tsx
|
|
258
|
+
<GtkScale
|
|
259
|
+
orientation={Gtk.Orientation.HORIZONTAL}
|
|
260
|
+
drawValue
|
|
261
|
+
valuePos={Gtk.PositionType.TOP}
|
|
262
|
+
>
|
|
263
|
+
<x.ScaleMark value={0} label="Min" />
|
|
264
|
+
<x.ScaleMark value={50} />
|
|
265
|
+
<x.ScaleMark value={100} label="Max" />
|
|
266
|
+
</GtkScale>
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
**ScaleMark props:** `value` (required), `position`, `label`
|
|
270
|
+
|
|
271
|
+
### GtkCalendar
|
|
272
|
+
Date picker with markable days.
|
|
273
|
+
|
|
274
|
+
```tsx
|
|
275
|
+
<GtkCalendar onDaySelected={(cal) => setDate(cal.getDate())}>
|
|
276
|
+
<x.CalendarMark day={15} />
|
|
277
|
+
<x.CalendarMark day={20} />
|
|
278
|
+
</GtkCalendar>
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### GtkLevelBar
|
|
282
|
+
Progress/level indicator with customizable thresholds.
|
|
283
|
+
|
|
284
|
+
```tsx
|
|
285
|
+
<GtkLevelBar value={0.6}>
|
|
286
|
+
<x.LevelBarOffset id="low" value={0.25} />
|
|
287
|
+
<x.LevelBarOffset id="high" value={0.75} />
|
|
288
|
+
<x.LevelBarOffset id="full" value={1.0} />
|
|
289
|
+
</GtkLevelBar>
|
|
290
|
+
```
|
|
291
|
+
|
|
224
292
|
---
|
|
225
293
|
|
|
226
294
|
## Display
|
|
@@ -375,24 +443,36 @@ Settings UI.
|
|
|
375
443
|
<AdwPreferencesGroup title="Appearance" description="Customize look">
|
|
376
444
|
<AdwSwitchRow title="Dark Mode" active={dark} onActivated={() => setDark(!dark)} />
|
|
377
445
|
<AdwActionRow title="Theme" subtitle="Select color">
|
|
378
|
-
<x.
|
|
446
|
+
<x.ActionRowPrefix>
|
|
447
|
+
<GtkImage iconName="preferences-color-symbolic" />
|
|
448
|
+
</x.ActionRowPrefix>
|
|
449
|
+
<x.ActionRowSuffix>
|
|
379
450
|
<GtkImage iconName="go-next-symbolic" valign={Gtk.Align.CENTER} />
|
|
380
|
-
</x.
|
|
451
|
+
</x.ActionRowSuffix>
|
|
381
452
|
</AdwActionRow>
|
|
382
453
|
</AdwPreferencesGroup>
|
|
383
454
|
</AdwPreferencesPage>
|
|
384
455
|
```
|
|
385
456
|
|
|
457
|
+
**ActionRow children:** Use `x.ActionRowPrefix` for left widgets, `x.ActionRowSuffix` for right widgets, or `x.Slot for={AdwActionRow} id="activatableWidget"` for clickable suffix.
|
|
458
|
+
|
|
386
459
|
### AdwExpanderRow
|
|
387
|
-
Expandable settings row.
|
|
460
|
+
Expandable settings row with optional action widget.
|
|
388
461
|
|
|
389
462
|
```tsx
|
|
390
463
|
<AdwExpanderRow title="Advanced" subtitle="More options">
|
|
391
|
-
<
|
|
392
|
-
|
|
464
|
+
<x.ExpanderRowAction>
|
|
465
|
+
<GtkButton iconName="emblem-system-symbolic" cssClasses={["flat"]} />
|
|
466
|
+
</x.ExpanderRowAction>
|
|
467
|
+
<x.ExpanderRowRow>
|
|
468
|
+
<AdwSwitchRow title="Option 1" active />
|
|
469
|
+
<AdwSwitchRow title="Option 2" active={false} />
|
|
470
|
+
</x.ExpanderRowRow>
|
|
393
471
|
</AdwExpanderRow>
|
|
394
472
|
```
|
|
395
473
|
|
|
474
|
+
**ExpanderRow slots:** `x.ExpanderRowRow` for nested rows, `x.ExpanderRowAction` for header action widget. Direct children also work for simple cases.
|
|
475
|
+
|
|
396
476
|
### AdwEntryRow / AdwPasswordEntryRow
|
|
397
477
|
Input in list row.
|
|
398
478
|
|
|
@@ -401,6 +481,37 @@ Input in list row.
|
|
|
401
481
|
<AdwPasswordEntryRow title="Password" />
|
|
402
482
|
```
|
|
403
483
|
|
|
484
|
+
### AdwToggleGroup
|
|
485
|
+
Segmented button group for mutually exclusive options.
|
|
486
|
+
|
|
487
|
+
```tsx
|
|
488
|
+
<AdwToggleGroup active={viewMode} onToggled={setViewMode}>
|
|
489
|
+
<x.Toggle id="list" iconName="view-list-symbolic" tooltip="List view" />
|
|
490
|
+
<x.Toggle id="grid" iconName="view-grid-symbolic" tooltip="Grid view" />
|
|
491
|
+
<x.Toggle id="flow" label="Flow" />
|
|
492
|
+
</AdwToggleGroup>
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
**Toggle props:** `id` (optional), `label`, `iconName`, `tooltip`, `enabled`
|
|
496
|
+
|
|
497
|
+
### AdwNavigationView
|
|
498
|
+
Stack-based navigation with history.
|
|
499
|
+
|
|
500
|
+
```tsx
|
|
501
|
+
const [history, setHistory] = useState(["home"]);
|
|
502
|
+
|
|
503
|
+
<AdwNavigationView history={history} onHistoryChanged={setHistory}>
|
|
504
|
+
<x.NavigationPage id="home" title="Home">
|
|
505
|
+
<GtkButton label="Go to Details" onClicked={() => setHistory([...history, "details"])} />
|
|
506
|
+
</x.NavigationPage>
|
|
507
|
+
<x.NavigationPage id="details" title="Details" canPop>
|
|
508
|
+
<GtkLabel label="Details content" />
|
|
509
|
+
</x.NavigationPage>
|
|
510
|
+
</AdwNavigationView>
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
**NavigationPage props:** `id` (required), `title`, `canPop`. Control navigation via `history` array.
|
|
514
|
+
|
|
404
515
|
### Other Adwaita Widgets
|
|
405
516
|
|
|
406
517
|
| Widget | Description |
|