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,18 @@
1
+ // Dev-only warn-once helper shared by the style pipeline. Each unique key
2
+ // warns a single time per process — repeated renders stay silent.
3
+ const warned = new Set();
4
+ export const warnOnce = (key, message) => {
5
+ if (process.env.NODE_ENV === "production") {
6
+ return;
7
+ }
8
+ if (warned.has(key)) {
9
+ return;
10
+ }
11
+ warned.add(key);
12
+ console.warn(message);
13
+ };
14
+ // Test-only escape hatch: clears the warn-once registry between test cases.
15
+ export const resetDevWarnings = () => {
16
+ warned.clear();
17
+ };
18
+ //# sourceMappingURL=dev-warning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-warning.js","sourceRoot":"","sources":["../../src/style/dev-warning.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,kEAAkE;AAElE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAA;AAEhC,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAE,OAAe,EAAQ,EAAE;IAC7D,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;QAC1C,OAAM;IACR,CAAC;IACD,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QACpB,OAAM;IACR,CAAC;IACD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACf,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;AACvB,CAAC,CAAA;AAED,4EAA4E;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAS,EAAE;IACzC,MAAM,CAAC,KAAK,EAAE,CAAA;AAChB,CAAC,CAAA","sourcesContent":["// Dev-only warn-once helper shared by the style pipeline. Each unique key\n// warns a single time per process — repeated renders stay silent.\n\nconst warned = new Set<string>()\n\nexport const warnOnce = (key: string, message: string): void => {\n if (process.env.NODE_ENV === \"production\") {\n return\n }\n if (warned.has(key)) {\n return\n }\n warned.add(key)\n console.warn(message)\n}\n\n// Test-only escape hatch: clears the warn-once registry between test cases.\nexport const resetDevWarnings = (): void => {\n warned.clear()\n}\n"]}
@@ -0,0 +1,7 @@
1
+ export { parseColor, PlatformColor } from "./colors";
2
+ export { resetDevWarnings } from "./dev-warning";
3
+ export { createCssRegistry, type CssFn, type CssRegistry } from "./registry";
4
+ export { splitStyle } from "./split-style";
5
+ export { absoluteFill, absoluteFillObject, compose, create, flatten, hairlineWidth, StyleSheet, } from "./style-sheet";
6
+ export { textAlignToLabelProps, type LabelAlignProps, type TextAlign, } from "./text-align";
7
+ export { visualStyleToCss } from "./visual-css";
@@ -0,0 +1,14 @@
1
+ // Style pipeline (task 005): StyleSheet → flatten → splitStyle →
2
+ // visualStyleToCss → memoized class registry.
3
+ //
4
+ // Everything exported here is pure (no bridge imports) and unit-testable on
5
+ // any OS. The production registry that talks to the gtkx `css` helper lives
6
+ // in ./registry.gtkx.ts and is imported directly by components (006).
7
+ export { parseColor, PlatformColor } from "./colors";
8
+ export { resetDevWarnings } from "./dev-warning";
9
+ export { createCssRegistry } from "./registry";
10
+ export { splitStyle } from "./split-style";
11
+ export { absoluteFill, absoluteFillObject, compose, create, flatten, hairlineWidth, StyleSheet, } from "./style-sheet";
12
+ export { textAlignToLabelProps, } from "./text-align";
13
+ export { visualStyleToCss } from "./visual-css";
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/style/index.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,8CAA8C;AAC9C,EAAE;AACF,4EAA4E;AAC5E,4EAA4E;AAC5E,sEAAsE;AAEtE,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,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA","sourcesContent":["// Style pipeline (task 005): 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 components (006).\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 { visualStyleToCss } from \"./visual-css\"\n"]}
@@ -0,0 +1,12 @@
1
+ import type { VisualStyle } from "../contracts";
2
+ export type CssFn = (cssText: string) => string;
3
+ export type CssRegistry = {
4
+ /**
5
+ * Returns the GTK CSS class name for a visual style, or null when the
6
+ * style produces no CSS (empty, or transform/textAlign-only). Equal
7
+ * styles map to the same class: the cache key is the generated CSS text,
8
+ * so property order and non-CSS props do not fragment the cache.
9
+ */
10
+ getClassName(visual: VisualStyle): string | null;
11
+ };
12
+ export declare const createCssRegistry: (cssFn: CssFn) => CssRegistry;
@@ -0,0 +1,2 @@
1
+ import { type CssRegistry } from "./registry";
2
+ export declare const defaultCssRegistry: CssRegistry;
@@ -0,0 +1,9 @@
1
+ // Production adapter — the ONLY style module that touches the bridge.
2
+ // Components (task 006) import the default registry from here; everything
3
+ // else in src/style is pure and must not depend on this file. It is also
4
+ // deliberately not re-exported from src/style/index.ts so that unit tests
5
+ // (and any pure consumer) never pull in @gtkx bindings transitively.
6
+ import { css } from "../gtkx/bridge/index";
7
+ import { createCssRegistry } from "./registry";
8
+ export const defaultCssRegistry = createCssRegistry((cssText) => css(cssText));
9
+ //# sourceMappingURL=registry.gtkx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.gtkx.js","sourceRoot":"","sources":["../../src/style/registry.gtkx.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,0EAA0E;AAC1E,yEAAyE;AACzE,0EAA0E;AAC1E,qEAAqE;AAErE,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAA;AAC1C,OAAO,EAAE,iBAAiB,EAAoB,MAAM,YAAY,CAAA;AAEhE,MAAM,CAAC,MAAM,kBAAkB,GAAgB,iBAAiB,CAAC,CAAC,OAAO,EAAE,EAAE,CAC3E,GAAG,CAAC,OAAO,CAAC,CACb,CAAA","sourcesContent":["// Production adapter — the ONLY style module that touches the bridge.\n// Components (task 006) import the default registry from here; everything\n// else in src/style is pure and must not depend on this file. It is also\n// deliberately not re-exported from src/style/index.ts so that unit tests\n// (and any pure consumer) never pull in @gtkx bindings transitively.\n\nimport { css } from \"../gtkx/bridge/index\"\nimport { createCssRegistry, type CssRegistry } from \"./registry\"\n\nexport const defaultCssRegistry: CssRegistry = createCssRegistry((cssText) =>\n css(cssText),\n)\n"]}
@@ -0,0 +1,23 @@
1
+ // Memoized CSS class registry. The actual `css` function is injected:
2
+ // production uses the bridge (registry.gtkx.ts), tests use a fake — this
3
+ // module stays pure and unit-testable on any OS.
4
+ import { visualStyleToCss } from "./visual-css";
5
+ export const createCssRegistry = (cssFn) => {
6
+ const classByCssText = new Map();
7
+ return {
8
+ getClassName(visual) {
9
+ const cssText = visualStyleToCss(visual);
10
+ if (cssText === "") {
11
+ return null;
12
+ }
13
+ const cached = classByCssText.get(cssText);
14
+ if (cached !== undefined) {
15
+ return cached;
16
+ }
17
+ const className = cssFn(cssText);
18
+ classByCssText.set(cssText, className);
19
+ return className;
20
+ },
21
+ };
22
+ };
23
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/style/registry.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,yEAAyE;AACzE,iDAAiD;AAGjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAc/C,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAY,EAAe,EAAE;IAC7D,MAAM,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAA;IAChD,OAAO;QACL,YAAY,CAAC,MAAM;YACjB,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAA;YACxC,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;gBACnB,OAAO,IAAI,CAAA;YACb,CAAC;YACD,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YAC1C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,OAAO,MAAM,CAAA;YACf,CAAC;YACD,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,CAAA;YAChC,cAAc,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;YACtC,OAAO,SAAS,CAAA;QAClB,CAAC;KACF,CAAA;AACH,CAAC,CAAA","sourcesContent":["// Memoized CSS class registry. The actual `css` function is injected:\n// production uses the bridge (registry.gtkx.ts), tests use a fake — this\n// module stays pure and unit-testable on any OS.\n\nimport type { VisualStyle } from \"../contracts\"\nimport { visualStyleToCss } from \"./visual-css\"\n\nexport type CssFn = (cssText: string) => string\n\nexport type CssRegistry = {\n /**\n * Returns the GTK CSS class name for a visual style, or null when the\n * style produces no CSS (empty, or transform/textAlign-only). Equal\n * styles map to the same class: the cache key is the generated CSS text,\n * so property order and non-CSS props do not fragment the cache.\n */\n getClassName(visual: VisualStyle): string | null\n}\n\nexport const createCssRegistry = (cssFn: CssFn): CssRegistry => {\n const classByCssText = new Map<string, string>()\n return {\n getClassName(visual) {\n const cssText = visualStyleToCss(visual)\n if (cssText === \"\") {\n return null\n }\n const cached = classByCssText.get(cssText)\n if (cached !== undefined) {\n return cached\n }\n const className = cssFn(cssText)\n classByCssText.set(cssText, className)\n return className\n },\n }\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import type { FlatStyle, SplitStyle } from "../contracts";
2
+ /**
3
+ * Splits a flattened style into { layout, visual }. Unknown properties are
4
+ * ignored with a one-time dev warning per key; undefined values are dropped.
5
+ */
6
+ export declare const splitStyle: (flat: FlatStyle) => SplitStyle;
@@ -0,0 +1,107 @@
1
+ // Classifies a flattened style into layout props (consumed by the Yoga
2
+ // engine, task 004) and visual props (compiled into GTK CSS). Pure module.
3
+ import { warnOnce } from "./dev-warning";
4
+ // Exhaustive over the frozen contract: adding a key to LayoutStyle in
5
+ // contracts.ts fails compilation here until the key is classified.
6
+ const LAYOUT_KEYS = {
7
+ alignContent: true,
8
+ alignItems: true,
9
+ alignSelf: true,
10
+ aspectRatio: true,
11
+ bottom: true,
12
+ columnGap: true,
13
+ direction: true,
14
+ display: true,
15
+ flex: true,
16
+ flexBasis: true,
17
+ flexDirection: true,
18
+ flexGrow: true,
19
+ flexShrink: true,
20
+ flexWrap: true,
21
+ gap: true,
22
+ height: true,
23
+ justifyContent: true,
24
+ left: true,
25
+ margin: true,
26
+ marginBottom: true,
27
+ marginHorizontal: true,
28
+ marginLeft: true,
29
+ marginRight: true,
30
+ marginTop: true,
31
+ marginVertical: true,
32
+ maxHeight: true,
33
+ maxWidth: true,
34
+ minHeight: true,
35
+ minWidth: true,
36
+ overflow: true,
37
+ padding: true,
38
+ paddingBottom: true,
39
+ paddingHorizontal: true,
40
+ paddingLeft: true,
41
+ paddingRight: true,
42
+ paddingTop: true,
43
+ paddingVertical: true,
44
+ position: true,
45
+ right: true,
46
+ rowGap: true,
47
+ top: true,
48
+ width: true,
49
+ };
50
+ // Note: `transform` is visual by contract — it is applied by the layout
51
+ // engine through Fixed.Child matrices, not through CSS, and is passed
52
+ // through here untouched.
53
+ const VISUAL_KEYS = {
54
+ backgroundColor: true,
55
+ borderBottomColor: true,
56
+ borderBottomLeftRadius: true,
57
+ borderBottomRightRadius: true,
58
+ borderBottomWidth: true,
59
+ borderColor: true,
60
+ borderLeftColor: true,
61
+ borderLeftWidth: true,
62
+ borderRadius: true,
63
+ borderRightColor: true,
64
+ borderRightWidth: true,
65
+ borderStyle: true,
66
+ borderTopColor: true,
67
+ borderTopLeftRadius: true,
68
+ borderTopRightRadius: true,
69
+ borderTopWidth: true,
70
+ borderWidth: true,
71
+ color: true,
72
+ fontFamily: true,
73
+ fontSize: true,
74
+ fontStyle: true,
75
+ fontWeight: true,
76
+ letterSpacing: true,
77
+ lineHeight: true,
78
+ opacity: true,
79
+ textAlign: true,
80
+ transform: true,
81
+ };
82
+ /**
83
+ * Splits a flattened style into { layout, visual }. Unknown properties are
84
+ * ignored with a one-time dev warning per key; undefined values are dropped.
85
+ */
86
+ export const splitStyle = (flat) => {
87
+ const layout = {};
88
+ const visual = {};
89
+ for (const [key, value] of Object.entries(flat)) {
90
+ if (value === undefined) {
91
+ continue;
92
+ }
93
+ if (Object.hasOwn(LAYOUT_KEYS, key)) {
94
+ ;
95
+ layout[key] = value;
96
+ }
97
+ else if (Object.hasOwn(VISUAL_KEYS, key)) {
98
+ ;
99
+ visual[key] = value;
100
+ }
101
+ else {
102
+ warnOnce(`unknown-style-prop:${key}`, `[react-native-gtkx] Unknown style property "${key}" is not supported and will be ignored`);
103
+ }
104
+ }
105
+ return { layout, visual };
106
+ };
107
+ //# sourceMappingURL=split-style.js.map
@@ -0,0 +1 @@
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, task 004) 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: `transform` is visual by contract — it is applied by the layout\n// engine through Fixed.Child matrices, not through CSS, and is passed\n// through here untouched.\nconst VISUAL_KEYS: Record<keyof VisualStyle, true> = {\n backgroundColor: 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 textAlign: true,\n transform: true,\n}\n\n/**\n * Splits a flattened style into { layout, visual }. Unknown properties are\n * ignored with a one-time dev warning per key; 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 {\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,43 @@
1
+ import type { FlatStyle, StyleProp } from "../contracts";
2
+ export declare const hairlineWidth = 1;
3
+ export declare const absoluteFillObject: {
4
+ position: "absolute";
5
+ left: number;
6
+ right: number;
7
+ top: number;
8
+ bottom: number;
9
+ };
10
+ export declare const absoluteFill: FlatStyle;
11
+ type NamedStyles<T> = {
12
+ [P in keyof T]: FlatStyle;
13
+ };
14
+ /**
15
+ * Registers a map of named styles. Identity function at runtime (like modern
16
+ * React Native); exists for typing and API compatibility.
17
+ */
18
+ export declare const create: <T extends NamedStyles<T>>(styles: T & NamedStyles<T>) => T;
19
+ /**
20
+ * Flattens a style prop (object, or arbitrarily nested arrays with falsy
21
+ * holes `[a, b, cond && c]`) into a single plain object. Later entries win.
22
+ */
23
+ export declare const flatten: (style: StyleProp<FlatStyle>) => FlatStyle;
24
+ /**
25
+ * Combines two style props so that style2 takes precedence. Mirrors React
26
+ * Native: returns the non-null one when the other is null/undefined.
27
+ */
28
+ export declare const compose: (style1: StyleProp<FlatStyle>, style2: StyleProp<FlatStyle>) => StyleProp<FlatStyle>;
29
+ export declare const StyleSheet: {
30
+ absoluteFill: FlatStyle;
31
+ absoluteFillObject: {
32
+ position: "absolute";
33
+ left: number;
34
+ right: number;
35
+ top: number;
36
+ bottom: number;
37
+ };
38
+ compose: (style1: StyleProp<FlatStyle>, style2: StyleProp<FlatStyle>) => StyleProp<FlatStyle>;
39
+ create: <T extends NamedStyles<T>>(styles: T & NamedStyles<T>) => T;
40
+ flatten: (style: StyleProp<FlatStyle>) => FlatStyle;
41
+ hairlineWidth: number;
42
+ };
43
+ export {};
@@ -0,0 +1,57 @@
1
+ // React Native's StyleSheet API. Pure module — no bridge imports.
2
+ // GTK renders in logical pixels (scale factor is applied by the compositor),
3
+ // so the thinnest visible line is 1.
4
+ export const hairlineWidth = 1;
5
+ export const absoluteFillObject = {
6
+ position: "absolute",
7
+ left: 0,
8
+ right: 0,
9
+ top: 0,
10
+ bottom: 0,
11
+ };
12
+ export const absoluteFill = Object.freeze({ ...absoluteFillObject });
13
+ /**
14
+ * Registers a map of named styles. Identity function at runtime (like modern
15
+ * React Native); exists for typing and API compatibility.
16
+ */
17
+ export const create = (styles) => styles;
18
+ const collect = (style, out) => {
19
+ if (!style) {
20
+ return;
21
+ }
22
+ if (Array.isArray(style)) {
23
+ for (const item of style) {
24
+ collect(item, out);
25
+ }
26
+ return;
27
+ }
28
+ Object.assign(out, style);
29
+ };
30
+ /**
31
+ * Flattens a style prop (object, or arbitrarily nested arrays with falsy
32
+ * holes `[a, b, cond && c]`) into a single plain object. Later entries win.
33
+ */
34
+ export const flatten = (style) => {
35
+ const out = {};
36
+ collect(style, out);
37
+ return out;
38
+ };
39
+ /**
40
+ * Combines two style props so that style2 takes precedence. Mirrors React
41
+ * Native: returns the non-null one when the other is null/undefined.
42
+ */
43
+ export const compose = (style1, style2) => {
44
+ if (style1 != null && style2 != null) {
45
+ return [style1, style2];
46
+ }
47
+ return style1 != null ? style1 : style2;
48
+ };
49
+ export const StyleSheet = {
50
+ absoluteFill,
51
+ absoluteFillObject,
52
+ compose,
53
+ create,
54
+ flatten,
55
+ hairlineWidth,
56
+ };
57
+ //# sourceMappingURL=style-sheet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style-sheet.js","sourceRoot":"","sources":["../../src/style/style-sheet.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAIlE,6EAA6E;AAC7E,qCAAqC;AACrC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAA;AAE9B,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,QAAQ,EAAE,UAAU;IACpB,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;IACR,GAAG,EAAE,CAAC;IACN,MAAM,EAAE,CAAC;CACU,CAAA;AAErB,MAAM,CAAC,MAAM,YAAY,GAAc,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,kBAAkB,EAAE,CAAC,CAAA;AAI/E;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CACpB,MAA0B,EACvB,EAAE,CAAC,MAAM,CAAA;AAEd,MAAM,OAAO,GAAG,CACd,KAA2B,EAC3B,GAA4B,EACtB,EAAE;IACR,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAM;IACR,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,MAAM,IAAI,IAAI,KAA4C,EAAE,CAAC;YAChE,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QACpB,CAAC;QACD,OAAM;IACR,CAAC;IACD,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;AAC3B,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,KAA2B,EAAa,EAAE;IAChE,MAAM,GAAG,GAA4B,EAAE,CAAA;IACvC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IACnB,OAAO,GAAgB,CAAA;AACzB,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CACrB,MAA4B,EAC5B,MAA4B,EACN,EAAE;IACxB,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACrC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACzB,CAAC;IACD,OAAO,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAA;AACzC,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,YAAY;IACZ,kBAAkB;IAClB,OAAO;IACP,MAAM;IACN,OAAO;IACP,aAAa;CACd,CAAA","sourcesContent":["// React Native's StyleSheet API. Pure module — no bridge imports.\n\nimport type { FlatStyle, StyleProp } from \"../contracts\"\n\n// GTK renders in logical pixels (scale factor is applied by the compositor),\n// so the thinnest visible line is 1.\nexport const hairlineWidth = 1\n\nexport const absoluteFillObject = {\n position: \"absolute\",\n left: 0,\n right: 0,\n top: 0,\n bottom: 0,\n} satisfies FlatStyle\n\nexport const absoluteFill: FlatStyle = Object.freeze({ ...absoluteFillObject })\n\ntype NamedStyles<T> = { [P in keyof T]: FlatStyle }\n\n/**\n * Registers a map of named styles. Identity function at runtime (like modern\n * React Native); exists for typing and API compatibility.\n */\nexport const create = <T extends NamedStyles<T>>(\n styles: T & NamedStyles<T>,\n): T => styles\n\nconst collect = (\n style: StyleProp<FlatStyle>,\n out: Record<string, unknown>,\n): void => {\n if (!style) {\n return\n }\n if (Array.isArray(style)) {\n for (const item of style as ReadonlyArray<StyleProp<FlatStyle>>) {\n collect(item, out)\n }\n return\n }\n Object.assign(out, style)\n}\n\n/**\n * Flattens a style prop (object, or arbitrarily nested arrays with falsy\n * holes `[a, b, cond && c]`) into a single plain object. Later entries win.\n */\nexport const flatten = (style: StyleProp<FlatStyle>): FlatStyle => {\n const out: Record<string, unknown> = {}\n collect(style, out)\n return out as FlatStyle\n}\n\n/**\n * Combines two style props so that style2 takes precedence. Mirrors React\n * Native: returns the non-null one when the other is null/undefined.\n */\nexport const compose = (\n style1: StyleProp<FlatStyle>,\n style2: StyleProp<FlatStyle>,\n): StyleProp<FlatStyle> => {\n if (style1 != null && style2 != null) {\n return [style1, style2]\n }\n return style1 != null ? style1 : style2\n}\n\nexport const StyleSheet = {\n absoluteFill,\n absoluteFillObject,\n compose,\n create,\n flatten,\n hairlineWidth,\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import type { VisualStyle } from "../contracts";
2
+ export type TextAlign = NonNullable<VisualStyle["textAlign"]>;
3
+ export type LabelAlignProps = {
4
+ xalign: number;
5
+ justification: "left" | "right" | "center" | "fill";
6
+ };
7
+ export declare const textAlignToLabelProps: (textAlign: TextAlign | undefined) => LabelAlignProps;
@@ -0,0 +1,22 @@
1
+ // GTK4 CSS has no text-align property, so textAlign never reaches the CSS
2
+ // generator: the Text component (006) maps it onto GtkLabel properties with
3
+ // this pure helper (no bridge imports).
4
+ //
5
+ // - xalign positions the whole text block inside the label allocation;
6
+ // - justification aligns wrapped lines relative to each other (values match
7
+ // Gtk.Justification: left/right/center/fill).
8
+ export const textAlignToLabelProps = (textAlign) => {
9
+ switch (textAlign) {
10
+ case "right":
11
+ return { xalign: 1, justification: "right" };
12
+ case "center":
13
+ return { xalign: 0.5, justification: "center" };
14
+ case "justify":
15
+ return { xalign: 0, justification: "fill" };
16
+ case "auto":
17
+ case "left":
18
+ case undefined:
19
+ return { xalign: 0, justification: "left" };
20
+ }
21
+ };
22
+ //# sourceMappingURL=text-align.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-align.js","sourceRoot":"","sources":["../../src/style/text-align.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,4EAA4E;AAC5E,wCAAwC;AACxC,EAAE;AACF,uEAAuE;AACvE,4EAA4E;AAC5E,gDAAgD;AAWhD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,SAAgC,EACf,EAAE;IACnB,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,OAAO;YACV,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,CAAA;QAC9C,KAAK,QAAQ;YACX,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAA;QACjD,KAAK,SAAS;YACZ,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,CAAA;QAC7C,KAAK,MAAM,CAAC;QACZ,KAAK,MAAM,CAAC;QACZ,KAAK,SAAS;YACZ,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,CAAA;IAC/C,CAAC;AACH,CAAC,CAAA","sourcesContent":["// GTK4 CSS has no text-align property, so textAlign never reaches the CSS\n// generator: the Text component (006) maps it onto GtkLabel properties with\n// this pure helper (no bridge imports).\n//\n// - xalign positions the whole text block inside the label allocation;\n// - justification aligns wrapped lines relative to each other (values match\n// Gtk.Justification: left/right/center/fill).\n\nimport type { VisualStyle } from \"../contracts\"\n\nexport type TextAlign = NonNullable<VisualStyle[\"textAlign\"]>\n\nexport type LabelAlignProps = {\n xalign: number\n justification: \"left\" | \"right\" | \"center\" | \"fill\"\n}\n\nexport const textAlignToLabelProps = (\n textAlign: TextAlign | undefined,\n): LabelAlignProps => {\n switch (textAlign) {\n case \"right\":\n return { xalign: 1, justification: \"right\" }\n case \"center\":\n return { xalign: 0.5, justification: \"center\" }\n case \"justify\":\n return { xalign: 0, justification: \"fill\" }\n case \"auto\":\n case \"left\":\n case undefined:\n return { xalign: 0, justification: \"left\" }\n }\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import type { VisualStyle } from "../contracts";
2
+ /**
3
+ * Renders a VisualStyle as GTK CSS declarations (one per line, stable
4
+ * order). Returns "" when the style produces no CSS (e.g. transform-only).
5
+ */
6
+ export declare const visualStyleToCss: (visual: VisualStyle) => string;
@@ -0,0 +1,133 @@
1
+ // Compiles a VisualStyle into a GTK4 CSS declaration block (no selector).
2
+ // Pure module — the resulting string is registered as a class through an
3
+ // injected `css` function (see registry.ts / registry.gtkx.ts).
4
+ //
5
+ // GTK4 CSS is not web CSS. What this generator relies on:
6
+ // - background-color, border-*, border-radius (incl. per-corner), opacity,
7
+ // color, font-*, letter-spacing: supported by GTK4;
8
+ // - line-height: supported since GTK 4.6 (we target 4.20+);
9
+ // - text-align does NOT exist in GTK CSS — textAlign is applied by the Text
10
+ // component via widget properties (justify/xalign), so it is skipped here;
11
+ // - transform is applied by the layout engine via Fixed.Child matrices,
12
+ // never through CSS, and is skipped here as well.
13
+ import { parseColor } from "./colors";
14
+ import { warnOnce } from "./dev-warning";
15
+ const px = (value) => `${value}px`;
16
+ const clamp01 = (value) => Math.min(1, Math.max(0, value));
17
+ const pushColor = (declarations, cssProperty, value, styleProperty) => {
18
+ const parsed = parseColor(value);
19
+ if (parsed === null) {
20
+ warnOnce(`invalid-color:${styleProperty}:${value}`, `[react-native-gtkx] Invalid color ${JSON.stringify(value)} in "${styleProperty}" — declaration dropped`);
21
+ return;
22
+ }
23
+ declarations.push(`${cssProperty}: ${parsed};`);
24
+ };
25
+ const formatFontFamily = (family) => {
26
+ const trimmed = family.trim();
27
+ if (/^(".*"|'.*')$/.test(trimmed)) {
28
+ return trimmed;
29
+ }
30
+ return /^[A-Za-z][\w-]*$/.test(trimmed)
31
+ ? trimmed
32
+ : `"${trimmed.replace(/"/g, '\\"')}"`;
33
+ };
34
+ /**
35
+ * Renders a VisualStyle as GTK CSS declarations (one per line, stable
36
+ * order). Returns "" when the style produces no CSS (e.g. transform-only).
37
+ */
38
+ export const visualStyleToCss = (visual) => {
39
+ const decls = [];
40
+ if (visual.backgroundColor !== undefined) {
41
+ pushColor(decls, "background-color", visual.backgroundColor, "backgroundColor");
42
+ }
43
+ if (visual.opacity !== undefined) {
44
+ decls.push(`opacity: ${clamp01(visual.opacity)};`);
45
+ }
46
+ // GTK defaults border-style to none — width alone renders nothing. An
47
+ // explicit borderStyle wins (GTK4 CSS supports solid/dotted/dashed);
48
+ // otherwise any positive border width turns the border on with "solid".
49
+ const hasVisibleBorderWidth = [
50
+ visual.borderWidth,
51
+ visual.borderTopWidth,
52
+ visual.borderRightWidth,
53
+ visual.borderBottomWidth,
54
+ visual.borderLeftWidth,
55
+ ].some((width) => width !== undefined && width > 0);
56
+ if (visual.borderStyle !== undefined) {
57
+ decls.push(`border-style: ${visual.borderStyle};`);
58
+ }
59
+ else if (hasVisibleBorderWidth) {
60
+ decls.push("border-style: solid;");
61
+ }
62
+ // Shorthands first, then per-side overrides so the sides win.
63
+ if (visual.borderWidth !== undefined) {
64
+ decls.push(`border-width: ${px(visual.borderWidth)};`);
65
+ }
66
+ if (visual.borderTopWidth !== undefined) {
67
+ decls.push(`border-top-width: ${px(visual.borderTopWidth)};`);
68
+ }
69
+ if (visual.borderRightWidth !== undefined) {
70
+ decls.push(`border-right-width: ${px(visual.borderRightWidth)};`);
71
+ }
72
+ if (visual.borderBottomWidth !== undefined) {
73
+ decls.push(`border-bottom-width: ${px(visual.borderBottomWidth)};`);
74
+ }
75
+ if (visual.borderLeftWidth !== undefined) {
76
+ decls.push(`border-left-width: ${px(visual.borderLeftWidth)};`);
77
+ }
78
+ if (visual.borderColor !== undefined) {
79
+ pushColor(decls, "border-color", visual.borderColor, "borderColor");
80
+ }
81
+ if (visual.borderTopColor !== undefined) {
82
+ pushColor(decls, "border-top-color", visual.borderTopColor, "borderTopColor");
83
+ }
84
+ if (visual.borderRightColor !== undefined) {
85
+ pushColor(decls, "border-right-color", visual.borderRightColor, "borderRightColor");
86
+ }
87
+ if (visual.borderBottomColor !== undefined) {
88
+ pushColor(decls, "border-bottom-color", visual.borderBottomColor, "borderBottomColor");
89
+ }
90
+ if (visual.borderLeftColor !== undefined) {
91
+ pushColor(decls, "border-left-color", visual.borderLeftColor, "borderLeftColor");
92
+ }
93
+ if (visual.borderRadius !== undefined) {
94
+ decls.push(`border-radius: ${px(visual.borderRadius)};`);
95
+ }
96
+ // Per-corner radii come after the shorthand so they override it.
97
+ if (visual.borderTopLeftRadius !== undefined) {
98
+ decls.push(`border-top-left-radius: ${px(visual.borderTopLeftRadius)};`);
99
+ }
100
+ if (visual.borderTopRightRadius !== undefined) {
101
+ decls.push(`border-top-right-radius: ${px(visual.borderTopRightRadius)};`);
102
+ }
103
+ if (visual.borderBottomRightRadius !== undefined) {
104
+ decls.push(`border-bottom-right-radius: ${px(visual.borderBottomRightRadius)};`);
105
+ }
106
+ if (visual.borderBottomLeftRadius !== undefined) {
107
+ decls.push(`border-bottom-left-radius: ${px(visual.borderBottomLeftRadius)};`);
108
+ }
109
+ if (visual.color !== undefined) {
110
+ pushColor(decls, "color", visual.color, "color");
111
+ }
112
+ if (visual.fontFamily !== undefined) {
113
+ decls.push(`font-family: ${formatFontFamily(visual.fontFamily)};`);
114
+ }
115
+ if (visual.fontSize !== undefined) {
116
+ decls.push(`font-size: ${px(visual.fontSize)};`);
117
+ }
118
+ if (visual.fontStyle !== undefined) {
119
+ decls.push(`font-style: ${visual.fontStyle};`);
120
+ }
121
+ if (visual.fontWeight !== undefined) {
122
+ decls.push(`font-weight: ${visual.fontWeight};`);
123
+ }
124
+ if (visual.letterSpacing !== undefined) {
125
+ decls.push(`letter-spacing: ${px(visual.letterSpacing)};`);
126
+ }
127
+ if (visual.lineHeight !== undefined) {
128
+ decls.push(`line-height: ${px(visual.lineHeight)};`);
129
+ }
130
+ // visual.textAlign, visual.transform: intentionally not CSS (see header).
131
+ return decls.join("\n");
132
+ };
133
+ //# sourceMappingURL=visual-css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visual-css.js","sourceRoot":"","sources":["../../src/style/visual-css.ts"],"names":[],"mappings":"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","sourcesContent":["// Compiles a VisualStyle into a GTK4 CSS declaration block (no selector).\n// Pure module — the resulting string is registered as a class through an\n// injected `css` function (see registry.ts / registry.gtkx.ts).\n//\n// GTK4 CSS is not web CSS. What this generator relies on:\n// - background-color, border-*, border-radius (incl. per-corner), opacity,\n// color, font-*, letter-spacing: supported by GTK4;\n// - line-height: supported since GTK 4.6 (we target 4.20+);\n// - text-align does NOT exist in GTK CSS — textAlign is applied by the Text\n// component via widget properties (justify/xalign), so it is skipped here;\n// - transform is applied by the layout engine via Fixed.Child matrices,\n// never through CSS, and is skipped here as well.\n\nimport type { VisualStyle } from \"../contracts\"\nimport { parseColor } from \"./colors\"\nimport { warnOnce } from \"./dev-warning\"\n\nconst px = (value: number): string => `${value}px`\n\nconst clamp01 = (value: number): number => Math.min(1, Math.max(0, value))\n\nconst pushColor = (\n declarations: string[],\n cssProperty: string,\n value: string,\n styleProperty: string,\n): void => {\n const parsed = parseColor(value)\n if (parsed === null) {\n warnOnce(\n `invalid-color:${styleProperty}:${value}`,\n `[react-native-gtkx] Invalid color ${JSON.stringify(value)} in \"${styleProperty}\" — declaration dropped`,\n )\n return\n }\n declarations.push(`${cssProperty}: ${parsed};`)\n}\n\nconst formatFontFamily = (family: string): string => {\n const trimmed = family.trim()\n if (/^(\".*\"|'.*')$/.test(trimmed)) {\n return trimmed\n }\n return /^[A-Za-z][\\w-]*$/.test(trimmed)\n ? trimmed\n : `\"${trimmed.replace(/\"/g, '\\\\\"')}\"`\n}\n\n/**\n * Renders a VisualStyle as GTK CSS declarations (one per line, stable\n * order). Returns \"\" when the style produces no CSS (e.g. transform-only).\n */\nexport const visualStyleToCss = (visual: VisualStyle): string => {\n const decls: string[] = []\n\n if (visual.backgroundColor !== undefined) {\n pushColor(\n decls,\n \"background-color\",\n visual.backgroundColor,\n \"backgroundColor\",\n )\n }\n if (visual.opacity !== undefined) {\n decls.push(`opacity: ${clamp01(visual.opacity)};`)\n }\n\n // GTK defaults border-style to none — width alone renders nothing. An\n // explicit borderStyle wins (GTK4 CSS supports solid/dotted/dashed);\n // otherwise any positive border width turns the border on with \"solid\".\n const hasVisibleBorderWidth = [\n visual.borderWidth,\n visual.borderTopWidth,\n visual.borderRightWidth,\n visual.borderBottomWidth,\n visual.borderLeftWidth,\n ].some((width) => width !== undefined && width > 0)\n if (visual.borderStyle !== undefined) {\n decls.push(`border-style: ${visual.borderStyle};`)\n } else if (hasVisibleBorderWidth) {\n decls.push(\"border-style: solid;\")\n }\n // Shorthands first, then per-side overrides so the sides win.\n if (visual.borderWidth !== undefined) {\n decls.push(`border-width: ${px(visual.borderWidth)};`)\n }\n if (visual.borderTopWidth !== undefined) {\n decls.push(`border-top-width: ${px(visual.borderTopWidth)};`)\n }\n if (visual.borderRightWidth !== undefined) {\n decls.push(`border-right-width: ${px(visual.borderRightWidth)};`)\n }\n if (visual.borderBottomWidth !== undefined) {\n decls.push(`border-bottom-width: ${px(visual.borderBottomWidth)};`)\n }\n if (visual.borderLeftWidth !== undefined) {\n decls.push(`border-left-width: ${px(visual.borderLeftWidth)};`)\n }\n if (visual.borderColor !== undefined) {\n pushColor(decls, \"border-color\", visual.borderColor, \"borderColor\")\n }\n if (visual.borderTopColor !== undefined) {\n pushColor(\n decls,\n \"border-top-color\",\n visual.borderTopColor,\n \"borderTopColor\",\n )\n }\n if (visual.borderRightColor !== undefined) {\n pushColor(\n decls,\n \"border-right-color\",\n visual.borderRightColor,\n \"borderRightColor\",\n )\n }\n if (visual.borderBottomColor !== undefined) {\n pushColor(\n decls,\n \"border-bottom-color\",\n visual.borderBottomColor,\n \"borderBottomColor\",\n )\n }\n if (visual.borderLeftColor !== undefined) {\n pushColor(\n decls,\n \"border-left-color\",\n visual.borderLeftColor,\n \"borderLeftColor\",\n )\n }\n if (visual.borderRadius !== undefined) {\n decls.push(`border-radius: ${px(visual.borderRadius)};`)\n }\n // Per-corner radii come after the shorthand so they override it.\n if (visual.borderTopLeftRadius !== undefined) {\n decls.push(`border-top-left-radius: ${px(visual.borderTopLeftRadius)};`)\n }\n if (visual.borderTopRightRadius !== undefined) {\n decls.push(`border-top-right-radius: ${px(visual.borderTopRightRadius)};`)\n }\n if (visual.borderBottomRightRadius !== undefined) {\n decls.push(\n `border-bottom-right-radius: ${px(visual.borderBottomRightRadius)};`,\n )\n }\n if (visual.borderBottomLeftRadius !== undefined) {\n decls.push(\n `border-bottom-left-radius: ${px(visual.borderBottomLeftRadius)};`,\n )\n }\n\n if (visual.color !== undefined) {\n pushColor(decls, \"color\", visual.color, \"color\")\n }\n if (visual.fontFamily !== undefined) {\n decls.push(`font-family: ${formatFontFamily(visual.fontFamily)};`)\n }\n if (visual.fontSize !== undefined) {\n decls.push(`font-size: ${px(visual.fontSize)};`)\n }\n if (visual.fontStyle !== undefined) {\n decls.push(`font-style: ${visual.fontStyle};`)\n }\n if (visual.fontWeight !== undefined) {\n decls.push(`font-weight: ${visual.fontWeight};`)\n }\n if (visual.letterSpacing !== undefined) {\n decls.push(`letter-spacing: ${px(visual.letterSpacing)};`)\n }\n if (visual.lineHeight !== undefined) {\n decls.push(`line-height: ${px(visual.lineHeight)};`)\n }\n\n // visual.textAlign, visual.transform: intentionally not CSS (see header).\n\n return decls.join(\"\\n\")\n}\n"]}
@@ -0,0 +1,53 @@
1
+ import type { Plugin } from "vite";
2
+ /** Options shared by the preset factory and the pure resolver helpers. */
3
+ export type PlatformResolutionOptions = {
4
+ /** Platform suffix priority, most specific first. Default: ["linux", "native"]. */
5
+ platforms?: readonly string[];
6
+ /** Source extensions tried for every platform suffix. Default: ["tsx", "ts", "jsx", "js"]. */
7
+ extensions?: readonly string[];
8
+ };
9
+ /** Predicate the plugin injects as fs.existsSync; tests inject fakes. */
10
+ export type FileExists = (filePath: string) => boolean;
11
+ export declare const DEFAULT_PLATFORMS: readonly string[];
12
+ export declare const DEFAULT_EXTENSIONS: readonly string[];
13
+ /**
14
+ * Maps `react-native` (and its subpaths) to `react-native-gtkx`.
15
+ * Returns null for every other specifier, including `react-native-gtkx`
16
+ * itself and lookalikes such as `react-native-web`.
17
+ */
18
+ export declare const rewriteReactNativeImport: (source: string) => string | null;
19
+ /** Splits a vite specifier into its path part and its `?query` suffix. */
20
+ export declare const splitQuery: (source: string) => {
21
+ specifier: string;
22
+ query: string;
23
+ };
24
+ /**
25
+ * Ordered platform suffixes, platform-major: every extension of the first
26
+ * platform is tried before any extension of the next one
27
+ * (`.linux.tsx`, `.linux.ts`, …, `.native.tsx`, …).
28
+ */
29
+ export declare const platformSuffixes: (options?: PlatformResolutionOptions) => string[];
30
+ /**
31
+ * Candidate file paths for an extensionless base path, in priority order:
32
+ * direct platform files first, then platform index files of a directory —
33
+ * mirroring Metro, which exhausts file resolution before directory resolution.
34
+ * The base file itself is not a candidate: when no platform file exists the
35
+ * plugin bails out and the default resolver picks the base module.
36
+ */
37
+ export declare const platformCandidates: (base: string, options?: PlatformResolutionOptions) => string[];
38
+ /**
39
+ * Metro platform-extension resolution for a single import:
40
+ * only extensionless relative (or absolute) specifiers participate; the first
41
+ * existing candidate wins; the `?query` suffix is carried over. Returns null
42
+ * when the import is out of scope or no platform file exists, handing the
43
+ * import back to the default resolver.
44
+ */
45
+ export declare const resolvePlatformSpecifier: (source: string, importer: string | undefined, exists: FileExists, options?: PlatformResolutionOptions) => string | null;
46
+ export type ReactNativeGtkxOptions = PlatformResolutionOptions;
47
+ /**
48
+ * Vite plugin: aliases `react-native` (and subpaths) to `react-native-gtkx`
49
+ * and resolves Metro-style platform extensions
50
+ * (`.linux.tsx` → `.native.tsx` → base) for extensionless imports.
51
+ */
52
+ export declare const reactNativeGtkx: (options?: ReactNativeGtkxOptions) => Plugin;
53
+ export default reactNativeGtkx;