@servicetitan/stylelint-config 40.0.0 → 40.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"function-url-no-absolute.d.ts","sourceRoot":"","sources":["../src/function-url-no-absolute.ts"],"names":[],"mappings":";;;;;;AAoDA,kBAA+E"}
1
+ {"version":3,"file":"function-url-no-absolute.d.ts","sourceRoot":"","sources":["../src/function-url-no-absolute.ts"],"names":[],"mappings":";;;;;;AAmDA,kBAA+E"}
@@ -1,11 +1,5 @@
1
1
  "use strict";
2
- const _trim = /*#__PURE__*/ _interop_require_default(require("lodash/trim"));
3
2
  const _stylelint = require("stylelint");
4
- function _interop_require_default(obj) {
5
- return obj && obj.__esModule ? obj : {
6
- default: obj
7
- };
8
- }
9
3
  const functionArgumentsSearch = require('stylelint/lib/utils/functionArgumentsSearch.mjs').default;
10
4
  const isAbsoluteUrl = (url)=>/^\//.test(url) && !/^\/\//.test(url);
11
5
  const ruleName = '@servicetitan/function-url-no-absolute';
@@ -22,7 +16,7 @@ const plugin = (actual)=>{
22
16
  }
23
17
  root.walkDecls((decl)=>{
24
18
  functionArgumentsSearch(decl.toString().toLowerCase(), 'url', (args, index)=>{
25
- const url = (0, _trim.default)(args, ' \'"');
19
+ const url = args.replace(/(^[ '"]+)|([ '"]+$)/g, '');
26
20
  if (!isAbsoluteUrl(url)) {
27
21
  return;
28
22
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/function-url-no-absolute.ts"],"sourcesContent":["import trim from 'lodash/trim';\nimport { Rule, createPlugin, utils } from 'stylelint';\n\nconst functionArgumentsSearch = (\n require('stylelint/lib/utils/functionArgumentsSearch.mjs') as {\n default: (\n source: string,\n functionName: string,\n callback: (args: string, index: number) => void\n ) => void;\n }\n).default;\n\nconst isAbsoluteUrl = (url: string) => /^\\//.test(url) && !/^\\/\\//.test(url);\n\nconst ruleName = '@servicetitan/function-url-no-absolute';\nconst messages = utils.ruleMessages(ruleName, {\n rejected: 'Unexpected absolute url',\n});\n\nconst plugin: Rule = actual => {\n return (root, result) => {\n const validOptions = utils.validateOptions(result, ruleName, { actual });\n\n if (!validOptions) {\n return;\n }\n\n root.walkDecls(decl => {\n functionArgumentsSearch(decl.toString().toLowerCase(), 'url', (args, index) => {\n const url = trim(args, ' \\'\"');\n\n if (!isAbsoluteUrl(url)) {\n return;\n }\n\n utils.report({\n message: messages.rejected,\n node: decl,\n index,\n endIndex: index + args.length,\n result,\n ruleName,\n });\n });\n });\n };\n};\n\nplugin.ruleName = ruleName;\nplugin.messages = messages;\n\nexport = Object.assign(createPlugin(ruleName, plugin), { ruleName, messages });\n"],"names":["functionArgumentsSearch","require","default","isAbsoluteUrl","url","test","ruleName","messages","utils","ruleMessages","rejected","plugin","actual","root","result","validOptions","validateOptions","walkDecls","decl","toString","toLowerCase","args","index","trim","report","message","node","endIndex","length","Object","assign","createPlugin"],"mappings":";6DAAiB;2BACyB;;;;;;AAE1C,MAAMA,0BAA0B,AAC5BC,QAAQ,mDAOVC,OAAO;AAET,MAAMC,gBAAgB,CAACC,MAAgB,MAAMC,IAAI,CAACD,QAAQ,CAAC,QAAQC,IAAI,CAACD;AAExE,MAAME,WAAW;AACjB,MAAMC,WAAWC,gBAAK,CAACC,YAAY,CAACH,UAAU;IAC1CI,UAAU;AACd;AAEA,MAAMC,SAAeC,CAAAA;IACjB,OAAO,CAACC,MAAMC;QACV,MAAMC,eAAeP,gBAAK,CAACQ,eAAe,CAACF,QAAQR,UAAU;YAAEM;QAAO;QAEtE,IAAI,CAACG,cAAc;YACf;QACJ;QAEAF,KAAKI,SAAS,CAACC,CAAAA;YACXlB,wBAAwBkB,KAAKC,QAAQ,GAAGC,WAAW,IAAI,OAAO,CAACC,MAAMC;gBACjE,MAAMlB,MAAMmB,IAAAA,aAAI,EAACF,MAAM;gBAEvB,IAAI,CAAClB,cAAcC,MAAM;oBACrB;gBACJ;gBAEAI,gBAAK,CAACgB,MAAM,CAAC;oBACTC,SAASlB,SAASG,QAAQ;oBAC1BgB,MAAMR;oBACNI;oBACAK,UAAUL,QAAQD,KAAKO,MAAM;oBAC7Bd;oBACAR;gBACJ;YACJ;QACJ;IACJ;AACJ;AAEAK,OAAOL,QAAQ,GAAGA;AAClBK,OAAOJ,QAAQ,GAAGA;iBAETsB,OAAOC,MAAM,CAACC,IAAAA,uBAAY,EAACzB,UAAUK,SAAS;IAAEL;IAAUC;AAAS"}
1
+ {"version":3,"sources":["../src/function-url-no-absolute.ts"],"sourcesContent":["import { Rule, createPlugin, utils } from 'stylelint';\n\nconst functionArgumentsSearch = (\n require('stylelint/lib/utils/functionArgumentsSearch.mjs') as {\n default: (\n source: string,\n functionName: string,\n callback: (args: string, index: number) => void\n ) => void;\n }\n).default;\n\nconst isAbsoluteUrl = (url: string) => /^\\//.test(url) && !/^\\/\\//.test(url);\n\nconst ruleName = '@servicetitan/function-url-no-absolute';\nconst messages = utils.ruleMessages(ruleName, {\n rejected: 'Unexpected absolute url',\n});\n\nconst plugin: Rule = actual => {\n return (root, result) => {\n const validOptions = utils.validateOptions(result, ruleName, { actual });\n\n if (!validOptions) {\n return;\n }\n\n root.walkDecls(decl => {\n functionArgumentsSearch(decl.toString().toLowerCase(), 'url', (args, index) => {\n const url = args.replace(/(^[ '\"]+)|([ '\"]+$)/g, '');\n\n if (!isAbsoluteUrl(url)) {\n return;\n }\n\n utils.report({\n message: messages.rejected,\n node: decl,\n index,\n endIndex: index + args.length,\n result,\n ruleName,\n });\n });\n });\n };\n};\n\nplugin.ruleName = ruleName;\nplugin.messages = messages;\n\nexport = Object.assign(createPlugin(ruleName, plugin), { ruleName, messages });\n"],"names":["functionArgumentsSearch","require","default","isAbsoluteUrl","url","test","ruleName","messages","utils","ruleMessages","rejected","plugin","actual","root","result","validOptions","validateOptions","walkDecls","decl","toString","toLowerCase","args","index","replace","report","message","node","endIndex","length","Object","assign","createPlugin"],"mappings":";2BAA0C;AAE1C,MAAMA,0BAA0B,AAC5BC,QAAQ,mDAOVC,OAAO;AAET,MAAMC,gBAAgB,CAACC,MAAgB,MAAMC,IAAI,CAACD,QAAQ,CAAC,QAAQC,IAAI,CAACD;AAExE,MAAME,WAAW;AACjB,MAAMC,WAAWC,gBAAK,CAACC,YAAY,CAACH,UAAU;IAC1CI,UAAU;AACd;AAEA,MAAMC,SAAeC,CAAAA;IACjB,OAAO,CAACC,MAAMC;QACV,MAAMC,eAAeP,gBAAK,CAACQ,eAAe,CAACF,QAAQR,UAAU;YAAEM;QAAO;QAEtE,IAAI,CAACG,cAAc;YACf;QACJ;QAEAF,KAAKI,SAAS,CAACC,CAAAA;YACXlB,wBAAwBkB,KAAKC,QAAQ,GAAGC,WAAW,IAAI,OAAO,CAACC,MAAMC;gBACjE,MAAMlB,MAAMiB,KAAKE,OAAO,CAAC,wBAAwB;gBAEjD,IAAI,CAACpB,cAAcC,MAAM;oBACrB;gBACJ;gBAEAI,gBAAK,CAACgB,MAAM,CAAC;oBACTC,SAASlB,SAASG,QAAQ;oBAC1BgB,MAAMR;oBACNI;oBACAK,UAAUL,QAAQD,KAAKO,MAAM;oBAC7Bd;oBACAR;gBACJ;YACJ;QACJ;IACJ;AACJ;AAEAK,OAAOL,QAAQ,GAAGA;AAClBK,OAAOJ,QAAQ,GAAGA;iBAETsB,OAAOC,MAAM,CAACC,IAAAA,uBAAY,EAACzB,UAAUK,SAAS;IAAEL;IAAUC;AAAS"}
@@ -1,8 +1,3 @@
1
- declare const _default: import("stylelint").Plugin & {
2
- ruleName: string;
3
- messages: {
4
- variableExpected: (expected: string, found: string) => string;
5
- };
6
- };
7
- export = _default;
1
+ import plugin from './use-tokens';
2
+ export = plugin;
8
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/use-tokens/index.ts"],"names":[],"mappings":";;;qCAgBiC,MAAM,SAAS,MAAM;;;AAkJtD,kBAA+E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/use-tokens/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,cAAc,CAAC;AAElC,SAAS,MAAM,CAAC"}
@@ -1,122 +1,10 @@
1
1
  "use strict";
2
- const _color = /*#__PURE__*/ _interop_require_default(require("color"));
3
- const _stylelint = require("stylelint");
4
- const _values = require("./values");
2
+ const _usetokens = /*#__PURE__*/ _interop_require_default(require("./use-tokens"));
5
3
  function _interop_require_default(obj) {
6
4
  return obj && obj.__esModule ? obj : {
7
5
  default: obj
8
6
  };
9
7
  }
10
- const ruleName = '@servicetitan/use-tokens';
11
- const messages = _stylelint.utils.ruleMessages(ruleName, {
12
- variableExpected: (expected, found)=>`You should use "${expected}" variable from the \`@servicetitan/tokens\` instead of "${found}".`
13
- });
14
- const plugin = (_0, _1, context)=>{
15
- return (root, result)=>{
16
- var _result_opts_from_split_pop, _result_opts_from, _result_opts;
17
- const extension = (_result_opts = result.opts) === null || _result_opts === void 0 ? void 0 : (_result_opts_from = _result_opts.from) === null || _result_opts_from === void 0 ? void 0 : (_result_opts_from_split_pop = _result_opts_from.split('.').pop()) === null || _result_opts_from_split_pop === void 0 ? void 0 : _result_opts_from_split_pop.toLowerCase();
18
- function convertToVariable(key) {
19
- switch(extension){
20
- case 'less':
21
- return `@${key}`;
22
- case 'sass':
23
- case 'scss':
24
- return `$${key}`;
25
- default:
26
- return `var(--${key})`;
27
- }
28
- }
29
- root.walkDecls((decl)=>{
30
- function lint(collection, { condition, transformer, solid } = {}) {
31
- if (condition && !condition(decl.prop)) {
32
- return true;
33
- }
34
- const values = !solid ? decl.value.split(' ') : [
35
- decl.value
36
- ];
37
- let reported = false;
38
- for (const rawValue of values){
39
- var _ref;
40
- const value = (_ref = transformer === null || transformer === void 0 ? void 0 : transformer(rawValue)) !== null && _ref !== void 0 ? _ref : rawValue;
41
- if (collection[value]) {
42
- const variable = (rawValue.startsWith('-') ? '-' : '') + convertToVariable(collection[value]);
43
- if (context.fix) {
44
- values[values.indexOf(rawValue)] = variable;
45
- } else {
46
- _stylelint.utils.report({
47
- node: decl,
48
- message: messages.variableExpected(variable, rawValue),
49
- word: value,
50
- ruleName,
51
- result
52
- });
53
- }
54
- reported = true;
55
- }
56
- }
57
- if (context.fix) {
58
- decl.value = values.join(' ');
59
- }
60
- return !reported;
61
- }
62
- const linters = {
63
- colors: ()=>lint(_values.colors, {
64
- transformer: (value)=>{
65
- try {
66
- return new _color.default(value).hex();
67
- } catch (unused) {
68
- return '';
69
- }
70
- }
71
- }),
72
- typescales: ()=>lint(_values.typescales, {
73
- condition: (property)=>property === 'font-size',
74
- solid: true
75
- }),
76
- borderRadiuses: ()=>lint(_values.borderRadiuses, {
77
- condition: (property)=>property.startsWith('border-') && property.endsWith('-radius'),
78
- transformer: (value)=>value === '0px' ? '0' : value
79
- }),
80
- lintSpacings: ()=>lint(_values.spacings, {
81
- // other spacings like "top"?
82
- condition: (property)=>property.startsWith('margin') || property.startsWith('padding'),
83
- transformer: (value)=>value === '0px' ? '0' : value.startsWith('-') ? value.slice(1) : value
84
- }),
85
- fontWeights: ()=>lint(_values.fontWeights, {
86
- condition: (property)=>property === 'font-weight',
87
- solid: true
88
- }),
89
- opacities: ()=>lint(_values.opacities, {
90
- condition: (property)=>property === 'opacity',
91
- transformer: (value)=>value.startsWith('0.') ? value.slice(1) : value,
92
- solid: true
93
- }),
94
- zIndexes: ()=>lint(_values.zIndexes, {
95
- condition: (property)=>property === 'z-index',
96
- solid: true
97
- }),
98
- lineHeights: ()=>lint(_values.lineHeights, {
99
- condition: (property)=>property === 'line-height',
100
- solid: true
101
- }),
102
- fontFamilies: ()=>lint(_values.fontFamilies, {
103
- condition: (property)=>property === 'font-family',
104
- solid: true
105
- })
106
- };
107
- for (const handler of Object.values(linters)){
108
- if (!handler()) {
109
- return;
110
- }
111
- }
112
- });
113
- };
114
- };
115
- plugin.ruleName = ruleName;
116
- plugin.messages = messages;
117
- module.exports = Object.assign((0, _stylelint.createPlugin)(ruleName, plugin), {
118
- ruleName,
119
- messages
120
- });
8
+ module.exports = _usetokens.default;
121
9
 
122
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/use-tokens/index.ts"],"sourcesContent":["import Color from 'color';\nimport { Rule, createPlugin, utils } from 'stylelint';\nimport {\n borderRadiuses,\n colors,\n fontFamilies,\n fontWeights,\n lineHeights,\n opacities,\n spacings,\n typescales,\n zIndexes,\n} from './values';\n\nconst ruleName = '@servicetitan/use-tokens';\nconst messages = utils.ruleMessages(ruleName, {\n variableExpected: (expected: string, found: string) =>\n `You should use \"${expected}\" variable from the \\`@servicetitan/tokens\\` instead of \"${found}\".`,\n});\n\nconst plugin: Rule = (_0, _1, context) => {\n return (root, result) => {\n const extension = result.opts?.from?.split('.').pop()?.toLowerCase();\n\n function convertToVariable(key: string) {\n switch (extension) {\n case 'less':\n return `@${key}`;\n\n case 'sass':\n case 'scss':\n return `$${key}`;\n\n default:\n return `var(--${key})`;\n }\n }\n\n root.walkDecls(decl => {\n function lint(\n collection: Record<string, string>,\n {\n condition,\n transformer,\n solid,\n }: {\n condition?: (property: string) => boolean;\n transformer?: (value: string) => string;\n solid?: boolean;\n } = {}\n ) {\n if (condition && !condition(decl.prop)) {\n return true;\n }\n\n const values = !solid ? decl.value.split(' ') : [decl.value];\n\n let reported = false;\n for (const rawValue of values) {\n const value = transformer?.(rawValue) ?? rawValue;\n if (collection[value]) {\n const variable =\n (rawValue.startsWith('-') ? '-' : '') +\n convertToVariable(collection[value]);\n\n if (context.fix) {\n values[values.indexOf(rawValue)] = variable;\n } else {\n utils.report({\n node: decl,\n message: messages.variableExpected(variable, rawValue),\n word: value,\n ruleName,\n result,\n });\n }\n reported = true;\n }\n }\n\n if (context.fix) {\n decl.value = values.join(' ');\n }\n\n return !reported;\n }\n\n const linters = {\n colors: () =>\n lint(colors, {\n transformer: value => {\n try {\n return new Color(value).hex();\n } catch {\n return '';\n }\n },\n }),\n\n typescales: () =>\n lint(typescales, {\n condition: property => property === 'font-size',\n solid: true,\n }),\n\n borderRadiuses: () =>\n lint(borderRadiuses, {\n condition: property =>\n property.startsWith('border-') && property.endsWith('-radius'),\n transformer: value => (value === '0px' ? '0' : value),\n }),\n\n lintSpacings: () =>\n lint(spacings, {\n // other spacings like \"top\"?\n condition: property =>\n property.startsWith('margin') || property.startsWith('padding'),\n transformer: value =>\n value === '0px' ? '0' : value.startsWith('-') ? value.slice(1) : value,\n }),\n\n fontWeights: () =>\n lint(fontWeights, {\n condition: property => property === 'font-weight',\n solid: true,\n }),\n\n opacities: () =>\n lint(opacities, {\n condition: property => property === 'opacity',\n transformer: value => (value.startsWith('0.') ? value.slice(1) : value),\n solid: true,\n }),\n\n zIndexes: () =>\n lint(zIndexes, { condition: property => property === 'z-index', solid: true }),\n\n lineHeights: () =>\n lint(lineHeights, {\n condition: property => property === 'line-height',\n solid: true,\n }),\n\n fontFamilies: () =>\n lint(fontFamilies, {\n condition: property => property === 'font-family',\n solid: true,\n }),\n };\n\n for (const handler of Object.values(linters)) {\n if (!handler()) {\n return;\n }\n }\n });\n };\n};\n\nplugin.ruleName = ruleName;\nplugin.messages = messages;\n\nexport = Object.assign(createPlugin(ruleName, plugin), { ruleName, messages });\n"],"names":["ruleName","messages","utils","ruleMessages","variableExpected","expected","found","plugin","_0","_1","context","root","result","extension","opts","from","split","pop","toLowerCase","convertToVariable","key","walkDecls","decl","lint","collection","condition","transformer","solid","prop","values","value","reported","rawValue","variable","startsWith","fix","indexOf","report","node","message","word","join","linters","colors","Color","hex","typescales","property","borderRadiuses","endsWith","lintSpacings","spacings","slice","fontWeights","opacities","zIndexes","lineHeights","fontFamilies","handler","Object","assign","createPlugin"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/use-tokens/index.ts"],"sourcesContent":["import plugin from './use-tokens';\n\nexport = plugin;\n"],"names":["plugin"],"mappings":";kEAAmB;;;;;;iBAEVA,kBAAM"}
@@ -0,0 +1,11 @@
1
+ export declare const DESIGN_SYSTEM_SOURCE = "@servicetitan/tokens";
2
+ export declare const ANVIL2_SOURCE = "@servicetitan/anvil2";
3
+ export type TokenSource = typeof DESIGN_SYSTEM_SOURCE | typeof ANVIL2_SOURCE;
4
+ export interface Token {
5
+ name: string;
6
+ customProperty: string;
7
+ source: TokenSource;
8
+ value: string;
9
+ }
10
+ export declare function loadTokens(): Token[];
11
+ //# sourceMappingURL=load-tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-tokens.d.ts","sourceRoot":"","sources":["../../src/use-tokens/load-tokens.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAC3D,eAAO,MAAM,aAAa,yBAAyB,CAAC;AACpD,MAAM,MAAM,WAAW,GAAG,OAAO,oBAAoB,GAAG,OAAO,aAAa,CAAC;AAE7E,MAAM,WAAW,KAAK;IAElB,IAAI,EAAE,MAAM,CAAC;IAEb,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACjB;AAMD,wBAAgB,UAAU,IAAI,KAAK,EAAE,CAEpC"}
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get ANVIL2_SOURCE () {
13
+ return ANVIL2_SOURCE;
14
+ },
15
+ get DESIGN_SYSTEM_SOURCE () {
16
+ return DESIGN_SYSTEM_SOURCE;
17
+ },
18
+ get loadTokens () {
19
+ return loadTokens;
20
+ }
21
+ });
22
+ const _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
23
+ function _interop_require_default(obj) {
24
+ return obj && obj.__esModule ? obj : {
25
+ default: obj
26
+ };
27
+ }
28
+ const DESIGN_SYSTEM_SOURCE = '@servicetitan/tokens';
29
+ const ANVIL2_SOURCE = '@servicetitan/anvil2';
30
+ function loadTokens() {
31
+ return [
32
+ ...loadDesignSystemTokens(),
33
+ ...loadAnvil2Tokens()
34
+ ];
35
+ }
36
+ function loadDesignSystemTokens() {
37
+ var _optionalRequire;
38
+ const tokens = (_optionalRequire = optionalRequire('@servicetitan/tokens/core')) === null || _optionalRequire === void 0 ? void 0 : _optionalRequire.tokens;
39
+ if (!tokens) {
40
+ return [];
41
+ }
42
+ /*
43
+ * An alias is a second name for a value a canonical token already holds, for example
44
+ * "@default-border-radius: 3px; // (alias)" duplicates "@border-radius-1: 3px". Excluding
45
+ * aliases limits suggestions to the canonical name.
46
+ */ const aliases = _fs.default.readFileSync(require.resolve('@servicetitan/tokens/core/tokens.less'), 'utf8').split('\n').filter((row)=>row.startsWith('@') && row.endsWith('(alias)')).map((row)=>row.split(':')[0].slice(1));
47
+ return Object.entries(tokens).map(([key, value])=>({
48
+ name: toKebabCase(key),
49
+ value
50
+ })).filter(({ name })=>!aliases.includes(name)).map(({ name, value })=>({
51
+ name,
52
+ customProperty: `--${name}`,
53
+ source: DESIGN_SYSTEM_SOURCE,
54
+ value
55
+ }));
56
+ }
57
+ function loadAnvil2Tokens() {
58
+ var _optionalRequire, _optionalRequire1;
59
+ const primitives = (_optionalRequire = optionalRequire('@servicetitan/anvil2/token')) === null || _optionalRequire === void 0 ? void 0 : _optionalRequire.core.primitive;
60
+ if (!primitives) {
61
+ return [];
62
+ }
63
+ const version = (_optionalRequire1 = optionalRequire('@servicetitan/anvil2/package.json')) === null || _optionalRequire1 === void 0 ? void 0 : _optionalRequire1.version;
64
+ /*
65
+ * Anvil2 v3 prefixes its CSS custom properties with "a2-". All versions <3
66
+ * export package.json, so a version that doesn't is v3 or later.
67
+ */ const prefix = version === undefined || parseInt(version, 10) >= 3 ? 'a2-' : '';
68
+ return Object.entries(primitives).map(([key, { value }])=>{
69
+ const name = toKebabCase(key);
70
+ return {
71
+ name,
72
+ customProperty: `--${prefix}${name}`,
73
+ source: ANVIL2_SOURCE,
74
+ value
75
+ };
76
+ });
77
+ }
78
+ /*
79
+ * Returns undefined when the package isn't installed, or is a version that doesn't export the
80
+ * requested path.
81
+ */ function optionalRequire(id) {
82
+ try {
83
+ return require(id);
84
+ } catch (error) {
85
+ const code = error.code;
86
+ if (code === 'MODULE_NOT_FOUND' || code === 'ERR_PACKAGE_PATH_NOT_EXPORTED') {
87
+ return undefined;
88
+ }
89
+ throw error;
90
+ }
91
+ }
92
+ function toKebabCase(str) {
93
+ const camelCase = str.charAt(0).toLowerCase() + str.slice(1);
94
+ return camelCase.replace(/([A-Z]|[a-z]\d)/g, ([letter, digit])=>digit === undefined ? `-${letter.toLowerCase()}` : `${letter}-${digit}`);
95
+ }
96
+
97
+ //# sourceMappingURL=load-tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/use-tokens/load-tokens.ts"],"sourcesContent":["import fs from 'fs';\n\nexport const DESIGN_SYSTEM_SOURCE = '@servicetitan/tokens';\nexport const ANVIL2_SOURCE = '@servicetitan/anvil2';\nexport type TokenSource = typeof DESIGN_SYSTEM_SOURCE | typeof ANVIL2_SOURCE;\n\nexport interface Token {\n /* Kebab-case name of the token's Less and Sass variables. */\n name: string;\n /* CSS custom property that holds the token's value at runtime. */\n customProperty: string;\n source: TokenSource;\n value: string;\n}\n\n/*\n * Loads tokens from whichever token packages are installed. Both are optional peers, so a\n * missing package contributes no tokens.\n */\nexport function loadTokens(): Token[] {\n return [...loadDesignSystemTokens(), ...loadAnvil2Tokens()];\n}\n\nfunction loadDesignSystemTokens(): Token[] {\n const tokens = optionalRequire<{ tokens: Record<string, string> }>(\n '@servicetitan/tokens/core'\n )?.tokens;\n if (!tokens) {\n return [];\n }\n\n /*\n * An alias is a second name for a value a canonical token already holds, for example\n * \"@default-border-radius: 3px; // (alias)\" duplicates \"@border-radius-1: 3px\". Excluding\n * aliases limits suggestions to the canonical name.\n */\n const aliases = fs\n .readFileSync(require.resolve('@servicetitan/tokens/core/tokens.less'), 'utf8')\n .split('\\n')\n .filter(row => row.startsWith('@') && row.endsWith('(alias)'))\n .map(row => row.split(':')[0].slice(1));\n\n return Object.entries(tokens)\n .map(([key, value]) => ({ name: toKebabCase(key), value }))\n .filter(({ name }) => !aliases.includes(name))\n .map(({ name, value }) => ({\n name,\n customProperty: `--${name}`,\n source: DESIGN_SYSTEM_SOURCE,\n value,\n }));\n}\n\nfunction loadAnvil2Tokens(): Token[] {\n const primitives = optionalRequire<{\n core: { primitive: Record<string, { value: string }> };\n }>('@servicetitan/anvil2/token')?.core.primitive;\n if (!primitives) {\n return [];\n }\n\n const version = optionalRequire<{ version: string }>(\n '@servicetitan/anvil2/package.json'\n )?.version;\n /*\n * Anvil2 v3 prefixes its CSS custom properties with \"a2-\". All versions <3\n * export package.json, so a version that doesn't is v3 or later.\n */\n const prefix = version === undefined || parseInt(version, 10) >= 3 ? 'a2-' : '';\n\n return Object.entries(primitives).map(([key, { value }]) => {\n const name = toKebabCase(key);\n return {\n name,\n customProperty: `--${prefix}${name}`,\n source: ANVIL2_SOURCE,\n value,\n };\n });\n}\n\n/*\n * Returns undefined when the package isn't installed, or is a version that doesn't export the\n * requested path.\n */\nfunction optionalRequire<T>(id: string): T | undefined {\n try {\n return require(id);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === 'MODULE_NOT_FOUND' || code === 'ERR_PACKAGE_PATH_NOT_EXPORTED') {\n return undefined;\n }\n throw error;\n }\n}\n\nfunction toKebabCase(str: string) {\n const camelCase = str.charAt(0).toLowerCase() + str.slice(1);\n return camelCase.replace(/([A-Z]|[a-z]\\d)/g, ([letter, digit]) =>\n digit === undefined ? `-${letter.toLowerCase()}` : `${letter}-${digit}`\n );\n}\n"],"names":["ANVIL2_SOURCE","DESIGN_SYSTEM_SOURCE","loadTokens","loadDesignSystemTokens","loadAnvil2Tokens","optionalRequire","tokens","aliases","fs","readFileSync","require","resolve","split","filter","row","startsWith","endsWith","map","slice","Object","entries","key","value","name","toKebabCase","includes","customProperty","source","primitives","core","primitive","version","prefix","undefined","parseInt","id","error","code","str","camelCase","charAt","toLowerCase","replace","letter","digit"],"mappings":";;;;;;;;;;;QAGaA;eAAAA;;QADAC;eAAAA;;QAiBGC;eAAAA;;;2DAnBD;;;;;;AAER,MAAMD,uBAAuB;AAC7B,MAAMD,gBAAgB;AAgBtB,SAASE;IACZ,OAAO;WAAIC;WAA6BC;KAAmB;AAC/D;AAEA,SAASD;QACUE;IAAf,MAAMC,UAASD,mBAAAA,gBACX,0CADWA,uCAAAA,iBAEZC,MAAM;IACT,IAAI,CAACA,QAAQ;QACT,OAAO,EAAE;IACb;IAEA;;;;KAIC,GACD,MAAMC,UAAUC,WAAE,CACbC,YAAY,CAACC,QAAQC,OAAO,CAAC,0CAA0C,QACvEC,KAAK,CAAC,MACNC,MAAM,CAACC,CAAAA,MAAOA,IAAIC,UAAU,CAAC,QAAQD,IAAIE,QAAQ,CAAC,YAClDC,GAAG,CAACH,CAAAA,MAAOA,IAAIF,KAAK,CAAC,IAAI,CAAC,EAAE,CAACM,KAAK,CAAC;IAExC,OAAOC,OAAOC,OAAO,CAACd,QACjBW,GAAG,CAAC,CAAC,CAACI,KAAKC,MAAM,GAAM,CAAA;YAAEC,MAAMC,YAAYH;YAAMC;QAAM,CAAA,GACvDT,MAAM,CAAC,CAAC,EAAEU,IAAI,EAAE,GAAK,CAAChB,QAAQkB,QAAQ,CAACF,OACvCN,GAAG,CAAC,CAAC,EAAEM,IAAI,EAAED,KAAK,EAAE,GAAM,CAAA;YACvBC;YACAG,gBAAgB,CAAC,EAAE,EAAEH,MAAM;YAC3BI,QAAQ1B;YACRqB;QACJ,CAAA;AACR;AAEA,SAASlB;QACcC,kBAOHA;IAPhB,MAAMuB,cAAavB,mBAAAA,gBAEhB,2CAFgBA,uCAAAA,iBAEewB,IAAI,CAACC,SAAS;IAChD,IAAI,CAACF,YAAY;QACb,OAAO,EAAE;IACb;IAEA,MAAMG,WAAU1B,oBAAAA,gBACZ,kDADYA,wCAAAA,kBAEb0B,OAAO;IACV;;;KAGC,GACD,MAAMC,SAASD,YAAYE,aAAaC,SAASH,SAAS,OAAO,IAAI,QAAQ;IAE7E,OAAOZ,OAAOC,OAAO,CAACQ,YAAYX,GAAG,CAAC,CAAC,CAACI,KAAK,EAAEC,KAAK,EAAE,CAAC;QACnD,MAAMC,OAAOC,YAAYH;QACzB,OAAO;YACHE;YACAG,gBAAgB,CAAC,EAAE,EAAEM,SAAST,MAAM;YACpCI,QAAQ3B;YACRsB;QACJ;IACJ;AACJ;AAEA;;;CAGC,GACD,SAASjB,gBAAmB8B,EAAU;IAClC,IAAI;QACA,OAAOzB,QAAQyB;IACnB,EAAE,OAAOC,OAAO;QACZ,MAAMC,OAAO,AAACD,MAAgCC,IAAI;QAClD,IAAIA,SAAS,sBAAsBA,SAAS,iCAAiC;YACzE,OAAOJ;QACX;QACA,MAAMG;IACV;AACJ;AAEA,SAASZ,YAAYc,GAAW;IAC5B,MAAMC,YAAYD,IAAIE,MAAM,CAAC,GAAGC,WAAW,KAAKH,IAAIpB,KAAK,CAAC;IAC1D,OAAOqB,UAAUG,OAAO,CAAC,oBAAoB,CAAC,CAACC,QAAQC,MAAM,GACzDA,UAAUX,YAAY,CAAC,CAAC,EAAEU,OAAOF,WAAW,IAAI,GAAG,GAAGE,OAAO,CAAC,EAAEC,OAAO;AAE/E"}
@@ -0,0 +1,9 @@
1
+ import stylelint from 'stylelint';
2
+ declare const _default: stylelint.Plugin & {
3
+ ruleName: string;
4
+ messages: {
5
+ variableExpected: (expected: string, found: string) => string;
6
+ };
7
+ };
8
+ export = _default;
9
+ //# sourceMappingURL=use-tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-tokens.d.ts","sourceRoot":"","sources":["../../src/use-tokens/use-tokens.ts"],"names":[],"mappings":"AAGA,OAAO,SAAmB,MAAM,WAAW,CAAC;;;;qCAyBX,MAAM,SAAS,MAAM;;;AA+HtD,kBAA+E"}
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ const _color = /*#__PURE__*/ _interop_require_default(require("color"));
3
+ const _path = /*#__PURE__*/ _interop_require_default(require("path"));
4
+ const _stylelint = /*#__PURE__*/ _interop_require_default(require("stylelint"));
5
+ const _loadtokens = require("./load-tokens");
6
+ const _values = require("./values");
7
+ function _interop_require_default(obj) {
8
+ return obj && obj.__esModule ? obj : {
9
+ default: obj
10
+ };
11
+ }
12
+ const { createPlugin, utils } = _stylelint.default;
13
+ /*
14
+ * Matches spaces outside color functions, so splitting a value on it keeps a color such as
15
+ * rgb(2, 101, 220) whole while still separating the colors inside a gradient.
16
+ */ const spaceOutsideColorFunction = / (?<!\b(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch|color)\([^()]*)/;
17
+ const ruleName = '@servicetitan/use-tokens';
18
+ const messages = utils.ruleMessages(ruleName, {
19
+ variableExpected: (expected, found)=>`You should use ${expected} instead of "${found}".`
20
+ });
21
+ const linters = [
22
+ {
23
+ collection: _values.colors,
24
+ transformer: (value)=>{
25
+ try {
26
+ /* Includes alpha, so a translucent color doesn't match an opaque token. */ return new _color.default(value).hexa();
27
+ } catch (unused) {
28
+ return '';
29
+ }
30
+ },
31
+ multipleValues: true
32
+ },
33
+ {
34
+ collection: _values.typescales,
35
+ condition: (property)=>property === 'font-size'
36
+ },
37
+ {
38
+ collection: _values.borderRadiuses,
39
+ condition: (property)=>property.startsWith('border-') && property.endsWith('-radius'),
40
+ transformer: (value)=>value === '0px' ? '0' : value,
41
+ multipleValues: true
42
+ },
43
+ {
44
+ collection: _values.spacings,
45
+ condition: (property)=>property.startsWith('margin') || property.startsWith('padding'),
46
+ transformer: (value)=>{
47
+ if (value === '0px') {
48
+ return '0';
49
+ }
50
+ return value.startsWith('-') ? value.slice(1) : value;
51
+ },
52
+ multipleValues: true
53
+ },
54
+ {
55
+ collection: _values.fontWeights,
56
+ condition: (property)=>property === 'font-weight'
57
+ },
58
+ {
59
+ collection: _values.opacities,
60
+ condition: (property)=>property === 'opacity',
61
+ transformer: (value)=>value.startsWith('0.') ? value.slice(1) : value
62
+ },
63
+ {
64
+ collection: _values.zIndexes,
65
+ condition: (property)=>property === 'z-index'
66
+ },
67
+ {
68
+ collection: _values.lineHeights,
69
+ condition: (property)=>property === 'line-height'
70
+ },
71
+ {
72
+ collection: _values.fontFamilies,
73
+ condition: (property)=>property === 'font-family'
74
+ }
75
+ ];
76
+ const plugin = (_0, _1, context)=>{
77
+ return (root, result)=>{
78
+ var _result_opts_from;
79
+ const extension = _path.default.extname((_result_opts_from = result.opts.from) !== null && _result_opts_from !== void 0 ? _result_opts_from : '').slice(1).toLowerCase();
80
+ /* Returns whether any part of the declaration's value matched a token. */ function lint(decl, { collection, condition, transformer, multipleValues }) {
81
+ if (condition && !condition(decl.prop)) {
82
+ return false;
83
+ }
84
+ const values = multipleValues ? decl.value.split(spaceOutsideColorFunction) : [
85
+ decl.value
86
+ ];
87
+ let matched = false;
88
+ for (const rawValue of values){
89
+ var _ref;
90
+ const value = (_ref = transformer === null || transformer === void 0 ? void 0 : transformer(rawValue)) !== null && _ref !== void 0 ? _ref : rawValue;
91
+ const tokens = collection.get(value);
92
+ if (!tokens) {
93
+ continue;
94
+ }
95
+ matched = true;
96
+ const replacements = getReplacements(tokens, rawValue, extension);
97
+ if (context.fix && replacements.length === 1) {
98
+ values[values.indexOf(rawValue)] = replacements[0].variable;
99
+ } else {
100
+ /* When several tokens match, the developer picks one. */ const message = formatMessage(replacements, rawValue);
101
+ utils.report({
102
+ node: decl,
103
+ message,
104
+ word: rawValue,
105
+ ruleName,
106
+ result
107
+ });
108
+ }
109
+ }
110
+ if (context.fix) {
111
+ decl.value = values.join(' ');
112
+ }
113
+ return matched;
114
+ }
115
+ root.walkDecls((decl)=>{
116
+ linters.some((linter)=>lint(decl, linter));
117
+ });
118
+ };
119
+ };
120
+ plugin.ruleName = ruleName;
121
+ plugin.messages = messages;
122
+ /*
123
+ * Returns the variables that can replace a literal, negated when the literal is negative, for
124
+ * example "-16px" becomes "-$spacing-2" in Sass.
125
+ */ function getReplacements(tokens, rawValue, extension) {
126
+ const negative = rawValue.startsWith('-');
127
+ return tokens.reduce((replacements, token)=>{
128
+ const plain = convertToVariable(token, extension);
129
+ const variable = negative ? negate(plain, token.source) : plain;
130
+ /*
131
+ * When tokens from different sources match a literal with the same
132
+ * replacement, issue just one replacement that --fix can apply.
133
+ */ return replacements.some((replacement)=>replacement.variable === variable) ? replacements : [
134
+ ...replacements,
135
+ {
136
+ variable,
137
+ source: token.source
138
+ }
139
+ ];
140
+ }, []);
141
+ }
142
+ function convertToVariable({ name, customProperty, source }, extension) {
143
+ switch(extension){
144
+ case 'less':
145
+ /* Anvil2 publishes no Less variables. */ return source === _loadtokens.DESIGN_SYSTEM_SOURCE ? `@${name}` : `var(${customProperty})`;
146
+ case 'sass':
147
+ case 'scss':
148
+ return `$${name}`;
149
+ default:
150
+ return `var(${customProperty})`;
151
+ }
152
+ }
153
+ /*
154
+ * A minus sign negates only a variable that holds a plain number, such as a design-system Sass or
155
+ * Less variable. CSS has no unary minus for var(), and Anvil2's Sass variables can hold var(), so
156
+ * those are negated with calc().
157
+ */ function negate(variable, source) {
158
+ return source === _loadtokens.DESIGN_SYSTEM_SOURCE && !variable.startsWith('var(') ? `-${variable}` : `calc(-1 * ${variable})`;
159
+ }
160
+ function formatMessage(replacements, found) {
161
+ const choices = replacements.map(({ variable, source })=>`"${variable}" from \`${source}\``).join(' or ');
162
+ return messages.variableExpected(choices, found);
163
+ }
164
+ module.exports = Object.assign(createPlugin(ruleName, plugin), {
165
+ ruleName,
166
+ messages
167
+ });
168
+
169
+ //# sourceMappingURL=use-tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/use-tokens/use-tokens.ts"],"sourcesContent":["import Color from 'color';\nimport path from 'path';\nimport type { Declaration } from 'postcss';\nimport stylelint, { Rule } from 'stylelint';\nimport { DESIGN_SYSTEM_SOURCE, Token, TokenSource } from './load-tokens';\nimport {\n borderRadiuses,\n colors,\n fontFamilies,\n fontWeights,\n lineHeights,\n opacities,\n spacings,\n TokenCollection,\n typescales,\n zIndexes,\n} from './values';\n\nconst { createPlugin, utils } = stylelint;\n\n/*\n * Matches spaces outside color functions, so splitting a value on it keeps a color such as\n * rgb(2, 101, 220) whole while still separating the colors inside a gradient.\n */\nconst spaceOutsideColorFunction = / (?<!\\b(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch|color)\\([^()]*)/;\n\nconst ruleName = '@servicetitan/use-tokens';\nconst messages = utils.ruleMessages(ruleName, {\n variableExpected: (expected: string, found: string) =>\n `You should use ${expected} instead of \"${found}\".`,\n});\n\ninterface Linter {\n collection: TokenCollection;\n /* Limits the check to matching properties. Without it, every property is checked. */\n condition?: (property: string) => boolean;\n /* Normalizes a value before it's looked up in the collection. */\n transformer?: (value: string) => string;\n /* Looks up each space-separated part of the value. Without it, the whole value is looked up. */\n multipleValues?: boolean;\n}\n\nconst linters: Linter[] = [\n {\n collection: colors,\n transformer: value => {\n try {\n /* Includes alpha, so a translucent color doesn't match an opaque token. */\n return new Color(value).hexa();\n } catch {\n return '';\n }\n },\n multipleValues: true,\n },\n {\n collection: typescales,\n condition: property => property === 'font-size',\n },\n {\n collection: borderRadiuses,\n condition: property => property.startsWith('border-') && property.endsWith('-radius'),\n transformer: value => (value === '0px' ? '0' : value),\n multipleValues: true,\n },\n {\n collection: spacings,\n condition: property => property.startsWith('margin') || property.startsWith('padding'),\n transformer: value => {\n if (value === '0px') {\n return '0';\n }\n return value.startsWith('-') ? value.slice(1) : value;\n },\n multipleValues: true,\n },\n {\n collection: fontWeights,\n condition: property => property === 'font-weight',\n },\n {\n collection: opacities,\n condition: property => property === 'opacity',\n transformer: value => (value.startsWith('0.') ? value.slice(1) : value),\n },\n {\n collection: zIndexes,\n condition: property => property === 'z-index',\n },\n {\n collection: lineHeights,\n condition: property => property === 'line-height',\n },\n {\n collection: fontFamilies,\n condition: property => property === 'font-family',\n },\n];\n\nconst plugin: Rule = (_0, _1, context) => {\n return (root, result) => {\n const extension = path\n .extname(result.opts.from ?? '')\n .slice(1)\n .toLowerCase();\n\n /* Returns whether any part of the declaration's value matched a token. */\n function lint(\n decl: Declaration,\n { collection, condition, transformer, multipleValues }: Linter\n ) {\n if (condition && !condition(decl.prop)) {\n return false;\n }\n\n const values = multipleValues\n ? decl.value.split(spaceOutsideColorFunction)\n : [decl.value];\n\n let matched = false;\n for (const rawValue of values) {\n const value = transformer?.(rawValue) ?? rawValue;\n const tokens = collection.get(value);\n if (!tokens) {\n continue;\n }\n\n matched = true;\n const replacements = getReplacements(tokens, rawValue, extension);\n\n if (context.fix && replacements.length === 1) {\n values[values.indexOf(rawValue)] = replacements[0].variable;\n } else {\n /* When several tokens match, the developer picks one. */\n const message = formatMessage(replacements, rawValue);\n utils.report({ node: decl, message, word: rawValue, ruleName, result });\n }\n }\n\n if (context.fix) {\n decl.value = values.join(' ');\n }\n\n return matched;\n }\n\n root.walkDecls(decl => {\n linters.some(linter => lint(decl, linter));\n });\n };\n};\n\nplugin.ruleName = ruleName;\nplugin.messages = messages;\n\nexport = Object.assign(createPlugin(ruleName, plugin), { ruleName, messages });\n\ninterface Replacement {\n variable: string;\n source: TokenSource;\n}\n\n/*\n * Returns the variables that can replace a literal, negated when the literal is negative, for\n * example \"-16px\" becomes \"-$spacing-2\" in Sass.\n */\nfunction getReplacements(tokens: Token[], rawValue: string, extension: string) {\n const negative = rawValue.startsWith('-');\n\n return tokens.reduce<Replacement[]>((replacements, token) => {\n const plain = convertToVariable(token, extension);\n const variable = negative ? negate(plain, token.source) : plain;\n /*\n * When tokens from different sources match a literal with the same\n * replacement, issue just one replacement that --fix can apply.\n */\n return replacements.some(replacement => replacement.variable === variable)\n ? replacements\n : [...replacements, { variable, source: token.source }];\n }, []);\n}\n\nfunction convertToVariable({ name, customProperty, source }: Token, extension: string) {\n switch (extension) {\n case 'less':\n /* Anvil2 publishes no Less variables. */\n return source === DESIGN_SYSTEM_SOURCE ? `@${name}` : `var(${customProperty})`;\n\n case 'sass':\n case 'scss':\n return `$${name}`;\n\n default:\n return `var(${customProperty})`;\n }\n}\n\n/*\n * A minus sign negates only a variable that holds a plain number, such as a design-system Sass or\n * Less variable. CSS has no unary minus for var(), and Anvil2's Sass variables can hold var(), so\n * those are negated with calc().\n */\nfunction negate(variable: string, source: TokenSource) {\n return source === DESIGN_SYSTEM_SOURCE && !variable.startsWith('var(')\n ? `-${variable}`\n : `calc(-1 * ${variable})`;\n}\n\nfunction formatMessage(replacements: Replacement[], found: string) {\n const choices = replacements\n .map(({ variable, source }) => `\"${variable}\" from \\`${source}\\``)\n .join(' or ');\n return messages.variableExpected(choices, found);\n}\n"],"names":["createPlugin","utils","stylelint","spaceOutsideColorFunction","ruleName","messages","ruleMessages","variableExpected","expected","found","linters","collection","colors","transformer","value","Color","hexa","multipleValues","typescales","condition","property","borderRadiuses","startsWith","endsWith","spacings","slice","fontWeights","opacities","zIndexes","lineHeights","fontFamilies","plugin","_0","_1","context","root","result","extension","path","extname","opts","from","toLowerCase","lint","decl","prop","values","split","matched","rawValue","tokens","get","replacements","getReplacements","fix","length","indexOf","variable","message","formatMessage","report","node","word","join","walkDecls","some","linter","negative","reduce","token","plain","convertToVariable","negate","source","replacement","name","customProperty","DESIGN_SYSTEM_SOURCE","choices","map","Object","assign"],"mappings":"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"}
@@ -1,10 +1,12 @@
1
- export declare const colors: Record<string, string>;
2
- export declare const typescales: Record<string, string>;
3
- export declare const borderRadiuses: Record<string, string>;
4
- export declare const spacings: Record<string, string>;
5
- export declare const fontWeights: Record<string, string>;
6
- export declare const opacities: Record<string, string>;
7
- export declare const zIndexes: Record<string, string>;
8
- export declare const lineHeights: Record<string, string>;
9
- export declare const fontFamilies: Record<string, string>;
1
+ import { Token } from './load-tokens';
2
+ export type TokenCollection = Map<string, Token[]>;
3
+ export declare const colors: TokenCollection;
4
+ export declare const typescales: TokenCollection;
5
+ export declare const borderRadiuses: TokenCollection;
6
+ export declare const spacings: TokenCollection;
7
+ export declare const fontWeights: TokenCollection;
8
+ export declare const opacities: TokenCollection;
9
+ export declare const zIndexes: TokenCollection;
10
+ export declare const lineHeights: TokenCollection;
11
+ export declare const fontFamilies: TokenCollection;
10
12
  //# sourceMappingURL=values.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"values.d.ts","sourceRoot":"","sources":["../../src/use-tokens/values.ts"],"names":[],"mappings":"AA+BA,eAAO,MAAM,MAAM,wBAGlB,CAAC;AACF,eAAO,MAAM,UAAU,wBAA0D,CAAC;AAClF,eAAO,MAAM,cAAc,wBAA6D,CAAC;AACzF,eAAO,MAAM,QAAQ,wBAAwD,CAAC;AAC9E,eAAO,MAAM,WAAW,wBAA2D,CAAC;AACpF,eAAO,MAAM,SAAS,wBAAwD,CAAC;AAC/E,eAAO,MAAM,QAAQ,wBAAuD,CAAC;AAC7E,eAAO,MAAM,WAAW,wBAAyD,CAAC;AAClF,eAAO,MAAM,YAAY,wBAGxB,CAAC"}
1
+ {"version":3,"file":"values.d.ts","sourceRoot":"","sources":["../../src/use-tokens/values.ts"],"names":[],"mappings":"AACA,OAAO,EAAuC,KAAK,EAA2B,MAAM,eAAe,CAAC;AAGpG,MAAM,MAAM,eAAe,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;AAInD,eAAO,MAAM,MAAM,iBAGlB,CAAC;AACF,eAAO,MAAM,UAAU,iBAGrB,CAAC;AACH,eAAO,MAAM,cAAc,iBAGzB,CAAC;AACH,eAAO,MAAM,QAAQ,iBAGnB,CAAC;AACH,eAAO,MAAM,WAAW,iBAGtB,CAAC;AACH,eAAO,MAAM,SAAS,iBAAoD,CAAC;AAC3E,eAAO,MAAM,QAAQ,iBAAoD,CAAC;AAC1E,eAAO,MAAM,WAAW,iBAGtB,CAAC;AACH,eAAO,MAAM,YAAY,iBAGxB,CAAC"}