@multiplatform.one/theme 7.34.3 → 7.35.0

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 (280) hide show
  1. package/package.json +20 -5
  2. package/src/audit/constraintAudit.spec.ts +274 -87
  3. package/src/audit/constraintAudit.ts +135 -120
  4. package/src/audit/constraintScope.spec.ts +1 -1
  5. package/src/audit/designTokens.ts +42 -0
  6. package/src/audit/themeMatrix.spec.ts +83 -2
  7. package/src/audit/themeMatrix.ts +33 -1
  8. package/src/figma/figmaTokens.spec.ts +26 -34
  9. package/src/figma/figmaTokens.ts +26 -50
  10. package/src/fonts/createFontLoader.ts +4 -1
  11. package/src/menuRow.ts +4 -1
  12. package/src/theme/FontKnobStyles.tsx +2 -1
  13. package/src/theme/Preset.stories.tsx +0 -1
  14. package/src/theme/Preset.tsx +6 -1
  15. package/src/theme/PresetContext.ts +4 -0
  16. package/src/theme/Surface.spec.tsx +114 -67
  17. package/src/theme/Surface.stories.tsx +8 -25
  18. package/src/theme/Surface.tsx +87 -43
  19. package/src/theme/accentFloor.spec.ts +37 -11
  20. package/src/theme/activateThemeConfig.ts +22 -6
  21. package/src/theme/animations/animations.spec.ts +62 -0
  22. package/src/theme/animations/css.ts +9 -35
  23. package/src/theme/animations/reactNative.ts +98 -25
  24. package/src/theme/boundaryFloor.spec.ts +57 -0
  25. package/src/theme/chartPalette.spec.ts +56 -27
  26. package/src/theme/chartPalette.ts +33 -28
  27. package/src/theme/colorRules.spec.ts +32 -72
  28. package/src/theme/cookies.spec.ts +49 -18
  29. package/src/theme/cookies.ts +36 -7
  30. package/src/theme/cookiesPersistence.spec.ts +5 -5
  31. package/src/theme/createDefaultThemeConfig.spec.ts +182 -20
  32. package/src/theme/createDefaultThemeConfig.ts +34 -28
  33. package/src/theme/createThemes.ts +169 -218
  34. package/src/theme/defaults/accent.ts +3 -35
  35. package/src/theme/defaults/base.ts +14 -53
  36. package/src/theme/defaults/builderOptions.ts +68 -85
  37. package/src/theme/defaults/categoryFonts.ts +10 -0
  38. package/src/theme/defaults/fonts.spec.ts +84 -4
  39. package/src/theme/defaults/fonts.ts +166 -124
  40. package/src/theme/defaults/house.ts +48 -0
  41. package/src/theme/defaults/index.ts +1 -0
  42. package/src/theme/defaults/neutralRamp.spec.ts +52 -47
  43. package/src/theme/devtools/ColorLineVisualizer.tsx +6 -6
  44. package/src/theme/devtools/ThemeDevtoolsPanel.setMarkers.spec.tsx +13 -6
  45. package/src/theme/devtools/ThemeDevtoolsPanel.tsx +14 -77
  46. package/src/theme/devtools/animationOptions.spec.ts +23 -37
  47. package/src/theme/devtools/animationOptions.ts +4 -6
  48. package/src/theme/devtools/buildSnapshot.ts +0 -3
  49. package/src/theme/devtools/knobIcons.tsx +4 -24
  50. package/src/theme/focusState.spec.ts +9 -30
  51. package/src/theme/index.ts +17 -0
  52. package/src/theme/intentFill.spec.ts +42 -0
  53. package/src/theme/knobs.ts +14 -42
  54. package/src/theme/layoutTokens.ts +15 -1
  55. package/src/theme/layoutTokensHooks.spec.tsx +8 -4
  56. package/src/theme/mergedTokens.ts +20 -0
  57. package/src/theme/motion.spec.ts +84 -0
  58. package/src/theme/motion.ts +53 -0
  59. package/src/theme/motionStops.ts +17 -0
  60. package/src/theme/motionTiming.ts +59 -0
  61. package/src/theme/mpo13Proof.spec.ts +43 -46
  62. package/src/theme/mpo19Proof.spec.ts +13 -14
  63. package/src/theme/namedInkFloor.spec.ts +60 -0
  64. package/src/theme/overlaySurfaces.tsx +330 -0
  65. package/src/theme/preset.types.ts +16 -0
  66. package/src/theme/presetPreview.ts +32 -0
  67. package/src/theme/presetRoot.spec.tsx +89 -0
  68. package/src/theme/presetStore.persistence.spec.ts +141 -0
  69. package/src/theme/presetStore.spec.ts +205 -0
  70. package/src/theme/presetStore.ts +286 -0
  71. package/src/theme/presetUserSync.spec.tsx +168 -0
  72. package/src/theme/presetUserSync.ts +47 -0
  73. package/src/theme/presets.spec.ts +22 -15
  74. package/src/theme/presets.ts +22 -10
  75. package/src/theme/radiusClass.spec.ts +60 -41
  76. package/src/theme/radiusClass.ts +17 -4
  77. package/src/theme/radiusClassTable.generated.ts +3 -3
  78. package/src/theme/readableColor.spec.ts +59 -152
  79. package/src/theme/readableColor.ts +34 -174
  80. package/src/theme/recipeInputs.ts +153 -295
  81. package/src/theme/recipes.ts +58 -18
  82. package/src/theme/resolveKnobs.spec.ts +528 -588
  83. package/src/theme/resolveKnobs.ts +250 -325
  84. package/src/theme/scale/ScaleStyles.native.tsx +19 -0
  85. package/src/theme/scale/ScaleStyles.tsx +48 -0
  86. package/src/theme/scale/activeScale.ts +30 -0
  87. package/src/theme/scale/deriveRecipeInputs.ts +110 -0
  88. package/src/theme/scale/generateScale.spec.ts +260 -0
  89. package/src/theme/scale/generateScale.ts +147 -0
  90. package/src/theme/scale/index.ts +54 -0
  91. package/src/theme/scale/installScaleConfig.native.spec.ts +77 -0
  92. package/src/theme/scale/installScaleConfig.native.ts +57 -0
  93. package/src/theme/scale/installScaleConfig.ts +7 -0
  94. package/src/theme/scale/scaleAttribute.ts +21 -0
  95. package/src/theme/scale/scaleCss.probe.spec.tsx +64 -0
  96. package/src/theme/scale/scaleCss.spec.ts +132 -0
  97. package/src/theme/scale/scaleCss.ts +95 -0
  98. package/src/theme/scale/scaleFonts.ts +106 -0
  99. package/src/theme/scale/scaleInputs.ts +322 -0
  100. package/src/theme/scale/themeScales.ts +181 -0
  101. package/src/theme/scale/useActiveScale.spec.tsx +129 -0
  102. package/src/theme/scale/useActiveScale.ts +95 -0
  103. package/src/theme/schemeStore.spec.ts +81 -0
  104. package/src/theme/schemeStore.ts +67 -0
  105. package/src/theme/shared.spec.ts +7 -6
  106. package/src/theme/shared.tsx +37 -3
  107. package/src/theme/sizeLadder.spec.ts +37 -36
  108. package/src/theme/sizeRecipes.spec.ts +179 -85
  109. package/src/theme/sizeRecipes.ts +48 -25
  110. package/src/theme/subsetThemes.spec.ts +9 -3
  111. package/src/theme/switchThumb.spec.ts +69 -0
  112. package/src/theme/syntaxFloor.spec.ts +11 -8
  113. package/src/theme/theme.hydration.native.spec.tsx +51 -0
  114. package/src/theme/theme.native.tsx +59 -21
  115. package/src/theme/theme.palette.spec.tsx +76 -0
  116. package/src/theme/theme.preset.native.spec.tsx +73 -0
  117. package/src/theme/theme.provider.spec.ts +143 -1
  118. package/src/theme/theme.tsx +61 -25
  119. package/src/theme/tileSizes.ts +6 -7
  120. package/src/theme/transitionProps.native.ts +25 -2
  121. package/src/theme/transitionProps.spec.ts +34 -0
  122. package/src/theme/transitionProps.ts +26 -2
  123. package/src/theme/usePresetSwitch.native.spec.tsx +68 -0
  124. package/src/theme/usePresetSwitch.native.ts +32 -0
  125. package/src/theme/usePresetSwitch.spec.tsx +103 -0
  126. package/src/theme/usePresetSwitch.ts +54 -0
  127. package/src/theme/useResolvedKnobs.hydration.spec.tsx +2 -2
  128. package/src/theme/useResolvedKnobs.ts +23 -90
  129. package/src/theme/useResolvedKnobsBehavior.spec.tsx +25 -30
  130. package/src/theme/useSchemePreference.native.ts +33 -0
  131. package/src/theme/useSchemePreference.spec.tsx +51 -0
  132. package/src/theme/useSchemePreference.ts +32 -0
  133. package/src/theme/useSchemePreference.web.spec.tsx +32 -0
  134. package/src/theme/useTheme.native.spec.tsx +68 -0
  135. package/src/theme/useTheme.native.ts +49 -24
  136. package/src/theme/useTheme.ts +7 -4
  137. package/types/audit/constraintAudit.d.ts +6 -5
  138. package/types/audit/constraintAudit.d.ts.map +1 -1
  139. package/types/audit/designTokens.d.ts +13 -0
  140. package/types/audit/designTokens.d.ts.map +1 -0
  141. package/types/audit/themeMatrix.d.ts +10 -0
  142. package/types/audit/themeMatrix.d.ts.map +1 -1
  143. package/types/figma/figmaTokens.d.ts +11 -28
  144. package/types/figma/figmaTokens.d.ts.map +1 -1
  145. package/types/fonts/createFontLoader.d.ts.map +1 -1
  146. package/types/menuRow.d.ts +4 -1
  147. package/types/menuRow.d.ts.map +1 -1
  148. package/types/theme/FontKnobStyles.d.ts.map +1 -1
  149. package/types/theme/Preset.d.ts.map +1 -1
  150. package/types/theme/PresetContext.d.ts +4 -0
  151. package/types/theme/PresetContext.d.ts.map +1 -1
  152. package/types/theme/Surface.d.ts +57 -26
  153. package/types/theme/Surface.d.ts.map +1 -1
  154. package/types/theme/activateThemeConfig.d.ts +5 -3
  155. package/types/theme/activateThemeConfig.d.ts.map +1 -1
  156. package/types/theme/animations/css.d.ts +27 -34
  157. package/types/theme/animations/css.d.ts.map +1 -1
  158. package/types/theme/animations/reactNative.d.ts +196 -45
  159. package/types/theme/animations/reactNative.d.ts.map +1 -1
  160. package/types/theme/chartPalette.d.ts +11 -3
  161. package/types/theme/chartPalette.d.ts.map +1 -1
  162. package/types/theme/colorRules.d.ts +1 -1
  163. package/types/theme/cookies.d.ts +12 -1
  164. package/types/theme/cookies.d.ts.map +1 -1
  165. package/types/theme/createDefaultThemeConfig.d.ts +13 -13
  166. package/types/theme/createDefaultThemeConfig.d.ts.map +1 -1
  167. package/types/theme/createThemes.d.ts +58 -2
  168. package/types/theme/createThemes.d.ts.map +1 -1
  169. package/types/theme/defaults/accent.d.ts.map +1 -1
  170. package/types/theme/defaults/base.d.ts.map +1 -1
  171. package/types/theme/defaults/builderOptions.d.ts.map +1 -1
  172. package/types/theme/defaults/categoryFonts.d.ts +10 -0
  173. package/types/theme/defaults/categoryFonts.d.ts.map +1 -1
  174. package/types/theme/defaults/fonts.d.ts +330 -30
  175. package/types/theme/defaults/fonts.d.ts.map +1 -1
  176. package/types/theme/defaults/house.d.ts +8 -0
  177. package/types/theme/defaults/house.d.ts.map +1 -0
  178. package/types/theme/defaults/index.d.ts +1 -0
  179. package/types/theme/defaults/index.d.ts.map +1 -1
  180. package/types/theme/devtools/ThemeDevtoolsPanel.d.ts +3 -3
  181. package/types/theme/devtools/ThemeDevtoolsPanel.d.ts.map +1 -1
  182. package/types/theme/devtools/animationOptions.d.ts.map +1 -1
  183. package/types/theme/devtools/buildSnapshot.d.ts.map +1 -1
  184. package/types/theme/devtools/knobIcons.d.ts +0 -3
  185. package/types/theme/devtools/knobIcons.d.ts.map +1 -1
  186. package/types/theme/index.d.ts +11 -0
  187. package/types/theme/index.d.ts.map +1 -1
  188. package/types/theme/knobs.d.ts +8 -36
  189. package/types/theme/knobs.d.ts.map +1 -1
  190. package/types/theme/layoutTokens.d.ts +13 -1
  191. package/types/theme/layoutTokens.d.ts.map +1 -1
  192. package/types/theme/mergedTokens.d.ts +11 -0
  193. package/types/theme/mergedTokens.d.ts.map +1 -0
  194. package/types/theme/motion.d.ts +17 -0
  195. package/types/theme/motion.d.ts.map +1 -0
  196. package/types/theme/motionStops.d.ts +3 -0
  197. package/types/theme/motionStops.d.ts.map +1 -0
  198. package/types/theme/motionTiming.d.ts +36 -0
  199. package/types/theme/motionTiming.d.ts.map +1 -0
  200. package/types/theme/overlaySurfaces.d.ts +70 -0
  201. package/types/theme/overlaySurfaces.d.ts.map +1 -0
  202. package/types/theme/preset.types.d.ts +16 -0
  203. package/types/theme/preset.types.d.ts.map +1 -1
  204. package/types/theme/presetPreview.d.ts +14 -0
  205. package/types/theme/presetPreview.d.ts.map +1 -0
  206. package/types/theme/presetStore.d.ts +40 -0
  207. package/types/theme/presetStore.d.ts.map +1 -0
  208. package/types/theme/presetUserSync.d.ts +7 -0
  209. package/types/theme/presetUserSync.d.ts.map +1 -0
  210. package/types/theme/presets.d.ts +12 -4
  211. package/types/theme/presets.d.ts.map +1 -1
  212. package/types/theme/radiusClass.d.ts +5 -2
  213. package/types/theme/radiusClass.d.ts.map +1 -1
  214. package/types/theme/radiusClassTable.generated.d.ts +3 -3
  215. package/types/theme/readableColor.d.ts +11 -49
  216. package/types/theme/readableColor.d.ts.map +1 -1
  217. package/types/theme/recipeInputs.d.ts +39 -70
  218. package/types/theme/recipeInputs.d.ts.map +1 -1
  219. package/types/theme/recipes.d.ts +79 -18
  220. package/types/theme/recipes.d.ts.map +1 -1
  221. package/types/theme/resolveKnobs.d.ts +64 -32
  222. package/types/theme/resolveKnobs.d.ts.map +1 -1
  223. package/types/theme/scale/ScaleStyles.d.ts +18 -0
  224. package/types/theme/scale/ScaleStyles.d.ts.map +1 -0
  225. package/types/theme/scale/ScaleStyles.native.d.ts +10 -0
  226. package/types/theme/scale/ScaleStyles.native.d.ts.map +1 -0
  227. package/types/theme/scale/activeScale.d.ts +13 -0
  228. package/types/theme/scale/activeScale.d.ts.map +1 -0
  229. package/types/theme/scale/deriveRecipeInputs.d.ts +10 -0
  230. package/types/theme/scale/deriveRecipeInputs.d.ts.map +1 -0
  231. package/types/theme/scale/generateScale.d.ts +38 -0
  232. package/types/theme/scale/generateScale.d.ts.map +1 -0
  233. package/types/theme/scale/index.d.ts +17 -0
  234. package/types/theme/scale/index.d.ts.map +1 -0
  235. package/types/theme/scale/installScaleConfig.d.ts +4 -0
  236. package/types/theme/scale/installScaleConfig.d.ts.map +1 -0
  237. package/types/theme/scale/installScaleConfig.native.d.ts +13 -0
  238. package/types/theme/scale/installScaleConfig.native.d.ts.map +1 -0
  239. package/types/theme/scale/scaleAttribute.d.ts +14 -0
  240. package/types/theme/scale/scaleAttribute.d.ts.map +1 -0
  241. package/types/theme/scale/scaleCss.d.ts +25 -0
  242. package/types/theme/scale/scaleCss.d.ts.map +1 -0
  243. package/types/theme/scale/scaleFonts.d.ts +16 -0
  244. package/types/theme/scale/scaleFonts.d.ts.map +1 -0
  245. package/types/theme/scale/scaleInputs.d.ts +66 -0
  246. package/types/theme/scale/scaleInputs.d.ts.map +1 -0
  247. package/types/theme/scale/themeScales.d.ts +52 -0
  248. package/types/theme/scale/themeScales.d.ts.map +1 -0
  249. package/types/theme/scale/useActiveScale.d.ts +31 -0
  250. package/types/theme/scale/useActiveScale.d.ts.map +1 -0
  251. package/types/theme/schemeStore.d.ts +6 -0
  252. package/types/theme/schemeStore.d.ts.map +1 -0
  253. package/types/theme/shared.d.ts +18 -0
  254. package/types/theme/shared.d.ts.map +1 -1
  255. package/types/theme/sizeRecipes.d.ts +20 -15
  256. package/types/theme/sizeRecipes.d.ts.map +1 -1
  257. package/types/theme/theme.d.ts +2 -1
  258. package/types/theme/theme.d.ts.map +1 -1
  259. package/types/theme/theme.native.d.ts +10 -1
  260. package/types/theme/theme.native.d.ts.map +1 -1
  261. package/types/theme/tileSizes.d.ts +6 -7
  262. package/types/theme/tileSizes.d.ts.map +1 -1
  263. package/types/theme/transitionProps.d.ts +3 -1
  264. package/types/theme/transitionProps.d.ts.map +1 -1
  265. package/types/theme/transitionProps.native.d.ts +3 -1
  266. package/types/theme/transitionProps.native.d.ts.map +1 -1
  267. package/types/theme/usePresetSwitch.d.ts +10 -0
  268. package/types/theme/usePresetSwitch.d.ts.map +1 -0
  269. package/types/theme/usePresetSwitch.native.d.ts +10 -0
  270. package/types/theme/usePresetSwitch.native.d.ts.map +1 -0
  271. package/types/theme/useResolvedKnobs.d.ts +13 -13
  272. package/types/theme/useResolvedKnobs.d.ts.map +1 -1
  273. package/types/theme/useSchemePreference.d.ts +8 -0
  274. package/types/theme/useSchemePreference.d.ts.map +1 -0
  275. package/types/theme/useSchemePreference.native.d.ts +8 -0
  276. package/types/theme/useSchemePreference.native.d.ts.map +1 -0
  277. package/types/theme/useTheme.d.ts +4 -2
  278. package/types/theme/useTheme.d.ts.map +1 -1
  279. package/types/theme/useTheme.native.d.ts +10 -1
  280. package/types/theme/useTheme.native.d.ts.map +1 -1
@@ -4,15 +4,10 @@ import { useTouchSurface } from "./useTouchSurface";
4
4
  import { defaultKnobs, type Knobs } from "./knobs";
5
5
  import type { IntentOverride } from "./preset.types";
6
6
  import type { KnobPropsOverride, ResolvedKnobs } from "./recipes";
7
- import { applyDensity, compactSpaceMap, resolveKnobs } from "./resolveKnobs";
7
+ import { resolveKnobs } from "./resolveKnobs";
8
8
  import { usePresetContext } from "./PresetContext";
9
9
  import { defaultIntents } from "./intents";
10
- import {
11
- clampSurfaceDensity,
12
- clampSurfaceSize,
13
- SurfaceContext,
14
- type SurfaceIntent,
15
- } from "./Surface";
10
+ import { clampSurfaceSize, SurfaceContext } from "./Surface";
16
11
 
17
12
  export const IntentContext = createContext<string | null>(null);
18
13
 
@@ -46,61 +41,23 @@ function usePrefersReducedMotion(): boolean {
46
41
  return useSyncExternalStore(subscribeReducedMotion, readReducedMotion, serverReducedMotion);
47
42
  }
48
43
 
49
- function applySurfaceToKnobs(
50
- knobs: Knobs,
51
- surface: SurfaceIntent,
52
- opts: { sizeOverride: boolean; densityOverride: boolean },
53
- ): Knobs {
54
- let next = knobs;
55
- if (surface.size !== "unset") {
56
- if (!opts.sizeOverride) {
57
- next = { ...next, size: surface.size };
58
- } else {
59
- const size = clampSurfaceSize(next.size, surface.size);
60
- if (size !== "unset" && size !== next.size) {
61
- next = { ...next, size };
62
- }
63
- }
64
- }
65
- if (surface.density !== "unset") {
66
- if (!opts.densityOverride) {
67
- next = { ...next, density: surface.density };
68
- } else {
69
- const density = clampSurfaceDensity(next.density, surface.density);
70
- if (density !== "unset" && density !== next.density) {
71
- next = { ...next, density };
72
- }
73
- }
74
- }
75
- return next;
76
- }
77
-
78
44
  export interface UseResolvedKnobsOptions {
79
45
  intent?: string;
80
46
  component?: string;
81
47
  override?: KnobPropsOverride;
82
- /** Override the size from knobs */
48
+ /**
49
+ * The control size token (Tamagui's own `size`, "$3"). Clamped to the
50
+ * nearest `<Surface size>` ceiling (LC-78); omitted = the Surface's token,
51
+ * else `$true`.
52
+ */
83
53
  size?: SizeTokens;
84
54
  /**
85
- * Density-compact override (layout gaps only — does not step size).
86
- * When set, wins over `knobs.density`:
87
- * `true` forces compact density; `false` forces comfortable.
88
- * Then re-clamped to the parent Surface ceiling (LC-68).
89
- * When omitted, the density knob / Surface controls compact vs comfortable.
55
+ * Whether an ancestor already paints a surface box. Omitted = the nearest
56
+ * `<Surface painted>`; overlay frames pass `false` because they float.
90
57
  */
91
- compact?: boolean;
58
+ painted?: boolean;
92
59
  }
93
60
 
94
- const sizeTokenToKnobSize: Record<string, Knobs["size"]> = {
95
- $1: "small",
96
- $2: "small",
97
- $3: "small",
98
- $4: "medium",
99
- $5: "large",
100
- $6: "large",
101
- $true: "medium",
102
- };
103
-
104
61
  export const solidButtonIntents = new Set(["error", "warning", "success"]);
105
62
 
106
63
  /**
@@ -118,12 +75,11 @@ export const solidPaletteThemes = new Set(["accent"]);
118
75
  * 1. Base knobs from nearest <Preset> context
119
76
  * 2. Merge intent-level overrides (if intent provided or from context)
120
77
  * 3. Merge intent+component overrides (if both provided)
121
- * 4. Apply size override if provided
122
- * 5. Clamp size/density to Surface context (step-down only, LC-68)
123
- * 6. Apply density (space only; compact option wins when provided)
124
- * 7. Re-clamp to Surface ceiling (compact option cannot exceed parent)
125
- * 8. OS reduced-motion forces animation="none"
126
- * 9. Call resolveKnobs(mergedKnobs, override, scheme) — override merges last
78
+ * 4. Size token: the `size` option clamped to the Surface ceiling (LC-78);
79
+ * `painted` from the option, else the Surface
80
+ * 5. OS reduced-motion forces animation="none"
81
+ * 6. Call resolveKnobs(mergedKnobs, override, scheme, { touch, sizeToken, painted })
82
+ * — override merges last
127
83
  */
128
84
  export function useResolvedKnobs(options?: UseResolvedKnobsOptions): ResolvedKnobs {
129
85
  const touch = useTouchSurface();
@@ -134,13 +90,12 @@ export function useResolvedKnobs(options?: UseResolvedKnobsOptions): ResolvedKno
134
90
  const scheme = themeName?.startsWith("dark") ? "dark" : "light";
135
91
  const surfaceCtx = SurfaceContext.useStyledContext();
136
92
  const surfaceSize = surfaceCtx?.size ?? "unset";
137
- const surfaceDensity = surfaceCtx?.density ?? "unset";
93
+ const painted = options?.painted ?? surfaceCtx?.painted ?? false;
138
94
 
139
95
  const intent = options?.intent ?? contextIntent ?? undefined;
140
96
  const component = options?.component;
141
97
  const override = options?.override;
142
98
  const sizeOverride = options?.size;
143
- const compact = options?.compact;
144
99
 
145
100
  return useMemo(() => {
146
101
  const baseKnobs: Knobs = presetCtx
@@ -171,37 +126,16 @@ export function useResolvedKnobs(options?: UseResolvedKnobsOptions): ResolvedKno
171
126
  }
172
127
  }
173
128
 
174
- if (sizeOverride) {
175
- const sizeStr = String(sizeOverride);
176
- const knobSize = sizeTokenToKnobSize[sizeStr];
177
- if (knobSize) {
178
- merged = { ...merged, size: knobSize };
179
- }
180
- }
181
-
182
- const surfaceIntent: SurfaceIntent = { size: surfaceSize, density: surfaceDensity };
183
- merged = applySurfaceToKnobs(merged, surfaceIntent, {
184
- sizeOverride: Boolean(sizeOverride),
185
- densityOverride: compact !== undefined,
186
- });
187
-
188
- const spaceBeforeDensity = merged.space;
189
- merged = applyDensity(merged, compact);
190
- merged = applySurfaceToKnobs(merged, surfaceIntent, {
191
- sizeOverride: true,
192
- densityOverride: true,
193
- });
194
- if (merged.density === "compact") {
195
- merged = { ...merged, space: compactSpaceMap[spaceBeforeDensity] };
196
- } else {
197
- merged = { ...merged, space: spaceBeforeDensity };
198
- }
199
-
200
129
  if (prefersReducedMotion) {
201
130
  merged = { ...merged, animation: "none" };
202
131
  }
203
132
 
204
- const resolved = resolveKnobs(merged, override, scheme, { touch });
133
+ const sizeToken = clampSurfaceSize(sizeOverride ?? "unset", surfaceSize);
134
+ const resolved = resolveKnobs(merged, override, scheme, {
135
+ touch,
136
+ sizeToken: sizeToken === "unset" ? undefined : String(sizeToken),
137
+ painted,
138
+ });
205
139
 
206
140
  if (intent && component === "Button" && solidButtonIntents.has(intent)) {
207
141
  const labelColor = merged.fillStyle === "filled" ? "$color" : "$color11";
@@ -221,10 +155,9 @@ export function useResolvedKnobs(options?: UseResolvedKnobsOptions): ResolvedKno
221
155
  component,
222
156
  override,
223
157
  sizeOverride,
224
- compact,
225
158
  prefersReducedMotion,
226
159
  surfaceSize,
227
- surfaceDensity,
160
+ painted,
228
161
  scheme,
229
162
  touch,
230
163
  ]);
@@ -1,8 +1,8 @@
1
1
  import { TestProviders } from "@multiplatform.one/test-utils";
2
2
  /**
3
3
  * useResolvedKnobs behavior specs — the resolution rules consumers feel but
4
- * that aren't covered by the pure resolveKnobs specs: Tamagui size-token →
5
- * knob-size mapping, OS reduced-motion forcing animation off, the legacy
4
+ * that aren't covered by the pure resolveKnobs specs: the Tamagui size token
5
+ * passing through as the control token, OS reduced-motion forcing animation off, the legacy
6
6
  * addListener matchMedia branch, and the semantic-intent Button label color
7
7
  * rule (filled binds $color, outlined pins $color11).
8
8
  */
@@ -79,22 +79,23 @@ function makePreset(overrides: Partial<PresetType> = {}): PresetType {
79
79
  };
80
80
  }
81
81
 
82
- describe("size token mapping", () => {
83
- it.each([
84
- ["$1", "small"],
85
- ["$3", "small"],
86
- ["$4", "medium"],
87
- ["$5", "large"],
88
- ["$6", "large"],
89
- ["$true", "medium"],
90
- ] as const)("maps Tamagui size %s to knob size %s", (token, expected) => {
91
- const { result } = renderHook(() => useResolvedKnobs({ size: token as never }));
92
- expect(result.current.knobProps.size).toBe(expected);
82
+ describe("size token", () => {
83
+ it.each(["$1", "$2", "$3", "$4", "$5", "$6", "$true"] as const)(
84
+ "the Tamagui size %s is the control token, unmapped",
85
+ (token) => {
86
+ const { result } = renderHook(() => useResolvedKnobs({ size: token }));
87
+ expect(result.current.knobProps.sizeToken).toBe(token);
88
+ },
89
+ );
90
+
91
+ it("defaults to $true with no size option and no Surface", () => {
92
+ const { result } = renderHook(() => useResolvedKnobs());
93
+ expect(result.current.knobProps.sizeToken).toBe("$true");
93
94
  });
94
95
 
95
- it("keeps the knob size for unmapped tokens", () => {
96
- const { result } = renderHook(() => useResolvedKnobs({ size: "$11" as never }));
97
- expect(result.current.knobProps.size).toBe(defaultKnobs.size);
96
+ it("a numeric size is not a token and resolves $true", () => {
97
+ const { result } = renderHook(() => useResolvedKnobs({ size: 40 as never }));
98
+ expect(result.current.knobProps.sizeToken).toBe("$true");
98
99
  });
99
100
  });
100
101
 
@@ -176,19 +177,13 @@ describe("intent + component knob merging", () => {
176
177
  );
177
178
  });
178
179
 
179
- it("compact option does not shrink size; it shrinks gap and sets density compact", () => {
180
- const comfortable = renderHook(() => useResolvedKnobs());
181
- const compact = renderHook(() => useResolvedKnobs({ compact: true }));
182
- expect(comfortable.result.current.knobProps.size).toBe("medium");
183
- expect(compact.result.current.knobProps.size).toBe("medium");
184
- expect(compact.result.current.knobProps.sizeToken).toBe(
185
- comfortable.result.current.knobProps.sizeToken,
186
- );
187
- expect(compact.result.current.knobProps.control.height).toBe(
188
- comfortable.result.current.knobProps.control.height,
189
- );
190
- expect(compact.result.current.knobProps.density).toBe("compact");
191
- expect(comfortable.result.current.knobProps.gap).toEqual({ gap: "$4" });
192
- expect(compact.result.current.knobProps.gap).toEqual({ gap: "$2" });
180
+ it("the options carry no compact switch: a smaller size token is the only per-site control", () => {
181
+ const options: Parameters<typeof useResolvedKnobs>[0] = {
182
+ // @ts-expect-error density is folded into the preset's token scale
183
+ compact: true,
184
+ };
185
+ const { result } = renderHook(() => useResolvedKnobs(options));
186
+ expect(result.current.knobProps.gap).toEqual({ gap: "$3" });
187
+ expect(result.current.knobProps).not.toHaveProperty("density");
193
188
  });
194
189
  });
@@ -0,0 +1,33 @@
1
+ import { useEffect, useSyncExternalStore } from "react";
2
+ import { Appearance, useColorScheme } from "react-native";
3
+ import { useDidFinishSSR } from "tamagui";
4
+ import { isWeb } from "@multiplatform.one/platform";
5
+ import { getStoredScheme, setStoredScheme, subscribeStoredScheme } from "./schemeStore";
6
+ import type { ThemeScheme } from "./useTheme";
7
+
8
+ export interface SchemePreference {
9
+ setting: ThemeScheme;
10
+ value: "light" | "dark";
11
+ set(scheme: ThemeScheme): void;
12
+ }
13
+ const serverScheme = (): ThemeScheme => "system";
14
+
15
+ export function useSchemePreference(): SchemePreference {
16
+ const setting = useSyncExternalStore(subscribeStoredScheme, getStoredScheme, serverScheme);
17
+ const os = useColorScheme();
18
+ const hydrated = useDidFinishSSR();
19
+ useEffect(() => {
20
+ if (!isWeb) Appearance.setColorScheme(setting === "system" ? "unspecified" : setting);
21
+ }, [setting]);
22
+ return {
23
+ setting: hydrated ? setting : "system",
24
+ value: !hydrated
25
+ ? "light"
26
+ : setting === "system"
27
+ ? os === "dark"
28
+ ? "dark"
29
+ : "light"
30
+ : setting,
31
+ set: setStoredScheme,
32
+ };
33
+ }
@@ -0,0 +1,51 @@
1
+ import { act, cleanup, renderHook } from "@testing-library/react";
2
+ import { afterEach, expect, it, vi } from "vitest";
3
+ import { useSyncExternalStore } from "react";
4
+
5
+ const os = vi.hoisted(() => ({
6
+ value: "light",
7
+ forced: null as string | null,
8
+ listeners: new Set<() => void>(),
9
+ }));
10
+ vi.mock("@multiplatform.one/platform", () => ({ isWeb: false }));
11
+ vi.mock("@multiplatform.one/store", () => ({
12
+ storage: { getItem: () => null, setItem: () => {} },
13
+ }));
14
+ vi.mock("tamagui", () => ({ useDidFinishSSR: () => true }));
15
+ vi.mock("react-native", () => ({
16
+ useColorScheme: () =>
17
+ useSyncExternalStore(
18
+ (l) => {
19
+ os.listeners.add(l);
20
+ return () => {
21
+ os.listeners.delete(l);
22
+ };
23
+ },
24
+ () => os.forced ?? os.value,
25
+ ),
26
+ Appearance: {
27
+ setColorScheme: (value: string | null) => {
28
+ os.forced = value === "unspecified" ? null : value;
29
+ os.listeners.forEach((l) => l());
30
+ },
31
+ },
32
+ }));
33
+ import { useSchemePreference } from "./useSchemePreference.native";
34
+ afterEach(cleanup);
35
+
36
+ it("shares selection, clears the native override for System and follows subsequent OS changes", () => {
37
+ const first = renderHook(useSchemePreference);
38
+ const second = renderHook(useSchemePreference);
39
+ act(() => first.result.current.set("dark"));
40
+ expect(second.result.current.value).toBe("dark");
41
+ expect(os.forced).toBe("dark");
42
+ act(() => first.result.current.set("system"));
43
+ expect(os.forced).toBeNull();
44
+ expect(second.result.current.value).toBe("light");
45
+ act(() => {
46
+ os.value = "dark";
47
+ os.listeners.forEach((l) => l());
48
+ });
49
+ expect(second.result.current.value).toBe("dark");
50
+ expect(second.result.current.setting).toBe("system");
51
+ });
@@ -0,0 +1,32 @@
1
+ import { useSyncExternalStore } from "react";
2
+ import { useDidFinishSSR } from "tamagui";
3
+ import { getStoredScheme, setStoredScheme, subscribeStoredScheme } from "./schemeStore";
4
+ import type { ThemeScheme } from "./useTheme";
5
+
6
+ export interface SchemePreference {
7
+ setting: ThemeScheme;
8
+ value: "light" | "dark";
9
+ set(scheme: ThemeScheme): void;
10
+ }
11
+ const serverScheme = (): ThemeScheme => "system";
12
+ const serverDark = () => false;
13
+ const prefersDark = () =>
14
+ typeof window !== "undefined" &&
15
+ window.matchMedia?.("(prefers-color-scheme: dark)").matches === true;
16
+ function subscribeOs(listener: () => void) {
17
+ const query = window.matchMedia?.("(prefers-color-scheme: dark)");
18
+ if (!query) return () => {};
19
+ query.addEventListener("change", listener);
20
+ return () => query.removeEventListener("change", listener);
21
+ }
22
+
23
+ export function useSchemePreference(): SchemePreference {
24
+ const setting = useSyncExternalStore(subscribeStoredScheme, getStoredScheme, serverScheme);
25
+ const dark = useSyncExternalStore(subscribeOs, prefersDark, serverDark);
26
+ const hydrated = useDidFinishSSR();
27
+ return {
28
+ setting: hydrated ? setting : "system",
29
+ value: !hydrated ? "light" : setting === "system" ? (dark ? "dark" : "light") : setting,
30
+ set: setStoredScheme,
31
+ };
32
+ }
@@ -0,0 +1,32 @@
1
+ import { act, cleanup, renderHook } from "@testing-library/react";
2
+ import { afterEach, expect, it, vi } from "vitest";
3
+ import { useSchemePreference } from "./useSchemePreference";
4
+ import { setStoredScheme } from "./schemeStore";
5
+
6
+ afterEach(() => {
7
+ cleanup();
8
+ vi.unstubAllGlobals();
9
+ });
10
+ it("follows browser OS changes only while System is selected", () => {
11
+ let dark = false;
12
+ const listeners = new Set<() => void>();
13
+ vi.stubGlobal("matchMedia", () => ({
14
+ get matches() {
15
+ return dark;
16
+ },
17
+ addEventListener: (_event: string, listener: () => void) => listeners.add(listener),
18
+ removeEventListener: (_event: string, listener: () => void) => listeners.delete(listener),
19
+ }));
20
+ setStoredScheme("system");
21
+ const hook = renderHook(useSchemePreference);
22
+ expect(hook.result.current.value).toBe("light");
23
+ act(() => {
24
+ dark = true;
25
+ listeners.forEach((l) => l());
26
+ });
27
+ expect(hook.result.current.value).toBe("dark");
28
+ act(() => hook.result.current.set("light"));
29
+ expect(hook.result.current.value).toBe("light");
30
+ act(() => hook.result.current.set("system"));
31
+ expect(hook.result.current.value).toBe("dark");
32
+ });
@@ -0,0 +1,68 @@
1
+ import { act, cleanup, renderHook } from "@testing-library/react";
2
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
+
4
+ const { items } = vi.hoisted(() => ({ items: new Map<string, string>() }));
5
+ vi.mock("@multiplatform.one/store", () => ({
6
+ storage: {
7
+ getItem: (key: string) => items.get(key) ?? null,
8
+ setItem: (key: string, value: string) => {
9
+ items.set(key, value);
10
+ },
11
+ removeItem: (key: string) => {
12
+ items.delete(key);
13
+ },
14
+ },
15
+ }));
16
+
17
+ vi.mock("./shared", async () => {
18
+ const { densePreset, roomyPreset } = await import("./presets");
19
+ return {
20
+ getPreset: (name: string) =>
21
+ name === "dense" ? densePreset : name === "roomy" ? roomyPreset : undefined,
22
+ };
23
+ });
24
+
25
+ beforeEach(() => {
26
+ items.clear();
27
+ vi.resetModules();
28
+ });
29
+ afterEach(cleanup);
30
+
31
+ async function nativeHooks() {
32
+ const hooks = await import("./useTheme.native");
33
+ const store = await import("./presetStore");
34
+ return { ...hooks, ...store };
35
+ }
36
+
37
+ describe("native useTheme persistence", () => {
38
+ it("persists the active preset and hydrates it after an in-memory reset", async () => {
39
+ const first = await nativeHooks();
40
+ const { result, unmount } = renderHook(() => first.useTheme());
41
+ act(() => result.current[3]("dense"));
42
+ await vi.waitFor(() => expect(items.get("mp.preset")).toBe("dense"));
43
+ expect(result.current[4]).toBe("dense");
44
+ expect(items.has("mp.preset.by-user")).toBe(false);
45
+ unmount();
46
+ vi.resetModules();
47
+ const fresh = await nativeHooks();
48
+ await fresh.hydrateStoredPreset();
49
+ expect(fresh.getStoredPreset()).toEqual({ presetName: "dense", overrides: {}, hydrated: true });
50
+ expect(renderHook(() => fresh.useTheme()).result.current[4]).toBe("dense");
51
+ });
52
+
53
+ it("records the user's choice only when options are supplied", async () => {
54
+ const hooks = await nativeHooks();
55
+ const { result } = renderHook(() => hooks.useTheme());
56
+ act(() => result.current[3]("roomy", { userId: "u1" }));
57
+ await vi.waitFor(() => expect(items.get("mp.preset")).toBe("roomy"));
58
+ expect(hooks.getPresetChoices()).toEqual({ users: { u1: "roomy" }, owner: "u1" });
59
+ await vi.waitFor(() => expect(items.has("mp.preset.by-user")).toBe(true));
60
+ expect(JSON.parse(items.get("mp.preset.by-user")!)).toEqual(hooks.getPresetChoices());
61
+ act(() => result.current[3]("dense", {}));
62
+ expect(hooks.getPresetChoices()).toEqual({
63
+ device: "dense",
64
+ users: { u1: "roomy" },
65
+ owner: undefined,
66
+ });
67
+ });
68
+ });
@@ -1,5 +1,13 @@
1
- import { useCallback, useState } from "react";
1
+ import { useCallback, useMemo, useSyncExternalStore } from "react";
2
+ import { computeOverrides } from "./cookies";
2
3
  import { type Knobs, defaultKnobs } from "./knobs";
4
+ import {
5
+ getStoredPreset,
6
+ recordPresetChoice,
7
+ setStoredOverrides,
8
+ setStoredPreset,
9
+ subscribeStoredPreset,
10
+ } from "./presetStore";
3
11
  import { getPreset } from "./shared";
4
12
 
5
13
  // ---------------------------------------------------------------------------
@@ -9,41 +17,58 @@ import { getPreset } from "./shared";
9
17
  export type ThemeScheme = "system" | "dark" | "light";
10
18
 
11
19
  // ---------------------------------------------------------------------------
12
- // useTheme hook — knob-aware (native variant uses local state only, no cookies)
20
+ // useTheme hook — knob-aware (native variant persists through the preset store)
13
21
  // ---------------------------------------------------------------------------
14
22
 
23
+ /**
24
+ * Same tuple as the web hook. State lives in the shared preset store
25
+ * (`presetStore.ts`), persisted to `@multiplatform.one/store` storage under
26
+ * `mp.preset` / `mp.ov`, so every caller and the ThemeProvider see one preset
27
+ * and it survives a relaunch. The fourth element switches presets; supplying
28
+ * options also records the user's (or signed-out device's) choice.
29
+ */
15
30
  export function useTheme(): [
16
31
  Knobs,
17
32
  (knobs?: Partial<Knobs>) => void,
18
33
  boolean,
19
- (presetName: string) => void,
34
+ (presetName: string, options?: { userId?: string | null }) => void,
20
35
  string | undefined,
21
36
  ] {
22
- const [localKnobs, setLocalKnobs] = useState<Knobs>(() => ({ ...defaultKnobs }));
23
- const [activePreset, setActivePreset] = useState<string | undefined>(undefined);
24
-
25
- const setKnobs = useCallback((partial?: Partial<Knobs>): void => {
26
- if (!partial) return;
27
- setLocalKnobs((prev) => {
28
- let hasChanges = false;
29
- const updated = { ...prev };
37
+ const stored = useSyncExternalStore(subscribeStoredPreset, getStoredPreset, getStoredPreset);
38
+ const presetName = stored.presetName;
39
+ const baseKnobs = (presetName ? getPreset(presetName)?.knobs : undefined) ?? defaultKnobs;
40
+
41
+ const knobs = useMemo<Knobs>(
42
+ () => ({ ...baseKnobs, ...stored.overrides }),
43
+ [baseKnobs, stored.overrides],
44
+ );
45
+
46
+ const setKnobs = useCallback(
47
+ (partial?: Partial<Knobs>): void => {
48
+ if (!partial) return;
49
+ let changed = false;
50
+ const next = { ...knobs };
30
51
  for (const key of Object.keys(partial) as Array<keyof Knobs>) {
31
- const newValue = partial[key];
32
- if (newValue !== undefined && newValue !== prev[key]) {
33
- (updated as Record<string, unknown>)[key] = newValue;
34
- hasChanges = true;
52
+ const value = partial[key];
53
+ if (value === undefined) continue;
54
+ const differs =
55
+ typeof value === "object" && value !== null
56
+ ? JSON.stringify(value) !== JSON.stringify(knobs[key])
57
+ : value !== knobs[key];
58
+ if (differs) {
59
+ (next as Record<string, unknown>)[key] = value;
60
+ changed = true;
35
61
  }
36
62
  }
37
- return hasChanges ? updated : prev;
38
- });
39
- }, []);
63
+ if (changed) setStoredOverrides(computeOverrides(baseKnobs, next));
64
+ },
65
+ [knobs, baseKnobs],
66
+ );
40
67
 
41
- const setPresetFn = useCallback((newPresetName: string) => {
42
- const preset = getPreset(newPresetName);
43
- const knobs = preset?.knobs ?? defaultKnobs;
44
- setActivePreset(newPresetName);
45
- setLocalKnobs(knobs);
68
+ const setPresetFn = useCallback((newPresetName: string, options?: { userId?: string | null }) => {
69
+ if (options) recordPresetChoice(newPresetName, options.userId);
70
+ setStoredPreset(newPresetName);
46
71
  }, []);
47
72
 
48
- return [localKnobs, setKnobs, false, setPresetFn, activePreset];
73
+ return [knobs, setKnobs, presetName != null, setPresetFn, presetName];
49
74
  }
@@ -5,11 +5,13 @@ import {
5
5
  cookiePreset,
6
6
  computeOverrides,
7
7
  getCookieWatchList,
8
+ isKnobKey,
8
9
  readOverridesCookie,
9
10
  readPresetCookie,
10
11
  writeOverridesCookie,
11
12
  } from "./cookies";
12
13
  import { type Knobs, defaultKnobs } from "./knobs";
14
+ import { recordPresetChoice } from "./presetStore";
13
15
  import { getPreset } from "./shared";
14
16
 
15
17
  // ---------------------------------------------------------------------------
@@ -34,7 +36,7 @@ export type ThemeScheme = "system" | "dark" | "light";
34
36
  * Knobs, // resolved knobs
35
37
  * (knobs?: Partial<Knobs>) => void, // merge partial knob updates
36
38
  * boolean, // true if initialized from cookie
37
- * (presetName: string) => void, // switch preset (resets overrides)
39
+ * (presetName: string, options?: { userId?: string | null }) => void, // switch preset; options record a choice
38
40
  * string | undefined, // active preset name
39
41
  * ]
40
42
  * ```
@@ -47,7 +49,7 @@ export function useTheme(): [
47
49
  Knobs,
48
50
  (knobs?: Partial<Knobs>) => void,
49
51
  boolean,
50
- (presetName: string) => void,
52
+ (presetName: string, options?: { userId?: string | null }) => void,
51
53
  string | undefined,
52
54
  ] {
53
55
  const isCookieDisabled =
@@ -132,7 +134,7 @@ export function useTheme(): [
132
134
  let hasChanges = false;
133
135
  const updated = { ...current };
134
136
 
135
- for (const key of Object.keys(partial) as Array<keyof Knobs>) {
137
+ for (const key of Object.keys(partial).filter(isKnobKey)) {
136
138
  const newValue = partial[key];
137
139
  if (newValue === undefined) continue;
138
140
  const oldValue = current[key];
@@ -177,7 +179,8 @@ export function useTheme(): [
177
179
  // setPreset — switch the active preset (resets overrides to empty)
178
180
  // -------------------------------------------------------------------------
179
181
  const setPresetFn = useCallback(
180
- (newPresetName: string) => {
182
+ (newPresetName: string, options?: { userId?: string | null }) => {
183
+ if (options) recordPresetChoice(newPresetName, options.userId);
181
184
  const preset = getPreset(newPresetName);
182
185
  const knobs = preset?.knobs ?? defaultKnobs;
183
186
 
@@ -5,7 +5,8 @@
5
5
  * Tamagui token steps defined by the knob system. Off-scale values indicate
6
6
  * styles that bypassed the constraint system.
7
7
  *
8
- * Token values are from @tamagui/themes v5 + resolveKnobs.ts mappings.
8
+ * Token values are the active generated scale (`globalThis.__MPO_SCALE__`,
9
+ * else the default `generateScale`) + resolveKnobs.ts mappings.
9
10
  * Run this in-browser via Playwright's page.evaluate(runConstraintAudit).
10
11
  */
11
12
  export interface PropertyAudit {
@@ -76,13 +77,13 @@ export interface AuditReport {
76
77
  elements: ElementAudit[];
77
78
  }
78
79
  /**
79
- * Gap (inner spacing) knob → pixel value
80
- * Source: gapMap in resolveKnobs.ts ($2, $4, $5 space tokens)
80
+ * Within-group gap roles → pixel value on the scale.
81
+ * Source: spacingRoles in resolveKnobs.ts (gapSm $2, gap $3).
81
82
  */
82
83
  export declare const GAP_KNOB: Record<string, number>;
83
84
  /**
84
- * Gap large (gapLg) knob → pixel value
85
- * Source: gapLgMap in resolveKnobs.ts ($3, $5, $6 space tokens)
85
+ * Between-groups gap role → pixel value on the scale.
86
+ * Source: spacingRoles in resolveKnobs.ts (gapLg $5).
86
87
  */
87
88
  export declare const GAP_LG_KNOB: Record<string, number>;
88
89
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"constraintAudit.d.ts","sourceRoot":"","sources":["../../src/audit/constraintAudit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,qFAAqF;IACrF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,eAAe;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,8BAA8B;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,6CAA6C;IAC7C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,mBAAmB,CAAC,EAAE,aAAa,CAAC;IACpC,oBAAoB,CAAC,EAAE,aAAa,CAAC;IACrC,uBAAuB,CAAC,EAAE,aAAa,CAAC;IACxC,sBAAsB,CAAC,EAAE,aAAa,CAAC;IACvC,WAAW,CAAC,EAAE,aAAa,CAAC;IAC5B,GAAG,CAAC,EAAE,aAAa,CAAC;IACpB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,aAAa,CAAC;IAC5B,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,uCAAuC;IACvC,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE;QACV,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,CAAC;IACtB,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,sDAAsD;IACtD,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AA6ED;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAI3C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAI9C,CAAC;AAmJF;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,WAAW,CAguBrE"}
1
+ {"version":3,"file":"constraintAudit.d.ts","sourceRoot":"","sources":["../../src/audit/constraintAudit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,qFAAqF;IACrF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,eAAe;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,8BAA8B;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,6CAA6C;IAC7C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,mBAAmB,CAAC,EAAE,aAAa,CAAC;IACpC,oBAAoB,CAAC,EAAE,aAAa,CAAC;IACrC,uBAAuB,CAAC,EAAE,aAAa,CAAC;IACxC,sBAAsB,CAAC,EAAE,aAAa,CAAC;IACvC,WAAW,CAAC,EAAE,aAAa,CAAC;IAC5B,GAAG,CAAC,EAAE,aAAa,CAAC;IACpB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,aAAa,CAAC;IAC5B,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,uCAAuC;IACvC,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE;QACV,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,CAAC;IACtB,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,sDAAsD;IACtD,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AA+DD;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAG3C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAE9C,CAAC;AAmJF;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,WAAW,CA4vBrE"}