@symbo.ls/scratch 3.5.1 → 3.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,6 +11,8 @@ Recevies a configuration and outputs the system of design related properties. It
11
11
  | `verbose` | `false` | Output the warning logs in console (only in `dev`, `test` enviroment) |
12
12
  | `useReset` | `true` | Apply CSS reset to the document |
13
13
  | `useVariable` | `true` | Output CSS variables in properties |
14
+ | `globalTheme` | `'auto'` | Theme mode: `'auto'` (system preference), `'dark'`, `'light'`, or any custom theme name |
15
+ | `useThemeSuffixedVars` | `false` | Also generate suffixed vars like `--theme-document-dark-background` |
14
16
 
15
17
  A design system configuration of the following systems:
16
18
 
@@ -28,11 +30,62 @@ set({
28
30
  font_family: {},
29
31
  timing: {},
30
32
  reset: {}
31
- }, {
33
+ }, {
32
34
  // options
33
35
  })
34
36
  ```
35
37
 
38
+ ## Theme System
39
+
40
+ Themes with `@dark`/`@light` (or custom `@ocean`, `@sunset`, etc.) variants automatically generate non-suffixed CSS variables that switch via CSS — no JavaScript re-renders needed.
41
+
42
+ ```javascript
43
+ set({
44
+ theme: {
45
+ document: {
46
+ '@dark': { color: 'white', background: 'black' },
47
+ '@light': { color: 'black', background: 'white' },
48
+ '@ocean': { color: 'white', background: '#0a2e4e' }
49
+ }
50
+ }
51
+ })
52
+ ```
53
+
54
+ Generated CSS:
55
+
56
+ ```css
57
+ /* System theme auto-switching (when no data-theme attribute is set) */
58
+ @media (prefers-color-scheme: dark) {
59
+ :root:not([data-theme]) { --theme-document-background: #000; --theme-document-color: #fff; }
60
+ }
61
+ @media (prefers-color-scheme: light) {
62
+ :root:not([data-theme]) { --theme-document-background: #fff; --theme-document-color: #000; }
63
+ }
64
+
65
+ /* Explicit theme forcing via data-theme attribute */
66
+ [data-theme="dark"] { --theme-document-background: #000; --theme-document-color: #fff; }
67
+ [data-theme="light"] { --theme-document-background: #fff; --theme-document-color: #000; }
68
+ [data-theme="ocean"] { --theme-document-background: #0a2e4e; --theme-document-color: #fff; }
69
+ ```
70
+
71
+ ### Theme switching
72
+
73
+ - **Auto** (default): system `prefers-color-scheme` drives dark/light switching
74
+ - **Force a theme**: set `data-theme` attribute on the root element — instant CSS switch, zero re-renders
75
+ - **Custom themes**: add any `@name` variant to your theme config, activate with `data-theme="name"`
76
+ - **Per-component override**: use `themeModifier` prop to force a specific scheme on individual components
77
+
78
+ ### `globalTheme` option
79
+
80
+ | Value | Behavior |
81
+ | --- | --- |
82
+ | `'auto'` (default) | `@dark`/`@light` use `prefers-color-scheme` media queries. Custom themes use `[data-theme]` selectors. |
83
+ | `'dark'` / `'light'` / `'custom'` | Non-suffixed vars are set directly in `:root` with the forced theme's values. |
84
+
85
+ ### `useThemeSuffixedVars` option
86
+
87
+ When `true`, also generates suffixed variables like `--theme-document-dark-background` alongside the non-suffixed `--theme-document-background`. Disabled by default to reduce CSS variable count.
88
+
36
89
  Read more at [docs](https://www.symbols.app/developersdesign-system)
37
90
 
38
91
  ### TODO:
@@ -29,6 +29,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  var factory_exports = {};
30
30
  __export(factory_exports, {
31
31
  CONFIG: () => CONFIG,
32
+ CSS_MEDIA_VARS: () => CSS_MEDIA_VARS,
32
33
  CSS_VARS: () => CSS_VARS,
33
34
  FACTORY: () => FACTORY,
34
35
  activateConfig: () => activateConfig,
@@ -39,7 +40,8 @@ module.exports = __toCommonJS(factory_exports);
39
40
  var import_utils = require("@domql/utils");
40
41
  var CONF = __toESM(require("./defaultConfig"), 1);
41
42
  const CSS_VARS = {};
42
- const _CONF = CONF.default || CONF;
43
+ const CSS_MEDIA_VARS = {};
44
+ const _CONF = CONF;
43
45
  const _confLower = {};
44
46
  for (const key in _CONF) {
45
47
  const lower = key.toLowerCase();
@@ -50,7 +52,9 @@ const CONFIG = {
50
52
  verbose: false,
51
53
  useVariable: true,
52
54
  useReset: true,
55
+ globalTheme: "auto",
53
56
  CSS_VARS,
57
+ CSS_MEDIA_VARS,
54
58
  ..._confLower
55
59
  };
56
60
  const cachedConfig = (0, import_utils.deepClone)(CONFIG);
package/dist/cjs/set.js CHANGED
@@ -98,11 +98,13 @@ const set = (recivedConfig, options = SET_OPTIONS) => {
98
98
  useDefaultConfig,
99
99
  SEMANTIC_ICONS,
100
100
  semantic_icons,
101
+ files,
101
102
  ...config
102
103
  } = recivedConfig;
103
104
  if (options.newConfig) {
104
105
  CONFIG = (0, import_factory.setActiveConfig)(options.newConfig);
105
106
  }
107
+ if (files !== void 0) CONFIG.files = files;
106
108
  if (verbose !== void 0) CONFIG.verbose = verbose;
107
109
  if (useVariable !== void 0) CONFIG.useVariable = useVariable;
108
110
  if (useReset !== void 0) CONFIG.useReset = useReset;
@@ -111,6 +113,7 @@ const set = (recivedConfig, options = SET_OPTIONS) => {
111
113
  if (useIconSprite !== void 0) CONFIG.useIconSprite = useIconSprite;
112
114
  if (useDocumentTheme !== void 0) CONFIG.useDocumentTheme = useDocumentTheme;
113
115
  if (globalTheme !== void 0) CONFIG.globalTheme = globalTheme;
116
+ if (recivedConfig.useThemeSuffixedVars !== void 0) CONFIG.useThemeSuffixedVars = recivedConfig.useThemeSuffixedVars;
114
117
  if (useDefaultConfig !== void 0) CONFIG.useDefaultConfig = useDefaultConfig;
115
118
  const _semanticIcons = SEMANTIC_ICONS || semantic_icons;
116
119
  if (_semanticIcons !== void 0) {
@@ -28,22 +28,25 @@ var import_smbls_utils = require("@symbo.ls/smbls-utils");
28
28
  var import_factory = require("../factory.js");
29
29
  var import_utils2 = require("../utils");
30
30
  const setFont = (val, key) => {
31
+ const CONFIG = (0, import_factory.getActiveConfig)();
31
32
  const CSSvar = `--font-${key}`;
32
33
  if (!val || (0, import_utils.isArray)(val) && !val[0]) return;
33
34
  let fontFace;
34
35
  if (val.isVariable) {
35
- if ((0, import_utils2.isGoogleFontsUrl)(val.url)) {
36
- fontFace = (0, import_utils2.setFontImport)(val.url);
36
+ const url = (0, import_utils2.resolveFileUrl)(val.url, CONFIG.files) || val.url;
37
+ if ((0, import_utils2.isGoogleFontsUrl)(url)) {
38
+ fontFace = (0, import_utils2.setFontImport)(url);
37
39
  } else {
38
- fontFace = (0, import_utils2.setCustomFontMedia)(key, val.url, val.fontWeight, {
40
+ fontFace = (0, import_utils2.setCustomFontMedia)(key, url, val.fontWeight, {
39
41
  fontStretch: val.fontStretch,
40
42
  fontDisplay: val.fontDisplay || "swap"
41
43
  });
42
44
  }
43
45
  } else if (val[0]) {
44
- fontFace = (0, import_utils2.getFontFaceEach)(key, val);
46
+ fontFace = (0, import_utils2.getFontFaceEach)(key, val, CONFIG.files);
45
47
  } else {
46
- fontFace = (0, import_utils2.setCustomFontMedia)(key, val.url);
48
+ const url = (0, import_utils2.resolveFileUrl)(val.url, CONFIG.files) || val.url;
49
+ fontFace = (0, import_utils2.setCustomFontMedia)(key, url);
47
50
  }
48
51
  return { var: CSSvar, value: val, fontFace };
49
52
  };
@@ -32,7 +32,7 @@ const applyReset = (reset = {}) => {
32
32
  const configReset = RESET;
33
33
  const configTemplates = TYPOGRAPHY.templates;
34
34
  configReset.body = {
35
- ...CONFIG.useDocumentTheme ? (0, import_theme.getMediaTheme)("document", `@${CONFIG.globalTheme}`) : {},
35
+ ...CONFIG.useDocumentTheme ? (0, import_theme.getMediaTheme)("document") : {},
36
36
  ...configTemplates.body
37
37
  };
38
38
  configReset.h1 = configTemplates.h1;
@@ -43,7 +43,7 @@ const applyReset = (reset = {}) => {
43
43
  configReset.h6 = configTemplates.h6;
44
44
  }
45
45
  const { body, ...templates } = TYPOGRAPHY.templates;
46
- const globalTheme = CONFIG.useDocumentTheme ? (0, import_theme.getMediaTheme)("document", `@${CONFIG.globalTheme}`) : {};
46
+ const globalTheme = CONFIG.useDocumentTheme ? (0, import_theme.getMediaTheme)("document") : {};
47
47
  if (RESET.html) (0, import_utils.overwriteDeep)(RESET.html, globalTheme);
48
48
  return (0, import_utils.deepMerge)((0, import_utils.merge)(RESET, reset), {
49
49
  html: {
@@ -141,24 +141,101 @@ const keySetters = {
141
141
  ":": (theme, value) => setSelectors(theme, value),
142
142
  ".": (theme, value) => setHelpers(theme, value)
143
143
  };
144
+ const generateAutoVars = (schemes, varPrefix, CONFIG) => {
145
+ const { CSS_VARS } = CONFIG;
146
+ if (!CONFIG.CSS_MEDIA_VARS) CONFIG.CSS_MEDIA_VARS = {};
147
+ const MEDIA_VARS = CONFIG.CSS_MEDIA_VARS;
148
+ const globalTheme = CONFIG.globalTheme !== void 0 ? CONFIG.globalTheme : "auto";
149
+ const result = {};
150
+ const allKeys = /* @__PURE__ */ new Set();
151
+ for (const scheme in schemes) {
152
+ if (schemes[scheme]) for (const k of Object.keys(schemes[scheme])) allKeys.add(k);
153
+ }
154
+ for (const param of allKeys) {
155
+ const symb = param.slice(0, 1);
156
+ const hasObject = Object.values(schemes).some((s) => (0, import_utils.isObjectLike)(s?.[param]));
157
+ if (symb === "." && hasObject) {
158
+ const helperName = param.slice(1);
159
+ const subSchemes = {};
160
+ for (const scheme in schemes) {
161
+ if ((0, import_utils.isObjectLike)(schemes[scheme]?.[param])) subSchemes[scheme] = schemes[scheme][param];
162
+ }
163
+ result[param] = generateAutoVars(subSchemes, `${varPrefix}-${helperName}`, CONFIG);
164
+ } else if (symb === ":" && hasObject) {
165
+ const pseudoName = param.replace(/^:+/, "");
166
+ const subSchemes = {};
167
+ for (const scheme in schemes) {
168
+ if ((0, import_utils.isObjectLike)(schemes[scheme]?.[param])) subSchemes[scheme] = schemes[scheme][param];
169
+ }
170
+ result[param] = generateAutoVars(subSchemes, `${varPrefix}-${pseudoName}`, CONFIG);
171
+ } else if (symb !== "@" && symb !== "." && symb !== ":") {
172
+ const autoVar = `--theme-${varPrefix}-${param}`;
173
+ if (globalTheme === "auto") {
174
+ for (const scheme in schemes) {
175
+ const val = schemes[scheme]?.[param];
176
+ if (val === void 0) continue;
177
+ const color = (0, import_color.getColor)(val, `@${scheme}`);
178
+ if (color === void 0) continue;
179
+ const selector = `[data-theme="${scheme}"]`;
180
+ if (!MEDIA_VARS[selector]) MEDIA_VARS[selector] = {};
181
+ MEDIA_VARS[selector][autoVar] = color;
182
+ if (scheme === "dark" || scheme === "light") {
183
+ const mq = `@media (prefers-color-scheme: ${scheme})`;
184
+ if (!MEDIA_VARS[mq]) MEDIA_VARS[mq] = {};
185
+ MEDIA_VARS[mq][autoVar] = color;
186
+ }
187
+ }
188
+ } else {
189
+ const forced = String(globalTheme).replace(/^'|'$/g, "");
190
+ const source = schemes[forced]?.[param];
191
+ if (source !== void 0) {
192
+ const color = (0, import_color.getColor)(source, `@${forced}`);
193
+ if (color !== void 0) CSS_VARS[autoVar] = color;
194
+ }
195
+ }
196
+ result[param] = `var(${autoVar})`;
197
+ result[`.${param}`] = { [param]: result[param] };
198
+ }
199
+ }
200
+ if (result.background || result.color || result.backgroundColor) {
201
+ result[".inversed"] = {
202
+ color: result.background || result.backgroundColor,
203
+ background: result.color
204
+ };
205
+ }
206
+ return result;
207
+ };
144
208
  const setMediaTheme = (val, key, suffix, prefers) => {
145
209
  const CONFIG = (0, import_factory.getActiveConfig)();
146
210
  const { CSS_VARS } = CONFIG;
147
211
  const theme = { value: val };
212
+ const isTopLevel = !suffix && !prefers;
148
213
  if ((0, import_utils.isObjectLike)(val)) {
214
+ if (isTopLevel && CONFIG.useVariable) {
215
+ const schemes = {};
216
+ for (const param in val) {
217
+ if (param.startsWith("@") && (0, import_utils.isObjectLike)(val[param])) {
218
+ schemes[param.slice(1)] = val[param];
219
+ }
220
+ }
221
+ if (Object.keys(schemes).length) {
222
+ const autoResult = generateAutoVars(schemes, key, CONFIG);
223
+ Object.assign(theme, autoResult);
224
+ }
225
+ }
149
226
  for (const param in val) {
150
227
  const symb = param.slice(0, 1);
151
228
  const value = val[param];
152
229
  if (symb === "@" || symb === ":" || symb === ".") {
153
230
  const hasPrefers = symb === "@" && param;
154
231
  theme[param] = setMediaTheme(value, key, param, prefers || hasPrefers);
155
- } else {
232
+ } else if (!isTopLevel) {
156
233
  const color = (0, import_color.getColor)(value, prefers);
157
234
  const metaSuffixes = [...new Set([prefers, suffix].filter((v) => v).map((v) => v.slice(1)))];
158
235
  const varmetaSuffixName = metaSuffixes.length ? "-" + metaSuffixes.join("-") : "";
159
236
  const CSSVar = `--theme-${key}${varmetaSuffixName}-${param}`;
160
237
  if (CONFIG.useVariable) {
161
- CSS_VARS[CSSVar] = color;
238
+ if (CONFIG.useThemeSuffixedVars) CSS_VARS[CSSVar] = color;
162
239
  theme[param] = `var(${CSSVar})`;
163
240
  } else {
164
241
  theme[param] = color;
@@ -166,7 +243,7 @@ const setMediaTheme = (val, key, suffix, prefers) => {
166
243
  theme[`.${param}`] = { [param]: theme[param] };
167
244
  }
168
245
  }
169
- if (theme.background || theme.color || theme.backgroundColor) {
246
+ if (!theme[".inversed"] && (theme.background || theme.color || theme.backgroundColor)) {
170
247
  theme[".inversed"] = {
171
248
  color: theme.background || theme.backgroundColor,
172
249
  background: theme.color
@@ -188,9 +265,7 @@ const recursiveTheme = (val) => {
188
265
  const symb = param.slice(0, 1);
189
266
  if ((0, import_utils.isObjectLike)(val[param])) {
190
267
  if (symb === "@") {
191
- const query = CONFIG.MEDIA[param.slice(1)];
192
- const media = "@media " + (query === "print" ? `${query}` : `screen and ${query}`);
193
- obj[media] = recursiveTheme(val[param]);
268
+ continue;
194
269
  } else if (symb === ":") {
195
270
  obj[`&${param}`] = recursiveTheme(val[param]);
196
271
  }
@@ -226,8 +301,10 @@ const getMediaTheme = (value, modifier) => {
226
301
  }
227
302
  const [themeName, ...themeModifiers] = (0, import_utils.isArray)(value) ? value : value.split(" ");
228
303
  let themeValue = activeConfig.THEME[themeName];
229
- if (themeValue && (themeModifiers || modifier)) {
230
- themeValue = findModifier(themeValue, themeModifiers.length ? themeModifiers : modifier);
304
+ if (themeValue && themeModifiers.length) {
305
+ themeValue = findModifier(themeValue, themeModifiers);
306
+ } else if (themeValue && modifier) {
307
+ themeValue = findModifier(themeValue, modifier);
231
308
  }
232
309
  const resolvedTheme = recursiveTheme(themeValue);
233
310
  return resolvedTheme;
@@ -200,7 +200,7 @@ function transformSize(propertyName, val, props = {}, opts = {}) {
200
200
  }
201
201
  const shouldScaleBoxSize = props.scaleBoxSize;
202
202
  const isBoxSize = (0, import_system.checkIfBoxSize)(propertyName);
203
- if (!shouldScaleBoxSize && isBoxSize) {
203
+ if (!shouldScaleBoxSize && isBoxSize && !opts.ratio) {
204
204
  value = (0, import_system.splitSpacedValue)(value);
205
205
  }
206
206
  }
@@ -25,12 +25,24 @@ __export(font_exports, {
25
25
  getFontFaceString: () => getFontFaceString,
26
26
  getFontFormat: () => getFontFormat,
27
27
  isGoogleFontsUrl: () => isGoogleFontsUrl,
28
+ resolveFileUrl: () => resolveFileUrl,
28
29
  setCustomFont: () => setCustomFont,
29
30
  setCustomFontMedia: () => setCustomFontMedia,
30
31
  setFontImport: () => setFontImport,
31
32
  setInCustomFontMedia: () => setInCustomFontMedia
32
33
  });
33
34
  module.exports = __toCommonJS(font_exports);
35
+ const resolveFileUrl = (url, files) => {
36
+ if (!url || !files) return null;
37
+ try {
38
+ new URL(url);
39
+ return null;
40
+ } catch (e) {
41
+ }
42
+ const file = files[url];
43
+ if (file) return file.content && file.content.src;
44
+ return null;
45
+ };
34
46
  const getDefaultOrFirstKey = (LIBRARY, key) => {
35
47
  if (LIBRARY[key]) return LIBRARY[key].value;
36
48
  if (LIBRARY.default) return LIBRARY[LIBRARY.default].value;
@@ -58,32 +70,35 @@ const setCustomFont = (name, url, weight, options = {}) => {
58
70
  };
59
71
  const setCustomFontMedia = (name, url, weight, options) => `@font-face {${setCustomFont(name, url, weight, options)}
60
72
  }`;
61
- const getFontFaceEach = (name, weights) => {
73
+ const getFontFaceEach = (name, weights, files) => {
62
74
  const keys = Object.keys(weights);
63
75
  return keys.map((key) => {
64
76
  const { url, fontWeight } = weights[key];
65
- return setCustomFont(name, url, fontWeight);
77
+ const resolvedUrl = resolveFileUrl(url, files) || url;
78
+ return setCustomFont(name, resolvedUrl, fontWeight);
66
79
  });
67
80
  };
68
81
  const getFontFace = (LIBRARY) => {
69
82
  const keys = Object.keys(LIBRARY);
70
83
  return keys.map((key) => getFontFaceEach(key, LIBRARY[key].value));
71
84
  };
72
- const getFontFaceEachString = (name, weights) => {
85
+ const getFontFaceEachString = (name, weights, files) => {
73
86
  if (weights && weights.isVariable) {
74
- if (isGoogleFontsUrl(weights.url)) {
75
- return setFontImport(weights.url);
87
+ const url2 = resolveFileUrl(weights.url, files) || weights.url;
88
+ if (isGoogleFontsUrl(url2)) {
89
+ return setFontImport(url2);
76
90
  }
77
- return setCustomFontMedia(name, weights.url, weights.fontWeight, {
91
+ return setCustomFontMedia(name, url2, weights.fontWeight, {
78
92
  fontStretch: weights.fontStretch,
79
93
  fontDisplay: weights.fontDisplay || "swap"
80
94
  });
81
95
  }
82
96
  const isArr = weights[0];
83
- if (isArr) return getFontFaceEach(name, weights).map(setInCustomFontMedia);
84
- return setCustomFontMedia(name, weights.url);
97
+ if (isArr) return getFontFaceEach(name, weights, files).map(setInCustomFontMedia);
98
+ const url = resolveFileUrl(weights.url, files) || weights.url;
99
+ return setCustomFontMedia(name, url);
85
100
  };
86
- const getFontFaceString = (LIBRARY) => {
101
+ const getFontFaceString = (LIBRARY, files) => {
87
102
  const keys = Object.keys(LIBRARY);
88
- return keys.map((key) => getFontFaceEachString(key, LIBRARY[key].value));
103
+ return keys.map((key) => getFontFaceEachString(key, LIBRARY[key].value, files));
89
104
  };
@@ -6,7 +6,8 @@ import {
6
6
  } from "@domql/utils";
7
7
  import * as CONF from "./defaultConfig";
8
8
  const CSS_VARS = {};
9
- const _CONF = CONF.default || CONF;
9
+ const CSS_MEDIA_VARS = {};
10
+ const _CONF = CONF;
10
11
  const _confLower = {};
11
12
  for (const key in _CONF) {
12
13
  const lower = key.toLowerCase();
@@ -17,7 +18,9 @@ const CONFIG = {
17
18
  verbose: false,
18
19
  useVariable: true,
19
20
  useReset: true,
21
+ globalTheme: "auto",
20
22
  CSS_VARS,
23
+ CSS_MEDIA_VARS,
21
24
  ..._confLower
22
25
  };
23
26
  const cachedConfig = deepClone(CONFIG);
@@ -42,6 +45,7 @@ const setActiveConfig = (newConfig) => {
42
45
  };
43
46
  export {
44
47
  CONFIG,
48
+ CSS_MEDIA_VARS,
45
49
  CSS_VARS,
46
50
  FACTORY,
47
51
  activateConfig,
package/dist/esm/set.js CHANGED
@@ -86,11 +86,13 @@ const set = (recivedConfig, options = SET_OPTIONS) => {
86
86
  useDefaultConfig,
87
87
  SEMANTIC_ICONS,
88
88
  semantic_icons,
89
+ files,
89
90
  ...config
90
91
  } = recivedConfig;
91
92
  if (options.newConfig) {
92
93
  CONFIG = setActiveConfig(options.newConfig);
93
94
  }
95
+ if (files !== void 0) CONFIG.files = files;
94
96
  if (verbose !== void 0) CONFIG.verbose = verbose;
95
97
  if (useVariable !== void 0) CONFIG.useVariable = useVariable;
96
98
  if (useReset !== void 0) CONFIG.useReset = useReset;
@@ -99,6 +101,7 @@ const set = (recivedConfig, options = SET_OPTIONS) => {
99
101
  if (useIconSprite !== void 0) CONFIG.useIconSprite = useIconSprite;
100
102
  if (useDocumentTheme !== void 0) CONFIG.useDocumentTheme = useDocumentTheme;
101
103
  if (globalTheme !== void 0) CONFIG.globalTheme = globalTheme;
104
+ if (recivedConfig.useThemeSuffixedVars !== void 0) CONFIG.useThemeSuffixedVars = recivedConfig.useThemeSuffixedVars;
102
105
  if (useDefaultConfig !== void 0) CONFIG.useDefaultConfig = useDefaultConfig;
103
106
  const _semanticIcons = SEMANTIC_ICONS || semantic_icons;
104
107
  if (_semanticIcons !== void 0) {
@@ -6,25 +6,29 @@ import {
6
6
  getFontFaceEach,
7
7
  isGoogleFontsUrl,
8
8
  setCustomFontMedia,
9
- setFontImport
9
+ setFontImport,
10
+ resolveFileUrl
10
11
  } from "../utils";
11
12
  const setFont = (val, key) => {
13
+ const CONFIG = getActiveConfig();
12
14
  const CSSvar = `--font-${key}`;
13
15
  if (!val || isArray(val) && !val[0]) return;
14
16
  let fontFace;
15
17
  if (val.isVariable) {
16
- if (isGoogleFontsUrl(val.url)) {
17
- fontFace = setFontImport(val.url);
18
+ const url = resolveFileUrl(val.url, CONFIG.files) || val.url;
19
+ if (isGoogleFontsUrl(url)) {
20
+ fontFace = setFontImport(url);
18
21
  } else {
19
- fontFace = setCustomFontMedia(key, val.url, val.fontWeight, {
22
+ fontFace = setCustomFontMedia(key, url, val.fontWeight, {
20
23
  fontStretch: val.fontStretch,
21
24
  fontDisplay: val.fontDisplay || "swap"
22
25
  });
23
26
  }
24
27
  } else if (val[0]) {
25
- fontFace = getFontFaceEach(key, val);
28
+ fontFace = getFontFaceEach(key, val, CONFIG.files);
26
29
  } else {
27
- fontFace = setCustomFontMedia(key, val.url);
30
+ const url = resolveFileUrl(val.url, CONFIG.files) || val.url;
31
+ fontFace = setCustomFontMedia(key, url);
28
32
  }
29
33
  return { var: CSSvar, value: val, fontFace };
30
34
  };
@@ -9,7 +9,7 @@ const applyReset = (reset = {}) => {
9
9
  const configReset = RESET;
10
10
  const configTemplates = TYPOGRAPHY.templates;
11
11
  configReset.body = {
12
- ...CONFIG.useDocumentTheme ? getMediaTheme("document", `@${CONFIG.globalTheme}`) : {},
12
+ ...CONFIG.useDocumentTheme ? getMediaTheme("document") : {},
13
13
  ...configTemplates.body
14
14
  };
15
15
  configReset.h1 = configTemplates.h1;
@@ -20,7 +20,7 @@ const applyReset = (reset = {}) => {
20
20
  configReset.h6 = configTemplates.h6;
21
21
  }
22
22
  const { body, ...templates } = TYPOGRAPHY.templates;
23
- const globalTheme = CONFIG.useDocumentTheme ? getMediaTheme("document", `@${CONFIG.globalTheme}`) : {};
23
+ const globalTheme = CONFIG.useDocumentTheme ? getMediaTheme("document") : {};
24
24
  if (RESET.html) overwriteDeep(RESET.html, globalTheme);
25
25
  return deepMerge(merge(RESET, reset), {
26
26
  html: {
@@ -120,24 +120,101 @@ const keySetters = {
120
120
  ":": (theme, value) => setSelectors(theme, value),
121
121
  ".": (theme, value) => setHelpers(theme, value)
122
122
  };
123
+ const generateAutoVars = (schemes, varPrefix, CONFIG) => {
124
+ const { CSS_VARS } = CONFIG;
125
+ if (!CONFIG.CSS_MEDIA_VARS) CONFIG.CSS_MEDIA_VARS = {};
126
+ const MEDIA_VARS = CONFIG.CSS_MEDIA_VARS;
127
+ const globalTheme = CONFIG.globalTheme !== void 0 ? CONFIG.globalTheme : "auto";
128
+ const result = {};
129
+ const allKeys = /* @__PURE__ */ new Set();
130
+ for (const scheme in schemes) {
131
+ if (schemes[scheme]) for (const k of Object.keys(schemes[scheme])) allKeys.add(k);
132
+ }
133
+ for (const param of allKeys) {
134
+ const symb = param.slice(0, 1);
135
+ const hasObject = Object.values(schemes).some((s) => isObjectLike(s?.[param]));
136
+ if (symb === "." && hasObject) {
137
+ const helperName = param.slice(1);
138
+ const subSchemes = {};
139
+ for (const scheme in schemes) {
140
+ if (isObjectLike(schemes[scheme]?.[param])) subSchemes[scheme] = schemes[scheme][param];
141
+ }
142
+ result[param] = generateAutoVars(subSchemes, `${varPrefix}-${helperName}`, CONFIG);
143
+ } else if (symb === ":" && hasObject) {
144
+ const pseudoName = param.replace(/^:+/, "");
145
+ const subSchemes = {};
146
+ for (const scheme in schemes) {
147
+ if (isObjectLike(schemes[scheme]?.[param])) subSchemes[scheme] = schemes[scheme][param];
148
+ }
149
+ result[param] = generateAutoVars(subSchemes, `${varPrefix}-${pseudoName}`, CONFIG);
150
+ } else if (symb !== "@" && symb !== "." && symb !== ":") {
151
+ const autoVar = `--theme-${varPrefix}-${param}`;
152
+ if (globalTheme === "auto") {
153
+ for (const scheme in schemes) {
154
+ const val = schemes[scheme]?.[param];
155
+ if (val === void 0) continue;
156
+ const color = getColor(val, `@${scheme}`);
157
+ if (color === void 0) continue;
158
+ const selector = `[data-theme="${scheme}"]`;
159
+ if (!MEDIA_VARS[selector]) MEDIA_VARS[selector] = {};
160
+ MEDIA_VARS[selector][autoVar] = color;
161
+ if (scheme === "dark" || scheme === "light") {
162
+ const mq = `@media (prefers-color-scheme: ${scheme})`;
163
+ if (!MEDIA_VARS[mq]) MEDIA_VARS[mq] = {};
164
+ MEDIA_VARS[mq][autoVar] = color;
165
+ }
166
+ }
167
+ } else {
168
+ const forced = String(globalTheme).replace(/^'|'$/g, "");
169
+ const source = schemes[forced]?.[param];
170
+ if (source !== void 0) {
171
+ const color = getColor(source, `@${forced}`);
172
+ if (color !== void 0) CSS_VARS[autoVar] = color;
173
+ }
174
+ }
175
+ result[param] = `var(${autoVar})`;
176
+ result[`.${param}`] = { [param]: result[param] };
177
+ }
178
+ }
179
+ if (result.background || result.color || result.backgroundColor) {
180
+ result[".inversed"] = {
181
+ color: result.background || result.backgroundColor,
182
+ background: result.color
183
+ };
184
+ }
185
+ return result;
186
+ };
123
187
  const setMediaTheme = (val, key, suffix, prefers) => {
124
188
  const CONFIG = getActiveConfig();
125
189
  const { CSS_VARS } = CONFIG;
126
190
  const theme = { value: val };
191
+ const isTopLevel = !suffix && !prefers;
127
192
  if (isObjectLike(val)) {
193
+ if (isTopLevel && CONFIG.useVariable) {
194
+ const schemes = {};
195
+ for (const param in val) {
196
+ if (param.startsWith("@") && isObjectLike(val[param])) {
197
+ schemes[param.slice(1)] = val[param];
198
+ }
199
+ }
200
+ if (Object.keys(schemes).length) {
201
+ const autoResult = generateAutoVars(schemes, key, CONFIG);
202
+ Object.assign(theme, autoResult);
203
+ }
204
+ }
128
205
  for (const param in val) {
129
206
  const symb = param.slice(0, 1);
130
207
  const value = val[param];
131
208
  if (symb === "@" || symb === ":" || symb === ".") {
132
209
  const hasPrefers = symb === "@" && param;
133
210
  theme[param] = setMediaTheme(value, key, param, prefers || hasPrefers);
134
- } else {
211
+ } else if (!isTopLevel) {
135
212
  const color = getColor(value, prefers);
136
213
  const metaSuffixes = [...new Set([prefers, suffix].filter((v) => v).map((v) => v.slice(1)))];
137
214
  const varmetaSuffixName = metaSuffixes.length ? "-" + metaSuffixes.join("-") : "";
138
215
  const CSSVar = `--theme-${key}${varmetaSuffixName}-${param}`;
139
216
  if (CONFIG.useVariable) {
140
- CSS_VARS[CSSVar] = color;
217
+ if (CONFIG.useThemeSuffixedVars) CSS_VARS[CSSVar] = color;
141
218
  theme[param] = `var(${CSSVar})`;
142
219
  } else {
143
220
  theme[param] = color;
@@ -145,7 +222,7 @@ const setMediaTheme = (val, key, suffix, prefers) => {
145
222
  theme[`.${param}`] = { [param]: theme[param] };
146
223
  }
147
224
  }
148
- if (theme.background || theme.color || theme.backgroundColor) {
225
+ if (!theme[".inversed"] && (theme.background || theme.color || theme.backgroundColor)) {
149
226
  theme[".inversed"] = {
150
227
  color: theme.background || theme.backgroundColor,
151
228
  background: theme.color
@@ -167,9 +244,7 @@ const recursiveTheme = (val) => {
167
244
  const symb = param.slice(0, 1);
168
245
  if (isObjectLike(val[param])) {
169
246
  if (symb === "@") {
170
- const query = CONFIG.MEDIA[param.slice(1)];
171
- const media = "@media " + (query === "print" ? `${query}` : `screen and ${query}`);
172
- obj[media] = recursiveTheme(val[param]);
247
+ continue;
173
248
  } else if (symb === ":") {
174
249
  obj[`&${param}`] = recursiveTheme(val[param]);
175
250
  }
@@ -205,8 +280,10 @@ const getMediaTheme = (value, modifier) => {
205
280
  }
206
281
  const [themeName, ...themeModifiers] = isArray(value) ? value : value.split(" ");
207
282
  let themeValue = activeConfig.THEME[themeName];
208
- if (themeValue && (themeModifiers || modifier)) {
209
- themeValue = findModifier(themeValue, themeModifiers.length ? themeModifiers : modifier);
283
+ if (themeValue && themeModifiers.length) {
284
+ themeValue = findModifier(themeValue, themeModifiers);
285
+ } else if (themeValue && modifier) {
286
+ themeValue = findModifier(themeValue, modifier);
210
287
  }
211
288
  const resolvedTheme = recursiveTheme(themeValue);
212
289
  return resolvedTheme;
@@ -182,7 +182,7 @@ function transformSize(propertyName, val, props = {}, opts = {}) {
182
182
  }
183
183
  const shouldScaleBoxSize = props.scaleBoxSize;
184
184
  const isBoxSize = checkIfBoxSize(propertyName);
185
- if (!shouldScaleBoxSize && isBoxSize) {
185
+ if (!shouldScaleBoxSize && isBoxSize && !opts.ratio) {
186
186
  value = splitSpacedValue(value);
187
187
  }
188
188
  }