bsmnt 0.2.8 → 0.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -146
- package/package.json +2 -2
- package/src/helpers/integrate/sanity/files/lib/utils/metadata.ts +1 -1
- package/src/templates/next-default/README.md +28 -199
- package/src/templates/next-default/app/layout.tsx +2 -3
- package/src/templates/next-default/biome.json +1 -14
- package/src/templates/next-default/components/layout/theme/index.tsx +2 -5
- package/src/templates/next-default/components/layout/wrapper/index.tsx +1 -2
- package/src/templates/next-default/components/ui/README.md +2 -3
- package/src/templates/next-default/components/ui/image/index.tsx +3 -3
- package/src/templates/next-default/lib/README.md +3 -3
- package/src/templates/next-default/lib/hooks/use-device-detection.ts +3 -2
- package/src/templates/next-default/lib/hooks/use-media-breakpoint.ts +10 -3
- package/src/templates/next-default/lib/scripts/dev.ts +9 -29
- package/src/templates/next-default/lib/styles/README.md +7 -58
- package/src/templates/next-default/lib/styles/fonts.ts +7 -15
- package/src/templates/next-default/lib/styles/global.css +198 -0
- package/src/templates/next-default/lib/styles/index.css +3 -0
- package/src/templates/next-default/lib/styles/tokens.css +179 -0
- package/src/templates/next-default/lib/utils/global-css.d.ts +1 -0
- package/src/templates/next-default/lib/utils/metadata.ts +1 -1
- package/src/templates/next-default/lib/utils/viewport.ts +11 -5
- package/src/templates/next-default/next.config.ts +0 -1
- package/src/templates/next-default/package.json +10 -17
- package/src/templates/next-default/postcss.config.mjs +0 -14
- package/src/templates/next-default/tsconfig.tsbuildinfo +1 -0
- package/src/templates/next-experiments/README.md +29 -200
- package/src/templates/next-experiments/app/layout.tsx +2 -3
- package/src/templates/next-experiments/app/page.tsx +46 -39
- package/src/templates/next-experiments/biome.json +1 -14
- package/src/templates/next-experiments/components/layout/theme/index.tsx +2 -5
- package/src/templates/next-experiments/components/layout/wrapper/index.tsx +1 -2
- package/src/templates/next-experiments/components/ui/README.md +2 -3
- package/src/templates/next-experiments/components/ui/image/index.tsx +3 -2
- package/src/templates/next-experiments/lib/README.md +3 -3
- package/src/templates/next-experiments/lib/hooks/use-device-detection.ts +3 -2
- package/src/templates/next-experiments/lib/hooks/use-media-breakpoint.ts +10 -3
- package/src/templates/next-experiments/lib/scripts/dev.ts +9 -29
- package/src/templates/next-experiments/lib/styles/README.md +7 -58
- package/src/templates/next-experiments/lib/styles/fonts.ts +7 -15
- package/src/templates/next-experiments/lib/styles/global.css +198 -0
- package/src/templates/next-experiments/lib/styles/index.css +3 -0
- package/src/templates/next-experiments/lib/styles/tokens.css +179 -0
- package/src/templates/next-experiments/lib/utils/global-css.d.ts +1 -0
- package/src/templates/next-experiments/lib/utils/metadata.ts +1 -1
- package/src/templates/next-experiments/lib/utils/viewport.ts +11 -5
- package/src/templates/next-experiments/next.config.ts +0 -1
- package/src/templates/next-experiments/package.json +10 -21
- package/src/templates/next-experiments/postcss.config.mjs +0 -14
- package/src/templates/next-experiments/tsconfig.tsbuildinfo +1 -0
- package/src/templates/next-webgl/README.md +30 -200
- package/src/templates/next-webgl/app/layout.tsx +2 -3
- package/src/templates/next-webgl/biome.json +1 -14
- package/src/templates/next-webgl/components/layout/theme/index.tsx +2 -5
- package/src/templates/next-webgl/components/layout/wrapper/index.tsx +1 -2
- package/src/templates/next-webgl/components/ui/README.md +2 -3
- package/src/templates/next-webgl/components/ui/image/index.tsx +3 -3
- package/src/templates/next-webgl/lib/README.md +3 -3
- package/src/templates/next-webgl/lib/hooks/use-device-detection.ts +3 -2
- package/src/templates/next-webgl/lib/hooks/use-media-breakpoint.ts +10 -3
- package/src/templates/next-webgl/lib/scripts/dev.ts +9 -29
- package/src/templates/next-webgl/lib/styles/README.md +7 -58
- package/src/templates/next-webgl/lib/styles/fonts.ts +7 -15
- package/src/templates/next-webgl/lib/styles/global.css +198 -0
- package/src/templates/next-webgl/lib/styles/index.css +3 -0
- package/src/templates/next-webgl/lib/styles/tokens.css +179 -0
- package/src/templates/next-webgl/lib/utils/global-css.d.ts +1 -0
- package/src/templates/next-webgl/lib/utils/metadata.ts +1 -1
- package/src/templates/next-webgl/lib/utils/viewport.ts +11 -5
- package/src/templates/next-webgl/next.config.ts +0 -1
- package/src/templates/next-webgl/package.json +10 -19
- package/src/templates/next-webgl/postcss.config.mjs +0 -14
- package/src/templates/next-webgl/tsconfig.tsbuildinfo +1 -0
- package/src/templates/next-default/components/ui/image/image.module.css +0 -5
- package/src/templates/next-default/lib/scripts/generate-component.ts +0 -322
- package/src/templates/next-default/lib/scripts/generate-page.ts +0 -193
- package/src/templates/next-default/lib/scripts/generate.ts +0 -79
- package/src/templates/next-default/lib/store/app.ts +0 -11
- package/src/templates/next-default/lib/store/index.ts +0 -11
- package/src/templates/next-default/lib/styles/colors.ts +0 -63
- package/src/templates/next-default/lib/styles/config.ts +0 -34
- package/src/templates/next-default/lib/styles/css/global.css +0 -85
- package/src/templates/next-default/lib/styles/css/index.css +0 -6
- package/src/templates/next-default/lib/styles/css/reset.css +0 -166
- package/src/templates/next-default/lib/styles/css/root.css +0 -68
- package/src/templates/next-default/lib/styles/css/tailwind.css +0 -132
- package/src/templates/next-default/lib/styles/easings.ts +0 -21
- package/src/templates/next-default/lib/styles/index.ts +0 -12
- package/src/templates/next-default/lib/styles/layout.mjs +0 -27
- package/src/templates/next-default/lib/styles/scripts/README.md +0 -29
- package/src/templates/next-default/lib/styles/scripts/generate-root.ts +0 -57
- package/src/templates/next-default/lib/styles/scripts/generate-tailwind.ts +0 -162
- package/src/templates/next-default/lib/styles/scripts/postcss-functions.mjs +0 -168
- package/src/templates/next-default/lib/styles/scripts/setup-styles.ts +0 -24
- package/src/templates/next-default/lib/styles/scripts/utils.ts +0 -20
- package/src/templates/next-default/lib/styles/typography.ts +0 -36
- package/src/templates/next-default/lib/utils/css.d.ts +0 -21
- package/src/templates/next-default/lib/utils/math.test.ts +0 -221
- package/src/templates/next-default/lib/utils/strings.test.ts +0 -166
- package/src/templates/next-default/lib/utils/viewport.test.ts +0 -256
- package/src/templates/next-default/public/fonts/geist/Geist-Mono.woff2 +0 -0
- package/src/templates/next-experiments/components/ui/image/image.module.css +0 -5
- package/src/templates/next-experiments/lib/scripts/generate-component.ts +0 -322
- package/src/templates/next-experiments/lib/scripts/generate-page.ts +0 -193
- package/src/templates/next-experiments/lib/scripts/generate.ts +0 -79
- package/src/templates/next-experiments/lib/store/app.ts +0 -11
- package/src/templates/next-experiments/lib/store/index.ts +0 -11
- package/src/templates/next-experiments/lib/styles/colors.ts +0 -63
- package/src/templates/next-experiments/lib/styles/config.ts +0 -34
- package/src/templates/next-experiments/lib/styles/css/global.css +0 -85
- package/src/templates/next-experiments/lib/styles/css/index.css +0 -6
- package/src/templates/next-experiments/lib/styles/css/reset.css +0 -166
- package/src/templates/next-experiments/lib/styles/css/root.css +0 -68
- package/src/templates/next-experiments/lib/styles/css/tailwind.css +0 -132
- package/src/templates/next-experiments/lib/styles/easings.ts +0 -21
- package/src/templates/next-experiments/lib/styles/index.ts +0 -12
- package/src/templates/next-experiments/lib/styles/layout.mjs +0 -27
- package/src/templates/next-experiments/lib/styles/scripts/README.md +0 -29
- package/src/templates/next-experiments/lib/styles/scripts/generate-root.ts +0 -57
- package/src/templates/next-experiments/lib/styles/scripts/generate-tailwind.ts +0 -162
- package/src/templates/next-experiments/lib/styles/scripts/postcss-functions.mjs +0 -168
- package/src/templates/next-experiments/lib/styles/scripts/setup-styles.ts +0 -24
- package/src/templates/next-experiments/lib/styles/scripts/utils.ts +0 -20
- package/src/templates/next-experiments/lib/styles/typography.ts +0 -36
- package/src/templates/next-experiments/lib/utils/css.d.ts +0 -21
- package/src/templates/next-experiments/lib/utils/math.test.ts +0 -221
- package/src/templates/next-experiments/lib/utils/strings.test.ts +0 -166
- package/src/templates/next-experiments/lib/utils/viewport.test.ts +0 -256
- package/src/templates/next-experiments/public/fonts/geist/Geist-Mono.woff2 +0 -0
- package/src/templates/next-webgl/components/ui/image/image.module.css +0 -5
- package/src/templates/next-webgl/lib/scripts/generate-component.ts +0 -322
- package/src/templates/next-webgl/lib/scripts/generate-page.ts +0 -193
- package/src/templates/next-webgl/lib/scripts/generate.ts +0 -79
- package/src/templates/next-webgl/lib/store/app.ts +0 -11
- package/src/templates/next-webgl/lib/store/index.ts +0 -11
- package/src/templates/next-webgl/lib/styles/colors.ts +0 -63
- package/src/templates/next-webgl/lib/styles/config.ts +0 -34
- package/src/templates/next-webgl/lib/styles/css/global.css +0 -85
- package/src/templates/next-webgl/lib/styles/css/index.css +0 -6
- package/src/templates/next-webgl/lib/styles/css/reset.css +0 -166
- package/src/templates/next-webgl/lib/styles/css/root.css +0 -68
- package/src/templates/next-webgl/lib/styles/css/tailwind.css +0 -132
- package/src/templates/next-webgl/lib/styles/easings.ts +0 -21
- package/src/templates/next-webgl/lib/styles/index.ts +0 -12
- package/src/templates/next-webgl/lib/styles/layout.mjs +0 -27
- package/src/templates/next-webgl/lib/styles/scripts/README.md +0 -29
- package/src/templates/next-webgl/lib/styles/scripts/generate-root.ts +0 -57
- package/src/templates/next-webgl/lib/styles/scripts/generate-tailwind.ts +0 -162
- package/src/templates/next-webgl/lib/styles/scripts/postcss-functions.mjs +0 -168
- package/src/templates/next-webgl/lib/styles/scripts/setup-styles.ts +0 -24
- package/src/templates/next-webgl/lib/styles/scripts/utils.ts +0 -20
- package/src/templates/next-webgl/lib/styles/typography.ts +0 -36
- package/src/templates/next-webgl/lib/utils/css.d.ts +0 -21
- package/src/templates/next-webgl/lib/utils/math.test.ts +0 -221
- package/src/templates/next-webgl/lib/utils/strings.test.ts +0 -166
- package/src/templates/next-webgl/lib/utils/viewport.test.ts +0 -256
- package/src/templates/next-webgl/public/fonts/geist/Geist-Mono.woff2 +0 -0
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import type { Config } from "../config"
|
|
2
|
-
import { formatObject } from "./utils"
|
|
3
|
-
|
|
4
|
-
export function generateTailwind({
|
|
5
|
-
breakpoints,
|
|
6
|
-
colors,
|
|
7
|
-
customSizes,
|
|
8
|
-
easings,
|
|
9
|
-
fonts,
|
|
10
|
-
palettes,
|
|
11
|
-
themes,
|
|
12
|
-
typography,
|
|
13
|
-
}: Pick<
|
|
14
|
-
Config,
|
|
15
|
-
| "breakpoints"
|
|
16
|
-
| "colors"
|
|
17
|
-
| "customSizes"
|
|
18
|
-
| "easings"
|
|
19
|
-
| "fonts"
|
|
20
|
-
| "palettes"
|
|
21
|
-
| "themes"
|
|
22
|
-
| "typography"
|
|
23
|
-
>) {
|
|
24
|
-
// Theme
|
|
25
|
-
const themeEntries = Object.entries(themes)
|
|
26
|
-
const firstTheme = themeEntries[0]?.[1] ?? {}
|
|
27
|
-
const theme = `/** Custom theme **/
|
|
28
|
-
@theme {
|
|
29
|
-
--breakpoint-*: initial;
|
|
30
|
-
${formatObject(breakpoints, ([name, value]) => `--breakpoint-${name}: ${value}px;`)}
|
|
31
|
-
|
|
32
|
-
--color-*: initial;
|
|
33
|
-
${formatObject(firstTheme, ([key, value]) => `--color-${key}: ${value};`)}
|
|
34
|
-
${formatObject(colors, ([key, value]) => `--color-${key}: ${value};`)}
|
|
35
|
-
|
|
36
|
-
${Object.entries(palettes)
|
|
37
|
-
.filter(([, scaleValues]) => Object.keys(scaleValues).length > 1)
|
|
38
|
-
.map(
|
|
39
|
-
([paletteName, paletteValues]) =>
|
|
40
|
-
`/* ${paletteName} */\n\t` +
|
|
41
|
-
Object.entries(paletteValues)
|
|
42
|
-
.map(([shade, value]) => `--color-${paletteName}-${shade}: ${value};`)
|
|
43
|
-
.join("\n\t")
|
|
44
|
-
)
|
|
45
|
-
.join("\n\n\t")}
|
|
46
|
-
|
|
47
|
-
--spacing: 0.25rem;
|
|
48
|
-
--spacing-0: 0;
|
|
49
|
-
--spacing-safe: var(--safe);
|
|
50
|
-
--spacing-gap: var(--gap);
|
|
51
|
-
${formatObject(customSizes, ([key]) => `--spacing-${key}: var(--${key});`)}
|
|
52
|
-
|
|
53
|
-
--font-*: initial;
|
|
54
|
-
${formatObject(fonts, ([name, variableName]) => `--font-${name}: var(${variableName});`)}
|
|
55
|
-
|
|
56
|
-
--ease-*: initial;
|
|
57
|
-
${formatObject(easings, ([name, value]) => `--ease-${name}: ${value};`)}
|
|
58
|
-
}`
|
|
59
|
-
|
|
60
|
-
// Theme overwrites
|
|
61
|
-
const themeOverwrites = `
|
|
62
|
-
/** Custom theme overwrites **/
|
|
63
|
-
${formatObject(
|
|
64
|
-
themes,
|
|
65
|
-
([name, value]) => `[data-theme=${name}] {
|
|
66
|
-
${formatObject(value, ([key, value]) => `--color-${key}: ${value};`)}
|
|
67
|
-
}`,
|
|
68
|
-
"\n"
|
|
69
|
-
)}
|
|
70
|
-
`
|
|
71
|
-
|
|
72
|
-
// Utilities
|
|
73
|
-
const utilities = `
|
|
74
|
-
/** Custom static utilities **/
|
|
75
|
-
${Object.entries(typography)
|
|
76
|
-
.map(
|
|
77
|
-
([name, value]) => `@utility ${name} {
|
|
78
|
-
${Object.entries(value)
|
|
79
|
-
.filter((entry) => entry?.[0] && entry?.[1])
|
|
80
|
-
.filter((entry) => entry !== undefined)
|
|
81
|
-
.map(([key, value]) => {
|
|
82
|
-
if (key === "font-size") {
|
|
83
|
-
if (typeof value === "number") {
|
|
84
|
-
return `font-size: ${value}px;`
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (
|
|
88
|
-
typeof value === "object" &&
|
|
89
|
-
"mobile" in value &&
|
|
90
|
-
"desktop" in value
|
|
91
|
-
) {
|
|
92
|
-
return [
|
|
93
|
-
`font-size: ${(value?.mobile as number) ?? 0}px;`,
|
|
94
|
-
`@variant desktop { font-size: ${(value?.desktop as number) ?? 0}px; }`,
|
|
95
|
-
].join("\n\t")
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return `font-size: ${value as unknown as number}px;`
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (typeof value === "object") {
|
|
102
|
-
return [
|
|
103
|
-
`${key}: ${value.mobile};`,
|
|
104
|
-
`@variant desktop { ${key}: ${value.desktop}; }`,
|
|
105
|
-
].join("\n\t")
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return `${key}: ${value};`
|
|
109
|
-
})
|
|
110
|
-
.join("\n\t")}
|
|
111
|
-
}`
|
|
112
|
-
)
|
|
113
|
-
.join("\n\n")}
|
|
114
|
-
|
|
115
|
-
@utility desktop-only {
|
|
116
|
-
@media (--mobile) {
|
|
117
|
-
display: none !important;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
@utility mobile-only {
|
|
122
|
-
@media (--desktop) {
|
|
123
|
-
display: none !important;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
@utility b-grid {
|
|
128
|
-
display: grid;
|
|
129
|
-
grid-template-columns: repeat(var(--columns), 1fr);
|
|
130
|
-
column-gap: var(--gap);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
@utility b-layout-block {
|
|
134
|
-
margin-inline: auto;
|
|
135
|
-
width: calc(100% - 2 * var(--safe));
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
@utility b-layout-block-inner {
|
|
139
|
-
padding-inline: var(--safe);
|
|
140
|
-
width: 100%;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
@utility b-layout-grid {
|
|
144
|
-
@apply b-layout-block b-grid;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
@utility b-layout-grid-inner {
|
|
148
|
-
@apply b-layout-block-inner b-grid;
|
|
149
|
-
}`
|
|
150
|
-
|
|
151
|
-
// Variants
|
|
152
|
-
const variants = `
|
|
153
|
-
/** Custom variants **/
|
|
154
|
-
${Object.keys(themes)
|
|
155
|
-
.map(
|
|
156
|
-
(name) =>
|
|
157
|
-
`@custom-variant ${name} (&:where([data-theme=${name}], [data-theme=${name}] *));`
|
|
158
|
-
)
|
|
159
|
-
.join("\n")}`
|
|
160
|
-
|
|
161
|
-
return [theme, themeOverwrites, utilities, variants].join("\n")
|
|
162
|
-
}
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
// THIS FILE HAS TO STAY .mjs AS ITS CONSUMED BY POSTCSS
|
|
2
|
-
import { breakpoints } from "../layout.mjs"
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Resolves a context size to a pixel value.
|
|
6
|
-
* @param {string | number} context - Context identifier or pixel value
|
|
7
|
-
* @returns {number} Pixel value
|
|
8
|
-
*/
|
|
9
|
-
function resolveContext(context) {
|
|
10
|
-
if (typeof context === "number") {
|
|
11
|
-
return context
|
|
12
|
-
}
|
|
13
|
-
const numContext = Number.parseFloat(context)
|
|
14
|
-
if (!Number.isNaN(numContext)) {
|
|
15
|
-
return numContext
|
|
16
|
-
}
|
|
17
|
-
return breakpoints[context] ?? breakpoints.desktop
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Validates and parses a pixel value.
|
|
22
|
-
* @param {string} value - Pixel value to parse
|
|
23
|
-
* @returns {number} Parsed pixel value
|
|
24
|
-
*/
|
|
25
|
-
function parsePixels(value) {
|
|
26
|
-
const numValue = Number.parseFloat(value)
|
|
27
|
-
if (Number.isNaN(numValue)) {
|
|
28
|
-
throw new Error(`Invalid pixel value: ${value}`)
|
|
29
|
-
}
|
|
30
|
-
return numValue
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Rounds a number to a maximum of 4 decimal places, removing trailing zeros.
|
|
35
|
-
* @param {number} value - Number to round
|
|
36
|
-
* @returns {string} Rounded number as string without trailing zeros
|
|
37
|
-
*/
|
|
38
|
-
function roundToMaxDecimals(value) {
|
|
39
|
-
// Round to 4 decimal places
|
|
40
|
-
const rounded = Math.round(value * 10000) / 10000
|
|
41
|
-
// Convert to string and remove trailing zeros only after decimal point
|
|
42
|
-
return rounded
|
|
43
|
-
.toString()
|
|
44
|
-
.replace(/\.0+$/, "")
|
|
45
|
-
.replace(/(\.\d*?)0+$/, "$1")
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export const functions = {
|
|
49
|
-
/**
|
|
50
|
-
* Converts a pixel value to viewport width units (vw).
|
|
51
|
-
* Optionally applies a minimum value using CSS max().
|
|
52
|
-
*
|
|
53
|
-
* Supports flexible parameter patterns:
|
|
54
|
-
* - `tovw(target)` - Uses default desktop context
|
|
55
|
-
* - `tovw(target, min)` - Sets minimum value (numeric)
|
|
56
|
-
* - `tovw(target, context)` - Sets context (string identifier)
|
|
57
|
-
* - `tovw(target, min, context)` - Sets both min and context
|
|
58
|
-
*
|
|
59
|
-
* @param {string} target - Target pixel value to convert
|
|
60
|
-
* @param {string} [minOrContext] - Minimum pixel value OR context identifier
|
|
61
|
-
* @param {string} [context] - Context size identifier (if min was provided)
|
|
62
|
-
* @returns {string} CSS string with vw units
|
|
63
|
-
*
|
|
64
|
-
* @example
|
|
65
|
-
* tovw(100) // "6.94vw"
|
|
66
|
-
* tovw(100, 50) // "max(50px, 6.94vw)"
|
|
67
|
-
* tovw(16, 'mobile') // "4.27vw" (no need for undefined!)
|
|
68
|
-
* tovw(100, 50, 'mobile') // "max(50px, 6.94vw)" with mobile context
|
|
69
|
-
*/
|
|
70
|
-
tovw: (target, minOrContext, context) => {
|
|
71
|
-
const numTarget = parsePixels(target)
|
|
72
|
-
if (numTarget === 0) {
|
|
73
|
-
return "0"
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
let min
|
|
77
|
-
let resolvedContext = "desktop"
|
|
78
|
-
|
|
79
|
-
if (minOrContext !== undefined && minOrContext !== "") {
|
|
80
|
-
// Fast check: is it a known breakpoint key?
|
|
81
|
-
if (minOrContext in breakpoints) {
|
|
82
|
-
// Second param is context
|
|
83
|
-
resolvedContext = minOrContext
|
|
84
|
-
if (context !== undefined && context !== "") {
|
|
85
|
-
resolvedContext = context
|
|
86
|
-
}
|
|
87
|
-
} else {
|
|
88
|
-
// Second param is min value (numeric)
|
|
89
|
-
min = parsePixels(minOrContext)
|
|
90
|
-
if (context !== undefined && context !== "") {
|
|
91
|
-
resolvedContext = context
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
} else if (context !== undefined && context !== "") {
|
|
95
|
-
// Only context provided as third param (legacy support)
|
|
96
|
-
resolvedContext = context
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const contextSize = resolveContext(resolvedContext)
|
|
100
|
-
const vwValue = (numTarget / contextSize) * 100
|
|
101
|
-
|
|
102
|
-
if (min !== undefined) {
|
|
103
|
-
return `max(${min}px, ${roundToMaxDecimals(vwValue)}vw)`
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return `${roundToMaxDecimals(vwValue)}vw`
|
|
107
|
-
},
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Converts a pixel value to rem units.
|
|
111
|
-
*
|
|
112
|
-
* @param {string} target - Target pixel value to convert
|
|
113
|
-
* @param {string} [context='16'] - Base font size in pixels
|
|
114
|
-
* @returns {string} CSS string with rem units
|
|
115
|
-
*
|
|
116
|
-
* @example
|
|
117
|
-
* torem(24) // "1.5rem"
|
|
118
|
-
* torem(18, 14) // "1.29rem"
|
|
119
|
-
*/
|
|
120
|
-
torem: (target, context = "16") => {
|
|
121
|
-
const numTarget = parsePixels(target)
|
|
122
|
-
if (numTarget === 0) {
|
|
123
|
-
return "0"
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const numContext = parsePixels(context)
|
|
127
|
-
return `${roundToMaxDecimals(numTarget / numContext)}rem`
|
|
128
|
-
},
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Converts a pixel value to em units.
|
|
132
|
-
*
|
|
133
|
-
* @param {string} target - Target pixel value to convert
|
|
134
|
-
* @param {string} context - Context size in pixels (required)
|
|
135
|
-
* @returns {string} CSS string with em units
|
|
136
|
-
*
|
|
137
|
-
* @example
|
|
138
|
-
* toem(24, 16) // "1.5em"
|
|
139
|
-
* toem(18, 14) // "1.29em"
|
|
140
|
-
*/
|
|
141
|
-
toem: (target, context) => {
|
|
142
|
-
const numTarget = parsePixels(target)
|
|
143
|
-
if (numTarget === 0) {
|
|
144
|
-
return "0"
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (!context) {
|
|
148
|
-
throw new Error("toem requires a context parameter")
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const numContext = parsePixels(context)
|
|
152
|
-
return `${roundToMaxDecimals(numTarget / numContext)}em`
|
|
153
|
-
},
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Calculates column width based on number of columns.
|
|
157
|
-
*
|
|
158
|
-
* @param {string} columns - Number of columns
|
|
159
|
-
* @returns {string} CSS calc expression
|
|
160
|
-
*/
|
|
161
|
-
columns: (columns) => {
|
|
162
|
-
const numColumns = Number.parseFloat(columns)
|
|
163
|
-
if (Number.isNaN(numColumns)) {
|
|
164
|
-
throw new Error(`Invalid column value: ${columns}`)
|
|
165
|
-
}
|
|
166
|
-
return `calc((${numColumns} * var(--column-width)) + ((${numColumns} - 1) * var(--gap)))`
|
|
167
|
-
},
|
|
168
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import * as config from "../config"
|
|
2
|
-
import { generateRoot } from "./generate-root"
|
|
3
|
-
import { generateTailwind } from "./generate-tailwind"
|
|
4
|
-
|
|
5
|
-
const tailwind = generateTailwind(config)
|
|
6
|
-
const root = generateRoot(config)
|
|
7
|
-
|
|
8
|
-
const banner = `/*
|
|
9
|
-
* THIS FILE IS GENERATED BY setup-styles.ts
|
|
10
|
-
* DO NOT EDIT IT DIRECTLY.
|
|
11
|
-
*/`
|
|
12
|
-
|
|
13
|
-
const tailwindcss = [banner, tailwind]
|
|
14
|
-
const rootcss = [banner, root]
|
|
15
|
-
|
|
16
|
-
await Bun.write("./lib/styles/css/tailwind.css", tailwindcss.join("\n\n"))
|
|
17
|
-
await Bun.write("./lib/styles/css/root.css", rootcss.join("\n\n"))
|
|
18
|
-
|
|
19
|
-
console.log(
|
|
20
|
-
Bun.color("green", "ansi"),
|
|
21
|
-
"✓",
|
|
22
|
-
Bun.color("black", "ansi"),
|
|
23
|
-
"Style config generated successfully"
|
|
24
|
-
)
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export function scalingCalc(value: number) {
|
|
2
|
-
return `calc(((${value} * 100) / var(--device-width)) * 1vw)`
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Format an object into a string of CSS variables
|
|
7
|
-
* @param obj - The object to format
|
|
8
|
-
* @param mapper - A function that maps the object's entries to a string
|
|
9
|
-
* @param joiner - The string to join the mapped entries with
|
|
10
|
-
* @returns A string of CSS variables
|
|
11
|
-
*/
|
|
12
|
-
export function formatObject<Obj extends Record<string, unknown>>(
|
|
13
|
-
obj: Obj,
|
|
14
|
-
mapper: (args: [key: keyof Obj, value: Obj[keyof Obj]]) => string,
|
|
15
|
-
joiner = "\n\t"
|
|
16
|
-
) {
|
|
17
|
-
return Object.entries(obj)
|
|
18
|
-
.map(([key, value]) => mapper([key as keyof Obj, value as Obj[keyof Obj]]))
|
|
19
|
-
.join(joiner)
|
|
20
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import type { CSSProperties } from "react"
|
|
2
|
-
|
|
3
|
-
const fonts = {
|
|
4
|
-
mono: "--geist-mono", // this should be the variable name defined in fonts.ts
|
|
5
|
-
} as const
|
|
6
|
-
|
|
7
|
-
const typography: TypeStyles = {
|
|
8
|
-
"test-mono": {
|
|
9
|
-
"font-family": `var(${fonts.mono})`,
|
|
10
|
-
"font-style": "normal",
|
|
11
|
-
"font-weight": 400,
|
|
12
|
-
"line-height": "90%",
|
|
13
|
-
"letter-spacing": "0em",
|
|
14
|
-
"font-size": { mobile: 20, desktop: 24 },
|
|
15
|
-
},
|
|
16
|
-
} as const
|
|
17
|
-
|
|
18
|
-
export { fonts, typography }
|
|
19
|
-
|
|
20
|
-
// UTIL TYPES
|
|
21
|
-
type TypeStyles = Record<
|
|
22
|
-
string,
|
|
23
|
-
{
|
|
24
|
-
"font-family": string
|
|
25
|
-
"font-style": CSSProperties["fontStyle"]
|
|
26
|
-
"font-weight": CSSProperties["fontWeight"]
|
|
27
|
-
"line-height":
|
|
28
|
-
| `${number}%`
|
|
29
|
-
| { mobile: `${number}%`; desktop: `${number}%` }
|
|
30
|
-
"letter-spacing":
|
|
31
|
-
| `${number}em`
|
|
32
|
-
| { mobile: `${number}em`; desktop: `${number}em` }
|
|
33
|
-
"font-feature-settings"?: string
|
|
34
|
-
"font-size": number | { mobile: number; desktop: number }
|
|
35
|
-
}
|
|
36
|
-
>
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// CSS module type declarations (ambient - no imports allowed)
|
|
2
|
-
|
|
3
|
-
declare module "*.module.css" {
|
|
4
|
-
const classes: { [key: string]: string }
|
|
5
|
-
export default classes
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
declare module "*.module.scss" {
|
|
9
|
-
const classes: { [key: string]: string }
|
|
10
|
-
export default classes
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
declare module "*.module.sass" {
|
|
14
|
-
const classes: { [key: string]: string }
|
|
15
|
-
export default classes
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// Regular CSS imports
|
|
19
|
-
declare module "*.css"
|
|
20
|
-
declare module "*.scss"
|
|
21
|
-
declare module "*.sass"
|
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unit tests for math utilities
|
|
3
|
-
*
|
|
4
|
-
* Run with: bun test lib/utils/math.test.ts
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { describe, expect, it } from "bun:test"
|
|
8
|
-
import {
|
|
9
|
-
clamp,
|
|
10
|
-
degToRad,
|
|
11
|
-
distance,
|
|
12
|
-
lerp,
|
|
13
|
-
mapRange,
|
|
14
|
-
modulo,
|
|
15
|
-
normalize,
|
|
16
|
-
radToDeg,
|
|
17
|
-
roundTo,
|
|
18
|
-
truncate,
|
|
19
|
-
} from "./math"
|
|
20
|
-
|
|
21
|
-
describe("clamp", () => {
|
|
22
|
-
it("should return input when within bounds", () => {
|
|
23
|
-
expect(clamp(0, 50, 100)).toBe(50)
|
|
24
|
-
expect(clamp(-10, 0, 10)).toBe(0)
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it("should return min when input is below min", () => {
|
|
28
|
-
expect(clamp(0, -5, 100)).toBe(0)
|
|
29
|
-
expect(clamp(10, 5, 20)).toBe(10)
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
it("should return max when input is above max", () => {
|
|
33
|
-
expect(clamp(0, 150, 100)).toBe(100)
|
|
34
|
-
expect(clamp(10, 25, 20)).toBe(20)
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
it("should handle edge cases", () => {
|
|
38
|
-
expect(clamp(0, 0, 100)).toBe(0)
|
|
39
|
-
expect(clamp(0, 100, 100)).toBe(100)
|
|
40
|
-
})
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
describe("lerp", () => {
|
|
44
|
-
it("should return start when amount is 0", () => {
|
|
45
|
-
expect(lerp(0, 100, 0)).toBe(0)
|
|
46
|
-
expect(lerp(-50, 50, 0)).toBe(-50)
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
it("should return end when amount is 1", () => {
|
|
50
|
-
expect(lerp(0, 100, 1)).toBe(100)
|
|
51
|
-
expect(lerp(-50, 50, 1)).toBe(50)
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
it("should return midpoint when amount is 0.5", () => {
|
|
55
|
-
expect(lerp(0, 100, 0.5)).toBe(50)
|
|
56
|
-
expect(lerp(-100, 100, 0.5)).toBe(0)
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
it("should handle intermediate values", () => {
|
|
60
|
-
expect(lerp(0, 100, 0.25)).toBe(25)
|
|
61
|
-
expect(lerp(0, 100, 0.75)).toBe(75)
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
it("should extrapolate beyond 0-1 range", () => {
|
|
65
|
-
expect(lerp(0, 100, 1.5)).toBe(150)
|
|
66
|
-
expect(lerp(0, 100, -0.5)).toBe(-50)
|
|
67
|
-
})
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
describe("mapRange", () => {
|
|
71
|
-
it("should map value from one range to another", () => {
|
|
72
|
-
expect(mapRange(0, 100, 50, 0, 1)).toBe(0.5)
|
|
73
|
-
expect(mapRange(0, 1000, 500, 0, 1)).toBe(0.5)
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
it("should handle inverted output ranges", () => {
|
|
77
|
-
expect(mapRange(0, 100, 50, 1, 0)).toBe(0.5)
|
|
78
|
-
expect(mapRange(0, 100, 0, 1, 0)).toBe(1)
|
|
79
|
-
expect(mapRange(0, 100, 100, 1, 0)).toBe(0)
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
it("should not clamp by default", () => {
|
|
83
|
-
expect(mapRange(0, 100, 150, 0, 1)).toBe(1.5)
|
|
84
|
-
expect(mapRange(0, 100, -50, 0, 1)).toBe(-0.5)
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
it("should clamp when shouldClamp is true", () => {
|
|
88
|
-
expect(mapRange(0, 100, 150, 0, 1, true)).toBe(1)
|
|
89
|
-
expect(mapRange(0, 100, -50, 0, 1, true)).toBe(0)
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
it("should clamp inverted ranges correctly", () => {
|
|
93
|
-
expect(mapRange(0, 100, 150, 1, 0, true)).toBe(0)
|
|
94
|
-
expect(mapRange(0, 100, -50, 1, 0, true)).toBe(1)
|
|
95
|
-
})
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
describe("truncate", () => {
|
|
99
|
-
it("should truncate to specified decimal places", () => {
|
|
100
|
-
expect(truncate(1.23456789, 2)).toBe(1.23)
|
|
101
|
-
expect(truncate(1.23456789, 3)).toBe(1.235)
|
|
102
|
-
expect(truncate(1.23456789, 4)).toBe(1.2346)
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
it("should handle 0 decimal places", () => {
|
|
106
|
-
expect(truncate(1.23456789, 0)).toBe(1)
|
|
107
|
-
expect(truncate(3.9, 0)).toBe(4)
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
it("should handle already truncated numbers", () => {
|
|
111
|
-
expect(truncate(3.14, 2)).toBe(3.14)
|
|
112
|
-
expect(truncate(5, 2)).toBe(5)
|
|
113
|
-
})
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
describe("modulo", () => {
|
|
117
|
-
it("should work like JavaScript % for positive numbers", () => {
|
|
118
|
-
expect(modulo(5, 3)).toBe(2)
|
|
119
|
-
expect(modulo(10, 4)).toBe(2)
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
it("should handle negative dividends correctly (true modulo)", () => {
|
|
123
|
-
expect(modulo(-1, 3)).toBe(2)
|
|
124
|
-
expect(modulo(-5, 3)).toBe(1)
|
|
125
|
-
expect(modulo(-10, 4)).toBe(2)
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
it("should return input when divisor is 0", () => {
|
|
129
|
-
expect(modulo(5, 0)).toBe(5)
|
|
130
|
-
expect(modulo(-5, 0)).toBe(-5)
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
it("should return NaN for negative divisors", () => {
|
|
134
|
-
expect(modulo(5, -3)).toBeNaN()
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
it("should wrap array indices correctly", () => {
|
|
138
|
-
const length = 5
|
|
139
|
-
expect(modulo(-1, length)).toBe(4)
|
|
140
|
-
expect(modulo(5, length)).toBe(0)
|
|
141
|
-
expect(modulo(7, length)).toBe(2)
|
|
142
|
-
})
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
describe("roundTo", () => {
|
|
146
|
-
it("should round to the nearest multiple", () => {
|
|
147
|
-
expect(roundTo(23, 10)).toBe(20)
|
|
148
|
-
expect(roundTo(27, 10)).toBe(30)
|
|
149
|
-
expect(roundTo(25, 10)).toBe(30)
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
it("should handle decimal multiples", () => {
|
|
153
|
-
expect(roundTo(0.23, 0.1)).toBeCloseTo(0.2, 10)
|
|
154
|
-
expect(roundTo(0.27, 0.1)).toBeCloseTo(0.3, 10)
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
it("should handle exact multiples", () => {
|
|
158
|
-
expect(roundTo(20, 10)).toBe(20)
|
|
159
|
-
expect(roundTo(0.5, 0.5)).toBe(0.5)
|
|
160
|
-
})
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
describe("degToRad", () => {
|
|
164
|
-
it("should convert degrees to radians", () => {
|
|
165
|
-
expect(degToRad(0)).toBe(0)
|
|
166
|
-
expect(degToRad(180)).toBeCloseTo(Math.PI, 10)
|
|
167
|
-
expect(degToRad(90)).toBeCloseTo(Math.PI / 2, 10)
|
|
168
|
-
expect(degToRad(360)).toBeCloseTo(Math.PI * 2, 10)
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
it("should handle negative degrees", () => {
|
|
172
|
-
expect(degToRad(-90)).toBeCloseTo(-Math.PI / 2, 10)
|
|
173
|
-
})
|
|
174
|
-
})
|
|
175
|
-
|
|
176
|
-
describe("radToDeg", () => {
|
|
177
|
-
it("should convert radians to degrees", () => {
|
|
178
|
-
expect(radToDeg(0)).toBe(0)
|
|
179
|
-
expect(radToDeg(Math.PI)).toBeCloseTo(180, 10)
|
|
180
|
-
expect(radToDeg(Math.PI / 2)).toBeCloseTo(90, 10)
|
|
181
|
-
expect(radToDeg(Math.PI * 2)).toBeCloseTo(360, 10)
|
|
182
|
-
})
|
|
183
|
-
|
|
184
|
-
it("should handle negative radians", () => {
|
|
185
|
-
expect(radToDeg(-Math.PI / 2)).toBeCloseTo(-90, 10)
|
|
186
|
-
})
|
|
187
|
-
})
|
|
188
|
-
|
|
189
|
-
describe("distance", () => {
|
|
190
|
-
it("should calculate distance between two points", () => {
|
|
191
|
-
expect(distance(0, 0, 3, 4)).toBe(5)
|
|
192
|
-
expect(distance(0, 0, 0, 0)).toBe(0)
|
|
193
|
-
})
|
|
194
|
-
|
|
195
|
-
it("should handle negative coordinates", () => {
|
|
196
|
-
expect(distance(-3, -4, 0, 0)).toBe(5)
|
|
197
|
-
expect(distance(-1, -1, 1, 1)).toBeCloseTo(Math.sqrt(8), 10)
|
|
198
|
-
})
|
|
199
|
-
|
|
200
|
-
it("should be symmetric", () => {
|
|
201
|
-
expect(distance(0, 0, 3, 4)).toBe(distance(3, 4, 0, 0))
|
|
202
|
-
})
|
|
203
|
-
})
|
|
204
|
-
|
|
205
|
-
describe("normalize", () => {
|
|
206
|
-
it("should normalize value to 0-1 range", () => {
|
|
207
|
-
expect(normalize(0, 100, 50)).toBe(0.5)
|
|
208
|
-
expect(normalize(0, 100, 0)).toBe(0)
|
|
209
|
-
expect(normalize(0, 100, 100)).toBe(1)
|
|
210
|
-
})
|
|
211
|
-
|
|
212
|
-
it("should handle non-zero min values", () => {
|
|
213
|
-
expect(normalize(50, 100, 75)).toBe(0.5)
|
|
214
|
-
expect(normalize(-100, 100, 0)).toBe(0.5)
|
|
215
|
-
})
|
|
216
|
-
|
|
217
|
-
it("should extrapolate outside range", () => {
|
|
218
|
-
expect(normalize(0, 100, 150)).toBe(1.5)
|
|
219
|
-
expect(normalize(0, 100, -50)).toBe(-0.5)
|
|
220
|
-
})
|
|
221
|
-
})
|