@salty-css/core 0.1.0-alpha.3 → 0.1.0-alpha.30

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 (77) hide show
  1. package/README.md +209 -0
  2. package/astro-component-5hrNTCJ5.js +4 -0
  3. package/astro-component-Dj3enX6K.cjs +4 -0
  4. package/bin/commands/build.d.ts +2 -0
  5. package/bin/commands/generate.d.ts +2 -0
  6. package/bin/commands/init.d.ts +2 -0
  7. package/bin/commands/update.d.ts +2 -0
  8. package/bin/commands/version.d.ts +2 -0
  9. package/bin/confirm-install.d.ts +34 -0
  10. package/bin/context.d.ts +22 -0
  11. package/bin/detection/css-file.d.ts +5 -0
  12. package/bin/frameworks/astro.d.ts +4 -0
  13. package/bin/frameworks/index.d.ts +13 -0
  14. package/bin/frameworks/react.d.ts +2 -0
  15. package/bin/frameworks/types.d.ts +27 -0
  16. package/bin/integrations/astro.d.ts +11 -0
  17. package/bin/integrations/eslint.d.ts +6 -0
  18. package/bin/integrations/index.d.ts +21 -0
  19. package/bin/integrations/next.d.ts +9 -0
  20. package/bin/integrations/types.d.ts +29 -0
  21. package/bin/integrations/vite.d.ts +8 -0
  22. package/bin/main.cjs +653 -336
  23. package/bin/main.d.ts +8 -0
  24. package/bin/main.js +653 -336
  25. package/bin/package-json.d.ts +21 -0
  26. package/bin/saltyrc.d.ts +31 -0
  27. package/bin/templates.d.ts +14 -0
  28. package/{class-name-generator-YeSQe_Ik.js → class-name-generator-B0WkxoIg.js} +17 -2
  29. package/{class-name-generator-B2Pb2obX.cjs → class-name-generator-BEOEMEKX.cjs} +17 -2
  30. package/compiler/resolve-import.d.ts +17 -0
  31. package/compiler/salty-compiler.cjs +131 -30
  32. package/compiler/salty-compiler.d.ts +8 -1
  33. package/compiler/salty-compiler.js +133 -31
  34. package/config/index.cjs +4 -0
  35. package/config/index.js +5 -1
  36. package/css/dynamic-styles.cjs +15 -0
  37. package/css/dynamic-styles.d.ts +10 -0
  38. package/css/dynamic-styles.js +15 -0
  39. package/css/index.cjs +3 -0
  40. package/css/index.d.ts +1 -0
  41. package/css/index.js +3 -0
  42. package/css/keyframes.cjs +1 -1
  43. package/css/keyframes.js +1 -1
  44. package/factories/define-font.d.ts +28 -0
  45. package/factories/define-import.d.ts +14 -0
  46. package/factories/index.cjs +141 -0
  47. package/factories/index.d.ts +2 -0
  48. package/factories/index.js +141 -0
  49. package/generators/index.cjs +1 -1
  50. package/generators/index.js +2 -2
  51. package/instances/classname-instance.cjs +1 -1
  52. package/instances/classname-instance.js +1 -1
  53. package/package.json +5 -1
  54. package/parse-styles-BBJ3PWyV.js +514 -0
  55. package/parse-styles-lOMGe_c5.cjs +513 -0
  56. package/parsers/index.cjs +93 -3
  57. package/parsers/index.d.ts +1 -0
  58. package/parsers/index.js +97 -7
  59. package/parsers/parse-templates.d.ts +10 -0
  60. package/parsers/parser-regexes.d.ts +3 -0
  61. package/parsers/resolve-template-variants.d.ts +21 -0
  62. package/parsers/strict.d.ts +2 -0
  63. package/runtime/index.cjs +1 -1
  64. package/runtime/index.js +1 -1
  65. package/{salty.config-cqavVm2t.cjs → salty.config-DogY_sSQ.cjs} +1 -1
  66. package/salty.config-GV37Q-D2.js +4 -0
  67. package/styled-file-BzmB9_Ez.cjs +12 -0
  68. package/{react-styled-file-U02jek-B.cjs → styled-file-CPd_rTW2.cjs} +2 -2
  69. package/{react-styled-file-B99mwk0w.js → styled-file-Cda3EeR6.js} +2 -2
  70. package/styled-file-DLcgYmGN.js +12 -0
  71. package/types/config-types.d.ts +42 -2
  72. package/types/font-types.d.ts +53 -0
  73. package/{react-vanilla-file-D9px70iK.js → vanilla-file-1kOqbCIM.js} +2 -2
  74. package/{react-vanilla-file-Bj6XC8GS.cjs → vanilla-file-r0fp2q_m.cjs} +2 -2
  75. package/parse-styles-BTIoYnBr.js +0 -232
  76. package/parse-styles-CA3TP5n1.cjs +0 -231
  77. package/salty.config-DjosWdPw.js +0 -4
@@ -2,19 +2,20 @@ var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
  import * as esbuild from "esbuild";
5
- import { join, parse } from "path";
5
+ import { resolve, dirname, relative, join, basename, parse } from "path";
6
6
  import { createLogger, transports, format } from "winston";
7
7
  import { readFile } from "fs/promises";
8
- import { readFileSync, existsSync, mkdirSync, statSync, readdirSync, writeFileSync } from "fs";
8
+ import { existsSync, mkdirSync, copyFileSync, readFileSync, statSync, readdirSync, writeFileSync } from "fs";
9
9
  import { execSync } from "child_process";
10
10
  import { isSaltyFile, resolveExportValue, getCorePackageRoot, saltyFileExtensions } from "./helpers.js";
11
- import { d as defineTemplates } from "../define-templates-CVhhgPnd.js";
12
11
  import { d as dashCase } from "../dash-case-DblXvymC.js";
13
12
  import { t as toHash } from "../to-hash-DAN2LcHK.js";
14
- import { p as parseAndJoinStyles, b as parseVariableTokens } from "../parse-styles-BTIoYnBr.js";
13
+ import { d as defineTemplates } from "../define-templates-CVhhgPnd.js";
14
+ import { createRequire } from "module";
15
+ import { p as parseAndJoinStyles, c as parseVariableTokens } from "../parse-styles-BBJ3PWyV.js";
15
16
  import { mergeObjects, mergeFactories } from "../css/merge.js";
16
- import { getPackageJson } from "./get-files.js";
17
- import { parseTemplates, getTemplateTypes } from "../parsers/index.js";
17
+ import { parseTemplates, getTemplateTypes, getTemplateVariantMaps } from "../parsers/index.js";
18
+ import { detectCurrentModuleType } from "../util/module-type";
18
19
  import console from "console";
19
20
  const logger = createLogger({
20
21
  level: "debug",
@@ -24,19 +25,53 @@ const logger = createLogger({
24
25
  const logError = (message) => {
25
26
  logger.error(message);
26
27
  };
27
- const readPackageJsonModule = async (dirname) => {
28
- const packageJsonContent = await getPackageJson(dirname);
29
- if (!packageJsonContent) return void 0;
30
- return packageJsonContent.type;
28
+ const EXTERNAL_URL = /^(?:[a-z][a-z0-9+.-]*:)?\/\//i;
29
+ const normaliseSpec = (spec) => {
30
+ if (typeof spec === "string") return { url: spec };
31
+ return spec;
32
+ };
33
+ const ensureRelativePrefix = (path) => {
34
+ if (path.startsWith(".") || path.startsWith("/")) return path;
35
+ return `./${path}`;
36
+ };
37
+ const toPosix = (path) => path.split("\\").join("/");
38
+ const defaultResolveModule = (specifier, sourceFile) => {
39
+ return createRequire(sourceFile).resolve(specifier);
40
+ };
41
+ const defaultCopyAsset = (from, to) => {
42
+ const dir = dirname(to);
43
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
44
+ copyFileSync(from, to);
31
45
  };
32
- let cachedModuleType;
33
- const detectCurrentModuleType = async (dirname) => {
34
- if (cachedModuleType) return cachedModuleType;
35
- const packageJsonModule = await readPackageJsonModule(dirname);
36
- if (packageJsonModule === "module") cachedModuleType = "esm";
37
- else if (packageJsonModule === "commonjs") cachedModuleType = "cjs";
38
- else if (import.meta.url.endsWith(".cjs")) cachedModuleType = "cjs";
39
- return cachedModuleType || "esm";
46
+ const buildRule = (url, { media, supports }) => {
47
+ let rule = `@import url('${url}')`;
48
+ if (supports) rule += ` supports(${supports})`;
49
+ if (media) rule += ` ${media}`;
50
+ return `${rule};`;
51
+ };
52
+ const resolveImport = (spec, sourceFile, destDir, options = {}) => {
53
+ const opts = normaliseSpec(spec);
54
+ const { url } = opts;
55
+ const resolveModule = options.resolveModule ?? defaultResolveModule;
56
+ const copyAsset = options.copyAsset ?? defaultCopyAsset;
57
+ if (EXTERNAL_URL.test(url)) {
58
+ return { rule: buildRule(url, opts) };
59
+ }
60
+ if (url.startsWith("/")) {
61
+ return { rule: buildRule(url, opts) };
62
+ }
63
+ if (url.startsWith("./") || url.startsWith("../")) {
64
+ const absolute2 = resolve(dirname(sourceFile), url);
65
+ const fromImportsFile = relative(join(destDir, "css"), absolute2);
66
+ return { rule: buildRule(ensureRelativePrefix(toPosix(fromImportsFile)), opts) };
67
+ }
68
+ const specifier = url.startsWith("~") ? url.slice(1) : url;
69
+ const absolute = resolveModule(specifier, sourceFile);
70
+ const hash = toHash(absolute, 6);
71
+ const fileName = `${hash}-${basename(absolute)}`;
72
+ const destPath = join(destDir, "imports", fileName);
73
+ copyAsset(absolute, destPath);
74
+ return { rule: buildRule(`../imports/${fileName}`, opts) };
40
75
  };
41
76
  function dotCase(str) {
42
77
  if (!str) return "";
@@ -91,7 +126,7 @@ const saltyReset = {
91
126
  }
92
127
  };
93
128
  class SaltyCompiler {
94
- constructor(projectRootDir) {
129
+ constructor(projectRootDir, options = {}) {
95
130
  __publicField(this, "importFile", (path) => {
96
131
  const now = Date.now();
97
132
  return import(
@@ -121,10 +156,10 @@ class SaltyCompiler {
121
156
  * Get the project configuration from the .saltyrc.json file based on the current directory.
122
157
  * If no specific project configuration is found, it falls back to the default project.
123
158
  */
124
- __publicField(this, "getRCProjectConfig", async (dirname) => {
159
+ __publicField(this, "getRCProjectConfig", async (dirname2) => {
125
160
  var _a, _b;
126
- const rcFile = await this.readRCFile(dirname);
127
- const projectConfig = (_a = rcFile.projects) == null ? void 0 : _a.find((project) => dirname.endsWith(project.dir || ""));
161
+ const rcFile = await this.readRCFile(dirname2);
162
+ const projectConfig = (_a = rcFile.projects) == null ? void 0 : _a.find((project) => dirname2.endsWith(project.dir || ""));
128
163
  if (!projectConfig) return (_b = rcFile.projects) == null ? void 0 : _b.find((project) => project.dir === rcFile.defaultProject);
129
164
  return projectConfig;
130
165
  });
@@ -213,6 +248,7 @@ ${currentFile}`;
213
248
  mkdirSync(join(destDir, "types"));
214
249
  mkdirSync(join(destDir, "js"));
215
250
  mkdirSync(join(destDir, "cache"));
251
+ mkdirSync(join(destDir, "imports"));
216
252
  };
217
253
  if (clean) clearDistDir();
218
254
  const files = /* @__PURE__ */ new Set();
@@ -328,7 +364,7 @@ ${currentFile}`;
328
364
  });
329
365
  }
330
366
  const otherGlobalCssFiles = globalCssFiles.map((file) => `@import url('./css/${file}');`).join("\n");
331
- const globalCssFilenames = ["_variables.css", "_reset.css", "_global.css", "_templates.css"];
367
+ const globalCssFilenames = ["_imports.css", "_variables.css", "_reset.css", "_global.css", "_templates.css", "_fonts.css"];
332
368
  const importsWithData = globalCssFilenames.filter((file) => {
333
369
  try {
334
370
  const data = readFileSync(join(destDir, "css", file), "utf8");
@@ -337,9 +373,12 @@ ${currentFile}`;
337
373
  return false;
338
374
  }
339
375
  });
340
- const globalImports = importsWithData.map((file) => `@import url('./css/${file}');`);
376
+ const globalImports = importsWithData.map((file) => {
377
+ const layerSuffix = file === "_imports.css" ? " layer(imports)" : "";
378
+ return `@import url('./css/${file}')${layerSuffix};`;
379
+ });
341
380
  const generatorText = "/*!\n * Generated with Salty CSS (https://salty-css.dev)\n * Do not edit this file directly\n */\n";
342
- let cssContent = `${generatorText}@layer reset, global, templates, l0, l1, l2, l3, l4, l5, l6, l7, l8;
381
+ let cssContent = `${generatorText}@layer imports, reset, global, templates, fonts, l0, l1, l2, l3, l4, l5, l6, l7, l8;
343
382
 
344
383
  ${globalImports.join(
345
384
  "\n"
@@ -385,7 +424,9 @@ ${css}
385
424
  mediaQueries: [],
386
425
  globalStyles: [],
387
426
  variables: [],
388
- templates: []
427
+ templates: [],
428
+ imports: [],
429
+ fonts: []
389
430
  };
390
431
  await Promise.all(
391
432
  [...configFiles].map(async (src) => {
@@ -395,6 +436,8 @@ ${css}
395
436
  else if (value.isGlobalDefine) generationResults.globalStyles.push(value);
396
437
  else if (value.isDefineVariables) generationResults.variables.push(value);
397
438
  else if (value.isDefineTemplates) generationResults.templates.push(value._setPath(`${name};;${outputFilePath}`));
439
+ else if (value.isDefineImport) generationResults.imports.push(value._setPath(src));
440
+ else if (value.isDefineFont) generationResults.fonts.push(value);
398
441
  });
399
442
  })
400
443
  );
@@ -491,23 +534,79 @@ ${css}
491
534
  const templates = mergeObjects(config.templates, generationResults.templates);
492
535
  const templateStylesString = await parseTemplates(templates);
493
536
  const templateTokens = getTemplateTypes(templates);
537
+ const templateVariantMaps = getTemplateVariantMaps(templates);
494
538
  writeFileSync(templateStylesPath, `@layer templates { ${templateStylesString} }`);
495
539
  configCacheContent.templates = templates;
540
+ const importsPath = join(destDir, "css/_imports.css");
541
+ const importRules = [];
542
+ for (const factory of generationResults.imports) {
543
+ const sourceFile = factory._path;
544
+ if (!sourceFile) continue;
545
+ for (const spec of factory._current) {
546
+ try {
547
+ const { rule } = resolveImport(spec, sourceFile, destDir);
548
+ importRules.push(rule);
549
+ } catch (e) {
550
+ const url = typeof spec === "string" ? spec : spec.url;
551
+ logger.error(`Failed to resolve defineImport(${JSON.stringify(url)}) from ${sourceFile}: ${e.message}`);
552
+ }
553
+ }
554
+ }
555
+ writeFileSync(importsPath, importRules.join("\n"));
496
556
  const configTemplateFactories = config.templates ? [defineTemplates(config.templates)._setPath(`config;;${configPath}`)] : [];
497
557
  const templateFactories = mergeFactories(generationResults.templates, configTemplateFactories);
498
558
  configCacheContent.templatePaths = Object.fromEntries(Object.entries(templateFactories).map(([key, faktory]) => [key, faktory._path]));
559
+ const fontsStylesPath = join(destDir, "css/_fonts.css");
560
+ if (generationResults.fonts.length === 0) {
561
+ writeFileSync(fontsStylesPath, "");
562
+ } else {
563
+ const fontImports = [];
564
+ const fontBodies = [];
565
+ for (const font of generationResults.fonts) {
566
+ const { imports, body } = font._toCss();
567
+ fontImports.push(...imports);
568
+ fontBodies.push(body);
569
+ }
570
+ const importBlock = fontImports.length ? `${fontImports.join("\n")}
571
+
572
+ ` : "";
573
+ writeFileSync(fontsStylesPath, `${importBlock}@layer fonts { ${fontBodies.join(" ")} }`);
574
+ }
499
575
  const tsTokensPath = join(destDir, "types/css-tokens.d.ts");
500
576
  const tsVariableTokens = [...variableTokens].join("|");
577
+ const pascal = (str) => str.split(/[.\-_]/).filter(Boolean).map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("");
578
+ const templateVariantMapEntries = Object.entries(templateVariantMaps);
579
+ const hasVariantMaps = templateVariantMapEntries.some(([, pathMap]) => Object.keys(pathMap).length > 0);
580
+ const tsTemplateVariantMap = hasVariantMaps ? `type TemplateVariantTokens = {
581
+ ${templateVariantMapEntries.filter(([, pathMap]) => Object.keys(pathMap).length > 0).map(([templateKey, pathMap]) => {
582
+ const pathEntries = Object.entries(pathMap).map(
583
+ ([dotPath, axes]) => `'${dotPath}': { ${Object.entries(axes).map(([axis, valueType]) => `${axis}?: ${valueType}`).join("; ")} }`
584
+ ).join(";\n ");
585
+ return `${templateKey}: {
586
+ ${pathEntries}
587
+ }`;
588
+ }).join(";\n ")}
589
+ }` : `type TemplateVariantTokens = Record<string, Record<string, Record<string, never>>>;`;
590
+ const tsTemplateVariantAliases = templateVariantMapEntries.flatMap(
591
+ ([templateKey, pathMap]) => Object.keys(pathMap).map((dotPath) => `type ${pascal(templateKey)}${pascal(dotPath)}Variants = TemplateVariantTokens['${templateKey}']['${dotPath}'];`)
592
+ ).join("\n ");
501
593
  const tsTokensTypes = `
502
594
  // Variable types
503
- type VariableTokens = ${tsVariableTokens || `''`};
595
+ type VariableTokens = ${tsVariableTokens || `''`};
504
596
  type PropertyValueToken = \`{\${VariableTokens}}\`;
505
-
597
+
506
598
  // Template types
507
599
  type TemplateTokens = {
508
- ${Object.entries(templateTokens).map(([key, value]) => `${key}?: ${value}`).join("\n")}
600
+ ${Object.entries(templateTokens).map(([key, value]) => {
601
+ if (!value || value === "any") return `${key}?: ${value || "any"}`;
602
+ return `${key}?: ${value} | \`\${${value}}@\${string}\``;
603
+ }).join("\n")}
509
604
  }
510
-
605
+
606
+ // Template variant types (per docs/template-variants-spec.md §7)
607
+ ${tsTemplateVariantMap}
608
+ ${tsTemplateVariantAliases}
609
+
511
610
  // Media query types
512
611
  type MediaQueryKeys = ${mediaQueryKeys || `''`};
513
612
  `;
@@ -526,7 +625,8 @@ ${css}
526
625
  let currentFile = readFileSync(sourceFilePath, "utf8");
527
626
  currentFile = this.replaceStyledTag(currentFile);
528
627
  currentFile = this.addConfigCache(currentFile);
529
- const outputFilePath = join(outputDirectory, "js", hashedName + ".js");
628
+ const currentFileHash = toHash(currentFile);
629
+ const outputFilePath = join(outputDirectory, "js", `${hashedName}-${currentFileHash}.js`);
530
630
  const rcProject = await this.getRCProjectConfig(this.projectRootDir);
531
631
  const coreConfigPath = join(this.projectRootDir, (rcProject == null ? void 0 : rcProject.configDir) || "", "salty.config.ts");
532
632
  const externalModules = this.getExternalModules(coreConfigPath);
@@ -670,11 +770,13 @@ ${newContent}
670
770
  });
671
771
  });
672
772
  this.projectRootDir = projectRootDir;
773
+ this.options = options;
673
774
  if (typeof process === "undefined") {
674
775
  throw new Error("SaltyServer can only be used in a Node.js environment.");
675
776
  }
676
777
  }
677
778
  get isProduction() {
779
+ if (this.options.mode) return this.options.mode === "production";
678
780
  try {
679
781
  return process.env["NODE_ENV"] !== "development";
680
782
  } catch {
package/config/index.cjs CHANGED
@@ -5,9 +5,13 @@ const defineTemplates = require("../define-templates-Deq1aCbN.cjs");
5
5
  const defineConfig = (config) => {
6
6
  return config;
7
7
  };
8
+ exports.FontFactory = factories_index.FontFactory;
8
9
  exports.GlobalStylesFactory = factories_index.GlobalStylesFactory;
10
+ exports.ImportFactory = factories_index.ImportFactory;
9
11
  exports.VariablesFactory = factories_index.VariablesFactory;
12
+ exports.defineFont = factories_index.defineFont;
10
13
  exports.defineGlobalStyles = factories_index.defineGlobalStyles;
14
+ exports.defineImport = factories_index.defineImport;
11
15
  exports.defineMediaQuery = factories_index.defineMediaQuery;
12
16
  exports.defineVariables = factories_index.defineVariables;
13
17
  exports.TemplateFactory = defineTemplates.TemplateFactory;
package/config/index.js CHANGED
@@ -1,15 +1,19 @@
1
- import { GlobalStylesFactory, VariablesFactory, defineGlobalStyles, defineMediaQuery, defineVariables } from "../factories/index.js";
1
+ import { FontFactory, GlobalStylesFactory, ImportFactory, VariablesFactory, defineFont, defineGlobalStyles, defineImport, defineMediaQuery, defineVariables } from "../factories/index.js";
2
2
  import { T, a, d } from "../define-templates-CVhhgPnd.js";
3
3
  const defineConfig = (config) => {
4
4
  return config;
5
5
  };
6
6
  export {
7
+ FontFactory,
7
8
  GlobalStylesFactory,
9
+ ImportFactory,
8
10
  T as TemplateFactory,
9
11
  a as TemplatesFactory,
10
12
  VariablesFactory,
11
13
  defineConfig,
14
+ defineFont,
12
15
  defineGlobalStyles,
16
+ defineImport,
13
17
  defineMediaQuery,
14
18
  d as defineTemplates,
15
19
  defineVariables
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const parseStyles = require("../parse-styles-lOMGe_c5.cjs");
4
+ const toHash = require("../to-hash-C05Y906F.cjs");
5
+ const cache_resolveDynamicConfigCache = require("../cache/resolve-dynamic-config-cache.cjs");
6
+ const getDynamicStylesClassName = (styles) => {
7
+ return toHash.toHash(styles);
8
+ };
9
+ const getDynamicStylesCss = async (styles, scope) => {
10
+ const config = await cache_resolveDynamicConfigCache.resolveDynamicConfigCache();
11
+ const parsed = await parseStyles.parseStyles(styles, scope, config);
12
+ return parsed.join("\n");
13
+ };
14
+ exports.getDynamicStylesClassName = getDynamicStylesClassName;
15
+ exports.getDynamicStylesCss = getDynamicStylesCss;
@@ -0,0 +1,10 @@
1
+ import { BaseStyles } from '../types';
2
+ /**
3
+ * Create a hash of the dynamic styles that then can be used as scope.
4
+ */
5
+ export declare const getDynamicStylesClassName: (styles: BaseStyles) => string;
6
+ /**
7
+ * Add any dynamic styles to your app with a custom scope.
8
+ * Note: this works only with server components.
9
+ */
10
+ export declare const getDynamicStylesCss: (styles: BaseStyles, scope?: string) => Promise<string>;
@@ -0,0 +1,15 @@
1
+ import { a as parseStyles } from "../parse-styles-BBJ3PWyV.js";
2
+ import { t as toHash } from "../to-hash-DAN2LcHK.js";
3
+ import { resolveDynamicConfigCache } from "../cache/resolve-dynamic-config-cache.js";
4
+ const getDynamicStylesClassName = (styles) => {
5
+ return toHash(styles);
6
+ };
7
+ const getDynamicStylesCss = async (styles, scope) => {
8
+ const config = await resolveDynamicConfigCache();
9
+ const parsed = await parseStyles(styles, scope, config);
10
+ return parsed.join("\n");
11
+ };
12
+ export {
13
+ getDynamicStylesClassName,
14
+ getDynamicStylesCss
15
+ };
package/css/index.cjs CHANGED
@@ -4,9 +4,12 @@ const css_keyframes = require("./keyframes.cjs");
4
4
  const css_media = require("./media.cjs");
5
5
  const css_token = require("./token.cjs");
6
6
  const css_merge = require("./merge.cjs");
7
+ const css_dynamicStyles = require("./dynamic-styles.cjs");
7
8
  exports.keyframes = css_keyframes.keyframes;
8
9
  exports.MediaQueryFactory = css_media.MediaQueryFactory;
9
10
  exports.media = css_media.media;
10
11
  exports.token = css_token.token;
11
12
  exports.mergeFactories = css_merge.mergeFactories;
12
13
  exports.mergeObjects = css_merge.mergeObjects;
14
+ exports.getDynamicStylesClassName = css_dynamicStyles.getDynamicStylesClassName;
15
+ exports.getDynamicStylesCss = css_dynamicStyles.getDynamicStylesCss;
package/css/index.d.ts CHANGED
@@ -2,3 +2,4 @@ export * from './keyframes';
2
2
  export * from './media';
3
3
  export * from './token';
4
4
  export * from './merge';
5
+ export * from './dynamic-styles';
package/css/index.js CHANGED
@@ -2,8 +2,11 @@ import { keyframes } from "./keyframes.js";
2
2
  import { MediaQueryFactory, media } from "./media.js";
3
3
  import { token } from "./token.js";
4
4
  import { mergeFactories, mergeObjects } from "./merge.js";
5
+ import { getDynamicStylesClassName, getDynamicStylesCss } from "./dynamic-styles.js";
5
6
  export {
6
7
  MediaQueryFactory,
8
+ getDynamicStylesClassName,
9
+ getDynamicStylesCss,
7
10
  keyframes,
8
11
  media,
9
12
  mergeFactories,
package/css/keyframes.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const parseStyles = require("../parse-styles-CA3TP5n1.cjs");
3
+ const parseStyles = require("../parse-styles-lOMGe_c5.cjs");
4
4
  const toHash = require("../to-hash-C05Y906F.cjs");
5
5
  const keyframes = ({ animationName: _name, params: _params, appendInitialStyles, ...keyframes2 }) => {
6
6
  const modifyKeyframes = async (params = {}) => {
package/css/keyframes.js CHANGED
@@ -1,4 +1,4 @@
1
- import { p as parseAndJoinStyles } from "../parse-styles-BTIoYnBr.js";
1
+ import { p as parseAndJoinStyles } from "../parse-styles-BBJ3PWyV.js";
2
2
  import { t as toHash } from "../to-hash-DAN2LcHK.js";
3
3
  const keyframes = ({ animationName: _name, params: _params, appendInitialStyles, ...keyframes2 }) => {
4
4
  const modifyKeyframes = async (params = {}) => {
@@ -0,0 +1,28 @@
1
+ import { DefineFontOptions } from '../types/font-types';
2
+ export interface FontCss {
3
+ /** `@import url(...)` lines that must sit at the top of the stylesheet, before any `@layer`. */
4
+ imports: string[];
5
+ /** Body that goes inside the `@layer fonts { ... }` wrapper. */
6
+ body: string;
7
+ }
8
+ export declare class FontFactory {
9
+ readonly _options: DefineFontOptions;
10
+ readonly variable: string;
11
+ readonly fontFamily: string;
12
+ readonly className: string;
13
+ constructor(_options: DefineFontOptions);
14
+ get isDefineFont(): true;
15
+ /** Acts as a string equal to the resolved font-family value. */
16
+ toString(): string;
17
+ /** Inline-style helper: spread onto a React `style` prop. */
18
+ get style(): Record<string, string>;
19
+ /** Build the CSS pieces written to `_fonts.css`. */
20
+ _toCss(): FontCss;
21
+ }
22
+ /**
23
+ * Define a custom font that is registered globally as `@font-face` and exposed
24
+ * as a CSS variable. The returned object stringifies to its `font-family`
25
+ * value, and exposes `.variable`, `.fontFamily`, `.className`, and `.style`
26
+ * for use in styles and components.
27
+ */
28
+ export declare const defineFont: (options: DefineFontOptions) => FontFactory;
@@ -0,0 +1,14 @@
1
+ export interface ImportSpecOptions {
2
+ url: string;
3
+ media?: string;
4
+ supports?: string;
5
+ }
6
+ export type ImportSpec = string | ImportSpecOptions;
7
+ export declare class ImportFactory {
8
+ _current: ImportSpec[];
9
+ _path?: string;
10
+ constructor(_current: ImportSpec[]);
11
+ get isDefineImport(): boolean;
12
+ _setPath(path: string): this;
13
+ }
14
+ export declare const defineImport: (...specs: ImportSpec[]) => ImportFactory;
@@ -1,7 +1,130 @@
1
1
  "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
2
5
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
6
+ const dashCase = require("../dash-case-DIwKaYgE.cjs");
7
+ const toHash = require("../to-hash-C05Y906F.cjs");
3
8
  const css_media = require("../css/media.cjs");
4
9
  const defineTemplates = require("../define-templates-Deq1aCbN.cjs");
10
+ const FONT_FORMAT_BY_EXTENSION = {
11
+ woff2: "woff2",
12
+ woff: "woff",
13
+ ttf: "truetype",
14
+ otf: "opentype",
15
+ eot: "embedded-opentype",
16
+ svg: "svg",
17
+ ttc: "collection"
18
+ };
19
+ const detectFontFormat = (url) => {
20
+ const cleaned = url.split("?")[0].split("#")[0];
21
+ const dot = cleaned.lastIndexOf(".");
22
+ if (dot === -1) return void 0;
23
+ const ext = cleaned.slice(dot + 1).toLowerCase();
24
+ return FONT_FORMAT_BY_EXTENSION[ext];
25
+ };
26
+ const toFontSrc = (entry) => {
27
+ if (typeof entry === "string") return { url: entry, format: detectFontFormat(entry) };
28
+ return entry;
29
+ };
30
+ const normalizeSources = (src) => {
31
+ if (Array.isArray(src)) return src.map(toFontSrc);
32
+ return [toFontSrc(src)];
33
+ };
34
+ const normalizeVariable = (variable) => {
35
+ const trimmed = variable.trim();
36
+ const stripped = trimmed.replace(/^--/, "");
37
+ if (!stripped) throw new Error(`defineFont: invalid \`variable\` value "${variable}".`);
38
+ return `--${dashCase.dashCase(stripped)}`;
39
+ };
40
+ const deriveVariable = (options) => {
41
+ const hashSource = [options.name, options.fallback, "variants" in options ? options.variants : void 0, "import" in options ? options.import : void 0];
42
+ return `--font-${dashCase.dashCase(options.name)}-${toHash.toHash(hashSource, 6)}`;
43
+ };
44
+ const quoteFamily = (name) => {
45
+ if (/^["'].*["']$/.test(name)) return name;
46
+ if (/\s/.test(name)) return `"${name}"`;
47
+ return name;
48
+ };
49
+ const buildFontFamilyValue = (name, fallback) => {
50
+ const head = quoteFamily(name);
51
+ if (!fallback || fallback.length === 0) return head;
52
+ return [head, fallback].join(", ");
53
+ };
54
+ const formatSrc = (src) => {
55
+ const parts = [`url("${src.url}")`];
56
+ if (src.format) parts.push(`format("${src.format}")`);
57
+ if (src.tech) parts.push(`tech(${src.tech})`);
58
+ return parts.join(" ");
59
+ };
60
+ const variantToFontFace = (name, variant, defaultDisplay) => {
61
+ const sources = normalizeSources(variant.src);
62
+ if (sources.length === 0) {
63
+ throw new Error(`defineFont(${name}): variant must declare at least one \`src\`.`);
64
+ }
65
+ const lines = [`font-family: ${quoteFamily(name)};`, `src: ${sources.map(formatSrc).join(", ")};`, `font-display: ${variant.display ?? defaultDisplay};`];
66
+ if (variant.weight !== void 0) lines.push(`font-weight: ${variant.weight};`);
67
+ if (variant.style !== void 0) lines.push(`font-style: ${variant.style};`);
68
+ if (variant.stretch !== void 0) lines.push(`font-stretch: ${variant.stretch};`);
69
+ if (variant.unicodeRange !== void 0) lines.push(`unicode-range: ${variant.unicodeRange};`);
70
+ if (variant.ascentOverride !== void 0) lines.push(`ascent-override: ${variant.ascentOverride};`);
71
+ if (variant.descentOverride !== void 0) lines.push(`descent-override: ${variant.descentOverride};`);
72
+ if (variant.lineGapOverride !== void 0) lines.push(`line-gap-override: ${variant.lineGapOverride};`);
73
+ if (variant.sizeAdjust !== void 0) lines.push(`size-adjust: ${variant.sizeAdjust};`);
74
+ return `@font-face { ${lines.join(" ")} }`;
75
+ };
76
+ class FontFactory {
77
+ constructor(_options) {
78
+ __publicField(this, "variable");
79
+ __publicField(this, "fontFamily");
80
+ __publicField(this, "className");
81
+ this._options = _options;
82
+ if (!_options || !_options.name) {
83
+ throw new Error("defineFont: `name` is required.");
84
+ }
85
+ if ("variants" in _options && "import" in _options && _options.import !== void 0 && _options.variants !== void 0) {
86
+ throw new Error("defineFont: provide either `variants` or `import`, not both.");
87
+ }
88
+ if (!("variants" in _options && _options.variants) && !("import" in _options && _options.import)) {
89
+ throw new Error("defineFont: must provide either `variants` or `import`.");
90
+ }
91
+ this.variable = _options.variable ? normalizeVariable(_options.variable) : deriveVariable(_options);
92
+ this.fontFamily = buildFontFamilyValue(_options.name, _options.fallback);
93
+ this.className = `font-${dashCase.dashCase(_options.name)}`;
94
+ }
95
+ get isDefineFont() {
96
+ return true;
97
+ }
98
+ /** Acts as a string equal to the resolved font-family value. */
99
+ toString() {
100
+ return this.fontFamily;
101
+ }
102
+ /** Inline-style helper: spread onto a React `style` prop. */
103
+ get style() {
104
+ return {
105
+ fontFamily: this.fontFamily,
106
+ [this.variable]: this.fontFamily
107
+ };
108
+ }
109
+ /** Build the CSS pieces written to `_fonts.css`. */
110
+ _toCss() {
111
+ const imports = [];
112
+ const blocks = [];
113
+ if ("import" in this._options && this._options.import) {
114
+ imports.push(`@import url("${this._options.import}");`);
115
+ } else if ("variants" in this._options && this._options.variants) {
116
+ const display = this._options.display ?? "swap";
117
+ for (const variant of this._options.variants) {
118
+ blocks.push(variantToFontFace(this._options.name, variant, display));
119
+ }
120
+ }
121
+ blocks.push(`:root { ${this.variable}: ${this.fontFamily}; }`, `.${this.className} { font-family: var(${this.variable}); }`);
122
+ return { imports, body: blocks.join(" ") };
123
+ }
124
+ }
125
+ const defineFont = (options) => {
126
+ return new FontFactory(options);
127
+ };
5
128
  class GlobalStylesFactory {
6
129
  constructor(_current) {
7
130
  this._current = _current;
@@ -13,6 +136,20 @@ class GlobalStylesFactory {
13
136
  const defineGlobalStyles = (styles) => {
14
137
  return new GlobalStylesFactory(styles);
15
138
  };
139
+ class ImportFactory {
140
+ constructor(_current) {
141
+ __publicField(this, "_path");
142
+ this._current = _current;
143
+ }
144
+ get isDefineImport() {
145
+ return true;
146
+ }
147
+ _setPath(path) {
148
+ this._path = path;
149
+ return this;
150
+ }
151
+ }
152
+ const defineImport = (...specs) => new ImportFactory(specs);
16
153
  const defineMediaQuery = (mediaFactory) => {
17
154
  return mediaFactory(css_media.media);
18
155
  };
@@ -30,8 +167,12 @@ const defineVariables = (variables) => {
30
167
  exports.TemplateFactory = defineTemplates.TemplateFactory;
31
168
  exports.TemplatesFactory = defineTemplates.TemplatesFactory;
32
169
  exports.defineTemplates = defineTemplates.defineTemplates;
170
+ exports.FontFactory = FontFactory;
33
171
  exports.GlobalStylesFactory = GlobalStylesFactory;
172
+ exports.ImportFactory = ImportFactory;
34
173
  exports.VariablesFactory = VariablesFactory;
174
+ exports.defineFont = defineFont;
35
175
  exports.defineGlobalStyles = defineGlobalStyles;
176
+ exports.defineImport = defineImport;
36
177
  exports.defineMediaQuery = defineMediaQuery;
37
178
  exports.defineVariables = defineVariables;
@@ -1,4 +1,6 @@
1
+ export * from './define-font';
1
2
  export * from './define-global-styles';
3
+ export * from './define-import';
2
4
  export * from './define-media-query';
3
5
  export * from './define-variables';
4
6
  export * from './define-templates';