@gtkx/cli 0.13.0 → 0.13.2

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.0",
3
+ "version": "0.13.2",
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.0",
62
- "@gtkx/mcp": "0.13.0",
63
- "@gtkx/react": "0.13.0"
61
+ "@gtkx/ffi": "0.13.2",
62
+ "@gtkx/mcp": "0.13.2",
63
+ "@gtkx/react": "0.13.2"
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.0"
69
+ "@gtkx/testing": "0.13.2"
70
70
  },
71
71
  "peerDependencies": {
72
72
  "react": "^19",
73
- "@gtkx/testing": "0.13.0"
73
+ "@gtkx/testing": "0.13.2"
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.Slot for={AdwActionRow} id="activatableWidget">
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.Slot>
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
- <AdwSwitchRow title="Option 1" active />
392
- <AdwSwitchRow title="Option 2" active={false} />
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 |