@gtkx/cli 0.21.0 → 1.0.0-rc.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/README.md +173 -0
- package/bin/gtkx-dev-runner.js +9 -0
- package/dist/builder.d.ts +5 -52
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +24 -57
- package/dist/builder.js.map +1 -1
- package/dist/cli.d.ts +1 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +24 -122
- package/dist/cli.js.map +1 -1
- package/dist/codegen/freshness.d.ts +11 -0
- package/dist/codegen/freshness.d.ts.map +1 -0
- package/dist/codegen/freshness.js +45 -0
- package/dist/codegen/freshness.js.map +1 -0
- package/dist/codegen/report.d.ts +4 -0
- package/dist/codegen/report.d.ts.map +1 -0
- package/dist/codegen/report.js +18 -0
- package/dist/codegen/report.js.map +1 -0
- package/dist/codegen/run-codegen.d.ts +35 -0
- package/dist/codegen/run-codegen.d.ts.map +1 -0
- package/dist/codegen/run-codegen.js +162 -0
- package/dist/codegen/run-codegen.js.map +1 -0
- package/dist/codegen/store-resolver.d.ts +24 -0
- package/dist/codegen/store-resolver.d.ts.map +1 -0
- package/dist/codegen/store-resolver.js +72 -0
- package/dist/codegen/store-resolver.js.map +1 -0
- package/dist/commands/build.d.ts +10 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +34 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/codegen.d.ts +10 -0
- package/dist/commands/codegen.d.ts.map +1 -0
- package/dist/commands/codegen.js +42 -0
- package/dist/commands/codegen.js.map +1 -0
- package/dist/commands/dev.d.ts +6 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +22 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/docs.d.ts +20 -0
- package/dist/commands/docs.d.ts.map +1 -0
- package/dist/commands/docs.js +74 -0
- package/dist/commands/docs.js.map +1 -0
- package/dist/dev/icon-dir.d.ts +3 -0
- package/dist/dev/icon-dir.d.ts.map +1 -0
- package/dist/dev/icon-dir.js +16 -0
- package/dist/dev/icon-dir.js.map +1 -0
- package/dist/dev/refresh-tracker.d.ts +7 -0
- package/dist/dev/refresh-tracker.d.ts.map +1 -0
- package/dist/dev/refresh-tracker.js +19 -0
- package/dist/dev/refresh-tracker.js.map +1 -0
- package/dist/dev/runner-deps.d.ts +4 -0
- package/dist/dev/runner-deps.d.ts.map +1 -0
- package/dist/dev/runner-deps.js +55 -0
- package/dist/dev/runner-deps.js.map +1 -0
- package/dist/dev/runner-main.d.ts +3 -0
- package/dist/dev/runner-main.d.ts.map +1 -0
- package/dist/dev/runner-main.js +29 -0
- package/dist/dev/runner-main.js.map +1 -0
- package/dist/dev/runner.d.ts +24 -0
- package/dist/dev/runner.d.ts.map +1 -0
- package/dist/dev/runner.js +119 -0
- package/dist/dev/runner.js.map +1 -0
- package/dist/dev/schema-dir.d.ts +3 -0
- package/dist/dev/schema-dir.d.ts.map +1 -0
- package/dist/dev/schema-dir.js +12 -0
- package/dist/dev/schema-dir.js.map +1 -0
- package/dist/dev/supervisor.d.ts +18 -0
- package/dist/dev/supervisor.d.ts.map +1 -0
- package/dist/dev/supervisor.js +182 -0
- package/dist/dev/supervisor.js.map +1 -0
- package/dist/dev/vite-dev-server.d.ts +21 -0
- package/dist/dev/vite-dev-server.d.ts.map +1 -0
- package/dist/dev/vite-dev-server.js +13 -0
- package/dist/dev/vite-dev-server.js.map +1 -0
- package/dist/internal/banner.d.ts +4 -0
- package/dist/internal/banner.d.ts.map +1 -0
- package/dist/internal/banner.js +9 -0
- package/dist/internal/banner.js.map +1 -0
- package/dist/internal/data-dir.d.ts +4 -0
- package/dist/internal/data-dir.d.ts.map +1 -0
- package/dist/internal/data-dir.js +52 -0
- package/dist/internal/data-dir.js.map +1 -0
- package/dist/internal/entry-arg.d.ts +20 -0
- package/dist/internal/entry-arg.d.ts.map +1 -0
- package/dist/internal/entry-arg.js +36 -0
- package/dist/internal/entry-arg.js.map +1 -0
- package/dist/internal/errors.d.ts +5 -0
- package/dist/internal/errors.d.ts.map +1 -0
- package/dist/internal/errors.js +29 -0
- package/dist/internal/errors.js.map +1 -0
- package/dist/internal/list-files.d.ts +7 -0
- package/dist/internal/list-files.d.ts.map +1 -0
- package/dist/internal/list-files.js +15 -0
- package/dist/internal/list-files.js.map +1 -0
- package/dist/internal/resolve-cli-tool.d.ts +3 -0
- package/dist/internal/resolve-cli-tool.d.ts.map +1 -0
- package/dist/internal/resolve-cli-tool.js +27 -0
- package/dist/internal/resolve-cli-tool.js.map +1 -0
- package/dist/internal/staging-dir.d.ts +4 -0
- package/dist/internal/staging-dir.d.ts.map +1 -0
- package/dist/internal/staging-dir.js +17 -0
- package/dist/internal/staging-dir.js.map +1 -0
- package/dist/internal/xdg-data-dirs.d.ts +3 -0
- package/dist/internal/xdg-data-dirs.d.ts.map +1 -0
- package/dist/internal/xdg-data-dirs.js +10 -0
- package/dist/internal/xdg-data-dirs.js.map +1 -0
- package/dist/mcp/client.d.ts +28 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +182 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/handlers.d.ts +9 -0
- package/dist/mcp/handlers.d.ts.map +1 -0
- package/dist/mcp/handlers.js +147 -0
- package/dist/mcp/handlers.js.map +1 -0
- package/dist/mcp/index.d.ts +4 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +34 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/serialize-widget.d.ts +10 -0
- package/dist/mcp/serialize-widget.d.ts.map +1 -0
- package/dist/mcp/serialize-widget.js +23 -0
- package/dist/mcp/serialize-widget.js.map +1 -0
- package/dist/mcp/testing-loader.d.ts +5 -0
- package/dist/mcp/testing-loader.d.ts.map +1 -0
- package/dist/mcp/testing-loader.js +47 -0
- package/dist/mcp/testing-loader.js.map +1 -0
- package/dist/mcp/widget-registry.d.ts +14 -0
- package/dist/mcp/widget-registry.d.ts.map +1 -0
- package/dist/mcp/widget-registry.js +39 -0
- package/dist/mcp/widget-registry.js.map +1 -0
- package/dist/refresh-globals.d.ts +2 -0
- package/dist/refresh-globals.d.ts.map +1 -0
- package/dist/refresh-globals.js +8 -0
- package/dist/refresh-globals.js.map +1 -0
- package/dist/refresh-runtime.d.ts +10 -26
- package/dist/refresh-runtime.d.ts.map +1 -1
- package/dist/refresh-runtime.js +26 -48
- package/dist/refresh-runtime.js.map +1 -1
- package/dist/settings/compile.d.ts +3 -0
- package/dist/settings/compile.d.ts.map +1 -0
- package/dist/settings/compile.js +21 -0
- package/dist/settings/compile.js.map +1 -0
- package/dist/settings/parser.d.ts +24 -0
- package/dist/settings/parser.d.ts.map +1 -0
- package/dist/settings/parser.js +121 -0
- package/dist/settings/parser.js.map +1 -0
- package/dist/settings/render.d.ts +5 -0
- package/dist/settings/render.d.ts.map +1 -0
- package/dist/settings/render.js +122 -0
- package/dist/settings/render.js.map +1 -0
- package/dist/settings/schema.d.ts +13 -0
- package/dist/settings/schema.d.ts.map +1 -0
- package/dist/settings/schema.js +121 -0
- package/dist/settings/schema.js.map +1 -0
- package/dist/vite-plugins/asset-extensions.d.ts +5 -0
- package/dist/vite-plugins/asset-extensions.d.ts.map +1 -0
- package/dist/vite-plugins/asset-extensions.js +28 -0
- package/dist/vite-plugins/asset-extensions.js.map +1 -0
- package/dist/vite-plugins/built-url.d.ts +4 -0
- package/dist/vite-plugins/built-url.d.ts.map +1 -0
- package/dist/vite-plugins/built-url.js +36 -0
- package/dist/vite-plugins/built-url.js.map +1 -0
- package/dist/vite-plugins/css.d.ts +4 -0
- package/dist/vite-plugins/css.d.ts.map +1 -0
- package/dist/vite-plugins/css.js +38 -0
- package/dist/vite-plugins/css.js.map +1 -0
- package/dist/vite-plugins/fast-refresh/refresh-filter.d.ts +8 -0
- package/dist/vite-plugins/fast-refresh/refresh-filter.d.ts.map +1 -0
- package/dist/vite-plugins/fast-refresh/refresh-filter.js +19 -0
- package/dist/vite-plugins/fast-refresh/refresh-filter.js.map +1 -0
- package/dist/vite-plugins/fast-refresh/swc-refresh.d.ts +6 -0
- package/dist/vite-plugins/fast-refresh/swc-refresh.d.ts.map +1 -0
- package/dist/vite-plugins/fast-refresh/swc-refresh.js +70 -0
- package/dist/vite-plugins/fast-refresh/swc-refresh.js.map +1 -0
- package/dist/vite-plugins/icons.d.ts +4 -0
- package/dist/vite-plugins/icons.d.ts.map +1 -0
- package/dist/vite-plugins/icons.js +51 -0
- package/dist/vite-plugins/icons.js.map +1 -0
- package/dist/vite-plugins/index.d.ts +4 -0
- package/dist/vite-plugins/index.d.ts.map +1 -0
- package/dist/vite-plugins/index.js +22 -0
- package/dist/vite-plugins/index.js.map +1 -0
- package/dist/vite-plugins/native.d.ts +4 -0
- package/dist/vite-plugins/native.d.ts.map +1 -0
- package/dist/vite-plugins/native.js +62 -0
- package/dist/vite-plugins/native.js.map +1 -0
- package/dist/vite-plugins/react-compiler.d.ts +5 -0
- package/dist/vite-plugins/react-compiler.d.ts.map +1 -0
- package/dist/vite-plugins/react-compiler.js +62 -0
- package/dist/vite-plugins/react-compiler.js.map +1 -0
- package/dist/vite-plugins/react-dom-prebundle.d.ts +4 -0
- package/dist/vite-plugins/react-dom-prebundle.d.ts.map +1 -0
- package/dist/vite-plugins/react-dom-prebundle.js +12 -0
- package/dist/vite-plugins/react-dom-prebundle.js.map +1 -0
- package/dist/vite-plugins/resource-init-module.d.ts +6 -0
- package/dist/vite-plugins/resource-init-module.d.ts.map +1 -0
- package/dist/vite-plugins/resource-init-module.js +51 -0
- package/dist/vite-plugins/resource-init-module.js.map +1 -0
- package/dist/vite-plugins/resource-shared.d.ts +8 -0
- package/dist/vite-plugins/resource-shared.d.ts.map +1 -0
- package/dist/vite-plugins/resource-shared.js +28 -0
- package/dist/vite-plugins/resource-shared.js.map +1 -0
- package/dist/vite-plugins/resources.d.ts +5 -0
- package/dist/vite-plugins/resources.d.ts.map +1 -0
- package/dist/vite-plugins/resources.js +260 -0
- package/dist/vite-plugins/resources.js.map +1 -0
- package/dist/vite-plugins/settings-worker-env.d.ts +4 -0
- package/dist/vite-plugins/settings-worker-env.d.ts.map +1 -0
- package/dist/vite-plugins/settings-worker-env.js +23 -0
- package/dist/vite-plugins/settings-worker-env.js.map +1 -0
- package/dist/vite-plugins/settings.d.ts +4 -0
- package/dist/vite-plugins/settings.d.ts.map +1 -0
- package/dist/vite-plugins/settings.js +214 -0
- package/dist/vite-plugins/settings.js.map +1 -0
- package/dist/vite-plugins/strip-query.d.ts +3 -0
- package/dist/vite-plugins/strip-query.d.ts.map +1 -0
- package/dist/vite-plugins/strip-query.js +6 -0
- package/dist/vite-plugins/strip-query.js.map +1 -0
- package/dist/vite-plugins/undeclared-library.d.ts +4 -0
- package/dist/vite-plugins/undeclared-library.d.ts.map +1 -0
- package/dist/vite-plugins/undeclared-library.js +50 -0
- package/dist/vite-plugins/undeclared-library.js.map +1 -0
- package/dist/vite-plugins/virtual-module.d.ts +22 -0
- package/dist/vite-plugins/virtual-module.d.ts.map +1 -0
- package/dist/vite-plugins/virtual-module.js +20 -0
- package/dist/vite-plugins/virtual-module.js.map +1 -0
- package/dist/vitest-plugin.d.ts +10 -0
- package/dist/vitest-plugin.d.ts.map +1 -0
- package/dist/vitest-plugin.js +12 -0
- package/dist/vitest-plugin.js.map +1 -0
- package/env.d.ts +91 -8
- package/package.json +30 -38
- package/src/babel-modules.d.ts +11 -0
- package/src/builder.ts +31 -86
- package/src/cli.ts +42 -0
- package/src/codegen/freshness.ts +65 -0
- package/src/codegen/report.ts +28 -0
- package/src/codegen/run-codegen.ts +260 -0
- package/src/codegen/store-resolver.ts +116 -0
- package/src/commands/build.ts +38 -0
- package/src/commands/codegen.ts +49 -0
- package/src/commands/dev.ts +24 -0
- package/src/commands/docs.ts +95 -0
- package/src/dev/icon-dir.ts +21 -0
- package/src/dev/refresh-tracker.ts +25 -0
- package/src/dev/runner-deps.ts +65 -0
- package/src/dev/runner-main.ts +34 -0
- package/src/dev/runner.ts +185 -0
- package/src/dev/schema-dir.ts +16 -0
- package/src/dev/supervisor.ts +276 -0
- package/src/dev/vite-dev-server.ts +36 -0
- package/src/internal/banner.ts +13 -0
- package/src/internal/data-dir.ts +70 -0
- package/src/internal/entry-arg.ts +46 -0
- package/src/internal/errors.ts +36 -0
- package/src/internal/list-files.ts +23 -0
- package/src/internal/resolve-cli-tool.ts +37 -0
- package/src/internal/staging-dir.ts +19 -0
- package/src/internal/xdg-data-dirs.ts +13 -0
- package/src/mcp/client.ts +235 -0
- package/src/mcp/handlers.ts +213 -0
- package/src/mcp/index.ts +46 -0
- package/src/mcp/serialize-widget.ts +41 -0
- package/src/mcp/testing-loader.ts +73 -0
- package/src/mcp/widget-registry.ts +49 -0
- package/src/refresh-globals.ts +10 -0
- package/src/refresh-runtime.ts +30 -55
- package/src/settings/compile.ts +22 -0
- package/src/settings/parser.ts +193 -0
- package/src/settings/render.ts +167 -0
- package/src/settings/schema.ts +169 -0
- package/src/vite-plugins/asset-extensions.ts +29 -0
- package/src/vite-plugins/built-url.ts +50 -0
- package/src/vite-plugins/css.ts +53 -0
- package/src/vite-plugins/fast-refresh/refresh-filter.ts +26 -0
- package/src/vite-plugins/fast-refresh/swc-refresh.ts +92 -0
- package/src/vite-plugins/icons.ts +74 -0
- package/src/vite-plugins/index.ts +25 -0
- package/src/vite-plugins/native.ts +83 -0
- package/src/vite-plugins/react-compiler.ts +84 -0
- package/src/vite-plugins/react-dom-prebundle.ts +17 -0
- package/src/vite-plugins/resource-init-module.ts +57 -0
- package/src/vite-plugins/resource-shared.ts +40 -0
- package/src/vite-plugins/resources.ts +366 -0
- package/src/vite-plugins/settings-worker-env.ts +30 -0
- package/src/vite-plugins/settings.ts +286 -0
- package/src/vite-plugins/strip-query.ts +7 -0
- package/src/vite-plugins/undeclared-library.ts +78 -0
- package/src/vite-plugins/virtual-module.ts +44 -0
- package/src/vitest-plugin.ts +13 -0
- package/dist/create.d.ts +0 -55
- package/dist/create.d.ts.map +0 -1
- package/dist/create.js +0 -236
- package/dist/create.js.map +0 -1
- package/dist/dev-server.d.ts +0 -37
- package/dist/dev-server.d.ts.map +0 -1
- package/dist/dev-server.js +0 -130
- package/dist/dev-server.js.map +0 -1
- package/dist/index.d.ts +0 -4
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -4
- package/dist/index.js.map +0 -1
- package/dist/mcp-client.d.ts +0 -31
- package/dist/mcp-client.d.ts.map +0 -1
- package/dist/mcp-client.js +0 -430
- package/dist/mcp-client.js.map +0 -1
- package/dist/templates.d.ts +0 -9
- package/dist/templates.d.ts.map +0 -1
- package/dist/templates.js +0 -16
- package/dist/templates.js.map +0 -1
- package/dist/vite-plugin-gtkx-assets.d.ts +0 -20
- package/dist/vite-plugin-gtkx-assets.d.ts.map +0 -1
- package/dist/vite-plugin-gtkx-assets.js +0 -57
- package/dist/vite-plugin-gtkx-assets.js.map +0 -1
- package/dist/vite-plugin-gtkx-built-url.d.ts +0 -18
- package/dist/vite-plugin-gtkx-built-url.d.ts.map +0 -1
- package/dist/vite-plugin-gtkx-built-url.js +0 -43
- package/dist/vite-plugin-gtkx-built-url.js.map +0 -1
- package/dist/vite-plugin-gtkx-gsettings.d.ts +0 -28
- package/dist/vite-plugin-gtkx-gsettings.d.ts.map +0 -1
- package/dist/vite-plugin-gtkx-gsettings.js +0 -147
- package/dist/vite-plugin-gtkx-gsettings.js.map +0 -1
- package/dist/vite-plugin-gtkx-native.d.ts +0 -14
- package/dist/vite-plugin-gtkx-native.d.ts.map +0 -1
- package/dist/vite-plugin-gtkx-native.js +0 -53
- package/dist/vite-plugin-gtkx-native.js.map +0 -1
- package/dist/vite-plugin-gtkx-refresh.d.ts +0 -8
- package/dist/vite-plugin-gtkx-refresh.d.ts.map +0 -1
- package/dist/vite-plugin-gtkx-refresh.js +0 -37
- package/dist/vite-plugin-gtkx-refresh.js.map +0 -1
- package/dist/vite-plugin-swc-ssr-refresh.d.ts +0 -8
- package/dist/vite-plugin-swc-ssr-refresh.d.ts.map +0 -1
- package/dist/vite-plugin-swc-ssr-refresh.js +0 -46
- package/dist/vite-plugin-swc-ssr-refresh.js.map +0 -1
- package/src/cli.tsx +0 -154
- package/src/create.ts +0 -326
- package/src/dev-server.tsx +0 -162
- package/src/index.ts +0 -3
- package/src/mcp-client.ts +0 -518
- package/src/templates.ts +0 -26
- package/src/vite-plugin-gtkx-assets.ts +0 -69
- package/src/vite-plugin-gtkx-built-url.ts +0 -48
- package/src/vite-plugin-gtkx-gsettings.ts +0 -168
- package/src/vite-plugin-gtkx-native.ts +0 -64
- package/src/vite-plugin-gtkx-refresh.ts +0 -54
- package/src/vite-plugin-swc-ssr-refresh.ts +0 -61
- package/templates/claude/EXAMPLES.md.ejs +0 -744
- package/templates/claude/SKILL.md.ejs +0 -93
- package/templates/claude/WIDGETS.md.ejs +0 -820
- package/templates/config/vitest.config.ts.ejs +0 -11
- package/templates/gitignore.ejs +0 -4
- package/templates/package.json.ejs +0 -16
- package/templates/src/app.tsx.ejs +0 -32
- package/templates/src/dev.tsx.ejs +0 -5
- package/templates/src/gtkx-env.d.ts.ejs +0 -1
- package/templates/src/index.tsx.ejs +0 -5
- package/templates/tests/app.test.tsx.ejs +0 -16
- package/templates/tsconfig.json.ejs +0 -14
|
@@ -1,820 +0,0 @@
|
|
|
1
|
-
# GTKX Widget Reference
|
|
2
|
-
|
|
3
|
-
## Common Props (All Widgets)
|
|
4
|
-
|
|
5
|
-
| Prop | Type | Description |
|
|
6
|
-
|------|------|-------------|
|
|
7
|
-
| `hexpand` / `vexpand` | boolean | Expand to fill available space |
|
|
8
|
-
| `halign` / `valign` | `Gtk.Align.START \| CENTER \| END \| FILL` | Alignment |
|
|
9
|
-
| `marginStart/End/Top/Bottom` | number | Margins in pixels |
|
|
10
|
-
| `sensitive` | boolean | Enabled/disabled state |
|
|
11
|
-
| `visible` | boolean | Visibility |
|
|
12
|
-
| `cssClasses` | string[] | CSS classes for styling |
|
|
13
|
-
| `widthRequest` / `heightRequest` | number | Minimum size |
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## Containers
|
|
18
|
-
|
|
19
|
-
### GtkBox
|
|
20
|
-
Linear layout (horizontal or vertical).
|
|
21
|
-
|
|
22
|
-
```tsx
|
|
23
|
-
<GtkBox orientation={Gtk.Orientation.VERTICAL} spacing={12}>
|
|
24
|
-
{children}
|
|
25
|
-
</GtkBox>
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
### GtkGrid
|
|
29
|
-
2D grid with explicit positioning using `GridChild`.
|
|
30
|
-
|
|
31
|
-
```tsx
|
|
32
|
-
<GtkGrid rowSpacing={8} columnSpacing={12}>
|
|
33
|
-
<x.GridChild column={0} row={0}><GtkLabel label="Name:" /></x.GridChild>
|
|
34
|
-
<x.GridChild column={1} row={0}><GtkEntry hexpand /></x.GridChild>
|
|
35
|
-
<x.GridChild column={0} row={1} columnSpan={2}><GtkButton label="Submit" /></x.GridChild>
|
|
36
|
-
</GtkGrid>
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
**GridChild props:** `column`, `row`, `columnSpan`, `rowSpan`
|
|
40
|
-
|
|
41
|
-
### GtkStack
|
|
42
|
-
Page container, shows one child at a time.
|
|
43
|
-
|
|
44
|
-
```tsx
|
|
45
|
-
<GtkStack page="page1" transitionType={Gtk.StackTransitionType.SLIDE_LEFT_RIGHT}>
|
|
46
|
-
<x.StackPage id="page1" title="First" iconName="document-new">
|
|
47
|
-
<Content1 />
|
|
48
|
-
</x.StackPage>
|
|
49
|
-
<x.StackPage id="page2" title="Second">
|
|
50
|
-
<Content2 />
|
|
51
|
-
</x.StackPage>
|
|
52
|
-
</GtkStack>
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
**StackPage props:** `id` (optional), `title`, `iconName`, `needsAttention`, `badgeNumber` (AdwViewStack only)
|
|
56
|
-
|
|
57
|
-
### GtkNotebook
|
|
58
|
-
Tabbed container with visible tabs.
|
|
59
|
-
|
|
60
|
-
```tsx
|
|
61
|
-
<GtkNotebook>
|
|
62
|
-
<x.NotebookPage label="Tab 1"><Content1 /></x.NotebookPage>
|
|
63
|
-
<x.NotebookPage label="Tab 2" tabExpand tabFill><Content2 /></x.NotebookPage>
|
|
64
|
-
</GtkNotebook>
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
Custom tab widget:
|
|
68
|
-
```tsx
|
|
69
|
-
<x.NotebookPage>
|
|
70
|
-
<x.NotebookPageTab>
|
|
71
|
-
<GtkBox spacing={4}>
|
|
72
|
-
<GtkImage iconName="folder-symbolic" />
|
|
73
|
-
<GtkLabel label="Files" />
|
|
74
|
-
</GtkBox>
|
|
75
|
-
</x.NotebookPageTab>
|
|
76
|
-
<Content />
|
|
77
|
-
</x.NotebookPage>
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
**NotebookPage props:** `label`, `tabExpand`, `tabFill`
|
|
81
|
-
|
|
82
|
-
### GtkPaned
|
|
83
|
-
Resizable split with draggable divider. **Requires Slot components.**
|
|
84
|
-
|
|
85
|
-
```tsx
|
|
86
|
-
<GtkPaned position={280} shrinkStartChild={false}>
|
|
87
|
-
<x.Slot for={GtkPaned} id="startChild"><Sidebar /></x.Slot>
|
|
88
|
-
<x.Slot for={GtkPaned} id="endChild"><MainContent /></x.Slot>
|
|
89
|
-
</GtkPaned>
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
### GtkOverlay
|
|
93
|
-
Stack widgets on top of each other. First child is base layer, additional children need `OverlayChild` wrapper. Multiple children supported per overlay.
|
|
94
|
-
|
|
95
|
-
```tsx
|
|
96
|
-
<GtkOverlay>
|
|
97
|
-
<GtkButton label="Notifications" />
|
|
98
|
-
<x.OverlayChild>
|
|
99
|
-
<GtkLabel label="3" cssClasses={["badge"]} halign={Gtk.Align.END} valign={Gtk.Align.START} />
|
|
100
|
-
</x.OverlayChild>
|
|
101
|
-
</GtkOverlay>
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
### GtkFixed
|
|
105
|
-
Absolute positioning with optional 3D transforms. Use `x.FixedChild` wrapper for children.
|
|
106
|
-
|
|
107
|
-
```tsx
|
|
108
|
-
<GtkFixed>
|
|
109
|
-
<x.FixedChild x={20} y={30}>
|
|
110
|
-
<GtkLabel label="Top Left" />
|
|
111
|
-
</x.FixedChild>
|
|
112
|
-
<x.FixedChild x={200} y={100} transform={someGskTransform}>
|
|
113
|
-
<GtkLabel label="Transformed" />
|
|
114
|
-
</x.FixedChild>
|
|
115
|
-
</GtkFixed>
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
**FixedChild props:** `x`, `y` (pixel coordinates), `transform` (optional `Gsk.Transform`)
|
|
119
|
-
|
|
120
|
-
### GtkScrolledWindow
|
|
121
|
-
Scrollable container.
|
|
122
|
-
|
|
123
|
-
```tsx
|
|
124
|
-
<GtkScrolledWindow vexpand hscrollbarPolicy={Gtk.PolicyType.NEVER}>
|
|
125
|
-
<Content />
|
|
126
|
-
</GtkScrolledWindow>
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
---
|
|
130
|
-
|
|
131
|
-
## Virtual Lists
|
|
132
|
-
|
|
133
|
-
All virtual list widgets use an `items` data prop and a `renderItem` function. Items are `{ id: string, value: T }` objects.
|
|
134
|
-
|
|
135
|
-
### GtkListView
|
|
136
|
-
High-performance scrollable list with selection.
|
|
137
|
-
|
|
138
|
-
```tsx
|
|
139
|
-
<GtkListView
|
|
140
|
-
estimatedItemHeight={48}
|
|
141
|
-
vexpand
|
|
142
|
-
selected={selectedId ? [selectedId] : []}
|
|
143
|
-
selectionMode={Gtk.SelectionMode.SINGLE}
|
|
144
|
-
onSelectionChanged={(ids) => setSelectedId(ids[0])}
|
|
145
|
-
items={items.map(item => ({ id: item.id, value: item }))}
|
|
146
|
-
renderItem={(item: Item) => <GtkLabel label={item.name} />}
|
|
147
|
-
/>
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
### GtkGridView
|
|
151
|
-
Grid-based virtual scrolling.
|
|
152
|
-
|
|
153
|
-
```tsx
|
|
154
|
-
<GtkGridView
|
|
155
|
-
estimatedItemHeight={100}
|
|
156
|
-
minColumns={2}
|
|
157
|
-
maxColumns={4}
|
|
158
|
-
items={items.map(item => ({ id: item.id, value: item }))}
|
|
159
|
-
renderItem={(item: Item) => (
|
|
160
|
-
<GtkBox orientation={Gtk.Orientation.VERTICAL}>
|
|
161
|
-
<GtkImage iconName={item.icon} />
|
|
162
|
-
<GtkLabel label={item.name} />
|
|
163
|
-
</GtkBox>
|
|
164
|
-
)}
|
|
165
|
-
/>
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
### GtkColumnView
|
|
169
|
-
Table with sortable columns.
|
|
170
|
-
|
|
171
|
-
```tsx
|
|
172
|
-
<GtkColumnView
|
|
173
|
-
estimatedRowHeight={48}
|
|
174
|
-
sortColumn="name"
|
|
175
|
-
sortOrder={Gtk.SortType.ASCENDING}
|
|
176
|
-
onSortChanged={handleSort}
|
|
177
|
-
items={items.map(item => ({ id: item.id, value: item }))}
|
|
178
|
-
>
|
|
179
|
-
<x.ColumnViewColumn
|
|
180
|
-
title="Name"
|
|
181
|
-
id="name"
|
|
182
|
-
expand
|
|
183
|
-
resizable
|
|
184
|
-
sortable
|
|
185
|
-
renderCell={(item: Item) => <GtkLabel label={item.name} />}
|
|
186
|
-
/>
|
|
187
|
-
<x.ColumnViewColumn
|
|
188
|
-
title="Size"
|
|
189
|
-
id="size"
|
|
190
|
-
fixedWidth={100}
|
|
191
|
-
renderCell={(item: Item) => <GtkLabel label={`${item.size} KB`} />}
|
|
192
|
-
/>
|
|
193
|
-
</GtkColumnView>
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
### GtkDropDown
|
|
197
|
-
Selection dropdown.
|
|
198
|
-
|
|
199
|
-
```tsx
|
|
200
|
-
<GtkDropDown
|
|
201
|
-
selectedId={selectedId}
|
|
202
|
-
onSelectionChanged={setSelectedId}
|
|
203
|
-
items={options.map(opt => ({ id: opt.id, value: opt.label }))}
|
|
204
|
-
/>
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
### GtkListView (tree mode)
|
|
208
|
-
Hierarchical tree with expand/collapse. Items with nested `children` arrays trigger tree behavior.
|
|
209
|
-
|
|
210
|
-
```tsx
|
|
211
|
-
<GtkListView
|
|
212
|
-
estimatedItemHeight={48}
|
|
213
|
-
vexpand
|
|
214
|
-
autoexpand={false}
|
|
215
|
-
selectionMode={Gtk.SelectionMode.SINGLE}
|
|
216
|
-
selected={selectedId ? [selectedId] : []}
|
|
217
|
-
onSelectionChanged={(ids) => setSelectedId(ids[0])}
|
|
218
|
-
items={files.map(file => ({
|
|
219
|
-
id: file.id,
|
|
220
|
-
value: file,
|
|
221
|
-
children: file.children?.map(child => ({ id: child.id, value: child })),
|
|
222
|
-
}))}
|
|
223
|
-
renderItem={(item: FileNode, row) => (
|
|
224
|
-
<GtkBox spacing={8}>
|
|
225
|
-
<GtkImage iconName={item.isDirectory ? "folder-symbolic" : "text-x-generic-symbolic"} />
|
|
226
|
-
<GtkLabel label={item.name} />
|
|
227
|
-
</GtkBox>
|
|
228
|
-
)}
|
|
229
|
-
/>
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
**ListItem data props:** `id`, `value`, `children` (nested items for tree mode), `hideExpander`, `indentForDepth`, `indentForIcon`, `section` (for sectioned lists)
|
|
233
|
-
|
|
234
|
-
---
|
|
235
|
-
|
|
236
|
-
## Inputs
|
|
237
|
-
|
|
238
|
-
### GtkEntry
|
|
239
|
-
Single-line text input. **Requires two-way binding.**
|
|
240
|
-
|
|
241
|
-
```tsx
|
|
242
|
-
const [text, setText] = useState("");
|
|
243
|
-
<GtkEntry text={text} onChanged={(e) => setText(e.getText())} placeholderText="Enter text..." />
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
### GtkToggleButton
|
|
247
|
-
Toggle button. Auto-prevents signal feedback loops.
|
|
248
|
-
|
|
249
|
-
```tsx
|
|
250
|
-
<GtkToggleButton active={isActive} onToggled={() => setIsActive(!isActive)} label="Toggle" />
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
### GtkCheckButton
|
|
254
|
-
Checkbox.
|
|
255
|
-
|
|
256
|
-
```tsx
|
|
257
|
-
<GtkCheckButton active={checked} onToggled={() => setChecked(!checked)} label="Option" />
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
### GtkSwitch
|
|
261
|
-
On/off switch.
|
|
262
|
-
|
|
263
|
-
```tsx
|
|
264
|
-
<GtkSwitch active={enabled} onStateSet={() => { setEnabled(!enabled); return true; }} />
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
### GtkSpinButton
|
|
268
|
-
Numeric input with increment/decrement. Adjustment props are set directly.
|
|
269
|
-
|
|
270
|
-
```tsx
|
|
271
|
-
<GtkSpinButton
|
|
272
|
-
value={count}
|
|
273
|
-
lower={0}
|
|
274
|
-
upper={100}
|
|
275
|
-
stepIncrement={1}
|
|
276
|
-
onValueChanged={setCount}
|
|
277
|
-
/>
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
### GtkScale
|
|
281
|
-
Slider with adjustment props and optional marks.
|
|
282
|
-
|
|
283
|
-
```tsx
|
|
284
|
-
<GtkScale
|
|
285
|
-
drawValue
|
|
286
|
-
valuePos={Gtk.PositionType.TOP}
|
|
287
|
-
value={volume}
|
|
288
|
-
lower={0}
|
|
289
|
-
upper={100}
|
|
290
|
-
stepIncrement={1}
|
|
291
|
-
onValueChanged={setVolume}
|
|
292
|
-
marks={[
|
|
293
|
-
{ value: 0, label: "Min", position: Gtk.PositionType.BOTTOM },
|
|
294
|
-
{ value: 50, position: Gtk.PositionType.BOTTOM },
|
|
295
|
-
{ value: 100, label: "Max", position: Gtk.PositionType.BOTTOM },
|
|
296
|
-
]}
|
|
297
|
-
/>
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
**Adjustment props:** `value`, `lower`, `upper`, `stepIncrement`, `pageIncrement`, `pageSize`, `onValueChanged`
|
|
301
|
-
**ScaleMark type:** `{ value: number, position?: Gtk.PositionType, label?: string }`
|
|
302
|
-
|
|
303
|
-
### GtkCalendar
|
|
304
|
-
Date picker with markable days.
|
|
305
|
-
|
|
306
|
-
```tsx
|
|
307
|
-
<GtkCalendar
|
|
308
|
-
onDaySelected={(cal) => setDate(cal.getDate())}
|
|
309
|
-
markedDays={[15, 20, 25]}
|
|
310
|
-
/>
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
### GtkLevelBar
|
|
314
|
-
Progress/level indicator with customizable thresholds.
|
|
315
|
-
|
|
316
|
-
```tsx
|
|
317
|
-
<GtkLevelBar
|
|
318
|
-
value={0.6}
|
|
319
|
-
offsets={[
|
|
320
|
-
{ id: "low", value: 0.25 },
|
|
321
|
-
{ id: "high", value: 0.75 },
|
|
322
|
-
{ id: "full", value: 1.0 },
|
|
323
|
-
]}
|
|
324
|
-
/>
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
**LevelBarOffset type:** `{ id: string, value: number }`
|
|
328
|
-
|
|
329
|
-
---
|
|
330
|
-
|
|
331
|
-
## Display
|
|
332
|
-
|
|
333
|
-
### GtkLabel
|
|
334
|
-
```tsx
|
|
335
|
-
<GtkLabel label="Text" halign={Gtk.Align.START} wrap useMarkup />
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
### GtkButton
|
|
339
|
-
```tsx
|
|
340
|
-
<GtkButton label="Click" onClicked={handleClick} iconName="document-new-symbolic" />
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
### GtkImage
|
|
344
|
-
```tsx
|
|
345
|
-
<GtkImage iconName="folder-symbolic" pixelSize={48} />
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
---
|
|
349
|
-
|
|
350
|
-
## Header & Action Bars
|
|
351
|
-
|
|
352
|
-
### GtkHeaderBar
|
|
353
|
-
Title bar with packed widgets. Use `x.ContainerSlot` for packing and `x.Slot` for titleWidget.
|
|
354
|
-
|
|
355
|
-
```tsx
|
|
356
|
-
<GtkHeaderBar>
|
|
357
|
-
<x.ContainerSlot for={GtkHeaderBar} id="packStart"><GtkButton iconName="go-previous-symbolic" /></x.ContainerSlot>
|
|
358
|
-
<x.Slot for={GtkHeaderBar} id="titleWidget">
|
|
359
|
-
<GtkLabel label="Title" cssClasses={["title"]} />
|
|
360
|
-
</x.Slot>
|
|
361
|
-
<x.ContainerSlot for={GtkHeaderBar} id="packEnd"><GtkMenuButton iconName="open-menu-symbolic" /></x.ContainerSlot>
|
|
362
|
-
</GtkHeaderBar>
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
### GtkActionBar
|
|
366
|
-
Bottom action bar.
|
|
367
|
-
|
|
368
|
-
```tsx
|
|
369
|
-
<GtkActionBar>
|
|
370
|
-
<x.ContainerSlot for={GtkActionBar} id="packStart"><GtkButton label="Cancel" /></x.ContainerSlot>
|
|
371
|
-
<x.ContainerSlot for={GtkActionBar} id="packEnd"><GtkButton label="Save" cssClasses={["suggested-action"]} /></x.ContainerSlot>
|
|
372
|
-
</GtkActionBar>
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
---
|
|
376
|
-
|
|
377
|
-
## Menus
|
|
378
|
-
|
|
379
|
-
### GtkPopoverMenu with GtkMenuButton
|
|
380
|
-
|
|
381
|
-
```tsx
|
|
382
|
-
<GtkMenuButton iconName="open-menu-symbolic">
|
|
383
|
-
<x.Slot for={GtkMenuButton} id="popover">
|
|
384
|
-
<GtkPopoverMenu>
|
|
385
|
-
<x.MenuSection>
|
|
386
|
-
<x.MenuItem id="new" label="New" onActivate={handleNew} accels="<Control>n" />
|
|
387
|
-
<x.MenuItem id="open" label="Open" onActivate={handleOpen} />
|
|
388
|
-
</x.MenuSection>
|
|
389
|
-
<x.MenuSection>
|
|
390
|
-
<x.MenuSubmenu label="Export">
|
|
391
|
-
<x.MenuItem id="pdf" label="PDF" onActivate={exportPdf} />
|
|
392
|
-
<x.MenuItem id="csv" label="CSV" onActivate={exportCsv} />
|
|
393
|
-
</x.MenuSubmenu>
|
|
394
|
-
</x.MenuSection>
|
|
395
|
-
<x.MenuSection>
|
|
396
|
-
<x.MenuItem id="quit" label="Quit" onActivate={quit} accels="<Control>q" />
|
|
397
|
-
</x.MenuSection>
|
|
398
|
-
</GtkPopoverMenu>
|
|
399
|
-
</x.Slot>
|
|
400
|
-
</GtkMenuButton>
|
|
401
|
-
```
|
|
402
|
-
|
|
403
|
-
**Menu.Item props:** `id` (required), `label`, `onActivate`, `accels` (e.g., `"<Control>n"`)
|
|
404
|
-
|
|
405
|
-
---
|
|
406
|
-
|
|
407
|
-
## Windows
|
|
408
|
-
|
|
409
|
-
### GtkApplicationWindow
|
|
410
|
-
|
|
411
|
-
```tsx
|
|
412
|
-
<GtkApplicationWindow
|
|
413
|
-
title="App"
|
|
414
|
-
defaultWidth={800}
|
|
415
|
-
defaultHeight={600}
|
|
416
|
-
onClose={quit}
|
|
417
|
-
>
|
|
418
|
-
<Content />
|
|
419
|
-
</GtkApplicationWindow>
|
|
420
|
-
```
|
|
421
|
-
|
|
422
|
-
Custom titlebar:
|
|
423
|
-
```tsx
|
|
424
|
-
<GtkApplicationWindow ...>
|
|
425
|
-
<x.Slot for={GtkWindow} id="titlebar">
|
|
426
|
-
<GtkHeaderBar />
|
|
427
|
-
</x.Slot>
|
|
428
|
-
<Content />
|
|
429
|
-
</GtkApplicationWindow>
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
---
|
|
433
|
-
|
|
434
|
-
## Adwaita (Libadwaita)
|
|
435
|
-
|
|
436
|
-
Import: `import * as Adw from "@gtkx/ffi/adw";`
|
|
437
|
-
|
|
438
|
-
### AdwApplicationWindow + AdwToolbarView
|
|
439
|
-
Modern app structure.
|
|
440
|
-
|
|
441
|
-
```tsx
|
|
442
|
-
<AdwApplicationWindow title="App" defaultWidth={800} defaultHeight={600} onClose={quit}>
|
|
443
|
-
<AdwToolbarView>
|
|
444
|
-
<x.ContainerSlot for={AdwToolbarView} id="addTopBar">
|
|
445
|
-
<AdwHeaderBar>
|
|
446
|
-
<x.Slot for={AdwHeaderBar} id="titleWidget">
|
|
447
|
-
<AdwWindowTitle title="App" subtitle="Description" />
|
|
448
|
-
</x.Slot>
|
|
449
|
-
</AdwHeaderBar>
|
|
450
|
-
</x.ContainerSlot>
|
|
451
|
-
<MainContent />
|
|
452
|
-
<x.ContainerSlot for={AdwToolbarView} id="addBottomBar">
|
|
453
|
-
<GtkActionBar />
|
|
454
|
-
</x.ContainerSlot>
|
|
455
|
-
</AdwToolbarView>
|
|
456
|
-
</AdwApplicationWindow>
|
|
457
|
-
```
|
|
458
|
-
|
|
459
|
-
### AdwStatusPage
|
|
460
|
-
Welcome, error, or empty state.
|
|
461
|
-
|
|
462
|
-
```tsx
|
|
463
|
-
<AdwStatusPage iconName="applications-system-symbolic" title="Welcome" description="Get started" vexpand>
|
|
464
|
-
<GtkButton label="Start" cssClasses={["suggested-action", "pill"]} halign={Gtk.Align.CENTER} />
|
|
465
|
-
</AdwStatusPage>
|
|
466
|
-
```
|
|
467
|
-
|
|
468
|
-
### AdwBanner
|
|
469
|
-
Dismissable notification.
|
|
470
|
-
|
|
471
|
-
```tsx
|
|
472
|
-
<AdwBanner title="Update available" buttonLabel="Dismiss" revealed={show} onButtonClicked={() => setShow(false)} />
|
|
473
|
-
```
|
|
474
|
-
|
|
475
|
-
### AdwPreferencesPage / AdwPreferencesGroup
|
|
476
|
-
Settings UI.
|
|
477
|
-
|
|
478
|
-
```tsx
|
|
479
|
-
<AdwPreferencesPage title="Settings">
|
|
480
|
-
<AdwPreferencesGroup title="Appearance" description="Customize look">
|
|
481
|
-
<AdwSwitchRow title="Dark Mode" active={dark} onActivated={() => setDark(!dark)} />
|
|
482
|
-
<AdwActionRow title="Theme" subtitle="Select color">
|
|
483
|
-
<x.ContainerSlot for={AdwActionRow} id="addPrefix">
|
|
484
|
-
<GtkImage iconName="preferences-color-symbolic" />
|
|
485
|
-
</x.ContainerSlot>
|
|
486
|
-
<x.ContainerSlot for={AdwActionRow} id="addSuffix">
|
|
487
|
-
<GtkImage iconName="go-next-symbolic" valign={Gtk.Align.CENTER} />
|
|
488
|
-
</x.ContainerSlot>
|
|
489
|
-
</AdwActionRow>
|
|
490
|
-
</AdwPreferencesGroup>
|
|
491
|
-
</AdwPreferencesPage>
|
|
492
|
-
```
|
|
493
|
-
|
|
494
|
-
**ActionRow children:** Use `x.ContainerSlot for={AdwActionRow} id="addPrefix"` for left widgets, `x.ContainerSlot for={AdwActionRow} id="addSuffix"` for right widgets, or `x.Slot for={AdwActionRow} id="activatableWidget"` for clickable suffix.
|
|
495
|
-
|
|
496
|
-
### AdwExpanderRow
|
|
497
|
-
Expandable settings row with optional action widget.
|
|
498
|
-
|
|
499
|
-
```tsx
|
|
500
|
-
<AdwExpanderRow title="Advanced" subtitle="More options">
|
|
501
|
-
<x.ContainerSlot for={AdwExpanderRow} id="addAction">
|
|
502
|
-
<GtkButton iconName="emblem-system-symbolic" cssClasses={["flat"]} />
|
|
503
|
-
</x.ContainerSlot>
|
|
504
|
-
<x.ContainerSlot for={AdwExpanderRow} id="addRow">
|
|
505
|
-
<AdwSwitchRow title="Option 1" active />
|
|
506
|
-
<AdwSwitchRow title="Option 2" />
|
|
507
|
-
</x.ContainerSlot>
|
|
508
|
-
</AdwExpanderRow>
|
|
509
|
-
```
|
|
510
|
-
|
|
511
|
-
**ExpanderRow slots:** `x.ContainerSlot for={AdwExpanderRow} id="addRow"` for nested rows, `x.ContainerSlot for={AdwExpanderRow} id="addAction"` for header action widget. Direct children also work for simple cases.
|
|
512
|
-
|
|
513
|
-
### AdwEntryRow / AdwPasswordEntryRow
|
|
514
|
-
Input in list row.
|
|
515
|
-
|
|
516
|
-
```tsx
|
|
517
|
-
<AdwEntryRow title="Username" text={username} onChanged={(e) => setUsername(e.getText())} />
|
|
518
|
-
<AdwPasswordEntryRow title="Password" />
|
|
519
|
-
```
|
|
520
|
-
|
|
521
|
-
### AdwToggleGroup
|
|
522
|
-
Segmented button group for mutually exclusive options.
|
|
523
|
-
|
|
524
|
-
```tsx
|
|
525
|
-
const [mode, setMode] = useState("list");
|
|
526
|
-
|
|
527
|
-
<AdwToggleGroup activeName={mode} onActiveChanged={(_index, name) => setMode(name ?? "list")}>
|
|
528
|
-
<x.Toggle id="list" iconName="view-list-symbolic" tooltip="List view" />
|
|
529
|
-
<x.Toggle id="grid" iconName="view-grid-symbolic" tooltip="Grid view" />
|
|
530
|
-
<x.Toggle id="flow" label="Flow" />
|
|
531
|
-
</AdwToggleGroup>
|
|
532
|
-
```
|
|
533
|
-
|
|
534
|
-
**ToggleGroup props:** `activeName`, `active` (index), `onActiveChanged` (callback with index and name)
|
|
535
|
-
|
|
536
|
-
**Toggle props:** `id` (optional), `label`, `iconName`, `tooltip`, `enabled`
|
|
537
|
-
|
|
538
|
-
### AdwNavigationView
|
|
539
|
-
Stack-based navigation with history.
|
|
540
|
-
|
|
541
|
-
```tsx
|
|
542
|
-
const [history, setHistory] = useState(["home"]);
|
|
543
|
-
|
|
544
|
-
<AdwNavigationView history={history} onHistoryChanged={setHistory}>
|
|
545
|
-
<x.NavigationPage for={AdwNavigationView} id="home" title="Home">
|
|
546
|
-
<GtkButton label="Go to Details" onClicked={() => setHistory([...history, "details"])} />
|
|
547
|
-
</x.NavigationPage>
|
|
548
|
-
<x.NavigationPage for={AdwNavigationView} id="details" title="Details" canPop>
|
|
549
|
-
<GtkLabel label="Details content" />
|
|
550
|
-
</x.NavigationPage>
|
|
551
|
-
</AdwNavigationView>
|
|
552
|
-
```
|
|
553
|
-
|
|
554
|
-
**NavigationPage props:** `for` (required, parent widget type), `id` (required), `title`, `canPop`. Control navigation via `history` array.
|
|
555
|
-
|
|
556
|
-
### AdwNavigationSplitView
|
|
557
|
-
Sidebar/content split layout for master-detail interfaces.
|
|
558
|
-
|
|
559
|
-
```tsx
|
|
560
|
-
const [selected, setSelected] = useState(items[0]);
|
|
561
|
-
|
|
562
|
-
<AdwNavigationSplitView sidebarWidthFraction={0.33} minSidebarWidth={200} maxSidebarWidth={300}>
|
|
563
|
-
<x.NavigationPage for={AdwNavigationSplitView} id="sidebar" title="Sidebar">
|
|
564
|
-
<AdwToolbarView>
|
|
565
|
-
<x.ContainerSlot for={AdwToolbarView} id="addTopBar"><AdwHeaderBar /></x.ContainerSlot>
|
|
566
|
-
<GtkListBox cssClasses={["navigation-sidebar"]} onRowSelected={(row) => {
|
|
567
|
-
if (!row) return;
|
|
568
|
-
const item = items[row.getIndex()];
|
|
569
|
-
if (item) setSelected(item);
|
|
570
|
-
}}>
|
|
571
|
-
{items.map((item) => <AdwActionRow key={item.id} title={item.title} />)}
|
|
572
|
-
</GtkListBox>
|
|
573
|
-
</AdwToolbarView>
|
|
574
|
-
</x.NavigationPage>
|
|
575
|
-
|
|
576
|
-
<x.NavigationPage for={AdwNavigationSplitView} id="content" title={selected?.title ?? ""}>
|
|
577
|
-
<AdwToolbarView>
|
|
578
|
-
<x.ContainerSlot for={AdwToolbarView} id="addTopBar"><AdwHeaderBar /></x.ContainerSlot>
|
|
579
|
-
<GtkLabel label={selected?.title ?? ""} />
|
|
580
|
-
</AdwToolbarView>
|
|
581
|
-
</x.NavigationPage>
|
|
582
|
-
</AdwNavigationSplitView>
|
|
583
|
-
```
|
|
584
|
-
|
|
585
|
-
**Props:** `sidebarWidthFraction`, `minSidebarWidth`, `maxSidebarWidth`, `collapsed`, `showContent`.
|
|
586
|
-
**NavigationPage:** Use `for={AdwNavigationSplitView}` with `id="sidebar"` for left pane, `id="content"` for right pane.
|
|
587
|
-
**Selection:** Use `GtkListBox` with `onRowSelected` (single click) not `onRowActivated` (double click).
|
|
588
|
-
|
|
589
|
-
### AdwAlertDialog
|
|
590
|
-
Modern modal alert dialogs with response buttons.
|
|
591
|
-
|
|
592
|
-
```tsx
|
|
593
|
-
const [showDialog, setShowDialog] = useState(false);
|
|
594
|
-
|
|
595
|
-
{showDialog && (
|
|
596
|
-
<AdwAlertDialog
|
|
597
|
-
heading="Delete File?"
|
|
598
|
-
body="This action cannot be undone."
|
|
599
|
-
onResponse={(id) => {
|
|
600
|
-
if (id === "delete") handleDelete();
|
|
601
|
-
setShowDialog(false);
|
|
602
|
-
}}
|
|
603
|
-
>
|
|
604
|
-
<x.AlertDialogResponse id="cancel" label="Cancel" />
|
|
605
|
-
<x.AlertDialogResponse id="delete" label="Delete" appearance={Adw.ResponseAppearance.DESTRUCTIVE} />
|
|
606
|
-
</AdwAlertDialog>
|
|
607
|
-
)}
|
|
608
|
-
```
|
|
609
|
-
|
|
610
|
-
**AlertDialogResponse props:** `id`, `label`, `appearance` (SUGGESTED, DESTRUCTIVE), `enabled`
|
|
611
|
-
|
|
612
|
-
### GtkColorDialogButton / GtkFontDialogButton
|
|
613
|
-
Color and font picker dialogs.
|
|
614
|
-
|
|
615
|
-
```tsx
|
|
616
|
-
<GtkColorDialogButton rgba={color} onRgbaChanged={setColor} title="Select Color" modal withAlpha />
|
|
617
|
-
<GtkFontDialogButton fontDesc={font} onFontDescChanged={setFont} title="Select Font" modal useFont useSize />
|
|
618
|
-
```
|
|
619
|
-
|
|
620
|
-
### Other Adwaita Widgets
|
|
621
|
-
|
|
622
|
-
| Widget | Description |
|
|
623
|
-
|--------|-------------|
|
|
624
|
-
| `AdwClamp` | Limits content width (`maximumSize={600}`) |
|
|
625
|
-
| `AdwAvatar` | User avatar (`size={48} text="Name" showInitials`) |
|
|
626
|
-
| `AdwSpinner` | Loading indicator |
|
|
627
|
-
| `AdwWindowTitle` | Title + subtitle for header bars |
|
|
628
|
-
| `AdwButtonRow` | Button styled as list row |
|
|
629
|
-
|
|
630
|
-
---
|
|
631
|
-
|
|
632
|
-
## Animations
|
|
633
|
-
|
|
634
|
-
Wrap widgets in `x.Animation` for declarative animations with spring or timed transitions:
|
|
635
|
-
|
|
636
|
-
```tsx
|
|
637
|
-
<x.Animation
|
|
638
|
-
initial={{ opacity: 0, scale: 0.8 }}
|
|
639
|
-
animate={{ opacity: 1, scale: 1 }}
|
|
640
|
-
transition={{ mode: "spring", damping: 0.8, stiffness: 200, mass: 1 }}
|
|
641
|
-
animateOnMount
|
|
642
|
-
onAnimationComplete={() => console.log("done")}
|
|
643
|
-
>
|
|
644
|
-
<GtkBox>...</GtkBox>
|
|
645
|
-
</x.Animation>
|
|
646
|
-
```
|
|
647
|
-
|
|
648
|
-
**Props:** `initial`, `animate`, `exit`, `transition` (`AnimationTransition` discriminated union), `animateOnMount`, `onAnimationStart`, `onAnimationComplete`
|
|
649
|
-
|
|
650
|
-
**Spring transition:** `{ mode: "spring", damping, stiffness, mass, initialVelocity, clamp, delay }`
|
|
651
|
-
|
|
652
|
-
**Timed transition:** `{ mode: "timed", duration, easing (from Adw.Easing), delay, repeat, reverse, alternate }`
|
|
653
|
-
|
|
654
|
-
---
|
|
655
|
-
|
|
656
|
-
## Drag and Drop
|
|
657
|
-
|
|
658
|
-
All widgets support drag-and-drop through props. Use `onDragPrepare`, `onDragBegin`, and `onDragEnd` to make a widget draggable, and `dropTypes`, `onDrop`, `onDropEnter`, and `onDropLeave` to accept drops.
|
|
659
|
-
|
|
660
|
-
```tsx
|
|
661
|
-
import * as Gdk from "@gtkx/ffi/gdk";
|
|
662
|
-
import { Type, Value } from "@gtkx/ffi/gobject";
|
|
663
|
-
|
|
664
|
-
const DraggableButton = ({ label }: { label: string }) => (
|
|
665
|
-
<GtkButton
|
|
666
|
-
label={label}
|
|
667
|
-
onDragPrepare={() => Gdk.ContentProvider.newForValue(Value.newFromString(label))}
|
|
668
|
-
dragIcon={someTexture}
|
|
669
|
-
dragIconHotX={16}
|
|
670
|
-
dragIconHotY={16}
|
|
671
|
-
/>
|
|
672
|
-
);
|
|
673
|
-
|
|
674
|
-
const DropZone = () => {
|
|
675
|
-
const [dropped, setDropped] = useState<string | null>(null);
|
|
676
|
-
return (
|
|
677
|
-
<GtkBox
|
|
678
|
-
dropTypes={[Type.STRING]}
|
|
679
|
-
onDrop={(value: Value) => { setDropped(value.getString()); return true; }}
|
|
680
|
-
>
|
|
681
|
-
<GtkLabel label={dropped ?? "Drop here"} />
|
|
682
|
-
</GtkBox>
|
|
683
|
-
);
|
|
684
|
-
};
|
|
685
|
-
```
|
|
686
|
-
|
|
687
|
-
**Drag source props:** `dragIcon`, `dragIconHotX`, `dragIconHotY`
|
|
688
|
-
|
|
689
|
-
## GValue Factories
|
|
690
|
-
|
|
691
|
-
Create typed values for drag-and-drop and signal emission:
|
|
692
|
-
|
|
693
|
-
| Factory | Description |
|
|
694
|
-
| ------------------------------ | ----------------------------- |
|
|
695
|
-
| `Value.newFromString(str)` | String values |
|
|
696
|
-
| `Value.newFromDouble(num)` | 64-bit floating point |
|
|
697
|
-
| `Value.newFromInt(num)` | 32-bit signed integer |
|
|
698
|
-
| `Value.newFromBoolean(bool)` | Boolean values |
|
|
699
|
-
| `Value.newFromObject(obj)` | GObject instances |
|
|
700
|
-
| `Value.newFromBoxed(boxed)` | Boxed types (Gdk.RGBA, etc.) |
|
|
701
|
-
| `Value.newFromEnum(gtype, n)` | Enum values (requires GType) |
|
|
702
|
-
| `Value.newFromFlags(gtype, n)` | Flags values (requires GType) |
|
|
703
|
-
|
|
704
|
-
Type constants for `dropTypes`: `Type.STRING`, `Type.INT`, `Type.DOUBLE`, `Type.BOOLEAN`, `Type.OBJECT`.
|
|
705
|
-
|
|
706
|
-
## Custom Drawing
|
|
707
|
-
|
|
708
|
-
Render custom graphics with `GtkDrawingArea` using the `render` callback:
|
|
709
|
-
|
|
710
|
-
```tsx
|
|
711
|
-
import type { Context } from "@gtkx/ffi/cairo";
|
|
712
|
-
|
|
713
|
-
const Canvas = () => {
|
|
714
|
-
const handleDraw = (cr: Context, width: number, height: number) => {
|
|
715
|
-
cr.setSourceRgb(0.2, 0.4, 0.8);
|
|
716
|
-
cr.rectangle(10, 10, width - 20, height - 20);
|
|
717
|
-
cr.fill();
|
|
718
|
-
};
|
|
719
|
-
|
|
720
|
-
return <GtkDrawingArea contentWidth={400} contentHeight={300} render={handleDraw} />;
|
|
721
|
-
};
|
|
722
|
-
```
|
|
723
|
-
|
|
724
|
-
Changing the `render` callback reference automatically queues a redraw. Add a `GtkGestureDrag` child for interactive drawing.
|
|
725
|
-
|
|
726
|
-
## Event Controllers
|
|
727
|
-
|
|
728
|
-
Event controllers are added as children to any widget. They are auto-generated from GTK's introspection data.
|
|
729
|
-
|
|
730
|
-
```tsx
|
|
731
|
-
<GtkBox focusable>
|
|
732
|
-
<GtkEventControllerMotion
|
|
733
|
-
onEnter={(x, y) => console.log("Entered at", x, y)}
|
|
734
|
-
onMotion={(x, y) => setPosition({ x, y })}
|
|
735
|
-
onLeave={() => console.log("Left")}
|
|
736
|
-
/>
|
|
737
|
-
<GtkEventControllerKey
|
|
738
|
-
onKeyPressed={(keyval, keycode, state) => {
|
|
739
|
-
console.log("Key pressed:", keyval);
|
|
740
|
-
return false;
|
|
741
|
-
}}
|
|
742
|
-
/>
|
|
743
|
-
<GtkGestureClick onPressed={(nPress, x, y) => console.log("Clicked")} />
|
|
744
|
-
<GtkLabel label="Hover or type here" />
|
|
745
|
-
</GtkBox>
|
|
746
|
-
```
|
|
747
|
-
|
|
748
|
-
**Input controllers:** `GtkEventControllerMotion`, `GtkEventControllerKey`, `GtkEventControllerScroll`, `GtkEventControllerFocus`
|
|
749
|
-
|
|
750
|
-
**Gesture controllers:** `GtkGestureClick`, `GtkGestureDrag`, `GtkGestureLongPress`, `GtkGestureZoom`, `GtkGestureRotate`, `GtkGestureSwipe`, `GtkGestureStylus`, `GtkGesturePan`
|
|
751
|
-
|
|
752
|
-
**Drag-and-drop:** `GtkDragSource`, `GtkDropTarget`, `GtkDropControllerMotion`
|
|
753
|
-
|
|
754
|
-
## SearchBar
|
|
755
|
-
|
|
756
|
-
```tsx
|
|
757
|
-
const [searchActive, setSearchActive] = useState(false);
|
|
758
|
-
|
|
759
|
-
<GtkSearchBar searchModeEnabled={searchActive} onSearchModeChanged={setSearchActive}>
|
|
760
|
-
<GtkSearchEntry text={query} onSearchChanged={(entry) => setQuery(entry.getText())} />
|
|
761
|
-
</GtkSearchBar>
|
|
762
|
-
```
|
|
763
|
-
|
|
764
|
-
The `onSearchModeChanged` callback fires when search mode changes (e.g., user presses Escape).
|
|
765
|
-
|
|
766
|
-
## TextView / SourceView
|
|
767
|
-
|
|
768
|
-
Text content is provided as direct children. Use `x.TextTag` for formatting and `x.TextAnchor` for embedded widgets.
|
|
769
|
-
|
|
770
|
-
```tsx
|
|
771
|
-
<GtkTextView enableUndo onBufferChanged={(text) => console.log(text)}>
|
|
772
|
-
Normal text, <x.TextTag id="bold" weight={Pango.Weight.BOLD}>bold</x.TextTag>, and
|
|
773
|
-
<x.TextAnchor><GtkButton label="Click" /></x.TextAnchor> inline.
|
|
774
|
-
</GtkTextView>
|
|
775
|
-
```
|
|
776
|
-
|
|
777
|
-
**TextView props:** `enableUndo`, `onBufferChanged`, `onTextInserted`, `onTextDeleted`, `onCanUndoChanged`, `onCanRedoChanged`
|
|
778
|
-
|
|
779
|
-
**TextTag props:** `id` (required), `priority`, `foreground`, `background`, `weight`, `style`, `underline`, `strikethrough`, `family`, `size`, `sizePoints`, `scale`, `justification`, `leftMargin`, `rightMargin`, `indent`, `editable`, `invisible`
|
|
780
|
-
|
|
781
|
-
**TextAnchor:** Embeds widgets inline with `children`
|
|
782
|
-
|
|
783
|
-
**TextPaintable:** Embeds images inline with `paintable` prop
|
|
784
|
-
|
|
785
|
-
```tsx
|
|
786
|
-
<GtkSourceView
|
|
787
|
-
showLineNumbers
|
|
788
|
-
highlightCurrentLine
|
|
789
|
-
language="typescript"
|
|
790
|
-
styleScheme="Adwaita-dark"
|
|
791
|
-
highlightSyntax
|
|
792
|
-
highlightMatchingBrackets
|
|
793
|
-
enableUndo
|
|
794
|
-
onBufferChanged={setCode}
|
|
795
|
-
>
|
|
796
|
-
{code}
|
|
797
|
-
</GtkSourceView>
|
|
798
|
-
```
|
|
799
|
-
|
|
800
|
-
**SourceView additional props:** `language`, `styleScheme`, `highlightSyntax`, `highlightMatchingBrackets`, `implicitTrailingNewline`, `onCursorMoved`, `onHighlightUpdated`
|
|
801
|
-
|
|
802
|
-
## Keyboard Shortcuts
|
|
803
|
-
|
|
804
|
-
Attach shortcuts with `<GtkShortcutController>` and `x.Shortcut`:
|
|
805
|
-
|
|
806
|
-
```tsx
|
|
807
|
-
<GtkBox orientation={Gtk.Orientation.VERTICAL} spacing={12} focusable>
|
|
808
|
-
<GtkShortcutController scope={Gtk.ShortcutScope.LOCAL}>
|
|
809
|
-
<x.Shortcut trigger="<Control>equal" onActivate={() => setCount((c) => c + 1)} />
|
|
810
|
-
<x.Shortcut trigger="<Control>minus" onActivate={() => setCount((c) => c - 1)} />
|
|
811
|
-
</GtkShortcutController>
|
|
812
|
-
<GtkLabel label={`Count: ${count}`} />
|
|
813
|
-
</GtkBox>
|
|
814
|
-
```
|
|
815
|
-
|
|
816
|
-
**Scopes:** `LOCAL` (widget focus), `MANAGED` (parent managed), `GLOBAL` (window-wide)
|
|
817
|
-
|
|
818
|
-
**Trigger syntax:** `<Control>s`, `<Control><Shift>s`, `<Alt>F4`, `<Primary>q`, `F5`
|
|
819
|
-
|
|
820
|
-
**Multiple triggers:** `trigger={["F5", "<Control>r"]}`
|