unholy-design-tokens 1.0.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.
- package/.github/workflows/lint-format-build.yml +35 -0
- package/.github/workflows/publish_release.yml +18 -0
- package/.prettierrc +9 -0
- package/ANALOGY_HOUSE.md +139 -0
- package/ANALOGY_I18NEXT.md +160 -0
- package/LICENSE +201 -0
- package/README.md +90 -0
- package/WHY_THIS_EXISTS.md +74 -0
- package/bin/build-tokens.ts +34 -0
- package/build/css/bg/bg.css +60 -0
- package/build/css/border/border.css +51 -0
- package/build/css/colors.css +204 -0
- package/build/css/conditional.css +8 -0
- package/build/css/cube/cube.block.css +18 -0
- package/build/css/cube/cube.composition.css +16 -0
- package/build/css/cube/cube.utility.css +185 -0
- package/build/css/font/font.css +24 -0
- package/build/css/space.css +20 -0
- package/build/css/text/text.css +48 -0
- package/build/css/themes/private-theme.css +228 -0
- package/build/css/themes/public-theme.css +228 -0
- package/build/css/variant/variant.css +42 -0
- package/build/css/variants.css +167 -0
- package/build/types/theme.d.ts +932 -0
- package/build/types/tokens.ts +653 -0
- package/dist/bin/build-tokens.js +27 -0
- package/dist/scripts/build-style-dictionary.js +32 -0
- package/dist/scripts/generate-typography-tokens.js +125 -0
- package/dist/src/colors/color.config.js +45 -0
- package/dist/src/colors/color.filter.js +19 -0
- package/dist/src/colors/color.formatter.js +25 -0
- package/dist/src/colors/index.js +2 -0
- package/dist/src/cube-css/cube.config.js +42 -0
- package/dist/src/cube-css/cube.formatter.js +89 -0
- package/dist/src/style-dictionary.config.js +143 -0
- package/dist/src/type-declarations/type-declarations.config.js +29 -0
- package/dist/src/type-declarations/type-declarations.formatter.js +111 -0
- package/dist/src/utils/helpers.js +9 -0
- package/dist/src/utils/index.js +4 -0
- package/dist/src/utils/template.js +83 -0
- package/dist/src/utils/tokens.js +80 -0
- package/dist/src/utils/utopia.js +19 -0
- package/eslint.config.js +67 -0
- package/package.json +60 -0
- package/scripts/build-style-dictionary.ts +44 -0
- package/scripts/generate-typography-tokens.ts +138 -0
- package/src/LICENSE +201 -0
- package/src/README.md +88 -0
- package/src/colors/color.config.ts +48 -0
- package/src/colors/color.filter.ts +28 -0
- package/src/colors/color.formatter.ts +43 -0
- package/src/colors/index.ts +6 -0
- package/src/cube-css/cube.config.ts +50 -0
- package/src/cube-css/cube.formatter.ts +104 -0
- package/src/formatters/spacing.js +95 -0
- package/src/style-dictionary.config.ts +151 -0
- package/src/theme/README.md +256 -0
- package/src/theme/cube-theme-addon.js +44 -0
- package/src/theme/helper.js +38 -0
- package/src/theme/index.js +6 -0
- package/src/theme/theme.config.js +42 -0
- package/src/theme/theme.filter.js +42 -0
- package/src/theme/theme.formatter.js +71 -0
- package/src/tokens/1 - primitives/README.md +58 -0
- package/src/tokens/1 - primitives/border.json +54 -0
- package/src/tokens/1 - primitives/breakpoint.json +10 -0
- package/src/tokens/1 - primitives/color-pool.json +266 -0
- package/src/tokens/1 - primitives/color.json +266 -0
- package/src/tokens/1 - primitives/font-scale.json +27 -0
- package/src/tokens/1 - primitives/font.json +23 -0
- package/src/tokens/1 - primitives/shadow.json +26 -0
- package/src/tokens/1 - primitives/space.json +27 -0
- package/src/tokens/2 - semantic/README.md +49 -0
- package/src/tokens/2 - semantic/border.json +27 -0
- package/src/tokens/2 - semantic/color.json +263 -0
- package/src/tokens/2 - semantic/details.md +1 -0
- package/src/tokens/2 - semantic/layout.json +52 -0
- package/src/tokens/2 - semantic/radius.json +13 -0
- package/src/tokens/2 - semantic/shadow.json +19 -0
- package/src/tokens/2 - semantic/spacing.json +25 -0
- package/src/tokens/3 - intent/README.md +43 -0
- package/src/tokens/3 - intent/background.json +135 -0
- package/src/tokens/3 - intent/color.json +265 -0
- package/src/tokens/3 - intent/font.json +61 -0
- package/src/tokens/3 - intent/text +67 -0
- package/src/tokens/README.md +176 -0
- package/src/tokens/color/brand.json +316 -0
- package/src/tokens/component/theming.json +69 -0
- package/src/tokens/conditional.json +40 -0
- package/src/tokens/custom/4 - (OPTIONAL) cube css/README.md +38 -0
- package/src/tokens/custom/4 - (OPTIONAL) cube css/block.json +24 -0
- package/src/tokens/custom/4 - (OPTIONAL) cube css/composition.json +26 -0
- package/src/tokens/custom/4 - (OPTIONAL) cube css/global.json +15 -0
- package/src/tokens/custom/4 - (OPTIONAL) cube css/utility.json +224 -0
- package/src/tokens/custom/OKlch/color.json +61 -0
- package/src/tokens/custom/OKlch/state.json +107 -0
- package/src/tokens/custom/OKlch/theme-color.json +34 -0
- package/src/tokens/custom/OKlch/variant.json +67 -0
- package/src/tokens/custom/components/highlighted.json +16 -0
- package/src/tokens/state.js +29 -0
- package/src/tokens/theme-color.json +34 -0
- package/src/type-declarations/type-declarations.config.ts +34 -0
- package/src/type-declarations/type-declarations.formatter.ts +122 -0
- package/src/utils/helpers.ts +11 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/template.ts +110 -0
- package/src/utils/tokens.ts +95 -0
- package/src/utils/utopia.ts +36 -0
- package/tailwind.md +720 -0
- package/tsconfig.json +19 -0
- package/turbowatch.ts +14 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import StyleDictionary from 'style-dictionary'
|
|
2
|
+
import type { Format } from 'style-dictionary/types'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generates a TypeScript interface declaration for all design tokens.
|
|
6
|
+
*
|
|
7
|
+
* @type {{ name: string; format: ({ dictionary }: FormatFnArguments) => string; }}
|
|
8
|
+
*
|
|
9
|
+
* Will return:
|
|
10
|
+
* export interface YThemeToken {
|
|
11
|
+
* tokenName1: string;
|
|
12
|
+
* tokenName2: string;
|
|
13
|
+
* ...
|
|
14
|
+
* }
|
|
15
|
+
*/
|
|
16
|
+
StyleDictionary.registerFormat({
|
|
17
|
+
name: 'typescript/types-declaration',
|
|
18
|
+
format: function ({ dictionary }) {
|
|
19
|
+
const props = dictionary.tokens
|
|
20
|
+
console.log('📟 - props → ', props)
|
|
21
|
+
// const types = props.map((token) => ` '${token.name}': string;`).join("\n");
|
|
22
|
+
|
|
23
|
+
// return `export interface YThemeToken {\n${types}\n}\n`;
|
|
24
|
+
},
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Generates a TypeScript interface declaration for all design tokens.
|
|
29
|
+
*
|
|
30
|
+
* Will return:
|
|
31
|
+
* export interface YThemeToken {
|
|
32
|
+
* tokenName1: string;
|
|
33
|
+
* tokenName2: string;
|
|
34
|
+
* ...
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
37
|
+
* where tokenName is the name of the token e.g. 'color-primary-100'
|
|
38
|
+
*/
|
|
39
|
+
export const tokensDeclarationFormatter: Format = {
|
|
40
|
+
name: 'typescript/tokens-declaration',
|
|
41
|
+
format: function ({ dictionary }) {
|
|
42
|
+
const myMap = dictionary.tokenMap
|
|
43
|
+
let types = ''
|
|
44
|
+
for (const value of myMap.values()) {
|
|
45
|
+
const name = value.name
|
|
46
|
+
types += ` '${name}': string;\n`
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return `export interface YThemeToken {\n${types}\n}\n`
|
|
50
|
+
},
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @type {{ name: string; format: ({ dictionary }: FormatFnArguments) => string; }}
|
|
55
|
+
*
|
|
56
|
+
* Will return:
|
|
57
|
+
* export interface DesignTokens {
|
|
58
|
+
* border: {
|
|
59
|
+
* width: {
|
|
60
|
+
* base: string;
|
|
61
|
+
* scale: string;
|
|
62
|
+
* };
|
|
63
|
+
* };
|
|
64
|
+
* ...
|
|
65
|
+
* }
|
|
66
|
+
*/
|
|
67
|
+
export const typesDeclarationFormatter: Format = {
|
|
68
|
+
name: 'typescript/types-declaration',
|
|
69
|
+
format: function ({ dictionary }) {
|
|
70
|
+
const interfaceBody = generateNestedInterface(dictionary.tokens, 1)
|
|
71
|
+
return `/**
|
|
72
|
+
* Do not edit directly, this file was auto-generated.
|
|
73
|
+
*/
|
|
74
|
+
|
|
75
|
+
export interface DesignTokens {
|
|
76
|
+
${interfaceBody}}
|
|
77
|
+
`
|
|
78
|
+
},
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Check if an object is a leaf token (has $value or value property)
|
|
83
|
+
*/
|
|
84
|
+
function isToken(obj: Record<string, unknown>): boolean {
|
|
85
|
+
return obj && typeof obj === 'object' && ('$value' in obj || 'value' in obj)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Escape property name if it contains special characters
|
|
90
|
+
*/
|
|
91
|
+
function formatKey(key: string): string {
|
|
92
|
+
// If key starts with a number or contains special chars, quote it
|
|
93
|
+
if (/^[0-9]/.test(key) || /[^a-zA-Z0-9_$]/.test(key)) {
|
|
94
|
+
return `'${key}'`
|
|
95
|
+
}
|
|
96
|
+
return key
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Recursively generate nested interface from token tree
|
|
101
|
+
*/
|
|
102
|
+
function generateNestedInterface(obj: Record<string, unknown>, depth = 0): string {
|
|
103
|
+
const indent = ' '.repeat(depth)
|
|
104
|
+
let result = ''
|
|
105
|
+
|
|
106
|
+
for (const key of Object.keys(obj)) {
|
|
107
|
+
const value = obj[key]
|
|
108
|
+
|
|
109
|
+
if (isToken(value as Record<string, unknown>)) {
|
|
110
|
+
// Leaf token - output as string type
|
|
111
|
+
result += `${indent}${formatKey(key)}: string;\n`
|
|
112
|
+
} else if (typeof value === 'object' && value !== null) {
|
|
113
|
+
// Nested object - recurse
|
|
114
|
+
const nested = generateNestedInterface(value as Record<string, unknown>, depth + 1)
|
|
115
|
+
if (nested.trim()) {
|
|
116
|
+
result += `${indent}${formatKey(key)}: {\n${nested}${indent}};\n`
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return result
|
|
122
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function capitalizeFirstLetter(string: string): string {
|
|
2
|
+
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function toKebab(s: string | number): string {
|
|
6
|
+
return String(s)
|
|
7
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1-$2")
|
|
8
|
+
.replace(/[_.]/g, "-")
|
|
9
|
+
|
|
10
|
+
.toLowerCase();
|
|
11
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for template generation.
|
|
3
|
+
* https://styledictionary.com/reference/hooks/formats/#using-a-template--templating-engine-to-create-a-format
|
|
4
|
+
*/
|
|
5
|
+
import { capitalizeFirstLetter } from "./helpers.js";
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
generateHeader,
|
|
9
|
+
generateSubheader,
|
|
10
|
+
formatInLayer,
|
|
11
|
+
generateFigmaHeaderReference,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const startComment = "/* ";
|
|
15
|
+
const endComment = " */";
|
|
16
|
+
const headerLength = 60;
|
|
17
|
+
const subheaderLength = 20;
|
|
18
|
+
const separatorChar = "-";
|
|
19
|
+
const headerSeparator = " ";
|
|
20
|
+
|
|
21
|
+
function generateSeparator(length: number): string {
|
|
22
|
+
return `${startComment}${separatorChar.repeat(length)}${endComment}`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Will generate a comment block like this:
|
|
27
|
+
/* ------------------------------------------------------------ *\/
|
|
28
|
+
/* Title *\/
|
|
29
|
+
/* ------------------------------------------------------------ *\/
|
|
30
|
+
*
|
|
31
|
+
*/
|
|
32
|
+
function generateCommentBlock(title: string, totalLength: number, separatorChar: string, indent = ""): string {
|
|
33
|
+
let titleTotalLength = totalLength - title.length;
|
|
34
|
+
let halfLength = Math.floor(titleTotalLength / 2);
|
|
35
|
+
let titleSeparator = headerSeparator.repeat(halfLength);
|
|
36
|
+
|
|
37
|
+
if (totalLength % 2 !== 0) {
|
|
38
|
+
titleSeparator += separatorChar;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
`\n${indent}${generateSeparator(totalLength)}` +
|
|
43
|
+
`\n${indent}${startComment}${titleSeparator}${title}${titleSeparator}${endComment}` +
|
|
44
|
+
`\n${indent}${generateSeparator(totalLength)}\n`
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Generates a header comment block for a given header string.
|
|
50
|
+
* /* ------------------------------------------------------------ *\/
|
|
51
|
+
* /* Header *\/
|
|
52
|
+
* /* ------------------------------------------------------------ *\/
|
|
53
|
+
*/
|
|
54
|
+
function generateHeader(header: string): string {
|
|
55
|
+
if (!header) return "";
|
|
56
|
+
|
|
57
|
+
return generateCommentBlock(
|
|
58
|
+
capitalizeFirstLetter(header),
|
|
59
|
+
headerLength,
|
|
60
|
+
separatorChar,
|
|
61
|
+
"",
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Generates a subheader comment block for a given subheader string.
|
|
67
|
+
* /* ---------------------- \/*
|
|
68
|
+
* /* Subheader *\/
|
|
69
|
+
* /* ---------------------- *\/
|
|
70
|
+
*/
|
|
71
|
+
function generateSubheader(subheader: string): string {
|
|
72
|
+
if (!subheader) return "";
|
|
73
|
+
|
|
74
|
+
return generateCommentBlock(
|
|
75
|
+
capitalizeFirstLetter(subheader),
|
|
76
|
+
subheaderLength,
|
|
77
|
+
separatorChar,
|
|
78
|
+
" ",
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Formats content within a CSS layer block.
|
|
84
|
+
* @layer name {
|
|
85
|
+
* :root {
|
|
86
|
+
* --variable: value;
|
|
87
|
+
* }
|
|
88
|
+
* }
|
|
89
|
+
*/
|
|
90
|
+
function formatInLayer(name: string, content: string): string {
|
|
91
|
+
let result = `@layer ${name} {`;
|
|
92
|
+
result += `\n`;
|
|
93
|
+
result += ` :root {`;
|
|
94
|
+
result += `\n`;
|
|
95
|
+
result += `${content}`;
|
|
96
|
+
result += ` }\n`;
|
|
97
|
+
result += `}\n`;
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Generates a Figma header reference comment block
|
|
103
|
+
* /* Collection name: <collectionName> *\/
|
|
104
|
+
* /* Mode: <mode> *\/
|
|
105
|
+
*
|
|
106
|
+
* See https://www.figma.com/community/plugin/1470777269812001046/css-variables-import-export
|
|
107
|
+
*/
|
|
108
|
+
function generateFigmaHeaderReference(collectionName: string, mode = "Light"): string {
|
|
109
|
+
return `/* Collection name: ${collectionName} */\n/* Mode: ${mode} */`;
|
|
110
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Dictionary, Token } from 'style-dictionary'
|
|
2
|
+
import { LocalOptions, TransformedToken } from 'style-dictionary/types'
|
|
3
|
+
import { getReferences, usesReferences } from 'style-dictionary/utils'
|
|
4
|
+
import { toKebab } from './helpers.js'
|
|
5
|
+
|
|
6
|
+
interface RefToken extends TransformedToken {
|
|
7
|
+
ref?: string[]
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function tokenName(token: Token) {
|
|
11
|
+
const attrs = token.attributes
|
|
12
|
+
const path = attrs?.item ? [attrs.category, attrs.type, attrs.item] : token.path
|
|
13
|
+
return path.join('-')
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// TODO:
|
|
17
|
+
export function resolveTokenReferences(
|
|
18
|
+
token: Token,
|
|
19
|
+
options: LocalOptions,
|
|
20
|
+
dictionary: Dictionary,
|
|
21
|
+
privateVar = false,
|
|
22
|
+
) {
|
|
23
|
+
const originalValue = token.original?.value
|
|
24
|
+
// if (!shouldOutputReferences(token, options, dictionary)) {
|
|
25
|
+
// return originalValue != null
|
|
26
|
+
// ? cssValue(originalValue)
|
|
27
|
+
// : cssValue(token.value);
|
|
28
|
+
// }
|
|
29
|
+
|
|
30
|
+
if (!originalValue) return cssValue(token.value)
|
|
31
|
+
|
|
32
|
+
// if (
|
|
33
|
+
// (originalValueParsed && originalValueParsed.startsWith("var(--")) ||
|
|
34
|
+
// originalValueParsed.startsWith("calc") ||
|
|
35
|
+
// originalValueParsed.startsWith("clamp")
|
|
36
|
+
// ) {
|
|
37
|
+
// ("📟 - cssValue(originalValue) → ", cssValue(originalValue));
|
|
38
|
+
// return originalValue;
|
|
39
|
+
// }
|
|
40
|
+
if (!usesReferences(originalValue)) return cssValue(token.value)
|
|
41
|
+
if (!shouldOutputReferences(token, options, dictionary)) {
|
|
42
|
+
return rewriteOriginalRefs(originalValue, dictionary.tokens, privateVar)
|
|
43
|
+
} else {
|
|
44
|
+
return cssValue(originalValue)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export function refToTokenRefString(ref: RefToken) {
|
|
48
|
+
// Verify if the ref is a style-dictionary reference object pattern or a direct var(--...) string
|
|
49
|
+
const refPath = ref.ref ?? ref.path
|
|
50
|
+
return `{${refPath.join('.')}}`
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function refToCssVar(ref: RefToken, privateVar: boolean) {
|
|
54
|
+
return `var(--${privateVar ? '_' : ''}${toKebab(ref.name)})`
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const cssValue = (v: unknown): string => {
|
|
58
|
+
if (v == null) return ''
|
|
59
|
+
if (typeof v === 'string') return v
|
|
60
|
+
if (typeof v === 'number') return String(v)
|
|
61
|
+
if (typeof v === 'boolean') return v ? 'true' : 'false'
|
|
62
|
+
if (Array.isArray(v)) return v.join(',')
|
|
63
|
+
return JSON.stringify(v)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function rewriteOriginalRefs(originalValue: unknown, dictionaryTokens: Dictionary['tokens'], privateVar: boolean): string | null {
|
|
67
|
+
if (typeof originalValue !== 'string' || !usesReferences(originalValue)) return null
|
|
68
|
+
|
|
69
|
+
const refs = getReferences(originalValue, dictionaryTokens)
|
|
70
|
+
let out = originalValue
|
|
71
|
+
|
|
72
|
+
for (const ref of refs) {
|
|
73
|
+
out = out.replaceAll(refToTokenRefString(ref), refToCssVar(ref, privateVar))
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return out
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function shouldOutputReferences(token: Token, options: LocalOptions, dictionary: Dictionary): boolean {
|
|
80
|
+
const originalValue = token.original?.value
|
|
81
|
+
if (!usesReferences(originalValue)) return false
|
|
82
|
+
const originalValueParsed = cssValue(originalValue)
|
|
83
|
+
if (
|
|
84
|
+
(originalValueParsed && originalValueParsed.startsWith('var(--')) ||
|
|
85
|
+
originalValueParsed.startsWith('calc') ||
|
|
86
|
+
originalValueParsed.startsWith('clamp')
|
|
87
|
+
) {
|
|
88
|
+
return false
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const { usesDtcg, outputReferences } = options ?? {}
|
|
92
|
+
return typeof outputReferences === 'function'
|
|
93
|
+
? outputReferences(token as TransformedToken, { dictionary, usesDtcg })
|
|
94
|
+
: Boolean(outputReferences)
|
|
95
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// src/utils/utopia.js
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Generate a Utopia fluid type scale.
|
|
5
|
+
*
|
|
6
|
+
* Based on https://utopia.fyi/type/calculator/
|
|
7
|
+
* by James Gilyead & Trys Mudford
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export function generateUtopiaScale({
|
|
11
|
+
minViewport = 360,
|
|
12
|
+
maxViewport = 1280,
|
|
13
|
+
minFont = 16,
|
|
14
|
+
maxFont = 20,
|
|
15
|
+
scaleMin = 1.2,
|
|
16
|
+
scaleMax = 1.25,
|
|
17
|
+
steps = [-2, -1, 0, 1, 2, 3, 4],
|
|
18
|
+
} = {}) {
|
|
19
|
+
const results: Record<number, string> = {};
|
|
20
|
+
|
|
21
|
+
steps.forEach((step) => {
|
|
22
|
+
const minSize = minFont * scaleMin ** step;
|
|
23
|
+
const maxSize = maxFont * scaleMax ** step;
|
|
24
|
+
|
|
25
|
+
const slope = ((maxSize - minSize) / (maxViewport - minViewport)) * 100;
|
|
26
|
+
const intercept = minSize - (slope / 100) * minViewport;
|
|
27
|
+
|
|
28
|
+
const clampValue = `clamp(${minSize / 16}rem, ${
|
|
29
|
+
intercept / 16
|
|
30
|
+
}rem + ${slope}vw, ${maxSize / 16}rem)`;
|
|
31
|
+
|
|
32
|
+
results[step] = clampValue;
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return results;
|
|
36
|
+
}
|