spoko-design-system 1.1.2 → 1.1.4

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 CHANGED
@@ -1,3 +1,15 @@
1
+ ## [1.1.4](https://github.com/polo-blue/sds/compare/v1.1.3...v1.1.4) (2025-09-23)
2
+
3
+ ### Bug Fixes
4
+
5
+ * remove unused variables and improve TypeScript types ([db637f6](https://github.com/polo-blue/sds/commit/db637f6829bb2a23342a35d8041e803d4c9ad9c4))
6
+
7
+ ## [1.1.3](https://github.com/polo-blue/sds/compare/v1.1.2...v1.1.3) (2025-09-23)
8
+
9
+ ### Bug Fixes
10
+
11
+ * resolve Astro syntax errors in components ([18003e7](https://github.com/polo-blue/sds/commit/18003e78558a1dbc8f34d0e4faed6183eaaa80cb))
12
+
1
13
  ## [1.1.2](https://github.com/polo-blue/sds/compare/v1.1.1...v1.1.2) (2025-09-23)
2
14
 
3
15
  ### Bug Fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spoko-design-system",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "private": false,
5
5
  "main": "./index.ts",
6
6
  "module": "./index.ts",
@@ -1,5 +1,5 @@
1
1
  ---
2
- const { class: className, imgSrc, imgAlt, href } = Astro.props;
2
+ const { imgSrc, imgAlt, href } = Astro.props;
3
3
 
4
4
  import Image from '../components/Image.astro';
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- const { activeCategorySlug, locale, class: className } = Astro.props;
2
+ const { activeCategorySlug } = Astro.props;
3
3
 
4
4
  import { getTranslatedLink } from '@utils/text/getTranslatedLink';
5
5
  import { getMainCategoryList } from '@utils/category/getMainCategoryList';
@@ -3,16 +3,8 @@ import CategorySidebarToggler from './CategorySidebarToggler.vue';
3
3
  import CategoryViewToggler from './CategoryViewToggler.astro';
4
4
  import { Icon } from 'astro-icon/components';
5
5
 
6
- const {
7
- category,
8
- subcategory,
9
- subtitle,
10
- subsubtitle,
11
- titleSmall,
12
- locale,
13
- showViewToggler,
14
- viewerLabels,
15
- } = Astro.props;
6
+ const { category, subcategory, subtitle, subsubtitle, titleSmall, showViewToggler, viewerLabels } =
7
+ Astro.props;
16
8
 
17
9
  const baseURL = '';
18
10
  ---
@@ -44,7 +44,7 @@ const getLinkClasses = link => {
44
44
  </Astronav>
45
45
 
46
46
  <script is:inline>
47
- window.addEventListener('DOMContentLoaded', event => {
47
+ window.addEventListener('DOMContentLoaded', () => {
48
48
  var target = document.querySelector('[aria-current="page"]');
49
49
  if (target && target.offsetTop > window.innerHeight - 100) {
50
50
  document.querySelector('.nav-groups').scrollTop = target.offsetTop;
@@ -2,7 +2,7 @@
2
2
  import ProductLink from './ProductLink.astro';
3
3
 
4
4
  // Get the product directly from the prop on render
5
- const { locale, class: className, products, isShopProduct = false, ...rest } = Astro.props;
5
+ const { locale, products, isShopProduct = false } = Astro.props;
6
6
  ---
7
7
 
8
8
  {
@@ -7,7 +7,7 @@ interface Props {
7
7
  locale: string;
8
8
  index: number;
9
9
  bigTile?: boolean;
10
- loading?: "eager" | "lazy";
10
+ loading?: 'eager' | 'lazy';
11
11
  isShopProduct?: boolean;
12
12
  }
13
13
 
@@ -17,80 +17,101 @@ const {
17
17
  bigTile,
18
18
  locale,
19
19
  index,
20
- loading = "lazy",
20
+ loading = 'lazy',
21
21
  isShopProduct = false,
22
22
  } = Astro.props;
23
23
 
24
24
  import { getProductById } from '@utils/product/getProductById';
25
25
  import { getShopProductById } from '@utils/product/getShopProductById';
26
- import { getProductUrl } from "@utils/product/getProductUrl";
27
- import { getShopProductUrl } from "@utils/product/getShopProductUrl";
28
- import { getProductTranslation } from "@utils/product/getProductTranslation";
26
+ import { getProductUrl } from '@utils/product/getProductUrl';
27
+ import { getShopProductUrl } from '@utils/product/getShopProductUrl';
28
+ import { getProductTranslation } from '@utils/product/getProductTranslation';
29
29
  import { getImageUrl } from '@utils/getImageUrl';
30
- import { ProductImage, ProductNumber, removeSemicolon, getPriceFormatted } from "spoko-design-system";
30
+ import {
31
+ ProductImage,
32
+ ProductNumber,
33
+ removeSemicolon,
34
+ getPriceFormatted,
35
+ } from 'spoko-design-system';
31
36
 
32
37
  // Użycie productObject jeśli przekazane, inaczej pobranie produktu na podstawie productId
33
- const product = productObject || (productId ? (isShopProduct ? await getShopProductById(productId) : await getProductById(productId)) : null);
38
+ const product =
39
+ productObject ||
40
+ (productId
41
+ ? isShopProduct
42
+ ? await getShopProductById(productId)
43
+ : await getProductById(productId)
44
+ : null);
34
45
 
35
46
  // Określenie URL miniatury produktu
36
- const thumb = product ? (
37
- isShopProduct
38
- ? await getImageUrl(product.images?.[0]?.path || "", "SHOP")
39
- : await getImageUrl(product.photo || "", `'ProductLink' ${product.number}`)
40
- ) : "";
47
+ const thumb = product
48
+ ? isShopProduct
49
+ ? await getImageUrl(product.images?.[0]?.path || '', 'SHOP')
50
+ : await getImageUrl(product.photo || '', `'ProductLink' ${product.number}`)
51
+ : '';
41
52
 
42
53
  // Product translation removed - using English only
43
- const productTranslation = productId ? await getProductTranslation(productId, product?.number || "") : null;
44
-
45
- const productName = product ? (
46
- isShopProduct
54
+ const productTranslation = productId
55
+ ? await getProductTranslation(productId, product?.number || '')
56
+ : null;
57
+
58
+ const productName = product
59
+ ? isShopProduct
47
60
  ? product.name_en || product.name
48
61
  : productTranslation?.name || product.name
49
- ) : 'NO NAME';
62
+ : 'NO NAME';
50
63
 
51
64
  const nameFormatted = removeSemicolon(productName.toString());
52
65
  ---
53
66
 
54
- {product && (
55
- <div class={bigTile ? 'product-link--big-tile' : 'product-thumb--plp product-thumb--carousel'}>
56
- {product.photo !== null && thumb ? (
57
- <ProductImage
58
- imagesApiUrl="https://api.polo.blue"
59
- imageObject={{
60
- src: thumb,
61
- alt: productName,
62
- height: '180',
63
- width: '240',
64
- loading
65
- }}
66
- />
67
- ) : (
68
- <img src="/1x1.png" class="bg-neutral-lightest/70" alt={productName} />
69
- )}
70
- </div>
67
+ {
68
+ product && (
69
+ <>
70
+ <div
71
+ class={bigTile ? 'product-link--big-tile' : 'product-thumb--plp product-thumb--carousel'}
72
+ >
73
+ {product.photo !== null && thumb ? (
74
+ <ProductImage
75
+ imagesApiUrl="https://api.polo.blue"
76
+ imageObject={{
77
+ src: thumb,
78
+ alt: productName,
79
+ height: '180',
80
+ width: '240',
81
+ loading,
82
+ }}
83
+ />
84
+ ) : (
85
+ <img src="/1x1.png" class="bg-neutral-lightest/70" alt={productName} />
86
+ )}
87
+ </div>
88
+
89
+ <div class={bigTile ? '' : 'sm:pl-4'}>
90
+ {product.price_pln && (
91
+ <p class="block mb-2 font-600 font-headbold text-5">{getPriceFormatted(product)}</p>
92
+ )}
71
93
 
72
- <div class={bigTile ? '' : 'sm:pl-4'}>
73
- {product.price_pln && (
74
- <p class="block mb-2 font-600 font-headbold text-5">
75
- {getPriceFormatted(product)}
76
- </p>
77
- )}
94
+ <a
95
+ class="product-link--url"
96
+ href={
97
+ isShopProduct
98
+ ? getShopProductUrl(product.slug, locale)
99
+ : getProductUrl(product.number, locale)
100
+ }
101
+ itemprop="url"
102
+ title={product.number}
103
+ set:html={nameFormatted}
104
+ />
78
105
 
79
- <a
80
- class="product-link--url"
81
- href={isShopProduct ? getShopProductUrl(product.slug, locale) : getProductUrl(product.number, locale)}
82
- itemprop="url"
83
- title={product.number}
84
- set:html={nameFormatted}
85
- />
106
+ <ProductNumber productNumber={product.number} copyDisabled={true} />
86
107
 
87
- <ProductNumber productNumber={product.number} copyDisabled={true} />
88
-
89
- {index !== null && (
90
- <>
91
- <meta itemprop="position" content={index.toString()} />
92
- <meta itemprop="name" content={nameFormatted} />
93
- </>
94
- )}
95
- </div>
96
- )}
108
+ {index !== null && (
109
+ <>
110
+ <meta itemprop="position" content={index.toString()} />
111
+ <meta itemprop="name" content={nameFormatted} />
112
+ </>
113
+ )}
114
+ </div>
115
+ </>
116
+ )
117
+ }
@@ -4,7 +4,6 @@ import useFormatProductNumber from '../../utils/product/useFormatProductNumber';
4
4
 
5
5
  const {
6
6
  productNumber,
7
- copyDisabled = false,
8
7
  isPdp = false,
9
8
  small = false,
10
9
  big = false,
@@ -1,47 +1,51 @@
1
1
  ---
2
- const { productObject, locale, index } = Astro.props;
3
- import Image from "./Image.astro"
4
- import ProductNumber from "./Product/ProductNumber.astro"
2
+ const { productObject, index } = Astro.props;
3
+ import Image from './Image.astro';
4
+ import ProductNumber from './Product/ProductNumber.astro';
5
5
  ---
6
6
 
7
- { productObject &&
8
- (
9
-
10
- <!-- product image -->
11
- <div class="img--4/3 img--small">
12
- { productObject.photo !== null ?
13
- <Image
14
- imageObject={
15
- {
7
+ {
8
+ productObject && (
9
+ <>
10
+ <div class="img--4/3 img--small">
11
+ {productObject.photo !== null ? (
12
+ <Image
13
+ imageObject={{
16
14
  src: 'https://img.freepik.com/darmowe-wektory/tlo-retro-modeli-geometrycznych_52683-17902.jpg?w=1380&t=st=1706311337',
17
15
  alt: 'Image Alt',
18
16
  height: '180',
19
17
  width: '240',
20
- class: 'img--overlay object-cover'
21
- }
22
- }
23
- />
24
- :
25
- <img src="/1x1.png" class="bg-gray-100/70" alt={productObject.name} />
26
- }
27
- </div>
28
-
29
- <!-- product deails -->
30
- <div class="sm:pl-4 flex flex-col" >
31
- <a class="font-light leading-none mb-2 pr-4 line-clamp-2 h-[2em] before:(content-empty absolute left-0 right-4 h-full top-0)"
32
- href={productObject.url} itemprop="url"
33
- title={productObject.number}
34
- >
35
- { productObject.name }
36
- </a>
18
+ class: 'img--overlay object-cover',
19
+ }}
20
+ />
21
+ ) : (
22
+ <img src="/1x1.png" class="bg-gray-100/70" alt={productObject.name} />
23
+ )}
24
+ </div>
37
25
 
38
- <ProductNumber productNumber={productObject.number} copyDisabled={false} buttonTexts={{ copy: 'Copy', copied: 'Copied' }} />
39
-
40
- { index !== null &&
41
- ( <meta itemprop="position" content={String(index)} />
42
- <meta itemprop="name" content={productObject.name} /> )
43
- }
44
- </div>
26
+ <div class="sm:pl-4 flex flex-col">
27
+ <a
28
+ class="font-light leading-none mb-2 pr-4 line-clamp-2 h-[2em] before:(content-empty absolute left-0 right-4 h-full top-0)"
29
+ href={productObject.url}
30
+ itemprop="url"
31
+ title={productObject.number}
32
+ >
33
+ {productObject.name}
34
+ </a>
45
35
 
46
- )}
36
+ <ProductNumber
37
+ productNumber={productObject.number}
38
+ copyDisabled={false}
39
+ buttonTexts={{ copy: 'Copy', copied: 'Copied' }}
40
+ />
47
41
 
42
+ {index !== null && (
43
+ <>
44
+ <meta itemprop="position" content={String(index)} />
45
+ <meta itemprop="name" content={productObject.name} />
46
+ </>
47
+ )}
48
+ </div>
49
+ </>
50
+ )
51
+ }
@@ -32,7 +32,7 @@ const navItemsLeft = [
32
32
  <div class="hidden sm:block sm:ml-6">
33
33
  <div class="flex space-x-4" itemprop="hasPart">
34
34
  {
35
- navItemsLeft.map(({ title, description, url, img }) => (
35
+ navItemsLeft.map(({ title, description, url }) => (
36
36
  <a
37
37
  href={url}
38
38
  class="text-gray-400 hover:bg-blue-darker hover:text-white px-3 py-1 rounded-full text-sm font-medium"
@@ -6,12 +6,6 @@ import { iconConfig } from '../../../icon.config';
6
6
  const iconifyUrl = 'https://icon-sets.iconify.design/';
7
7
  const ICONS = iconConfig.include;
8
8
 
9
- type IconGroup = {
10
- name: string;
11
- icons: string[];
12
- url: string;
13
- };
14
-
15
9
  const sortedIconCollections = Object.entries(ICONS)
16
10
  .sort(([a], [b]) => a.localeCompare(b))
17
11
  .map(([name, icons]) => ({
@@ -1,49 +1,49 @@
1
1
  ---
2
- import MainLayout from '../../layouts/MainLayout.astro'
3
- import { typography } from '../../../uno-config/theme/typography'
2
+ import MainLayout from '../../layouts/MainLayout.astro';
3
+ import { typography } from '../../../uno-config/theme/typography';
4
4
 
5
- const fonts = Object.entries(typography.fontFamily)
6
- const loremText = "Lorem ipsum dolor sit amet, consectetur adipiscing"
5
+ const fonts = Object.entries(typography.fontFamily);
6
+ const loremText = 'Lorem ipsum dolor sit amet, consectetur adipiscing';
7
7
  ---
8
8
 
9
9
  <MainLayout>
10
- <div class="max-w-7xl mx-auto px-4 py-8 sm:px-6 lg:px-8">
11
- <h1 class="text-4xl font-bold text-gray-900 mb-8">Font Family Preview</h1>
12
-
13
- <!-- Font Preview Cards -->
14
- <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-12">
15
- {fonts.map(([name, family]) => (
16
- <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6 hover:shadow-md transition-shadow">
17
- <!-- Font Sample -->
18
- <div class={`font-${name} text-3xl mb-4 min-h-[120px] flex items-center`}>
19
- {loremText}
20
- </div>
21
-
22
- <!-- Font Info -->
23
- <div class="border-t pt-4">
24
- <div class="flex items-center justify-between mb-2">
25
- <span class="text-lg font-medium text-gray-900">{name}</span>
26
- <span class="px-3 py-1 bg-gray-100 rounded-full text-sm text-gray-600">font-{name}</span>
27
- </div>
28
- <code class="text-sm text-gray-500 block overflow-x-auto whitespace-nowrap">
29
- {family.join(', ')}
30
- </code>
31
- </div>
32
- </div>
33
- ))}
34
- </div>
10
+ <div class="max-w-7xl mx-auto px-4 py-8 sm:px-6 lg:px-8">
11
+ <h1 class="text-4xl font-bold text-gray-900 mb-8">Font Family Preview</h1>
35
12
 
36
- <!-- Font Configuration Code -->
37
- <div class="bg-gray-900 rounded-lg overflow-hidden">
38
- <div class="bg-gray-800 px-4 py-2 text-gray-400">
39
- Font Configuration
13
+ <!-- Font Preview Cards -->
14
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-12">
15
+ {
16
+ fonts.map(([name, family]) => (
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}
40
20
  </div>
41
- <pre class="p-4 overflow-x-auto">
21
+
22
+ <div class="border-t pt-4">
23
+ <div class="flex items-center justify-between mb-2">
24
+ <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>
28
+ </div>
29
+ <code class="text-sm text-gray-500 block overflow-x-auto whitespace-nowrap">
30
+ {family.join(', ')}
31
+ </code>
32
+ </div>
33
+ </div>
34
+ ))
35
+ }
36
+ </div>
37
+
38
+ <!-- Font Configuration Code -->
39
+ <div class="bg-gray-900 rounded-lg overflow-hidden">
40
+ <div class="bg-gray-800 px-4 py-2 text-gray-400">Font Configuration</div>
41
+ <pre
42
+ class="p-4 overflow-x-auto">
42
43
  <code class="text-gray-200 text-sm">
43
44
  {fonts.map(([name, family]) => `font-${name}:\n${family.join(', ')}
44
45
  `).join('\n')}</code>
45
46
  </pre>
46
- </div>
47
47
  </div>
48
+ </div>
48
49
  </MainLayout>
49
-
@@ -4,7 +4,7 @@ import { getApiCategories } from '@utils/api/getCategories';
4
4
  import { getSortedCategories } from '@utils/category/getSortedCategories';
5
5
 
6
6
  // Retrieve main categories:
7
- export const getMainCategoryList = async (locale: string = 'en'): Promise<CatObject[]> => {
7
+ export const getMainCategoryList = async (): Promise<CatObject[]> => {
8
8
  // Fetch categories from API
9
9
  const categories = await getApiCategories();
10
10
 
@@ -1,4 +1,9 @@
1
- export const getPriceFormatted = (product: any) => {
1
+ interface Product {
2
+ price_eur?: number;
3
+ price_pln?: number;
4
+ }
5
+
6
+ export const getPriceFormatted = (product: Product) => {
2
7
  // Default to EUR formatting for English-only design system
3
8
  if (product.price_eur) {
4
9
  return new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(