spoko-design-system 1.0.0 → 1.0.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.
@@ -68,33 +68,6 @@ import HandDrive from 'spoko-design-system/src/components/HandDrive.astro'
68
68
  />
69
69
  ```
70
70
 
71
- ## API Integration
72
-
73
- The component is designed to work seamlessly with API data:
74
-
75
- ```js
76
- // API Response Format
77
- {
78
- "hand_drive": 1, // Original number (legacy)
79
- "hand_drive_type": "lhd", // Clean string value
80
- "hand_drive_text": "Left-Hand Drive" // Translated text
81
- }
82
-
83
- // Component Usage
84
- <HandDrive
85
- handDrive={partData.hand_drive_type}
86
- text={partData.hand_drive_text}
87
- />
88
- ```
89
-
90
- ### API Call Example
91
- ```js
92
- const response = await fetch('/api/parts/6R106150282V?locale=en&with_translations=1');
93
- const partData = await response.json();
94
-
95
- // partData.hand_drive_type = "lhd"
96
- // partData.hand_drive_text = "Left-Hand Drive"
97
- ```
98
71
 
99
72
  ## Design Principles
100
73
 
@@ -1,5 +1,4 @@
1
1
  ---
2
- import { changeLanguage } from "i18next";
3
2
  import { Icon } from "astro-icon/components";
4
3
  import { SITE } from "../config";
5
4
  import Jumbotron from "../components/Jumbotron.astro";
@@ -14,19 +13,19 @@ const navItems = [
14
13
  title: "Core",
15
14
  description: "Base colors, typography, shadows etc.",
16
15
  url: "/core/introduction",
17
- icon: "ant-design:cluster-outlined",
16
+ icon: "streamline-freehand-color:database",
18
17
  },
19
18
  {
20
19
  title: "Components",
21
20
  description: "The building blocks for our UI.",
22
21
  url: "/components/buttons",
23
- icon: "ant-design:build-twotone",
22
+ icon: "streamline-freehand-color:module-building-blocks",
24
23
  },
25
24
  {
26
25
  title: "Patterns",
27
26
  description: "Common patterns for building interfaces.",
28
27
  url: "/patterns/introduction",
29
- icon: "ant-design:audit-outlined",
28
+ icon: "streamline-freehand-color:layouts-array-1",
30
29
  },
31
30
  ];
32
31
  ---
@@ -75,6 +74,69 @@ const navItems = [
75
74
  }
76
75
  </div>
77
76
  </nav>
77
+
78
+ <!-- Features Section -->
79
+ <section class="py-16 px-4 max-w-5xl mx-auto">
80
+ <div class="text-center mb-12">
81
+ <Headline as="h2" textSize="3xl" underline="center" class="text-gray-900 mb-6">
82
+ Why Spoko Design System?
83
+ </Headline>
84
+ <p class="text-lg text-gray-600 max-w-2xl mx-auto">
85
+ A modern, comprehensive design system built with Astro and Vue, featuring consistent components and patterns for rapid development.
86
+ </p>
87
+ </div>
88
+
89
+ <div class="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
90
+ <div class="text-center p-6 bg-white rounded-lg shadow-sm border border-gray-100">
91
+ <Headline as="h3" textSize="xl" underline={false} class="mb-3 text-gray-900 flex items-center justify-center">
92
+ <Icon name="simple-icons:astro" aria-hidden="true" class="text-3xl text-blue-400 mr-3" />
93
+ Astro-Powered
94
+ </Headline>
95
+ <p class="text-gray-600">Built with <a href="https://astro.build/" target="_blank" rel="noopener noreferrer" class="text-blue-600 hover:text-blue-800 underline transition-colors">Astro</a> for lightning-fast performance and seamless integration with modern frameworks.</p>
96
+ </div>
97
+
98
+ <div class="text-center p-6 bg-white rounded-lg shadow-sm border border-gray-100">
99
+ <Headline as="h3" textSize="xl" underline={false} class="mb-3 text-gray-900 flex items-center justify-center">
100
+ <Icon name="streamline-freehand-color:data-transfer-document-module" aria-hidden="true" class="text-3xl text-blue-400 mr-3" />
101
+ Rich Components
102
+ </Headline>
103
+ <p class="text-gray-600">20+ production-ready components including buttons, modals, carousels, and specialized automotive elements.</p>
104
+ </div>
105
+
106
+ <div class="text-center p-6 bg-white rounded-lg shadow-sm border border-gray-100">
107
+ <Headline as="h3" textSize="xl" underline={false} class="mb-3 text-gray-900 flex items-center justify-center">
108
+ <Icon name="vscode-icons:file-type-unocss" aria-hidden="true" class="text-3xl text-blue-400 mr-3" />
109
+ UnoCSS Styling
110
+ </Headline>
111
+ <p class="text-gray-600">Atomic CSS approach with <a href="https://unocss.dev/" target="_blank" rel="noopener noreferrer" class="text-blue-600 hover:text-blue-800 underline transition-colors">UnoCSS</a> for flexible, maintainable styling and consistent design tokens.</p>
112
+ </div>
113
+
114
+ <div class="text-center p-6 bg-white rounded-lg shadow-sm border border-gray-100">
115
+ <Headline as="h3" textSize="xl" underline={false} class="mb-3 text-gray-900 flex items-center justify-center">
116
+ <Icon name="vscode-icons:file-type-vue" aria-hidden="true" class="text-3xl text-blue-400 mr-3" />
117
+ Vue Integration
118
+ </Headline>
119
+ <p class="text-gray-600">Seamless <a href="https://vuejs.org/" target="_blank" rel="noopener noreferrer" class="text-blue-600 hover:text-blue-800 underline transition-colors">Vue 3</a> component integration with TypeScript support for interactive elements.</p>
120
+ </div>
121
+
122
+ <div class="text-center p-6 bg-white rounded-lg shadow-sm border border-gray-100">
123
+ <Headline as="h3" textSize="xl" underline={false} class="mb-3 text-gray-900 flex items-center justify-center">
124
+ <Icon name="streamline-freehand-color:design-process-drawing-board" aria-hidden="true" class="text-3xl text-blue-400 mr-3" />
125
+ Design Patterns
126
+ </Headline>
127
+ <p class="text-gray-600">Proven patterns and layouts for common use cases, from landing pages to product catalogs.</p>
128
+ </div>
129
+
130
+ <div class="text-center p-6 bg-white rounded-lg shadow-sm border border-gray-100">
131
+ <Headline as="h3" textSize="xl" underline={false} class="mb-3 text-gray-900 flex items-center justify-center">
132
+ <Icon name="streamline-freehand-color:app-window-source-code" aria-hidden="true" class="text-3xl text-blue-400 mr-3" />
133
+ Developer Ready
134
+ </Headline>
135
+ <p class="text-gray-600">Complete documentation, TypeScript support, and easy npm installation for quick project setup.</p>
136
+ </div>
137
+ </div>
138
+ </section>
139
+
78
140
  <div
79
141
  class="mt-12 py-20 bg-blue-darker bg-vw text-white flex items-center justify-center relative"
80
142
  >
@@ -86,44 +148,113 @@ const navItems = [
86
148
  </Quote>
87
149
  </div>
88
150
 
89
- <div class="px-4 grid lg:grid-cols-2 gap-4 md:gap-10 max-w-5xl mx-auto text-center py-12 md:px-0">
90
-
91
- <div>
92
- <Headline underline as="div" class="mx-auto text-gray-900" textSize="3xl">Download:</Headline>
93
- <div class="grid grid-flow-col gap-4 auto-cols-max text-6xl mb-12">
94
- <a href="https://www.npmjs.com/package/spoko-design-system" rel="noopener" title="npm page" class="hover:text-accent-light">
95
- <Icon name="mdi:npm"/>
96
- </a>
97
- <a href="https://github.com/polo-blue/sds" rel="noopener" title="Github Page" class="hover:text-accent-light">
98
- <Icon name="mdi:github"/>
99
- </a>
151
+ <!-- Download & Examples Section -->
152
+ <section class="py-16 px-4 max-w-6xl mx-auto">
153
+ <div class="grid lg:grid-cols-2 gap-8 md:gap-12">
154
+
155
+ <!-- Download Section -->
156
+ <div class="text-center">
157
+ <Headline underline as="h2" class="text-gray-900 mb-8" textSize="3xl">
158
+ <Icon name="streamline-freehand-color:archive-box" aria-hidden="true" class="text-3xl text-blue-400 mr-3" />
159
+ Get Started
160
+ </Headline>
161
+
162
+ <!-- Installation Commands -->
163
+ <div class="bg-gray-900 rounded-lg p-6 mb-6 text-left space-y-4">
164
+ <div>
165
+ <p class="text-gray-400 text-sm mb-2">Install via npm:</p>
166
+ <code class="text-green-400 font-mono text-lg">npm install spoko-design-system</code>
167
+ </div>
168
+ <div>
169
+ <p class="text-gray-400 text-sm mb-2">Or with pnpm (recommended):</p>
170
+ <code class="text-blue-400 font-mono text-lg">pnpm add spoko-design-system</code>
171
+ </div>
172
+ </div>
173
+
174
+ <!-- Download Links -->
175
+ <div class="flex justify-center gap-6 mb-6">
176
+ <a href="https://www.npmjs.com/package/spoko-design-system"
177
+ target="_blank"
178
+ rel="noopener noreferrer"
179
+ class="flex items-center gap-3 bg-red-600 hover:bg-red-700 text-white px-6 py-3 rounded-lg transition-colors">
180
+ <Icon name="mdi:npm" class="text-3xl" />
181
+ <span class="font-semibold">npm Package</span>
182
+ </a>
183
+ <a href="https://github.com/polo-blue/sds"
184
+ target="_blank"
185
+ rel="noopener noreferrer"
186
+ class="flex items-center gap-3 bg-gray-800 hover:bg-gray-900 text-white px-6 py-3 rounded-lg transition-colors">
187
+ <Icon name="mdi:github" class="text-2xl" />
188
+ <span class="font-semibold">Source Code</span>
189
+ </a>
190
+ </div>
191
+
192
+ <p class="text-gray-600 text-sm">
193
+ TypeScript support included • Complete documentation • Production ready
194
+ </p>
100
195
  </div>
101
- </div>
102
-
103
-
104
- <div>
105
- <Headline underline as="div" class="mx-auto text-gray-900" textSize="3xl">Examples:</Headline>
106
- <ul class="flex flex-wrap text-2xl pt-6 lg:(py-4 gap-4) text-left justify-center lg:justify-start w-full">
107
- <li class="leading-5 me-6 mb-4 lg:mb-0 flex-shrink-0">
108
- <a href="https://catalog.polo.blue" class="example-link whitespace-nowrap" target="_blank"> catalog.polo.blue</a>
109
- </li>
110
- <li class="leading-5 me-6 mb-4 lg:mb-0 flex-shrink-0">
111
- <a href="https://polo.blue" class="example-link whitespace-nowrap" target="_blank"> polo.blue</a>
112
- </li>
113
- <li class="leading-5 me-6 mb-4 lg:mb-0 flex-shrink-0">
114
- <a href="https://spoko.space" class="example-link whitespace-nowrap" target="_blank"> spoko.space</a>
115
- </li>
116
- <li class="leading-5 me-6 mb-4 lg:mb-0 flex-shrink-0">
117
- <a href="https://sale.polo.blue/" class="example-link whitespace-nowrap" target="_blank">sale.polo.blue</a>
118
- </li>
119
- <li class="leading-5 me-6 mb-4 lg:mb-0 flex-shrink-0">
120
- <a href="https://polo6r.pl" class="example-link whitespace-nowrap" target="_blank">polo6r.pl</a>
121
- </li>
122
- </ul>
123
- </div>
124
196
 
197
+ <!-- Examples Section -->
198
+ <div class="text-center">
199
+ <Headline underline as="h2" class="text-gray-900 mb-8" textSize="3xl">
200
+ <Icon name="streamline-freehand-color:app-window-source-code" aria-hidden="true" class="text-3xl text-blue-400 mr-3" />
201
+ Live Examples
202
+ </Headline>
125
203
 
126
- </div>
204
+ <!-- Example Sites Grid -->
205
+ <div class="grid gap-4 mb-6">
206
+ <a href="https://catalog.polo.blue"
207
+ target="_blank"
208
+ rel="noopener noreferrer"
209
+ class="flex items-center justify-between p-4 bg-white border border-gray-200 rounded-lg hover:border-blue-400 hover:shadow-md transition-all group">
210
+ <div class="text-left">
211
+ <h4 class="font-semibold text-gray-900 group-hover:text-blue-600">catalog.polo.blue</h4>
212
+ <p class="text-sm text-gray-600">Car parts catalog</p>
213
+ </div>
214
+ <Icon name="lucide:link" class="text-gray-400 group-hover:text-blue-400" />
215
+ </a>
216
+
217
+ <a href="https://polo.blue"
218
+ target="_blank"
219
+ rel="noopener noreferrer"
220
+ class="flex items-center justify-between p-4 bg-white border border-gray-200 rounded-lg hover:border-blue-400 hover:shadow-md transition-all group">
221
+ <div class="text-left">
222
+ <h4 class="font-semibold text-gray-900 group-hover:text-blue-600">polo.blue</h4>
223
+ <p class="text-sm text-gray-600">Polo 6R DIY workshop & guides</p>
224
+ </div>
225
+ <Icon name="lucide:link" class="text-gray-400 group-hover:text-blue-400" />
226
+ </a>
227
+
228
+ <a href="https://sale.polo.blue/"
229
+ target="_blank"
230
+ rel="noopener noreferrer"
231
+ class="flex items-center justify-between p-4 bg-white border border-gray-200 rounded-lg hover:border-blue-400 hover:shadow-md transition-all group">
232
+ <div class="text-left">
233
+ <h4 class="font-semibold text-gray-900 group-hover:text-blue-600">sale.polo.blue</h4>
234
+ <p class="text-sm text-gray-600">Used car parts marketplace</p>
235
+ </div>
236
+ <Icon name="lucide:link" class="text-gray-400 group-hover:text-blue-400" />
237
+ </a>
238
+
239
+ <a href="https://polo6r.pl"
240
+ target="_blank"
241
+ rel="noopener noreferrer"
242
+ class="flex items-center justify-between p-4 bg-white border border-gray-200 rounded-lg hover:border-blue-400 hover:shadow-md transition-all group">
243
+ <div class="text-left">
244
+ <h4 class="font-semibold text-gray-900 group-hover:text-blue-600">polo6r.pl</h4>
245
+ <p class="text-sm text-gray-600">Polo V Manual</p>
246
+ </div>
247
+ <Icon name="lucide:link" class="text-gray-400 group-hover:text-blue-400" />
248
+ </a>
249
+ </div>
250
+
251
+ <p class="text-gray-600 text-sm">
252
+ See the design system in action across different project types
253
+ </p>
254
+ </div>
255
+
256
+ </div>
257
+ </section>
127
258
  </div>
128
259
  <script is:inline></script>
129
260
  </Layout>
@@ -1,31 +1,22 @@
1
1
  import type { CatObject } from "@types/index";
2
2
 
3
- import i18next, { t } from "i18next";
4
3
  import { getApiCategories } from "@utils/api/getCategories";
5
4
  import { getSortedCategories } from "@utils/category/getSortedCategories";
6
5
 
7
6
  // Retrieve main categories:
8
7
  export const getMainCategoryList = async (locale: string = 'en'): Promise<CatObject[]> => {
9
- // Set the selected language
10
- await i18next.changeLanguage(locale);
11
-
12
8
  // Fetch categories from API
13
9
  const categories = await getApiCategories();
14
10
 
15
- // Map categories with translations
16
- const translatedCategories = categories.map((category) => {
17
- const name = t(`cat.${category.slug}.name`);
18
- const desc = i18next.exists(`cat.${category.slug}.desc`)
19
- ? t(`cat.${category.slug}.desc`)
20
- : '';
21
-
22
- if (!desc) {
23
- console.warn('No category description', category.slug, i18next.language);
24
- }
25
-
26
- return { ...category, name, desc };
11
+ // Use category data directly (English only)
12
+ const processedCategories = categories.map((category) => {
13
+ return {
14
+ ...category,
15
+ name: category.name || category.slug,
16
+ desc: category.desc || ''
17
+ };
27
18
  });
28
19
 
29
20
  // Sort and return processed categories
30
- return translatedCategories.sort(getSortedCategories);
21
+ return processedCategories.sort(getSortedCategories);
31
22
  };
@@ -1,15 +1,12 @@
1
- import i18next from "i18next";
2
-
3
1
  export const getPriceFormatted = (product: any) => {
4
- if (i18next.language === 'en') {
5
- return new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(product.price_eur, )
6
- }
7
- if (i18next.language === 'pl') {
8
- return new Intl.NumberFormat('pl-PL', { style: 'currency', currency: 'PLN' }).format(product.price_pln, )
2
+ // Default to EUR formatting for English-only design system
3
+ if (product.price_eur) {
4
+ return new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(product.price_eur)
9
5
  }
10
- else {
11
- return 'no price'
6
+ if (product.price_pln) {
7
+ return new Intl.NumberFormat('pl-PL', { style: 'currency', currency: 'PLN' }).format(product.price_pln)
12
8
  }
9
+ return 'no price'
13
10
  }
14
11
 
15
12
 
@@ -1,4 +1,3 @@
1
- import { t } from "i18next";
2
1
 
3
2
  export const getProductCheckList = (productDetails) => {
4
3
  if (!productDetails || !productDetails.length) {
@@ -11,7 +10,7 @@ export const getProductCheckList = (productDetails) => {
11
10
  return null;
12
11
  }
13
12
 
14
- return list.map(detail => t(`detail.value.${detail.value}`));
13
+ return list.map(detail => detail.value || 'Detail');
15
14
  }
16
15
 
17
16
  export default getProductCheckList;
@@ -1,7 +1,6 @@
1
1
  /* Format numbers like details data: liters, measuring etc. */
2
2
 
3
- import i18next from "i18next";
4
-
5
3
  export default function formatLocaleNumber(number: number ) {
6
- return i18next.language === 'en' ? String(number).replace(/,/g, '.') : String(number);
4
+ // For English-only design system, always use dot notation
5
+ return String(number).replace(/,/g, '.');
7
6
  }
@@ -44,6 +44,8 @@ import phIcons from '@iconify-json/ph/icons.json';
44
44
  import simpleIcons from '@iconify-json/simple-icons/icons.json';
45
45
  import systemUiconsIcons from '@iconify-json/system-uicons/icons.json';
46
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';
47
49
 
48
50
  // List of peer selectors we want to preserve during build
49
51
  const peerSelectorClasses = [
@@ -164,36 +166,26 @@ export function createSdsConfig(customConfig: CustomConfig = {}) {
164
166
  extract({ code, id }) {
165
167
  const result = new Set();
166
168
 
167
- // Enhanced class extraction for Astro components
169
+ // Only extract from class attributes to prevent false positives
168
170
  const classRegex = /class(?:Name)?=["'`]([^"'`]+)["'`]/g;
169
171
  let match;
170
172
  while ((match = classRegex.exec(code)) !== null) {
171
173
  match[1].split(/\s+/).forEach(cls => {
172
- if (cls) result.add(cls);
174
+ // Only add classes that don't look like malformed icon names
175
+ if (cls && !cls.match(/^(lucide|simple-icons)-\w+-[A-Z]/) && !cls.includes('Grouping')) {
176
+ result.add(cls);
177
+ }
173
178
  });
174
179
  }
175
180
 
176
- // Extract peer selectors
177
- const peerRegex = /peer-[a-zA-Z0-9-]+(?::[a-zA-Z0-9-]+)*/g;
178
- const peerMatches = code.match(peerRegex);
179
- if (peerMatches) {
180
- peerMatches.forEach(match => result.add(match));
181
- }
182
-
183
- // Extract shortcut references
184
- const shortcutRegex = /\b(?:input|button|layout|component|product|jumbotron)-[a-zA-Z0-9-]+/g;
185
- const shortcutMatches = code.match(shortcutRegex);
186
- if (shortcutMatches) {
187
- shortcutMatches.forEach(match => result.add(match));
188
- }
189
-
190
- // For .astro files, extract from both template and script sections
181
+ // For .astro files, extract from dynamic class bindings
191
182
  if (id && id.endsWith('.astro')) {
192
- // Extract from dynamic class bindings
193
183
  const dynamicClassRegex = /class:\w+\s*=\s*["'`]([^"'`]+)["'`]/g;
194
184
  while ((match = dynamicClassRegex.exec(code)) !== null) {
195
185
  match[1].split(/\s+/).forEach(cls => {
196
- if (cls) result.add(cls);
186
+ if (cls && !cls.match(/^(lucide|simple-icons)-\w+-[A-Z]/) && !cls.includes('Grouping')) {
187
+ result.add(cls);
188
+ }
197
189
  });
198
190
  }
199
191
  }
@@ -240,6 +232,8 @@ export function createSdsConfig(customConfig: CustomConfig = {}) {
240
232
  'simple-icons': simpleIcons,
241
233
  'system-uicons': systemUiconsIcons,
242
234
  'uil': uilIcons,
235
+ 'vscode-icons': vscodeIcons,
236
+ 'streamline-freehand-color': streamlineFreehandColorIcons,
243
237
  }
244
238
  }),
245
239
  presetTypography(),