@tenphi/tasty 0.0.0-snapshot.26b4630 → 0.0.0-snapshot.2705ab9

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 (218) hide show
  1. package/README.md +315 -159
  2. package/dist/chunks/cacheKey.js +16 -8
  3. package/dist/chunks/cacheKey.js.map +1 -1
  4. package/dist/chunks/definitions.d.ts +1 -1
  5. package/dist/chunks/definitions.js +2 -3
  6. package/dist/chunks/definitions.js.map +1 -1
  7. package/dist/chunks/renderChunk.js +31 -32
  8. package/dist/chunks/renderChunk.js.map +1 -1
  9. package/dist/config.d.ts +98 -12
  10. package/dist/config.js +134 -33
  11. package/dist/config.js.map +1 -1
  12. package/dist/core/index.d.ts +11 -10
  13. package/dist/core/index.js +8 -7
  14. package/dist/counter-style/index.js +51 -0
  15. package/dist/counter-style/index.js.map +1 -0
  16. package/dist/debug.d.ts +26 -141
  17. package/dist/debug.js +356 -635
  18. package/dist/debug.js.map +1 -1
  19. package/dist/font-face/index.js +63 -0
  20. package/dist/font-face/index.js.map +1 -0
  21. package/dist/hooks/resolve-ssr-collector.js +15 -0
  22. package/dist/hooks/resolve-ssr-collector.js.map +1 -0
  23. package/dist/hooks/useCounterStyle.d.ts +50 -0
  24. package/dist/hooks/useCounterStyle.js +47 -0
  25. package/dist/hooks/useCounterStyle.js.map +1 -0
  26. package/dist/hooks/useFontFace.d.ts +43 -0
  27. package/dist/hooks/useFontFace.js +71 -0
  28. package/dist/hooks/useFontFace.js.map +1 -0
  29. package/dist/hooks/useGlobalStyles.d.ts +3 -0
  30. package/dist/hooks/useGlobalStyles.js +24 -1
  31. package/dist/hooks/useGlobalStyles.js.map +1 -1
  32. package/dist/hooks/useKeyframes.js +14 -3
  33. package/dist/hooks/useKeyframes.js.map +1 -1
  34. package/dist/hooks/useProperty.js +32 -13
  35. package/dist/hooks/useProperty.js.map +1 -1
  36. package/dist/hooks/useRawCSS.js +9 -1
  37. package/dist/hooks/useRawCSS.js.map +1 -1
  38. package/dist/hooks/useStyles.d.ts +5 -0
  39. package/dist/hooks/useStyles.js +115 -46
  40. package/dist/hooks/useStyles.js.map +1 -1
  41. package/dist/index.d.ts +22 -11
  42. package/dist/index.js +10 -7
  43. package/dist/injector/index.d.ts +28 -2
  44. package/dist/injector/index.js +27 -1
  45. package/dist/injector/index.js.map +1 -1
  46. package/dist/injector/injector.d.ts +28 -1
  47. package/dist/injector/injector.js +93 -32
  48. package/dist/injector/injector.js.map +1 -1
  49. package/dist/injector/sheet-manager.d.ts +16 -7
  50. package/dist/injector/sheet-manager.js +31 -11
  51. package/dist/injector/sheet-manager.js.map +1 -1
  52. package/dist/injector/types.d.ts +70 -1
  53. package/dist/parser/classify.js +5 -4
  54. package/dist/parser/classify.js.map +1 -1
  55. package/dist/parser/const.js +17 -1
  56. package/dist/parser/const.js.map +1 -1
  57. package/dist/parser/parser.js +1 -1
  58. package/dist/pipeline/conditions.js +14 -8
  59. package/dist/pipeline/conditions.js.map +1 -1
  60. package/dist/pipeline/index.d.ts +3 -1
  61. package/dist/pipeline/index.js +137 -69
  62. package/dist/pipeline/index.js.map +1 -1
  63. package/dist/pipeline/materialize.js +404 -208
  64. package/dist/pipeline/materialize.js.map +1 -1
  65. package/dist/pipeline/parseStateKey.d.ts +1 -1
  66. package/dist/pipeline/parseStateKey.js +37 -20
  67. package/dist/pipeline/parseStateKey.js.map +1 -1
  68. package/dist/pipeline/simplify.js +111 -152
  69. package/dist/pipeline/simplify.js.map +1 -1
  70. package/dist/pipeline/warnings.js +18 -0
  71. package/dist/pipeline/warnings.js.map +1 -0
  72. package/dist/plugins/okhsl-plugin.js +2 -275
  73. package/dist/plugins/okhsl-plugin.js.map +1 -1
  74. package/dist/plugins/types.d.ts +9 -2
  75. package/dist/properties/index.js +82 -17
  76. package/dist/properties/index.js.map +1 -1
  77. package/dist/properties/property-type-resolver.d.ts +24 -0
  78. package/dist/properties/property-type-resolver.js +91 -0
  79. package/dist/properties/property-type-resolver.js.map +1 -0
  80. package/dist/ssr/astro.d.ts +29 -0
  81. package/dist/ssr/astro.js +65 -0
  82. package/dist/ssr/astro.js.map +1 -0
  83. package/dist/ssr/async-storage.d.ts +17 -0
  84. package/dist/ssr/async-storage.js +35 -0
  85. package/dist/ssr/async-storage.js.map +1 -0
  86. package/dist/ssr/collect-auto-properties.js +40 -0
  87. package/dist/ssr/collect-auto-properties.js.map +1 -0
  88. package/dist/ssr/collector.d.ts +102 -0
  89. package/dist/ssr/collector.js +227 -0
  90. package/dist/ssr/collector.js.map +1 -0
  91. package/dist/ssr/context.d.ts +8 -0
  92. package/dist/ssr/context.js +14 -0
  93. package/dist/ssr/context.js.map +1 -0
  94. package/dist/ssr/format-global-rules.js +22 -0
  95. package/dist/ssr/format-global-rules.js.map +1 -0
  96. package/dist/ssr/format-keyframes.js +70 -0
  97. package/dist/ssr/format-keyframes.js.map +1 -0
  98. package/dist/ssr/format-property.js +50 -0
  99. package/dist/ssr/format-property.js.map +1 -0
  100. package/dist/ssr/format-rules.js +73 -0
  101. package/dist/ssr/format-rules.js.map +1 -0
  102. package/dist/ssr/hydrate.d.ts +22 -0
  103. package/dist/ssr/hydrate.js +50 -0
  104. package/dist/ssr/hydrate.js.map +1 -0
  105. package/dist/ssr/index.d.ts +5 -0
  106. package/dist/ssr/index.js +12 -0
  107. package/dist/ssr/index.js.map +1 -0
  108. package/dist/ssr/next.d.ts +45 -0
  109. package/dist/ssr/next.js +71 -0
  110. package/dist/ssr/next.js.map +1 -0
  111. package/dist/ssr/ssr-collector-ref.js +12 -0
  112. package/dist/ssr/ssr-collector-ref.js.map +1 -0
  113. package/dist/states/index.js +12 -257
  114. package/dist/states/index.js.map +1 -1
  115. package/dist/styles/align.d.ts +1 -1
  116. package/dist/styles/align.js.map +1 -1
  117. package/dist/styles/border.d.ts +1 -1
  118. package/dist/styles/border.js +2 -2
  119. package/dist/styles/border.js.map +1 -1
  120. package/dist/styles/color.d.ts +2 -2
  121. package/dist/styles/color.js +9 -5
  122. package/dist/styles/color.js.map +1 -1
  123. package/dist/styles/createStyle.js +25 -22
  124. package/dist/styles/createStyle.js.map +1 -1
  125. package/dist/styles/fade.d.ts +1 -1
  126. package/dist/styles/fade.js.map +1 -1
  127. package/dist/styles/fill.d.ts +14 -16
  128. package/dist/styles/fill.js +6 -5
  129. package/dist/styles/fill.js.map +1 -1
  130. package/dist/styles/flow.d.ts +3 -3
  131. package/dist/styles/flow.js.map +1 -1
  132. package/dist/styles/index.js +1 -1
  133. package/dist/styles/justify.d.ts +1 -1
  134. package/dist/styles/justify.js.map +1 -1
  135. package/dist/styles/predefined.d.ts +0 -2
  136. package/dist/styles/predefined.js +1 -4
  137. package/dist/styles/predefined.js.map +1 -1
  138. package/dist/styles/preset.d.ts +5 -0
  139. package/dist/styles/preset.js +48 -47
  140. package/dist/styles/preset.js.map +1 -1
  141. package/dist/styles/radius.d.ts +1 -1
  142. package/dist/styles/radius.js.map +1 -1
  143. package/dist/styles/scrollbar.d.ts +9 -5
  144. package/dist/styles/scrollbar.js +25 -82
  145. package/dist/styles/scrollbar.js.map +1 -1
  146. package/dist/styles/shadow.d.ts +2 -2
  147. package/dist/styles/shadow.js.map +1 -1
  148. package/dist/styles/transition.d.ts +1 -1
  149. package/dist/styles/transition.js +1 -1
  150. package/dist/styles/transition.js.map +1 -1
  151. package/dist/styles/types.d.ts +70 -21
  152. package/dist/tasty.d.ts +30 -893
  153. package/dist/tasty.js +60 -19
  154. package/dist/tasty.js.map +1 -1
  155. package/dist/types.d.ts +3 -3
  156. package/dist/utils/cache-wrapper.js +4 -8
  157. package/dist/utils/cache-wrapper.js.map +1 -1
  158. package/dist/utils/color-math.d.ts +46 -0
  159. package/dist/utils/color-math.js +749 -0
  160. package/dist/utils/color-math.js.map +1 -0
  161. package/dist/utils/color-space.d.ts +5 -0
  162. package/dist/utils/color-space.js +229 -0
  163. package/dist/utils/color-space.js.map +1 -0
  164. package/dist/utils/colors.d.ts +1 -1
  165. package/dist/utils/colors.js +3 -1
  166. package/dist/utils/colors.js.map +1 -1
  167. package/dist/utils/css-types.d.ts +1 -1
  168. package/dist/utils/dotize.d.ts +1 -1
  169. package/dist/utils/has-keys.js +13 -0
  170. package/dist/utils/has-keys.js.map +1 -0
  171. package/dist/utils/mod-attrs.js +2 -2
  172. package/dist/utils/mod-attrs.js.map +1 -1
  173. package/dist/utils/process-tokens.d.ts +3 -13
  174. package/dist/utils/process-tokens.js +18 -98
  175. package/dist/utils/process-tokens.js.map +1 -1
  176. package/dist/utils/selector-transform.js +32 -0
  177. package/dist/utils/selector-transform.js.map +1 -0
  178. package/dist/utils/string.js.map +1 -1
  179. package/dist/utils/styles.d.ts +4 -88
  180. package/dist/utils/styles.js +34 -398
  181. package/dist/utils/styles.js.map +1 -1
  182. package/dist/utils/typography.d.ts +24 -13
  183. package/dist/utils/typography.js +14 -16
  184. package/dist/utils/typography.js.map +1 -1
  185. package/dist/zero/babel.d.ts +67 -8
  186. package/dist/zero/babel.js +109 -17
  187. package/dist/zero/babel.js.map +1 -1
  188. package/dist/zero/extractor.js +118 -1
  189. package/dist/zero/extractor.js.map +1 -1
  190. package/dist/zero/next.d.ts +44 -30
  191. package/dist/zero/next.js +102 -38
  192. package/dist/zero/next.js.map +1 -1
  193. package/docs/PIPELINE.md +519 -0
  194. package/docs/README.md +31 -0
  195. package/docs/adoption.md +296 -0
  196. package/docs/comparison.md +420 -0
  197. package/docs/configuration.md +326 -0
  198. package/docs/debug.md +318 -0
  199. package/docs/design-system.md +424 -0
  200. package/docs/dsl.md +673 -0
  201. package/docs/getting-started.md +217 -0
  202. package/docs/injector.md +528 -0
  203. package/docs/methodology.md +567 -0
  204. package/docs/runtime.md +485 -0
  205. package/docs/ssr.md +384 -0
  206. package/docs/styles.md +579 -0
  207. package/docs/tasty-static.md +433 -0
  208. package/package.json +98 -28
  209. package/dist/styles/styledScrollbar.d.ts +0 -47
  210. package/dist/styles/styledScrollbar.js +0 -38
  211. package/dist/styles/styledScrollbar.js.map +0 -1
  212. package/dist/tokens/typography.d.ts +0 -19
  213. package/dist/tokens/typography.js +0 -237
  214. package/dist/tokens/typography.js.map +0 -1
  215. package/dist/utils/hsl-to-rgb.js +0 -38
  216. package/dist/utils/hsl-to-rgb.js.map +0 -1
  217. package/dist/utils/okhsl-to-rgb.js +0 -296
  218. package/dist/utils/okhsl-to-rgb.js.map +0 -1
@@ -1,7 +1,13 @@
1
- import { makeEmptyDetails } from "../parser/types.js";
2
1
  import { parseStyle } from "../utils/styles.js";
3
2
 
4
3
  //#region src/styles/preset.ts
4
+ const PRESET_MODIFIERS = new Set([
5
+ "strong",
6
+ "bold",
7
+ "italic",
8
+ "icon",
9
+ "tight"
10
+ ]);
5
11
  /**
6
12
  * Convert a value to CSS, handling numbers as pixels for numeric properties
7
13
  */
@@ -10,46 +16,40 @@ function toCSS(value, isNumeric) {
10
16
  if (typeof value === "number") return isNumeric ? `${value}px` : String(value);
11
17
  return parseStyle(String(value)).groups[0]?.values[0] || String(value);
12
18
  }
13
- function setCSSValue(styles, styleName, presetName, isPropOnly = false) {
14
- styles[`--${styleName}`] = (() => {
19
+ function setCSSValue(styles, styleName, presetName, { varOnly, cssOnly } = {}) {
20
+ const value = (() => {
15
21
  if (presetName === "inherit") return "inherit";
16
- const defaultValue = `var(--default-${styleName}, ${styleName === "font-family" ? "var(--font, NonexistentFontName)" : "inherit"})`;
17
- const fontSuffix = styleName === "font-family" ? ", var(--font, sans-serif)" : "";
22
+ const defaultValue = `var(--default-${styleName}${styleName === "font-family" ? ", var(--font-sans, var(--font-sans-fallback))" : ""})`;
23
+ const fontSuffix = styleName === "font-family" ? ", var(--font-sans, var(--font-sans-fallback))" : "";
18
24
  if (presetName === "default") return `${defaultValue}${fontSuffix}`;
19
25
  else return `var(--${presetName}-${styleName}, ${defaultValue})${fontSuffix}`;
20
26
  })();
21
- if (!isPropOnly) styles[styleName] = styles[`--${styleName}`];
27
+ if (!cssOnly) styles[`--${styleName}`] = value;
28
+ if (!varOnly) styles[styleName] = value;
22
29
  }
23
30
  /**
24
31
  * Resolve font/fontFamily value to CSS font-family string.
25
32
  *
26
- * - `font="monospace"` → var(--monospace-font)
27
- * - `font={true}` → var(--font)
28
- * - `font="CustomFont"` → CustomFont, var(--font)
33
+ * - `font="monospace"` → var(--font-mono, var(--font-mono-fallback))
34
+ * - `font={true}` → var(--font-sans, var(--font-sans-fallback))
35
+ * - `font="CustomFont"` → CustomFont, var(--font-sans, var(--font-sans-fallback))
29
36
  * - `fontFamily="Arial"` → Arial (direct, no fallback)
30
37
  */
31
38
  function resolveFontFamily(font, fontFamily) {
32
- if (fontFamily) return {
33
- value: fontFamily,
34
- setVar: false
35
- };
39
+ if (fontFamily) return fontFamily;
36
40
  if (font == null || font === false) return null;
37
- if (font === "monospace") return {
38
- value: "var(--monospace-font)",
39
- setVar: true
40
- };
41
- if (font === true) return {
42
- value: "var(--font)",
43
- setVar: true
44
- };
45
- return {
46
- value: `${font}, var(--font)`,
47
- setVar: true
48
- };
41
+ if (font === "monospace") return "var(--font-mono, var(--font-mono-fallback))";
42
+ if (font === true) return "var(--font-sans, var(--font-sans-fallback))";
43
+ return `${font}, var(--font-sans, var(--font-sans-fallback))`;
49
44
  }
50
45
  /**
51
46
  * Handles typography preset and individual font properties.
52
47
  *
48
+ * Preset syntax uses `/` to separate name from modifier:
49
+ * - `preset="h1"` — name only
50
+ * - `preset="h2 / strong"` — name + modifier
51
+ * - `preset="bold"` — modifier-only shorthand (name defaults to `inherit`)
52
+ *
53
53
  * When `preset` is defined, it sets up CSS custom properties for typography.
54
54
  * Individual font props can be used with or without `preset`:
55
55
  * - With `preset`: overrides the preset value for that property
@@ -65,29 +65,33 @@ function resolveFontFamily(font, fontFamily) {
65
65
  function presetStyle({ preset, fontSize, lineHeight, textTransform, letterSpacing, fontWeight, fontStyle, fontFamily, font }) {
66
66
  const styles = {};
67
67
  if (preset != null && preset !== false) {
68
- let { mods } = parseStyle(preset === true ? "" : String(preset)).groups[0] ?? makeEmptyDetails();
69
- const isStrong = mods.includes("strong");
70
- const isItalic = mods.includes("italic");
71
- const isIcon = mods.includes("icon");
72
- const isTight = mods.includes("tight");
73
- mods = mods.filter((mod) => mod !== "strong" && mod !== "bold" && mod !== "italic" && mod !== "icon" && mod !== "tight");
74
- const name = mods[0] || "inherit";
75
- if (fontSize == null) setCSSValue(styles, "font-size", name);
76
- if (lineHeight == null) setCSSValue(styles, "line-height", name);
77
- if (letterSpacing == null) setCSSValue(styles, "letter-spacing", name);
78
- if (fontWeight == null) setCSSValue(styles, "font-weight", name);
79
- if (fontStyle == null) setCSSValue(styles, "font-style", name);
80
- if (textTransform == null) setCSSValue(styles, "text-transform", name);
81
- if (fontFamily == null && font == null) setCSSValue(styles, "font-family", name);
82
- setCSSValue(styles, "bold-font-weight", name, true);
83
- setCSSValue(styles, "icon-size", name, true);
68
+ const { parts } = parseStyle(preset === true ? "" : String(preset)).groups[0] ?? { parts: [] };
69
+ const namePart = parts[0];
70
+ const modPart = parts[1];
71
+ const nameToken = namePart?.mods[0] ?? "";
72
+ const isModOnly = PRESET_MODIFIERS.has(nameToken);
73
+ const name = isModOnly ? "inherit" : nameToken || "inherit";
74
+ const modifier = isModOnly ? nameToken : modPart?.mods[0] ?? "";
75
+ const isStrong = modifier === "strong" || modifier === "bold";
76
+ const isItalic = modifier === "italic";
77
+ const isIcon = modifier === "icon";
78
+ const isTight = modifier === "tight";
79
+ if (fontSize == null) setCSSValue(styles, "font-size", name, { cssOnly: true });
80
+ if (lineHeight == null) setCSSValue(styles, "line-height", name, { cssOnly: true });
81
+ if (letterSpacing == null) setCSSValue(styles, "letter-spacing", name, { cssOnly: true });
82
+ if (fontWeight == null) setCSSValue(styles, "font-weight", name, { cssOnly: true });
83
+ if (fontStyle == null) setCSSValue(styles, "font-style", name, { cssOnly: true });
84
+ if (textTransform == null) setCSSValue(styles, "text-transform", name, { cssOnly: true });
85
+ if (fontFamily == null && font == null) setCSSValue(styles, "font-family", name, { cssOnly: true });
86
+ setCSSValue(styles, "bold-font-weight", name, { varOnly: true });
87
+ setCSSValue(styles, "icon-size", name, { varOnly: true });
84
88
  if (isStrong) styles["font-weight"] = "var(--bold-font-weight)";
85
89
  if (isItalic) styles["font-style"] = "italic";
86
90
  if (isIcon) {
87
91
  styles["font-size"] = "var(--icon-size)";
88
92
  styles["line-height"] = "var(--icon-size)";
89
93
  }
90
- if (isTight) styles["line-height"] = "var(--font-size)";
94
+ if (isTight) styles["line-height"] = "1em";
91
95
  }
92
96
  const fontSizeVal = toCSS(fontSize, true);
93
97
  if (fontSizeVal) styles["font-size"] = fontSizeVal;
@@ -101,11 +105,8 @@ function presetStyle({ preset, fontSize, lineHeight, textTransform, letterSpacin
101
105
  else if (fontStyle !== "inherit") styles["font-style"] = fontStyle ? "italic" : "normal";
102
106
  else styles["font-style"] = "inherit";
103
107
  if (textTransform) styles["text-transform"] = textTransform;
104
- const fontResult = resolveFontFamily(font, fontFamily);
105
- if (fontResult) {
106
- styles["font-family"] = fontResult.value;
107
- if (fontResult.setVar) styles["--font-family"] = fontResult.value;
108
- }
108
+ const fontFamily_ = resolveFontFamily(font, fontFamily);
109
+ if (fontFamily_) styles["font-family"] = fontFamily_;
109
110
  if (Object.keys(styles).length === 0) return;
110
111
  return styles;
111
112
  }
@@ -1 +1 @@
1
- {"version":3,"file":"preset.js","names":[],"sources":["../../src/styles/preset.ts"],"sourcesContent":["import { makeEmptyDetails } from '../parser/types';\nimport { parseStyle } from '../utils/styles';\n\nimport type { Styles } from './types';\n\n/**\n * Convert a value to CSS, handling numbers as pixels for numeric properties\n */\nfunction toCSS(\n value: string | number | undefined,\n isNumeric: boolean,\n): string | null {\n if (value == null) return null;\n if (typeof value === 'number') {\n return isNumeric ? `${value}px` : String(value);\n }\n // Parse through style parser to handle custom units like 1x, 2r, etc.\n const processed = parseStyle(String(value));\n return processed.groups[0]?.values[0] || String(value);\n}\n\nfunction setCSSValue(\n styles: Styles,\n styleName: string,\n presetName: string,\n isPropOnly = false,\n) {\n styles[`--${styleName}`] = (() => {\n if (presetName === 'inherit') {\n return 'inherit';\n }\n\n const defaultValue = `var(--default-${styleName}, ${\n styleName === 'font-family'\n ? 'var(--font, NonexistentFontName)'\n : 'inherit'\n })`;\n const fontSuffix =\n styleName === 'font-family' ? ', var(--font, sans-serif)' : '';\n\n if (presetName === 'default') {\n return `${defaultValue}${fontSuffix}`;\n } else {\n return `var(--${presetName}-${styleName}, ${defaultValue})${fontSuffix}`;\n }\n })();\n\n if (!isPropOnly) {\n styles[styleName] = styles[`--${styleName}`];\n }\n}\n\ninterface PresetStyleProps {\n preset?: string | boolean;\n fontSize?: string | number;\n lineHeight?: string | number;\n textTransform?: string;\n letterSpacing?: string | number;\n fontWeight?: string | number;\n fontStyle?: string | boolean;\n fontFamily?: string;\n /** Alias for fontFamily with special handling for 'monospace' and boolean */\n font?: string | boolean;\n}\n\n/**\n * Resolve font/fontFamily value to CSS font-family string.\n *\n * - `font=\"monospace\"` → var(--monospace-font)\n * - `font={true}` → var(--font)\n * - `font=\"CustomFont\"` → CustomFont, var(--font)\n * - `fontFamily=\"Arial\"` → Arial (direct, no fallback)\n */\nfunction resolveFontFamily(\n font: string | boolean | undefined,\n fontFamily: string | undefined,\n): { value: string; setVar: boolean } | null {\n // fontFamily takes precedence as a direct value\n if (fontFamily) {\n return { value: fontFamily, setVar: false };\n }\n\n if (font == null || font === false) {\n return null;\n }\n\n if (font === 'monospace') {\n return { value: 'var(--monospace-font)', setVar: true };\n }\n\n if (font === true) {\n return { value: 'var(--font)', setVar: true };\n }\n\n return { value: `${font}, var(--font)`, setVar: true };\n}\n\n/**\n * Handles typography preset and individual font properties.\n *\n * When `preset` is defined, it sets up CSS custom properties for typography.\n * Individual font props can be used with or without `preset`:\n * - With `preset`: overrides the preset value for that property\n * - Without `preset`: outputs the CSS directly\n *\n * Number values are converted to pixels for fontSize, lineHeight, letterSpacing.\n * fontWeight accepts numbers directly (e.g., 400, 700).\n *\n * font vs fontFamily:\n * - `font` is the recommended prop with special handling (monospace, boolean, fallback)\n * - `fontFamily` is a direct value without special handling\n */\nexport function presetStyle({\n preset,\n fontSize,\n lineHeight,\n textTransform,\n letterSpacing,\n fontWeight,\n fontStyle,\n fontFamily,\n font,\n}: PresetStyleProps) {\n const styles: Styles = {};\n const hasPreset = preset != null && preset !== false;\n\n // Handle preset if defined\n if (hasPreset) {\n const presetValue = preset === true ? '' : String(preset);\n\n const processed = parseStyle(presetValue);\n let { mods } = processed.groups[0] ?? makeEmptyDetails();\n\n const isStrong = mods.includes('strong');\n const isItalic = mods.includes('italic');\n const isIcon = mods.includes('icon');\n const isTight = mods.includes('tight');\n\n mods = mods.filter(\n (mod) =>\n mod !== 'strong' &&\n mod !== 'bold' &&\n mod !== 'italic' &&\n mod !== 'icon' &&\n mod !== 'tight',\n );\n\n const name = mods[0] || 'inherit';\n\n // Set preset values for properties not explicitly overridden\n if (fontSize == null) {\n setCSSValue(styles, 'font-size', name);\n }\n if (lineHeight == null) {\n setCSSValue(styles, 'line-height', name);\n }\n if (letterSpacing == null) {\n setCSSValue(styles, 'letter-spacing', name);\n }\n if (fontWeight == null) {\n setCSSValue(styles, 'font-weight', name);\n }\n if (fontStyle == null) {\n setCSSValue(styles, 'font-style', name);\n }\n if (textTransform == null) {\n setCSSValue(styles, 'text-transform', name);\n }\n if (fontFamily == null && font == null) {\n setCSSValue(styles, 'font-family', name);\n }\n\n setCSSValue(styles, 'bold-font-weight', name, true);\n setCSSValue(styles, 'icon-size', name, true);\n\n if (isStrong) {\n styles['font-weight'] = 'var(--bold-font-weight)';\n }\n if (isItalic) {\n styles['font-style'] = 'italic';\n }\n if (isIcon) {\n styles['font-size'] = 'var(--icon-size)';\n styles['line-height'] = 'var(--icon-size)';\n }\n if (isTight) {\n styles['line-height'] = 'var(--font-size)';\n }\n }\n\n // Handle individual font properties (work with or without preset)\n const fontSizeVal = toCSS(fontSize, true);\n if (fontSizeVal) {\n styles['font-size'] = fontSizeVal;\n }\n\n const lineHeightVal = toCSS(lineHeight, true);\n if (lineHeightVal) {\n styles['line-height'] = lineHeightVal;\n }\n\n const letterSpacingVal = toCSS(letterSpacing, true);\n if (letterSpacingVal) {\n styles['letter-spacing'] = letterSpacingVal;\n }\n\n // fontWeight: numbers should NOT get 'px' suffix\n const fontWeightVal = toCSS(fontWeight, false);\n if (fontWeightVal) {\n styles['font-weight'] = fontWeightVal;\n }\n\n // fontStyle: handle boolean (true → italic) and string values\n if (fontStyle != null) {\n if (fontStyle === true) {\n styles['font-style'] = 'italic';\n } else if (fontStyle !== 'inherit') {\n styles['font-style'] = fontStyle ? 'italic' : 'normal';\n } else {\n styles['font-style'] = 'inherit';\n }\n }\n\n if (textTransform) {\n styles['text-transform'] = textTransform;\n }\n\n // Handle font/fontFamily (font has special handling, fontFamily is direct)\n const fontResult = resolveFontFamily(font, fontFamily);\n if (fontResult) {\n styles['font-family'] = fontResult.value;\n if (fontResult.setVar) {\n styles['--font-family'] = fontResult.value;\n }\n }\n\n // Return undefined if no styles to apply\n if (Object.keys(styles).length === 0) {\n return;\n }\n\n return styles;\n}\n\npresetStyle.__lookupStyles = [\n 'preset',\n 'fontSize',\n 'lineHeight',\n 'letterSpacing',\n 'textTransform',\n 'fontWeight',\n 'fontStyle',\n 'fontFamily',\n 'font',\n];\n"],"mappings":"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"}
1
+ {"version":3,"file":"preset.js","names":[],"sources":["../../src/styles/preset.ts"],"sourcesContent":["import { parseStyle } from '../utils/styles';\n\nimport type { Styles } from './types';\n\nconst PRESET_MODIFIERS = new Set(['strong', 'bold', 'italic', 'icon', 'tight']);\n\n/**\n * Convert a value to CSS, handling numbers as pixels for numeric properties\n */\nfunction toCSS(\n value: string | number | undefined,\n isNumeric: boolean,\n): string | null {\n if (value == null) return null;\n if (typeof value === 'number') {\n return isNumeric ? `${value}px` : String(value);\n }\n // Parse through style parser to handle custom units like 1x, 2r, etc.\n const processed = parseStyle(String(value));\n return processed.groups[0]?.values[0] || String(value);\n}\n\nfunction setCSSValue(\n styles: Styles,\n styleName: string,\n presetName: string,\n { varOnly, cssOnly }: { varOnly?: boolean; cssOnly?: boolean } = {},\n) {\n const value = (() => {\n if (presetName === 'inherit') {\n return 'inherit';\n }\n\n const defaultValue = `var(--default-${styleName}${\n styleName === 'font-family'\n ? ', var(--font-sans, var(--font-sans-fallback))'\n : ''\n })`;\n const fontSuffix =\n styleName === 'font-family'\n ? ', var(--font-sans, var(--font-sans-fallback))'\n : '';\n\n if (presetName === 'default') {\n return `${defaultValue}${fontSuffix}`;\n } else {\n return `var(--${presetName}-${styleName}, ${defaultValue})${fontSuffix}`;\n }\n })();\n\n if (!cssOnly) {\n styles[`--${styleName}`] = value;\n }\n\n if (!varOnly) {\n styles[styleName] = value;\n }\n}\n\ninterface PresetStyleProps {\n preset?: string | boolean;\n fontSize?: string | number;\n lineHeight?: string | number;\n textTransform?: string;\n letterSpacing?: string | number;\n fontWeight?: string | number;\n fontStyle?: string | boolean;\n fontFamily?: string;\n /** Alias for fontFamily with special handling for 'monospace' and boolean */\n font?: string | boolean;\n}\n\n/**\n * Resolve font/fontFamily value to CSS font-family string.\n *\n * - `font=\"monospace\"` → var(--font-mono, var(--font-mono-fallback))\n * - `font={true}` → var(--font-sans, var(--font-sans-fallback))\n * - `font=\"CustomFont\"` → CustomFont, var(--font-sans, var(--font-sans-fallback))\n * - `fontFamily=\"Arial\"` → Arial (direct, no fallback)\n */\nfunction resolveFontFamily(\n font: string | boolean | undefined,\n fontFamily: string | undefined,\n): string | null {\n // fontFamily takes precedence as a direct value\n if (fontFamily) {\n return fontFamily;\n }\n\n if (font == null || font === false) {\n return null;\n }\n\n if (font === 'monospace') {\n return 'var(--font-mono, var(--font-mono-fallback))';\n }\n\n if (font === true) {\n return 'var(--font-sans, var(--font-sans-fallback))';\n }\n\n return `${font}, var(--font-sans, var(--font-sans-fallback))`;\n}\n\n/**\n * Handles typography preset and individual font properties.\n *\n * Preset syntax uses `/` to separate name from modifier:\n * - `preset=\"h1\"` — name only\n * - `preset=\"h2 / strong\"` — name + modifier\n * - `preset=\"bold\"` — modifier-only shorthand (name defaults to `inherit`)\n *\n * When `preset` is defined, it sets up CSS custom properties for typography.\n * Individual font props can be used with or without `preset`:\n * - With `preset`: overrides the preset value for that property\n * - Without `preset`: outputs the CSS directly\n *\n * Number values are converted to pixels for fontSize, lineHeight, letterSpacing.\n * fontWeight accepts numbers directly (e.g., 400, 700).\n *\n * font vs fontFamily:\n * - `font` is the recommended prop with special handling (monospace, boolean, fallback)\n * - `fontFamily` is a direct value without special handling\n */\nexport function presetStyle({\n preset,\n fontSize,\n lineHeight,\n textTransform,\n letterSpacing,\n fontWeight,\n fontStyle,\n fontFamily,\n font,\n}: PresetStyleProps) {\n const styles: Styles = {};\n const hasPreset = preset != null && preset !== false;\n\n // Handle preset if defined\n if (hasPreset) {\n const presetValue = preset === true ? '' : String(preset);\n\n const processed = parseStyle(presetValue);\n const group = processed.groups[0];\n const { parts } = group ?? { parts: [] };\n\n // parts[0] = preset name (or a modifier for shorthand like preset=\"bold\")\n // parts[1] = optional modifier after slash (e.g. \"t3 / bold\")\n const namePart = parts[0];\n const modPart = parts[1];\n\n const nameToken = namePart?.mods[0] ?? '';\n const isModOnly = PRESET_MODIFIERS.has(nameToken);\n\n const name = isModOnly ? 'inherit' : nameToken || 'inherit';\n const modifier = isModOnly ? nameToken : (modPart?.mods[0] ?? '');\n\n const isStrong = modifier === 'strong' || modifier === 'bold';\n const isItalic = modifier === 'italic';\n const isIcon = modifier === 'icon';\n const isTight = modifier === 'tight';\n\n // Set preset values for properties not explicitly overridden\n if (fontSize == null) {\n setCSSValue(styles, 'font-size', name, { cssOnly: true });\n }\n if (lineHeight == null) {\n setCSSValue(styles, 'line-height', name, { cssOnly: true });\n }\n if (letterSpacing == null) {\n setCSSValue(styles, 'letter-spacing', name, { cssOnly: true });\n }\n if (fontWeight == null) {\n setCSSValue(styles, 'font-weight', name, { cssOnly: true });\n }\n if (fontStyle == null) {\n setCSSValue(styles, 'font-style', name, { cssOnly: true });\n }\n if (textTransform == null) {\n setCSSValue(styles, 'text-transform', name, { cssOnly: true });\n }\n if (fontFamily == null && font == null) {\n setCSSValue(styles, 'font-family', name, { cssOnly: true });\n }\n\n setCSSValue(styles, 'bold-font-weight', name, { varOnly: true });\n setCSSValue(styles, 'icon-size', name, { varOnly: true });\n\n if (isStrong) {\n styles['font-weight'] = 'var(--bold-font-weight)';\n }\n if (isItalic) {\n styles['font-style'] = 'italic';\n }\n if (isIcon) {\n styles['font-size'] = 'var(--icon-size)';\n styles['line-height'] = 'var(--icon-size)';\n }\n if (isTight) {\n styles['line-height'] = '1em';\n }\n }\n\n // Handle individual font properties (work with or without preset)\n const fontSizeVal = toCSS(fontSize, true);\n if (fontSizeVal) {\n styles['font-size'] = fontSizeVal;\n }\n\n const lineHeightVal = toCSS(lineHeight, true);\n if (lineHeightVal) {\n styles['line-height'] = lineHeightVal;\n }\n\n const letterSpacingVal = toCSS(letterSpacing, true);\n if (letterSpacingVal) {\n styles['letter-spacing'] = letterSpacingVal;\n }\n\n // fontWeight: numbers should NOT get 'px' suffix\n const fontWeightVal = toCSS(fontWeight, false);\n if (fontWeightVal) {\n styles['font-weight'] = fontWeightVal;\n }\n\n // fontStyle: handle boolean (true → italic) and string values\n if (fontStyle != null) {\n if (fontStyle === true) {\n styles['font-style'] = 'italic';\n } else if (fontStyle !== 'inherit') {\n styles['font-style'] = fontStyle ? 'italic' : 'normal';\n } else {\n styles['font-style'] = 'inherit';\n }\n }\n\n if (textTransform) {\n styles['text-transform'] = textTransform;\n }\n\n // Handle font/fontFamily (font has special handling, fontFamily is direct)\n const fontFamily_ = resolveFontFamily(font, fontFamily);\n if (fontFamily_) {\n styles['font-family'] = fontFamily_;\n }\n\n // Return undefined if no styles to apply\n if (Object.keys(styles).length === 0) {\n return;\n }\n\n return styles;\n}\n\npresetStyle.__lookupStyles = [\n 'preset',\n 'fontSize',\n 'lineHeight',\n 'letterSpacing',\n 'textTransform',\n 'fontWeight',\n 'fontStyle',\n 'fontFamily',\n 'font',\n];\n"],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  declare function radiusStyle({
3
3
  radius
4
4
  }: {
5
- radius: any;
5
+ radius?: string | number | boolean;
6
6
  }): {
7
7
  'border-radius': string;
8
8
  } | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"radius.js","names":[],"sources":["../../src/styles/radius.ts"],"sourcesContent":["import { makeEmptyDetails } from '../parser/types';\nimport { DIRECTIONS, parseStyle } from '../utils/styles';\n\nconst PROP = 'var(--radius)';\nconst SHARP = 'var(--sharp-radius)';\n\nexport function radiusStyle({ radius }) {\n if (typeof radius === 'number') {\n radius = `${radius}px`;\n }\n\n if (!radius) return;\n\n if (radius === true) radius = '1r';\n\n const processed = parseStyle(radius);\n const { mods } = processed.groups[0] ?? makeEmptyDetails();\n let { values } = processed.groups[0] ?? makeEmptyDetails();\n\n if (mods.includes('round')) {\n values = ['9999rem'];\n } else if (mods.includes('ellipse')) {\n values = ['50%'];\n } else if (!values.length) {\n values = [PROP];\n }\n\n if (mods.includes('leaf')) {\n values = [\n values[1] || SHARP,\n values[0] || PROP,\n values[1] || SHARP,\n values[0] || PROP,\n ];\n } else if (mods.includes('backleaf')) {\n values = [\n values[0] || PROP,\n values[1] || SHARP,\n values[0] || PROP,\n values[1] || SHARP,\n ];\n } else if (mods.length) {\n const arr = ['0', '0', '0', '0'];\n\n let flag = false;\n\n DIRECTIONS.forEach((dir, i) => {\n if (!mods.includes(dir)) return;\n\n flag = true;\n\n arr[i] = values[0] || PROP;\n arr[(i + 1) % 4] = values[0] || PROP;\n });\n\n if (flag) {\n values = arr;\n }\n }\n\n return {\n 'border-radius': values.join(' '),\n };\n}\n\nradiusStyle.__lookupStyles = ['radius'];\n"],"mappings":";;;;AAGA,MAAM,OAAO;AACb,MAAM,QAAQ;AAEd,SAAgB,YAAY,EAAE,UAAU;AACtC,KAAI,OAAO,WAAW,SACpB,UAAS,GAAG,OAAO;AAGrB,KAAI,CAAC,OAAQ;AAEb,KAAI,WAAW,KAAM,UAAS;CAE9B,MAAM,YAAY,WAAW,OAAO;CACpC,MAAM,EAAE,SAAS,UAAU,OAAO,MAAM,kBAAkB;CAC1D,IAAI,EAAE,WAAW,UAAU,OAAO,MAAM,kBAAkB;AAE1D,KAAI,KAAK,SAAS,QAAQ,CACxB,UAAS,CAAC,UAAU;UACX,KAAK,SAAS,UAAU,CACjC,UAAS,CAAC,MAAM;UACP,CAAC,OAAO,OACjB,UAAS,CAAC,KAAK;AAGjB,KAAI,KAAK,SAAS,OAAO,CACvB,UAAS;EACP,OAAO,MAAM;EACb,OAAO,MAAM;EACb,OAAO,MAAM;EACb,OAAO,MAAM;EACd;UACQ,KAAK,SAAS,WAAW,CAClC,UAAS;EACP,OAAO,MAAM;EACb,OAAO,MAAM;EACb,OAAO,MAAM;EACb,OAAO,MAAM;EACd;UACQ,KAAK,QAAQ;EACtB,MAAM,MAAM;GAAC;GAAK;GAAK;GAAK;GAAI;EAEhC,IAAI,OAAO;AAEX,aAAW,SAAS,KAAK,MAAM;AAC7B,OAAI,CAAC,KAAK,SAAS,IAAI,CAAE;AAEzB,UAAO;AAEP,OAAI,KAAK,OAAO,MAAM;AACtB,QAAK,IAAI,KAAK,KAAK,OAAO,MAAM;IAChC;AAEF,MAAI,KACF,UAAS;;AAIb,QAAO,EACL,iBAAiB,OAAO,KAAK,IAAI,EAClC;;AAGH,YAAY,iBAAiB,CAAC,SAAS"}
1
+ {"version":3,"file":"radius.js","names":[],"sources":["../../src/styles/radius.ts"],"sourcesContent":["import { makeEmptyDetails } from '../parser/types';\nimport { DIRECTIONS, parseStyle } from '../utils/styles';\n\nconst PROP = 'var(--radius)';\nconst SHARP = 'var(--sharp-radius)';\n\nexport function radiusStyle({\n radius,\n}: {\n radius?: string | number | boolean;\n}) {\n if (typeof radius === 'number') {\n radius = `${radius}px`;\n }\n\n if (!radius) return;\n\n if (radius === true) radius = '1r';\n\n const processed = parseStyle(radius);\n const { mods } = processed.groups[0] ?? makeEmptyDetails();\n let { values } = processed.groups[0] ?? makeEmptyDetails();\n\n if (mods.includes('round')) {\n values = ['9999rem'];\n } else if (mods.includes('ellipse')) {\n values = ['50%'];\n } else if (!values.length) {\n values = [PROP];\n }\n\n if (mods.includes('leaf')) {\n values = [\n values[1] || SHARP,\n values[0] || PROP,\n values[1] || SHARP,\n values[0] || PROP,\n ];\n } else if (mods.includes('backleaf')) {\n values = [\n values[0] || PROP,\n values[1] || SHARP,\n values[0] || PROP,\n values[1] || SHARP,\n ];\n } else if (mods.length) {\n const arr = ['0', '0', '0', '0'];\n\n let flag = false;\n\n DIRECTIONS.forEach((dir, i) => {\n if (!mods.includes(dir)) return;\n\n flag = true;\n\n arr[i] = values[0] || PROP;\n arr[(i + 1) % 4] = values[0] || PROP;\n });\n\n if (flag) {\n values = arr;\n }\n }\n\n return {\n 'border-radius': values.join(' '),\n };\n}\n\nradiusStyle.__lookupStyles = ['radius'];\n"],"mappings":";;;;AAGA,MAAM,OAAO;AACb,MAAM,QAAQ;AAEd,SAAgB,YAAY,EAC1B,UAGC;AACD,KAAI,OAAO,WAAW,SACpB,UAAS,GAAG,OAAO;AAGrB,KAAI,CAAC,OAAQ;AAEb,KAAI,WAAW,KAAM,UAAS;CAE9B,MAAM,YAAY,WAAW,OAAO;CACpC,MAAM,EAAE,SAAS,UAAU,OAAO,MAAM,kBAAkB;CAC1D,IAAI,EAAE,WAAW,UAAU,OAAO,MAAM,kBAAkB;AAE1D,KAAI,KAAK,SAAS,QAAQ,CACxB,UAAS,CAAC,UAAU;UACX,KAAK,SAAS,UAAU,CACjC,UAAS,CAAC,MAAM;UACP,CAAC,OAAO,OACjB,UAAS,CAAC,KAAK;AAGjB,KAAI,KAAK,SAAS,OAAO,CACvB,UAAS;EACP,OAAO,MAAM;EACb,OAAO,MAAM;EACb,OAAO,MAAM;EACb,OAAO,MAAM;EACd;UACQ,KAAK,SAAS,WAAW,CAClC,UAAS;EACP,OAAO,MAAM;EACb,OAAO,MAAM;EACb,OAAO,MAAM;EACb,OAAO,MAAM;EACd;UACQ,KAAK,QAAQ;EACtB,MAAM,MAAM;GAAC;GAAK;GAAK;GAAK;GAAI;EAEhC,IAAI,OAAO;AAEX,aAAW,SAAS,KAAK,MAAM;AAC7B,OAAI,CAAC,KAAK,SAAS,IAAI,CAAE;AAEzB,UAAO;AAEP,OAAI,KAAK,OAAO,MAAM;AACtB,QAAK,IAAI,KAAK,KAAK,OAAO,MAAM;IAChC;AAEF,MAAI,KACF,UAAS;;AAIb,QAAO,EACL,iBAAiB,OAAO,KAAK,IAAI,EAClC;;AAGH,YAAY,iBAAiB,CAAC,SAAS"}
@@ -1,18 +1,22 @@
1
1
  //#region src/styles/scrollbar.d.ts
2
2
  interface ScrollbarStyleProps {
3
- scrollbar?: string | boolean | number;
3
+ scrollbar?: string | boolean;
4
4
  overflow?: string;
5
5
  }
6
6
  /**
7
- * Creates cross-browser compatible scrollbar styles
7
+ * Standard CSS scrollbar styling via `scrollbar-width`, `scrollbar-color`,
8
+ * and `scrollbar-gutter`.
8
9
  *
9
- * Supports both Firefox (scrollbar-width, scrollbar-color) and
10
- * WebKit/Chromium browsers (::-webkit-scrollbar)
10
+ * Width values: `thin` (default), `auto`, `none`
11
+ * Modifiers: `stable`, `both-edges`, `always`
12
+ *
13
+ * Note: `auto` is classified as a VALUE_KEYWORD by the parser, so it lands
14
+ * in `values` rather than `mods`. Both locations are checked for robustness.
11
15
  */
12
16
  declare function scrollbarStyle({
13
17
  scrollbar,
14
18
  overflow
15
- }: ScrollbarStyleProps): {} | undefined;
19
+ }: ScrollbarStyleProps): Record<string, string> | undefined;
16
20
  declare namespace scrollbarStyle {
17
21
  var __lookupStyles: string[];
18
22
  }
@@ -1,100 +1,43 @@
1
1
  import { makeEmptyDetails } from "../parser/types.js";
2
2
  import { parseStyle } from "../utils/styles.js";
3
+ import { warn } from "../utils/warnings.js";
3
4
 
4
5
  //#region src/styles/scrollbar.ts
5
6
  /**
6
- * Creates cross-browser compatible scrollbar styles
7
+ * Standard CSS scrollbar styling via `scrollbar-width`, `scrollbar-color`,
8
+ * and `scrollbar-gutter`.
7
9
  *
8
- * Supports both Firefox (scrollbar-width, scrollbar-color) and
9
- * WebKit/Chromium browsers (::-webkit-scrollbar)
10
+ * Width values: `thin` (default), `auto`, `none`
11
+ * Modifiers: `stable`, `both-edges`, `always`
12
+ *
13
+ * Note: `auto` is classified as a VALUE_KEYWORD by the parser, so it lands
14
+ * in `values` rather than `mods`. Both locations are checked for robustness.
10
15
  */
11
16
  function scrollbarStyle({ scrollbar, overflow }) {
12
- if (!scrollbar && scrollbar !== 0) return;
13
- const value = scrollbar === true || scrollbar === "" ? "thin" : scrollbar;
17
+ if (!scrollbar) return;
18
+ const value = scrollbar === true ? "thin" : scrollbar;
14
19
  const { mods, colors, values } = parseStyle(String(value)).groups[0] ?? makeEmptyDetails();
15
- const style = {};
16
20
  const defaultThumbColor = "var(--scrollbar-thumb-color)";
17
21
  const defaultTrackColor = "var(--scrollbar-track-color, transparent)";
18
- style["scrollbar-color"] = `${defaultThumbColor} transparent`;
19
- const sizeValue = values[0] || "8px";
20
- if (mods.includes("thin")) style["scrollbar-width"] = "thin";
21
- else if (mods.includes("none")) {
22
+ const style = {};
23
+ if (mods.includes("none")) {
24
+ const ignored = [
25
+ ...mods.filter((m) => m !== "none"),
26
+ ...values,
27
+ ...colors
28
+ ];
29
+ if (ignored.length) warn(`scrollbar="none" hides the scrollbar; other tokens are ignored: ${ignored.join(", ")}`);
22
30
  style["scrollbar-width"] = "none";
23
- delete style["scrollbar-color"];
24
- style["&::-webkit-scrollbar"] = {
25
- width: "0px",
26
- height: "0px",
27
- display: "none"
28
- };
29
31
  return style;
30
- } else if (mods.includes("auto")) style["scrollbar-width"] = "auto";
31
- if (mods.includes("stable") || mods.includes("both-edges")) style["scrollbar-gutter"] = mods.includes("both-edges") ? "stable both-edges" : "stable";
32
- if (sizeValue) style["&::-webkit-scrollbar"] = {
33
- ...style["&::-webkit-scrollbar"] || {},
34
- width: sizeValue,
35
- height: sizeValue
36
- };
37
- const thumbColor = colors && colors[0] ? colors[0] : defaultThumbColor;
38
- const trackColor = colors && colors[1] ? colors[1] : defaultTrackColor;
39
- const cornerColor = colors && colors[2] ? colors[2] : trackColor;
40
- if (colors && colors.length) {
41
- style["scrollbar-color"] = `${thumbColor} ${trackColor}`;
42
- if (!style["&::-webkit-scrollbar"]) style["&::-webkit-scrollbar"] = {};
43
- style["&::-webkit-scrollbar"]["background"] = trackColor;
44
- style["&::-webkit-scrollbar-track"] = {
45
- ...style["&::-webkit-scrollbar-track"] || {},
46
- background: trackColor
47
- };
48
- style["&::-webkit-scrollbar-thumb"] = {
49
- ...style["&::-webkit-scrollbar-thumb"] || {},
50
- background: thumbColor
51
- };
52
- style["&::-webkit-scrollbar-corner"] = {
53
- ...style["&::-webkit-scrollbar-corner"] || {},
54
- background: cornerColor
55
- };
56
32
  }
33
+ if (mods.includes("auto") || values.includes("auto")) style["scrollbar-width"] = "auto";
34
+ else style["scrollbar-width"] = "thin";
35
+ style["scrollbar-color"] = `${colors?.[0] || defaultThumbColor} ${colors?.[1] || defaultTrackColor}`;
36
+ if (mods.includes("stable") || mods.includes("both-edges")) style["scrollbar-gutter"] = mods.includes("both-edges") ? "stable both-edges" : "stable";
57
37
  if (mods.includes("always")) {
58
- style["overflow"] = overflow || "scroll";
59
- if (!style["scrollbar-gutter"]) style["scrollbar-gutter"] = "stable";
60
- if (!style["&::-webkit-scrollbar"]) style["&::-webkit-scrollbar"] = {};
61
- style["&::-webkit-scrollbar"]["display"] = "block";
62
- }
63
- if (mods.includes("styled")) {
64
- const baseTransition = [
65
- "background var(--transition)",
66
- "border-radius var(--transition)",
67
- "box-shadow var(--transition)",
68
- "width var(--transition)",
69
- "height var(--transition)",
70
- "border var(--transition)"
71
- ].join(", ");
72
- style["scrollbar-width"] = style["scrollbar-width"] || "thin";
73
- style["scrollbar-color"] = style["scrollbar-color"] || `${defaultThumbColor} ${defaultTrackColor}`;
74
- style["&::-webkit-scrollbar"] = {
75
- width: sizeValue,
76
- height: sizeValue,
77
- transition: baseTransition,
78
- background: defaultTrackColor,
79
- ...style["&::-webkit-scrollbar"] || {}
80
- };
81
- style["&::-webkit-scrollbar-thumb"] = {
82
- "border-radius": "8px",
83
- "min-height": "24px",
84
- transition: baseTransition,
85
- background: defaultThumbColor,
86
- ...style["&::-webkit-scrollbar-thumb"] || {}
87
- };
88
- style["&::-webkit-scrollbar-track"] = {
89
- background: defaultTrackColor,
90
- transition: baseTransition,
91
- ...style["&::-webkit-scrollbar-track"] || {}
92
- };
93
- style["&::-webkit-scrollbar-corner"] = {
94
- background: defaultTrackColor,
95
- transition: baseTransition,
96
- ...style["&::-webkit-scrollbar-corner"] || {}
97
- };
38
+ const effectiveOverflow = overflow || "scroll";
39
+ style["overflow"] = effectiveOverflow;
40
+ if (!style["scrollbar-gutter"] && (effectiveOverflow === "scroll" || effectiveOverflow === "auto")) style["scrollbar-gutter"] = "stable";
98
41
  }
99
42
  return style;
100
43
  }
@@ -1 +1 @@
1
- {"version":3,"file":"scrollbar.js","names":[],"sources":["../../src/styles/scrollbar.ts"],"sourcesContent":["import { makeEmptyDetails } from '../parser/types';\nimport { parseStyle } from '../utils/styles';\n\ninterface ScrollbarStyleProps {\n scrollbar?: string | boolean | number;\n overflow?: string;\n}\n\n/**\n * Creates cross-browser compatible scrollbar styles\n *\n * Supports both Firefox (scrollbar-width, scrollbar-color) and\n * WebKit/Chromium browsers (::-webkit-scrollbar)\n */\nexport function scrollbarStyle({ scrollbar, overflow }: ScrollbarStyleProps) {\n // Check if scrollbar is defined\n if (!scrollbar && scrollbar !== 0) return;\n\n // Support true as alias for thin\n const value = scrollbar === true || scrollbar === '' ? 'thin' : scrollbar;\n const processed = parseStyle(String(value));\n const { mods, colors, values } = processed.groups[0] ?? makeEmptyDetails();\n const style = {};\n\n // Default colors for scrollbar\n const defaultThumbColor = 'var(--scrollbar-thumb-color)';\n const defaultTrackColor = 'var(--scrollbar-track-color, transparent)';\n\n // Setup default Firefox scrollbar style\n style['scrollbar-color'] = `${defaultThumbColor} transparent`;\n\n // Default scrollbar size\n const defaultSize = '8px';\n const sizeValue = values[0] || defaultSize;\n\n // Process modifiers\n if (mods.includes('thin')) {\n style['scrollbar-width'] = 'thin';\n } else if (mods.includes('none')) {\n style['scrollbar-width'] = 'none';\n // Remove scrollbar-color as it's not needed when scrollbar is hidden\n delete style['scrollbar-color'];\n // Also hide WebKit scrollbars\n style['&::-webkit-scrollbar'] = {\n width: '0px',\n height: '0px',\n display: 'none',\n };\n\n return style;\n } else if (mods.includes('auto')) {\n style['scrollbar-width'] = 'auto';\n }\n\n // Handle scrollbar gutter behavior\n if (mods.includes('stable') || mods.includes('both-edges')) {\n // scrollbar-gutter is supported in newer browsers only\n style['scrollbar-gutter'] = mods.includes('both-edges')\n ? 'stable both-edges'\n : 'stable';\n }\n\n // Custom size setup for WebKit\n if (sizeValue) {\n style['&::-webkit-scrollbar'] = {\n ...(style['&::-webkit-scrollbar'] || {}),\n width: sizeValue,\n height: sizeValue,\n };\n }\n\n // Extract colors (support up to 3: thumb, track, corner)\n // These will be used in various places throughout the function\n const thumbColor = colors && colors[0] ? colors[0] : defaultThumbColor;\n const trackColor = colors && colors[1] ? colors[1] : defaultTrackColor;\n const cornerColor = colors && colors[2] ? colors[2] : trackColor;\n\n // Apply colors if they are specified\n if (colors && colors.length) {\n // Firefox\n style['scrollbar-color'] = `${thumbColor} ${trackColor}`;\n\n // WebKit - always set these for consistency\n if (!style['&::-webkit-scrollbar']) {\n style['&::-webkit-scrollbar'] = {};\n }\n style['&::-webkit-scrollbar']['background'] = trackColor;\n\n style['&::-webkit-scrollbar-track'] = {\n ...(style['&::-webkit-scrollbar-track'] || {}),\n background: trackColor,\n };\n\n style['&::-webkit-scrollbar-thumb'] = {\n ...(style['&::-webkit-scrollbar-thumb'] || {}),\n background: thumbColor,\n };\n\n style['&::-webkit-scrollbar-corner'] = {\n ...(style['&::-webkit-scrollbar-corner'] || {}),\n background: cornerColor,\n };\n }\n\n // Handle 'always' mode: force scrollbars to show\n if (mods.includes('always')) {\n style['overflow'] = overflow || 'scroll';\n\n // Use auto for WebKit browsers since they don't support 'always'\n // This is closer to the expected behavior\n if (!style['scrollbar-gutter']) {\n style['scrollbar-gutter'] = 'stable';\n }\n\n // Ensure scrollbars appear in WebKit even with little content\n if (!style['&::-webkit-scrollbar']) {\n style['&::-webkit-scrollbar'] = {};\n }\n style['&::-webkit-scrollbar']['display'] = 'block';\n }\n\n // Enhanced 'styled' mode with better transitions and appearance\n if (mods.includes('styled')) {\n const baseTransition = [\n 'background var(--transition)',\n 'border-radius var(--transition)',\n 'box-shadow var(--transition)',\n 'width var(--transition)',\n 'height var(--transition)',\n 'border var(--transition)',\n ].join(', ');\n\n // Firefox\n style['scrollbar-width'] = style['scrollbar-width'] || 'thin';\n style['scrollbar-color'] =\n style['scrollbar-color'] || `${defaultThumbColor} ${defaultTrackColor}`;\n\n // WebKit\n style['&::-webkit-scrollbar'] = {\n width: sizeValue,\n height: sizeValue,\n transition: baseTransition,\n background: defaultTrackColor,\n ...(style['&::-webkit-scrollbar'] || {}),\n };\n\n style['&::-webkit-scrollbar-thumb'] = {\n 'border-radius': '8px',\n 'min-height': '24px',\n transition: baseTransition,\n background: defaultThumbColor,\n ...(style['&::-webkit-scrollbar-thumb'] || {}),\n };\n\n style['&::-webkit-scrollbar-track'] = {\n background: defaultTrackColor,\n transition: baseTransition,\n ...(style['&::-webkit-scrollbar-track'] || {}),\n };\n\n style['&::-webkit-scrollbar-corner'] = {\n background: defaultTrackColor,\n transition: baseTransition,\n ...(style['&::-webkit-scrollbar-corner'] || {}),\n };\n }\n\n return style;\n}\n\nscrollbarStyle.__lookupStyles = ['scrollbar', 'overflow'];\n"],"mappings":";;;;;;;;;;AAcA,SAAgB,eAAe,EAAE,WAAW,YAAiC;AAE3E,KAAI,CAAC,aAAa,cAAc,EAAG;CAGnC,MAAM,QAAQ,cAAc,QAAQ,cAAc,KAAK,SAAS;CAEhE,MAAM,EAAE,MAAM,QAAQ,WADJ,WAAW,OAAO,MAAM,CAAC,CACA,OAAO,MAAM,kBAAkB;CAC1E,MAAM,QAAQ,EAAE;CAGhB,MAAM,oBAAoB;CAC1B,MAAM,oBAAoB;AAG1B,OAAM,qBAAqB,GAAG,kBAAkB;CAIhD,MAAM,YAAY,OAAO,MADL;AAIpB,KAAI,KAAK,SAAS,OAAO,CACvB,OAAM,qBAAqB;UAClB,KAAK,SAAS,OAAO,EAAE;AAChC,QAAM,qBAAqB;AAE3B,SAAO,MAAM;AAEb,QAAM,0BAA0B;GAC9B,OAAO;GACP,QAAQ;GACR,SAAS;GACV;AAED,SAAO;YACE,KAAK,SAAS,OAAO,CAC9B,OAAM,qBAAqB;AAI7B,KAAI,KAAK,SAAS,SAAS,IAAI,KAAK,SAAS,aAAa,CAExD,OAAM,sBAAsB,KAAK,SAAS,aAAa,GACnD,sBACA;AAIN,KAAI,UACF,OAAM,0BAA0B;EAC9B,GAAI,MAAM,2BAA2B,EAAE;EACvC,OAAO;EACP,QAAQ;EACT;CAKH,MAAM,aAAa,UAAU,OAAO,KAAK,OAAO,KAAK;CACrD,MAAM,aAAa,UAAU,OAAO,KAAK,OAAO,KAAK;CACrD,MAAM,cAAc,UAAU,OAAO,KAAK,OAAO,KAAK;AAGtD,KAAI,UAAU,OAAO,QAAQ;AAE3B,QAAM,qBAAqB,GAAG,WAAW,GAAG;AAG5C,MAAI,CAAC,MAAM,wBACT,OAAM,0BAA0B,EAAE;AAEpC,QAAM,wBAAwB,gBAAgB;AAE9C,QAAM,gCAAgC;GACpC,GAAI,MAAM,iCAAiC,EAAE;GAC7C,YAAY;GACb;AAED,QAAM,gCAAgC;GACpC,GAAI,MAAM,iCAAiC,EAAE;GAC7C,YAAY;GACb;AAED,QAAM,iCAAiC;GACrC,GAAI,MAAM,kCAAkC,EAAE;GAC9C,YAAY;GACb;;AAIH,KAAI,KAAK,SAAS,SAAS,EAAE;AAC3B,QAAM,cAAc,YAAY;AAIhC,MAAI,CAAC,MAAM,oBACT,OAAM,sBAAsB;AAI9B,MAAI,CAAC,MAAM,wBACT,OAAM,0BAA0B,EAAE;AAEpC,QAAM,wBAAwB,aAAa;;AAI7C,KAAI,KAAK,SAAS,SAAS,EAAE;EAC3B,MAAM,iBAAiB;GACrB;GACA;GACA;GACA;GACA;GACA;GACD,CAAC,KAAK,KAAK;AAGZ,QAAM,qBAAqB,MAAM,sBAAsB;AACvD,QAAM,qBACJ,MAAM,sBAAsB,GAAG,kBAAkB,GAAG;AAGtD,QAAM,0BAA0B;GAC9B,OAAO;GACP,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,GAAI,MAAM,2BAA2B,EAAE;GACxC;AAED,QAAM,gCAAgC;GACpC,iBAAiB;GACjB,cAAc;GACd,YAAY;GACZ,YAAY;GACZ,GAAI,MAAM,iCAAiC,EAAE;GAC9C;AAED,QAAM,gCAAgC;GACpC,YAAY;GACZ,YAAY;GACZ,GAAI,MAAM,iCAAiC,EAAE;GAC9C;AAED,QAAM,iCAAiC;GACrC,YAAY;GACZ,YAAY;GACZ,GAAI,MAAM,kCAAkC,EAAE;GAC/C;;AAGH,QAAO;;AAGT,eAAe,iBAAiB,CAAC,aAAa,WAAW"}
1
+ {"version":3,"file":"scrollbar.js","names":[],"sources":["../../src/styles/scrollbar.ts"],"sourcesContent":["import { makeEmptyDetails } from '../parser/types';\nimport { parseStyle } from '../utils/styles';\nimport { warn } from '../utils/warnings';\n\ninterface ScrollbarStyleProps {\n scrollbar?: string | boolean;\n overflow?: string;\n}\n\n/**\n * Standard CSS scrollbar styling via `scrollbar-width`, `scrollbar-color`,\n * and `scrollbar-gutter`.\n *\n * Width values: `thin` (default), `auto`, `none`\n * Modifiers: `stable`, `both-edges`, `always`\n *\n * Note: `auto` is classified as a VALUE_KEYWORD by the parser, so it lands\n * in `values` rather than `mods`. Both locations are checked for robustness.\n */\nexport function scrollbarStyle({\n scrollbar,\n overflow,\n}: ScrollbarStyleProps): Record<string, string> | undefined {\n if (!scrollbar) return;\n\n // `true` is treated as `thin` (empty string is falsy, caught by the guard above)\n const value = scrollbar === true ? 'thin' : scrollbar;\n const processed = parseStyle(String(value));\n const { mods, colors, values } = processed.groups[0] ?? makeEmptyDetails();\n\n const defaultThumbColor = 'var(--scrollbar-thumb-color)';\n const defaultTrackColor = 'var(--scrollbar-track-color, transparent)';\n\n const style: Record<string, string> = {};\n\n if (mods.includes('none')) {\n const ignored = [...mods.filter((m) => m !== 'none'), ...values, ...colors];\n\n if (ignored.length) {\n warn(\n `scrollbar=\"none\" hides the scrollbar; other tokens are ignored: ${ignored.join(', ')}`,\n );\n }\n\n style['scrollbar-width'] = 'none';\n\n return style;\n }\n\n // `thin` is the default accepted as a value for readability but always\n // the fallback when neither `auto` nor `none` is specified.\n // `auto` is a VALUE_KEYWORD in the parser, so it may land in `values`.\n if (mods.includes('auto') || values.includes('auto')) {\n style['scrollbar-width'] = 'auto';\n } else {\n style['scrollbar-width'] = 'thin';\n }\n\n const thumbColor = colors?.[0] || defaultThumbColor;\n const trackColor = colors?.[1] || defaultTrackColor;\n style['scrollbar-color'] = `${thumbColor} ${trackColor}`;\n\n if (mods.includes('stable') || mods.includes('both-edges')) {\n style['scrollbar-gutter'] = mods.includes('both-edges')\n ? 'stable both-edges'\n : 'stable';\n }\n\n if (mods.includes('always')) {\n const effectiveOverflow = overflow || 'scroll';\n style['overflow'] = effectiveOverflow;\n\n // scrollbar-gutter only applies with scroll/auto overflow\n if (\n !style['scrollbar-gutter'] &&\n (effectiveOverflow === 'scroll' || effectiveOverflow === 'auto')\n ) {\n style['scrollbar-gutter'] = 'stable';\n }\n }\n\n return style;\n}\n\nscrollbarStyle.__lookupStyles = ['scrollbar', 'overflow'];\n"],"mappings":";;;;;;;;;;;;;;;AAmBA,SAAgB,eAAe,EAC7B,WACA,YAC0D;AAC1D,KAAI,CAAC,UAAW;CAGhB,MAAM,QAAQ,cAAc,OAAO,SAAS;CAE5C,MAAM,EAAE,MAAM,QAAQ,WADJ,WAAW,OAAO,MAAM,CAAC,CACA,OAAO,MAAM,kBAAkB;CAE1E,MAAM,oBAAoB;CAC1B,MAAM,oBAAoB;CAE1B,MAAM,QAAgC,EAAE;AAExC,KAAI,KAAK,SAAS,OAAO,EAAE;EACzB,MAAM,UAAU;GAAC,GAAG,KAAK,QAAQ,MAAM,MAAM,OAAO;GAAE,GAAG;GAAQ,GAAG;GAAO;AAE3E,MAAI,QAAQ,OACV,MACE,mEAAmE,QAAQ,KAAK,KAAK,GACtF;AAGH,QAAM,qBAAqB;AAE3B,SAAO;;AAMT,KAAI,KAAK,SAAS,OAAO,IAAI,OAAO,SAAS,OAAO,CAClD,OAAM,qBAAqB;KAE3B,OAAM,qBAAqB;AAK7B,OAAM,qBAAqB,GAFR,SAAS,MAAM,kBAEO,GADtB,SAAS,MAAM;AAGlC,KAAI,KAAK,SAAS,SAAS,IAAI,KAAK,SAAS,aAAa,CACxD,OAAM,sBAAsB,KAAK,SAAS,aAAa,GACnD,sBACA;AAGN,KAAI,KAAK,SAAS,SAAS,EAAE;EAC3B,MAAM,oBAAoB,YAAY;AACtC,QAAM,cAAc;AAGpB,MACE,CAAC,MAAM,wBACN,sBAAsB,YAAY,sBAAsB,QAEzD,OAAM,sBAAsB;;AAIhC,QAAO;;AAGT,eAAe,iBAAiB,CAAC,aAAa,WAAW"}
@@ -2,9 +2,9 @@
2
2
  declare function shadowStyle({
3
3
  shadow
4
4
  }: {
5
- shadow: any;
5
+ shadow?: string | boolean;
6
6
  }): {
7
- 'box-shadow': any;
7
+ 'box-shadow': string;
8
8
  } | undefined;
9
9
  declare namespace shadowStyle {
10
10
  var __lookupStyles: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"shadow.js","names":[],"sources":["../../src/styles/shadow.ts"],"sourcesContent":["import { makeEmptyDetails } from '../parser/types';\nimport { parseStyle } from '../utils/styles';\n\nfunction toBoxShadow(shadow) {\n const processed = parseStyle(shadow);\n const { values, mods, colors } = processed.groups[0] ?? makeEmptyDetails();\n const mod = mods[0] || '';\n const shadowColor = (colors && colors[0]) ?? '';\n\n return [mod, ...values, shadowColor].join(' ');\n}\n\nexport function shadowStyle({ shadow }) {\n if (!shadow) return;\n\n if (shadow === true) shadow = 'var(--shadow)';\n\n return {\n 'box-shadow': shadow.split(',').map(toBoxShadow).join(','),\n };\n}\n\nshadowStyle.__lookupStyles = ['shadow'];\n"],"mappings":";;;;AAGA,SAAS,YAAY,QAAQ;CAE3B,MAAM,EAAE,QAAQ,MAAM,WADJ,WAAW,OAAO,CACO,OAAO,MAAM,kBAAkB;CAC1E,MAAM,MAAM,KAAK,MAAM;CACvB,MAAM,eAAe,UAAU,OAAO,OAAO;AAE7C,QAAO;EAAC;EAAK,GAAG;EAAQ;EAAY,CAAC,KAAK,IAAI;;AAGhD,SAAgB,YAAY,EAAE,UAAU;AACtC,KAAI,CAAC,OAAQ;AAEb,KAAI,WAAW,KAAM,UAAS;AAE9B,QAAO,EACL,cAAc,OAAO,MAAM,IAAI,CAAC,IAAI,YAAY,CAAC,KAAK,IAAI,EAC3D;;AAGH,YAAY,iBAAiB,CAAC,SAAS"}
1
+ {"version":3,"file":"shadow.js","names":[],"sources":["../../src/styles/shadow.ts"],"sourcesContent":["import { makeEmptyDetails } from '../parser/types';\nimport { parseStyle } from '../utils/styles';\n\nfunction toBoxShadow(shadow: string): string {\n const processed = parseStyle(shadow);\n const { values, mods, colors } = processed.groups[0] ?? makeEmptyDetails();\n const mod = mods[0] || '';\n const shadowColor = (colors && colors[0]) ?? '';\n\n return [mod, ...values, shadowColor].join(' ');\n}\n\nexport function shadowStyle({ shadow }: { shadow?: string | boolean }) {\n if (!shadow) return;\n\n if (shadow === true) shadow = 'var(--shadow)';\n\n return {\n 'box-shadow': shadow.split(',').map(toBoxShadow).join(','),\n };\n}\n\nshadowStyle.__lookupStyles = ['shadow'];\n"],"mappings":";;;;AAGA,SAAS,YAAY,QAAwB;CAE3C,MAAM,EAAE,QAAQ,MAAM,WADJ,WAAW,OAAO,CACO,OAAO,MAAM,kBAAkB;CAC1E,MAAM,MAAM,KAAK,MAAM;CACvB,MAAM,eAAe,UAAU,OAAO,OAAO;AAE7C,QAAO;EAAC;EAAK,GAAG;EAAQ;EAAY,CAAC,KAAK,IAAI;;AAGhD,SAAgB,YAAY,EAAE,UAAyC;AACrE,KAAI,CAAC,OAAQ;AAEb,KAAI,WAAW,KAAM,UAAS;AAE9B,QAAO,EACL,cAAc,OAAO,MAAM,IAAI,CAAC,IAAI,YAAY,CAAC,KAAK,IAAI,EAC3D;;AAGH,YAAY,iBAAiB,CAAC,SAAS"}
@@ -2,7 +2,7 @@
2
2
  declare function transitionStyle({
3
3
  transition
4
4
  }: {
5
- transition: any;
5
+ transition?: string;
6
6
  }): {
7
7
  transition: string;
8
8
  } | undefined;
@@ -99,7 +99,7 @@ function isEasing(token) {
99
99
  return EASING_KEYWORDS.has(token) || token.startsWith("cubic-bezier(") || token.startsWith("steps(") || token.startsWith("linear(");
100
100
  }
101
101
  function getTiming(name) {
102
- return `var(--${name}-transition, var(--transition))`;
102
+ return `var(${name.startsWith("--") ? `${name}-transition` : `--${name}-transition`}, var(--transition))`;
103
103
  }
104
104
  function transitionStyle({ transition }) {
105
105
  if (!transition) return;
@@ -1 +1 @@
1
- {"version":3,"file":"transition.js","names":[],"sources":["../../src/styles/transition.ts"],"sourcesContent":["import { parseStyle } from '../utils/styles';\n\nconst SECOND_FILL_COLOR_PROPERTY = '--tasty-second-fill-color';\n\nconst MAP: Record<string, string[]> = {\n fade: ['mask', 'mask-composite'],\n translate: ['transform', 'translate'],\n rotate: ['transform', 'rotate'],\n scale: ['transform', 'scale'],\n fill: ['background-color', 'background-image', SECOND_FILL_COLOR_PROPERTY],\n image: [\n 'background-image',\n 'background-position',\n 'background-size',\n 'background-repeat',\n 'background-attachment',\n 'background-origin',\n 'background-clip',\n SECOND_FILL_COLOR_PROPERTY,\n ],\n background: [\n 'background-color',\n 'background-image',\n 'background-position',\n 'background-size',\n 'background-repeat',\n 'background-attachment',\n 'background-origin',\n 'background-clip',\n SECOND_FILL_COLOR_PROPERTY,\n ],\n border: [\n 'border',\n 'border-top',\n 'border-right',\n 'border-bottom',\n 'border-left',\n ],\n filter: ['filter', 'backdrop-filter'],\n radius: ['border-radius'],\n shadow: ['box-shadow'],\n outline: ['outline', 'outline-offset'],\n preset: [\n 'font-size',\n 'line-height',\n 'letter-spacing',\n 'font-weight',\n 'font-style',\n ],\n text: ['font-weight', 'text-decoration-color'],\n color: ['color'],\n opacity: ['opacity'],\n theme: [\n 'color',\n 'background-color',\n 'background-image',\n 'box-shadow',\n 'border',\n 'border-radius',\n 'outline',\n 'opacity',\n SECOND_FILL_COLOR_PROPERTY,\n ],\n width: ['max-width', 'min-width', 'width'],\n height: ['max-height', 'min-height', 'height'],\n gap: ['gap', 'margin'],\n zIndex: ['z-index'],\n inset: ['inset', 'top', 'right', 'bottom', 'left'],\n};\n\nexport const DEFAULT_TIMING = 'var(--transition)';\nconst DEFAULT_EASING = 'linear';\n\nconst EASING_KEYWORDS = new Set([\n 'ease',\n 'ease-in',\n 'ease-out',\n 'ease-in-out',\n 'linear',\n 'step-start',\n 'step-end',\n]);\n\nfunction isEasing(token: string): boolean {\n return (\n EASING_KEYWORDS.has(token) ||\n token.startsWith('cubic-bezier(') ||\n token.startsWith('steps(') ||\n token.startsWith('linear(')\n );\n}\n\nfunction getTiming(name: string): string {\n return `var(--${name}-transition, var(--transition))`;\n}\n\ntype TransitionEntry = [\n name: string,\n easing: string | undefined,\n timing: string | undefined,\n delay: string | undefined,\n];\n\nexport function transitionStyle({ transition }) {\n if (!transition) return;\n\n const processed = parseStyle(transition);\n const tokens: string[] = [];\n processed.groups.forEach((g, idx) => {\n tokens.push(...g.all);\n if (idx < processed.groups.length - 1) tokens.push(',');\n });\n\n if (tokens.length === 0) return;\n\n let tempTransition: string[] = [];\n const transitions: string[][] = [];\n\n tokens.forEach((token) => {\n if (token === ',') {\n if (tempTransition.length) {\n transitions.push(tempTransition);\n tempTransition = [];\n }\n } else {\n tempTransition.push(token);\n }\n });\n\n if (tempTransition.length) {\n transitions.push(tempTransition);\n }\n\n const map: Record<string, TransitionEntry> = {};\n\n transitions.forEach((transition) => {\n const name = transition[0];\n\n let timing: string | undefined;\n let easing: string | undefined;\n let delay: string | undefined;\n\n if (transition[1] && isEasing(transition[1])) {\n easing = transition[1];\n delay = transition[2];\n } else {\n timing = transition[1];\n easing = transition[2];\n delay = transition[3];\n }\n\n const styles = MAP[name] || [name];\n\n styles.forEach((style) => {\n map[style] = [name, easing, timing, delay];\n });\n });\n\n const result = Object.entries(map)\n .map(([style, [name, easing, timing, delay]]) => {\n let value = `${style} ${timing || getTiming(name)}`;\n if (easing || delay) {\n value += ` ${easing || DEFAULT_EASING}`;\n }\n if (delay) {\n value += ` ${delay}`;\n }\n return value;\n })\n .join(', ');\n\n return { transition: result };\n}\n\ntransitionStyle.__lookupStyles = ['transition'];\n"],"mappings":"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"}
1
+ {"version":3,"file":"transition.js","names":[],"sources":["../../src/styles/transition.ts"],"sourcesContent":["import { parseStyle } from '../utils/styles';\n\nconst SECOND_FILL_COLOR_PROPERTY = '--tasty-second-fill-color';\n\nconst MAP: Record<string, string[]> = {\n fade: ['mask', 'mask-composite'],\n translate: ['transform', 'translate'],\n rotate: ['transform', 'rotate'],\n scale: ['transform', 'scale'],\n fill: ['background-color', 'background-image', SECOND_FILL_COLOR_PROPERTY],\n image: [\n 'background-image',\n 'background-position',\n 'background-size',\n 'background-repeat',\n 'background-attachment',\n 'background-origin',\n 'background-clip',\n SECOND_FILL_COLOR_PROPERTY,\n ],\n background: [\n 'background-color',\n 'background-image',\n 'background-position',\n 'background-size',\n 'background-repeat',\n 'background-attachment',\n 'background-origin',\n 'background-clip',\n SECOND_FILL_COLOR_PROPERTY,\n ],\n border: [\n 'border',\n 'border-top',\n 'border-right',\n 'border-bottom',\n 'border-left',\n ],\n filter: ['filter', 'backdrop-filter'],\n radius: ['border-radius'],\n shadow: ['box-shadow'],\n outline: ['outline', 'outline-offset'],\n preset: [\n 'font-size',\n 'line-height',\n 'letter-spacing',\n 'font-weight',\n 'font-style',\n ],\n text: ['font-weight', 'text-decoration-color'],\n color: ['color'],\n opacity: ['opacity'],\n theme: [\n 'color',\n 'background-color',\n 'background-image',\n 'box-shadow',\n 'border',\n 'border-radius',\n 'outline',\n 'opacity',\n SECOND_FILL_COLOR_PROPERTY,\n ],\n width: ['max-width', 'min-width', 'width'],\n height: ['max-height', 'min-height', 'height'],\n gap: ['gap', 'margin'],\n zIndex: ['z-index'],\n inset: ['inset', 'top', 'right', 'bottom', 'left'],\n};\n\nexport const DEFAULT_TIMING = 'var(--transition)';\nconst DEFAULT_EASING = 'linear';\n\nconst EASING_KEYWORDS = new Set([\n 'ease',\n 'ease-in',\n 'ease-out',\n 'ease-in-out',\n 'linear',\n 'step-start',\n 'step-end',\n]);\n\nfunction isEasing(token: string): boolean {\n return (\n EASING_KEYWORDS.has(token) ||\n token.startsWith('cubic-bezier(') ||\n token.startsWith('steps(') ||\n token.startsWith('linear(')\n );\n}\n\nfunction getTiming(name: string): string {\n const varName = name.startsWith('--')\n ? `${name}-transition`\n : `--${name}-transition`;\n return `var(${varName}, var(--transition))`;\n}\n\ntype TransitionEntry = [\n name: string,\n easing: string | undefined,\n timing: string | undefined,\n delay: string | undefined,\n];\n\nexport function transitionStyle({ transition }: { transition?: string }) {\n if (!transition) return;\n\n const processed = parseStyle(transition);\n const tokens: string[] = [];\n processed.groups.forEach((g, idx) => {\n tokens.push(...g.all);\n if (idx < processed.groups.length - 1) tokens.push(',');\n });\n\n if (tokens.length === 0) return;\n\n let tempTransition: string[] = [];\n const transitions: string[][] = [];\n\n tokens.forEach((token) => {\n if (token === ',') {\n if (tempTransition.length) {\n transitions.push(tempTransition);\n tempTransition = [];\n }\n } else {\n tempTransition.push(token);\n }\n });\n\n if (tempTransition.length) {\n transitions.push(tempTransition);\n }\n\n const map: Record<string, TransitionEntry> = {};\n\n transitions.forEach((transition) => {\n const name = transition[0];\n\n let timing: string | undefined;\n let easing: string | undefined;\n let delay: string | undefined;\n\n if (transition[1] && isEasing(transition[1])) {\n easing = transition[1];\n delay = transition[2];\n } else {\n timing = transition[1];\n easing = transition[2];\n delay = transition[3];\n }\n\n const styles = MAP[name] || [name];\n\n styles.forEach((style) => {\n map[style] = [name, easing, timing, delay];\n });\n });\n\n const result = Object.entries(map)\n .map(([style, [name, easing, timing, delay]]) => {\n let value = `${style} ${timing || getTiming(name)}`;\n if (easing || delay) {\n value += ` ${easing || DEFAULT_EASING}`;\n }\n if (delay) {\n value += ` ${delay}`;\n }\n return value;\n })\n .join(', ');\n\n return { transition: result };\n}\n\ntransitionStyle.__lookupStyles = ['transition'];\n"],"mappings":"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"}