react-native-gtkx 0.1.0-alpha.3 → 0.2.0-alpha.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/README.md +41 -3
- package/dist/adw/index.d.ts +3 -0
- package/dist/adw/index.js +41 -0
- package/dist/adw/index.js.map +1 -0
- package/dist/adw/widgets.generated.d.ts +63 -0
- package/dist/adw/widgets.generated.js +125 -0
- package/dist/adw/widgets.generated.js.map +1 -0
- package/dist/animated/create-animated.js +1 -1
- package/dist/animated/create-animated.js.map +1 -1
- package/dist/animated/index.js +3 -3
- package/dist/animated/index.js.map +1 -1
- package/dist/common/content.d.ts +69 -0
- package/dist/common/content.js +84 -0
- package/dist/common/content.js.map +1 -0
- package/dist/common/index.d.ts +3 -0
- package/dist/common/index.js +19 -0
- package/dist/common/index.js.map +1 -0
- package/dist/common/navigation-stack.d.ts +84 -0
- package/dist/common/navigation-stack.js +313 -0
- package/dist/common/navigation-stack.js.map +1 -0
- package/dist/common/widget.d.ts +83 -0
- package/dist/common/widget.js +142 -0
- package/dist/common/widget.js.map +1 -0
- package/dist/components/animated.d.ts +3 -2
- package/dist/components/animated.js +85 -66
- package/dist/components/animated.js.map +1 -1
- package/dist/components/app-registry.d.ts +10 -1
- package/dist/components/app-registry.js +8 -3
- package/dist/components/app-registry.js.map +1 -1
- package/dist/components/pressable.js +109 -16
- package/dist/components/pressable.js.map +1 -1
- package/dist/components/rect-store.d.ts +11 -1
- package/dist/components/rect-store.js +27 -3
- package/dist/components/rect-store.js.map +1 -1
- package/dist/components/svg/animated-support.d.ts +19 -0
- package/dist/components/svg/animated-support.js +64 -0
- package/dist/components/svg/animated-support.js.map +1 -0
- package/dist/components/svg/context.d.ts +8 -0
- package/dist/components/svg/context.js +15 -0
- package/dist/components/svg/context.js.map +1 -0
- package/dist/components/svg/gradients.d.ts +31 -0
- package/dist/components/svg/gradients.js +93 -0
- package/dist/components/svg/gradients.js.map +1 -0
- package/dist/components/svg/group.d.ts +8 -0
- package/dist/components/svg/group.js +30 -0
- package/dist/components/svg/group.js.map +1 -0
- package/dist/components/svg/index.d.ts +6 -0
- package/dist/components/svg/index.js +5 -0
- package/dist/components/svg/index.js.map +1 -0
- package/dist/components/svg/node.d.ts +7 -0
- package/dist/components/svg/node.js +7 -0
- package/dist/components/svg/node.js.map +1 -0
- package/dist/components/svg/paint.d.ts +24 -0
- package/dist/components/svg/paint.js +57 -0
- package/dist/components/svg/paint.js.map +1 -0
- package/dist/components/svg/shapes.d.ts +47 -0
- package/dist/components/svg/shapes.js +51 -0
- package/dist/components/svg/shapes.js.map +1 -0
- package/dist/components/svg/svg.d.ts +14 -0
- package/dist/components/svg/svg.js +48 -0
- package/dist/components/svg/svg.js.map +1 -0
- package/dist/components/svg/use-shape-node.d.ts +12 -0
- package/dist/components/svg/use-shape-node.js +52 -0
- package/dist/components/svg/use-shape-node.js.map +1 -0
- package/dist/components/text-input.js +3 -2
- package/dist/components/text-input.js.map +1 -1
- package/dist/components/text.js +11 -2
- package/dist/components/text.js.map +1 -1
- package/dist/components/use-layout-child.js +47 -4
- package/dist/components/use-layout-child.js.map +1 -1
- package/dist/contracts.d.ts +12 -1
- package/dist/contracts.js +2 -3
- package/dist/contracts.js.map +1 -1
- package/dist/gtk/index.d.ts +6 -0
- package/dist/gtk/index.js +39 -0
- package/dist/gtk/index.js.map +1 -0
- package/dist/gtk/widgets.generated.d.ts +103 -0
- package/dist/gtk/widgets.generated.js +206 -0
- package/dist/gtk/widgets.generated.js.map +1 -0
- package/dist/gtkx/bridge/index.d.ts +9 -4
- package/dist/gtkx/bridge/index.js +41 -5
- package/dist/gtkx/bridge/index.js.map +1 -1
- package/dist/gtkx/bridge/layout-manager.d.ts +2 -1
- package/dist/gtkx/bridge/layout-manager.js +31 -9
- package/dist/gtkx/bridge/layout-manager.js.map +1 -1
- package/dist/gtkx/bridge/svg-node.d.ts +79 -0
- package/dist/gtkx/bridge/svg-node.js +367 -0
- package/dist/gtkx/bridge/svg-node.js.map +1 -0
- package/dist/gtkx/bridge/theme.js +1 -1
- package/dist/gtkx/bridge/theme.js.map +1 -1
- package/dist/gtkx/bridge/use-signal.js +21 -10
- package/dist/gtkx/bridge/use-signal.js.map +1 -1
- package/dist/gtkx/bridge/widgets.generated.d.ts +2 -0
- package/dist/gtkx/bridge/widgets.generated.js +14 -0
- package/dist/gtkx/bridge/widgets.generated.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/bin.d.ts +2 -0
- package/dist/mcp/bin.js +17 -0
- package/dist/mcp/bin.js.map +1 -0
- package/dist/mcp/data/generated.d.ts +1282 -0
- package/dist/mcp/data/generated.js +1148 -0
- package/dist/mcp/data/generated.js.map +1 -0
- package/dist/mcp/index.d.ts +5 -0
- package/dist/mcp/index.js +9 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/list.d.ts +4 -0
- package/dist/mcp/list.js +56 -0
- package/dist/mcp/list.js.map +1 -0
- package/dist/mcp/resolve.d.ts +55 -0
- package/dist/mcp/resolve.js +151 -0
- package/dist/mcp/resolve.js.map +1 -0
- package/dist/mcp/search.d.ts +13 -0
- package/dist/mcp/search.js +48 -0
- package/dist/mcp/search.js.map +1 -0
- package/dist/mcp/server.d.ts +7 -0
- package/dist/mcp/server.js +135 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tool.d.ts +21 -0
- package/dist/mcp/tool.js +36 -0
- package/dist/mcp/tool.js.map +1 -0
- package/dist/metro/index.js +10 -0
- package/dist/metro/index.js.map +1 -1
- package/dist/navigation/index.d.ts +50 -13
- package/dist/navigation/index.js +183 -148
- package/dist/navigation/index.js.map +1 -1
- package/dist/navigation/option-warnings.js +9 -1
- package/dist/navigation/option-warnings.js.map +1 -1
- package/dist/navigation/sidebar.d.ts +177 -9
- package/dist/navigation/sidebar.js +284 -10
- package/dist/navigation/sidebar.js.map +1 -1
- package/dist/runner/index.d.ts +22 -2
- package/dist/runner/index.js +163 -12
- package/dist/runner/index.js.map +1 -1
- package/dist/sea/assemble.d.ts +29 -0
- package/dist/sea/assemble.js +129 -0
- package/dist/sea/assemble.js.map +1 -0
- package/dist/sea/bundle.d.ts +61 -0
- package/dist/sea/bundle.js +202 -0
- package/dist/sea/bundle.js.map +1 -0
- package/dist/sea/gtkx-config-module.d.ts +18 -0
- package/dist/sea/gtkx-config-module.js +67 -0
- package/dist/sea/gtkx-config-module.js.map +1 -0
- package/dist/sea/native-shim.d.ts +40 -0
- package/dist/sea/native-shim.js +121 -0
- package/dist/sea/native-shim.js.map +1 -0
- package/dist/sea/react-anchor-plugin.d.ts +2 -0
- package/dist/sea/react-anchor-plugin.js +30 -0
- package/dist/sea/react-anchor-plugin.js.map +1 -0
- package/dist/style/colors.js +3 -1
- package/dist/style/colors.js.map +1 -1
- package/dist/style/index.d.ts +1 -0
- package/dist/style/index.js +3 -2
- package/dist/style/index.js.map +1 -1
- package/dist/style/registry.gtkx.js +1 -1
- package/dist/style/registry.gtkx.js.map +1 -1
- package/dist/style/split-style.js +3 -3
- package/dist/style/split-style.js.map +1 -1
- package/dist/style/text-align.js +1 -1
- package/dist/style/text-align.js.map +1 -1
- package/dist/style/transform.d.ts +22 -0
- package/dist/style/transform.js +137 -0
- package/dist/style/transform.js.map +1 -0
- package/dist/style/visual-css.js +3 -2
- package/dist/style/visual-css.js.map +1 -1
- package/dist/svg/geometry.d.ts +19 -0
- package/dist/svg/geometry.js +80 -0
- package/dist/svg/geometry.js.map +1 -0
- package/dist/svg/gradient-geometry.d.ts +15 -0
- package/dist/svg/gradient-geometry.js +18 -0
- package/dist/svg/gradient-geometry.js.map +1 -0
- package/dist/svg/transform.d.ts +22 -0
- package/dist/svg/transform.js +74 -0
- package/dist/svg/transform.js.map +1 -0
- package/dist/svg/view-box.d.ts +34 -0
- package/dist/svg/view-box.js +108 -0
- package/dist/svg/view-box.js.map +1 -0
- package/dist/svg-compat/index.d.ts +1 -0
- package/dist/svg-compat/index.js +16 -0
- package/dist/svg-compat/index.js.map +1 -0
- package/dist/testing/index.d.ts +14 -0
- package/dist/testing/index.js +14 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/vite/index.d.ts +7 -3
- package/dist/vite/index.js +16 -3
- package/dist/vite/index.js.map +1 -1
- package/dist/vitest/index.d.ts +52 -0
- package/dist/vitest/index.js +58 -0
- package/dist/vitest/index.js.map +1 -0
- package/dist/vitest/setup.d.ts +4 -0
- package/dist/vitest/setup.js +22 -0
- package/dist/vitest/setup.js.map +1 -0
- package/package.json +47 -8
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
// RnGtkxSvgNode — one GObject class (registerClass, same mechanism as
|
|
2
|
+
// RnGtkxLayout/RnGtkxViewBox) reused for the <Svg> root AND every descendant
|
|
3
|
+
// (<G>, <Path>, <Rect>, ..., <Defs>, <LinearGradient>, <Stop>). Descendants
|
|
4
|
+
// are ordinary GTK children (the reconciler's generic set_parent/insert_after
|
|
5
|
+
// attachment — the same one View relies on) that GTK never snapshots on its
|
|
6
|
+
// own, because nothing ever calls snapshotChild() on them: only the mounted
|
|
7
|
+
// <Svg> instance's snapshot() vfunc actually runs, and it walks
|
|
8
|
+
// getFirstChild()/getNextSibling() itself, reading each node's role from a
|
|
9
|
+
// WeakMap (native wrappers get re-created by the runtime, so per-instance
|
|
10
|
+
// state cannot live on `this` — same reasoning as hooksByManager in
|
|
11
|
+
// layout-manager.ts).
|
|
12
|
+
//
|
|
13
|
+
// `Gtk.Widget.snapshot()` is a real, working vfunc in gtkx's codegen
|
|
14
|
+
// (node_modules/@gtkx/gi/gtk/gtk.js, registerWrapperClass(Widget, ...) lists
|
|
15
|
+
// it with byteOffset 320) even though it is missing from the shipped
|
|
16
|
+
// `gtk.d.ts` — the type generator drops it, the codegen that actually wires
|
|
17
|
+
// vfuncs does not. Verified by reading the generated registry before writing
|
|
18
|
+
// any of this; see epic.md.
|
|
19
|
+
import * as Gdk from "@gtkx/gi/gdk";
|
|
20
|
+
import * as Graphene from "@gtkx/gi/graphene";
|
|
21
|
+
import * as Gsk from "@gtkx/gi/gsk";
|
|
22
|
+
import * as Gtk from "@gtkx/gi/gtk";
|
|
23
|
+
import { createElementComponent } from "@gtkx/react/internal";
|
|
24
|
+
import { registerClass } from "@gtkx/runtime";
|
|
25
|
+
import { parseColor } from "../../style/colors";
|
|
26
|
+
import { resolveGradientPoint, resolveGradientRadius, } from "../../svg/gradient-geometry";
|
|
27
|
+
import { resolveViewBoxTransform, } from "../../svg/view-box";
|
|
28
|
+
const nodeDescriptors = new WeakMap();
|
|
29
|
+
export const setSvgNodeDescriptor = (widget, descriptor) => {
|
|
30
|
+
nodeDescriptors.set(widget, descriptor);
|
|
31
|
+
};
|
|
32
|
+
export const getSvgNodeDescriptor = (widget) => nodeDescriptors.get(widget);
|
|
33
|
+
// --- paint resolution ----------------------------------------------------
|
|
34
|
+
// `parseColor` also passes CSS variables (`var(--x)`) and legacy GTK named
|
|
35
|
+
// colors (`@name`) through unchanged, for the CSS-cascade styling path
|
|
36
|
+
// elsewhere in this codebase. Raw Gsk paint nodes have no cascade to resolve
|
|
37
|
+
// those against — deliberate cut (epic.md): SVG fill/stroke only accepts
|
|
38
|
+
// static CSS colors (hex/rgb/hsl/named/transparent), not PlatformColor.
|
|
39
|
+
export const resolveSvgColor = (spec) => {
|
|
40
|
+
if (!spec) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const normalized = parseColor(spec);
|
|
44
|
+
if (!normalized ||
|
|
45
|
+
normalized.startsWith("var(") ||
|
|
46
|
+
normalized.startsWith("@")) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const rgba = new Gdk.RGBA();
|
|
50
|
+
return rgba.parse(normalized) ? rgba : null;
|
|
51
|
+
};
|
|
52
|
+
const URL_REF_PATTERN = /^url\(#(.+)\)$/;
|
|
53
|
+
export const resolveSvgPaint = (spec) => {
|
|
54
|
+
if (!spec || spec === "none") {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
const match = URL_REF_PATTERN.exec(spec.trim());
|
|
58
|
+
if (match) {
|
|
59
|
+
return { kind: "ref", id: match[1] };
|
|
60
|
+
}
|
|
61
|
+
const rgba = resolveSvgColor(spec);
|
|
62
|
+
return rgba ? { kind: "color", rgba } : null;
|
|
63
|
+
};
|
|
64
|
+
const scaledAlpha = (rgba, factor) => factor >= 1
|
|
65
|
+
? rgba
|
|
66
|
+
: new Gdk.RGBA({
|
|
67
|
+
red: rgba.red,
|
|
68
|
+
green: rgba.green,
|
|
69
|
+
blue: rgba.blue,
|
|
70
|
+
alpha: rgba.alpha * factor,
|
|
71
|
+
});
|
|
72
|
+
const clamp01 = (value) => Math.max(0, Math.min(1, value));
|
|
73
|
+
// RC2-WORKAROUND(gsk-colorstop-boxed-write) — row in docs/gtkx-rc2-notes.md.
|
|
74
|
+
// Writing a Gdk.RGBA into a Gsk.ColorStop's `color` field crashes in the
|
|
75
|
+
// native addon (@gtkx/native)
|
|
76
|
+
// with "Expected an Object for Boxed field write type, got Object" —
|
|
77
|
+
// verified through THREE independent paths, all hitting the same native
|
|
78
|
+
// code: the generated constructor (uses the wrong of two RGBA descriptors,
|
|
79
|
+
// _desc1 instead of the inline _desc2 — a real codegen bug), the property
|
|
80
|
+
// setter (uses the documented-correct _desc2 descriptor and STILL fails,
|
|
81
|
+
// which rules out a simple descriptor mix-up as the whole story), and a
|
|
82
|
+
// bypass that skips ColorStop construction and hands appendLinearGradient a
|
|
83
|
+
// plain {offset, color} object array instead (fails differently, with "No
|
|
84
|
+
// native handle associated with Object" — the array marshaling genuinely
|
|
85
|
+
// requires a native-backed instance per element, so there is no JS-level
|
|
86
|
+
// escape hatch). This is a native-addon bug, not something fixable from
|
|
87
|
+
// application code.
|
|
88
|
+
//
|
|
89
|
+
// Rather than crash every app that uses a gradient, or drop the gradient
|
|
90
|
+
// components from the API while their descriptor-building is fully correct
|
|
91
|
+
// and tested, a stop that fails to construct is treated exactly like a
|
|
92
|
+
// missing gradient reference (see the url(#missing) test): the shape using
|
|
93
|
+
// it simply paints no fill/stroke for that paint, instead of throwing.
|
|
94
|
+
const makeColorStop = (offset, color) => {
|
|
95
|
+
try {
|
|
96
|
+
const stop = new Gsk.ColorStop();
|
|
97
|
+
stop.offset = offset;
|
|
98
|
+
stop.color = color;
|
|
99
|
+
return stop;
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
const collectStops = (gradientWidget) => {
|
|
106
|
+
const stops = [];
|
|
107
|
+
let child = gradientWidget.getFirstChild();
|
|
108
|
+
while (child) {
|
|
109
|
+
const descriptor = nodeDescriptors.get(child);
|
|
110
|
+
if (descriptor?.kind === "stop") {
|
|
111
|
+
const stop = makeColorStop(descriptor.offset, descriptor.color);
|
|
112
|
+
if (stop) {
|
|
113
|
+
stops.push(stop);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
child = child.getNextSibling();
|
|
117
|
+
}
|
|
118
|
+
return stops;
|
|
119
|
+
};
|
|
120
|
+
// Only DIRECT <Defs> children of <Svg> are scanned (a deliberate simplicity
|
|
121
|
+
// cut — every real react-native-svg example keeps Defs at the top).
|
|
122
|
+
const collectGradients = (root) => {
|
|
123
|
+
const gradients = new Map();
|
|
124
|
+
let child = root.getFirstChild();
|
|
125
|
+
while (child) {
|
|
126
|
+
if (nodeDescriptors.get(child)?.kind === "defs") {
|
|
127
|
+
let gradientNode = child.getFirstChild();
|
|
128
|
+
while (gradientNode) {
|
|
129
|
+
const descriptor = nodeDescriptors.get(gradientNode);
|
|
130
|
+
if (descriptor?.kind === "gradient") {
|
|
131
|
+
gradients.set(descriptor.id, {
|
|
132
|
+
descriptor,
|
|
133
|
+
stops: collectStops(gradientNode),
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
gradientNode = gradientNode.getNextSibling();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
child = child.getNextSibling();
|
|
140
|
+
}
|
|
141
|
+
return gradients;
|
|
142
|
+
};
|
|
143
|
+
const asBoundingBox = (rect) => ({
|
|
144
|
+
x: rect.origin.x,
|
|
145
|
+
y: rect.origin.y,
|
|
146
|
+
width: rect.size.width,
|
|
147
|
+
height: rect.size.height,
|
|
148
|
+
});
|
|
149
|
+
const appendGradient = (snapshot, path, entry, opacity) => {
|
|
150
|
+
if (entry.stops.length === 0) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const rescaled = opacity >= 1
|
|
154
|
+
? entry.stops
|
|
155
|
+
: entry.stops
|
|
156
|
+
.map((stop) => makeColorStop(stop.offset, scaledAlpha(stop.color, opacity)))
|
|
157
|
+
.filter((stop) => stop !== null);
|
|
158
|
+
// fillOpacity/strokeOpacity < 1 on a gradient re-builds each stop with a
|
|
159
|
+
// scaled alpha (see makeColorStop's WORKAROUND note); if that rebuild
|
|
160
|
+
// itself fails, fall back to the already-working full-opacity stops
|
|
161
|
+
// rather than losing the gradient entirely over an opacity nuance.
|
|
162
|
+
const stops = rescaled.length > 0 ? rescaled : entry.stops;
|
|
163
|
+
const [hasBounds, tightBounds] = path.getBounds();
|
|
164
|
+
const bounds = hasBounds ? tightBounds : Graphene.Rect.zero();
|
|
165
|
+
const box = asBoundingBox(bounds);
|
|
166
|
+
const { descriptor } = entry;
|
|
167
|
+
if (descriptor.type === "linear") {
|
|
168
|
+
const start = resolveGradientPoint(box, descriptor.x1, descriptor.y1, descriptor.units);
|
|
169
|
+
const end = resolveGradientPoint(box, descriptor.x2, descriptor.y2, descriptor.units);
|
|
170
|
+
snapshot.appendLinearGradient(bounds, new Graphene.Point(start), new Graphene.Point(end), stops);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const center = resolveGradientPoint(box, descriptor.cx, descriptor.cy, descriptor.units);
|
|
174
|
+
const { hradius, vradius } = resolveGradientRadius(box, descriptor.r, descriptor.units);
|
|
175
|
+
snapshot.appendRadialGradient(bounds, new Graphene.Point(center), hradius, vradius, 0, 1, stops);
|
|
176
|
+
};
|
|
177
|
+
// --- drawing ---------------------------------------------------------------
|
|
178
|
+
const applyTransformOps = (snapshot, ops) => {
|
|
179
|
+
for (const op of ops) {
|
|
180
|
+
switch (op.type) {
|
|
181
|
+
case "translate":
|
|
182
|
+
snapshot.translate(new Graphene.Point({ x: op.x, y: op.y }));
|
|
183
|
+
break;
|
|
184
|
+
case "scale":
|
|
185
|
+
snapshot.scale(op.x, op.y);
|
|
186
|
+
break;
|
|
187
|
+
case "rotate":
|
|
188
|
+
snapshot.rotate(op.angleDeg);
|
|
189
|
+
break;
|
|
190
|
+
case "matrix":
|
|
191
|
+
snapshot.transform(Gsk.Transform.new().matrix2d(op.a, op.b, op.c, op.d, op.e, op.f));
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
const paintFill = (snapshot, path, paint, opacity, fillRule, gradients) => {
|
|
197
|
+
if (paint.kind === "color") {
|
|
198
|
+
snapshot.appendFill(path, fillRule, scaledAlpha(paint.rgba, opacity));
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const gradient = gradients.get(paint.id);
|
|
202
|
+
if (!gradient) {
|
|
203
|
+
// url(#missing-id): SVG renders nothing for that paint, not an error.
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
snapshot.pushFill(path, fillRule);
|
|
207
|
+
appendGradient(snapshot, path, gradient, opacity);
|
|
208
|
+
snapshot.pop();
|
|
209
|
+
};
|
|
210
|
+
const paintStroke = (snapshot, path, shape, paint, opacity, gradients) => {
|
|
211
|
+
const stroke = Gsk.Stroke.new(shape.strokeWidth);
|
|
212
|
+
stroke.setLineCap(shape.strokeLinecap);
|
|
213
|
+
stroke.setLineJoin(shape.strokeLinejoin);
|
|
214
|
+
stroke.setMiterLimit(shape.strokeMiterlimit);
|
|
215
|
+
if (shape.strokeDasharray && shape.strokeDasharray.length > 0) {
|
|
216
|
+
stroke.setDash(shape.strokeDasharray);
|
|
217
|
+
stroke.setDashOffset(shape.strokeDashoffset);
|
|
218
|
+
}
|
|
219
|
+
if (paint.kind === "color") {
|
|
220
|
+
snapshot.appendStroke(path, stroke, scaledAlpha(paint.rgba, opacity));
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
const gradient = gradients.get(paint.id);
|
|
224
|
+
if (!gradient) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
snapshot.pushStroke(path, stroke);
|
|
228
|
+
appendGradient(snapshot, path, gradient, opacity);
|
|
229
|
+
snapshot.pop();
|
|
230
|
+
};
|
|
231
|
+
const drawShape = (snapshot, shape, gradients) => {
|
|
232
|
+
const path = shape.path;
|
|
233
|
+
if (!path || path.isEmpty()) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
const groupOpacity = clamp01(shape.opacity);
|
|
237
|
+
const needsGroup = groupOpacity < 1;
|
|
238
|
+
if (needsGroup) {
|
|
239
|
+
snapshot.pushOpacity(groupOpacity);
|
|
240
|
+
}
|
|
241
|
+
if (shape.fill) {
|
|
242
|
+
paintFill(snapshot, path, shape.fill, clamp01(shape.fillOpacity), shape.fillRule, gradients);
|
|
243
|
+
}
|
|
244
|
+
if (shape.stroke && shape.strokeWidth > 0) {
|
|
245
|
+
paintStroke(snapshot, path, shape, shape.stroke, clamp01(shape.strokeOpacity), gradients);
|
|
246
|
+
}
|
|
247
|
+
if (needsGroup) {
|
|
248
|
+
snapshot.pop();
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
const drawChildren = (snapshot, parent, gradients) => {
|
|
252
|
+
let child = parent.getFirstChild();
|
|
253
|
+
while (child) {
|
|
254
|
+
drawNode(snapshot, child, gradients);
|
|
255
|
+
child = child.getNextSibling();
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
const drawNode = (snapshot, widget, gradients) => {
|
|
259
|
+
const descriptor = nodeDescriptors.get(widget);
|
|
260
|
+
if (!descriptor) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
switch (descriptor.kind) {
|
|
264
|
+
case "shape":
|
|
265
|
+
drawShape(snapshot, descriptor, gradients);
|
|
266
|
+
return;
|
|
267
|
+
case "g": {
|
|
268
|
+
const opacity = clamp01(descriptor.opacity);
|
|
269
|
+
const needsOpacity = opacity < 1;
|
|
270
|
+
snapshot.save();
|
|
271
|
+
applyTransformOps(snapshot, descriptor.transformOps);
|
|
272
|
+
if (needsOpacity) {
|
|
273
|
+
snapshot.pushOpacity(opacity);
|
|
274
|
+
}
|
|
275
|
+
drawChildren(snapshot, widget, gradients);
|
|
276
|
+
if (needsOpacity) {
|
|
277
|
+
snapshot.pop();
|
|
278
|
+
}
|
|
279
|
+
snapshot.restore();
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
// defs/gradient/stop are resources, not paint; a nested <Svg> is not a
|
|
283
|
+
// supported composition (undocumented, no-op rather than a crash).
|
|
284
|
+
case "defs":
|
|
285
|
+
case "gradient":
|
|
286
|
+
case "stop":
|
|
287
|
+
case "svg":
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
// --- widget registration ---------------------------------------------------
|
|
292
|
+
let RnGtkxSvgNodeClass = null;
|
|
293
|
+
const ensureRegistered = () => {
|
|
294
|
+
if (RnGtkxSvgNodeClass) {
|
|
295
|
+
return RnGtkxSvgNodeClass;
|
|
296
|
+
}
|
|
297
|
+
// Box, not a bare Widget: the reconciler only auto-attaches JSX children
|
|
298
|
+
// (generic set_parent/insert_after) for widget types that carry a
|
|
299
|
+
// registered "children" behavior, resolved by walking the GType ancestry
|
|
300
|
+
// chain (@gtkx/react's typeInfoFor/buildTypeInfo). Plain GtkWidget has no
|
|
301
|
+
// such behavior — only concrete container types like Box do — which is
|
|
302
|
+
// also why RnGtkxViewBox (view-box.ts) is a Box subclass, not a bare
|
|
303
|
+
// Widget one. GtkBox's own default BoxLayout then measures/allocates
|
|
304
|
+
// these children, but harmlessly: they report a natural size of 0x0 (no
|
|
305
|
+
// style, no content) and their own snapshot() no-ops for anything that
|
|
306
|
+
// is not the mounted <Svg> root (see below), so nothing is ever
|
|
307
|
+
// double-painted through GTK's normal child-snapshot path.
|
|
308
|
+
class RnGtkxSvgNode extends Gtk.Box {
|
|
309
|
+
// Only ever invoked by GTK on the mounted <Svg> root (nothing calls
|
|
310
|
+
// snapshotChild() on the inert descendant instances). Defensive no-op
|
|
311
|
+
// otherwise, so a stray direct call never throws.
|
|
312
|
+
snapshot(snapshot) {
|
|
313
|
+
const descriptor = nodeDescriptors.get(this);
|
|
314
|
+
if (!descriptor || descriptor.kind !== "svg") {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
const width = this.getWidth();
|
|
318
|
+
const height = this.getHeight();
|
|
319
|
+
if (width <= 0 || height <= 0) {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
const transform = resolveViewBoxTransform(descriptor.viewBox, width, height, descriptor.preserveAspectRatio);
|
|
323
|
+
const gradients = collectGradients(this);
|
|
324
|
+
// RC2-WORKAROUND(graphene-rect-nested-boxed-props) — row in
|
|
325
|
+
// docs/gtkx-rc2-notes.md. `new Graphene.Rect({ origin: new
|
|
326
|
+
// Graphene.Point(...), size: new Graphene.Size(...) })` hits the same
|
|
327
|
+
// native "Expected an Object for Boxed field write type, got Object"
|
|
328
|
+
// as Gsk.ColorStop's `color` field (see makeColorStop below) — Rect
|
|
329
|
+
// has a working escape hatch, `.alloc().init(x, y, w, h)`, that
|
|
330
|
+
// ColorStop does not.
|
|
331
|
+
//
|
|
332
|
+
// SVG clips to the viewport by default (no overflow:visible opt-out
|
|
333
|
+
// in this API — deliberate cut, see epic.md).
|
|
334
|
+
snapshot.pushClip(Graphene.Rect.alloc().init(0, 0, width, height));
|
|
335
|
+
snapshot.save();
|
|
336
|
+
snapshot.translate(new Graphene.Point({
|
|
337
|
+
x: transform.translateX,
|
|
338
|
+
y: transform.translateY,
|
|
339
|
+
}));
|
|
340
|
+
snapshot.scale(transform.scaleX, transform.scaleY);
|
|
341
|
+
drawChildren(snapshot, this, gradients);
|
|
342
|
+
snapshot.restore();
|
|
343
|
+
snapshot.pop();
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
// Explicit typeName: bundlers minify class names (same reasoning as
|
|
347
|
+
// RnGtkxLayout/RnGtkxViewBox).
|
|
348
|
+
registerClass(RnGtkxSvgNode, { typeName: "RnGtkxSvgNode" });
|
|
349
|
+
RnGtkxSvgNodeClass = RnGtkxSvgNode;
|
|
350
|
+
return RnGtkxSvgNode;
|
|
351
|
+
};
|
|
352
|
+
let component = null;
|
|
353
|
+
export const getSvgNodeComponent = () => {
|
|
354
|
+
if (component) {
|
|
355
|
+
return component;
|
|
356
|
+
}
|
|
357
|
+
ensureRegistered();
|
|
358
|
+
component = createElementComponent("RnGtkxSvgNode");
|
|
359
|
+
return component;
|
|
360
|
+
};
|
|
361
|
+
/** Imperative invalidation channel for SVG: paint-only changes (including
|
|
362
|
+
* Animated-driven ones) call this instead of queueAllocate/queueResize —
|
|
363
|
+
* nothing here ever touches Yoga. */
|
|
364
|
+
export const queueSvgRedraw = (rootWidget) => {
|
|
365
|
+
rootWidget.queueDraw();
|
|
366
|
+
};
|
|
367
|
+
//# sourceMappingURL=svg-node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svg-node.js","sourceRoot":"","sources":["../../../src/gtkx/bridge/svg-node.ts"],"names":[],"mappings":"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","sourcesContent":["// RnGtkxSvgNode — one GObject class (registerClass, same mechanism as\n// RnGtkxLayout/RnGtkxViewBox) reused for the <Svg> root AND every descendant\n// (<G>, <Path>, <Rect>, ..., <Defs>, <LinearGradient>, <Stop>). Descendants\n// are ordinary GTK children (the reconciler's generic set_parent/insert_after\n// attachment — the same one View relies on) that GTK never snapshots on its\n// own, because nothing ever calls snapshotChild() on them: only the mounted\n// <Svg> instance's snapshot() vfunc actually runs, and it walks\n// getFirstChild()/getNextSibling() itself, reading each node's role from a\n// WeakMap (native wrappers get re-created by the runtime, so per-instance\n// state cannot live on `this` — same reasoning as hooksByManager in\n// layout-manager.ts).\n//\n// `Gtk.Widget.snapshot()` is a real, working vfunc in gtkx's codegen\n// (node_modules/@gtkx/gi/gtk/gtk.js, registerWrapperClass(Widget, ...) lists\n// it with byteOffset 320) even though it is missing from the shipped\n// `gtk.d.ts` — the type generator drops it, the codegen that actually wires\n// vfuncs does not. Verified by reading the generated registry before writing\n// any of this; see epic.md.\nimport * as Gdk from \"@gtkx/gi/gdk\"\nimport * as Graphene from \"@gtkx/gi/graphene\"\nimport * as Gsk from \"@gtkx/gi/gsk\"\nimport * as Gtk from \"@gtkx/gi/gtk\"\nimport { createElementComponent } from \"@gtkx/react/internal\"\nimport { registerClass } from \"@gtkx/runtime\"\nimport { parseColor } from \"../../style/colors\"\nimport {\n resolveGradientPoint,\n resolveGradientRadius,\n type BoundingBox,\n} from \"../../svg/gradient-geometry\"\nimport type { SvgTransformOp } from \"../../svg/transform\"\nimport {\n resolveViewBoxTransform,\n type PreserveAspectRatio,\n type ViewBox,\n} from \"../../svg/view-box\"\n\n// --- descriptors --------------------------------------------------------\n\nexport type SvgPaintSpec =\n { kind: \"color\"; rgba: Gdk.RGBA } | { kind: \"ref\"; id: string }\n\nexport type SvgGradientUnits = \"objectBoundingBox\" | \"userSpaceOnUse\"\n\nexport type SvgSvgDescriptor = {\n kind: \"svg\"\n viewBox: ViewBox | null\n preserveAspectRatio: PreserveAspectRatio\n}\n\nexport type SvgGroupDescriptor = {\n kind: \"g\"\n transformOps: SvgTransformOp[]\n opacity: number\n}\n\nexport type SvgShapeDescriptor = {\n kind: \"shape\"\n path: Gsk.Path | null\n fill: SvgPaintSpec | null\n fillOpacity: number\n fillRule: Gsk.FillRule\n stroke: SvgPaintSpec | null\n strokeOpacity: number\n strokeWidth: number\n strokeLinecap: Gsk.LineCap\n strokeLinejoin: Gsk.LineJoin\n strokeMiterlimit: number\n strokeDasharray: number[] | null\n strokeDashoffset: number\n opacity: number\n}\n\nexport type SvgDefsDescriptor = { kind: \"defs\" }\n\nexport type SvgLinearGradientDescriptor = {\n kind: \"gradient\"\n type: \"linear\"\n id: string\n units: SvgGradientUnits\n x1: number\n y1: number\n x2: number\n y2: number\n}\n\nexport type SvgRadialGradientDescriptor = {\n kind: \"gradient\"\n type: \"radial\"\n id: string\n units: SvgGradientUnits\n cx: number\n cy: number\n r: number\n}\n\nexport type SvgStopDescriptor = {\n kind: \"stop\"\n offset: number\n color: Gdk.RGBA\n}\n\nexport type SvgNodeDescriptor =\n | SvgSvgDescriptor\n | SvgGroupDescriptor\n | SvgShapeDescriptor\n | SvgDefsDescriptor\n | SvgLinearGradientDescriptor\n | SvgRadialGradientDescriptor\n | SvgStopDescriptor\n\nconst nodeDescriptors = new WeakMap<Gtk.Widget, SvgNodeDescriptor>()\n\nexport const setSvgNodeDescriptor = (\n widget: Gtk.Widget,\n descriptor: SvgNodeDescriptor,\n): void => {\n nodeDescriptors.set(widget, descriptor)\n}\n\nexport const getSvgNodeDescriptor = (\n widget: Gtk.Widget,\n): SvgNodeDescriptor | undefined => nodeDescriptors.get(widget)\n\n// --- paint resolution ----------------------------------------------------\n\n// `parseColor` also passes CSS variables (`var(--x)`) and legacy GTK named\n// colors (`@name`) through unchanged, for the CSS-cascade styling path\n// elsewhere in this codebase. Raw Gsk paint nodes have no cascade to resolve\n// those against — deliberate cut (epic.md): SVG fill/stroke only accepts\n// static CSS colors (hex/rgb/hsl/named/transparent), not PlatformColor.\nexport const resolveSvgColor = (spec: string | undefined): Gdk.RGBA | null => {\n if (!spec) {\n return null\n }\n const normalized = parseColor(spec)\n if (\n !normalized ||\n normalized.startsWith(\"var(\") ||\n normalized.startsWith(\"@\")\n ) {\n return null\n }\n const rgba = new Gdk.RGBA()\n return rgba.parse(normalized) ? rgba : null\n}\n\nconst URL_REF_PATTERN = /^url\\(#(.+)\\)$/\n\nexport const resolveSvgPaint = (\n spec: string | undefined,\n): SvgPaintSpec | null => {\n if (!spec || spec === \"none\") {\n return null\n }\n const match = URL_REF_PATTERN.exec(spec.trim())\n if (match) {\n return { kind: \"ref\", id: match[1]! }\n }\n const rgba = resolveSvgColor(spec)\n return rgba ? { kind: \"color\", rgba } : null\n}\n\nconst scaledAlpha = (rgba: Gdk.RGBA, factor: number): Gdk.RGBA =>\n factor >= 1\n ? rgba\n : new Gdk.RGBA({\n red: rgba.red,\n green: rgba.green,\n blue: rgba.blue,\n alpha: rgba.alpha * factor,\n })\n\nconst clamp01 = (value: number): number => Math.max(0, Math.min(1, value))\n\n// --- gradients -------------------------------------------------------------\n\ntype GradientEntry = {\n descriptor: SvgLinearGradientDescriptor | SvgRadialGradientDescriptor\n stops: Gsk.ColorStop[]\n}\n\n// RC2-WORKAROUND(gsk-colorstop-boxed-write) — row in docs/gtkx-rc2-notes.md.\n// Writing a Gdk.RGBA into a Gsk.ColorStop's `color` field crashes in the\n// native addon (@gtkx/native)\n// with \"Expected an Object for Boxed field write type, got Object\" —\n// verified through THREE independent paths, all hitting the same native\n// code: the generated constructor (uses the wrong of two RGBA descriptors,\n// _desc1 instead of the inline _desc2 — a real codegen bug), the property\n// setter (uses the documented-correct _desc2 descriptor and STILL fails,\n// which rules out a simple descriptor mix-up as the whole story), and a\n// bypass that skips ColorStop construction and hands appendLinearGradient a\n// plain {offset, color} object array instead (fails differently, with \"No\n// native handle associated with Object\" — the array marshaling genuinely\n// requires a native-backed instance per element, so there is no JS-level\n// escape hatch). This is a native-addon bug, not something fixable from\n// application code.\n//\n// Rather than crash every app that uses a gradient, or drop the gradient\n// components from the API while their descriptor-building is fully correct\n// and tested, a stop that fails to construct is treated exactly like a\n// missing gradient reference (see the url(#missing) test): the shape using\n// it simply paints no fill/stroke for that paint, instead of throwing.\nconst makeColorStop = (\n offset: number,\n color: Gdk.RGBA,\n): Gsk.ColorStop | null => {\n try {\n const stop = new Gsk.ColorStop()\n stop.offset = offset\n stop.color = color\n return stop\n } catch {\n return null\n }\n}\n\nconst collectStops = (gradientWidget: Gtk.Widget): Gsk.ColorStop[] => {\n const stops: Gsk.ColorStop[] = []\n let child = gradientWidget.getFirstChild()\n while (child) {\n const descriptor = nodeDescriptors.get(child)\n if (descriptor?.kind === \"stop\") {\n const stop = makeColorStop(descriptor.offset, descriptor.color)\n if (stop) {\n stops.push(stop)\n }\n }\n child = child.getNextSibling()\n }\n return stops\n}\n\n// Only DIRECT <Defs> children of <Svg> are scanned (a deliberate simplicity\n// cut — every real react-native-svg example keeps Defs at the top).\nconst collectGradients = (root: Gtk.Widget): Map<string, GradientEntry> => {\n const gradients = new Map<string, GradientEntry>()\n let child = root.getFirstChild()\n while (child) {\n if (nodeDescriptors.get(child)?.kind === \"defs\") {\n let gradientNode = child.getFirstChild()\n while (gradientNode) {\n const descriptor = nodeDescriptors.get(gradientNode)\n if (descriptor?.kind === \"gradient\") {\n gradients.set(descriptor.id, {\n descriptor,\n stops: collectStops(gradientNode),\n })\n }\n gradientNode = gradientNode.getNextSibling()\n }\n }\n child = child.getNextSibling()\n }\n return gradients\n}\n\nconst asBoundingBox = (rect: Graphene.Rect): BoundingBox => ({\n x: rect.origin.x,\n y: rect.origin.y,\n width: rect.size.width,\n height: rect.size.height,\n})\n\nconst appendGradient = (\n snapshot: Gtk.Snapshot,\n path: Gsk.Path,\n entry: GradientEntry,\n opacity: number,\n): void => {\n if (entry.stops.length === 0) {\n return\n }\n const rescaled =\n opacity >= 1\n ? entry.stops\n : entry.stops\n .map((stop) =>\n makeColorStop(stop.offset, scaledAlpha(stop.color, opacity)),\n )\n .filter((stop): stop is Gsk.ColorStop => stop !== null)\n // fillOpacity/strokeOpacity < 1 on a gradient re-builds each stop with a\n // scaled alpha (see makeColorStop's WORKAROUND note); if that rebuild\n // itself fails, fall back to the already-working full-opacity stops\n // rather than losing the gradient entirely over an opacity nuance.\n const stops = rescaled.length > 0 ? rescaled : entry.stops\n const [hasBounds, tightBounds] = path.getBounds()\n const bounds = hasBounds ? tightBounds : Graphene.Rect.zero()\n const box = asBoundingBox(bounds)\n const { descriptor } = entry\n\n if (descriptor.type === \"linear\") {\n const start = resolveGradientPoint(\n box,\n descriptor.x1,\n descriptor.y1,\n descriptor.units,\n )\n const end = resolveGradientPoint(\n box,\n descriptor.x2,\n descriptor.y2,\n descriptor.units,\n )\n snapshot.appendLinearGradient(\n bounds,\n new Graphene.Point(start),\n new Graphene.Point(end),\n stops,\n )\n return\n }\n\n const center = resolveGradientPoint(\n box,\n descriptor.cx,\n descriptor.cy,\n descriptor.units,\n )\n const { hradius, vradius } = resolveGradientRadius(\n box,\n descriptor.r,\n descriptor.units,\n )\n snapshot.appendRadialGradient(\n bounds,\n new Graphene.Point(center),\n hradius,\n vradius,\n 0,\n 1,\n stops,\n )\n}\n\n// --- drawing ---------------------------------------------------------------\n\nconst applyTransformOps = (\n snapshot: Gtk.Snapshot,\n ops: SvgTransformOp[],\n): void => {\n for (const op of ops) {\n switch (op.type) {\n case \"translate\":\n snapshot.translate(new Graphene.Point({ x: op.x, y: op.y }))\n break\n case \"scale\":\n snapshot.scale(op.x, op.y)\n break\n case \"rotate\":\n snapshot.rotate(op.angleDeg)\n break\n case \"matrix\":\n snapshot.transform(\n Gsk.Transform.new().matrix2d(op.a, op.b, op.c, op.d, op.e, op.f),\n )\n break\n }\n }\n}\n\nconst paintFill = (\n snapshot: Gtk.Snapshot,\n path: Gsk.Path,\n paint: SvgPaintSpec,\n opacity: number,\n fillRule: Gsk.FillRule,\n gradients: Map<string, GradientEntry>,\n): void => {\n if (paint.kind === \"color\") {\n snapshot.appendFill(path, fillRule, scaledAlpha(paint.rgba, opacity))\n return\n }\n const gradient = gradients.get(paint.id)\n if (!gradient) {\n // url(#missing-id): SVG renders nothing for that paint, not an error.\n return\n }\n snapshot.pushFill(path, fillRule)\n appendGradient(snapshot, path, gradient, opacity)\n snapshot.pop()\n}\n\nconst paintStroke = (\n snapshot: Gtk.Snapshot,\n path: Gsk.Path,\n shape: SvgShapeDescriptor,\n paint: SvgPaintSpec,\n opacity: number,\n gradients: Map<string, GradientEntry>,\n): void => {\n const stroke = Gsk.Stroke.new(shape.strokeWidth)\n stroke.setLineCap(shape.strokeLinecap)\n stroke.setLineJoin(shape.strokeLinejoin)\n stroke.setMiterLimit(shape.strokeMiterlimit)\n if (shape.strokeDasharray && shape.strokeDasharray.length > 0) {\n stroke.setDash(shape.strokeDasharray)\n stroke.setDashOffset(shape.strokeDashoffset)\n }\n if (paint.kind === \"color\") {\n snapshot.appendStroke(path, stroke, scaledAlpha(paint.rgba, opacity))\n return\n }\n const gradient = gradients.get(paint.id)\n if (!gradient) {\n return\n }\n snapshot.pushStroke(path, stroke)\n appendGradient(snapshot, path, gradient, opacity)\n snapshot.pop()\n}\n\nconst drawShape = (\n snapshot: Gtk.Snapshot,\n shape: SvgShapeDescriptor,\n gradients: Map<string, GradientEntry>,\n): void => {\n const path = shape.path\n if (!path || path.isEmpty()) {\n return\n }\n const groupOpacity = clamp01(shape.opacity)\n const needsGroup = groupOpacity < 1\n if (needsGroup) {\n snapshot.pushOpacity(groupOpacity)\n }\n if (shape.fill) {\n paintFill(\n snapshot,\n path,\n shape.fill,\n clamp01(shape.fillOpacity),\n shape.fillRule,\n gradients,\n )\n }\n if (shape.stroke && shape.strokeWidth > 0) {\n paintStroke(\n snapshot,\n path,\n shape,\n shape.stroke,\n clamp01(shape.strokeOpacity),\n gradients,\n )\n }\n if (needsGroup) {\n snapshot.pop()\n }\n}\n\nconst drawChildren = (\n snapshot: Gtk.Snapshot,\n parent: Gtk.Widget,\n gradients: Map<string, GradientEntry>,\n): void => {\n let child = parent.getFirstChild()\n while (child) {\n drawNode(snapshot, child, gradients)\n child = child.getNextSibling()\n }\n}\n\nconst drawNode = (\n snapshot: Gtk.Snapshot,\n widget: Gtk.Widget,\n gradients: Map<string, GradientEntry>,\n): void => {\n const descriptor = nodeDescriptors.get(widget)\n if (!descriptor) {\n return\n }\n switch (descriptor.kind) {\n case \"shape\":\n drawShape(snapshot, descriptor, gradients)\n return\n case \"g\": {\n const opacity = clamp01(descriptor.opacity)\n const needsOpacity = opacity < 1\n snapshot.save()\n applyTransformOps(snapshot, descriptor.transformOps)\n if (needsOpacity) {\n snapshot.pushOpacity(opacity)\n }\n drawChildren(snapshot, widget, gradients)\n if (needsOpacity) {\n snapshot.pop()\n }\n snapshot.restore()\n return\n }\n // defs/gradient/stop are resources, not paint; a nested <Svg> is not a\n // supported composition (undocumented, no-op rather than a crash).\n case \"defs\":\n case \"gradient\":\n case \"stop\":\n case \"svg\":\n return\n }\n}\n\n// --- widget registration ---------------------------------------------------\n\nlet RnGtkxSvgNodeClass: (new () => Gtk.Widget) | null = null\n\nconst ensureRegistered = (): new () => Gtk.Widget => {\n if (RnGtkxSvgNodeClass) {\n return RnGtkxSvgNodeClass\n }\n\n // Box, not a bare Widget: the reconciler only auto-attaches JSX children\n // (generic set_parent/insert_after) for widget types that carry a\n // registered \"children\" behavior, resolved by walking the GType ancestry\n // chain (@gtkx/react's typeInfoFor/buildTypeInfo). Plain GtkWidget has no\n // such behavior — only concrete container types like Box do — which is\n // also why RnGtkxViewBox (view-box.ts) is a Box subclass, not a bare\n // Widget one. GtkBox's own default BoxLayout then measures/allocates\n // these children, but harmlessly: they report a natural size of 0x0 (no\n // style, no content) and their own snapshot() no-ops for anything that\n // is not the mounted <Svg> root (see below), so nothing is ever\n // double-painted through GTK's normal child-snapshot path.\n class RnGtkxSvgNode extends Gtk.Box {\n // Only ever invoked by GTK on the mounted <Svg> root (nothing calls\n // snapshotChild() on the inert descendant instances). Defensive no-op\n // otherwise, so a stray direct call never throws.\n snapshot(snapshot: Gtk.Snapshot): void {\n const descriptor = nodeDescriptors.get(this)\n if (!descriptor || descriptor.kind !== \"svg\") {\n return\n }\n const width = this.getWidth()\n const height = this.getHeight()\n if (width <= 0 || height <= 0) {\n return\n }\n const transform = resolveViewBoxTransform(\n descriptor.viewBox,\n width,\n height,\n descriptor.preserveAspectRatio,\n )\n const gradients = collectGradients(this)\n // RC2-WORKAROUND(graphene-rect-nested-boxed-props) — row in\n // docs/gtkx-rc2-notes.md. `new Graphene.Rect({ origin: new\n // Graphene.Point(...), size: new Graphene.Size(...) })` hits the same\n // native \"Expected an Object for Boxed field write type, got Object\"\n // as Gsk.ColorStop's `color` field (see makeColorStop below) — Rect\n // has a working escape hatch, `.alloc().init(x, y, w, h)`, that\n // ColorStop does not.\n //\n // SVG clips to the viewport by default (no overflow:visible opt-out\n // in this API — deliberate cut, see epic.md).\n snapshot.pushClip(Graphene.Rect.alloc().init(0, 0, width, height))\n snapshot.save()\n snapshot.translate(\n new Graphene.Point({\n x: transform.translateX,\n y: transform.translateY,\n }),\n )\n snapshot.scale(transform.scaleX, transform.scaleY)\n drawChildren(snapshot, this, gradients)\n snapshot.restore()\n snapshot.pop()\n }\n }\n // Explicit typeName: bundlers minify class names (same reasoning as\n // RnGtkxLayout/RnGtkxViewBox).\n registerClass(RnGtkxSvgNode, { typeName: \"RnGtkxSvgNode\" })\n RnGtkxSvgNodeClass = RnGtkxSvgNode\n return RnGtkxSvgNode\n}\n\ntype SvgNodeComponent = ReturnType<typeof createElementComponent>\n\nlet component: SvgNodeComponent | null = null\n\nexport const getSvgNodeComponent = (): SvgNodeComponent => {\n if (component) {\n return component\n }\n ensureRegistered()\n component = createElementComponent(\"RnGtkxSvgNode\")\n return component\n}\n\n/** Imperative invalidation channel for SVG: paint-only changes (including\n * Animated-driven ones) call this instead of queueAllocate/queueResize —\n * nothing here ever touches Yoga. */\nexport const queueSvgRedraw = (rootWidget: Gtk.Widget): void => {\n rootWidget.queueDraw()\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as Adw from "@gtkx/gi/adw";
|
|
2
2
|
export const styleManager = () => Adw.StyleManager.getDefault();
|
|
3
|
-
// Appearance API
|
|
3
|
+
// The Appearance API subscribes to notify::dark on the style manager.
|
|
4
4
|
export const colorScheme = () => styleManager().getDark() ? "dark" : "light";
|
|
5
5
|
//# sourceMappingURL=theme.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../../../src/gtkx/bridge/theme.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AAInC,MAAM,CAAC,MAAM,YAAY,GAAG,GAAqB,EAAE,CACjD,GAAG,CAAC,YAAY,CAAC,UAAU,EAAE,CAAA;AAE/B,
|
|
1
|
+
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../../../src/gtkx/bridge/theme.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AAInC,MAAM,CAAC,MAAM,YAAY,GAAG,GAAqB,EAAE,CACjD,GAAG,CAAC,YAAY,CAAC,UAAU,EAAE,CAAA;AAE/B,sEAAsE;AACtE,MAAM,CAAC,MAAM,WAAW,GAAG,GAAgB,EAAE,CAC3C,YAAY,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAA","sourcesContent":["import * as Adw from \"@gtkx/gi/adw\"\n\nexport type ColorScheme = \"light\" | \"dark\"\n\nexport const styleManager = (): Adw.StyleManager =>\n Adw.StyleManager.getDefault()\n\n// The Appearance API subscribes to notify::dark on the style manager.\nexport const colorScheme = (): ColorScheme =>\n styleManager().getDark() ? \"dark\" : \"light\"\n"]}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
|
-
// RC2-WORKAROUND(use-signal-stale-handler):
|
|
2
|
-
// that "each emission runs the handler from
|
|
3
|
-
// delivered that by pinning the handler in a ref
|
|
4
|
-
// React's useEffectEvent instead, and
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
1
|
+
// RC2-WORKAROUND(use-signal-stale-handler): see docs/gtkx-rc2-notes.md
|
|
2
|
+
// @gtkx/react's useSignal documents that "each emission runs the handler from
|
|
3
|
+
// the latest render", and rc.1 delivered that by pinning the handler in a ref
|
|
4
|
+
// of its own. rc.2 routes it through React's useEffectEvent instead, and
|
|
5
|
+
// react-reconciler@0.33.0 only refreshes useEffectEvent in
|
|
6
|
+
// commitBeforeMutationEffects for `case 0` (FunctionComponent) — `case 11`
|
|
7
|
+
// (ForwardRef) and `case 15` (SimpleMemoComponent) fall through unrefreshed.
|
|
8
|
+
// Any useEffectEvent inside a memo or forwardRef component is pinned to its
|
|
9
|
+
// mount closure permanently; this has nothing to do with useSignal
|
|
10
|
+
// specifically (confirmed upstream: gtkx-org/gtkx#467) — plain
|
|
11
|
+
// useEffectEvent called from an Effect fails identically. It reproduced for
|
|
12
|
+
// us because our ScrollView is a forwardRef (components/scroll-view.tsx) with
|
|
13
|
+
// the useSignal calls inside it; tree depth was a coincidence, not the
|
|
14
|
+
// trigger. The consequence is not subtle — the mount-time scroll handler
|
|
15
|
+
// windows a VirtualizedList against the data it saw at mount, so a list
|
|
16
|
+
// whose rows arrive from a fetch renders EMPTY as soon as it is scrolled.
|
|
11
17
|
//
|
|
12
18
|
// Restore the documented contract at the bridge: keep the latest handler in a
|
|
13
19
|
// ref of our own and hand gtkx a stable wrapper (stable so the connection is
|
|
@@ -15,6 +21,11 @@
|
|
|
15
21
|
// refreshed in an INSERTION effect — the earliest commit phase, ahead of every
|
|
16
22
|
// layout effect, so a signal emitted from one (the list's own scroll
|
|
17
23
|
// corrections) already sees the handler from the render being committed.
|
|
24
|
+
// React fixed the refresh on the 19.3 line (moved into
|
|
25
|
+
// commitMutationEffectsOnFiber, covering `case 0/11/14/15` ahead of child
|
|
26
|
+
// traversal), but there is no stable 0.34.x gtkx release yet and the React
|
|
27
|
+
// canaries pin an exact prerelease peer, so this wrapper stays until a
|
|
28
|
+
// stable React 19.3 ships — not "when useSignal is fixed" (see gtkx#467).
|
|
18
29
|
import { useSignal as useGtkxSignal } from "@gtkx/react";
|
|
19
30
|
import { useCallback, useInsertionEffect, useRef } from "react";
|
|
20
31
|
export const useSignal = (object, signal, handler, options) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-signal.js","sourceRoot":"","sources":["../../../src/gtkx/bridge/use-signal.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,
|
|
1
|
+
{"version":3,"file":"use-signal.js","sourceRoot":"","sources":["../../../src/gtkx/bridge/use-signal.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,8EAA8E;AAC9E,8EAA8E;AAC9E,yEAAyE;AACzE,2DAA2D;AAC3D,2EAA2E;AAC3E,6EAA6E;AAC7E,4EAA4E;AAC5E,mEAAmE;AACnE,+DAA+D;AAC/D,4EAA4E;AAC5E,8EAA8E;AAC9E,uEAAuE;AACvE,yEAAyE;AACzE,wEAAwE;AACxE,0EAA0E;AAC1E,EAAE;AACF,8EAA8E;AAC9E,6EAA6E;AAC7E,8EAA8E;AAC9E,+EAA+E;AAC/E,qEAAqE;AACrE,yEAAyE;AACzE,uDAAuD;AACvD,0EAA0E;AAC1E,2EAA2E;AAC3E,uEAAuE;AACvE,0EAA0E;AAC1E,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAI/D,MAAM,CAAC,MAAM,SAAS,GAAyB,CAC7C,MAAM,EACN,MAAM,EACN,OAAO,EACP,OAAO,EACP,EAAE;IACF,4EAA4E;IAC5E,iEAAiE;IACjE,MAAM,MAAM,GAAG,MAAM,CAAa,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;IAClD,kBAAkB,CAAC,GAAG,EAAE;QACtB,MAAM,CAAC,OAAO,GAAG,OAAgC,CAAA;IACnD,CAAC,CAAC,CAAA;IACF,MAAM,MAAM,GAAG,WAAW,CACxB,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,EACpC,EAAE,CACH,CAAA;IACD,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAmC,EAAE,OAAO,CAAC,CAAA;AAC7E,CAAC,CAAA","sourcesContent":["// RC2-WORKAROUND(use-signal-stale-handler): see docs/gtkx-rc2-notes.md\n// @gtkx/react's useSignal documents that \"each emission runs the handler from\n// the latest render\", and rc.1 delivered that by pinning the handler in a ref\n// of its own. rc.2 routes it through React's useEffectEvent instead, and\n// react-reconciler@0.33.0 only refreshes useEffectEvent in\n// commitBeforeMutationEffects for `case 0` (FunctionComponent) — `case 11`\n// (ForwardRef) and `case 15` (SimpleMemoComponent) fall through unrefreshed.\n// Any useEffectEvent inside a memo or forwardRef component is pinned to its\n// mount closure permanently; this has nothing to do with useSignal\n// specifically (confirmed upstream: gtkx-org/gtkx#467) — plain\n// useEffectEvent called from an Effect fails identically. It reproduced for\n// us because our ScrollView is a forwardRef (components/scroll-view.tsx) with\n// the useSignal calls inside it; tree depth was a coincidence, not the\n// trigger. The consequence is not subtle — the mount-time scroll handler\n// windows a VirtualizedList against the data it saw at mount, so a list\n// whose rows arrive from a fetch renders EMPTY as soon as it is scrolled.\n//\n// Restore the documented contract at the bridge: keep the latest handler in a\n// ref of our own and hand gtkx a stable wrapper (stable so the connection is\n// never re-established, which is what its useEffectEvent was for). The ref is\n// refreshed in an INSERTION effect — the earliest commit phase, ahead of every\n// layout effect, so a signal emitted from one (the list's own scroll\n// corrections) already sees the handler from the render being committed.\n// React fixed the refresh on the 19.3 line (moved into\n// commitMutationEffectsOnFiber, covering `case 0/11/14/15` ahead of child\n// traversal), but there is no stable 0.34.x gtkx release yet and the React\n// canaries pin an exact prerelease peer, so this wrapper stays until a\n// stable React 19.3 ships — not \"when useSignal is fixed\" (see gtkx#467).\nimport { useSignal as useGtkxSignal } from \"@gtkx/react\"\nimport { useCallback, useInsertionEffect, useRef } from \"react\"\n\ntype AnyHandler = (...args: unknown[]) => unknown\n\nexport const useSignal: typeof useGtkxSignal = (\n object,\n signal,\n handler,\n options,\n) => {\n // The handler type is generic in the signal name; the wrapper only forwards\n // arguments, so it crosses that boundary as an untyped callable.\n const latest = useRef<AnyHandler>(() => undefined)\n useInsertionEffect(() => {\n latest.current = handler as unknown as AnyHandler\n })\n const stable = useCallback<AnyHandler>(\n (...args) => latest.current(...args),\n [],\n )\n useGtkxSignal(object, signal, stable as unknown as typeof handler, options)\n}\n"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { GtkAboutDialog, GtkActionBar, GtkAppChooserButton, GtkAppChooserDialog, GtkAppChooserWidget, GtkApplicationWindow, GtkAspectFrame, GtkAssistant, GtkBox, GtkButton, GtkCalendar, GtkCellView, GtkCenterBox, GtkCheckButton, GtkColorButton, GtkColorChooserDialog, GtkColorChooserWidget, GtkColorDialogButton, GtkColumnView, GtkComboBox, GtkComboBoxText, GtkDialog, GtkDragIcon, GtkDrawingArea, GtkDropDown, GtkEditableLabel, GtkEmojiChooser, GtkEntry, GtkExpander, GtkFileChooserDialog, GtkFileChooserWidget, GtkFixed, GtkFlowBox, GtkFlowBoxChild, GtkFontButton, GtkFontChooserDialog, GtkFontChooserWidget, GtkFontDialogButton, GtkFrame, GtkGLArea, GtkGraphicsOffload, GtkGrid, GtkGridView, GtkHeaderBar, GtkIconView, GtkImage, GtkInfoBar, GtkInscription, GtkLabel, GtkLevelBar, GtkLinkButton, GtkListBox, GtkListBoxRow, GtkListView, GtkLockButton, GtkMediaControls, GtkMenuButton, GtkMessageDialog, GtkNotebook, GtkOverlay, GtkPageSetupUnixDialog, GtkPaned, GtkPasswordEntry, GtkPicture, GtkPopover, GtkPopoverBin, GtkPopoverMenu, GtkPopoverMenuBar, GtkPrintUnixDialog, GtkProgressBar, GtkRange, GtkRevealer, GtkScale, GtkScaleButton, GtkScrollbar, GtkScrolledWindow, GtkSearchBar, GtkSearchEntry, GtkSeparator, GtkShortcutLabel, GtkShortcutsGroup, GtkShortcutsSection, GtkShortcutsShortcut, GtkShortcutsWindow, GtkSpinButton, GtkSpinner, GtkStack, GtkStackSidebar, GtkStackSwitcher, GtkStatusbar, GtkSwitch, GtkText, GtkTextView, GtkToggleButton, GtkTreeExpander, GtkTreeView, GtkVideo, GtkViewport, GtkVolumeButton, GtkWindow, GtkWindowControls, GtkWindowHandle, } from "@gtkx/jsx/gtk";
|
|
2
|
+
export { AdwAboutDialog, AdwAboutWindow, AdwActionRow, AdwAlertDialog, AdwApplicationWindow, AdwAvatar, AdwBanner, AdwBin, AdwBottomSheet, AdwBreakpointBin, AdwButtonContent, AdwButtonRow, AdwCarousel, AdwCarouselIndicatorDots, AdwCarouselIndicatorLines, AdwClamp, AdwClampScrollable, AdwComboRow, AdwDialog, AdwEntryRow, AdwExpanderRow, AdwFlap, AdwHeaderBar, AdwInlineViewSwitcher, AdwLayoutSlot, AdwLeaflet, AdwMessageDialog, AdwMultiLayoutView, AdwNavigationPage, AdwNavigationSplitView, AdwNavigationView, AdwOverlaySplitView, AdwPasswordEntryRow, AdwPreferencesDialog, AdwPreferencesGroup, AdwPreferencesPage, AdwPreferencesRow, AdwPreferencesWindow, AdwShortcutLabel, AdwShortcutsDialog, AdwSidebar, AdwSpinRow, AdwSpinner, AdwSplitButton, AdwSqueezer, AdwStatusPage, AdwSwitchRow, AdwTabBar, AdwTabButton, AdwTabOverview, AdwTabView, AdwToastOverlay, AdwToggleGroup, AdwToolbarView, AdwViewStack, AdwViewSwitcher, AdwViewSwitcherBar, AdwViewSwitcherSidebar, AdwViewSwitcherTitle, AdwWindow, AdwWindowTitle, AdwWrapBox, } from "@gtkx/jsx/adw";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// GENERATED FILE — do not edit by hand.
|
|
2
|
+
// Produced by scripts/generate-widget-surface.ts. Re-run it inside the VM
|
|
3
|
+
// after `npm run codegen` picks up a gtkx update; see
|
|
4
|
+
// scripts/widget-surface/classification.json for the full classification
|
|
5
|
+
// and .claude/epics/widget-surface/ for the rules behind it.
|
|
6
|
+
//
|
|
7
|
+
// Every widget the classifier resolved to a Gtk.Widget subclass, re-exported
|
|
8
|
+
// RAW. This is the only generated file (besides the hand-written bridge
|
|
9
|
+
// modules) allowed to import @gtkx/jsx directly — src/gtk/widgets.generated
|
|
10
|
+
// and src/adw/widgets.generated pull from here instead, so the
|
|
11
|
+
// no-restricted-imports carve-out for src/gtkx/bridge/** stays the only door.
|
|
12
|
+
export { GtkAboutDialog, GtkActionBar, GtkAppChooserButton, GtkAppChooserDialog, GtkAppChooserWidget, GtkApplicationWindow, GtkAspectFrame, GtkAssistant, GtkBox, GtkButton, GtkCalendar, GtkCellView, GtkCenterBox, GtkCheckButton, GtkColorButton, GtkColorChooserDialog, GtkColorChooserWidget, GtkColorDialogButton, GtkColumnView, GtkComboBox, GtkComboBoxText, GtkDialog, GtkDragIcon, GtkDrawingArea, GtkDropDown, GtkEditableLabel, GtkEmojiChooser, GtkEntry, GtkExpander, GtkFileChooserDialog, GtkFileChooserWidget, GtkFixed, GtkFlowBox, GtkFlowBoxChild, GtkFontButton, GtkFontChooserDialog, GtkFontChooserWidget, GtkFontDialogButton, GtkFrame, GtkGLArea, GtkGraphicsOffload, GtkGrid, GtkGridView, GtkHeaderBar, GtkIconView, GtkImage, GtkInfoBar, GtkInscription, GtkLabel, GtkLevelBar, GtkLinkButton, GtkListBox, GtkListBoxRow, GtkListView, GtkLockButton, GtkMediaControls, GtkMenuButton, GtkMessageDialog, GtkNotebook, GtkOverlay, GtkPageSetupUnixDialog, GtkPaned, GtkPasswordEntry, GtkPicture, GtkPopover, GtkPopoverBin, GtkPopoverMenu, GtkPopoverMenuBar, GtkPrintUnixDialog, GtkProgressBar, GtkRange, GtkRevealer, GtkScale, GtkScaleButton, GtkScrollbar, GtkScrolledWindow, GtkSearchBar, GtkSearchEntry, GtkSeparator, GtkShortcutLabel, GtkShortcutsGroup, GtkShortcutsSection, GtkShortcutsShortcut, GtkShortcutsWindow, GtkSpinButton, GtkSpinner, GtkStack, GtkStackSidebar, GtkStackSwitcher, GtkStatusbar, GtkSwitch, GtkText, GtkTextView, GtkToggleButton, GtkTreeExpander, GtkTreeView, GtkVideo, GtkViewport, GtkVolumeButton, GtkWindow, GtkWindowControls, GtkWindowHandle, } from "@gtkx/jsx/gtk";
|
|
13
|
+
export { AdwAboutDialog, AdwAboutWindow, AdwActionRow, AdwAlertDialog, AdwApplicationWindow, AdwAvatar, AdwBanner, AdwBin, AdwBottomSheet, AdwBreakpointBin, AdwButtonContent, AdwButtonRow, AdwCarousel, AdwCarouselIndicatorDots, AdwCarouselIndicatorLines, AdwClamp, AdwClampScrollable, AdwComboRow, AdwDialog, AdwEntryRow, AdwExpanderRow, AdwFlap, AdwHeaderBar, AdwInlineViewSwitcher, AdwLayoutSlot, AdwLeaflet, AdwMessageDialog, AdwMultiLayoutView, AdwNavigationPage, AdwNavigationSplitView, AdwNavigationView, AdwOverlaySplitView, AdwPasswordEntryRow, AdwPreferencesDialog, AdwPreferencesGroup, AdwPreferencesPage, AdwPreferencesRow, AdwPreferencesWindow, AdwShortcutLabel, AdwShortcutsDialog, AdwSidebar, AdwSpinRow, AdwSpinner, AdwSplitButton, AdwSqueezer, AdwStatusPage, AdwSwitchRow, AdwTabBar, AdwTabButton, AdwTabOverview, AdwTabView, AdwToastOverlay, AdwToggleGroup, AdwToolbarView, AdwViewStack, AdwViewSwitcher, AdwViewSwitcherBar, AdwViewSwitcherSidebar, AdwViewSwitcherTitle, AdwWindow, AdwWindowTitle, AdwWrapBox, } from "@gtkx/jsx/adw";
|
|
14
|
+
//# sourceMappingURL=widgets.generated.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widgets.generated.js","sourceRoot":"","sources":["../../../src/gtkx/bridge/widgets.generated.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,0EAA0E;AAC1E,sDAAsD;AACtD,yEAAyE;AACzE,6DAA6D;AAC7D,EAAE;AACF,6EAA6E;AAC7E,wEAAwE;AACxE,4EAA4E;AAC5E,+DAA+D;AAC/D,8EAA8E;AAE9E,OAAO,EACL,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,EACd,YAAY,EACZ,MAAM,EACN,SAAS,EACT,WAAW,EACX,WAAW,EACX,YAAY,EACZ,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,EACb,WAAW,EACX,eAAe,EACf,SAAS,EACT,WAAW,EACX,cAAc,EACd,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,WAAW,EACX,oBAAoB,EACpB,oBAAoB,EACpB,QAAQ,EACR,UAAU,EACV,eAAe,EACf,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,QAAQ,EACR,SAAS,EACT,kBAAkB,EAClB,OAAO,EACP,WAAW,EACX,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,UAAU,EACV,cAAc,EACd,QAAQ,EACR,WAAW,EACX,aAAa,EACb,UAAU,EACV,aAAa,EACb,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,sBAAsB,EACtB,QAAQ,EACR,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,EACb,UAAU,EACV,QAAQ,EACR,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACT,OAAO,EACP,WAAW,EACX,eAAe,EACf,eAAe,EACf,WAAW,EACX,QAAQ,EACR,WAAW,EACX,eAAe,EACf,SAAS,EACT,iBAAiB,EACjB,eAAe,GAChB,MAAM,eAAe,CAAA;AAEtB,OAAO,EACL,cAAc,EACd,cAAc,EACd,YAAY,EACZ,cAAc,EACd,oBAAoB,EACpB,SAAS,EACT,SAAS,EACT,MAAM,EACN,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,wBAAwB,EACxB,yBAAyB,EACzB,QAAQ,EACR,kBAAkB,EAClB,WAAW,EACX,SAAS,EACT,WAAW,EACX,cAAc,EACd,OAAO,EACP,YAAY,EACZ,qBAAqB,EACrB,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,UAAU,EACV,UAAU,EACV,UAAU,EACV,cAAc,EACd,WAAW,EACX,aAAa,EACb,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,cAAc,EACd,UAAU,EACV,eAAe,EACf,cAAc,EACd,cAAc,EACd,YAAY,EACZ,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,SAAS,EACT,cAAc,EACd,UAAU,GACX,MAAM,eAAe,CAAA","sourcesContent":["// GENERATED FILE — do not edit by hand.\n// Produced by scripts/generate-widget-surface.ts. Re-run it inside the VM\n// after `npm run codegen` picks up a gtkx update; see\n// scripts/widget-surface/classification.json for the full classification\n// and .claude/epics/widget-surface/ for the rules behind it.\n//\n// Every widget the classifier resolved to a Gtk.Widget subclass, re-exported\n// RAW. This is the only generated file (besides the hand-written bridge\n// modules) allowed to import @gtkx/jsx directly — src/gtk/widgets.generated\n// and src/adw/widgets.generated pull from here instead, so the\n// no-restricted-imports carve-out for src/gtkx/bridge/** stays the only door.\n\nexport {\n GtkAboutDialog,\n GtkActionBar,\n GtkAppChooserButton,\n GtkAppChooserDialog,\n GtkAppChooserWidget,\n GtkApplicationWindow,\n GtkAspectFrame,\n GtkAssistant,\n GtkBox,\n GtkButton,\n GtkCalendar,\n GtkCellView,\n GtkCenterBox,\n GtkCheckButton,\n GtkColorButton,\n GtkColorChooserDialog,\n GtkColorChooserWidget,\n GtkColorDialogButton,\n GtkColumnView,\n GtkComboBox,\n GtkComboBoxText,\n GtkDialog,\n GtkDragIcon,\n GtkDrawingArea,\n GtkDropDown,\n GtkEditableLabel,\n GtkEmojiChooser,\n GtkEntry,\n GtkExpander,\n GtkFileChooserDialog,\n GtkFileChooserWidget,\n GtkFixed,\n GtkFlowBox,\n GtkFlowBoxChild,\n GtkFontButton,\n GtkFontChooserDialog,\n GtkFontChooserWidget,\n GtkFontDialogButton,\n GtkFrame,\n GtkGLArea,\n GtkGraphicsOffload,\n GtkGrid,\n GtkGridView,\n GtkHeaderBar,\n GtkIconView,\n GtkImage,\n GtkInfoBar,\n GtkInscription,\n GtkLabel,\n GtkLevelBar,\n GtkLinkButton,\n GtkListBox,\n GtkListBoxRow,\n GtkListView,\n GtkLockButton,\n GtkMediaControls,\n GtkMenuButton,\n GtkMessageDialog,\n GtkNotebook,\n GtkOverlay,\n GtkPageSetupUnixDialog,\n GtkPaned,\n GtkPasswordEntry,\n GtkPicture,\n GtkPopover,\n GtkPopoverBin,\n GtkPopoverMenu,\n GtkPopoverMenuBar,\n GtkPrintUnixDialog,\n GtkProgressBar,\n GtkRange,\n GtkRevealer,\n GtkScale,\n GtkScaleButton,\n GtkScrollbar,\n GtkScrolledWindow,\n GtkSearchBar,\n GtkSearchEntry,\n GtkSeparator,\n GtkShortcutLabel,\n GtkShortcutsGroup,\n GtkShortcutsSection,\n GtkShortcutsShortcut,\n GtkShortcutsWindow,\n GtkSpinButton,\n GtkSpinner,\n GtkStack,\n GtkStackSidebar,\n GtkStackSwitcher,\n GtkStatusbar,\n GtkSwitch,\n GtkText,\n GtkTextView,\n GtkToggleButton,\n GtkTreeExpander,\n GtkTreeView,\n GtkVideo,\n GtkViewport,\n GtkVolumeButton,\n GtkWindow,\n GtkWindowControls,\n GtkWindowHandle,\n} from \"@gtkx/jsx/gtk\"\n\nexport {\n AdwAboutDialog,\n AdwAboutWindow,\n AdwActionRow,\n AdwAlertDialog,\n AdwApplicationWindow,\n AdwAvatar,\n AdwBanner,\n AdwBin,\n AdwBottomSheet,\n AdwBreakpointBin,\n AdwButtonContent,\n AdwButtonRow,\n AdwCarousel,\n AdwCarouselIndicatorDots,\n AdwCarouselIndicatorLines,\n AdwClamp,\n AdwClampScrollable,\n AdwComboRow,\n AdwDialog,\n AdwEntryRow,\n AdwExpanderRow,\n AdwFlap,\n AdwHeaderBar,\n AdwInlineViewSwitcher,\n AdwLayoutSlot,\n AdwLeaflet,\n AdwMessageDialog,\n AdwMultiLayoutView,\n AdwNavigationPage,\n AdwNavigationSplitView,\n AdwNavigationView,\n AdwOverlaySplitView,\n AdwPasswordEntryRow,\n AdwPreferencesDialog,\n AdwPreferencesGroup,\n AdwPreferencesPage,\n AdwPreferencesRow,\n AdwPreferencesWindow,\n AdwShortcutLabel,\n AdwShortcutsDialog,\n AdwSidebar,\n AdwSpinRow,\n AdwSpinner,\n AdwSplitButton,\n AdwSqueezer,\n AdwStatusPage,\n AdwSwitchRow,\n AdwTabBar,\n AdwTabButton,\n AdwTabOverview,\n AdwTabView,\n AdwToastOverlay,\n AdwToggleGroup,\n AdwToolbarView,\n AdwViewStack,\n AdwViewSwitcher,\n AdwViewSwitcherBar,\n AdwViewSwitcherSidebar,\n AdwViewSwitcherTitle,\n AdwWindow,\n AdwWindowTitle,\n AdwWrapBox,\n} from \"@gtkx/jsx/adw\"\n"]}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Public surface of react-native-gtkx, mirroring the `react-native` module.
|
|
2
|
-
// Components
|
|
2
|
+
// Components · APIs · StyleSheet, with the Yoga layout engine underneath.
|
|
3
3
|
export { ActivityIndicator, Animated, AppRegistry, Easing, FlatList, Image, Modal, IntrinsicRoot, NestedRoot, Pressable, Root, SafeAreaView, ScrollView, SectionList, StatusBar, Switch, Text, TextInput, TouchableOpacity, View, } from "./components/index";
|
|
4
4
|
export { Alert, Appearance, AppState, BackHandler, DevSettings, Dimensions, I18nManager, InteractionManager, Linking, Platform, useColorScheme, useWindowDimensions, } from "./apis/index";
|
|
5
5
|
export { PlatformColor, StyleSheet } from "./style/index";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,0EAA0E;AAE1E,OAAO,EACL,iBAAiB,EACjB,QAAQ,EACR,WAAW,EACX,MAAM,EACN,QAAQ,EACR,KAAK,EACL,KAAK,EACL,aAAa,EACb,UAAU,EACV,SAAS,EACT,IAAI,EACJ,YAAY,EACZ,UAAU,EACV,WAAW,EACX,SAAS,EACT,MAAM,EACN,IAAI,EACJ,SAAS,EACT,gBAAgB,EAChB,IAAI,GA0BL,MAAM,oBAAoB,CAAA;AAM3B,OAAO,EACL,KAAK,EACL,UAAU,EACV,QAAQ,EACR,WAAW,EACX,WAAW,EACX,UAAU,EACV,WAAW,EACX,kBAAkB,EAClB,OAAO,EACP,QAAQ,EACR,cAAc,EACd,mBAAmB,GAapB,MAAM,cAAc,CAAA;AAErB,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAYzD,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAA","sourcesContent":["// Public surface of react-native-gtkx, mirroring the `react-native` module.\n// Components · APIs · StyleSheet, with the Yoga layout engine underneath.\n\nexport {\n ActivityIndicator,\n Animated,\n AppRegistry,\n Easing,\n FlatList,\n Image,\n Modal,\n IntrinsicRoot,\n NestedRoot,\n Pressable,\n Root,\n SafeAreaView,\n ScrollView,\n SectionList,\n StatusBar,\n Switch,\n Text,\n TextInput,\n TouchableOpacity,\n View,\n type ActivityIndicatorProps,\n type FlatListProps,\n type ImageProps,\n type ImageSource,\n type LayoutEvent,\n type ListRenderItemInfo,\n type ModalProps,\n type PressableProps,\n type PressableStateCallbackType,\n type IntrinsicRootProps,\n type NestedRootProps,\n type PressEvent,\n type RootProps,\n type RunApplicationParams,\n type ScrollEvent,\n type ScrollViewHandle,\n type ScrollViewProps,\n type SectionListProps,\n type SwitchProps,\n type TextInputProps,\n type TextProps,\n type TouchableOpacityProps,\n type ViewabilityConfig,\n type ViewProps,\n type ViewToken,\n} from \"./components/index\"\n\n// List scroll handle (scrollTo/scrollToEnd/scrollToIndex/scrollToItem/\n// scrollToOffset) — exported straight from the component module.\nexport type { FlatListHandle } from \"./components/flat-list\"\n\nexport {\n Alert,\n Appearance,\n AppState,\n BackHandler,\n DevSettings,\n Dimensions,\n I18nManager,\n InteractionManager,\n Linking,\n Platform,\n useColorScheme,\n useWindowDimensions,\n type AlertButton,\n type AlertButtonStyle,\n type AlertOptions,\n type AppearancePreferences,\n type AppStateEvent,\n type AppStateStatus,\n type ColorSchemeName,\n type DimensionKey,\n type DimensionsPayload,\n type InteractionPromise,\n type PlatformSelectSpec,\n type ScaledSize,\n} from \"./apis/index\"\n\nexport { PlatformColor, StyleSheet } from \"./style/index\"\n\nexport type {\n DimensionValue,\n FlatStyle,\n LayoutStyle,\n PointerEventsValue,\n StyleProp,\n TransformPart,\n VisualStyle,\n} from \"./contracts\"\n\nexport const version = \"0.1.0\"\n"]}
|
package/dist/mcp/bin.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// The react-native-gtkx-mcp bin: run from a consumer project (npx picks up
|
|
3
|
+
// the locally installed react-native-gtkx first, so this always answers
|
|
4
|
+
// for the exact version that project has — see docs/getting-started.md).
|
|
5
|
+
// Executed by bare `node` (no bundler in the way, same reason
|
|
6
|
+
// src/runner/src/metro/src/vite stay self-contained) — hence every
|
|
7
|
+
// relative import in src/mcp/** carries an explicit .js extension.
|
|
8
|
+
import process from "node:process";
|
|
9
|
+
import { main } from "./server.js";
|
|
10
|
+
try {
|
|
11
|
+
await main();
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
console.error("[react-native-gtkx-mcp] fatal error:", error);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=bin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/mcp/bin.ts"],"names":[],"mappings":";AACA,2EAA2E;AAC3E,wEAAwE;AACxE,yEAAyE;AACzE,8DAA8D;AAC9D,mEAAmE;AACnE,mEAAmE;AACnE,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAElC,IAAI,CAAC;IACH,MAAM,IAAI,EAAE,CAAA;AACd,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAA;IAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC","sourcesContent":["#!/usr/bin/env node\n// The react-native-gtkx-mcp bin: run from a consumer project (npx picks up\n// the locally installed react-native-gtkx first, so this always answers\n// for the exact version that project has — see docs/getting-started.md).\n// Executed by bare `node` (no bundler in the way, same reason\n// src/runner/src/metro/src/vite stay self-contained) — hence every\n// relative import in src/mcp/** carries an explicit .js extension.\nimport process from \"node:process\"\nimport { main } from \"./server.js\"\n\ntry {\n await main()\n} catch (error) {\n console.error(\"[react-native-gtkx-mcp] fatal error:\", error)\n process.exit(1)\n}\n"]}
|