@gtkx/react 0.10.3 → 0.10.4

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/dist/jsx.d.ts CHANGED
@@ -105,29 +105,6 @@ export type FixedChildProps = SlotProps & {
105
105
  /** Y coordinate in pixels */
106
106
  y?: number;
107
107
  };
108
- /**
109
- * Props for declarative toast notifications.
110
- *
111
- * @see {@link Toast} for usage
112
- */
113
- export type ToastProps = {
114
- /** The toast message text */
115
- title: string;
116
- /** Timeout in seconds (0 for indefinite) */
117
- timeout?: number;
118
- /** Priority level for interrupting other toasts */
119
- priority?: import("@gtkx/ffi/adw").ToastPriority;
120
- /** Label for the action button */
121
- buttonLabel?: string;
122
- /** Action name to trigger when button is clicked */
123
- actionName?: string;
124
- /** Whether to use Pango markup in the title */
125
- useMarkup?: boolean;
126
- /** Callback when the toast button is clicked */
127
- onButtonClicked?: () => void;
128
- /** Callback when the toast is dismissed */
129
- onDismissed?: () => void;
130
- };
131
108
  /**
132
109
  * Props for custom list view rendering.
133
110
  *
@@ -336,29 +313,6 @@ export declare const GridChild: "GridChild";
336
313
  * ```
337
314
  */
338
315
  export declare const FixedChild: "FixedChild";
339
- /**
340
- * Element type for declarative toast notifications within an AdwToastOverlay.
341
- *
342
- * When mounted, shows the toast. When unmounted, the toast auto-dismisses.
343
- * Toasts can have an optional action button and callbacks.
344
- *
345
- * @example
346
- * ```tsx
347
- * <AdwToastOverlay>
348
- * <MyContent />
349
- * {showToast && (
350
- * <Toast
351
- * title="File saved"
352
- * timeout={3}
353
- * buttonLabel="Undo"
354
- * onButtonClicked={handleUndo}
355
- * onDismissed={() => setShowToast(false)}
356
- * />
357
- * )}
358
- * </AdwToastOverlay>
359
- * ```
360
- */
361
- export declare const Toast: "Toast";
362
316
  /**
363
317
  * Element types for pages within a GtkNotebook (tabbed interface).
364
318
  *
@@ -686,7 +640,6 @@ declare global {
686
640
  StackPage: StackPageProps;
687
641
  GridChild: GridChildProps;
688
642
  FixedChild: FixedChildProps;
689
- Toast: ToastProps;
690
643
  "Notebook.Page": NotebookPageProps;
691
644
  "Notebook.PageTab": NotebookPageTabProps;
692
645
  ListItem: ListItemProps;
package/dist/jsx.js CHANGED
@@ -73,29 +73,6 @@ export const GridChild = "GridChild";
73
73
  * ```
74
74
  */
75
75
  export const FixedChild = "FixedChild";
76
- /**
77
- * Element type for declarative toast notifications within an AdwToastOverlay.
78
- *
79
- * When mounted, shows the toast. When unmounted, the toast auto-dismisses.
80
- * Toasts can have an optional action button and callbacks.
81
- *
82
- * @example
83
- * ```tsx
84
- * <AdwToastOverlay>
85
- * <MyContent />
86
- * {showToast && (
87
- * <Toast
88
- * title="File saved"
89
- * timeout={3}
90
- * buttonLabel="Undo"
91
- * onButtonClicked={handleUndo}
92
- * onDismissed={() => setShowToast(false)}
93
- * />
94
- * )}
95
- * </AdwToastOverlay>
96
- * ```
97
- */
98
- export const Toast = "Toast";
99
76
  /**
100
77
  * Element types for pages within a GtkNotebook (tabbed interface).
101
78
  *
@@ -21,8 +21,6 @@ import "./simple-list-view.js";
21
21
  import "./slot.js";
22
22
  import "./stack-page.js";
23
23
  import "./stack.js";
24
- import "./toast-overlay.js";
25
- import "./toast.js";
26
24
  import "./toolbar-child.js";
27
25
  import "./tree-list-item.js";
28
26
  import "./tree-list-view.js";
@@ -21,8 +21,6 @@ import "./simple-list-view.js";
21
21
  import "./slot.js";
22
22
  import "./stack-page.js";
23
23
  import "./stack.js";
24
- import "./toast-overlay.js";
25
- import "./toast.js";
26
24
  import "./toolbar-child.js";
27
25
  import "./tree-list-item.js";
28
26
  import "./tree-list-view.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gtkx/react",
3
- "version": "0.10.3",
3
+ "version": "0.10.4",
4
4
  "description": "Build GTK4 desktop applications with React and TypeScript",
5
5
  "keywords": [
6
6
  "gtk",
@@ -36,8 +36,8 @@
36
36
  ],
37
37
  "dependencies": {
38
38
  "react-reconciler": "^0.33.0",
39
- "@gtkx/ffi": "0.10.3",
40
- "@gtkx/gir": "0.10.3"
39
+ "@gtkx/ffi": "0.10.4",
40
+ "@gtkx/gir": "0.10.4"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/react-reconciler": "^0.32.3",
package/README.md DELETED
@@ -1,103 +0,0 @@
1
- <p align="center">
2
- <img src="https://raw.githubusercontent.com/eugeniodepalo/gtkx/main/logo.svg" alt="GTKX" width="80" height="80">
3
- </p>
4
-
5
- <h1 align="center">GTKX</h1>
6
-
7
- <p align="center">
8
- <strong>Build native GTK4 desktop applications with React and TypeScript.</strong>
9
- </p>
10
-
11
- <p align="center">
12
- <a href="https://www.npmjs.com/package/@gtkx/react"><img src="https://img.shields.io/npm/v/@gtkx/react.svg" alt="npm version"></a>
13
- <a href="https://github.com/eugeniodepalo/gtkx/actions"><img src="https://img.shields.io/github/actions/workflow/status/eugeniodepalo/gtkx/ci.yml" alt="CI"></a>
14
- <a href="https://github.com/eugeniodepalo/gtkx/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MPL--2.0-blue.svg" alt="License"></a>
15
- <a href="https://github.com/eugeniodepalo/gtkx/discussions"><img src="https://img.shields.io/badge/discussions-GitHub-blue" alt="GitHub Discussions"></a>
16
- </p>
17
-
18
- ---
19
-
20
- GTKX lets you write Linux desktop applications using React. Your components render as native GTK4 widgets through a Rust FFI bridge—no webviews, no Electron, just native performance with the developer experience you already know.
21
-
22
- ## Quick Start
23
-
24
- ```bash
25
- npx @gtkx/cli create my-app
26
- cd my-app
27
- npm run dev
28
- ```
29
-
30
- ## Example
31
-
32
- ```tsx
33
- import {
34
- GtkApplicationWindow,
35
- GtkBox,
36
- GtkButton,
37
- GtkLabel,
38
- quit,
39
- render,
40
- } from "@gtkx/react";
41
- import * as Gtk from "@gtkx/ffi/gtk";
42
- import { useState } from "react";
43
-
44
- const App = () => {
45
- const [count, setCount] = useState(0);
46
-
47
- return (
48
- <GtkApplicationWindow
49
- title="Counter"
50
- defaultWidth={300}
51
- defaultHeight={200}
52
- onCloseRequest={quit}
53
- >
54
- <GtkBox
55
- orientation={Gtk.Orientation.VERTICAL}
56
- spacing={20}
57
- valign={Gtk.Align.CENTER}
58
- >
59
- <GtkLabel label={`Count: ${count}`} cssClasses={["title-1"]} />
60
- <GtkButton label="Increment" onClicked={() => setCount((c) => c + 1)} />
61
- </GtkBox>
62
- </GtkApplicationWindow>
63
- );
64
- };
65
-
66
- render(<App />, "com.example.counter");
67
- ```
68
-
69
- ## Features
70
-
71
- - **React 19** — Hooks, concurrent features, and the component model you know
72
- - **Native GTK4 widgets** — Real native controls, not web components in a webview
73
- - **Adwaita support** — Modern GNOME styling with Libadwaita components
74
- - **Hot Module Replacement** — Fast refresh during development
75
- - **TypeScript first** — Full type safety with auto-generated bindings
76
- - **CSS-in-JS styling** — Familiar styling patterns adapted for GTK
77
- - **Testing utilities** — Component testing similar to Testing Library
78
-
79
- ## Examples
80
-
81
- Explore complete applications in the [`examples/`](./examples) directory:
82
-
83
- - **[gtk-demo](./examples/gtk-demo)** — Full replica of the official GTK demo app
84
- - **[hello-world](./examples/hello-world)** — Minimal application showing a counter
85
- - **[todo](./examples/todo)** — Full-featured todo application with Adwaita styling and testing
86
- - **[deploying](./examples/deploying)** — Example of packaging and distributing a GTKX app
87
-
88
- ## Documentation
89
-
90
- Visit [https://eugeniodepalo.github.io/gtkx](https://eugeniodepalo.github.io/gtkx/) for the full documentation.
91
-
92
- ## Contributing
93
-
94
- Contributions are welcome! Please see the [contributing guidelines](./CONTRIBUTING.md) and check out the [good first issues](https://github.com/eugeniodepalo/gtkx/labels/good%20first%20issue).
95
-
96
- ## Community
97
-
98
- - [GitHub Discussions](https://github.com/eugeniodepalo/gtkx/discussions) — Questions, ideas, and general discussion
99
- - [Issue Tracker](https://github.com/eugeniodepalo/gtkx/issues) — Bug reports and feature requests
100
-
101
- ## License
102
-
103
- [MPL-2.0](./LICENSE)
@@ -1 +0,0 @@
1
- export {};
@@ -1,35 +0,0 @@
1
- import * as Adw from "@gtkx/ffi/adw";
2
- import { registerNodeClass } from "../registry.js";
3
- import { isContainerType } from "./internal/utils.js";
4
- import { ToastNode } from "./toast.js";
5
- import { WidgetNode } from "./widget.js";
6
- class ToastOverlayNode extends WidgetNode {
7
- static priority = 1;
8
- static matches(_type, containerOrClass) {
9
- return isContainerType(Adw.ToastOverlay, containerOrClass);
10
- }
11
- appendChild(child) {
12
- if (child instanceof ToastNode) {
13
- child.setParent(this.container);
14
- return;
15
- }
16
- if (child instanceof WidgetNode) {
17
- this.container.setChild(child.container);
18
- return;
19
- }
20
- throw new Error(`Cannot append '${child.typeName}' to 'ToastOverlay': expected Widget or Toast`);
21
- }
22
- insertBefore(child, _before) {
23
- this.appendChild(child);
24
- }
25
- removeChild(child) {
26
- if (child instanceof ToastNode) {
27
- child.unmount();
28
- return;
29
- }
30
- if (child instanceof WidgetNode) {
31
- this.container.setChild(undefined);
32
- }
33
- }
34
- }
35
- registerNodeClass(ToastOverlayNode);
@@ -1,17 +0,0 @@
1
- import * as Adw from "@gtkx/ffi/adw";
2
- import type { ToastProps } from "../jsx.js";
3
- import { VirtualNode } from "./virtual.js";
4
- type Props = ToastProps;
5
- export declare class ToastNode extends VirtualNode<Props> {
6
- static priority: number;
7
- static matches(type: string): boolean;
8
- private toast?;
9
- private parent?;
10
- setParent(parent?: Adw.ToastOverlay): void;
11
- private createToast;
12
- private showToast;
13
- updateProps(oldProps: Props | null, newProps: Props): void;
14
- mount(): void;
15
- unmount(): void;
16
- }
17
- export {};
@@ -1,78 +0,0 @@
1
- import * as Adw from "@gtkx/ffi/adw";
2
- import { registerNodeClass } from "../registry.js";
3
- import { signalStore } from "./internal/signal-store.js";
4
- import { VirtualNode } from "./virtual.js";
5
- export class ToastNode extends VirtualNode {
6
- static priority = 1;
7
- static matches(type) {
8
- return type === "Toast";
9
- }
10
- toast;
11
- parent;
12
- setParent(parent) {
13
- this.parent = parent;
14
- }
15
- createToast() {
16
- const toast = new Adw.Toast(this.props.title);
17
- if (this.props.timeout !== undefined) {
18
- toast.setTimeout(this.props.timeout);
19
- }
20
- if (this.props.priority !== undefined) {
21
- toast.setPriority(this.props.priority);
22
- }
23
- if (this.props.buttonLabel) {
24
- toast.setButtonLabel(this.props.buttonLabel);
25
- }
26
- if (this.props.actionName) {
27
- toast.setActionName(this.props.actionName);
28
- }
29
- if (this.props.useMarkup !== undefined) {
30
- toast.setUseMarkup(this.props.useMarkup);
31
- }
32
- return toast;
33
- }
34
- showToast() {
35
- if (!this.parent || this.toast)
36
- return;
37
- this.toast = this.createToast();
38
- if (this.props.onButtonClicked) {
39
- signalStore.set(this, this.toast, "button-clicked", () => {
40
- this.props.onButtonClicked?.();
41
- });
42
- }
43
- signalStore.set(this, this.toast, "dismissed", () => {
44
- this.props.onDismissed?.();
45
- });
46
- this.parent.addToast(this.toast);
47
- }
48
- updateProps(oldProps, newProps) {
49
- super.updateProps(oldProps, newProps);
50
- if (!this.toast)
51
- return;
52
- if (!oldProps || oldProps.title !== newProps.title) {
53
- this.toast.setTitle(newProps.title);
54
- }
55
- if (!oldProps || oldProps.buttonLabel !== newProps.buttonLabel) {
56
- this.toast.setButtonLabel(newProps.buttonLabel);
57
- }
58
- if (!oldProps || oldProps.actionName !== newProps.actionName) {
59
- this.toast.setActionName(newProps.actionName);
60
- }
61
- if (!oldProps || oldProps.useMarkup !== newProps.useMarkup) {
62
- this.toast.setUseMarkup(newProps.useMarkup ?? false);
63
- }
64
- }
65
- mount() {
66
- super.mount();
67
- this.showToast();
68
- }
69
- unmount() {
70
- if (this.toast) {
71
- this.toast.dismiss();
72
- this.props.onDismissed?.();
73
- }
74
- this.parent = undefined;
75
- super.unmount();
76
- }
77
- }
78
- registerNodeClass(ToastNode);