react-native-gtkx 0.2.0-alpha.1 → 0.2.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -2
- package/dist/adw/widgets.generated.d.ts +4 -4
- package/dist/adw/widgets.generated.js +51 -51
- package/dist/adw/widgets.generated.js.map +1 -1
- package/dist/animated/create-animated.d.ts +2 -0
- package/dist/animated/create-animated.js +2 -0
- package/dist/animated/create-animated.js.map +1 -1
- package/dist/animated/index.d.ts +2 -0
- package/dist/animated/index.js +1 -0
- package/dist/animated/index.js.map +1 -1
- package/dist/animated/value-xy.d.ts +41 -0
- package/dist/animated/value-xy.js +90 -0
- package/dist/animated/value-xy.js.map +1 -0
- package/dist/animated/value.d.ts +9 -0
- package/dist/animated/value.js +30 -2
- package/dist/animated/value.js.map +1 -1
- package/dist/common/icon.d.ts +23 -0
- package/dist/common/icon.js +14 -0
- package/dist/common/icon.js.map +1 -0
- package/dist/common/index.d.ts +2 -0
- package/dist/common/index.js +2 -0
- package/dist/common/index.js.map +1 -1
- package/dist/common/list.d.ts +82 -0
- package/dist/common/list.js +166 -0
- package/dist/common/list.js.map +1 -0
- package/dist/common/widget.d.ts +1 -22
- package/dist/common/widget.js +75 -8
- package/dist/common/widget.js.map +1 -1
- package/dist/components/animated.d.ts +4 -2
- package/dist/components/animated.js +3 -1
- package/dist/components/animated.js.map +1 -1
- package/dist/components/app-registry.d.ts +26 -0
- package/dist/components/app-registry.js.map +1 -1
- package/dist/components/host-node.d.ts +7 -0
- package/dist/components/host-node.js +26 -1
- package/dist/components/host-node.js.map +1 -1
- package/dist/components/index.d.ts +6 -2
- package/dist/components/index.js +2 -1
- package/dist/components/index.js.map +1 -1
- package/dist/components/measure.d.ts +13 -0
- package/dist/components/measure.js +51 -0
- package/dist/components/measure.js.map +1 -0
- package/dist/components/modal.d.ts +1 -1
- package/dist/components/press-event.d.ts +28 -0
- package/dist/components/press-event.js +46 -0
- package/dist/components/press-event.js.map +1 -0
- package/dist/components/pressable.d.ts +2 -6
- package/dist/components/pressable.js +14 -8
- package/dist/components/pressable.js.map +1 -1
- package/dist/components/scroll-view.d.ts +4 -0
- package/dist/components/scroll-view.js +8 -2
- package/dist/components/scroll-view.js.map +1 -1
- package/dist/components/text-input.js +1 -1
- package/dist/components/text-input.js.map +1 -1
- package/dist/components/text.js +25 -1
- package/dist/components/text.js.map +1 -1
- package/dist/components/use-layout-child.js +17 -14
- package/dist/components/use-layout-child.js.map +1 -1
- package/dist/components/view.d.ts +9 -4
- package/dist/components/view.js +8 -2
- package/dist/components/view.js.map +1 -1
- package/dist/contracts.d.ts +19 -3
- package/dist/contracts.js.map +1 -1
- package/dist/gtk/index.d.ts +2 -1
- package/dist/gtk/index.js +8 -1
- package/dist/gtk/index.js.map +1 -1
- package/dist/gtk/widgets.generated.d.ts +14 -14
- package/dist/gtk/widgets.generated.js +101 -102
- package/dist/gtk/widgets.generated.js.map +1 -1
- package/dist/gtk/window-actions.d.ts +77 -0
- package/dist/gtk/window-actions.js +193 -0
- package/dist/gtk/window-actions.js.map +1 -0
- package/dist/gtkx/bridge/geometry.d.ts +15 -0
- package/dist/gtkx/bridge/geometry.js +38 -0
- package/dist/gtkx/bridge/geometry.js.map +1 -0
- package/dist/gtkx/bridge/index.d.ts +2 -0
- package/dist/gtkx/bridge/index.js +7 -2
- package/dist/gtkx/bridge/index.js.map +1 -1
- package/dist/gtkx/bridge/slot-portal.d.ts +12 -0
- package/dist/gtkx/bridge/slot-portal.js +17 -0
- package/dist/gtkx/bridge/slot-portal.js.map +1 -0
- package/dist/gtkx/bridge/svg-node.js +10 -54
- package/dist/gtkx/bridge/svg-node.js.map +1 -1
- package/dist/gtkx/bridge/use-signal.js +2 -2
- package/dist/gtkx/bridge/use-signal.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/data/generated.d.ts +99 -77
- package/dist/mcp/data/generated.js +107 -76
- package/dist/mcp/data/generated.js.map +1 -1
- package/dist/mcp/server.js +1 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/navigation/sidebar.d.ts +31 -1
- package/dist/navigation/sidebar.js +12 -2
- package/dist/navigation/sidebar.js.map +1 -1
- package/dist/responder/system.d.ts +27 -0
- package/dist/responder/system.js +184 -0
- package/dist/responder/system.js.map +1 -0
- package/dist/responder/touch-history.d.ts +10 -0
- package/dist/responder/touch-history.js +78 -0
- package/dist/responder/touch-history.js.map +1 -0
- package/dist/responder/types.d.ts +63 -0
- package/dist/responder/types.js +29 -0
- package/dist/responder/types.js.map +1 -0
- package/dist/responder/use-responder.d.ts +12 -0
- package/dist/responder/use-responder.js +98 -0
- package/dist/responder/use-responder.js.map +1 -0
- package/dist/runner/host-dev.js +3 -1
- package/dist/runner/host-dev.js.map +1 -1
- package/dist/runner/host.js +5 -1
- package/dist/runner/host.js.map +1 -1
- package/dist/runner/index.js +1 -1
- package/dist/runner/index.js.map +1 -1
- package/dist/sea/gtkx-config-module.js +1 -1
- package/dist/sea/gtkx-config-module.js.map +1 -1
- package/dist/style/box-shadow.d.ts +7 -0
- package/dist/style/box-shadow.js +197 -0
- package/dist/style/box-shadow.js.map +1 -0
- package/dist/style/index.d.ts +2 -0
- package/dist/style/index.js +2 -0
- package/dist/style/index.js.map +1 -1
- package/dist/style/split-style.d.ts +5 -2
- package/dist/style/split-style.js +31 -3
- package/dist/style/split-style.js.map +1 -1
- package/dist/style/text-decoration.d.ts +15 -0
- package/dist/style/text-decoration.js +26 -0
- package/dist/style/text-decoration.js.map +1 -0
- package/dist/style/visual-css.js +37 -1
- package/dist/style/visual-css.js.map +1 -1
- package/dist/svg/gradient-geometry.js +2 -5
- package/dist/svg/gradient-geometry.js.map +1 -1
- package/dist/testing/index.js.map +1 -1
- package/dist/vendor/react-native/pan-responder.d.ts +102 -0
- package/dist/vendor/react-native/pan-responder.js +196 -0
- package/dist/vendor/react-native/pan-responder.js.map +1 -0
- package/dist/vendor/react-native/touch-history-math.d.ts +18 -0
- package/dist/vendor/react-native/touch-history-math.js +102 -0
- package/dist/vendor/react-native/touch-history-math.js.map +1 -0
- package/dist/vite/index.js +1 -1
- package/dist/vite/index.js.map +1 -1
- package/dist/vitest/index.d.ts +1 -1
- package/dist/vitest/index.js.map +1 -1
- package/package.json +9 -9
package/dist/runner/index.js.map
CHANGED
|
@@ -1 +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\ntype CliConfig = { root: string }\ntype RunLinuxArgs = {\n entryFile: string\n bundleOutput?: string\n skipBundling?: boolean\n dev?: boolean\n port?: string\n}\ntype BuildLinuxArgs = {\n entryFile: string\n bundleOutput?: string\n standalone?: boolean\n sea?: boolean\n seaOutput?: 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\ntype PackageManifest = { version: string; exports?: Record<string, unknown> }\n\n/** The `@gtkx/react` subpath exports (its own `exports` map, minus `.` and `./package.json`). */\nconst reactSubexportsOf = (manifest: PackageManifest): string[] =>\n Object.keys(manifest.exports ?? {})\n .filter((key) => key.startsWith(\"./\") && key !== \"./package.json\")\n .map((key) => key.slice(2))\n\n// @gtkx/cli is meant for apps: its `codegen` command resolves gtkx.config.ts\n// from a cwd and trusts a freshness stamp, which is what the RC2-WORKAROUND\n// this replaced was dodging (running from a reconstructed \"project that owns\n// the hosting node_modules\" purely to keep that cwd resolution honest — see\n// gtkx-org/gtkx#468, #470). A library generating bindings on a consumer's\n// behalf should use the programmatic @gtkx/codegen API instead: it takes the\n// GIR libraries and store paths directly, so there is no cwd to get wrong and\n// no stamp to misread — and it runs its own fingerprint-based freshness\n// check in-process, so a missing/pruned store is regenerated rather than\n// misreported as \"up to date\".\n//\n// `root` (the app's real project root, resolved by the react-native CLI, not\n// us) is the right place to resolve gtkx.config.ts from, but NOT necessarily\n// where @gtkx/* actually lives on disk: in a workspace, npm hoists them to an\n// ancestor's node_modules, so `root/node_modules` can be a directory with no\n// @gtkx/* in it at all (confirmed against this repo's own examples/, which\n// are workspace members with nothing hoisted locally). The store — and the\n// @gtkx/gi and @gtkx/jsx links every other @gtkx/* package resolves through\n// its OWN up-the-tree lookup — must live in whichever node_modules actually\n// hosts @gtkx/runtime, so that's resolved rather than assumed.\nconst ensureCodegenStore = async (root: string): Promise<void> => {\n console.warn(\"[react-native-gtkx] ensuring gtkx codegen store…\")\n try {\n const [{ runCodegen, resolveGirPath, resolveLibraries }, { loadConfig }] =\n await Promise.all([import(\"@gtkx/codegen\"), import(\"@gtkx/config\")])\n const { config } = await loadConfig(root)\n if (config.codegen === false) {\n console.warn(\n \"[react-native-gtkx] codegen: disabled for this project (gtkx.config.ts)\",\n )\n return\n }\n const girPath = resolveGirPath(config.girPath)\n const libraries = resolveLibraries(config.libraries, girPath)\n const appRequire = createRequire(join(root, \"package.json\"))\n const runtimePackageJsonPath = appRequire.resolve(\n \"@gtkx/runtime/package.json\",\n )\n const nodeModules = dirname(dirname(dirname(runtimePackageJsonPath)))\n const runtime = appRequire(runtimePackageJsonPath) as PackageManifest\n const react = appRequire(\"@gtkx/react/package.json\") as PackageManifest\n const result = await runCodegen({\n libraries,\n girPath,\n gi: {\n storeDir: join(nodeModules, \".gtkx\", \"gi\"),\n linkDir: join(nodeModules, \"@gtkx\", \"gi\"),\n version: runtime.version,\n },\n jsx: {\n storeDir: join(nodeModules, \".gtkx\", \"jsx\"),\n linkDir: join(nodeModules, \"@gtkx\", \"jsx\"),\n version: react.version,\n },\n reactSubexports: reactSubexportsOf(react),\n })\n console.warn(\n result.regenerated\n ? \"[react-native-gtkx] codegen: regenerated stale bindings\"\n : \"[react-native-gtkx] codegen: bindings up to date\",\n )\n } catch (error) {\n console.error(\n \"[react-native-gtkx] gtkx codegen failed — are GTK4/libadwaita \" +\n \"development files installed?\",\n )\n console.error(error)\n process.exit(1)\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 // join over `new URL(script, import.meta.url)`: the global URL and the\n // node:url URL come from different type copies when the dependency tree\n // splits @types/node, and the two structurally diverge.\n const hostPath = join(dirname(fileURLToPath(import.meta.url)), script)\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 await ensureCodegenStore(config.root)\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/**\n * The executable name a `--sea` build defaults to: the app's package name\n * without its scope, so the artifact is `dist/hn-app`, not `dist/app`.\n */\nconst appBinaryName = (root: string): string => {\n try {\n const manifest = createRequire(join(root, \"package.json\"))(\n \"./package.json\",\n ) as { name?: string }\n const name = manifest.name?.split(\"/\").pop()\n return name && /^[\\w.-]+$/.test(name) ? name : \"app\"\n } catch {\n return \"app\"\n }\n}\n\n// The android/ios counterpart to run-linux's dev-only bundling: bundle for\n// distribution and stop, the way a release APK/IPA build does not launch\n// the app it produces. Deliberately skips ensureCodegenStore() — codegen\n// generates the @gtkx/gi bindings host.js imports to talk to GTK at RUN\n// time; bundling never touches them (Metro only reads/transforms JS, and\n// the GTK/react/yoga modules are proxied rather than imported — see\n// ../metro's HOST_MODULE_EXTERNALS). A machine that only builds never needs\n// GTK dev headers installed.\n//\n// --standalone and --sea are the exception: both inline\n// \"virtual:gtkx-config\", which re-exports @gtkx/jsx/metadata — a codegen\n// product — so they DO need the store, and therefore GTK dev headers.\n// Only those paths ensure it.\n//\n// The three artifacts, cheapest to heaviest, are deliberately one command\n// with flags rather than three commands: they share the Metro bundle step,\n// and the choice between them is a distribution question, not a different\n// build.\n// (default) main.jsbundle + a runtime node_modules + a system node\n// --standalone one .cjs file, no node_modules, + a system node\n// --sea one executable, nothing preinstalled at all\nconst buildLinux = async (\n _argv: string[],\n config: CliConfig,\n args: BuildLinuxArgs,\n): Promise<void> => {\n if (args.sea || args.standalone) {\n await ensureCodegenStore(config.root)\n }\n const output = args.bundleOutput ?? join(config.root, \"dist\", \"main.jsbundle\")\n mkdirSync(dirname(output), { recursive: true })\n bundle(config.root, args.entryFile, output)\n console.warn(`[react-native-gtkx] wrote the release bundle to ${output}`)\n if (!args.sea && !args.standalone) {\n return\n }\n const name = appBinaryName(config.root)\n const seaOutput =\n args.seaOutput ?? join(config.root, \"dist\", args.sea ? name : `${name}.cjs`)\n // Dynamically imported so the bundler is never loaded on the ordinary\n // jsbundle path.\n const { assembleSea, bundleStandalone } = await import(\"../sea/assemble.js\")\n const bytes = args.sea\n ? await assembleSea({\n appRoot: config.root,\n jsbundlePath: output,\n outFile: seaOutput,\n })\n : await bundleStandalone({\n appRoot: config.root,\n jsbundlePath: output,\n outFile: seaOutput,\n })\n const megabytes = (bytes / 1024 / 1024).toFixed(0)\n console.warn(\n args.sea\n ? `[react-native-gtkx] wrote the single executable to ${seaOutput} ` +\n `(${megabytes} MB — Node itself is most of it)`\n : `[react-native-gtkx] wrote the standalone script to ${seaOutput} ` +\n `(${megabytes} MB — run it with \\`node ${seaOutput}\\`)`,\n )\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 name: \"build-linux\",\n description:\n \"Bundle the app with Metro for the linux platform for distribution, without running it\",\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 release jsbundle (default: dist/main.jsbundle)\",\n },\n {\n name: \"--standalone\",\n description:\n \"Also produce one self-contained .cjs — no node_modules, run it \" +\n \"with a system node (dist/<package name>.cjs)\",\n },\n {\n name: \"--sea\",\n description:\n \"Also produce a single executable (Node SEA): one file that runs \" +\n \"with no node_modules and no system Node — at the cost of \" +\n \"carrying a whole Node binary (~120 MB)\",\n },\n {\n name: \"--sea-output <path>\",\n description:\n \"Where to write the --sea / --standalone artifact \" +\n \"(default: dist/<package name>[.cjs])\",\n },\n ],\n func: buildLinux,\n },\n]\n"]}
|
|
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\ntype CliConfig = { root: string }\ntype RunLinuxArgs = {\n entryFile: string\n bundleOutput?: string\n skipBundling?: boolean\n dev?: boolean\n port?: string\n}\ntype BuildLinuxArgs = {\n entryFile: string\n bundleOutput?: string\n standalone?: boolean\n sea?: boolean\n seaOutput?: 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\ntype PackageManifest = { version: string; exports?: Record<string, unknown> }\n\n/** The `@gtkx/react` subpath exports (its own `exports` map, minus `.` and `./package.json`). */\nconst reactSubexportsOf = (manifest: PackageManifest): string[] =>\n Object.keys(manifest.exports ?? {})\n .filter((key) => key.startsWith(\"./\") && key !== \"./package.json\")\n .map((key) => key.slice(2))\n\n// @gtkx/cli is meant for apps: its `codegen` command resolves gtkx.config.ts\n// from a cwd and trusts a freshness stamp, which is what the RC3-WORKAROUND\n// this replaced was dodging (running from a reconstructed \"project that owns\n// the hosting node_modules\" purely to keep that cwd resolution honest — see\n// gtkx-org/gtkx#468, #470). A library generating bindings on a consumer's\n// behalf should use the programmatic @gtkx/codegen API instead: it takes the\n// GIR libraries and store paths directly, so there is no cwd to get wrong and\n// no stamp to misread — and it runs its own fingerprint-based freshness\n// check in-process, so a missing/pruned store is regenerated rather than\n// misreported as \"up to date\".\n//\n// `root` (the app's real project root, resolved by the react-native CLI, not\n// us) is the right place to resolve gtkx.config.ts from, but NOT necessarily\n// where @gtkx/* actually lives on disk: in a workspace, npm hoists them to an\n// ancestor's node_modules, so `root/node_modules` can be a directory with no\n// @gtkx/* in it at all (confirmed against this repo's own examples/, which\n// are workspace members with nothing hoisted locally). The store — and the\n// @gtkx/gi and @gtkx/jsx links every other @gtkx/* package resolves through\n// its OWN up-the-tree lookup — must live in whichever node_modules actually\n// hosts @gtkx/runtime, so that's resolved rather than assumed.\nconst ensureCodegenStore = async (root: string): Promise<void> => {\n console.warn(\"[react-native-gtkx] ensuring gtkx codegen store…\")\n try {\n const [{ runCodegen, resolveGirPath, resolveLibraries }, { loadConfig }] =\n await Promise.all([import(\"@gtkx/codegen\"), import(\"@gtkx/config\")])\n const { config } = await loadConfig(root)\n if (config.codegen === false) {\n console.warn(\n \"[react-native-gtkx] codegen: disabled for this project (gtkx.config.ts)\",\n )\n return\n }\n const girPath = resolveGirPath(config.girPath)\n const libraries = resolveLibraries(config.libraries, girPath)\n const appRequire = createRequire(join(root, \"package.json\"))\n const runtimePackageJsonPath = appRequire.resolve(\n \"@gtkx/runtime/package.json\",\n )\n const nodeModules = dirname(dirname(dirname(runtimePackageJsonPath)))\n const runtime = appRequire(runtimePackageJsonPath) as PackageManifest\n const react = appRequire(\"@gtkx/react/package.json\") as PackageManifest\n const result = await runCodegen({\n libraries,\n girPath,\n gi: {\n storeDir: join(nodeModules, \".gtkx\", \"gi\"),\n linkDir: join(nodeModules, \"@gtkx\", \"gi\"),\n version: runtime.version,\n },\n jsx: {\n storeDir: join(nodeModules, \".gtkx\", \"jsx\"),\n linkDir: join(nodeModules, \"@gtkx\", \"jsx\"),\n version: react.version,\n },\n reactSubexports: reactSubexportsOf(react),\n })\n console.warn(\n result.regenerated\n ? \"[react-native-gtkx] codegen: regenerated stale bindings\"\n : \"[react-native-gtkx] codegen: bindings up to date\",\n )\n } catch (error) {\n console.error(\n \"[react-native-gtkx] gtkx codegen failed — are GTK4/libadwaita \" +\n \"development files installed?\",\n )\n console.error(error)\n process.exit(1)\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 // join over `new URL(script, import.meta.url)`: the global URL and the\n // node:url URL come from different type copies when the dependency tree\n // splits @types/node, and the two structurally diverge.\n const hostPath = join(dirname(fileURLToPath(import.meta.url)), script)\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 await ensureCodegenStore(config.root)\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/**\n * The executable name a `--sea` build defaults to: the app's package name\n * without its scope, so the artifact is `dist/hn-app`, not `dist/app`.\n */\nconst appBinaryName = (root: string): string => {\n try {\n const manifest = createRequire(join(root, \"package.json\"))(\n \"./package.json\",\n ) as { name?: string }\n const name = manifest.name?.split(\"/\").pop()\n return name && /^[\\w.-]+$/.test(name) ? name : \"app\"\n } catch {\n return \"app\"\n }\n}\n\n// The android/ios counterpart to run-linux's dev-only bundling: bundle for\n// distribution and stop, the way a release APK/IPA build does not launch\n// the app it produces. Deliberately skips ensureCodegenStore() — codegen\n// generates the @gtkx/gi bindings host.js imports to talk to GTK at RUN\n// time; bundling never touches them (Metro only reads/transforms JS, and\n// the GTK/react/yoga modules are proxied rather than imported — see\n// ../metro's HOST_MODULE_EXTERNALS). A machine that only builds never needs\n// GTK dev headers installed.\n//\n// --standalone and --sea are the exception: both inline\n// \"virtual:gtkx-config\", which re-exports @gtkx/jsx/metadata — a codegen\n// product — so they DO need the store, and therefore GTK dev headers.\n// Only those paths ensure it.\n//\n// The three artifacts, cheapest to heaviest, are deliberately one command\n// with flags rather than three commands: they share the Metro bundle step,\n// and the choice between them is a distribution question, not a different\n// build.\n// (default) main.jsbundle + a runtime node_modules + a system node\n// --standalone one .cjs file, no node_modules, + a system node\n// --sea one executable, nothing preinstalled at all\nconst buildLinux = async (\n _argv: string[],\n config: CliConfig,\n args: BuildLinuxArgs,\n): Promise<void> => {\n if (args.sea || args.standalone) {\n await ensureCodegenStore(config.root)\n }\n const output = args.bundleOutput ?? join(config.root, \"dist\", \"main.jsbundle\")\n mkdirSync(dirname(output), { recursive: true })\n bundle(config.root, args.entryFile, output)\n console.warn(`[react-native-gtkx] wrote the release bundle to ${output}`)\n if (!args.sea && !args.standalone) {\n return\n }\n const name = appBinaryName(config.root)\n const seaOutput =\n args.seaOutput ?? join(config.root, \"dist\", args.sea ? name : `${name}.cjs`)\n // Dynamically imported so the bundler is never loaded on the ordinary\n // jsbundle path.\n const { assembleSea, bundleStandalone } = await import(\"../sea/assemble.js\")\n const bytes = args.sea\n ? await assembleSea({\n appRoot: config.root,\n jsbundlePath: output,\n outFile: seaOutput,\n })\n : await bundleStandalone({\n appRoot: config.root,\n jsbundlePath: output,\n outFile: seaOutput,\n })\n const megabytes = (bytes / 1024 / 1024).toFixed(0)\n console.warn(\n args.sea\n ? `[react-native-gtkx] wrote the single executable to ${seaOutput} ` +\n `(${megabytes} MB — Node itself is most of it)`\n : `[react-native-gtkx] wrote the standalone script to ${seaOutput} ` +\n `(${megabytes} MB — run it with \\`node ${seaOutput}\\`)`,\n )\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 name: \"build-linux\",\n description:\n \"Bundle the app with Metro for the linux platform for distribution, without running it\",\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 release jsbundle (default: dist/main.jsbundle)\",\n },\n {\n name: \"--standalone\",\n description:\n \"Also produce one self-contained .cjs — no node_modules, run it \" +\n \"with a system node (dist/<package name>.cjs)\",\n },\n {\n name: \"--sea\",\n description:\n \"Also produce a single executable (Node SEA): one file that runs \" +\n \"with no node_modules and no system Node — at the cost of \" +\n \"carrying a whole Node binary (~120 MB)\",\n },\n {\n name: \"--sea-output <path>\",\n description:\n \"Where to write the --sea / --standalone artifact \" +\n \"(default: dist/<package name>[.cjs])\",\n },\n ],\n func: buildLinux,\n },\n]\n"]}
|
|
@@ -24,7 +24,7 @@ export const CONFIG_REQUIRED = "gtkx.config.ts with an applicationId is required
|
|
|
24
24
|
*/
|
|
25
25
|
export const buildGtkxConfigModule = async (appRoot) => {
|
|
26
26
|
const loader = createConfigLoader();
|
|
27
|
-
const config = await loader(appRoot).catch((error) => {
|
|
27
|
+
const config = await loader.resolve(appRoot).catch((error) => {
|
|
28
28
|
throw new Error(`${CONFIG_REQUIRED}\n${String(error)}`);
|
|
29
29
|
});
|
|
30
30
|
if (!config.applicationId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gtkx-config-module.js","sourceRoot":"","sources":["../../src/sea/gtkx-config-module.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,wEAAwE;AACxE,0EAA0E;AAC1E,mEAAmE;AACnE,mEAAmE;AACnE,qEAAqE;AACrE,mEAAmE;AACnE,0EAA0E;AAC1E,yEAAyE;AACzE,EAAE;AACF,mEAAmE;AACnE,sEAAsE;AACtE,0EAA0E;AAC1E,yEAAyE;AACzE,yEAAyE;AACzE,oEAAoE;AACpE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAG1D,MAAM,CAAC,MAAM,eAAe,GAC1B,mEAAmE;IACnE,4EAA4E,CAAA;AAE9E;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,EACxC,OAAe,EACE,EAAE;IACnB,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAA;IACnC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"gtkx-config-module.js","sourceRoot":"","sources":["../../src/sea/gtkx-config-module.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,wEAAwE;AACxE,0EAA0E;AAC1E,mEAAmE;AACnE,mEAAmE;AACnE,qEAAqE;AACrE,mEAAmE;AACnE,0EAA0E;AAC1E,yEAAyE;AACzE,EAAE;AACF,mEAAmE;AACnE,sEAAsE;AACtE,0EAA0E;AAC1E,yEAAyE;AACzE,yEAAyE;AACzE,oEAAoE;AACpE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAG1D,MAAM,CAAC,MAAM,eAAe,GAC1B,mEAAmE;IACnE,4EAA4E,CAAA;AAE9E;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,EACxC,OAAe,EACE,EAAE;IACnB,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAA;IACnC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;QACpE,MAAM,IAAI,KAAK,CAAC,GAAG,eAAe,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IACzD,CAAC,CAAC,CAAA;IACF,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAA;IAClC,CAAC;IACD,iEAAiE;IACjE,uEAAuE;IACvE,wEAAwE;IACxE,4BAA4B;IAC5B,IAAI,MAAM,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,oEAAoE;YAClE,sDAAsD,CACzD,CAAA;IACH,CAAC;IACD,MAAM,YAAY,GAAG,MAAM,CAAC,WAAW,CACrC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAC1D,CAAA;IACD,OAAO;QACL,qCAAqC;QACrC,gCAAgC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG;QACvE,mCAAmC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG;QAC7E,2BAA2B,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,GAAG;KAC3D,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACd,CAAC,CAAA;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACvC,YAAoB,EACpB,OAAe,EACP,EAAE;IACV,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAA;IACtD,OAAO;QACL,IAAI,EAAE,qBAAqB;QAC3B,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,KAAK,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3E,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;KACtD,CAAA;AACH,CAAC,CAAA","sourcesContent":["// @gtkx/react imports the bare specifier \"virtual:gtkx-config\" for JSX\n// metadata plus the app's applicationId/userEventSignals/lazy elements.\n// runner/host.ts resolves it at every process start through a loader hook\n// (registerHooks), reading gtkx.config.ts from the current working\n// directory. A SEA has no \"app root\" to read a config file from at\n// runtime — there is no cwd convention once the app is a single file\n// copied anywhere — so this bakes the same values in at BUILD time\n// instead, the same way the vite path already does (its CLI plugin serves\n// virtual:gtkx-config from the build-time config, never a runtime read).\n//\n// Deliberately duplicated validation logic rather than shared with\n// host.ts: see host-dev.ts's header comment for why the hosts in this\n// package are self-contained twins rather than sharing relative imports —\n// this is a third twin, for the same reason (host.ts must keep resolving\n// its config at runtime for ordinary `run-linux`/installed-app use; this\n// one resolves it once, at bundle time, for the SEA artifact only).\nimport { join } from \"node:path\"\nimport { createConfigLoader } from \"@gtkx/config/internal\"\nimport type { Plugin } from \"rolldown\"\n\nexport const CONFIG_REQUIRED =\n \"gtkx.config.ts with an applicationId is required in the app root \" +\n '(export default defineConfig({ applicationId: \"...\", libraries: [...] })).'\n\n/**\n * Loads and validates the app's gtkx.config.ts, returning the source of a\n * virtual:gtkx-config module with the resolved values baked in as literals.\n */\nexport const buildGtkxConfigModule = async (\n appRoot: string,\n): Promise<string> => {\n const loader = createConfigLoader()\n const config = await loader.resolve(appRoot).catch((error: unknown) => {\n throw new Error(`${CONFIG_REQUIRED}\\n${String(error)}`)\n })\n if (!config.applicationId) {\n throw new Error(CONFIG_REQUIRED)\n }\n // A behaviors module would have to be bundled and merged through\n // @gtkx/react/config; the react-native surface owns element behaviors,\n // so no app declares one — refuse rather than silently drop it (mirrors\n // host.ts's runtime check).\n if (config.elements !== null) {\n throw new Error(\n \"gtkx.config.ts `elements.behaviors` is not supported on the linux \" +\n \"platform — react-native-gtkx owns element behaviors.\",\n )\n }\n const lazyElements = Object.fromEntries(\n config.lazyElements.map((type) => [type, { lazy: true }]),\n )\n return [\n `export * from \"@gtkx/jsx/metadata\";`,\n `export const applicationId = ${JSON.stringify(config.applicationId)};`,\n `export const userEventSignals = ${JSON.stringify(config.userEventSignals)};`,\n `export const elements = ${JSON.stringify(lazyElements)};`,\n ].join(\"\\n\")\n}\n\n/**\n * Resolves the bare \"virtual:gtkx-config\" specifier @gtkx/react imports to\n * the module source built by {@link buildGtkxConfigModule}, so the bundler\n * can inline it like any other static import — no runtime loader hook\n * needed.\n *\n * The module is given an id inside `appRoot` rather than a `\\0`-prefixed\n * virtual one because it re-exports \"@gtkx/jsx/metadata\": that bare\n * specifier needs a real directory to resolve from.\n */\nexport const virtualConfigModulePlugin = (\n moduleSource: string,\n appRoot: string,\n): Plugin => {\n const configId = join(appRoot, \"__gtkx-sea-config.js\")\n return {\n name: \"gtkx-virtual-config\",\n resolveId: (source) => (source === \"virtual:gtkx-config\" ? configId : null),\n load: (id) => (id === configId ? moduleSource : null),\n }\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { BoxShadowValue } from "../contracts";
|
|
2
|
+
/**
|
|
3
|
+
* Renders RN's `boxShadow` as a GTK CSS `box-shadow` value, or null when
|
|
4
|
+
* nothing usable came out of it (the caller then emits no declaration).
|
|
5
|
+
* Both RN forms are accepted; the string is parsed rather than forwarded.
|
|
6
|
+
*/
|
|
7
|
+
export declare const boxShadowToCss: (value: string | readonly BoxShadowValue[]) => string | null;
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
// Compiles React Native's `boxShadow` into a GTK4 CSS `box-shadow` value.
|
|
2
|
+
// Pure module — no bridge imports, unit-testable on any OS.
|
|
3
|
+
//
|
|
4
|
+
// WHY this is not a passthrough of the string form. RN accepts both a CSS
|
|
5
|
+
// string and a structured array, and the string is the form apps actually
|
|
6
|
+
// write. Handing that string straight to GTK would work for the easy cases
|
|
7
|
+
// and fail silently for the ones that matter here: a `PlatformColor` becomes
|
|
8
|
+
// `var(--card-shade-color)` only after ./colors.ts has seen it, a named
|
|
9
|
+
// colour like `rebeccapurple` is not in GTK's vocabulary at all, and an
|
|
10
|
+
// unparseable value would poison the whole declaration block with a GTK CSS
|
|
11
|
+
// warning rather than being dropped the way an invalid `backgroundColor`
|
|
12
|
+
// already is. Parsing here means both forms take the same path, colours go
|
|
13
|
+
// through the same normalizer as every other colour prop, and a bad shadow
|
|
14
|
+
// costs one dev warning instead of the rest of the style.
|
|
15
|
+
//
|
|
16
|
+
// What GTK4 CSS supports, and therefore what this emits: offset-x offset-y
|
|
17
|
+
// [blur] [spread] [color], plus the `inset` keyword, comma-separated. That
|
|
18
|
+
// is the same grammar as CSS, so the ordering rule is CSS's — the FIRST
|
|
19
|
+
// shadow paints on top — and RN follows it too.
|
|
20
|
+
import { parseColor } from "./colors";
|
|
21
|
+
import { warnOnce } from "./dev-warning";
|
|
22
|
+
/** RN's own shadow-length grammar, from `processBoxShadow.js`: a bare number
|
|
23
|
+
* or a number with `px`, nothing else. No percentages, no em — matching it
|
|
24
|
+
* exactly means a style that RN rejects is rejected here too, rather than
|
|
25
|
+
* quietly working on one platform. */
|
|
26
|
+
const LENGTH = /^[+-]?(\d*\.?\d+)(px)?$/;
|
|
27
|
+
const length = (value) => {
|
|
28
|
+
if (typeof value === "number") {
|
|
29
|
+
return Number.isFinite(value) ? `${value}px` : null;
|
|
30
|
+
}
|
|
31
|
+
const trimmed = value.trim();
|
|
32
|
+
const match = LENGTH.exec(trimmed);
|
|
33
|
+
return match ? `${match[1]}px` : null;
|
|
34
|
+
};
|
|
35
|
+
/** Blur is the one length CSS (and RN's parser) refuses to take negative. */
|
|
36
|
+
const nonNegativeLength = (value) => {
|
|
37
|
+
const rendered = length(value);
|
|
38
|
+
if (rendered === null || rendered.startsWith("-")) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
return rendered;
|
|
42
|
+
};
|
|
43
|
+
/** Splits on commas that are not inside parentheses, so `rgba(0, 0, 0, .5)`
|
|
44
|
+
* stays one token. */
|
|
45
|
+
const splitShadows = (value) => {
|
|
46
|
+
const parts = [];
|
|
47
|
+
let depth = 0;
|
|
48
|
+
let current = "";
|
|
49
|
+
for (const char of value) {
|
|
50
|
+
if (char === "(") {
|
|
51
|
+
depth += 1;
|
|
52
|
+
}
|
|
53
|
+
else if (char === ")") {
|
|
54
|
+
depth = Math.max(0, depth - 1);
|
|
55
|
+
}
|
|
56
|
+
if (char === "," && depth === 0) {
|
|
57
|
+
parts.push(current);
|
|
58
|
+
current = "";
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
current += char;
|
|
62
|
+
}
|
|
63
|
+
parts.push(current);
|
|
64
|
+
return parts.map((part) => part.trim()).filter((part) => part !== "");
|
|
65
|
+
};
|
|
66
|
+
/** Same rule as splitShadows, one level down: whitespace outside
|
|
67
|
+
* parentheses separates a shadow's own components. */
|
|
68
|
+
const splitTokens = (shadow) => {
|
|
69
|
+
const tokens = [];
|
|
70
|
+
let depth = 0;
|
|
71
|
+
let current = "";
|
|
72
|
+
for (const char of shadow) {
|
|
73
|
+
if (char === "(") {
|
|
74
|
+
depth += 1;
|
|
75
|
+
}
|
|
76
|
+
else if (char === ")") {
|
|
77
|
+
depth = Math.max(0, depth - 1);
|
|
78
|
+
}
|
|
79
|
+
if (/\s/.test(char) && depth === 0) {
|
|
80
|
+
if (current !== "") {
|
|
81
|
+
tokens.push(current);
|
|
82
|
+
current = "";
|
|
83
|
+
}
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
current += char;
|
|
87
|
+
}
|
|
88
|
+
if (current !== "") {
|
|
89
|
+
tokens.push(current);
|
|
90
|
+
}
|
|
91
|
+
return tokens;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Parses one CSS shadow into the structured form. Returns null when the
|
|
95
|
+
* shadow is not something CSS (or RN) would accept: too few or too many
|
|
96
|
+
* lengths, two colours, an unparseable token.
|
|
97
|
+
*/
|
|
98
|
+
const parseShadow = (shadow) => {
|
|
99
|
+
const tokens = splitTokens(shadow);
|
|
100
|
+
const lengths = [];
|
|
101
|
+
let color;
|
|
102
|
+
let inset = false;
|
|
103
|
+
for (const token of tokens) {
|
|
104
|
+
if (token.toLowerCase() === "inset") {
|
|
105
|
+
if (inset) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
inset = true;
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (length(token) !== null) {
|
|
112
|
+
lengths.push(token);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (color !== undefined) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
color = token;
|
|
119
|
+
}
|
|
120
|
+
// CSS requires offset-x and offset-y and allows blur and spread after
|
|
121
|
+
// them; anything else is a malformed shadow.
|
|
122
|
+
if (lengths.length < 2 || lengths.length > 4) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
offsetX: lengths[0],
|
|
127
|
+
offsetY: lengths[1],
|
|
128
|
+
...(lengths[2] !== undefined ? { blurRadius: lengths[2] } : {}),
|
|
129
|
+
...(lengths[3] !== undefined ? { spreadDistance: lengths[3] } : {}),
|
|
130
|
+
...(color !== undefined ? { color } : {}),
|
|
131
|
+
...(inset ? { inset: true } : {}),
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
/** One structured shadow as a GTK CSS value, or null when a part of it is
|
|
135
|
+
* not usable. */
|
|
136
|
+
const shadowToCss = (shadow) => {
|
|
137
|
+
const offsetX = length(shadow.offsetX);
|
|
138
|
+
const offsetY = length(shadow.offsetY);
|
|
139
|
+
if (offsetX === null || offsetY === null) {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
const parts = [];
|
|
143
|
+
if (shadow.inset === true) {
|
|
144
|
+
parts.push("inset");
|
|
145
|
+
}
|
|
146
|
+
parts.push(offsetX, offsetY);
|
|
147
|
+
if (shadow.blurRadius !== undefined) {
|
|
148
|
+
const blur = nonNegativeLength(shadow.blurRadius);
|
|
149
|
+
if (blur === null) {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
parts.push(blur);
|
|
153
|
+
}
|
|
154
|
+
if (shadow.spreadDistance !== undefined) {
|
|
155
|
+
// CSS positions spread after blur, so a spread with no blur needs an
|
|
156
|
+
// explicit zero blur rather than silently becoming one.
|
|
157
|
+
if (shadow.blurRadius === undefined) {
|
|
158
|
+
parts.push("0px");
|
|
159
|
+
}
|
|
160
|
+
const spread = length(shadow.spreadDistance);
|
|
161
|
+
if (spread === null) {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
parts.push(spread);
|
|
165
|
+
}
|
|
166
|
+
// RN's documented deviation from CSS: an omitted shadow colour is BLACK,
|
|
167
|
+
// not the inherited `currentColor`. Emitting it explicitly is what keeps
|
|
168
|
+
// this platform on RN's side of that difference — leaving it out would
|
|
169
|
+
// silently hand the app CSS's behaviour instead.
|
|
170
|
+
const parsed = parseColor(shadow.color ?? "black");
|
|
171
|
+
if (parsed === null) {
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
parts.push(parsed);
|
|
175
|
+
return parts.join(" ");
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* Renders RN's `boxShadow` as a GTK CSS `box-shadow` value, or null when
|
|
179
|
+
* nothing usable came out of it (the caller then emits no declaration).
|
|
180
|
+
* Both RN forms are accepted; the string is parsed rather than forwarded.
|
|
181
|
+
*/
|
|
182
|
+
export const boxShadowToCss = (value) => {
|
|
183
|
+
const shadows = typeof value === "string"
|
|
184
|
+
? splitShadows(value).map(parseShadow)
|
|
185
|
+
: value.map((shadow) => shadow);
|
|
186
|
+
const rendered = [];
|
|
187
|
+
for (const shadow of shadows) {
|
|
188
|
+
const css = shadow === null ? null : shadowToCss(shadow);
|
|
189
|
+
if (css === null) {
|
|
190
|
+
warnOnce(`invalid-box-shadow:${JSON.stringify(value)}`, `[react-native-gtkx] Invalid boxShadow ${JSON.stringify(value)} — declaration dropped`);
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
rendered.push(css);
|
|
194
|
+
}
|
|
195
|
+
return rendered.length > 0 ? rendered.join(", ") : null;
|
|
196
|
+
};
|
|
197
|
+
//# sourceMappingURL=box-shadow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"box-shadow.js","sourceRoot":"","sources":["../../src/style/box-shadow.ts"],"names":[],"mappings":"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","sourcesContent":["// Compiles React Native's `boxShadow` into a GTK4 CSS `box-shadow` value.\n// Pure module — no bridge imports, unit-testable on any OS.\n//\n// WHY this is not a passthrough of the string form. RN accepts both a CSS\n// string and a structured array, and the string is the form apps actually\n// write. Handing that string straight to GTK would work for the easy cases\n// and fail silently for the ones that matter here: a `PlatformColor` becomes\n// `var(--card-shade-color)` only after ./colors.ts has seen it, a named\n// colour like `rebeccapurple` is not in GTK's vocabulary at all, and an\n// unparseable value would poison the whole declaration block with a GTK CSS\n// warning rather than being dropped the way an invalid `backgroundColor`\n// already is. Parsing here means both forms take the same path, colours go\n// through the same normalizer as every other colour prop, and a bad shadow\n// costs one dev warning instead of the rest of the style.\n//\n// What GTK4 CSS supports, and therefore what this emits: offset-x offset-y\n// [blur] [spread] [color], plus the `inset` keyword, comma-separated. That\n// is the same grammar as CSS, so the ordering rule is CSS's — the FIRST\n// shadow paints on top — and RN follows it too.\n\nimport type { BoxShadowValue } from \"../contracts\"\nimport { parseColor } from \"./colors\"\nimport { warnOnce } from \"./dev-warning\"\n\n/** RN's own shadow-length grammar, from `processBoxShadow.js`: a bare number\n * or a number with `px`, nothing else. No percentages, no em — matching it\n * exactly means a style that RN rejects is rejected here too, rather than\n * quietly working on one platform. */\nconst LENGTH = /^[+-]?(\\d*\\.?\\d+)(px)?$/\n\nconst length = (value: number | string): string | null => {\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? `${value}px` : null\n }\n const trimmed = value.trim()\n const match = LENGTH.exec(trimmed)\n return match ? `${match[1]}px` : null\n}\n\n/** Blur is the one length CSS (and RN's parser) refuses to take negative. */\nconst nonNegativeLength = (value: number | string): string | null => {\n const rendered = length(value)\n if (rendered === null || rendered.startsWith(\"-\")) {\n return null\n }\n return rendered\n}\n\n/** Splits on commas that are not inside parentheses, so `rgba(0, 0, 0, .5)`\n * stays one token. */\nconst splitShadows = (value: string): string[] => {\n const parts: string[] = []\n let depth = 0\n let current = \"\"\n for (const char of value) {\n if (char === \"(\") {\n depth += 1\n } else if (char === \")\") {\n depth = Math.max(0, depth - 1)\n }\n if (char === \",\" && depth === 0) {\n parts.push(current)\n current = \"\"\n continue\n }\n current += char\n }\n parts.push(current)\n return parts.map((part) => part.trim()).filter((part) => part !== \"\")\n}\n\n/** Same rule as splitShadows, one level down: whitespace outside\n * parentheses separates a shadow's own components. */\nconst splitTokens = (shadow: string): string[] => {\n const tokens: string[] = []\n let depth = 0\n let current = \"\"\n for (const char of shadow) {\n if (char === \"(\") {\n depth += 1\n } else if (char === \")\") {\n depth = Math.max(0, depth - 1)\n }\n if (/\\s/.test(char) && depth === 0) {\n if (current !== \"\") {\n tokens.push(current)\n current = \"\"\n }\n continue\n }\n current += char\n }\n if (current !== \"\") {\n tokens.push(current)\n }\n return tokens\n}\n\n/**\n * Parses one CSS shadow into the structured form. Returns null when the\n * shadow is not something CSS (or RN) would accept: too few or too many\n * lengths, two colours, an unparseable token.\n */\nconst parseShadow = (shadow: string): BoxShadowValue | null => {\n const tokens = splitTokens(shadow)\n const lengths: (number | string)[] = []\n let color: string | undefined\n let inset = false\n for (const token of tokens) {\n if (token.toLowerCase() === \"inset\") {\n if (inset) {\n return null\n }\n inset = true\n continue\n }\n if (length(token) !== null) {\n lengths.push(token)\n continue\n }\n if (color !== undefined) {\n return null\n }\n color = token\n }\n // CSS requires offset-x and offset-y and allows blur and spread after\n // them; anything else is a malformed shadow.\n if (lengths.length < 2 || lengths.length > 4) {\n return null\n }\n return {\n offsetX: lengths[0]!,\n offsetY: lengths[1]!,\n ...(lengths[2] !== undefined ? { blurRadius: lengths[2] } : {}),\n ...(lengths[3] !== undefined ? { spreadDistance: lengths[3] } : {}),\n ...(color !== undefined ? { color } : {}),\n ...(inset ? { inset: true } : {}),\n }\n}\n\n/** One structured shadow as a GTK CSS value, or null when a part of it is\n * not usable. */\nconst shadowToCss = (shadow: BoxShadowValue): string | null => {\n const offsetX = length(shadow.offsetX)\n const offsetY = length(shadow.offsetY)\n if (offsetX === null || offsetY === null) {\n return null\n }\n const parts: string[] = []\n if (shadow.inset === true) {\n parts.push(\"inset\")\n }\n parts.push(offsetX, offsetY)\n if (shadow.blurRadius !== undefined) {\n const blur = nonNegativeLength(shadow.blurRadius)\n if (blur === null) {\n return null\n }\n parts.push(blur)\n }\n if (shadow.spreadDistance !== undefined) {\n // CSS positions spread after blur, so a spread with no blur needs an\n // explicit zero blur rather than silently becoming one.\n if (shadow.blurRadius === undefined) {\n parts.push(\"0px\")\n }\n const spread = length(shadow.spreadDistance)\n if (spread === null) {\n return null\n }\n parts.push(spread)\n }\n // RN's documented deviation from CSS: an omitted shadow colour is BLACK,\n // not the inherited `currentColor`. Emitting it explicitly is what keeps\n // this platform on RN's side of that difference — leaving it out would\n // silently hand the app CSS's behaviour instead.\n const parsed = parseColor(shadow.color ?? \"black\")\n if (parsed === null) {\n return null\n }\n parts.push(parsed)\n return parts.join(\" \")\n}\n\n/**\n * Renders RN's `boxShadow` as a GTK CSS `box-shadow` value, or null when\n * nothing usable came out of it (the caller then emits no declaration).\n * Both RN forms are accepted; the string is parsed rather than forwarded.\n */\nexport const boxShadowToCss = (\n value: string | readonly BoxShadowValue[],\n): string | null => {\n const shadows =\n typeof value === \"string\"\n ? splitShadows(value).map(parseShadow)\n : value.map((shadow) => shadow)\n const rendered: string[] = []\n for (const shadow of shadows) {\n const css = shadow === null ? null : shadowToCss(shadow)\n if (css === null) {\n warnOnce(\n `invalid-box-shadow:${JSON.stringify(value)}`,\n `[react-native-gtkx] Invalid boxShadow ${JSON.stringify(value)} — declaration dropped`,\n )\n return null\n }\n rendered.push(css)\n }\n return rendered.length > 0 ? rendered.join(\", \") : null\n}\n"]}
|
package/dist/style/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
export { boxShadowToCss } from "./box-shadow";
|
|
1
2
|
export { parseColor, PlatformColor } from "./colors";
|
|
2
3
|
export { resetDevWarnings } from "./dev-warning";
|
|
3
4
|
export { createCssRegistry, type CssFn, type CssRegistry } from "./registry";
|
|
4
5
|
export { splitStyle } from "./split-style";
|
|
5
6
|
export { absoluteFill, absoluteFillObject, compose, create, flatten, hairlineWidth, StyleSheet, } from "./style-sheet";
|
|
7
|
+
export { textDecorationToAttrs, type TextDecorations } from "./text-decoration";
|
|
6
8
|
export { textAlignToLabelProps, type LabelAlignProps, type TextAlign, } from "./text-align";
|
|
7
9
|
export { composeTransform, IDENTITY_TRANSFORM, isIdentityTransform, isTranslationOnly, parseAngle, } from "./transform";
|
|
8
10
|
export { visualStyleToCss } from "./visual-css";
|
package/dist/style/index.js
CHANGED
|
@@ -4,11 +4,13 @@
|
|
|
4
4
|
// Everything exported here is pure (no bridge imports) and unit-testable on
|
|
5
5
|
// any OS. The production registry that talks to the gtkx `css` helper lives
|
|
6
6
|
// in ./registry.gtkx.ts and is imported directly by the components.
|
|
7
|
+
export { boxShadowToCss } from "./box-shadow";
|
|
7
8
|
export { parseColor, PlatformColor } from "./colors";
|
|
8
9
|
export { resetDevWarnings } from "./dev-warning";
|
|
9
10
|
export { createCssRegistry } from "./registry";
|
|
10
11
|
export { splitStyle } from "./split-style";
|
|
11
12
|
export { absoluteFill, absoluteFillObject, compose, create, flatten, hairlineWidth, StyleSheet, } from "./style-sheet";
|
|
13
|
+
export { textDecorationToAttrs } from "./text-decoration";
|
|
12
14
|
export { textAlignToLabelProps, } from "./text-align";
|
|
13
15
|
export { composeTransform, IDENTITY_TRANSFORM, isIdentityTransform, isTranslationOnly, parseAngle, } from "./transform";
|
|
14
16
|
export { visualStyleToCss } from "./visual-css";
|
package/dist/style/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/style/index.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,8CAA8C;AAC9C,EAAE;AACF,4EAA4E;AAC5E,4EAA4E;AAC5E,oEAAoE;AAEpE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,iBAAiB,EAAgC,MAAM,YAAY,CAAA;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,OAAO,EACP,MAAM,EACN,OAAO,EACP,aAAa,EACb,UAAU,GACX,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,qBAAqB,GAGtB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,UAAU,GACX,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA","sourcesContent":["// Style pipeline: StyleSheet → flatten → splitStyle →\n// visualStyleToCss → memoized class registry.\n//\n// Everything exported here is pure (no bridge imports) and unit-testable on\n// any OS. The production registry that talks to the gtkx `css` helper lives\n// in ./registry.gtkx.ts and is imported directly by the components.\n\nexport { parseColor, PlatformColor } from \"./colors\"\nexport { resetDevWarnings } from \"./dev-warning\"\nexport { createCssRegistry, type CssFn, type CssRegistry } from \"./registry\"\nexport { splitStyle } from \"./split-style\"\nexport {\n absoluteFill,\n absoluteFillObject,\n compose,\n create,\n flatten,\n hairlineWidth,\n StyleSheet,\n} from \"./style-sheet\"\nexport {\n textAlignToLabelProps,\n type LabelAlignProps,\n type TextAlign,\n} from \"./text-align\"\nexport {\n composeTransform,\n IDENTITY_TRANSFORM,\n isIdentityTransform,\n isTranslationOnly,\n parseAngle,\n} from \"./transform\"\nexport { visualStyleToCss } from \"./visual-css\"\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/style/index.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,8CAA8C;AAC9C,EAAE;AACF,4EAA4E;AAC5E,4EAA4E;AAC5E,oEAAoE;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,iBAAiB,EAAgC,MAAM,YAAY,CAAA;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,OAAO,EACP,MAAM,EACN,OAAO,EACP,aAAa,EACb,UAAU,GACX,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,qBAAqB,EAAwB,MAAM,mBAAmB,CAAA;AAC/E,OAAO,EACL,qBAAqB,GAGtB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,UAAU,GACX,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA","sourcesContent":["// Style pipeline: StyleSheet → flatten → splitStyle →\n// visualStyleToCss → memoized class registry.\n//\n// Everything exported here is pure (no bridge imports) and unit-testable on\n// any OS. The production registry that talks to the gtkx `css` helper lives\n// in ./registry.gtkx.ts and is imported directly by the components.\n\nexport { boxShadowToCss } from \"./box-shadow\"\nexport { parseColor, PlatformColor } from \"./colors\"\nexport { resetDevWarnings } from \"./dev-warning\"\nexport { createCssRegistry, type CssFn, type CssRegistry } from \"./registry\"\nexport { splitStyle } from \"./split-style\"\nexport {\n absoluteFill,\n absoluteFillObject,\n compose,\n create,\n flatten,\n hairlineWidth,\n StyleSheet,\n} from \"./style-sheet\"\nexport { textDecorationToAttrs, type TextDecorations } from \"./text-decoration\"\nexport {\n textAlignToLabelProps,\n type LabelAlignProps,\n type TextAlign,\n} from \"./text-align\"\nexport {\n composeTransform,\n IDENTITY_TRANSFORM,\n isIdentityTransform,\n isTranslationOnly,\n parseAngle,\n} from \"./transform\"\nexport { visualStyleToCss } from \"./visual-css\"\n"]}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { FlatStyle, SplitStyle } from "../contracts";
|
|
2
2
|
/**
|
|
3
|
-
* Splits a flattened style into { layout, visual }.
|
|
4
|
-
*
|
|
3
|
+
* Splits a flattened style into { layout, visual }. Behavioral props
|
|
4
|
+
* (pointerEvents) belong to neither bucket and are consumed silently — the
|
|
5
|
+
* component that owns the behavior reads them from the flattened style.
|
|
6
|
+
* Unknown properties are ignored with a one-time dev warning per key;
|
|
7
|
+
* undefined values are dropped.
|
|
5
8
|
*/
|
|
6
9
|
export declare const splitStyle: (flat: FlatStyle) => SplitStyle;
|
|
@@ -47,11 +47,14 @@ const LAYOUT_KEYS = {
|
|
|
47
47
|
top: true,
|
|
48
48
|
width: true,
|
|
49
49
|
};
|
|
50
|
+
// Note: `textDecorationLine` and `textAlign` are visual by contract but never
|
|
51
|
+
// reach CSS — Pango carries both, and the Text component applies them.
|
|
50
52
|
// Note: `transform` is visual by contract — it is applied as the
|
|
51
53
|
// GskTransform of the child's allocation, not through CSS, and is passed
|
|
52
54
|
// through here untouched.
|
|
53
55
|
const VISUAL_KEYS = {
|
|
54
56
|
backgroundColor: true,
|
|
57
|
+
boxShadow: true,
|
|
55
58
|
borderBottomColor: true,
|
|
56
59
|
borderBottomLeftRadius: true,
|
|
57
60
|
borderBottomRightRadius: true,
|
|
@@ -76,12 +79,37 @@ const VISUAL_KEYS = {
|
|
|
76
79
|
letterSpacing: true,
|
|
77
80
|
lineHeight: true,
|
|
78
81
|
opacity: true,
|
|
82
|
+
outlineColor: true,
|
|
83
|
+
outlineOffset: true,
|
|
84
|
+
outlineStyle: true,
|
|
85
|
+
outlineWidth: true,
|
|
79
86
|
textAlign: true,
|
|
87
|
+
textDecorationLine: true,
|
|
80
88
|
transform: true,
|
|
81
89
|
};
|
|
90
|
+
// Behavioral props: supported, but by neither half of this pipeline. Since
|
|
91
|
+
// RN 0.71 `pointerEvents` may be written in a style and not only as a prop,
|
|
92
|
+
// and View reads it straight off the flattened style (components/view.tsx)
|
|
93
|
+
// to drive GTK picking — it never reaches Yoga and it has no CSS
|
|
94
|
+
// equivalent. So the splitter must CONSUME it silently: warning here told a
|
|
95
|
+
// user that working code was being ignored, on the very line where
|
|
96
|
+
// tests/gtk/components/pointer-events.gtk.test.tsx proves it is not.
|
|
97
|
+
//
|
|
98
|
+
// Exhaustive the same way the two buckets above are, but over what FlatStyle
|
|
99
|
+
// adds ON TOP of LayoutStyle and VisualStyle — that Omit makes the three
|
|
100
|
+
// records a partition of the contract, so a future fourth kind of style prop
|
|
101
|
+
// cannot be added to FlatStyle without failing compilation right here. That
|
|
102
|
+
// is exactly the drift this list suffered: `pointerEvents` was added to the
|
|
103
|
+
// contract and to View, and nothing forced anyone to classify it.
|
|
104
|
+
const BEHAVIORAL_KEYS = {
|
|
105
|
+
pointerEvents: true,
|
|
106
|
+
};
|
|
82
107
|
/**
|
|
83
|
-
* Splits a flattened style into { layout, visual }.
|
|
84
|
-
*
|
|
108
|
+
* Splits a flattened style into { layout, visual }. Behavioral props
|
|
109
|
+
* (pointerEvents) belong to neither bucket and are consumed silently — the
|
|
110
|
+
* component that owns the behavior reads them from the flattened style.
|
|
111
|
+
* Unknown properties are ignored with a one-time dev warning per key;
|
|
112
|
+
* undefined values are dropped.
|
|
85
113
|
*/
|
|
86
114
|
export const splitStyle = (flat) => {
|
|
87
115
|
const layout = {};
|
|
@@ -98,7 +126,7 @@ export const splitStyle = (flat) => {
|
|
|
98
126
|
;
|
|
99
127
|
visual[key] = value;
|
|
100
128
|
}
|
|
101
|
-
else {
|
|
129
|
+
else if (!Object.hasOwn(BEHAVIORAL_KEYS, key)) {
|
|
102
130
|
warnOnce(`unknown-style-prop:${key}`, `[react-native-gtkx] Unknown style property "${key}" is not supported and will be ignored`);
|
|
103
131
|
}
|
|
104
132
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"split-style.js","sourceRoot":"","sources":["../../src/style/split-style.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,iEAAiE;AAQjE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExC,sEAAsE;AACtE,mEAAmE;AACnE,MAAM,WAAW,GAAoC;IACnD,YAAY,EAAE,IAAI;IAClB,UAAU,EAAE,IAAI;IAChB,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,IAAI;IACjB,MAAM,EAAE,IAAI;IACZ,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,OAAO,EAAE,IAAI;IACb,IAAI,EAAE,IAAI;IACV,SAAS,EAAE,IAAI;IACf,aAAa,EAAE,IAAI;IACnB,QAAQ,EAAE,IAAI;IACd,UAAU,EAAE,IAAI;IAChB,QAAQ,EAAE,IAAI;IACd,GAAG,EAAE,IAAI;IACT,MAAM,EAAE,IAAI;IACZ,cAAc,EAAE,IAAI;IACpB,IAAI,EAAE,IAAI;IACV,MAAM,EAAE,IAAI;IACZ,YAAY,EAAE,IAAI;IAClB,gBAAgB,EAAE,IAAI;IACtB,UAAU,EAAE,IAAI;IAChB,WAAW,EAAE,IAAI;IACjB,SAAS,EAAE,IAAI;IACf,cAAc,EAAE,IAAI;IACpB,SAAS,EAAE,IAAI;IACf,QAAQ,EAAE,IAAI;IACd,SAAS,EAAE,IAAI;IACf,QAAQ,EAAE,IAAI;IACd,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,IAAI;IACb,aAAa,EAAE,IAAI;IACnB,iBAAiB,EAAE,IAAI;IACvB,WAAW,EAAE,IAAI;IACjB,YAAY,EAAE,IAAI;IAClB,UAAU,EAAE,IAAI;IAChB,eAAe,EAAE,IAAI;IACrB,QAAQ,EAAE,IAAI;IACd,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,GAAG,EAAE,IAAI;IACT,KAAK,EAAE,IAAI;CACZ,CAAA;AAED,iEAAiE;AACjE,yEAAyE;AACzE,0BAA0B;AAC1B,MAAM,WAAW,GAAoC;IACnD,eAAe,EAAE,IAAI;IACrB,iBAAiB,EAAE,IAAI;IACvB,sBAAsB,EAAE,IAAI;IAC5B,uBAAuB,EAAE,IAAI;IAC7B,iBAAiB,EAAE,IAAI;IACvB,WAAW,EAAE,IAAI;IACjB,eAAe,EAAE,IAAI;IACrB,eAAe,EAAE,IAAI;IACrB,YAAY,EAAE,IAAI;IAClB,gBAAgB,EAAE,IAAI;IACtB,gBAAgB,EAAE,IAAI;IACtB,WAAW,EAAE,IAAI;IACjB,cAAc,EAAE,IAAI;IACpB,mBAAmB,EAAE,IAAI;IACzB,oBAAoB,EAAE,IAAI;IAC1B,cAAc,EAAE,IAAI;IACpB,WAAW,EAAE,IAAI;IACjB,KAAK,EAAE,IAAI;IACX,UAAU,EAAE,IAAI;IAChB,QAAQ,EAAE,IAAI;IACd,SAAS,EAAE,IAAI;IACf,UAAU,EAAE,IAAI;IAChB,aAAa,EAAE,IAAI;IACnB,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;CAChB,CAAA;AAED
|
|
1
|
+
{"version":3,"file":"split-style.js","sourceRoot":"","sources":["../../src/style/split-style.ts"],"names":[],"mappings":"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","sourcesContent":["// Classifies a flattened style into layout props (consumed by the Yoga\n// engine) and visual props (compiled into GTK CSS). Pure module.\n\nimport type {\n FlatStyle,\n LayoutStyle,\n SplitStyle,\n VisualStyle,\n} from \"../contracts\"\nimport { warnOnce } from \"./dev-warning\"\n\n// Exhaustive over the frozen contract: adding a key to LayoutStyle in\n// contracts.ts fails compilation here until the key is classified.\nconst LAYOUT_KEYS: Record<keyof LayoutStyle, true> = {\n alignContent: true,\n alignItems: true,\n alignSelf: true,\n aspectRatio: true,\n bottom: true,\n columnGap: true,\n direction: true,\n display: true,\n flex: true,\n flexBasis: true,\n flexDirection: true,\n flexGrow: true,\n flexShrink: true,\n flexWrap: true,\n gap: true,\n height: true,\n justifyContent: true,\n left: true,\n margin: true,\n marginBottom: true,\n marginHorizontal: true,\n marginLeft: true,\n marginRight: true,\n marginTop: true,\n marginVertical: true,\n maxHeight: true,\n maxWidth: true,\n minHeight: true,\n minWidth: true,\n overflow: true,\n padding: true,\n paddingBottom: true,\n paddingHorizontal: true,\n paddingLeft: true,\n paddingRight: true,\n paddingTop: true,\n paddingVertical: true,\n position: true,\n right: true,\n rowGap: true,\n top: true,\n width: true,\n}\n\n// Note: `textDecorationLine` and `textAlign` are visual by contract but never\n// reach CSS — Pango carries both, and the Text component applies them.\n// Note: `transform` is visual by contract — it is applied as the\n// GskTransform of the child's allocation, not through CSS, and is passed\n// through here untouched.\nconst VISUAL_KEYS: Record<keyof VisualStyle, true> = {\n backgroundColor: true,\n boxShadow: true,\n borderBottomColor: true,\n borderBottomLeftRadius: true,\n borderBottomRightRadius: true,\n borderBottomWidth: true,\n borderColor: true,\n borderLeftColor: true,\n borderLeftWidth: true,\n borderRadius: true,\n borderRightColor: true,\n borderRightWidth: true,\n borderStyle: true,\n borderTopColor: true,\n borderTopLeftRadius: true,\n borderTopRightRadius: true,\n borderTopWidth: true,\n borderWidth: true,\n color: true,\n fontFamily: true,\n fontSize: true,\n fontStyle: true,\n fontWeight: true,\n letterSpacing: true,\n lineHeight: true,\n opacity: true,\n outlineColor: true,\n outlineOffset: true,\n outlineStyle: true,\n outlineWidth: true,\n textAlign: true,\n textDecorationLine: true,\n transform: true,\n}\n\n// Behavioral props: supported, but by neither half of this pipeline. Since\n// RN 0.71 `pointerEvents` may be written in a style and not only as a prop,\n// and View reads it straight off the flattened style (components/view.tsx)\n// to drive GTK picking — it never reaches Yoga and it has no CSS\n// equivalent. So the splitter must CONSUME it silently: warning here told a\n// user that working code was being ignored, on the very line where\n// tests/gtk/components/pointer-events.gtk.test.tsx proves it is not.\n//\n// Exhaustive the same way the two buckets above are, but over what FlatStyle\n// adds ON TOP of LayoutStyle and VisualStyle — that Omit makes the three\n// records a partition of the contract, so a future fourth kind of style prop\n// cannot be added to FlatStyle without failing compilation right here. That\n// is exactly the drift this list suffered: `pointerEvents` was added to the\n// contract and to View, and nothing forced anyone to classify it.\nconst BEHAVIORAL_KEYS: Record<\n keyof Omit<FlatStyle, keyof LayoutStyle | keyof VisualStyle>,\n true\n> = {\n pointerEvents: true,\n}\n\n/**\n * Splits a flattened style into { layout, visual }. Behavioral props\n * (pointerEvents) belong to neither bucket and are consumed silently — the\n * component that owns the behavior reads them from the flattened style.\n * Unknown properties are ignored with a one-time dev warning per key;\n * undefined values are dropped.\n */\nexport const splitStyle = (flat: FlatStyle): SplitStyle => {\n const layout: LayoutStyle = {}\n const visual: VisualStyle = {}\n for (const [key, value] of Object.entries(flat)) {\n if (value === undefined) {\n continue\n }\n if (Object.hasOwn(LAYOUT_KEYS, key)) {\n ;(layout as Record<string, unknown>)[key] = value\n } else if (Object.hasOwn(VISUAL_KEYS, key)) {\n ;(visual as Record<string, unknown>)[key] = value\n } else if (!Object.hasOwn(BEHAVIORAL_KEYS, key)) {\n warnOnce(\n `unknown-style-prop:${key}`,\n `[react-native-gtkx] Unknown style property \"${key}\" is not supported and will be ignored`,\n )\n }\n }\n return { layout, visual }\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { TextDecorationLine } from "../contracts";
|
|
2
|
+
export type TextDecorations = {
|
|
3
|
+
underline: boolean;
|
|
4
|
+
strikethrough: boolean;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Splits RN's `textDecorationLine` into the two Pango attributes that carry
|
|
8
|
+
* it. `"none"` and `undefined` produce neither, which is what lets the caller
|
|
9
|
+
* skip building an attribute list at all.
|
|
10
|
+
*
|
|
11
|
+
* RN's `"underline line-through"` is the combined value; the words are
|
|
12
|
+
* matched individually so the reversed spelling behaves the same, as it does
|
|
13
|
+
* in CSS.
|
|
14
|
+
*/
|
|
15
|
+
export declare const textDecorationToAttrs: (value: TextDecorationLine | undefined) => TextDecorations;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// textDecorationLine, classified. Pure module — no bridge imports.
|
|
2
|
+
//
|
|
3
|
+
// GTK4 CSS has no `text-decoration` for widgets, the same way it has no
|
|
4
|
+
// `text-align`: both are Pango's business, not the style sheet's. So this
|
|
5
|
+
// follows text-align.ts's shape exactly — the style system decides WHAT is
|
|
6
|
+
// wanted, and the Text component applies it through the label's Pango
|
|
7
|
+
// attribute list.
|
|
8
|
+
/**
|
|
9
|
+
* Splits RN's `textDecorationLine` into the two Pango attributes that carry
|
|
10
|
+
* it. `"none"` and `undefined` produce neither, which is what lets the caller
|
|
11
|
+
* skip building an attribute list at all.
|
|
12
|
+
*
|
|
13
|
+
* RN's `"underline line-through"` is the combined value; the words are
|
|
14
|
+
* matched individually so the reversed spelling behaves the same, as it does
|
|
15
|
+
* in CSS.
|
|
16
|
+
*/
|
|
17
|
+
export const textDecorationToAttrs = (value) => {
|
|
18
|
+
if (value === undefined || value === "none") {
|
|
19
|
+
return { underline: false, strikethrough: false };
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
underline: value.includes("underline"),
|
|
23
|
+
strikethrough: value.includes("line-through"),
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=text-decoration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-decoration.js","sourceRoot":"","sources":["../../src/style/text-decoration.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,EAAE;AACF,wEAAwE;AACxE,0EAA0E;AAC1E,2EAA2E;AAC3E,sEAAsE;AACtE,kBAAkB;AASlB;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,KAAqC,EACpB,EAAE;IACnB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QAC5C,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,CAAA;IACnD,CAAC;IACD,OAAO;QACL,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC;QACtC,aAAa,EAAE,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC;KAC9C,CAAA;AACH,CAAC,CAAA","sourcesContent":["// textDecorationLine, classified. Pure module — no bridge imports.\n//\n// GTK4 CSS has no `text-decoration` for widgets, the same way it has no\n// `text-align`: both are Pango's business, not the style sheet's. So this\n// follows text-align.ts's shape exactly — the style system decides WHAT is\n// wanted, and the Text component applies it through the label's Pango\n// attribute list.\n\nimport type { TextDecorationLine } from \"../contracts\"\n\nexport type TextDecorations = {\n underline: boolean\n strikethrough: boolean\n}\n\n/**\n * Splits RN's `textDecorationLine` into the two Pango attributes that carry\n * it. `\"none\"` and `undefined` produce neither, which is what lets the caller\n * skip building an attribute list at all.\n *\n * RN's `\"underline line-through\"` is the combined value; the words are\n * matched individually so the reversed spelling behaves the same, as it does\n * in CSS.\n */\nexport const textDecorationToAttrs = (\n value: TextDecorationLine | undefined,\n): TextDecorations => {\n if (value === undefined || value === \"none\") {\n return { underline: false, strikethrough: false }\n }\n return {\n underline: value.includes(\"underline\"),\n strikethrough: value.includes(\"line-through\"),\n }\n}\n"]}
|