react-native-gtkx 0.1.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.
Files changed (213) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +73 -0
  3. package/dist/animated/composite.d.ts +5 -0
  4. package/dist/animated/composite.js +132 -0
  5. package/dist/animated/composite.js.map +1 -0
  6. package/dist/animated/create-animated.d.ts +12 -0
  7. package/dist/animated/create-animated.js +17 -0
  8. package/dist/animated/create-animated.js.map +1 -0
  9. package/dist/animated/easing.d.ts +11 -0
  10. package/dist/animated/easing.js +91 -0
  11. package/dist/animated/easing.js.map +1 -0
  12. package/dist/animated/frame-loop.d.ts +6 -0
  13. package/dist/animated/frame-loop.js +25 -0
  14. package/dist/animated/frame-loop.js.map +1 -0
  15. package/dist/animated/index.d.ts +6 -0
  16. package/dist/animated/index.js +7 -0
  17. package/dist/animated/index.js.map +1 -0
  18. package/dist/animated/interpolate.d.ts +2 -0
  19. package/dist/animated/interpolate.js +90 -0
  20. package/dist/animated/interpolate.js.map +1 -0
  21. package/dist/animated/native-driver.d.ts +1 -0
  22. package/dist/animated/native-driver.js +17 -0
  23. package/dist/animated/native-driver.js.map +1 -0
  24. package/dist/animated/spring.d.ts +3 -0
  25. package/dist/animated/spring.js +67 -0
  26. package/dist/animated/spring.js.map +1 -0
  27. package/dist/animated/timing.d.ts +3 -0
  28. package/dist/animated/timing.js +30 -0
  29. package/dist/animated/timing.js.map +1 -0
  30. package/dist/animated/types.d.ts +51 -0
  31. package/dist/animated/types.js +6 -0
  32. package/dist/animated/types.js.map +1 -0
  33. package/dist/animated/value-animation.d.ts +9 -0
  34. package/dist/animated/value-animation.js +65 -0
  35. package/dist/animated/value-animation.js.map +1 -0
  36. package/dist/animated/value.d.ts +46 -0
  37. package/dist/animated/value.js +130 -0
  38. package/dist/animated/value.js.map +1 -0
  39. package/dist/apis/alert.d.ts +16 -0
  40. package/dist/apis/alert.js +33 -0
  41. package/dist/apis/alert.js.map +1 -0
  42. package/dist/apis/app-state.d.ts +11 -0
  43. package/dist/apis/app-state.js +54 -0
  44. package/dist/apis/app-state.js.map +1 -0
  45. package/dist/apis/appearance.d.ts +12 -0
  46. package/dist/apis/appearance.js +33 -0
  47. package/dist/apis/appearance.js.map +1 -0
  48. package/dist/apis/dev-settings.d.ts +9 -0
  49. package/dist/apis/dev-settings.js +25 -0
  50. package/dist/apis/dev-settings.js.map +1 -0
  51. package/dist/apis/dimensions.d.ts +14 -0
  52. package/dist/apis/dimensions.js +80 -0
  53. package/dist/apis/dimensions.js.map +1 -0
  54. package/dist/apis/emitter.d.ts +8 -0
  55. package/dist/apis/emitter.js +35 -0
  56. package/dist/apis/emitter.js.map +1 -0
  57. package/dist/apis/hooks.d.ts +11 -0
  58. package/dist/apis/hooks.js +29 -0
  59. package/dist/apis/hooks.js.map +1 -0
  60. package/dist/apis/host.d.ts +45 -0
  61. package/dist/apis/host.gtkx.d.ts +2 -0
  62. package/dist/apis/host.gtkx.js +301 -0
  63. package/dist/apis/host.gtkx.js.map +1 -0
  64. package/dist/apis/host.js +6 -0
  65. package/dist/apis/host.js.map +1 -0
  66. package/dist/apis/index.d.ts +39 -0
  67. package/dist/apis/index.js +21 -0
  68. package/dist/apis/index.js.map +1 -0
  69. package/dist/apis/linking.d.ts +7 -0
  70. package/dist/apis/linking.js +28 -0
  71. package/dist/apis/linking.js.map +1 -0
  72. package/dist/apis/platform.d.ts +14 -0
  73. package/dist/apis/platform.js +23 -0
  74. package/dist/apis/platform.js.map +1 -0
  75. package/dist/components/activity-indicator.d.ts +10 -0
  76. package/dist/components/activity-indicator.js +21 -0
  77. package/dist/components/activity-indicator.js.map +1 -0
  78. package/dist/components/animated.d.ts +34 -0
  79. package/dist/components/animated.js +152 -0
  80. package/dist/components/animated.js.map +1 -0
  81. package/dist/components/app-registry.d.ts +14 -0
  82. package/dist/components/app-registry.js +61 -0
  83. package/dist/components/app-registry.js.map +1 -0
  84. package/dist/components/flat-list.d.ts +48 -0
  85. package/dist/components/flat-list.js +23 -0
  86. package/dist/components/flat-list.js.map +1 -0
  87. package/dist/components/host-node.d.ts +10 -0
  88. package/dist/components/host-node.js +10 -0
  89. package/dist/components/host-node.js.map +1 -0
  90. package/dist/components/image-loader.d.ts +17 -0
  91. package/dist/components/image-loader.js +54 -0
  92. package/dist/components/image-loader.js.map +1 -0
  93. package/dist/components/image.d.ts +19 -0
  94. package/dist/components/image.js +73 -0
  95. package/dist/components/image.js.map +1 -0
  96. package/dist/components/index.d.ts +14 -0
  97. package/dist/components/index.js +14 -0
  98. package/dist/components/index.js.map +1 -0
  99. package/dist/components/modal.d.ts +12 -0
  100. package/dist/components/modal.js +18 -0
  101. package/dist/components/modal.js.map +1 -0
  102. package/dist/components/pressable.d.ts +33 -0
  103. package/dist/components/pressable.js +116 -0
  104. package/dist/components/pressable.js.map +1 -0
  105. package/dist/components/rect-store.d.ts +17 -0
  106. package/dist/components/rect-store.js +40 -0
  107. package/dist/components/rect-store.js.map +1 -0
  108. package/dist/components/root.d.ts +8 -0
  109. package/dist/components/root.js +59 -0
  110. package/dist/components/root.js.map +1 -0
  111. package/dist/components/scroll-view.d.ts +56 -0
  112. package/dist/components/scroll-view.js +324 -0
  113. package/dist/components/scroll-view.js.map +1 -0
  114. package/dist/components/switch.d.ts +11 -0
  115. package/dist/components/switch.js +20 -0
  116. package/dist/components/switch.js.map +1 -0
  117. package/dist/components/text-input.d.ts +23 -0
  118. package/dist/components/text-input.js +151 -0
  119. package/dist/components/text-input.js.map +1 -0
  120. package/dist/components/text.d.ts +11 -0
  121. package/dist/components/text.js +100 -0
  122. package/dist/components/text.js.map +1 -0
  123. package/dist/components/use-layout-child.d.ts +36 -0
  124. package/dist/components/use-layout-child.js +177 -0
  125. package/dist/components/use-layout-child.js.map +1 -0
  126. package/dist/components/view.d.ts +13 -0
  127. package/dist/components/view.js +60 -0
  128. package/dist/components/view.js.map +1 -0
  129. package/dist/components/virtualized-list.d.ts +67 -0
  130. package/dist/components/virtualized-list.js +519 -0
  131. package/dist/components/virtualized-list.js.map +1 -0
  132. package/dist/contracts.d.ts +119 -0
  133. package/dist/contracts.js +5 -0
  134. package/dist/contracts.js.map +1 -0
  135. package/dist/gtkx/bridge/index.d.ts +16 -0
  136. package/dist/gtkx/bridge/index.js +25 -0
  137. package/dist/gtkx/bridge/index.js.map +1 -0
  138. package/dist/gtkx/bridge/layout-manager.d.ts +11 -0
  139. package/dist/gtkx/bridge/layout-manager.js +87 -0
  140. package/dist/gtkx/bridge/layout-manager.js.map +1 -0
  141. package/dist/gtkx/bridge/measure.d.ts +9 -0
  142. package/dist/gtkx/bridge/measure.js +20 -0
  143. package/dist/gtkx/bridge/measure.js.map +1 -0
  144. package/dist/gtkx/bridge/theme.d.ts +4 -0
  145. package/dist/gtkx/bridge/theme.js +5 -0
  146. package/dist/gtkx/bridge/theme.js.map +1 -0
  147. package/dist/gtkx/bridge/view-box.d.ts +7 -0
  148. package/dist/gtkx/bridge/view-box.js +40 -0
  149. package/dist/gtkx/bridge/view-box.js.map +1 -0
  150. package/dist/index.d.ts +6 -0
  151. package/dist/index.js +7 -0
  152. package/dist/index.js.map +1 -0
  153. package/dist/layout/apply-style.d.ts +4 -0
  154. package/dist/layout/apply-style.js +148 -0
  155. package/dist/layout/apply-style.js.map +1 -0
  156. package/dist/layout/engine.d.ts +22 -0
  157. package/dist/layout/engine.js +90 -0
  158. package/dist/layout/engine.js.map +1 -0
  159. package/dist/layout/index.d.ts +3 -0
  160. package/dist/layout/index.js +4 -0
  161. package/dist/layout/index.js.map +1 -0
  162. package/dist/layout/node.d.ts +33 -0
  163. package/dist/layout/node.js +151 -0
  164. package/dist/layout/node.js.map +1 -0
  165. package/dist/layout/yoga.d.ts +13 -0
  166. package/dist/layout/yoga.js +52 -0
  167. package/dist/layout/yoga.js.map +1 -0
  168. package/dist/metro/index.d.ts +42 -0
  169. package/dist/metro/index.js +119 -0
  170. package/dist/metro/index.js.map +1 -0
  171. package/dist/runner/host-dev.d.ts +1 -0
  172. package/dist/runner/host-dev.js +208 -0
  173. package/dist/runner/host-dev.js.map +1 -0
  174. package/dist/runner/host.d.ts +1 -0
  175. package/dist/runner/host.js +101 -0
  176. package/dist/runner/host.js.map +1 -0
  177. package/dist/runner/index.d.ts +26 -0
  178. package/dist/runner/index.js +179 -0
  179. package/dist/runner/index.js.map +1 -0
  180. package/dist/style/colors.d.ts +17 -0
  181. package/dist/style/colors.js +375 -0
  182. package/dist/style/colors.js.map +1 -0
  183. package/dist/style/dev-warning.d.ts +2 -0
  184. package/dist/style/dev-warning.js +18 -0
  185. package/dist/style/dev-warning.js.map +1 -0
  186. package/dist/style/index.d.ts +7 -0
  187. package/dist/style/index.js +14 -0
  188. package/dist/style/index.js.map +1 -0
  189. package/dist/style/registry.d.ts +12 -0
  190. package/dist/style/registry.gtkx.d.ts +2 -0
  191. package/dist/style/registry.gtkx.js +9 -0
  192. package/dist/style/registry.gtkx.js.map +1 -0
  193. package/dist/style/registry.js +23 -0
  194. package/dist/style/registry.js.map +1 -0
  195. package/dist/style/split-style.d.ts +6 -0
  196. package/dist/style/split-style.js +107 -0
  197. package/dist/style/split-style.js.map +1 -0
  198. package/dist/style/style-sheet.d.ts +43 -0
  199. package/dist/style/style-sheet.js +57 -0
  200. package/dist/style/style-sheet.js.map +1 -0
  201. package/dist/style/text-align.d.ts +7 -0
  202. package/dist/style/text-align.js +22 -0
  203. package/dist/style/text-align.js.map +1 -0
  204. package/dist/style/visual-css.d.ts +6 -0
  205. package/dist/style/visual-css.js +133 -0
  206. package/dist/style/visual-css.js.map +1 -0
  207. package/dist/vite/index.d.ts +53 -0
  208. package/dist/vite/index.js +127 -0
  209. package/dist/vite/index.js.map +1 -0
  210. package/package.json +88 -0
  211. package/react-native.config.js +21 -0
  212. package/types.d.ts +43 -0
  213. package/types.js +4 -0
@@ -0,0 +1,179 @@
1
+ // The `run-linux` CLI command (registered through the package's
2
+ // react-native.config.js, the react-native-windows model): ensure the gtkx
3
+ // codegen store, then either build a release jsbundle with Metro and run
4
+ // it in the Node+GTK host (./host.ts), or — with --dev — start/reuse a
5
+ // Metro dev server and supervise the DEV host (./host-dev.ts): Fast
6
+ // Refresh applies edits to the live window, and a full-refresh request
7
+ // (exit code 65) restarts the host process.
8
+ //
9
+ // Like the hosts, this module must stay runnable under bare Node:
10
+ // builtins and bare specifiers only.
11
+ import { spawn, spawnSync } from "node:child_process";
12
+ import { mkdirSync } from "node:fs";
13
+ import { createRequire } from "node:module";
14
+ import { basename, dirname, extname, join } from "node:path";
15
+ import { fileURLToPath } from "node:url";
16
+ const fromPackage = createRequire(import.meta.url);
17
+ /** Exit code host-dev.ts uses to request a supervisor restart. */
18
+ const FULL_REFRESH_EXIT_CODE = 65;
19
+ const run = (command, args, cwd) => {
20
+ const result = spawnSync(command, args, { cwd, stdio: "inherit" });
21
+ return result.status ?? 1;
22
+ };
23
+ /** Resolve an executable script shipped by a dependency's bin field. */
24
+ const binOf = (requireFrom, packageName, binName) => {
25
+ const packageJsonPath = requireFrom.resolve(`${packageName}/package.json`);
26
+ const manifest = requireFrom(`${packageName}/package.json`);
27
+ const bin = typeof manifest.bin === "string" ? manifest.bin : manifest.bin?.[binName];
28
+ if (!bin) {
29
+ throw new Error(`${packageName} does not expose a "${binName}" binary`);
30
+ }
31
+ return join(dirname(packageJsonPath), bin);
32
+ };
33
+ // The codegen store lives in the node_modules that hosts the @gtkx
34
+ // packages — run the gtkx CLI from that tree's root so the store lands
35
+ // next to the bindings that read it.
36
+ const ensureCodegenStore = () => {
37
+ const gtkxRoot = dirname(dirname(dirname(fromPackage.resolve("@gtkx/react/package.json"))));
38
+ console.warn("[react-native-gtkx] ensuring gtkx codegen store…");
39
+ const status = run(process.execPath, [binOf(fromPackage, "@gtkx/cli", "gtkx"), "codegen"], gtkxRoot);
40
+ if (status !== 0) {
41
+ console.error("[react-native-gtkx] gtkx codegen failed — are GTK4/libadwaita " +
42
+ "development files installed?");
43
+ process.exit(status);
44
+ }
45
+ };
46
+ const bundle = (root, entryFile, output) => {
47
+ const appRequire = createRequire(join(root, "package.json"));
48
+ const status = run(process.execPath, [
49
+ binOf(appRequire, "react-native", "react-native"),
50
+ "bundle",
51
+ "--platform",
52
+ "linux",
53
+ "--dev",
54
+ "false",
55
+ "--entry-file",
56
+ entryFile,
57
+ "--bundle-output",
58
+ output,
59
+ ], root);
60
+ if (status !== 0) {
61
+ process.exit(status);
62
+ }
63
+ };
64
+ const isMetroRunning = async (server) => {
65
+ try {
66
+ const response = await fetch(`${server}/status`);
67
+ return (await response.text()).includes("packager-status:running");
68
+ }
69
+ catch {
70
+ return false;
71
+ }
72
+ };
73
+ const waitForMetro = async (server) => {
74
+ for (let attempt = 0; attempt < 120; attempt += 1) {
75
+ if (await isMetroRunning(server)) {
76
+ return;
77
+ }
78
+ await new Promise((resolve) => setTimeout(resolve, 500));
79
+ }
80
+ console.error(`[react-native-gtkx] Metro dev server never came up (${server}).`);
81
+ process.exit(1);
82
+ };
83
+ let activeHost = null;
84
+ const spawnHost = (script, argument, cwd) => new Promise((resolve) => {
85
+ const hostPath = fileURLToPath(new URL(script, import.meta.url));
86
+ const child = spawn(process.execPath, [hostPath, argument], {
87
+ cwd,
88
+ stdio: "inherit",
89
+ });
90
+ activeHost = child;
91
+ child.on("exit", (code) => {
92
+ activeHost = null;
93
+ resolve(code ?? 1);
94
+ });
95
+ });
96
+ const runLinuxDev = async (config, args) => {
97
+ const port = args.port ?? "8081";
98
+ const server = `http://localhost:${port}`;
99
+ let metro = null;
100
+ if (await isMetroRunning(server)) {
101
+ console.warn(`[react-native-gtkx] reusing the Metro dev server at ${server}`);
102
+ }
103
+ else {
104
+ console.warn(`[react-native-gtkx] starting the Metro dev server at ${server}…`);
105
+ const appRequire = createRequire(join(config.root, "package.json"));
106
+ metro = spawn(process.execPath, [
107
+ binOf(appRequire, "react-native", "react-native"),
108
+ "start",
109
+ "--port",
110
+ port,
111
+ ], { cwd: config.root, stdio: "inherit" });
112
+ await waitForMetro(server);
113
+ }
114
+ const entry = basename(args.entryFile, extname(args.entryFile));
115
+ const bundleUrl = `${server}/${entry}.bundle?platform=linux&dev=true&minify=false`;
116
+ const shutdown = (code) => {
117
+ activeHost?.kill();
118
+ metro?.kill();
119
+ process.exit(code);
120
+ };
121
+ process.on("SIGINT", () => shutdown(0));
122
+ process.on("SIGTERM", () => shutdown(0));
123
+ // Supervisor: a full-refresh request restarts the host with the window
124
+ // reopening on the fresh bundle; any other exit ends the session.
125
+ for (;;) {
126
+ const code = await spawnHost("./host-dev.js", bundleUrl, config.root);
127
+ if (code !== FULL_REFRESH_EXIT_CODE) {
128
+ shutdown(code);
129
+ }
130
+ console.warn("[react-native-gtkx] restarting the app after a full refresh…");
131
+ }
132
+ };
133
+ const runLinux = async (_argv, config, args) => {
134
+ ensureCodegenStore();
135
+ if (args.dev) {
136
+ await runLinuxDev(config, args);
137
+ return;
138
+ }
139
+ const output = args.bundleOutput ??
140
+ join(config.root, "node_modules", ".react-native-gtkx", "main.jsbundle");
141
+ if (!args.skipBundling) {
142
+ mkdirSync(dirname(output), { recursive: true });
143
+ bundle(config.root, args.entryFile, output);
144
+ }
145
+ const status = await spawnHost("./host.js", output, config.root);
146
+ process.exit(status);
147
+ };
148
+ /** Commands contributed to the RN CLI by the package's react-native.config.js. */
149
+ export const commands = [
150
+ {
151
+ name: "run-linux",
152
+ description: "Bundle the app with Metro for the linux platform and run it in the Node+GTK host",
153
+ options: [
154
+ {
155
+ name: "--entry-file <path>",
156
+ description: "Path to the app entry file",
157
+ default: "index.js",
158
+ },
159
+ {
160
+ name: "--bundle-output <path>",
161
+ description: "Where to write the jsbundle (default: node_modules/.react-native-gtkx/main.jsbundle)",
162
+ },
163
+ {
164
+ name: "--skip-bundling",
165
+ description: "Reuse the existing bundle at --bundle-output",
166
+ },
167
+ {
168
+ name: "--dev",
169
+ description: "Development mode: Metro dev server + Fast Refresh (edits apply to the live window)",
170
+ },
171
+ {
172
+ name: "--port <number>",
173
+ description: "Metro dev server port for --dev (default: 8081)",
174
+ },
175
+ ],
176
+ func: runLinux,
177
+ },
178
+ ];
179
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runner/index.ts"],"names":[],"mappings":"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","sourcesContent":["// The `run-linux` CLI command (registered through the package's\n// react-native.config.js, the react-native-windows model): ensure the gtkx\n// codegen store, then either build a release jsbundle with Metro and run\n// it in the Node+GTK host (./host.ts), or — with --dev — start/reuse a\n// Metro dev server and supervise the DEV host (./host-dev.ts): Fast\n// Refresh applies edits to the live window, and a full-refresh request\n// (exit code 65) restarts the host process.\n//\n// Like the hosts, this module must stay runnable under bare Node:\n// builtins and bare specifiers only.\nimport { spawn, spawnSync, type ChildProcess } from \"node:child_process\"\nimport { mkdirSync } from \"node:fs\"\nimport { createRequire } from \"node:module\"\nimport { basename, dirname, extname, join } from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\n\nconst fromPackage = createRequire(import.meta.url)\n\ntype CliConfig = { root: string }\ntype RunLinuxArgs = {\n entryFile: string\n bundleOutput?: string\n skipBundling?: boolean\n dev?: boolean\n port?: string\n}\n\n/** Exit code host-dev.ts uses to request a supervisor restart. */\nconst FULL_REFRESH_EXIT_CODE = 65\n\nconst run = (command: string, args: string[], cwd: string): number => {\n const result = spawnSync(command, args, { cwd, stdio: \"inherit\" })\n return result.status ?? 1\n}\n\n/** Resolve an executable script shipped by a dependency's bin field. */\nconst binOf = (\n requireFrom: NodeJS.Require,\n packageName: string,\n binName: string,\n): string => {\n const packageJsonPath = requireFrom.resolve(`${packageName}/package.json`)\n const manifest = requireFrom(`${packageName}/package.json`) as {\n bin?: string | Record<string, string>\n }\n const bin =\n typeof manifest.bin === \"string\" ? manifest.bin : manifest.bin?.[binName]\n if (!bin) {\n throw new Error(`${packageName} does not expose a \"${binName}\" binary`)\n }\n return join(dirname(packageJsonPath), bin)\n}\n\n// The codegen store lives in the node_modules that hosts the @gtkx\n// packages — run the gtkx CLI from that tree's root so the store lands\n// next to the bindings that read it.\nconst ensureCodegenStore = (): void => {\n const gtkxRoot = dirname(\n dirname(dirname(fromPackage.resolve(\"@gtkx/react/package.json\"))),\n )\n console.warn(\"[react-native-gtkx] ensuring gtkx codegen store…\")\n const status = run(\n process.execPath,\n [binOf(fromPackage, \"@gtkx/cli\", \"gtkx\"), \"codegen\"],\n gtkxRoot,\n )\n if (status !== 0) {\n console.error(\n \"[react-native-gtkx] gtkx codegen failed — are GTK4/libadwaita \" +\n \"development files installed?\",\n )\n process.exit(status)\n }\n}\n\nconst bundle = (root: string, entryFile: string, output: string): void => {\n const appRequire = createRequire(join(root, \"package.json\"))\n const status = run(\n process.execPath,\n [\n binOf(appRequire, \"react-native\", \"react-native\"),\n \"bundle\",\n \"--platform\",\n \"linux\",\n \"--dev\",\n \"false\",\n \"--entry-file\",\n entryFile,\n \"--bundle-output\",\n output,\n ],\n root,\n )\n if (status !== 0) {\n process.exit(status)\n }\n}\n\nconst isMetroRunning = async (server: string): Promise<boolean> => {\n try {\n const response = await fetch(`${server}/status`)\n return (await response.text()).includes(\"packager-status:running\")\n } catch {\n return false\n }\n}\n\nconst waitForMetro = async (server: string): Promise<void> => {\n for (let attempt = 0; attempt < 120; attempt += 1) {\n if (await isMetroRunning(server)) {\n return\n }\n await new Promise((resolve) => setTimeout(resolve, 500))\n }\n console.error(\n `[react-native-gtkx] Metro dev server never came up (${server}).`,\n )\n process.exit(1)\n}\n\nlet activeHost: ChildProcess | null = null\n\nconst spawnHost = (\n script: string,\n argument: string,\n cwd: string,\n): Promise<number> =>\n new Promise((resolve) => {\n const hostPath = fileURLToPath(new URL(script, import.meta.url))\n const child = spawn(process.execPath, [hostPath, argument], {\n cwd,\n stdio: \"inherit\",\n })\n activeHost = child\n child.on(\"exit\", (code) => {\n activeHost = null\n resolve(code ?? 1)\n })\n })\n\nconst runLinuxDev = async (\n config: CliConfig,\n args: RunLinuxArgs,\n): Promise<never> => {\n const port = args.port ?? \"8081\"\n const server = `http://localhost:${port}`\n let metro: ChildProcess | null = null\n if (await isMetroRunning(server)) {\n console.warn(\n `[react-native-gtkx] reusing the Metro dev server at ${server}`,\n )\n } else {\n console.warn(\n `[react-native-gtkx] starting the Metro dev server at ${server}…`,\n )\n const appRequire = createRequire(join(config.root, \"package.json\"))\n metro = spawn(\n process.execPath,\n [\n binOf(appRequire, \"react-native\", \"react-native\"),\n \"start\",\n \"--port\",\n port,\n ],\n { cwd: config.root, stdio: \"inherit\" },\n )\n await waitForMetro(server)\n }\n const entry = basename(args.entryFile, extname(args.entryFile))\n const bundleUrl = `${server}/${entry}.bundle?platform=linux&dev=true&minify=false`\n const shutdown = (code: number): never => {\n activeHost?.kill()\n metro?.kill()\n process.exit(code)\n }\n process.on(\"SIGINT\", () => shutdown(0))\n process.on(\"SIGTERM\", () => shutdown(0))\n // Supervisor: a full-refresh request restarts the host with the window\n // reopening on the fresh bundle; any other exit ends the session.\n for (;;) {\n const code = await spawnHost(\"./host-dev.js\", bundleUrl, config.root)\n if (code !== FULL_REFRESH_EXIT_CODE) {\n shutdown(code)\n }\n console.warn(\"[react-native-gtkx] restarting the app after a full refresh…\")\n }\n}\n\nconst runLinux = async (\n _argv: string[],\n config: CliConfig,\n args: RunLinuxArgs,\n): Promise<void> => {\n ensureCodegenStore()\n if (args.dev) {\n await runLinuxDev(config, args)\n return\n }\n const output =\n args.bundleOutput ??\n join(config.root, \"node_modules\", \".react-native-gtkx\", \"main.jsbundle\")\n if (!args.skipBundling) {\n mkdirSync(dirname(output), { recursive: true })\n bundle(config.root, args.entryFile, output)\n }\n const status = await spawnHost(\"./host.js\", output, config.root)\n process.exit(status)\n}\n\n/** Commands contributed to the RN CLI by the package's react-native.config.js. */\nexport const commands = [\n {\n name: \"run-linux\",\n description:\n \"Bundle the app with Metro for the linux platform and run it in the Node+GTK host\",\n options: [\n {\n name: \"--entry-file <path>\",\n description: \"Path to the app entry file\",\n default: \"index.js\",\n },\n {\n name: \"--bundle-output <path>\",\n description:\n \"Where to write the jsbundle (default: node_modules/.react-native-gtkx/main.jsbundle)\",\n },\n {\n name: \"--skip-bundling\",\n description: \"Reuse the existing bundle at --bundle-output\",\n },\n {\n name: \"--dev\",\n description:\n \"Development mode: Metro dev server + Fast Refresh (edits apply to the live window)\",\n },\n {\n name: \"--port <number>\",\n description: \"Metro dev server port for --dev (default: 8081)\",\n },\n ],\n func: runLinux,\n },\n]\n"]}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Parses a React Native color string into a GTK4 CSS color value.
3
+ * Returns null for values that cannot be understood.
4
+ */
5
+ export declare const parseColor: (value: string) => string | null;
6
+ /**
7
+ * React Native's PlatformColor for GTK: references theme colors by name.
8
+ * Names map onto CSS variables (Adwaita exposes its palette as
9
+ * `--accent-bg-color`, `--window-bg-color`, ... since libadwaita 1.6);
10
+ * extra names become var() fallbacks, tried in order. A name starting with
11
+ * "@" is a legacy GTK named color (`@define-color`) and terminates the
12
+ * fallback chain, because var() fallbacks cannot resolve further after it.
13
+ *
14
+ * PlatformColor("accent-bg-color") → "var(--accent-bg-color)"
15
+ * PlatformColor("accent-bg-color", "@blue_3") → "var(--accent-bg-color, @blue_3)"
16
+ */
17
+ export declare const PlatformColor: (...names: string[]) => string;
@@ -0,0 +1,375 @@
1
+ // Pure color handling: parses React Native color strings and normalizes them
2
+ // into GTK4 CSS color values. No bridge imports — unit-testable on any OS.
3
+ //
4
+ // Every parseable color is normalized to `rgb(r, g, b)` / `rgba(r, g, b, a)`
5
+ // so the output does not depend on which color syntaxes the GTK CSS parser of
6
+ // a particular version accepts. Two values pass through untouched:
7
+ // - `var(--name[, fallback])` — CSS variables (GTK 4.16+, Adwaita palette)
8
+ // - `@name` — legacy GTK named colors (`@define-color` references)
9
+ // CSS Color Module Level 4 named colors (the set React Native supports).
10
+ const NAMED_COLORS = {
11
+ aliceblue: "#f0f8ff",
12
+ antiquewhite: "#faebd7",
13
+ aqua: "#00ffff",
14
+ aquamarine: "#7fffd4",
15
+ azure: "#f0ffff",
16
+ beige: "#f5f5dc",
17
+ bisque: "#ffe4c4",
18
+ black: "#000000",
19
+ blanchedalmond: "#ffebcd",
20
+ blue: "#0000ff",
21
+ blueviolet: "#8a2be2",
22
+ brown: "#a52a2a",
23
+ burlywood: "#deb887",
24
+ cadetblue: "#5f9ea0",
25
+ chartreuse: "#7fff00",
26
+ chocolate: "#d2691e",
27
+ coral: "#ff7f50",
28
+ cornflowerblue: "#6495ed",
29
+ cornsilk: "#fff8dc",
30
+ crimson: "#dc143c",
31
+ cyan: "#00ffff",
32
+ darkblue: "#00008b",
33
+ darkcyan: "#008b8b",
34
+ darkgoldenrod: "#b8860b",
35
+ darkgray: "#a9a9a9",
36
+ darkgreen: "#006400",
37
+ darkgrey: "#a9a9a9",
38
+ darkkhaki: "#bdb76b",
39
+ darkmagenta: "#8b008b",
40
+ darkolivegreen: "#556b2f",
41
+ darkorange: "#ff8c00",
42
+ darkorchid: "#9932cc",
43
+ darkred: "#8b0000",
44
+ darksalmon: "#e9967a",
45
+ darkseagreen: "#8fbc8f",
46
+ darkslateblue: "#483d8b",
47
+ darkslategray: "#2f4f4f",
48
+ darkslategrey: "#2f4f4f",
49
+ darkturquoise: "#00ced1",
50
+ darkviolet: "#9400d3",
51
+ deeppink: "#ff1493",
52
+ deepskyblue: "#00bfff",
53
+ dimgray: "#696969",
54
+ dimgrey: "#696969",
55
+ dodgerblue: "#1e90ff",
56
+ firebrick: "#b22222",
57
+ floralwhite: "#fffaf0",
58
+ forestgreen: "#228b22",
59
+ fuchsia: "#ff00ff",
60
+ gainsboro: "#dcdcdc",
61
+ ghostwhite: "#f8f8ff",
62
+ gold: "#ffd700",
63
+ goldenrod: "#daa520",
64
+ gray: "#808080",
65
+ green: "#008000",
66
+ greenyellow: "#adff2f",
67
+ grey: "#808080",
68
+ honeydew: "#f0fff0",
69
+ hotpink: "#ff69b4",
70
+ indianred: "#cd5c5c",
71
+ indigo: "#4b0082",
72
+ ivory: "#fffff0",
73
+ khaki: "#f0e68c",
74
+ lavender: "#e6e6fa",
75
+ lavenderblush: "#fff0f5",
76
+ lawngreen: "#7cfc00",
77
+ lemonchiffon: "#fffacd",
78
+ lightblue: "#add8e6",
79
+ lightcoral: "#f08080",
80
+ lightcyan: "#e0ffff",
81
+ lightgoldenrodyellow: "#fafad2",
82
+ lightgray: "#d3d3d3",
83
+ lightgreen: "#90ee90",
84
+ lightgrey: "#d3d3d3",
85
+ lightpink: "#ffb6c1",
86
+ lightsalmon: "#ffa07a",
87
+ lightseagreen: "#20b2aa",
88
+ lightskyblue: "#87cefa",
89
+ lightslategray: "#778899",
90
+ lightslategrey: "#778899",
91
+ lightsteelblue: "#b0c4de",
92
+ lightyellow: "#ffffe0",
93
+ lime: "#00ff00",
94
+ limegreen: "#32cd32",
95
+ linen: "#faf0e6",
96
+ magenta: "#ff00ff",
97
+ maroon: "#800000",
98
+ mediumaquamarine: "#66cdaa",
99
+ mediumblue: "#0000cd",
100
+ mediumorchid: "#ba55d3",
101
+ mediumpurple: "#9370db",
102
+ mediumseagreen: "#3cb371",
103
+ mediumslateblue: "#7b68ee",
104
+ mediumspringgreen: "#00fa9a",
105
+ mediumturquoise: "#48d1cc",
106
+ mediumvioletred: "#c71585",
107
+ midnightblue: "#191970",
108
+ mintcream: "#f5fffa",
109
+ mistyrose: "#ffe4e1",
110
+ moccasin: "#ffe4b5",
111
+ navajowhite: "#ffdead",
112
+ navy: "#000080",
113
+ oldlace: "#fdf5e6",
114
+ olive: "#808000",
115
+ olivedrab: "#6b8e23",
116
+ orange: "#ffa500",
117
+ orangered: "#ff4500",
118
+ orchid: "#da70d6",
119
+ palegoldenrod: "#eee8aa",
120
+ palegreen: "#98fb98",
121
+ paleturquoise: "#afeeee",
122
+ palevioletred: "#db7093",
123
+ papayawhip: "#ffefd5",
124
+ peachpuff: "#ffdab9",
125
+ peru: "#cd853f",
126
+ pink: "#ffc0cb",
127
+ plum: "#dda0dd",
128
+ powderblue: "#b0e0e6",
129
+ purple: "#800080",
130
+ rebeccapurple: "#663399",
131
+ red: "#ff0000",
132
+ rosybrown: "#bc8f8f",
133
+ royalblue: "#4169e1",
134
+ saddlebrown: "#8b4513",
135
+ salmon: "#fa8072",
136
+ sandybrown: "#f4a460",
137
+ seagreen: "#2e8b57",
138
+ seashell: "#fff5ee",
139
+ sienna: "#a0522d",
140
+ silver: "#c0c0c0",
141
+ skyblue: "#87ceeb",
142
+ slateblue: "#6a5acd",
143
+ slategray: "#708090",
144
+ slategrey: "#708090",
145
+ snow: "#fffafa",
146
+ springgreen: "#00ff7f",
147
+ steelblue: "#4682b4",
148
+ tan: "#d2b48c",
149
+ teal: "#008080",
150
+ thistle: "#d8bfd8",
151
+ tomato: "#ff6347",
152
+ turquoise: "#40e0d0",
153
+ violet: "#ee82ee",
154
+ wheat: "#f5deb3",
155
+ white: "#ffffff",
156
+ whitesmoke: "#f5f5f5",
157
+ yellow: "#ffff00",
158
+ yellowgreen: "#9acd32",
159
+ };
160
+ const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
161
+ const formatRgba = ({ r, g, b, a }) => {
162
+ const alpha = Math.round(clamp(a, 0, 1) * 1000) / 1000;
163
+ return alpha >= 1
164
+ ? `rgb(${r}, ${g}, ${b})`
165
+ : `rgba(${r}, ${g}, ${b}, ${alpha})`;
166
+ };
167
+ const HEX_PATTERN = /^#([0-9a-f]+)$/i;
168
+ const hexPair = (digits, index) => Number.parseInt(digits.slice(index, index + 2), 16);
169
+ const hexSingle = (digits, index) => Number.parseInt(digits.charAt(index).repeat(2), 16);
170
+ const parseHex = (input) => {
171
+ const match = HEX_PATTERN.exec(input);
172
+ if (match === null) {
173
+ return null;
174
+ }
175
+ const digits = match[1] ?? "";
176
+ switch (digits.length) {
177
+ case 3:
178
+ return {
179
+ r: hexSingle(digits, 0),
180
+ g: hexSingle(digits, 1),
181
+ b: hexSingle(digits, 2),
182
+ a: 1,
183
+ };
184
+ case 4:
185
+ return {
186
+ r: hexSingle(digits, 0),
187
+ g: hexSingle(digits, 1),
188
+ b: hexSingle(digits, 2),
189
+ a: hexSingle(digits, 3) / 255,
190
+ };
191
+ case 6:
192
+ return {
193
+ r: hexPair(digits, 0),
194
+ g: hexPair(digits, 2),
195
+ b: hexPair(digits, 4),
196
+ a: 1,
197
+ };
198
+ case 8:
199
+ return {
200
+ r: hexPair(digits, 0),
201
+ g: hexPair(digits, 2),
202
+ b: hexPair(digits, 4),
203
+ a: hexPair(digits, 6) / 255,
204
+ };
205
+ default:
206
+ return null;
207
+ }
208
+ };
209
+ const NUMBER_PATTERN = /^[+-]?(?:\d+\.?\d*|\.\d+)$/;
210
+ const parseNumber = (token) => NUMBER_PATTERN.test(token) ? Number.parseFloat(token) : null;
211
+ // 0-255 integer or percentage → 0-255 integer.
212
+ const parseRgbChannel = (token) => {
213
+ if (token.endsWith("%")) {
214
+ const percent = parseNumber(token.slice(0, -1));
215
+ // (percent * 255) / 100 avoids float drift: 50 * 2.55 === 127.4999...
216
+ return percent === null
217
+ ? null
218
+ : Math.round((clamp(percent, 0, 100) * 255) / 100);
219
+ }
220
+ const value = parseNumber(token);
221
+ return value === null ? null : Math.round(clamp(value, 0, 255));
222
+ };
223
+ // 0-1 float or percentage → 0-1 float.
224
+ const parseAlpha = (token) => {
225
+ if (token.endsWith("%")) {
226
+ const percent = parseNumber(token.slice(0, -1));
227
+ return percent === null ? null : clamp(percent / 100, 0, 1);
228
+ }
229
+ const value = parseNumber(token);
230
+ return value === null ? null : clamp(value, 0, 1);
231
+ };
232
+ const parsePercentage = (token) => {
233
+ if (!token.endsWith("%")) {
234
+ return null;
235
+ }
236
+ const percent = parseNumber(token.slice(0, -1));
237
+ return percent === null ? null : clamp(percent / 100, 0, 1);
238
+ };
239
+ const parseHue = (token) => {
240
+ const raw = token.toLowerCase().endsWith("deg") ? token.slice(0, -3) : token;
241
+ const degrees = parseNumber(raw);
242
+ return degrees === null ? null : ((degrees % 360) + 360) % 360;
243
+ };
244
+ const hslToRgb = (h, s, l) => {
245
+ const chroma = (1 - Math.abs(2 * l - 1)) * s;
246
+ const hh = h / 60;
247
+ const x = chroma * (1 - Math.abs((hh % 2) - 1));
248
+ let rgb = [0, 0, 0];
249
+ if (hh < 1) {
250
+ rgb = [chroma, x, 0];
251
+ }
252
+ else if (hh < 2) {
253
+ rgb = [x, chroma, 0];
254
+ }
255
+ else if (hh < 3) {
256
+ rgb = [0, chroma, x];
257
+ }
258
+ else if (hh < 4) {
259
+ rgb = [0, x, chroma];
260
+ }
261
+ else if (hh < 5) {
262
+ rgb = [x, 0, chroma];
263
+ }
264
+ else {
265
+ rgb = [chroma, 0, x];
266
+ }
267
+ const m = l - chroma / 2;
268
+ return [
269
+ Math.round((rgb[0] + m) * 255),
270
+ Math.round((rgb[1] + m) * 255),
271
+ Math.round((rgb[2] + m) * 255),
272
+ ];
273
+ };
274
+ const FUNCTION_PATTERN = /^(rgba?|hsla?)\(([^()]*)\)$/i;
275
+ // Accepts legacy comma syntax and modern space syntax with optional "/ alpha".
276
+ const splitFunctionBody = (body) => body
277
+ .replace(/\//g, " ")
278
+ .split(/[,\s]+/)
279
+ .filter((token) => token.length > 0);
280
+ const parseColorFunction = (input) => {
281
+ const match = FUNCTION_PATTERN.exec(input);
282
+ if (match === null) {
283
+ return null;
284
+ }
285
+ const name = (match[1] ?? "").toLowerCase();
286
+ const tokens = splitFunctionBody(match[2] ?? "");
287
+ if (tokens.length < 3 || tokens.length > 4) {
288
+ return null;
289
+ }
290
+ const alpha = tokens.length === 4 ? parseAlpha(tokens[3] ?? "") : 1;
291
+ if (alpha === null) {
292
+ return null;
293
+ }
294
+ if (name === "rgb" || name === "rgba") {
295
+ const r = parseRgbChannel(tokens[0] ?? "");
296
+ const g = parseRgbChannel(tokens[1] ?? "");
297
+ const b = parseRgbChannel(tokens[2] ?? "");
298
+ if (r === null || g === null || b === null) {
299
+ return null;
300
+ }
301
+ return { r, g, b, a: alpha };
302
+ }
303
+ const h = parseHue(tokens[0] ?? "");
304
+ const s = parsePercentage(tokens[1] ?? "");
305
+ const l = parsePercentage(tokens[2] ?? "");
306
+ if (h === null || s === null || l === null) {
307
+ return null;
308
+ }
309
+ const [r, g, b] = hslToRgb(h, s, l);
310
+ return { r, g, b, a: alpha };
311
+ };
312
+ const CSS_VARIABLE_PATTERN = /^var\(--[\w-]+.*\)$/i;
313
+ const GTK_NAMED_COLOR_PATTERN = /^@[A-Za-z_][\w-]*$/;
314
+ /**
315
+ * Parses a React Native color string into a GTK4 CSS color value.
316
+ * Returns null for values that cannot be understood.
317
+ */
318
+ export const parseColor = (value) => {
319
+ if (typeof value !== "string") {
320
+ return null;
321
+ }
322
+ const input = value.trim();
323
+ if (input === "") {
324
+ return null;
325
+ }
326
+ // Adwaita/custom CSS variable references pass through untouched. The
327
+ // pattern is permissive on purpose: nested var() fallbacks stay valid.
328
+ if (input.toLowerCase().startsWith("var(")) {
329
+ return CSS_VARIABLE_PATTERN.test(input) ? input : null;
330
+ }
331
+ if (GTK_NAMED_COLOR_PATTERN.test(input)) {
332
+ return input;
333
+ }
334
+ const lower = input.toLowerCase();
335
+ if (lower === "transparent") {
336
+ return "rgba(0, 0, 0, 0)";
337
+ }
338
+ const named = NAMED_COLORS[lower];
339
+ const rgba = parseHex(named ?? input) ?? parseColorFunction(input);
340
+ return rgba === null ? null : formatRgba(rgba);
341
+ };
342
+ const toCssVariableName = (name) => name.startsWith("--") ? name : `--${name}`;
343
+ /**
344
+ * React Native's PlatformColor for GTK: references theme colors by name.
345
+ * Names map onto CSS variables (Adwaita exposes its palette as
346
+ * `--accent-bg-color`, `--window-bg-color`, ... since libadwaita 1.6);
347
+ * extra names become var() fallbacks, tried in order. A name starting with
348
+ * "@" is a legacy GTK named color (`@define-color`) and terminates the
349
+ * fallback chain, because var() fallbacks cannot resolve further after it.
350
+ *
351
+ * PlatformColor("accent-bg-color") → "var(--accent-bg-color)"
352
+ * PlatformColor("accent-bg-color", "@blue_3") → "var(--accent-bg-color, @blue_3)"
353
+ */
354
+ export const PlatformColor = (...names) => {
355
+ const cleaned = names.map((name) => name.trim()).filter((name) => name !== "");
356
+ if (cleaned.length === 0) {
357
+ throw new Error("PlatformColor requires at least one color name");
358
+ }
359
+ let expression = null;
360
+ for (let i = cleaned.length - 1; i >= 0; i -= 1) {
361
+ const name = cleaned[i] ?? "";
362
+ if (name.startsWith("@")) {
363
+ // Terminal value: names after it are unreachable fallbacks.
364
+ expression = name;
365
+ continue;
366
+ }
367
+ const variable = toCssVariableName(name);
368
+ expression =
369
+ expression === null
370
+ ? `var(${variable})`
371
+ : `var(${variable}, ${expression})`;
372
+ }
373
+ return expression ?? "";
374
+ };
375
+ //# sourceMappingURL=colors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.js","sourceRoot":"","sources":["../../src/style/colors.ts"],"names":[],"mappings":"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","sourcesContent":["// Pure color handling: parses React Native color strings and normalizes them\n// into GTK4 CSS color values. No bridge imports — unit-testable on any OS.\n//\n// Every parseable color is normalized to `rgb(r, g, b)` / `rgba(r, g, b, a)`\n// so the output does not depend on which color syntaxes the GTK CSS parser of\n// a particular version accepts. Two values pass through untouched:\n// - `var(--name[, fallback])` — CSS variables (GTK 4.16+, Adwaita palette)\n// - `@name` — legacy GTK named colors (`@define-color` references)\n\n// CSS Color Module Level 4 named colors (the set React Native supports).\nconst NAMED_COLORS: Record<string, string> = {\n aliceblue: \"#f0f8ff\",\n antiquewhite: \"#faebd7\",\n aqua: \"#00ffff\",\n aquamarine: \"#7fffd4\",\n azure: \"#f0ffff\",\n beige: \"#f5f5dc\",\n bisque: \"#ffe4c4\",\n black: \"#000000\",\n blanchedalmond: \"#ffebcd\",\n blue: \"#0000ff\",\n blueviolet: \"#8a2be2\",\n brown: \"#a52a2a\",\n burlywood: \"#deb887\",\n cadetblue: \"#5f9ea0\",\n chartreuse: \"#7fff00\",\n chocolate: \"#d2691e\",\n coral: \"#ff7f50\",\n cornflowerblue: \"#6495ed\",\n cornsilk: \"#fff8dc\",\n crimson: \"#dc143c\",\n cyan: \"#00ffff\",\n darkblue: \"#00008b\",\n darkcyan: \"#008b8b\",\n darkgoldenrod: \"#b8860b\",\n darkgray: \"#a9a9a9\",\n darkgreen: \"#006400\",\n darkgrey: \"#a9a9a9\",\n darkkhaki: \"#bdb76b\",\n darkmagenta: \"#8b008b\",\n darkolivegreen: \"#556b2f\",\n darkorange: \"#ff8c00\",\n darkorchid: \"#9932cc\",\n darkred: \"#8b0000\",\n darksalmon: \"#e9967a\",\n darkseagreen: \"#8fbc8f\",\n darkslateblue: \"#483d8b\",\n darkslategray: \"#2f4f4f\",\n darkslategrey: \"#2f4f4f\",\n darkturquoise: \"#00ced1\",\n darkviolet: \"#9400d3\",\n deeppink: \"#ff1493\",\n deepskyblue: \"#00bfff\",\n dimgray: \"#696969\",\n dimgrey: \"#696969\",\n dodgerblue: \"#1e90ff\",\n firebrick: \"#b22222\",\n floralwhite: \"#fffaf0\",\n forestgreen: \"#228b22\",\n fuchsia: \"#ff00ff\",\n gainsboro: \"#dcdcdc\",\n ghostwhite: \"#f8f8ff\",\n gold: \"#ffd700\",\n goldenrod: \"#daa520\",\n gray: \"#808080\",\n green: \"#008000\",\n greenyellow: \"#adff2f\",\n grey: \"#808080\",\n honeydew: \"#f0fff0\",\n hotpink: \"#ff69b4\",\n indianred: \"#cd5c5c\",\n indigo: \"#4b0082\",\n ivory: \"#fffff0\",\n khaki: \"#f0e68c\",\n lavender: \"#e6e6fa\",\n lavenderblush: \"#fff0f5\",\n lawngreen: \"#7cfc00\",\n lemonchiffon: \"#fffacd\",\n lightblue: \"#add8e6\",\n lightcoral: \"#f08080\",\n lightcyan: \"#e0ffff\",\n lightgoldenrodyellow: \"#fafad2\",\n lightgray: \"#d3d3d3\",\n lightgreen: \"#90ee90\",\n lightgrey: \"#d3d3d3\",\n lightpink: \"#ffb6c1\",\n lightsalmon: \"#ffa07a\",\n lightseagreen: \"#20b2aa\",\n lightskyblue: \"#87cefa\",\n lightslategray: \"#778899\",\n lightslategrey: \"#778899\",\n lightsteelblue: \"#b0c4de\",\n lightyellow: \"#ffffe0\",\n lime: \"#00ff00\",\n limegreen: \"#32cd32\",\n linen: \"#faf0e6\",\n magenta: \"#ff00ff\",\n maroon: \"#800000\",\n mediumaquamarine: \"#66cdaa\",\n mediumblue: \"#0000cd\",\n mediumorchid: \"#ba55d3\",\n mediumpurple: \"#9370db\",\n mediumseagreen: \"#3cb371\",\n mediumslateblue: \"#7b68ee\",\n mediumspringgreen: \"#00fa9a\",\n mediumturquoise: \"#48d1cc\",\n mediumvioletred: \"#c71585\",\n midnightblue: \"#191970\",\n mintcream: \"#f5fffa\",\n mistyrose: \"#ffe4e1\",\n moccasin: \"#ffe4b5\",\n navajowhite: \"#ffdead\",\n navy: \"#000080\",\n oldlace: \"#fdf5e6\",\n olive: \"#808000\",\n olivedrab: \"#6b8e23\",\n orange: \"#ffa500\",\n orangered: \"#ff4500\",\n orchid: \"#da70d6\",\n palegoldenrod: \"#eee8aa\",\n palegreen: \"#98fb98\",\n paleturquoise: \"#afeeee\",\n palevioletred: \"#db7093\",\n papayawhip: \"#ffefd5\",\n peachpuff: \"#ffdab9\",\n peru: \"#cd853f\",\n pink: \"#ffc0cb\",\n plum: \"#dda0dd\",\n powderblue: \"#b0e0e6\",\n purple: \"#800080\",\n rebeccapurple: \"#663399\",\n red: \"#ff0000\",\n rosybrown: \"#bc8f8f\",\n royalblue: \"#4169e1\",\n saddlebrown: \"#8b4513\",\n salmon: \"#fa8072\",\n sandybrown: \"#f4a460\",\n seagreen: \"#2e8b57\",\n seashell: \"#fff5ee\",\n sienna: \"#a0522d\",\n silver: \"#c0c0c0\",\n skyblue: \"#87ceeb\",\n slateblue: \"#6a5acd\",\n slategray: \"#708090\",\n slategrey: \"#708090\",\n snow: \"#fffafa\",\n springgreen: \"#00ff7f\",\n steelblue: \"#4682b4\",\n tan: \"#d2b48c\",\n teal: \"#008080\",\n thistle: \"#d8bfd8\",\n tomato: \"#ff6347\",\n turquoise: \"#40e0d0\",\n violet: \"#ee82ee\",\n wheat: \"#f5deb3\",\n white: \"#ffffff\",\n whitesmoke: \"#f5f5f5\",\n yellow: \"#ffff00\",\n yellowgreen: \"#9acd32\",\n}\n\ntype Rgba = { r: number; g: number; b: number; a: number }\n\nconst clamp = (value: number, min: number, max: number): number =>\n Math.min(max, Math.max(min, value))\n\nconst formatRgba = ({ r, g, b, a }: Rgba): string => {\n const alpha = Math.round(clamp(a, 0, 1) * 1000) / 1000\n return alpha >= 1\n ? `rgb(${r}, ${g}, ${b})`\n : `rgba(${r}, ${g}, ${b}, ${alpha})`\n}\n\nconst HEX_PATTERN = /^#([0-9a-f]+)$/i\n\nconst hexPair = (digits: string, index: number): number =>\n Number.parseInt(digits.slice(index, index + 2), 16)\n\nconst hexSingle = (digits: string, index: number): number =>\n Number.parseInt(digits.charAt(index).repeat(2), 16)\n\nconst parseHex = (input: string): Rgba | null => {\n const match = HEX_PATTERN.exec(input)\n if (match === null) {\n return null\n }\n const digits = match[1] ?? \"\"\n switch (digits.length) {\n case 3:\n return {\n r: hexSingle(digits, 0),\n g: hexSingle(digits, 1),\n b: hexSingle(digits, 2),\n a: 1,\n }\n case 4:\n return {\n r: hexSingle(digits, 0),\n g: hexSingle(digits, 1),\n b: hexSingle(digits, 2),\n a: hexSingle(digits, 3) / 255,\n }\n case 6:\n return {\n r: hexPair(digits, 0),\n g: hexPair(digits, 2),\n b: hexPair(digits, 4),\n a: 1,\n }\n case 8:\n return {\n r: hexPair(digits, 0),\n g: hexPair(digits, 2),\n b: hexPair(digits, 4),\n a: hexPair(digits, 6) / 255,\n }\n default:\n return null\n }\n}\n\nconst NUMBER_PATTERN = /^[+-]?(?:\\d+\\.?\\d*|\\.\\d+)$/\n\nconst parseNumber = (token: string): number | null =>\n NUMBER_PATTERN.test(token) ? Number.parseFloat(token) : null\n\n// 0-255 integer or percentage → 0-255 integer.\nconst parseRgbChannel = (token: string): number | null => {\n if (token.endsWith(\"%\")) {\n const percent = parseNumber(token.slice(0, -1))\n // (percent * 255) / 100 avoids float drift: 50 * 2.55 === 127.4999...\n return percent === null\n ? null\n : Math.round((clamp(percent, 0, 100) * 255) / 100)\n }\n const value = parseNumber(token)\n return value === null ? null : Math.round(clamp(value, 0, 255))\n}\n\n// 0-1 float or percentage → 0-1 float.\nconst parseAlpha = (token: string): number | null => {\n if (token.endsWith(\"%\")) {\n const percent = parseNumber(token.slice(0, -1))\n return percent === null ? null : clamp(percent / 100, 0, 1)\n }\n const value = parseNumber(token)\n return value === null ? null : clamp(value, 0, 1)\n}\n\nconst parsePercentage = (token: string): number | null => {\n if (!token.endsWith(\"%\")) {\n return null\n }\n const percent = parseNumber(token.slice(0, -1))\n return percent === null ? null : clamp(percent / 100, 0, 1)\n}\n\nconst parseHue = (token: string): number | null => {\n const raw = token.toLowerCase().endsWith(\"deg\") ? token.slice(0, -3) : token\n const degrees = parseNumber(raw)\n return degrees === null ? null : ((degrees % 360) + 360) % 360\n}\n\nconst hslToRgb = (\n h: number,\n s: number,\n l: number,\n): [number, number, number] => {\n const chroma = (1 - Math.abs(2 * l - 1)) * s\n const hh = h / 60\n const x = chroma * (1 - Math.abs((hh % 2) - 1))\n let rgb: [number, number, number] = [0, 0, 0]\n if (hh < 1) {\n rgb = [chroma, x, 0]\n } else if (hh < 2) {\n rgb = [x, chroma, 0]\n } else if (hh < 3) {\n rgb = [0, chroma, x]\n } else if (hh < 4) {\n rgb = [0, x, chroma]\n } else if (hh < 5) {\n rgb = [x, 0, chroma]\n } else {\n rgb = [chroma, 0, x]\n }\n const m = l - chroma / 2\n return [\n Math.round((rgb[0] + m) * 255),\n Math.round((rgb[1] + m) * 255),\n Math.round((rgb[2] + m) * 255),\n ]\n}\n\nconst FUNCTION_PATTERN = /^(rgba?|hsla?)\\(([^()]*)\\)$/i\n\n// Accepts legacy comma syntax and modern space syntax with optional \"/ alpha\".\nconst splitFunctionBody = (body: string): string[] =>\n body\n .replace(/\\//g, \" \")\n .split(/[,\\s]+/)\n .filter((token) => token.length > 0)\n\nconst parseColorFunction = (input: string): Rgba | null => {\n const match = FUNCTION_PATTERN.exec(input)\n if (match === null) {\n return null\n }\n const name = (match[1] ?? \"\").toLowerCase()\n const tokens = splitFunctionBody(match[2] ?? \"\")\n if (tokens.length < 3 || tokens.length > 4) {\n return null\n }\n const alpha = tokens.length === 4 ? parseAlpha(tokens[3] ?? \"\") : 1\n if (alpha === null) {\n return null\n }\n if (name === \"rgb\" || name === \"rgba\") {\n const r = parseRgbChannel(tokens[0] ?? \"\")\n const g = parseRgbChannel(tokens[1] ?? \"\")\n const b = parseRgbChannel(tokens[2] ?? \"\")\n if (r === null || g === null || b === null) {\n return null\n }\n return { r, g, b, a: alpha }\n }\n const h = parseHue(tokens[0] ?? \"\")\n const s = parsePercentage(tokens[1] ?? \"\")\n const l = parsePercentage(tokens[2] ?? \"\")\n if (h === null || s === null || l === null) {\n return null\n }\n const [r, g, b] = hslToRgb(h, s, l)\n return { r, g, b, a: alpha }\n}\n\nconst CSS_VARIABLE_PATTERN = /^var\\(--[\\w-]+.*\\)$/i\nconst GTK_NAMED_COLOR_PATTERN = /^@[A-Za-z_][\\w-]*$/\n\n/**\n * Parses a React Native color string into a GTK4 CSS color value.\n * Returns null for values that cannot be understood.\n */\nexport const parseColor = (value: string): string | null => {\n if (typeof value !== \"string\") {\n return null\n }\n const input = value.trim()\n if (input === \"\") {\n return null\n }\n // Adwaita/custom CSS variable references pass through untouched. The\n // pattern is permissive on purpose: nested var() fallbacks stay valid.\n if (input.toLowerCase().startsWith(\"var(\")) {\n return CSS_VARIABLE_PATTERN.test(input) ? input : null\n }\n if (GTK_NAMED_COLOR_PATTERN.test(input)) {\n return input\n }\n const lower = input.toLowerCase()\n if (lower === \"transparent\") {\n return \"rgba(0, 0, 0, 0)\"\n }\n const named = NAMED_COLORS[lower]\n const rgba = parseHex(named ?? input) ?? parseColorFunction(input)\n return rgba === null ? null : formatRgba(rgba)\n}\n\nconst toCssVariableName = (name: string): string =>\n name.startsWith(\"--\") ? name : `--${name}`\n\n/**\n * React Native's PlatformColor for GTK: references theme colors by name.\n * Names map onto CSS variables (Adwaita exposes its palette as\n * `--accent-bg-color`, `--window-bg-color`, ... since libadwaita 1.6);\n * extra names become var() fallbacks, tried in order. A name starting with\n * \"@\" is a legacy GTK named color (`@define-color`) and terminates the\n * fallback chain, because var() fallbacks cannot resolve further after it.\n *\n * PlatformColor(\"accent-bg-color\") → \"var(--accent-bg-color)\"\n * PlatformColor(\"accent-bg-color\", \"@blue_3\") → \"var(--accent-bg-color, @blue_3)\"\n */\nexport const PlatformColor = (...names: string[]): string => {\n const cleaned = names.map((name) => name.trim()).filter((name) => name !== \"\")\n if (cleaned.length === 0) {\n throw new Error(\"PlatformColor requires at least one color name\")\n }\n let expression: string | null = null\n for (let i = cleaned.length - 1; i >= 0; i -= 1) {\n const name = cleaned[i] ?? \"\"\n if (name.startsWith(\"@\")) {\n // Terminal value: names after it are unreachable fallbacks.\n expression = name\n continue\n }\n const variable = toCssVariableName(name)\n expression =\n expression === null\n ? `var(${variable})`\n : `var(${variable}, ${expression})`\n }\n return expression ?? \"\"\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare const warnOnce: (key: string, message: string) => void;
2
+ export declare const resetDevWarnings: () => void;