spoko-design-system 1.20.0 → 1.21.1
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/.claude/settings.json +48 -48
- package/.github/dependabot.yml +11 -11
- package/.github/todo.yml +3 -3
- package/.github/workflows/claude.yml +37 -37
- package/.github/workflows/code-quality.yml +72 -72
- package/.github/workflows/deploy.yml +43 -43
- package/.husky/README.md +41 -41
- package/.husky/commit-msg +1 -1
- package/.husky/pre-commit +40 -40
- package/.prettierignore +14 -14
- package/.prettierrc +30 -30
- package/.stackblitzrc +5 -5
- package/.vscode/extensions.json +4 -4
- package/.vscode/launch.json +11 -11
- package/.vscode/settings.json +21 -21
- package/CHANGELOG.md +476 -462
- package/CLAUDE.md +268 -268
- package/LICENSE +21 -21
- package/README.md +303 -303
- package/TOOLTIPS.md +236 -236
- package/astro.config.mjs +84 -84
- package/commitlint.config.js +3 -3
- package/dev-dist/sw.js +91 -91
- package/dev-dist/workbox-c676b6d3.js +3391 -3391
- package/eslint.config.js +70 -70
- package/icon.config.ts +348 -348
- package/index.ts +78 -78
- package/package.json +160 -160
- package/public/arrow-bottom.svg +7 -7
- package/public/fonts/lg.svg +53 -53
- package/public/fonts/vwhead-bold-demo.html +549 -549
- package/public/fonts/vwhead-regular-demo.html +549 -549
- package/public/fonts/vwtext-bold-demo.html +549 -549
- package/public/fonts/vwtext-regular-demo.html +549 -549
- package/public/github.svg +3 -3
- package/public/grid_dot.svg +4 -4
- package/public/linkedin.svg +44 -44
- package/public/make-scrollable-code-focusable.js +3 -3
- package/public/pagefind.yml +3 -3
- package/public/polo.blue.svg +29 -29
- package/public/spoko.space.svg +71 -71
- package/public/twitter.svg +46 -46
- package/renovate.json +6 -6
- package/sandbox.config.json +11 -11
- package/sonar-project.properties +26 -26
- package/src/components/Category/CategoriesCarousel.astro +3 -7
- package/src/pages/components/badges.mdx +57 -57
- package/src/pages/components/breadcrumbs.mdx +139 -139
- package/src/pages/components/buttons.mdx +359 -359
- package/src/pages/components/card.mdx +294 -294
- package/src/pages/components/carousel.mdx +62 -62
- package/src/pages/components/copyright.mdx +42 -42
- package/src/pages/components/details-list.mdx +207 -207
- package/src/pages/components/features-list.mdx +37 -37
- package/src/pages/components/flags.mdx +49 -49
- package/src/pages/components/fuck-russia.mdx +39 -39
- package/src/pages/components/hand-drive.mdx +78 -78
- package/src/pages/components/headline.mdx +337 -337
- package/src/pages/components/image.mdx +513 -513
- package/src/pages/components/input.mdx +367 -367
- package/src/pages/components/jumbotron.mdx +530 -530
- package/src/pages/components/modal.mdx +212 -212
- package/src/pages/components/post-header.mdx +64 -64
- package/src/pages/components/pr-code.mdx +213 -213
- package/src/pages/components/product-engine.mdx +418 -418
- package/src/pages/components/product-number.mdx +58 -58
- package/src/pages/components/product-tile.mdx +51 -51
- package/src/pages/components/quote.mdx +33 -33
- package/src/pages/components/slimbanner.mdx +260 -260
- package/src/pages/components/table.mdx +108 -108
- package/src/pages/core/colors.mdx +21 -21
- package/src/pages/core/grid.mdx +193 -193
- package/src/pages/core/introduction.mdx +77 -77
- package/src/pages/core/tooltips.mdx +491 -491
- package/src/pages/patterns/introduction.mdx +60 -60
- package/src/styles/_variables.scss +70 -70
- package/tailwind.config.cjs +8 -8
- package/tsconfig.json +28 -28
- package/uno-config/index.ts +269 -269
- package/uno-config/theme/breakpoints.ts +9 -9
- package/uno-config/theme/colors.ts +65 -65
- package/uno-config/theme/dimensions.ts +17 -17
- package/uno-config/theme/effects.ts +14 -14
- package/uno-config/theme/grid.ts +10 -10
- package/uno-config/theme/index.ts +26 -26
- package/uno-config/theme/shortcuts/buttons.ts +53 -53
- package/uno-config/theme/shortcuts/components.ts +124 -124
- package/uno-config/theme/shortcuts/index.ts +20 -20
- package/uno-config/theme/shortcuts/jumbotron.ts +71 -71
- package/uno-config/theme/shortcuts/layout.ts +75 -75
- package/uno-config/theme/typography.ts +29 -29
- package/uno.config.ts +2 -2
package/uno-config/index.ts
CHANGED
|
@@ -1,270 +1,270 @@
|
|
|
1
|
-
// uno-config/index.ts
|
|
2
|
-
import type { UserConfig, UserShortcuts } from 'unocss'
|
|
3
|
-
import { defineConfig } from 'unocss';
|
|
4
|
-
|
|
5
|
-
// REQUIRED IMPORTS: These imports are used in the createSdsConfig function
|
|
6
|
-
// Removing or commenting out any of these will break the UnoCSS configuration
|
|
7
|
-
import {
|
|
8
|
-
transformerDirectives, // Used in transformers array
|
|
9
|
-
transformerVariantGroup, // Used in transformers array
|
|
10
|
-
presetAttributify, // Used in presets array
|
|
11
|
-
presetIcons, // Used in presets array with specific configuration
|
|
12
|
-
} from 'unocss';
|
|
13
|
-
|
|
14
|
-
// These presets must be imported explicitly to be used in the configuration
|
|
15
|
-
import presetUno from '@unocss/preset-uno'; // Primary UnoCSS preset
|
|
16
|
-
import presetTypography from '@unocss/preset-typography'; // Typography preset
|
|
17
|
-
import presetWebFonts from '@unocss/preset-web-fonts'; // Web fonts preset
|
|
18
|
-
|
|
19
|
-
import { shortcuts } from './theme/shortcuts';
|
|
20
|
-
import { theme } from './theme';
|
|
21
|
-
|
|
22
|
-
// Static imports for all icon collections (prevents Vite module runner issues)
|
|
23
|
-
import antDesignIcons from '@iconify-json/ant-design/icons.json';
|
|
24
|
-
import biIcons from '@iconify-json/bi/icons.json';
|
|
25
|
-
import bxIcons from '@iconify-json/bx/icons.json';
|
|
26
|
-
import carbonIcons from '@iconify-json/carbon/icons.json';
|
|
27
|
-
import circleFlagsIcons from '@iconify-json/circle-flags/icons.json';
|
|
28
|
-
import eiIcons from '@iconify-json/ei/icons.json';
|
|
29
|
-
import elIcons from '@iconify-json/el/icons.json';
|
|
30
|
-
import eosIcons from '@iconify-json/eos-icons/icons.json';
|
|
31
|
-
import etIcons from '@iconify-json/et/icons.json';
|
|
32
|
-
import flowbiteIcons from '@iconify-json/flowbite/icons.json';
|
|
33
|
-
import fluentIcons from '@iconify-json/fluent/icons.json';
|
|
34
|
-
import fluentEmojiIcons from '@iconify-json/fluent-emoji/icons.json';
|
|
35
|
-
import icIcons from '@iconify-json/ic/icons.json';
|
|
36
|
-
import iconParkOutlineIcons from '@iconify-json/icon-park-outline/icons.json';
|
|
37
|
-
import laIcons from '@iconify-json/la/icons.json';
|
|
38
|
-
import lucideIcons from '@iconify-json/lucide/icons.json';
|
|
39
|
-
import materialSymbolsLightIcons from '@iconify-json/material-symbols-light/icons.json';
|
|
40
|
-
import mdiIcons from '@iconify-json/mdi/icons.json';
|
|
41
|
-
import notoV1Icons from '@iconify-json/noto-v1/icons.json';
|
|
42
|
-
import octiconIcons from '@iconify-json/octicon/icons.json';
|
|
43
|
-
import phIcons from '@iconify-json/ph/icons.json';
|
|
44
|
-
import simpleIcons from '@iconify-json/simple-icons/icons.json';
|
|
45
|
-
import systemUiconsIcons from '@iconify-json/system-uicons/icons.json';
|
|
46
|
-
import uilIcons from '@iconify-json/uil/icons.json';
|
|
47
|
-
import vscodeIcons from '@iconify-json/vscode-icons/icons.json';
|
|
48
|
-
import streamlineFreehandColorIcons from '@iconify-json/streamline-freehand-color/icons.json';
|
|
49
|
-
|
|
50
|
-
// List of peer selectors we want to preserve during build
|
|
51
|
-
const peerSelectorClasses = [
|
|
52
|
-
// Focus state classes
|
|
53
|
-
'peer-focus:text-blue-light',
|
|
54
|
-
'peer-focus:dark:text-blue-lightest',
|
|
55
|
-
'peer-focus:scale-75',
|
|
56
|
-
'peer-focus:-translate-y-6',
|
|
57
|
-
'peer-focus:-translate-y-4',
|
|
58
|
-
'peer-focus:start-0',
|
|
59
|
-
|
|
60
|
-
// Placeholder shown classes
|
|
61
|
-
'peer-placeholder-shown:scale-100',
|
|
62
|
-
'peer-placeholder-shown:translate-y-0',
|
|
63
|
-
|
|
64
|
-
// Not placeholder shown classes
|
|
65
|
-
'peer-not-placeholder-shown:scale-75',
|
|
66
|
-
'peer-not-placeholder-shown:-translate-y-6',
|
|
67
|
-
'peer-not-placeholder-shown:-translate-y-4',
|
|
68
|
-
];
|
|
69
|
-
|
|
70
|
-
interface CustomConfig extends Partial<UserConfig> {
|
|
71
|
-
shortcuts?: UserShortcuts;
|
|
72
|
-
theme?: Partial<typeof theme>;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Creates a UnoCSS configuration with Spoko Design System defaults
|
|
77
|
-
*
|
|
78
|
-
* IMPORTANT: This function requires all the imported UnoCSS presets and transformers.
|
|
79
|
-
* Do not remove any imports at the top of this file as they are necessary for
|
|
80
|
-
* proper functioning of the UnoCSS configuration.
|
|
81
|
-
*
|
|
82
|
-
* @param customConfig - Optional custom configuration to merge with defaults
|
|
83
|
-
* @returns Complete UnoCSS configuration
|
|
84
|
-
*/
|
|
85
|
-
export function createSdsConfig(customConfig: CustomConfig = {}) {
|
|
86
|
-
return defineConfig({
|
|
87
|
-
// Optimizations for static builds
|
|
88
|
-
...(process.env.NODE_ENV === 'production' && {
|
|
89
|
-
inspector: false,
|
|
90
|
-
hmr: false,
|
|
91
|
-
}),
|
|
92
|
-
|
|
93
|
-
// Transform directives and variant groups
|
|
94
|
-
transformers: [
|
|
95
|
-
transformerDirectives(),
|
|
96
|
-
transformerVariantGroup(),
|
|
97
|
-
],
|
|
98
|
-
shortcuts: {
|
|
99
|
-
...shortcuts,
|
|
100
|
-
...(customConfig.shortcuts || {})
|
|
101
|
-
},
|
|
102
|
-
theme: {
|
|
103
|
-
...theme,
|
|
104
|
-
...(customConfig.theme || {})
|
|
105
|
-
},
|
|
106
|
-
// Enhanced variants to better handle peer selectors
|
|
107
|
-
variants: [
|
|
108
|
-
// Add specific peer variant support
|
|
109
|
-
(matcher) => {
|
|
110
|
-
if (!matcher.startsWith('peer-'))
|
|
111
|
-
return matcher;
|
|
112
|
-
|
|
113
|
-
const peerVariant = matcher.slice(5);
|
|
114
|
-
const selectorMap = {
|
|
115
|
-
'focus:': (s) => `.peer:focus ~ ${s}`,
|
|
116
|
-
'hover:': (s) => `.peer:hover ~ ${s}`,
|
|
117
|
-
'placeholder-shown:': (s) => `.peer:placeholder-shown ~ ${s}`,
|
|
118
|
-
'not-placeholder-shown:': (s) => `.peer:not(:placeholder-shown) ~ ${s}`,
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
// Check for nested variants like 'peer-focus:text-blue'
|
|
122
|
-
for (const [key, selectorFn] of Object.entries(selectorMap)) {
|
|
123
|
-
if (peerVariant.startsWith(key)) {
|
|
124
|
-
return {
|
|
125
|
-
matcher: peerVariant.slice(key.length),
|
|
126
|
-
selector: selectorFn,
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Default peer handling
|
|
132
|
-
return {
|
|
133
|
-
matcher: peerVariant,
|
|
134
|
-
selector: (s) => `.peer:${peerVariant} ~ ${s}`,
|
|
135
|
-
};
|
|
136
|
-
},
|
|
137
|
-
],
|
|
138
|
-
// Optimized safelist for static Astro builds
|
|
139
|
-
safelist: [
|
|
140
|
-
// Layout and grid classes that might be used dynamically
|
|
141
|
-
'md:grid-cols-product',
|
|
142
|
-
|
|
143
|
-
// Component-specific classes for static generation
|
|
144
|
-
'breadcrumb-link-disabled',
|
|
145
|
-
'breadcrumb-link',
|
|
146
|
-
'breadcrumb-item',
|
|
147
|
-
'features-list-caption',
|
|
148
|
-
'features-list-ul',
|
|
149
|
-
'features-list-item',
|
|
150
|
-
'category-link-base',
|
|
151
|
-
'category-link-active',
|
|
152
|
-
|
|
153
|
-
// Essential peer and input classes
|
|
154
|
-
'peer',
|
|
155
|
-
'resize-none',
|
|
156
|
-
'origin-top-left',
|
|
157
|
-
'transform-gpu',
|
|
158
|
-
|
|
159
|
-
// Dynamic icons from ProductDetailsList component
|
|
160
|
-
'i-lucide-book-text',
|
|
161
|
-
'i-lucide-link',
|
|
162
|
-
'i-simple-icons-youtube',
|
|
163
|
-
'i-simple-icons-vimeo',
|
|
164
|
-
|
|
165
|
-
// All peer selectors from the list (needed for floating labels)
|
|
166
|
-
...peerSelectorClasses,
|
|
167
|
-
],
|
|
168
|
-
// Optimized extractors for static Astro builds
|
|
169
|
-
extractors: [
|
|
170
|
-
{
|
|
171
|
-
name: 'astro-static',
|
|
172
|
-
extract({ code, id }) {
|
|
173
|
-
const result = new Set();
|
|
174
|
-
|
|
175
|
-
// Only extract from class attributes to prevent false positives
|
|
176
|
-
const classRegex = /class(?:Name)?=["'`]([^"'`]+)["'`]/g;
|
|
177
|
-
let match;
|
|
178
|
-
while ((match = classRegex.exec(code)) !== null) {
|
|
179
|
-
match[1].split(/\s+/).forEach(cls => {
|
|
180
|
-
// Only add classes that don't look like malformed icon names
|
|
181
|
-
// Filter out patterns like i-lucide-link-Validate, i-simple-icons-youtube-case, etc.
|
|
182
|
-
if (cls && !cls.match(/^i-(lucide|simple-icons|mdi|ant-design|bi|bx|carbon|el|eos-icons|fluent|flowbite|la|octicon|uil|icon-park-outline|ph|ic|material-symbols-light|et|system-uicons|vscode-icons|streamline-freehand-color)-\w+-(case|return|if|const|Validate|items|validatedItems|Grouping|function|switch|default)/i) && !cls.includes('Grouping')) {
|
|
183
|
-
result.add(cls);
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// For .astro files, extract from dynamic class bindings
|
|
189
|
-
if (id && id.endsWith('.astro')) {
|
|
190
|
-
const dynamicClassRegex = /class:\w+\s*=\s*["'`]([^"'`]+)["'`]/g;
|
|
191
|
-
while ((match = dynamicClassRegex.exec(code)) !== null) {
|
|
192
|
-
match[1].split(/\s+/).forEach(cls => {
|
|
193
|
-
if (cls && !cls.match(/^i-(lucide|simple-icons|mdi|ant-design|bi|bx|carbon|el|eos-icons|fluent|flowbite|la|octicon|uil|icon-park-outline|ph|ic|material-symbols-light|et|system-uicons|vscode-icons|streamline-freehand-color)-\w+-(case|return|if|const|Validate|items|validatedItems|Grouping|function|switch|default)/i) && !cls.includes('Grouping')) {
|
|
194
|
-
result.add(cls);
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
return result;
|
|
201
|
-
},
|
|
202
|
-
},
|
|
203
|
-
],
|
|
204
|
-
// IMPORTANT: All of these presets are required for proper functioning
|
|
205
|
-
presets: [
|
|
206
|
-
presetUno(),
|
|
207
|
-
presetAttributify(),
|
|
208
|
-
presetIcons({
|
|
209
|
-
scale: 1.2,
|
|
210
|
-
warn: false, // Disabled to prevent false positives from JS code scanning
|
|
211
|
-
prefix: 'i-',
|
|
212
|
-
extraProperties: {
|
|
213
|
-
'display': 'inline-block',
|
|
214
|
-
'vertical-align': 'middle',
|
|
215
|
-
},
|
|
216
|
-
collections: {
|
|
217
|
-
// All icon collections with static imports to prevent Vite module runner issues
|
|
218
|
-
'ant-design': antDesignIcons,
|
|
219
|
-
'bi': biIcons,
|
|
220
|
-
'bx': bxIcons,
|
|
221
|
-
'carbon': carbonIcons,
|
|
222
|
-
'circle-flags': circleFlagsIcons,
|
|
223
|
-
'ei': eiIcons,
|
|
224
|
-
'el': elIcons,
|
|
225
|
-
'eos-icons': eosIcons,
|
|
226
|
-
'et': etIcons,
|
|
227
|
-
'flowbite': flowbiteIcons,
|
|
228
|
-
'fluent': fluentIcons,
|
|
229
|
-
'fluent-emoji': fluentEmojiIcons,
|
|
230
|
-
'ic': icIcons,
|
|
231
|
-
'icon-park-outline': iconParkOutlineIcons,
|
|
232
|
-
'la': laIcons,
|
|
233
|
-
'lucide': lucideIcons,
|
|
234
|
-
'material-symbols-light': materialSymbolsLightIcons,
|
|
235
|
-
'mdi': mdiIcons,
|
|
236
|
-
'noto-v1': notoV1Icons,
|
|
237
|
-
'octicon': octiconIcons,
|
|
238
|
-
'ph': phIcons,
|
|
239
|
-
'simple-icons': simpleIcons,
|
|
240
|
-
'system-uicons': systemUiconsIcons,
|
|
241
|
-
'uil': uilIcons,
|
|
242
|
-
'vscode-icons': vscodeIcons,
|
|
243
|
-
'streamline-freehand-color': streamlineFreehandColorIcons,
|
|
244
|
-
}
|
|
245
|
-
}),
|
|
246
|
-
presetTypography(),
|
|
247
|
-
presetWebFonts({
|
|
248
|
-
provider: 'none',
|
|
249
|
-
fonts: theme.fontFamily
|
|
250
|
-
})
|
|
251
|
-
],
|
|
252
|
-
|
|
253
|
-
// Additional optimizations for static Astro builds
|
|
254
|
-
preflights: [
|
|
255
|
-
{
|
|
256
|
-
getCSS: () => `
|
|
257
|
-
/* Optimized base styles for static builds */
|
|
258
|
-
*,*::before,*::after{box-sizing:border-box}
|
|
259
|
-
html{line-height:1.5;-webkit-text-size-adjust:100%}
|
|
260
|
-
body{margin:0;font-family:vw_textregular,system-ui,sans-serif}
|
|
261
|
-
`
|
|
262
|
-
}
|
|
263
|
-
],
|
|
264
|
-
|
|
265
|
-
...customConfig
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
export * from './theme';
|
|
1
|
+
// uno-config/index.ts
|
|
2
|
+
import type { UserConfig, UserShortcuts } from 'unocss'
|
|
3
|
+
import { defineConfig } from 'unocss';
|
|
4
|
+
|
|
5
|
+
// REQUIRED IMPORTS: These imports are used in the createSdsConfig function
|
|
6
|
+
// Removing or commenting out any of these will break the UnoCSS configuration
|
|
7
|
+
import {
|
|
8
|
+
transformerDirectives, // Used in transformers array
|
|
9
|
+
transformerVariantGroup, // Used in transformers array
|
|
10
|
+
presetAttributify, // Used in presets array
|
|
11
|
+
presetIcons, // Used in presets array with specific configuration
|
|
12
|
+
} from 'unocss';
|
|
13
|
+
|
|
14
|
+
// These presets must be imported explicitly to be used in the configuration
|
|
15
|
+
import presetUno from '@unocss/preset-uno'; // Primary UnoCSS preset
|
|
16
|
+
import presetTypography from '@unocss/preset-typography'; // Typography preset
|
|
17
|
+
import presetWebFonts from '@unocss/preset-web-fonts'; // Web fonts preset
|
|
18
|
+
|
|
19
|
+
import { shortcuts } from './theme/shortcuts';
|
|
20
|
+
import { theme } from './theme';
|
|
21
|
+
|
|
22
|
+
// Static imports for all icon collections (prevents Vite module runner issues)
|
|
23
|
+
import antDesignIcons from '@iconify-json/ant-design/icons.json';
|
|
24
|
+
import biIcons from '@iconify-json/bi/icons.json';
|
|
25
|
+
import bxIcons from '@iconify-json/bx/icons.json';
|
|
26
|
+
import carbonIcons from '@iconify-json/carbon/icons.json';
|
|
27
|
+
import circleFlagsIcons from '@iconify-json/circle-flags/icons.json';
|
|
28
|
+
import eiIcons from '@iconify-json/ei/icons.json';
|
|
29
|
+
import elIcons from '@iconify-json/el/icons.json';
|
|
30
|
+
import eosIcons from '@iconify-json/eos-icons/icons.json';
|
|
31
|
+
import etIcons from '@iconify-json/et/icons.json';
|
|
32
|
+
import flowbiteIcons from '@iconify-json/flowbite/icons.json';
|
|
33
|
+
import fluentIcons from '@iconify-json/fluent/icons.json';
|
|
34
|
+
import fluentEmojiIcons from '@iconify-json/fluent-emoji/icons.json';
|
|
35
|
+
import icIcons from '@iconify-json/ic/icons.json';
|
|
36
|
+
import iconParkOutlineIcons from '@iconify-json/icon-park-outline/icons.json';
|
|
37
|
+
import laIcons from '@iconify-json/la/icons.json';
|
|
38
|
+
import lucideIcons from '@iconify-json/lucide/icons.json';
|
|
39
|
+
import materialSymbolsLightIcons from '@iconify-json/material-symbols-light/icons.json';
|
|
40
|
+
import mdiIcons from '@iconify-json/mdi/icons.json';
|
|
41
|
+
import notoV1Icons from '@iconify-json/noto-v1/icons.json';
|
|
42
|
+
import octiconIcons from '@iconify-json/octicon/icons.json';
|
|
43
|
+
import phIcons from '@iconify-json/ph/icons.json';
|
|
44
|
+
import simpleIcons from '@iconify-json/simple-icons/icons.json';
|
|
45
|
+
import systemUiconsIcons from '@iconify-json/system-uicons/icons.json';
|
|
46
|
+
import uilIcons from '@iconify-json/uil/icons.json';
|
|
47
|
+
import vscodeIcons from '@iconify-json/vscode-icons/icons.json';
|
|
48
|
+
import streamlineFreehandColorIcons from '@iconify-json/streamline-freehand-color/icons.json';
|
|
49
|
+
|
|
50
|
+
// List of peer selectors we want to preserve during build
|
|
51
|
+
const peerSelectorClasses = [
|
|
52
|
+
// Focus state classes
|
|
53
|
+
'peer-focus:text-blue-light',
|
|
54
|
+
'peer-focus:dark:text-blue-lightest',
|
|
55
|
+
'peer-focus:scale-75',
|
|
56
|
+
'peer-focus:-translate-y-6',
|
|
57
|
+
'peer-focus:-translate-y-4',
|
|
58
|
+
'peer-focus:start-0',
|
|
59
|
+
|
|
60
|
+
// Placeholder shown classes
|
|
61
|
+
'peer-placeholder-shown:scale-100',
|
|
62
|
+
'peer-placeholder-shown:translate-y-0',
|
|
63
|
+
|
|
64
|
+
// Not placeholder shown classes
|
|
65
|
+
'peer-not-placeholder-shown:scale-75',
|
|
66
|
+
'peer-not-placeholder-shown:-translate-y-6',
|
|
67
|
+
'peer-not-placeholder-shown:-translate-y-4',
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
interface CustomConfig extends Partial<UserConfig> {
|
|
71
|
+
shortcuts?: UserShortcuts;
|
|
72
|
+
theme?: Partial<typeof theme>;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Creates a UnoCSS configuration with Spoko Design System defaults
|
|
77
|
+
*
|
|
78
|
+
* IMPORTANT: This function requires all the imported UnoCSS presets and transformers.
|
|
79
|
+
* Do not remove any imports at the top of this file as they are necessary for
|
|
80
|
+
* proper functioning of the UnoCSS configuration.
|
|
81
|
+
*
|
|
82
|
+
* @param customConfig - Optional custom configuration to merge with defaults
|
|
83
|
+
* @returns Complete UnoCSS configuration
|
|
84
|
+
*/
|
|
85
|
+
export function createSdsConfig(customConfig: CustomConfig = {}) {
|
|
86
|
+
return defineConfig({
|
|
87
|
+
// Optimizations for static builds
|
|
88
|
+
...(process.env.NODE_ENV === 'production' && {
|
|
89
|
+
inspector: false,
|
|
90
|
+
hmr: false,
|
|
91
|
+
}),
|
|
92
|
+
|
|
93
|
+
// Transform directives and variant groups
|
|
94
|
+
transformers: [
|
|
95
|
+
transformerDirectives(),
|
|
96
|
+
transformerVariantGroup(),
|
|
97
|
+
],
|
|
98
|
+
shortcuts: {
|
|
99
|
+
...shortcuts,
|
|
100
|
+
...(customConfig.shortcuts || {})
|
|
101
|
+
},
|
|
102
|
+
theme: {
|
|
103
|
+
...theme,
|
|
104
|
+
...(customConfig.theme || {})
|
|
105
|
+
},
|
|
106
|
+
// Enhanced variants to better handle peer selectors
|
|
107
|
+
variants: [
|
|
108
|
+
// Add specific peer variant support
|
|
109
|
+
(matcher) => {
|
|
110
|
+
if (!matcher.startsWith('peer-'))
|
|
111
|
+
return matcher;
|
|
112
|
+
|
|
113
|
+
const peerVariant = matcher.slice(5);
|
|
114
|
+
const selectorMap = {
|
|
115
|
+
'focus:': (s) => `.peer:focus ~ ${s}`,
|
|
116
|
+
'hover:': (s) => `.peer:hover ~ ${s}`,
|
|
117
|
+
'placeholder-shown:': (s) => `.peer:placeholder-shown ~ ${s}`,
|
|
118
|
+
'not-placeholder-shown:': (s) => `.peer:not(:placeholder-shown) ~ ${s}`,
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
// Check for nested variants like 'peer-focus:text-blue'
|
|
122
|
+
for (const [key, selectorFn] of Object.entries(selectorMap)) {
|
|
123
|
+
if (peerVariant.startsWith(key)) {
|
|
124
|
+
return {
|
|
125
|
+
matcher: peerVariant.slice(key.length),
|
|
126
|
+
selector: selectorFn,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Default peer handling
|
|
132
|
+
return {
|
|
133
|
+
matcher: peerVariant,
|
|
134
|
+
selector: (s) => `.peer:${peerVariant} ~ ${s}`,
|
|
135
|
+
};
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
// Optimized safelist for static Astro builds
|
|
139
|
+
safelist: [
|
|
140
|
+
// Layout and grid classes that might be used dynamically
|
|
141
|
+
'md:grid-cols-product',
|
|
142
|
+
|
|
143
|
+
// Component-specific classes for static generation
|
|
144
|
+
'breadcrumb-link-disabled',
|
|
145
|
+
'breadcrumb-link',
|
|
146
|
+
'breadcrumb-item',
|
|
147
|
+
'features-list-caption',
|
|
148
|
+
'features-list-ul',
|
|
149
|
+
'features-list-item',
|
|
150
|
+
'category-link-base',
|
|
151
|
+
'category-link-active',
|
|
152
|
+
|
|
153
|
+
// Essential peer and input classes
|
|
154
|
+
'peer',
|
|
155
|
+
'resize-none',
|
|
156
|
+
'origin-top-left',
|
|
157
|
+
'transform-gpu',
|
|
158
|
+
|
|
159
|
+
// Dynamic icons from ProductDetailsList component
|
|
160
|
+
'i-lucide-book-text',
|
|
161
|
+
'i-lucide-link',
|
|
162
|
+
'i-simple-icons-youtube',
|
|
163
|
+
'i-simple-icons-vimeo',
|
|
164
|
+
|
|
165
|
+
// All peer selectors from the list (needed for floating labels)
|
|
166
|
+
...peerSelectorClasses,
|
|
167
|
+
],
|
|
168
|
+
// Optimized extractors for static Astro builds
|
|
169
|
+
extractors: [
|
|
170
|
+
{
|
|
171
|
+
name: 'astro-static',
|
|
172
|
+
extract({ code, id }) {
|
|
173
|
+
const result = new Set();
|
|
174
|
+
|
|
175
|
+
// Only extract from class attributes to prevent false positives
|
|
176
|
+
const classRegex = /class(?:Name)?=["'`]([^"'`]+)["'`]/g;
|
|
177
|
+
let match;
|
|
178
|
+
while ((match = classRegex.exec(code)) !== null) {
|
|
179
|
+
match[1].split(/\s+/).forEach(cls => {
|
|
180
|
+
// Only add classes that don't look like malformed icon names
|
|
181
|
+
// Filter out patterns like i-lucide-link-Validate, i-simple-icons-youtube-case, etc.
|
|
182
|
+
if (cls && !cls.match(/^i-(lucide|simple-icons|mdi|ant-design|bi|bx|carbon|el|eos-icons|fluent|flowbite|la|octicon|uil|icon-park-outline|ph|ic|material-symbols-light|et|system-uicons|vscode-icons|streamline-freehand-color)-\w+-(case|return|if|const|Validate|items|validatedItems|Grouping|function|switch|default)/i) && !cls.includes('Grouping')) {
|
|
183
|
+
result.add(cls);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// For .astro files, extract from dynamic class bindings
|
|
189
|
+
if (id && id.endsWith('.astro')) {
|
|
190
|
+
const dynamicClassRegex = /class:\w+\s*=\s*["'`]([^"'`]+)["'`]/g;
|
|
191
|
+
while ((match = dynamicClassRegex.exec(code)) !== null) {
|
|
192
|
+
match[1].split(/\s+/).forEach(cls => {
|
|
193
|
+
if (cls && !cls.match(/^i-(lucide|simple-icons|mdi|ant-design|bi|bx|carbon|el|eos-icons|fluent|flowbite|la|octicon|uil|icon-park-outline|ph|ic|material-symbols-light|et|system-uicons|vscode-icons|streamline-freehand-color)-\w+-(case|return|if|const|Validate|items|validatedItems|Grouping|function|switch|default)/i) && !cls.includes('Grouping')) {
|
|
194
|
+
result.add(cls);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return result;
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
],
|
|
204
|
+
// IMPORTANT: All of these presets are required for proper functioning
|
|
205
|
+
presets: [
|
|
206
|
+
presetUno(),
|
|
207
|
+
presetAttributify(),
|
|
208
|
+
presetIcons({
|
|
209
|
+
scale: 1.2,
|
|
210
|
+
warn: false, // Disabled to prevent false positives from JS code scanning
|
|
211
|
+
prefix: 'i-',
|
|
212
|
+
extraProperties: {
|
|
213
|
+
'display': 'inline-block',
|
|
214
|
+
'vertical-align': 'middle',
|
|
215
|
+
},
|
|
216
|
+
collections: {
|
|
217
|
+
// All icon collections with static imports to prevent Vite module runner issues
|
|
218
|
+
'ant-design': antDesignIcons,
|
|
219
|
+
'bi': biIcons,
|
|
220
|
+
'bx': bxIcons,
|
|
221
|
+
'carbon': carbonIcons,
|
|
222
|
+
'circle-flags': circleFlagsIcons,
|
|
223
|
+
'ei': eiIcons,
|
|
224
|
+
'el': elIcons,
|
|
225
|
+
'eos-icons': eosIcons,
|
|
226
|
+
'et': etIcons,
|
|
227
|
+
'flowbite': flowbiteIcons,
|
|
228
|
+
'fluent': fluentIcons,
|
|
229
|
+
'fluent-emoji': fluentEmojiIcons,
|
|
230
|
+
'ic': icIcons,
|
|
231
|
+
'icon-park-outline': iconParkOutlineIcons,
|
|
232
|
+
'la': laIcons,
|
|
233
|
+
'lucide': lucideIcons,
|
|
234
|
+
'material-symbols-light': materialSymbolsLightIcons,
|
|
235
|
+
'mdi': mdiIcons,
|
|
236
|
+
'noto-v1': notoV1Icons,
|
|
237
|
+
'octicon': octiconIcons,
|
|
238
|
+
'ph': phIcons,
|
|
239
|
+
'simple-icons': simpleIcons,
|
|
240
|
+
'system-uicons': systemUiconsIcons,
|
|
241
|
+
'uil': uilIcons,
|
|
242
|
+
'vscode-icons': vscodeIcons,
|
|
243
|
+
'streamline-freehand-color': streamlineFreehandColorIcons,
|
|
244
|
+
}
|
|
245
|
+
}),
|
|
246
|
+
presetTypography(),
|
|
247
|
+
presetWebFonts({
|
|
248
|
+
provider: 'none',
|
|
249
|
+
fonts: theme.fontFamily
|
|
250
|
+
})
|
|
251
|
+
],
|
|
252
|
+
|
|
253
|
+
// Additional optimizations for static Astro builds
|
|
254
|
+
preflights: [
|
|
255
|
+
{
|
|
256
|
+
getCSS: () => `
|
|
257
|
+
/* Optimized base styles for static builds */
|
|
258
|
+
*,*::before,*::after{box-sizing:border-box}
|
|
259
|
+
html{line-height:1.5;-webkit-text-size-adjust:100%}
|
|
260
|
+
body{margin:0;font-family:vw_textregular,system-ui,sans-serif}
|
|
261
|
+
`
|
|
262
|
+
}
|
|
263
|
+
],
|
|
264
|
+
|
|
265
|
+
...customConfig
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export * from './theme';
|
|
270
270
|
export * from './theme/shortcuts';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
// theme/breakpoints.ts
|
|
2
|
-
export const breakpoints = {
|
|
3
|
-
sm: '640px',
|
|
4
|
-
md: '768px',
|
|
5
|
-
lg: '1024px',
|
|
6
|
-
xl: '1280px',
|
|
7
|
-
'2xl': '1536px',
|
|
8
|
-
'3xl': '1920px',
|
|
9
|
-
'4xl': '2400px',
|
|
1
|
+
// theme/breakpoints.ts
|
|
2
|
+
export const breakpoints = {
|
|
3
|
+
sm: '640px',
|
|
4
|
+
md: '768px',
|
|
5
|
+
lg: '1024px',
|
|
6
|
+
xl: '1280px',
|
|
7
|
+
'2xl': '1536px',
|
|
8
|
+
'3xl': '1920px',
|
|
9
|
+
'4xl': '2400px',
|
|
10
10
|
};
|