spoko-design-system 1.28.0 → 1.28.2
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/CHANGELOG.md +21 -0
- package/CLAUDE.md +23 -1
- package/index.ts +9 -10
- package/package.json +3 -2
- package/src/layouts/partials/HeadCommon.astro +2 -3
- package/src/pages/index.astro +5 -5
- package/src/styles/base/typography.css +19 -0
- package/uno-config/theme/shortcuts/jumbotron.ts +3 -3
- package/uno-config/theme/typography.ts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
## [1.28.2](https://github.com/polo-blue/sds/compare/v1.28.1...v1.28.2) (2026-03-08)
|
|
2
|
+
|
|
3
|
+
### ⚠ BREAKING CHANGES
|
|
4
|
+
|
|
5
|
+
* ButtonCopy, CategoryDetails, and LanguageSuggestion
|
|
6
|
+
are no longer available from the barrel import. Use direct subpath
|
|
7
|
+
imports instead:
|
|
8
|
+
import ButtonCopy from 'spoko-design-system/components/ButtonCopy.astro'
|
|
9
|
+
import CategoryDetails from 'spoko-design-system/components/Category/CategoryDetails.astro'
|
|
10
|
+
import LanguageSuggestion from 'spoko-design-system/components/LanguageSuggestion.astro'
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
* remove Astro components with <script> tags from barrel file ([36f36c2](https://github.com/polo-blue/sds/commit/36f36c2316aeb0a6248f4fe62450d730e9f9dac8))
|
|
15
|
+
|
|
16
|
+
## [1.28.1](https://github.com/polo-blue/sds/compare/v1.28.0...v1.28.1) (2026-03-07)
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* **homepage:** reduce CLS with font preloading and layout stabilization ([32d08f5](https://github.com/polo-blue/sds/commit/32d08f5b84c8b17f209073eaab7e6030f9dc53f9))
|
|
21
|
+
|
|
1
22
|
## [1.28.0](https://github.com/polo-blue/sds/compare/v1.27.3...v1.28.0) (2026-03-04)
|
|
2
23
|
|
|
3
24
|
### Features
|
package/CLAUDE.md
CHANGED
|
@@ -52,6 +52,26 @@ export { default as Button } from './src/components/Button.vue';
|
|
|
52
52
|
export { default as Button } from './components/Button.vue';
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
+
### Astro Components with `<script>` Tags — Barrel File Restriction
|
|
56
|
+
|
|
57
|
+
Astro components with `<script>` tags **MUST NOT** be exported from the barrel file (`index.ts`).
|
|
58
|
+
When any consumer imports from the barrel, Astro hoists ALL `<script>` tags from ALL exported `.astro`
|
|
59
|
+
components onto every page — even if the component is never rendered. This is a
|
|
60
|
+
[known Astro limitation](https://github.com/withastro/astro/issues/6906).
|
|
61
|
+
|
|
62
|
+
**Rule:** If an `.astro` component has a `<script>` tag, export it ONLY via subpath (`./components/*`):
|
|
63
|
+
```typescript
|
|
64
|
+
// ❌ DO NOT add to index.ts — script will load on ALL consumer pages
|
|
65
|
+
export { default as ButtonCopy } from './src/components/ButtonCopy.astro';
|
|
66
|
+
|
|
67
|
+
// ✅ Consumer uses direct subpath import instead
|
|
68
|
+
import ButtonCopy from 'spoko-design-system/components/ButtonCopy.astro';
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Components **without** `<script>` tags are safe in the barrel file.
|
|
72
|
+
|
|
73
|
+
Currently excluded from barrel: **ButtonCopy**, **CategoryDetails**, **LanguageSuggestion**.
|
|
74
|
+
|
|
55
75
|
### UnoCSS Configuration System
|
|
56
76
|
|
|
57
77
|
**Critical**: UnoCSS config is split across two locations:
|
|
@@ -198,10 +218,12 @@ On merge to `main`, GitHub Actions automatically:
|
|
|
198
218
|
- Vue: `src/components/ComponentName.vue`
|
|
199
219
|
- Astro: `src/components/ComponentName.astro`
|
|
200
220
|
|
|
201
|
-
2. Export from root `index.ts
|
|
221
|
+
2. Export from root `index.ts` (Vue components and Astro components **without** `<script>` tags):
|
|
202
222
|
```typescript
|
|
203
223
|
export { default as ComponentName } from './src/components/ComponentName.vue';
|
|
204
224
|
```
|
|
225
|
+
**Important:** If the Astro component has a `<script>` tag, do **NOT** add it to `index.ts`.
|
|
226
|
+
It will be available via the wildcard subpath export `./components/*` automatically.
|
|
205
227
|
|
|
206
228
|
3. Add documentation page in `src/pages/components/component-name.mdx`
|
|
207
229
|
|
package/index.ts
CHANGED
|
@@ -9,7 +9,6 @@ export { default as FlagPL } from './src/components/flags/FlagPL.vue';
|
|
|
9
9
|
export { default as Badges } from './src/components/Badges.vue';
|
|
10
10
|
export { default as SlimBanner } from './src/components/SlimBanner.vue';
|
|
11
11
|
|
|
12
|
-
export { default as Jumbotron } from './src/components/Jumbotron.astro';
|
|
13
12
|
export { default as Button } from './src/components/Button.vue';
|
|
14
13
|
export { default as Breadcrumbs } from './src/components/Breadcrumbs.vue';
|
|
15
14
|
export { default as ProductDetailsList } from './src/components/ProductDetailsList.vue';
|
|
@@ -29,10 +28,7 @@ export { default as ProductModel } from './src/components/Product/ProductModel.v
|
|
|
29
28
|
export { default as ProductModels } from './src/components/Product/ProductModels.vue';
|
|
30
29
|
export { default as ProductName } from './src/components/Product/ProductName.vue';
|
|
31
30
|
export { default as ProductPositions } from './src/components/Product/ProductPositions.vue';
|
|
32
|
-
export { default as ProductNumber } from './src/components/Product/ProductNumber.astro';
|
|
33
31
|
export { default as ProductLink } from './src/components/Product/ProductLink.vue';
|
|
34
|
-
// export { default as ProductCarousel } from './src/components/Product/ProductCarousel.astro';
|
|
35
|
-
export { default as LanguageSuggestion } from './src/components/LanguageSuggestion.astro';
|
|
36
32
|
export { default as Input } from './src/components/Input.vue';
|
|
37
33
|
|
|
38
34
|
export { default as PostCategories } from './src/components/Post/PostCategories.vue';
|
|
@@ -40,21 +36,24 @@ export { default as CategorySidebarToggler } from './src/components/Category/Cat
|
|
|
40
36
|
export { default as SubCategoryLink } from './src/components/Category/SubCategoryLink.vue';
|
|
41
37
|
export { default as CategoryLink } from './src/components/Category/CategoryLink.vue';
|
|
42
38
|
|
|
43
|
-
// Astro Components
|
|
44
|
-
export { default as
|
|
39
|
+
// Astro Components (without <script> tags — safe in barrel)
|
|
40
|
+
export { default as Jumbotron } from './src/components/Jumbotron.astro';
|
|
41
|
+
export { default as Copyright } from './src/components/Copyright.astro';
|
|
45
42
|
export { default as HandDrive } from './src/components/HandDrive.astro';
|
|
46
43
|
export { default as Faq } from './src/components/Faq.astro';
|
|
47
44
|
export { default as FaqItem } from './src/components/FaqItem.astro';
|
|
48
|
-
export { default as ButtonCopy } from './src/components/ButtonCopy.astro';
|
|
49
45
|
export { default as CallToAction } from './src/components/layout/CallToAction.astro';
|
|
50
|
-
|
|
46
|
+
export { default as ProductNumber } from './src/components/Product/ProductNumber.astro';
|
|
51
47
|
export { default as ProductImage } from './src/components/Product/ProductImage.astro';
|
|
52
48
|
export { default as ProductEngine } from './src/components/Product/ProductEngine.astro';
|
|
53
49
|
export { default as ProductEngines } from './src/components/Product/ProductEngines.astro';
|
|
54
|
-
|
|
55
|
-
export { default as CategoryDetails } from './src/components/Category/CategoryDetails.astro';
|
|
56
50
|
export { default as CategoryTile } from './src/components/Category/CategoryTile.astro';
|
|
57
51
|
|
|
52
|
+
// Astro Components WITH <script> tags — NOT in barrel to prevent script hoisting.
|
|
53
|
+
// Import directly: import ButtonCopy from 'spoko-design-system/components/ButtonCopy.astro'
|
|
54
|
+
// See: https://github.com/withastro/astro/issues/6906
|
|
55
|
+
// - ButtonCopy, CategoryDetails, LanguageSuggestion
|
|
56
|
+
|
|
58
57
|
|
|
59
58
|
// Utils: Product
|
|
60
59
|
export { default as getPriceFormatted } from './src/utils/product/getPriceFormatted';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spoko-design-system",
|
|
3
|
-
"version": "1.28.
|
|
3
|
+
"version": "1.28.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"main": "./index.ts",
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
"./scripts/*": "./src/scripts/*",
|
|
16
16
|
"./icons": "./icon.config.ts",
|
|
17
17
|
"./icon-collections": "./icon.collections.ts",
|
|
18
|
-
"./uno-config": "./uno-config/index.ts"
|
|
18
|
+
"./uno-config": "./uno-config/index.ts",
|
|
19
|
+
"./components/*": "./src/components/*"
|
|
19
20
|
},
|
|
20
21
|
"scripts": {
|
|
21
22
|
"dev": "astro dev",
|
|
@@ -13,9 +13,8 @@ import { pwaInfo } from 'virtual:pwa-info';
|
|
|
13
13
|
<link rel="sitemap" href="/sitemap-index.xml" />
|
|
14
14
|
|
|
15
15
|
<!-- Preload Fonts -->
|
|
16
|
-
|
|
17
|
-
<link rel="
|
|
18
|
-
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital@0;1&display=swap" rel="stylesheet" /> -->
|
|
16
|
+
<link rel="preload" href="/fonts/vwhead-light-webfont.woff2" as="font" type="font/woff2" crossorigin />
|
|
17
|
+
<link rel="preload" href="/fonts/vwhead-regular-webfont.woff2" as="font" type="font/woff2" crossorigin />
|
|
19
18
|
|
|
20
19
|
<!-- Scrollable a11y code helper -->
|
|
21
20
|
<script src="/make-scrollable-code-focusable.js" is:inline></script>
|
package/src/pages/index.astro
CHANGED
|
@@ -95,7 +95,7 @@ const exampleSites = [
|
|
|
95
95
|
<Jumbotron title={SITE.title}>
|
|
96
96
|
<p
|
|
97
97
|
slot="subtitle"
|
|
98
|
-
class="mt-3 text-base text-gray-200 sm:mt-5 text-lg md:text-xl lg:mx-0 md:mt-5"
|
|
98
|
+
class="mt-3 text-base text-gray-200 sm:mt-5 text-lg md:text-xl lg:mx-0 md:mt-5 leading-snug"
|
|
99
99
|
set:html={SITE.description}
|
|
100
100
|
/>
|
|
101
101
|
|
|
@@ -112,10 +112,10 @@ const exampleSites = [
|
|
|
112
112
|
<a
|
|
113
113
|
href={url}
|
|
114
114
|
title={description}
|
|
115
|
-
class="flex w-full flex-wrap bg-white rounded-md hover:-translate-y-1 hover:shadow-lg transition-all flex-1 items-center py-10 px-4 md:(flex-col w-auto flex-nowrap text-center py-16)"
|
|
115
|
+
class="flex w-full flex-wrap bg-white rounded-md hover:-translate-y-1 hover:shadow-lg transition-all flex-1 items-center py-10 px-4 min-h-24 md:(flex-col w-auto flex-nowrap text-center py-16 min-h-48)"
|
|
116
116
|
>
|
|
117
117
|
<Headline as="h2" class="text-3xl" underline={false}>
|
|
118
|
-
<Icon name={icon} aria-hidden="true" class="text-blue-400 mr-3 text-4xl" />
|
|
118
|
+
<Icon name={icon} aria-hidden="true" class="text-blue-400 mr-3 text-4xl w-10 h-10 shrink-0" />
|
|
119
119
|
{title}
|
|
120
120
|
</Headline>
|
|
121
121
|
<p class="text-slate-500 w-full">{description}</p>
|
|
@@ -140,13 +140,13 @@ const exampleSites = [
|
|
|
140
140
|
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
|
|
141
141
|
{
|
|
142
142
|
features.map(({ title, icon, description }) => (
|
|
143
|
-
<div class="text-center p-6 bg-white rounded-lg shadow-sm border border-gray-100">
|
|
143
|
+
<div class="text-center p-6 bg-white rounded-lg shadow-sm border border-gray-100 min-h-40">
|
|
144
144
|
<Headline
|
|
145
145
|
as="h3"
|
|
146
146
|
class="text-2xl mb-3 text-gray-900 flex items-center justify-center"
|
|
147
147
|
underline={false}
|
|
148
148
|
>
|
|
149
|
-
<Icon name={icon} aria-hidden="true" class="text-4xl text-blue-400 mr-3" />
|
|
149
|
+
<Icon name={icon} aria-hidden="true" class="text-4xl text-blue-400 mr-3 w-10 h-10 shrink-0" />
|
|
150
150
|
{title}
|
|
151
151
|
</Headline>
|
|
152
152
|
<p class="text-gray-600" set:html={description} />
|
|
@@ -64,6 +64,25 @@
|
|
|
64
64
|
font-display: swap;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
/* Fallback font metrics matching to reduce CLS on font swap */
|
|
68
|
+
@font-face {
|
|
69
|
+
font-family: 'vw_headlight_fallback';
|
|
70
|
+
src: local('Segoe UI'), local('Roboto'), local('Helvetica Neue'), local('Arial');
|
|
71
|
+
ascent-override: 78.7%;
|
|
72
|
+
descent-override: 21.3%;
|
|
73
|
+
line-gap-override: 0%;
|
|
74
|
+
size-adjust: 105%;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@font-face {
|
|
78
|
+
font-family: 'vw_headregular_fallback';
|
|
79
|
+
src: local('Segoe UI'), local('Roboto'), local('Helvetica Neue'), local('Arial');
|
|
80
|
+
ascent-override: 78.7%;
|
|
81
|
+
descent-override: 21.3%;
|
|
82
|
+
line-gap-override: 21.9%;
|
|
83
|
+
size-adjust: 105%;
|
|
84
|
+
}
|
|
85
|
+
|
|
67
86
|
/* for some content which don't need to index in Google */
|
|
68
87
|
[data-text]:before {
|
|
69
88
|
content: attr(data-text);
|
|
@@ -6,12 +6,12 @@ export const jumbotronShortcuts = [
|
|
|
6
6
|
// Default variant
|
|
7
7
|
['jumbotron-header-base', 'relative mx-auto my-auto w-full text-center py-8'],
|
|
8
8
|
['jumbotron-container-small', 'md:min-h-xs sm:py-12 md:py-14 lg:py-16 xl:py-20'],
|
|
9
|
-
['jumbotron-container-large', 'md:min-h-md sm:py-16 md:py-20 lg:py-28 xl:py-32'],
|
|
9
|
+
['jumbotron-container-large', 'min-h-48 md:min-h-md sm:py-16 md:py-20 lg:py-28 xl:py-32'],
|
|
10
10
|
[
|
|
11
11
|
'jumbotron-title-default',
|
|
12
|
-
'text-3xl headline-light text-white sm:(text-4xl pt-0) md:text-5xl lg:text-6xl',
|
|
12
|
+
'text-3xl headline-light text-white sm:(text-4xl pt-0) md:text-5xl lg:text-6xl leading-[1.15]',
|
|
13
13
|
],
|
|
14
|
-
['jumbotron-cta-wrapper', 'mt-5 sm:(mt-8 flex justify-center)'],
|
|
14
|
+
['jumbotron-cta-wrapper', 'mt-5 min-h-12 sm:(mt-8 flex justify-center)'],
|
|
15
15
|
|
|
16
16
|
// Hero variant
|
|
17
17
|
['jumbotron-hero-wrapper', 'relative w-full'],
|
|
@@ -17,8 +17,8 @@ interface FontFamily {
|
|
|
17
17
|
sans: ['vw_textregular', 'system-ui', 'ui-sans-serif'],
|
|
18
18
|
novamono: ['Nova Mono'],
|
|
19
19
|
mono: ['Nova Mono'],
|
|
20
|
-
headlight: ['vw_headlight', 'system-ui'],
|
|
21
|
-
headregular: ['vw_headregular'],
|
|
20
|
+
headlight: ['vw_headlight', 'vw_headlight_fallback', 'system-ui'],
|
|
21
|
+
headregular: ['vw_headregular', 'vw_headregular_fallback', 'system-ui'],
|
|
22
22
|
headbold: ['vw_headbold'],
|
|
23
23
|
textlight: ['vw_textlight'],
|
|
24
24
|
textregular: ['vw_textregular'],
|