spoko-design-system 1.9.0 → 1.9.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.
Files changed (86) hide show
  1. package/.claude/settings.json +1 -1
  2. package/.husky/pre-commit +17 -1
  3. package/.prettierrc +8 -4
  4. package/CHANGELOG.md +35 -0
  5. package/index.ts +8 -2
  6. package/package.json +4 -3
  7. package/src/components/Badge.vue +1 -4
  8. package/src/components/Badges.vue +1 -4
  9. package/src/components/Breadcrumbs.vue +10 -44
  10. package/src/components/Button.vue +1 -5
  11. package/src/components/ButtonCopy.astro +2 -7
  12. package/src/components/ButtonCopy.vue +2 -9
  13. package/src/components/Card.astro +1 -4
  14. package/src/components/Category/CategoriesCarousel.astro +3 -11
  15. package/src/components/Category/CategoryDetails.astro +7 -32
  16. package/src/components/Category/CategoryLink.vue +1 -5
  17. package/src/components/Category/CategorySidebarToggler.vue +1 -5
  18. package/src/components/Category/CategoryTile.astro +2 -9
  19. package/src/components/Category/CategoryViewToggler.astro +3 -16
  20. package/src/components/Copyright.astro +1 -4
  21. package/src/components/Date.astro +1 -4
  22. package/src/components/Faq.astro +1 -5
  23. package/src/components/FaqItem.astro +3 -14
  24. package/src/components/FeaturesList.vue +2 -9
  25. package/src/components/FuckRussia.vue +9 -36
  26. package/src/components/HandDrive.astro +2 -12
  27. package/src/components/Header/Header.astro +3 -14
  28. package/src/components/Header/SkipToContent.astro +1 -5
  29. package/src/components/Input.vue +19 -31
  30. package/src/components/Jumbotron/index.astro +7 -41
  31. package/src/components/Jumbotron/variants/Default.astro +2 -17
  32. package/src/components/Jumbotron/variants/Hero.astro +3 -17
  33. package/src/components/Jumbotron/variants/Post.astro +3 -13
  34. package/src/components/Jumbotron/variants/PostSplit.astro +3 -13
  35. package/src/components/Jumbotron.astro +3 -12
  36. package/src/components/LanguageSuggestion.astro +3 -14
  37. package/src/components/MainColors.vue +7 -25
  38. package/src/components/MainInput.vue +2 -1
  39. package/src/components/Modal.astro +43 -41
  40. package/src/components/PageContent.astro +1 -4
  41. package/src/components/PartNumber.vue +1 -4
  42. package/src/components/PostHeader.astro +3 -13
  43. package/src/components/PrCode.vue +2 -2
  44. package/src/components/Product/ProductButton.vue +1 -4
  45. package/src/components/Product/ProductDetailName.vue +1 -4
  46. package/src/components/Product/ProductDetails.vue +19 -65
  47. package/src/components/Product/ProductDoc.vue +1 -4
  48. package/src/components/Product/ProductEngine.astro +67 -0
  49. package/src/components/Product/ProductEngineType.vue +1 -4
  50. package/src/components/Product/ProductEngines.astro +43 -0
  51. package/src/components/Product/ProductLink.astro +8 -32
  52. package/src/components/Product/ProductLink.vue +8 -36
  53. package/src/components/Product/ProductLinkInfo.astro +4 -19
  54. package/src/components/Product/ProductModel.vue +3 -5
  55. package/src/components/Product/ProductModels.vue +2 -10
  56. package/src/components/Product/ProductNumber.astro +6 -26
  57. package/src/components/Product/ProductPositions.vue +1 -5
  58. package/src/components/ProductCodes.vue +6 -14
  59. package/src/components/ProductDetailName.vue +2 -7
  60. package/src/components/ProductDetailsList.vue +7 -33
  61. package/src/components/ProductTile.astro +3 -13
  62. package/src/components/ReloadPrompt.astro +1 -5
  63. package/src/components/SlimBanner.vue +10 -15
  64. package/src/components/Table.vue +3 -15
  65. package/src/components/Translations.vue +1 -4
  66. package/src/components/layout/CallToAction.astro +2 -7
  67. package/src/components/layout/Container.astro +1 -3
  68. package/src/components/layout/Header.astro +2 -12
  69. package/src/layouts/Layout.astro +2 -9
  70. package/src/layouts/MainLayout.astro +4 -17
  71. package/src/layouts/partials/HeadCommon.astro +7 -24
  72. package/src/layouts/partials/HeadSEO.astro +12 -48
  73. package/src/pages/components/icons.astro +1 -4
  74. package/src/pages/components/product-engine.mdx +75 -31
  75. package/src/pages/core/typography.astro +2 -6
  76. package/src/pages/index.astro +16 -63
  77. package/src/scripts/tooltips.ts +33 -28
  78. package/src/styles/main.css +4 -0
  79. package/src/styles/tippy-theme.css +4 -2
  80. package/src/utils/product/getEngineTooltipContent.ts +158 -0
  81. package/src/utils/product/getPriceFormatted.ts +2 -6
  82. package/src/utils/product/useFormatProductNumber.ts +1 -4
  83. package/src/utils/seo/getShorterDescription.ts +1 -4
  84. package/uno-config/index.ts +1 -1
  85. package/src/components/Product/ProductEngine.vue +0 -240
  86. package/src/components/Product/ProductEngines.vue +0 -116
@@ -2,28 +2,46 @@
2
2
  title: "ProductEngine"
3
3
  layout: "../../layouts/MainLayout.astro"
4
4
  ---
5
- import ProductEngine from '../../components/Product/ProductEngine.vue'
6
- import ProductEngines from '../../components/Product/ProductEngines.vue'
5
+ import ProductEngine from '../../components/Product/ProductEngine.astro'
6
+ import ProductEngines from '../../components/Product/ProductEngines.astro'
7
7
 
8
8
  # ProductEngine
9
9
 
10
10
  Engine codes with detailed tooltips showing specifications like power, displacement, dates, and more.
11
11
 
12
+ **⚡ Performance-optimized**: Uses Tippy.js delegation pattern - one global script handles all tooltips efficiently.
13
+
14
+ **🔍 SEO-friendly**: Engine codes rendered as static HTML (no client-side hydration required).
15
+
12
16
  ## Single Engine Code
13
17
 
14
18
  Display a single engine code with tooltip showing detailed engine information.
15
19
 
16
- ### import:
20
+ ### Setup:
21
+
22
+ **1. Import the component:**
17
23
 
18
24
  ```js
19
- import ProductEngine from 'spoko-design-system/src/components/Product/ProductEngine.vue'
25
+ import { ProductEngine } from 'spoko-design-system'
26
+ ```
27
+
28
+ **2. Initialize tooltips in your layout (once):**
29
+
30
+ ```astro
31
+ ---
32
+ // In your layout file (e.g., Layout.astro)
33
+ ---
34
+ <script>
35
+ import { initTooltips } from 'spoko-design-system';
36
+ initTooltips();
37
+ </script>
20
38
  ```
21
39
 
22
40
  ### Basic Usage (New API Structure):
23
41
 
24
42
  <div class="component-preview">
25
43
  <div class="bg-white p-6 w-full flex gap-2">
26
- <ProductEngine client:load engine={{
44
+ <ProductEngine engine={{
27
45
  code: "CAYA",
28
46
  name: "1.6 TDI",
29
47
  serie: { value: "EA189", label: "Seria silnika" },
@@ -31,7 +49,7 @@ import ProductEngine from 'spoko-design-system/src/components/Product/ProductEng
31
49
  displacement: { value: 1598, label: "Pojemność" },
32
50
  euro: { value: 5, label: "Norma Euro" }
33
51
  }} />
34
- <ProductEngine client:load engine={{
52
+ <ProductEngine engine={{
35
53
  code: "CAYB",
36
54
  name: "1.6 TDI",
37
55
  serie: { value: "EA189", label: "Seria silnika" },
@@ -42,21 +60,25 @@ import ProductEngine from 'spoko-design-system/src/components/Product/ProductEng
42
60
  </div>
43
61
  </div>
44
62
 
45
- ```vue
63
+ ```astro
64
+ ---
65
+ import { ProductEngine } from 'spoko-design-system';
66
+ ---
67
+
46
68
  <!-- New API structure (with built-in translations) -->
47
- <ProductEngine :engine="{
69
+ <ProductEngine engine={{
48
70
  code: 'CAYA',
49
71
  name: '1.6 TDI',
50
72
  serie: { value: 'EA189', label: 'Seria silnika' },
51
73
  power: { kw: 55, ps: 75, ps_label: 'KM', label: 'Moc' },
52
74
  displacement: { value: 1598, label: 'Pojemność' },
53
75
  euro: { value: 5, label: 'Norma Euro' }
54
- }" />
76
+ }} />
55
77
 
56
78
  <!-- Old API structure (backward compatible) -->
57
79
  <ProductEngine
58
- :engine="{ code: 'CAYA', name: '1.6 TDI', kw: 55, ps: 75, cc: 1598, serie: 3, euro: 5 }"
59
- :translations="{ power: 'Moc', cc: 'Pojemność', euro: 'Euro', horsepowerUnit: 'KM' }"
80
+ engine={{ code: 'CAYA', name: '1.6 TDI', kw: 55, ps: 75, cc: 1598, serie: 3, euro: 5 }}
81
+ translations={{ power: 'Moc', cc: 'Pojemność', euro: 'Euro', horsepowerUnit: 'KM' }}
60
82
  />
61
83
  ```
62
84
 
@@ -68,7 +90,7 @@ Engine codes for special editions are automatically color-coded:
68
90
  <div class="bg-white p-6 w-full flex flex-wrap gap-3">
69
91
  <div class="flex flex-col gap-1">
70
92
  <small class="text-xs text-gray-500">GTI Engine (Red)</small>
71
- <ProductEngine client:load engine={{
93
+ <ProductEngine engine={{
72
94
  code: "CAVE",
73
95
  name: "1.4 TSI",
74
96
  power: { kw: 132, ps: 180, ps_label: "KM", label: "Moc" },
@@ -78,7 +100,7 @@ Engine codes for special editions are automatically color-coded:
78
100
  </div>
79
101
  <div class="flex flex-col gap-1">
80
102
  <small class="text-xs text-gray-500">WRC Engine (Blue)</small>
81
- <ProductEngine client:load engine={{
103
+ <ProductEngine engine={{
82
104
  code: "CDLJ",
83
105
  name: "1.6 TDI",
84
106
  power: { kw: 165, ps: 220, ps_label: "KM", label: "Moc" },
@@ -88,7 +110,7 @@ Engine codes for special editions are automatically color-coded:
88
110
  </div>
89
111
  <div class="flex flex-col gap-1">
90
112
  <small class="text-xs text-gray-500">Special Blue</small>
91
- <ProductEngine client:load engine={{
113
+ <ProductEngine engine={{
92
114
  code: "CPTA",
93
115
  name: "1.0 TSI",
94
116
  power: { kw: 70, ps: 95, ps_label: "KM", label: "Moc" },
@@ -99,41 +121,41 @@ Engine codes for special editions are automatically color-coded:
99
121
  </div>
100
122
  </div>
101
123
 
102
- ```vue
124
+ ```astro
103
125
  <!-- GTI Engine - Red -->
104
- <ProductEngine :engine="{
126
+ <ProductEngine engine={{
105
127
  code: 'CAVE',
106
128
  name: '1.4 TSI',
107
129
  power: { kw: 132, ps: 180, ps_label: 'KM', label: 'Moc' },
108
130
  displacement: { value: 1390, label: 'Pojemność' },
109
131
  euro: { value: 5, label: 'Norma Euro' }
110
- }" />
132
+ }} />
111
133
 
112
134
  <!-- WRC Engine - Blue -->
113
- <ProductEngine :engine="{
135
+ <ProductEngine engine={{
114
136
  code: 'CDLJ',
115
137
  name: '1.6 TDI',
116
138
  power: { kw: 165, ps: 220, ps_label: 'KM', label: 'Moc' },
117
139
  displacement: { value: 1598, label: 'Pojemność' },
118
140
  euro: { value: 6, label: 'Norma Euro' }
119
- }" />
141
+ }} />
120
142
  ```
121
143
 
122
144
  ## Engine List
123
145
 
124
146
  Display multiple engine codes from an array (from API response).
125
147
 
126
- ### import:
148
+ ### Import:
127
149
 
128
150
  ```js
129
- import ProductEngines from 'spoko-design-system/src/components/Product/ProductEngines.vue'
151
+ import { ProductEngines } from 'spoko-design-system'
130
152
  ```
131
153
 
132
154
  ### Usage:
133
155
 
134
156
  <div class="component-preview">
135
157
  <div class="bg-white p-6 w-full">
136
- <ProductEngines client:load engines={[
158
+ <ProductEngines engines={[
137
159
  {
138
160
  id: 13,
139
161
  code: "CAYA",
@@ -165,8 +187,12 @@ import ProductEngines from 'spoko-design-system/src/components/Product/ProductEn
165
187
  </div>
166
188
  </div>
167
189
 
168
- ```vue
169
- <ProductEngines :engines="[
190
+ ```astro
191
+ ---
192
+ import { ProductEngines } from 'spoko-design-system';
193
+ ---
194
+
195
+ <ProductEngines engines={[
170
196
  {
171
197
  id: 13,
172
198
  code: 'CAYA',
@@ -185,17 +211,17 @@ import ProductEngines from 'spoko-design-system/src/components/Product/ProductEn
185
211
  displacement: { value: 1598, label: 'Pojemność' },
186
212
  euro: { value: 5, label: 'Norma Euro' }
187
213
  }
188
- ]" />
214
+ ]} />
189
215
  ```
190
216
 
191
217
  ### With API Data:
192
218
 
193
219
  When using data from the API, pass the `part_engines` array directly. The component automatically extracts translations from the nested structure:
194
220
 
195
- ```vue
221
+ ```astro
196
222
  <ProductEngines
197
- :engines="product.part_engines"
198
- :isPdp="true"
223
+ engines={product.part_engines}
224
+ isPdp={true}
199
225
  />
200
226
  ```
201
227
 
@@ -334,7 +360,9 @@ When using data from the API, pass the `part_engines` array directly. The compon
334
360
 
335
361
  ## Features
336
362
 
337
- - ✅ **Rich Tooltips**: Shows detailed engine specifications on hover (Tippy.js)
363
+ - ✅ **Rich Tooltips**: Shows detailed engine specifications on hover (Tippy.js delegation)
364
+ - ✅ **Performance Optimized**: One global script handles all tooltips efficiently
365
+ - ✅ **SEO-Friendly**: Engine codes rendered as static HTML (no hydration)
338
366
  - ✅ **API-Driven Translations**: Labels and units come directly from API
339
367
  - ✅ **Multi-language**: Supports Polish (KM), German (PS), English (HP)
340
368
  - ✅ **Two-Tone Design**: Dark blue header with light body for better hierarchy
@@ -342,7 +370,6 @@ When using data from the API, pass the `part_engines` array directly. The compon
342
370
  - ✅ **Clean Layout**: Flexbox-based design with semantic CSS classes
343
371
  - ✅ **Smart Data**: Only shows relevant fields (power, displacement, euro)
344
372
  - ✅ **Auto-sorting**: Engines automatically sorted alphabetically by code
345
- - ✅ **SEO-Friendly**: Static HTML enhanced with client-side tooltips
346
373
  - ✅ **Backward Compatible**: Works with both new and old API structures
347
374
  - ✅ **Touch Friendly**: Works on mobile devices
348
375
 
@@ -358,8 +385,10 @@ Special engine codes are automatically color-coded:
358
385
 
359
386
  ## Notes
360
387
 
388
+ - **Setup required**: Call `initTooltips()` once in your layout to enable tooltips
361
389
  - Hover over any engine code to see full specifications in a detailed tooltip
362
- - Tooltips use Tippy.js with custom two-tone SDS theme
390
+ - Tooltips use Tippy.js delegation pattern (one global handler for all tooltips)
391
+ - **Performance**: No client-side hydration needed - pure Astro components
363
392
  - **New API structure**: Labels come from API (e.g., "Moc", "Pojemność", "KM")
364
393
  - **No manual translations needed**: The API provides all labels and units
365
394
  - The component automatically extracts series value from nested structure
@@ -368,3 +397,18 @@ Special engine codes are automatically color-coded:
368
397
  - Commas between engine codes are automatically handled in lists
369
398
  - **Backward compatible**: Still works with old flat API structure
370
399
  - Tooltip has dark blue header (#001e50) with light gray body (#f3f4f6)
400
+
401
+ ## Migration from Vue to Astro
402
+
403
+ If upgrading from the old Vue version:
404
+
405
+ 1. **Remove `client:load`** directive from all ProductEngine/ProductEngines usage
406
+ 2. **Add tooltip initialization** to your layout:
407
+ ```astro
408
+ <script>
409
+ import { initTooltips } from 'spoko-design-system';
410
+ initTooltips();
411
+ </script>
412
+ ```
413
+ 3. **Update imports** to use Astro components (automatically handled by package exports)
414
+ 4. **No other changes needed** - props and API structure remain the same
@@ -15,16 +15,12 @@ const loremText = 'Lorem ipsum dolor sit amet, consectetur adipiscing';
15
15
  {
16
16
  fonts.map(([name, family]) => (
17
17
  <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6 hover:shadow-md transition-shadow">
18
- <div class={`font-${name} text-3xl mb-4 min-h-[120px] flex items-center`}>
19
- {loremText}
20
- </div>
18
+ <div class={`font-${name} text-3xl mb-4 min-h-[120px] flex items-center`}>{loremText}</div>
21
19
 
22
20
  <div class="border-t pt-4">
23
21
  <div class="flex items-center justify-between mb-2">
24
22
  <span class="text-lg font-medium text-gray-900">{name}</span>
25
- <span class="px-3 py-1 bg-gray-100 rounded-full text-sm text-gray-600">
26
- font-{name}
27
- </span>
23
+ <span class="px-3 py-1 bg-gray-100 rounded-full text-sm text-gray-600">font-{name}</span>
28
24
  </div>
29
25
  <code class="text-sm text-gray-500 block overflow-x-auto whitespace-nowrap">
30
26
  {family.join(', ')}
@@ -56,8 +56,7 @@ const features = [
56
56
  {
57
57
  title: 'Design Patterns',
58
58
  icon: 'streamline-freehand-color:design-process-drawing-board',
59
- description:
60
- 'Proven patterns and layouts for common use cases, from landing pages to product catalogs.',
59
+ description: 'Proven patterns and layouts for common use cases, from landing pages to product catalogs.',
61
60
  },
62
61
  {
63
62
  title: 'Developer Ready',
@@ -100,13 +99,7 @@ const exampleSites = [
100
99
  set:html={SITE.description}
101
100
  />
102
101
 
103
- <Button
104
- slot="cta-content"
105
- href="/core/introduction/"
106
- title="Spoko Design System"
107
- primary
108
- rounded
109
- >
102
+ <Button slot="cta-content" href="/core/introduction/" title="Spoko Design System" primary rounded>
110
103
  Read More
111
104
  </Button>
112
105
  </Jumbotron>
@@ -121,16 +114,8 @@ const exampleSites = [
121
114
  title={description}
122
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)"
123
116
  >
124
- <Headline
125
- as="h2"
126
- class="text-3xl"
127
- underline={false}
128
- >
129
- <Icon
130
- name={icon}
131
- aria-hidden="true"
132
- class="text-blue-400 mr-3 text-4xl"
133
- />
117
+ <Headline as="h2" class="text-3xl" underline={false}>
118
+ <Icon name={icon} aria-hidden="true" class="text-blue-400 mr-3 text-4xl" />
134
119
  {title}
135
120
  </Headline>
136
121
  <p class="text-slate-500 w-full">{description}</p>
@@ -143,16 +128,12 @@ const exampleSites = [
143
128
  <!-- Features Section -->
144
129
  <section class="py-16 px-4 max-w-5xl mx-auto">
145
130
  <div class="text-center mb-12">
146
- <Headline
147
- as="h2"
148
- class="text-3xl md:text-4xl text-gray-900 mb-6"
149
- underline="center"
150
- >
131
+ <Headline as="h2" class="text-3xl md:text-4xl text-gray-900 mb-6" underline="center">
151
132
  Why Spoko Design System?
152
133
  </Headline>
153
134
  <p class="text-lg text-gray-600 max-w-2xl mx-auto">
154
- A modern, comprehensive design system built with Astro and Vue, featuring consistent
155
- components and patterns for rapid development.
135
+ A modern, comprehensive design system built with Astro and Vue, featuring consistent components and
136
+ patterns for rapid development.
156
137
  </p>
157
138
  </div>
158
139
 
@@ -165,26 +146,17 @@ const exampleSites = [
165
146
  class="text-2xl mb-3 text-gray-900 flex items-center justify-center"
166
147
  underline={false}
167
148
  >
168
- <Icon
169
- name={icon}
170
- aria-hidden="true"
171
- class="text-4xl text-blue-400 mr-3"
172
- />
149
+ <Icon name={icon} aria-hidden="true" class="text-4xl text-blue-400 mr-3" />
173
150
  {title}
174
151
  </Headline>
175
- <p
176
- class="text-gray-600"
177
- set:html={description}
178
- />
152
+ <p class="text-gray-600" set:html={description} />
179
153
  </div>
180
154
  ))
181
155
  }
182
156
  </div>
183
157
  </section>
184
158
 
185
- <div
186
- class="mt-12 py-20 bg-blue-darker bg-vw text-white flex items-center justify-center relative"
187
- >
159
+ <div class="mt-12 py-20 bg-blue-darker bg-vw text-white flex items-center justify-center relative">
188
160
  <Quote>
189
161
  <blockquote>
190
162
  Well done is better than well said.
@@ -198,11 +170,7 @@ const exampleSites = [
198
170
  <div class="grid lg:grid-cols-2 gap-8 md:gap-12">
199
171
  <!-- Download Section -->
200
172
  <div class="text-center">
201
- <Headline
202
- underline
203
- as="h2"
204
- class="text-3xl text-gray-900 mb-8"
205
- >
173
+ <Headline underline as="h2" class="text-3xl text-gray-900 mb-8">
206
174
  <Icon
207
175
  name="streamline-freehand-color:archive-box"
208
176
  aria-hidden="true"
@@ -231,10 +199,7 @@ const exampleSites = [
231
199
  rel="noopener noreferrer"
232
200
  class="flex items-center gap-3 bg-red-600 hover:bg-red-700 text-white px-6 py-3 rounded-lg transition-colors"
233
201
  >
234
- <Icon
235
- name="vscode-icons:file-type-npm"
236
- class="text-3xl"
237
- />
202
+ <Icon name="vscode-icons:file-type-npm" class="text-3xl" />
238
203
  <span class="font-semibold">npm Package</span>
239
204
  </a>
240
205
  <a
@@ -243,10 +208,7 @@ const exampleSites = [
243
208
  rel="noopener noreferrer"
244
209
  class="flex items-center gap-3 bg-gray-800 hover:bg-gray-900 text-white px-6 py-3 rounded-lg transition-colors"
245
210
  >
246
- <Icon
247
- name="mdi:github"
248
- class="text-2xl"
249
- />
211
+ <Icon name="mdi:github" class="text-2xl" />
250
212
  <span class="font-semibold">Source Code</span>
251
213
  </a>
252
214
  </div>
@@ -258,11 +220,7 @@ const exampleSites = [
258
220
 
259
221
  <!-- Examples Section -->
260
222
  <div class="text-center">
261
- <Headline
262
- underline
263
- as="h2"
264
- class="text-3xl text-gray-900 mb-8"
265
- >
223
+ <Headline underline as="h2" class="text-3xl text-gray-900 mb-8">
266
224
  <Icon
267
225
  name="streamline-freehand-color:coding-files-network-folder"
268
226
  aria-hidden="true"
@@ -285,18 +243,13 @@ const exampleSites = [
285
243
  <h4 class="font-semibold text-gray-900 group-hover:text-blue-600">{title}</h4>
286
244
  <p class="text-sm text-gray-600">{description}</p>
287
245
  </div>
288
- <Icon
289
- name="lucide:link"
290
- class="text-gray-400 group-hover:text-blue-400"
291
- />
246
+ <Icon name="lucide:link" class="text-gray-400 group-hover:text-blue-400" />
292
247
  </a>
293
248
  ))
294
249
  }
295
250
  </div>
296
251
 
297
- <p class="text-gray-600 text-sm">
298
- See the design system in action across different project types
299
- </p>
252
+ <p class="text-gray-600 text-sm">See the design system in action across different project types</p>
300
253
  </div>
301
254
  </div>
302
255
  </section>
@@ -1,46 +1,51 @@
1
- import tippy from 'tippy.js';
2
- import 'tippy.js/dist/tippy.css';
3
- import '../styles/tippy-theme.css';
4
-
5
1
  /**
6
- * Global Tooltip Initializer
7
- * Automatically enhances all elements with data-tippy-content attribute
8
- * Works with static HTML - perfect for SEO and Astro static pages
2
+ * Global tooltip delegation script for SDS
3
+ * Uses Tippy.js delegation pattern for performance
4
+ * Handles tooltips for:
5
+ * - Engine codes (.engine-code)
6
+ * - PR codes (.btn-prcode)
7
+ * - Any other elements with data-tippy-content
9
8
  */
10
9
 
11
- function initTooltips() {
12
- // Destroy existing tooltips to avoid duplicates
13
- document.querySelectorAll('[data-tippy-content]').forEach((el: any) => {
14
- if (el._tippy) {
15
- el._tippy.destroy();
16
- }
17
- });
10
+ import { delegate } from 'tippy.js';
18
11
 
19
- // Initialize tooltips for all elements with data-tippy-content
20
- tippy('[data-tippy-content]', {
12
+ /**
13
+ * Initialize tooltips with delegation pattern
14
+ * Call this once in your layout after page load
15
+ */
16
+ export function initTooltips() {
17
+ // Delegate to body for all tooltip targets
18
+ delegate('body', {
19
+ target: '[data-tippy-content]', // Any element with data-tippy-content
20
+ allowHTML: true,
21
21
  theme: 'sds',
22
22
  placement: 'top',
23
23
  arrow: true,
24
24
  animation: 'shift-away',
25
25
  duration: [200, 150],
26
26
  maxWidth: 280,
27
- allowHTML: true, // Allow HTML content for rich tooltips
27
+ // Only show tooltip if there's actual content
28
+ onShow(instance) {
29
+ const content = instance.props.content;
30
+ if (!content || content === '' || content === 'undefined') {
31
+ return false;
32
+ }
33
+ },
28
34
  });
29
35
  }
30
36
 
31
- // Initialize on page load
32
- if (typeof window !== 'undefined') {
33
- // Initial load
34
- document.addEventListener('DOMContentLoaded', () => {
37
+ // Auto-initialize on Astro page load (for View Transitions)
38
+ if (typeof document !== 'undefined') {
39
+ document.addEventListener('astro:page-load', () => {
35
40
  initTooltips();
36
- // Reinitialize after a short delay to catch Vue components
37
- setTimeout(initTooltips, 100);
38
41
  });
39
42
 
40
- // Reinitialize on Astro page transitions (for View Transitions)
41
- document.addEventListener('astro:page-load', () => {
43
+ // Fallback for non-Astro or initial load
44
+ if (document.readyState === 'loading') {
45
+ document.addEventListener('DOMContentLoaded', () => {
46
+ initTooltips();
47
+ });
48
+ } else {
42
49
  initTooltips();
43
- // Reinitialize after a short delay to catch Vue components
44
- setTimeout(initTooltips, 100);
45
- });
50
+ }
46
51
  }
@@ -3,3 +3,7 @@
3
3
  @import 'base/grid';
4
4
 
5
5
  @import 'content.css';
6
+
7
+ /* Tippy.js for tooltips (used by ProductEngine component) */
8
+ @import 'tippy.js/dist/tippy.css';
9
+ @import './tippy-theme.css';
@@ -10,7 +10,9 @@
10
10
  font-size: 0.75rem;
11
11
  line-height: 1.5;
12
12
  border-radius: 0.5rem;
13
- box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
13
+ box-shadow:
14
+ 0 10px 15px -3px rgb(0 0 0 / 0.1),
15
+ 0 4px 6px -4px rgb(0 0 0 / 0.1);
14
16
  max-width: 280px;
15
17
  border: 1px solid #e5e7eb; /* neutral-lighter */
16
18
  }
@@ -92,7 +94,7 @@
92
94
 
93
95
  .tippy-box[data-theme~='sds'] .tooltip-label {
94
96
  font-size: 0.7rem;
95
- color: #64748B;
97
+ color: #64748b;
96
98
  font-weight: 400;
97
99
  }
98
100