bsmnt 0.2.9 → 0.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/README.md +84 -146
  2. package/dist/configs/skills.d.ts +27 -0
  3. package/dist/configs/skills.d.ts.map +1 -0
  4. package/dist/configs/skills.js +18 -0
  5. package/dist/configs/skills.js.map +1 -0
  6. package/dist/configs/skills.json +26 -0
  7. package/dist/helpers/add/hooks-config.d.ts.map +1 -1
  8. package/dist/helpers/add/hooks-config.js +0 -6
  9. package/dist/helpers/add/hooks-config.js.map +1 -1
  10. package/dist/helpers/create/setup-agent.d.ts.map +1 -1
  11. package/dist/helpers/create/setup-agent.js +15 -5
  12. package/dist/helpers/create/setup-agent.js.map +1 -1
  13. package/dist/helpers/integrate/merge-config.d.ts.map +1 -1
  14. package/dist/helpers/integrate/merge-config.js +1 -0
  15. package/dist/helpers/integrate/merge-config.js.map +1 -1
  16. package/dist/helpers/integrate/sanity/config.d.ts.map +1 -1
  17. package/dist/helpers/integrate/sanity/config.js +8 -2
  18. package/dist/helpers/integrate/sanity/config.js.map +1 -1
  19. package/dist/helpers/integrate/sanity/mergers/layout-merger.d.ts.map +1 -1
  20. package/dist/helpers/integrate/sanity/mergers/layout-merger.js +13 -12
  21. package/dist/helpers/integrate/sanity/mergers/layout-merger.js.map +1 -1
  22. package/dist/helpers/skills/index.d.ts +10 -0
  23. package/dist/helpers/skills/index.d.ts.map +1 -0
  24. package/dist/helpers/skills/index.js +136 -0
  25. package/dist/helpers/skills/index.js.map +1 -0
  26. package/dist/index.js +18 -0
  27. package/dist/index.js.map +1 -1
  28. package/package.json +4 -3
  29. package/src/helpers/integrate/sanity/files/app/api/blog/[slug]/route.ts +2 -1
  30. package/src/helpers/integrate/sanity/files/lib/integrations/sanity/confirm-publish-action.ts +31 -0
  31. package/src/helpers/integrate/sanity/files/lib/integrations/sanity/sanity.config.ts +17 -0
  32. package/src/helpers/integrate/sanity/files/lib/utils/json-ld.tsx +249 -0
  33. package/src/template-hooks/config.js +0 -6
  34. package/src/templates/next-default/README.md +28 -199
  35. package/src/templates/next-default/app/layout.tsx +20 -3
  36. package/src/templates/next-default/biome.json +1 -14
  37. package/src/templates/next-default/components/layout/theme/index.tsx +2 -5
  38. package/src/templates/next-default/components/layout/wrapper/index.tsx +1 -2
  39. package/src/templates/next-default/components/ui/README.md +2 -3
  40. package/src/templates/next-default/components/ui/image/index.tsx +3 -3
  41. package/src/templates/next-default/lib/README.md +3 -3
  42. package/src/templates/next-default/lib/hooks/use-device-detection.ts +4 -3
  43. package/src/templates/next-default/lib/hooks/use-media-breakpoint.ts +11 -4
  44. package/src/templates/next-default/lib/hooks/use-media.ts +29 -0
  45. package/src/templates/next-default/lib/scripts/dev.ts +9 -29
  46. package/src/templates/next-default/lib/styles/README.md +7 -58
  47. package/src/templates/next-default/lib/styles/fonts.ts +7 -15
  48. package/src/templates/next-default/lib/styles/global.css +198 -0
  49. package/src/templates/next-default/lib/styles/index.css +3 -0
  50. package/src/templates/next-default/lib/styles/tokens.css +179 -0
  51. package/src/templates/next-default/lib/utils/global-css.d.ts +1 -0
  52. package/src/templates/next-default/lib/utils/json-ld.tsx +199 -0
  53. package/src/templates/next-default/lib/utils/viewport.ts +11 -5
  54. package/src/templates/next-default/next.config.ts +0 -1
  55. package/src/templates/next-default/package.json +11 -18
  56. package/src/templates/next-default/postcss.config.mjs +0 -14
  57. package/src/templates/next-default/tsconfig.json +1 -0
  58. package/src/templates/next-default/tsconfig.tsbuildinfo +1 -0
  59. package/src/templates/next-experiments/README.md +29 -200
  60. package/src/templates/next-experiments/app/layout.tsx +20 -3
  61. package/src/templates/next-experiments/app/page.tsx +46 -39
  62. package/src/templates/next-experiments/biome.json +1 -14
  63. package/src/templates/next-experiments/components/layout/theme/index.tsx +2 -5
  64. package/src/templates/next-experiments/components/layout/wrapper/index.tsx +1 -2
  65. package/src/templates/next-experiments/components/ui/README.md +2 -3
  66. package/src/templates/next-experiments/components/ui/image/index.tsx +3 -2
  67. package/src/templates/next-experiments/lib/README.md +3 -3
  68. package/src/templates/next-experiments/lib/hooks/use-device-detection.ts +4 -3
  69. package/src/templates/next-experiments/lib/hooks/use-media-breakpoint.ts +11 -4
  70. package/src/templates/next-experiments/lib/hooks/use-media.ts +29 -0
  71. package/src/templates/next-experiments/lib/scripts/dev.ts +9 -29
  72. package/src/templates/next-experiments/lib/styles/README.md +7 -58
  73. package/src/templates/next-experiments/lib/styles/fonts.ts +7 -15
  74. package/src/templates/next-experiments/lib/styles/global.css +198 -0
  75. package/src/templates/next-experiments/lib/styles/index.css +3 -0
  76. package/src/templates/next-experiments/lib/styles/tokens.css +179 -0
  77. package/src/templates/next-experiments/lib/utils/global-css.d.ts +1 -0
  78. package/src/templates/next-experiments/lib/utils/json-ld.tsx +199 -0
  79. package/src/templates/next-experiments/lib/utils/viewport.ts +11 -5
  80. package/src/templates/next-experiments/next.config.ts +0 -1
  81. package/src/templates/next-experiments/package.json +11 -22
  82. package/src/templates/next-experiments/postcss.config.mjs +0 -14
  83. package/src/templates/next-experiments/tsconfig.json +1 -0
  84. package/src/templates/next-experiments/tsconfig.tsbuildinfo +1 -0
  85. package/src/templates/next-webgl/README.md +30 -200
  86. package/src/templates/next-webgl/app/layout.tsx +20 -3
  87. package/src/templates/next-webgl/biome.json +1 -14
  88. package/src/templates/next-webgl/components/layout/theme/index.tsx +2 -5
  89. package/src/templates/next-webgl/components/layout/wrapper/index.tsx +1 -2
  90. package/src/templates/next-webgl/components/ui/README.md +2 -3
  91. package/src/templates/next-webgl/components/ui/image/index.tsx +3 -3
  92. package/src/templates/next-webgl/lib/README.md +3 -3
  93. package/src/templates/next-webgl/lib/hooks/use-device-detection.ts +4 -3
  94. package/src/templates/next-webgl/lib/hooks/use-media-breakpoint.ts +11 -4
  95. package/src/templates/next-webgl/lib/hooks/use-media.ts +29 -0
  96. package/src/templates/next-webgl/lib/scripts/dev.ts +9 -29
  97. package/src/templates/next-webgl/lib/styles/README.md +7 -58
  98. package/src/templates/next-webgl/lib/styles/fonts.ts +7 -15
  99. package/src/templates/next-webgl/lib/styles/global.css +198 -0
  100. package/src/templates/next-webgl/lib/styles/index.css +3 -0
  101. package/src/templates/next-webgl/lib/styles/tokens.css +179 -0
  102. package/src/templates/next-webgl/lib/utils/global-css.d.ts +1 -0
  103. package/src/templates/next-webgl/lib/utils/json-ld.tsx +199 -0
  104. package/src/templates/next-webgl/lib/utils/viewport.ts +11 -5
  105. package/src/templates/next-webgl/next.config.ts +0 -1
  106. package/src/templates/next-webgl/package.json +11 -20
  107. package/src/templates/next-webgl/postcss.config.mjs +0 -14
  108. package/src/templates/next-webgl/tsconfig.json +1 -0
  109. package/src/templates/next-webgl/tsconfig.tsbuildinfo +1 -0
  110. package/plugins/no-anchor-element.grit +0 -11
  111. package/plugins/no-relative-parent-imports.grit +0 -6
  112. package/plugins/no-unnecessary-forwardref.grit +0 -5
  113. package/src/template-hooks/use-media.ts +0 -33
  114. package/src/templates/next-default/components/ui/image/image.module.css +0 -5
  115. package/src/templates/next-default/lib/scripts/generate-component.ts +0 -322
  116. package/src/templates/next-default/lib/scripts/generate-page.ts +0 -193
  117. package/src/templates/next-default/lib/scripts/generate.ts +0 -79
  118. package/src/templates/next-default/lib/store/app.ts +0 -11
  119. package/src/templates/next-default/lib/store/index.ts +0 -11
  120. package/src/templates/next-default/lib/styles/colors.ts +0 -63
  121. package/src/templates/next-default/lib/styles/config.ts +0 -34
  122. package/src/templates/next-default/lib/styles/css/global.css +0 -85
  123. package/src/templates/next-default/lib/styles/css/index.css +0 -6
  124. package/src/templates/next-default/lib/styles/css/reset.css +0 -166
  125. package/src/templates/next-default/lib/styles/css/root.css +0 -68
  126. package/src/templates/next-default/lib/styles/css/tailwind.css +0 -132
  127. package/src/templates/next-default/lib/styles/easings.ts +0 -21
  128. package/src/templates/next-default/lib/styles/index.ts +0 -12
  129. package/src/templates/next-default/lib/styles/layout.mjs +0 -27
  130. package/src/templates/next-default/lib/styles/scripts/README.md +0 -29
  131. package/src/templates/next-default/lib/styles/scripts/generate-root.ts +0 -57
  132. package/src/templates/next-default/lib/styles/scripts/generate-tailwind.ts +0 -162
  133. package/src/templates/next-default/lib/styles/scripts/postcss-functions.mjs +0 -168
  134. package/src/templates/next-default/lib/styles/scripts/setup-styles.ts +0 -24
  135. package/src/templates/next-default/lib/styles/scripts/utils.ts +0 -20
  136. package/src/templates/next-default/lib/styles/typography.ts +0 -36
  137. package/src/templates/next-default/lib/utils/css.d.ts +0 -21
  138. package/src/templates/next-default/lib/utils/math.test.ts +0 -221
  139. package/src/templates/next-default/lib/utils/strings.test.ts +0 -166
  140. package/src/templates/next-default/lib/utils/viewport.test.ts +0 -256
  141. package/src/templates/next-default/public/fonts/geist/Geist-Mono.woff2 +0 -0
  142. package/src/templates/next-experiments/components/ui/image/image.module.css +0 -5
  143. package/src/templates/next-experiments/lib/scripts/generate-component.ts +0 -322
  144. package/src/templates/next-experiments/lib/scripts/generate-page.ts +0 -193
  145. package/src/templates/next-experiments/lib/scripts/generate.ts +0 -79
  146. package/src/templates/next-experiments/lib/store/app.ts +0 -11
  147. package/src/templates/next-experiments/lib/store/index.ts +0 -11
  148. package/src/templates/next-experiments/lib/styles/colors.ts +0 -63
  149. package/src/templates/next-experiments/lib/styles/config.ts +0 -34
  150. package/src/templates/next-experiments/lib/styles/css/global.css +0 -85
  151. package/src/templates/next-experiments/lib/styles/css/index.css +0 -6
  152. package/src/templates/next-experiments/lib/styles/css/reset.css +0 -166
  153. package/src/templates/next-experiments/lib/styles/css/root.css +0 -68
  154. package/src/templates/next-experiments/lib/styles/css/tailwind.css +0 -132
  155. package/src/templates/next-experiments/lib/styles/easings.ts +0 -21
  156. package/src/templates/next-experiments/lib/styles/index.ts +0 -12
  157. package/src/templates/next-experiments/lib/styles/layout.mjs +0 -27
  158. package/src/templates/next-experiments/lib/styles/scripts/README.md +0 -29
  159. package/src/templates/next-experiments/lib/styles/scripts/generate-root.ts +0 -57
  160. package/src/templates/next-experiments/lib/styles/scripts/generate-tailwind.ts +0 -162
  161. package/src/templates/next-experiments/lib/styles/scripts/postcss-functions.mjs +0 -168
  162. package/src/templates/next-experiments/lib/styles/scripts/setup-styles.ts +0 -24
  163. package/src/templates/next-experiments/lib/styles/scripts/utils.ts +0 -20
  164. package/src/templates/next-experiments/lib/styles/typography.ts +0 -36
  165. package/src/templates/next-experiments/lib/utils/css.d.ts +0 -21
  166. package/src/templates/next-experiments/lib/utils/math.test.ts +0 -221
  167. package/src/templates/next-experiments/lib/utils/strings.test.ts +0 -166
  168. package/src/templates/next-experiments/lib/utils/viewport.test.ts +0 -256
  169. package/src/templates/next-experiments/public/fonts/geist/Geist-Mono.woff2 +0 -0
  170. package/src/templates/next-webgl/components/ui/image/image.module.css +0 -5
  171. package/src/templates/next-webgl/lib/scripts/generate-component.ts +0 -322
  172. package/src/templates/next-webgl/lib/scripts/generate-page.ts +0 -193
  173. package/src/templates/next-webgl/lib/scripts/generate.ts +0 -79
  174. package/src/templates/next-webgl/lib/store/app.ts +0 -11
  175. package/src/templates/next-webgl/lib/store/index.ts +0 -11
  176. package/src/templates/next-webgl/lib/styles/colors.ts +0 -63
  177. package/src/templates/next-webgl/lib/styles/config.ts +0 -34
  178. package/src/templates/next-webgl/lib/styles/css/global.css +0 -85
  179. package/src/templates/next-webgl/lib/styles/css/index.css +0 -6
  180. package/src/templates/next-webgl/lib/styles/css/reset.css +0 -166
  181. package/src/templates/next-webgl/lib/styles/css/root.css +0 -68
  182. package/src/templates/next-webgl/lib/styles/css/tailwind.css +0 -132
  183. package/src/templates/next-webgl/lib/styles/easings.ts +0 -21
  184. package/src/templates/next-webgl/lib/styles/index.ts +0 -12
  185. package/src/templates/next-webgl/lib/styles/layout.mjs +0 -27
  186. package/src/templates/next-webgl/lib/styles/scripts/README.md +0 -29
  187. package/src/templates/next-webgl/lib/styles/scripts/generate-root.ts +0 -57
  188. package/src/templates/next-webgl/lib/styles/scripts/generate-tailwind.ts +0 -162
  189. package/src/templates/next-webgl/lib/styles/scripts/postcss-functions.mjs +0 -168
  190. package/src/templates/next-webgl/lib/styles/scripts/setup-styles.ts +0 -24
  191. package/src/templates/next-webgl/lib/styles/scripts/utils.ts +0 -20
  192. package/src/templates/next-webgl/lib/styles/typography.ts +0 -36
  193. package/src/templates/next-webgl/lib/utils/css.d.ts +0 -21
  194. package/src/templates/next-webgl/lib/utils/math.test.ts +0 -221
  195. package/src/templates/next-webgl/lib/utils/strings.test.ts +0 -166
  196. package/src/templates/next-webgl/lib/utils/viewport.test.ts +0 -256
  197. 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
- })