spoko-design-system 0.2.84 → 0.2.86

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/astro.config.mjs CHANGED
@@ -1,15 +1,15 @@
1
1
  import { defineConfig, sharpImageService } from "astro/config";
2
+ import { iconConfig } from './icon.config';
2
3
  import vue from "@astrojs/vue";
3
4
  import mdx from '@astrojs/mdx';
4
5
  import UnoCSS from '@unocss/astro';
5
- // import Compress from "astro-compress";
6
- // https://github.com/yassinedoghri/astro-i18next#readme
7
6
  import astroI18next from "astro-i18next";
8
7
  import icon from "astro-icon";
9
8
  import sitemap from "@astrojs/sitemap";
10
9
  import pagefind from "astro-pagefind";
11
10
  import AstroPWA from '@vite-pwa/astro';
12
11
  import metaTags from "astro-meta-tags";
12
+ import playformInline from "@playform/inline";
13
13
 
14
14
  // https://astro.build/config
15
15
  export default defineConfig({
@@ -74,72 +74,8 @@ export default defineConfig({
74
74
  }
75
75
  }), UnoCSS({
76
76
  injectReset: true
77
- }), icon({
78
- include: {
79
- // mdi: ["*"], // (Default) Loads entire Material Design Icon set
80
- mdi: ["npm", "github", "facebook", "instagram", "post-it-note-edit-outline", "car-hatchback", "car-door", "car-side", "car-windshield-outline", "car-light-alert", "car-tire-alert", "car-light-dimmed", "car-light-fog", "car-light-high", "car-parking-lights", "car-esp", "car-brake-abs", "car-horn", "engine-outline", "fan", "fan-off", "air-conditioner", "coolant-temperature", "car-brake-alert", "car-traction-control", "card-text-outline", "fuel", "oil", "hazard-lights", "credit-card-outline"],
81
- "ant-design": ["menu-fold-outlined", "menu-unfold-outlined", "menu-outlined", "cluster-outlined", "audit-outlined", "build-twotone", "home-outlined", "close-outlined"],
82
- bi: ["envelope-open", "credit-card", "qr-code", "list-check", "list-task", "text-indent-left", "text-indent-right", "tag", "tags", "x"],
83
- bx: ["arrow-back", "check", "detail", "file", "car", "credit-card", "barcode", "qr"],
84
- carbon: ["language", "checkmark", "home", "dicom-overlay"],
85
- el: ["star-empty", "star", "heart-empty", "heart", "map-marker", "fire", "quote-right", "qrcode", "car", "indent-left", "indent-right", "ok"],
86
- 'eos-icons': ["three-dots-loading", "bubble-loading", "loading", "installing"],
87
- fluent: ["share-android-24-regular", "checkmark-24-filled", "tag-24-regular", "tag-multiple-24-regular"],
88
- "fluent-emoji": ["cookie", "construction", "warning", "wrench"],
89
- la: ["arrow-right", "arrow-left", "car", "car-side"],
90
- octicon: ["chevron-left-24", "x-24", "alert-24", "graph-24", "comment-24", "comment-discussion-24", "clock-24", "star-24", "star-fill-24", "file-media-24", "heart-24", "heart-fill-24", "project-roadmap-24", "location-24", "info-24", "mark-github-16"],
91
- uil: ["map-marker", "envelope", "phone", "tag-alt"],
92
- "simple-icons": ["ebay", "allegro", "volkswagen", "audi", "skoda", "seat", "whatsapp", "x", "facebook", "messenger", "instagram", "telegram"],
93
- "icon-park-outline": ["shopping-bag", "comment", "comments", "tag-one"],
94
- flowbite: ["arrow-left-outline", "arrow-right-outline", "angle-left-outline", "angle-right-outline", "chevron-left-outline", "chevron-right-outline", "map-location-outline", "map-pin-alt-solid", "x-outline", "messages-outline", "arrow-down-to-bracket-outline", "check-outline"]
95
- }
96
- }),
97
- // Compress({
98
- // CSS: true,
99
- // HTML: {
100
- // caseSensitive: true,
101
- // collapseBooleanAttributes: true,
102
- // collapseInlineTagWhitespace: false,
103
- // collapseWhitespace: true,
104
- // conservativeCollapse: false,
105
- // continueOnParseError: false,
106
- // customAttrAssign: [],
107
- // customAttrCollapse: "",
108
- // customAttrSurround: [],
109
- // customEventAttributes: [/^on[a-z]{3,}$/],
110
- // decodeEntities: false,
111
- // html5: true,
112
- // ignoreCustomComments: [],
113
- // ignoreCustomFragments: [],
114
- // includeAutoGeneratedTags: true,
115
- // keepClosingSlash: true,
116
- // maxLineLength: null,
117
- // minifyCSS: true,
118
- // minifyJS: true,
119
- // minifyURLs: false,
120
- // preserveLineBreaks: false,
121
- // preventAttributesEscaping: false,
122
- // processConditionalComments: true,
123
- // processScripts: ["module"],
124
- // quoteCharacter: "",
125
- // removeAttributeQuotes: true,
126
- // removeComments: false,
127
- // removeEmptyAttributes: false,
128
- // removeEmptyElements: false,
129
- // removeOptionalTags: false,
130
- // removeRedundantAttributes: true,
131
- // removeScriptTypeAttributes: true,
132
- // removeStyleLinkTypeAttributes: true,
133
- // removeTagWhitespace: true,
134
- // sortAttributes: true,
135
- // sortClassName: true,
136
- // trimCustomFragments: false,
137
- // useShortDoctype: false
138
- // },
139
- // Image: false,
140
- // JavaScript: true,
141
- // SVG: true
142
- // }),
77
+ }),
78
+ icon(iconConfig),
143
79
  metaTags(),
144
80
  (await import("@playform/inline")).default(),
145
81
  pagefind(),
package/icon.config.ts ADDED
@@ -0,0 +1,225 @@
1
+ interface IconConfig {
2
+ include: {
3
+ [key: string]: string[];
4
+ }
5
+ }
6
+
7
+ export const iconConfig: IconConfig = {
8
+ include: {
9
+ mdi: [
10
+ // Social
11
+ "npm",
12
+ "github",
13
+ "facebook",
14
+ "instagram",
15
+
16
+ // Notes & Content
17
+ "post-it-note-edit-outline",
18
+
19
+ // Car related
20
+ "car-hatchback",
21
+ "car-door",
22
+ "car-side",
23
+ "car-windshield-outline",
24
+ "car-light-alert",
25
+ "car-tire-alert",
26
+ "car-light-dimmed",
27
+ "car-light-fog",
28
+ "car-light-high",
29
+ "car-parking-lights",
30
+ "car-esp",
31
+ "car-brake-abs",
32
+ "car-horn",
33
+ "engine-outline",
34
+
35
+ // Climate & Temperature
36
+ "fan",
37
+ "fan-off",
38
+ "air-conditioner",
39
+ "coolant-temperature",
40
+
41
+ // Alerts & Warnings
42
+ "car-brake-alert",
43
+ "car-traction-control",
44
+
45
+ // Other
46
+ "card-text-outline",
47
+ "fuel",
48
+ "oil",
49
+ "hazard-lights",
50
+ "credit-card-outline"
51
+ ],
52
+
53
+ "ant-design": [
54
+ "menu-fold-outlined",
55
+ "menu-unfold-outlined",
56
+ "menu-outlined",
57
+ "bars-outlined",
58
+ "appstore-outlined",
59
+ "cluster-outlined",
60
+ "audit-outlined",
61
+ "build-twotone",
62
+ "home-outlined",
63
+ "close-outlined"
64
+ ],
65
+
66
+ bi: [
67
+ "envelope-open",
68
+ "credit-card",
69
+ "qr-code",
70
+ "list-check",
71
+ "list-task",
72
+ "text-indent-left",
73
+ "text-indent-right",
74
+ "tag",
75
+ "tags",
76
+ "x",
77
+ "graph-up"
78
+ ],
79
+
80
+ bx: [
81
+ "arrow-back",
82
+ "check",
83
+ "detail",
84
+ "file",
85
+ "car",
86
+ "credit-card",
87
+ "barcode",
88
+ "qr"
89
+ ],
90
+
91
+ carbon: [
92
+ "language",
93
+ "checkmark",
94
+ "home",
95
+ "dicom-overlay"
96
+ ],
97
+
98
+ el: [
99
+ "star-empty",
100
+ "star",
101
+ "heart-empty",
102
+ "heart",
103
+ "map-marker",
104
+ "fire",
105
+ "quote-right",
106
+ "qrcode",
107
+ "car",
108
+ "indent-left",
109
+ "indent-right",
110
+ "ok"
111
+ ],
112
+
113
+ 'eos-icons': [
114
+ "three-dots-loading",
115
+ "bubble-loading",
116
+ "loading",
117
+ "installing"
118
+ ],
119
+
120
+ fluent: [
121
+ "share-android-24-regular",
122
+ "checkmark-24-filled",
123
+ "tag-24-regular",
124
+ "tag-multiple-24-regular"
125
+ ],
126
+
127
+ "fluent-emoji": [
128
+ "cookie",
129
+ "construction",
130
+ "warning",
131
+ "wrench"
132
+ ],
133
+
134
+ la: [
135
+ "arrow-right",
136
+ "arrow-left",
137
+ "car",
138
+ "car-side"
139
+ ],
140
+
141
+ octicon: [
142
+ "chevron-left-24",
143
+ "x-24",
144
+ "alert-24",
145
+ "graph-24",
146
+ "comment-24",
147
+ "comment-discussion-24",
148
+ "clock-24",
149
+ "star-24",
150
+ "star-fill-24",
151
+ "file-media-24",
152
+ "heart-24",
153
+ "heart-fill-24",
154
+ "project-roadmap-24",
155
+ "location-24",
156
+ "info-24",
157
+ "mark-github-16"
158
+ ],
159
+
160
+ uil: [
161
+ "map-marker",
162
+ "envelope",
163
+ "phone",
164
+ "tag-alt"
165
+ ],
166
+
167
+ "simple-icons": [
168
+ "ebay",
169
+ "allegro",
170
+ "volkswagen",
171
+ "audi",
172
+ "skoda",
173
+ "seat",
174
+ "whatsapp",
175
+ "x",
176
+ "facebook",
177
+ "messenger",
178
+ "instagram",
179
+ "telegram",
180
+ "carrd"
181
+ ],
182
+
183
+ "icon-park-outline": [
184
+ "shopping-bag",
185
+ "comment",
186
+ "comments",
187
+ "tag-one"
188
+ ],
189
+
190
+ flowbite: [
191
+ "arrow-left-outline",
192
+ "arrow-right-outline",
193
+ "angle-left-outline",
194
+ "angle-right-outline",
195
+ "chevron-left-outline",
196
+ "chevron-right-outline",
197
+ "map-location-outline",
198
+ "map-pin-alt-solid",
199
+ "x-outline",
200
+ "messages-outline",
201
+ "arrow-down-to-bracket-outline",
202
+ "check-outline"
203
+ ],
204
+
205
+ // Nowe kolekcje
206
+ ph: [
207
+ 'images-light',
208
+ 'image-square-thin',
209
+ 'cat-thin',
210
+ 'copy-simple-light'
211
+ ],
212
+
213
+ ic: [
214
+ 'sharp-photo-library'
215
+ ],
216
+
217
+ 'material-symbols-light': [
218
+ 'broken-image-outline'
219
+ ],
220
+
221
+ et: [
222
+ 'documents'
223
+ ]
224
+ }
225
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spoko-design-system",
3
- "version": "0.2.84",
3
+ "version": "0.2.86",
4
4
  "private": false,
5
5
  "main": "./index.ts",
6
6
  "module": "./index.ts",
@@ -10,7 +10,8 @@
10
10
  "import": "./index.ts",
11
11
  "require": "./index.ts"
12
12
  },
13
- "./styles/*": "./src/styles/*"
13
+ "./styles/*": "./src/styles/*",
14
+ "./icons": "./icon.config.ts"
14
15
  },
15
16
  "scripts": {
16
17
  "dev": "astro dev",
@@ -51,21 +52,24 @@
51
52
  "@iconify-json/circle-flags": "^1.2.6",
52
53
  "@iconify-json/el": "^1.2.1",
53
54
  "@iconify-json/eos-icons": "^1.2.2",
55
+ "@iconify-json/et": "^1.2.1",
54
56
  "@iconify-json/flowbite": "^1.2.4",
55
57
  "@iconify-json/fluent": "^1.2.13",
56
58
  "@iconify-json/fluent-emoji": "1.2.3",
59
+ "@iconify-json/ic": "^1.2.2",
57
60
  "@iconify-json/icon-park-outline": "^1.2.2",
58
61
  "@iconify-json/la": "^1.2.1",
62
+ "@iconify-json/material-symbols-light": "^1.2.14",
59
63
  "@iconify-json/mdi": "^1.2.3",
60
64
  "@iconify-json/noto-v1": "^1.2.1",
61
- "@iconify-json/octicon": "^1.2.3",
65
+ "@iconify-json/octicon": "^1.2.4",
62
66
  "@iconify-json/ph": "^1.2.2",
63
67
  "@iconify-json/simple-icons": "^1.2.23",
64
68
  "@iconify-json/uil": "^1.2.3",
65
- "@iconify/json": "^2.2.303",
69
+ "@iconify/json": "^2.2.304",
66
70
  "@iconify/vue": "^4.3.0",
67
71
  "@playform/compress": "^0.1.7",
68
- "@playform/inline": "github:playform/inline",
72
+ "@playform/inline": "^0.1.1",
69
73
  "@types/node": "^22.13.1",
70
74
  "@unocss/astro": "^65.4.3",
71
75
  "@unocss/preset-attributify": "^65.4.3",
@@ -16,6 +16,6 @@ const props = defineProps({
16
16
  <template>
17
17
  <div v-if="(props.badges && props.badges.length > 0)" class="absolute z-2">
18
18
  <Badge v-for="(badge, index) in props.badges" :key="index" :badge="badge"
19
- :class="(badge.toLocaleLowerCase().includes('gti') ? 'bg-red-600' : badge.toLocaleLowerCase().includes('motorsport') ? 'bg-blue-600' : 'bg-black')" />
19
+ :class="(badge.toLocaleLowerCase().includes('gti') ? 'bg-red-600' : badge.toLocaleLowerCase().includes('motorsport') ? 'bg-blue-wrc' : 'bg-black')" />
20
20
  </div>
21
21
  </template>
@@ -75,7 +75,7 @@ const activeIndex = activeCategorySlug && categories ? categories.map(a => a.slu
75
75
 
76
76
  <style >
77
77
  .active {
78
- @apply bg-blue-700 text-white bg-opacity-100;
78
+ @apply bg-blue-darker text-white bg-opacity-100;
79
79
 
80
80
  &:not(:hover) .cats-img {
81
81
  filter: invert(100%);
@@ -1,63 +1,77 @@
1
1
  ---
2
2
  import CategorySidebarToggler from './CategorySidebarToggler.vue';
3
+ import CategoryViewToggler from './CategoryViewToggler.astro';
3
4
  import { Icon } from 'astro-icon/components';
4
- const { category, subcategory, subtitle, subsubtitle, titleSmall, locale } = Astro.props;
5
+ const { category, subcategory, subtitle, subsubtitle, titleSmall, locale, showViewToggler, viewerLabels } = Astro.props;
5
6
  import { t } from "i18next";
6
7
 
7
8
  // Compute base URL for localization
8
9
  const baseURL = locale === 'en' ? '' : `/${locale}`;
10
+
11
+ // View toggler translations
12
+ // const viewerLabels = {
13
+ // showText: t('category.view.show'),
14
+ // listText: t('category.view.list'),
15
+ // gridText: t('category.view.grid'),
16
+ // listAriaLabel: t('category.view.listAriaLabel'),
17
+ // gridAriaLabel: t('category.view.gridAriaLabel')
18
+ // };
9
19
  ---
10
20
 
11
- <div ref="el"
12
- class="flex flex-nowrap pr-3 sm:pb-3 sm:pt-4 md:pl-4 relative z-10-off bg-gray-100 md:bg-white"
13
- transition:name="category-details"
14
- transition:animate="fade"
21
+ <div
22
+ ref="el"
23
+ class="flex flex-nowrap items-center pr-3 sm:pb-3 sm:pt-4 md:pl-4 relative z-10-off bg-neutral-lightest md:bg-white"
24
+ transition:name="category-details"
25
+ transition:animate="fade"
15
26
  >
16
- <CategorySidebarToggler onclick="toggleSidebar()">
27
+ <CategorySidebarToggler client:load onclick="toggleSidebar()">
17
28
  <Icon name="ant-design:menu-fold-outlined" class="toggler-btn hidden md:block" />
18
29
  <Icon name="ant-design:menu-unfold-outlined" class="toggler-btn hidden" />
19
30
  <Icon name="ant-design:menu-outlined" class="toggler-btn md:hidden" />
20
31
  </CategorySidebarToggler>
21
32
 
22
33
  <div class="overflow-x-auto overflow-y-hidden flex max-w-full items-center">
23
- {subtitle ? (
24
- <>
25
- <a class="text-lg font-vw-headregular whitespace-nowrap block" href={`${baseURL}/${category.slug}/`}>
26
- {category.name}
27
- {titleSmall && <small>{titleSmall}</small>}
28
- </a>
29
- <span class="text-gray-200 text-lg inline-block px-1 font-headlight">/</span>
30
- {!subsubtitle ? (
31
- <h1 class="text-lg py-2.5 sm:py-0 whitespace-nowrap underline underline-offset-6 decoration-blue-300 decoration-0.5">
32
- {subtitle} <span class="sr-only"> {t('catalog.extra-short')}</span>
33
- </h1>
34
- ) : (
35
- <>
36
- <div class="text-lg py-2.5 sm:py-0 whitespace-nowrap ">
37
- <a href={`${baseURL}/${category.slug}/${subcategory.slug}/`}>
38
- {subtitle}
39
- </a>
40
- </div>
41
- <span class="text-gray-200 text-lg inline-block px-1 font-headlight">/</span>
42
- <h1 class="text-lg py-2.5 sm:py-0 whitespace-nowrap underline underline-offset-6 decoration-blue-300 decoration-0.5">
43
- {subsubtitle} <span class="sr-only"> {t('catalog.extra-short')}</span>
44
- </h1>
45
- </>
46
- )}
47
- </>
48
- ) : (
49
- <h1 class="text-lg py-2.5 sm:py-0 whitespace-nowrap">
34
+ {subtitle ? (
35
+ <>
36
+ <a class="text-lg font-vw-headregular whitespace-nowrap block" href={`${baseURL}/${category.slug}/`}>
50
37
  {category.name}
51
38
  {titleSmall && <small>{titleSmall}</small>}
52
- <span class="sr-only"> {t('catalog.extra-short')}</span>
53
- </h1>
54
- )}
39
+ </a>
40
+ <span class="text-neutral-lighter text-lg inline-block px-1 font-headlight">/</span>
41
+ {!subsubtitle ? (
42
+ <h1 class="text-lg py-2.5 sm:py-0 whitespace-nowrap underline underline-offset-6 decoration-blue-300 decoration-0.5">
43
+ {subtitle} <span class="sr-only"> {t('catalog.extra-short')}</span>
44
+ </h1>
45
+ ) : (
46
+ <>
47
+ <div class="text-lg py-2.5 sm:py-0 whitespace-nowrap ">
48
+ <a href={`${baseURL}/${category.slug}/${subcategory.slug}/`}>
49
+ {subtitle}
50
+ </a>
51
+ </div>
52
+ <span class="text-neutral-lighter text-lg inline-block px-1 font-headlight">/</span>
53
+ <h1 class="text-lg py-2.5 sm:py-0 whitespace-nowrap underline underline-offset-6 decoration-blue-300 decoration-0.5">
54
+ {subsubtitle} <span class="sr-only"> {t('catalog.extra-short')}</span>
55
+ </h1>
56
+ </>
57
+ )}
58
+ </>
59
+ ) : (
60
+ <h1 class="text-lg py-2.5 sm:py-0 whitespace-nowrap">
61
+ {category.name}
62
+ {titleSmall && <small>{titleSmall}</small>}
63
+ <span class="sr-only"> {t('catalog.extra-short')}</span>
64
+ </h1>
65
+ )}
55
66
  </div>
67
+
68
+ <CategoryViewToggler {...viewerLabels} showViewToggler={showViewToggler} />
56
69
  </div>
57
70
 
58
71
  <script is:inline>
59
72
  function toggleSidebar() {
60
73
  const sidebar = document.getElementById('sidebar');
74
+ const togglers = document.querySelectorAll('.toggler-btn');
61
75
  const isMobile = window.matchMedia("(max-width: 768px)").matches;
62
76
 
63
77
  if (sidebar) {
@@ -69,13 +83,17 @@ const baseURL = locale === 'en' ? '' : `/${locale}`;
69
83
  document.body.classList.remove('overflow-hidden');
70
84
  sidebar.classList.toggle('collapsed');
71
85
  localStorage.setItem('sidebarState', sidebar.classList.contains('collapsed') ? 'closed' : 'open');
86
+
87
+ // Toggle visibility of buttons on desktop
88
+ togglers.forEach(btn => btn.classList.toggle('hidden'));
72
89
  }
73
90
  }
74
91
  }
75
92
 
76
93
  // Read status from localStorage on page load
77
- document.addEventListener('DOMContentLoaded', () => {
94
+ document.addEventListener('astro:page-load', () => {
78
95
  const sidebar = document.getElementById('sidebar');
96
+ const togglers = document.querySelectorAll('.toggler-btn');
79
97
  const isMobile = window.matchMedia("(max-width: 768px)").matches;
80
98
  const savedState = localStorage.getItem('sidebarState');
81
99
 
@@ -85,22 +103,35 @@ const baseURL = locale === 'en' ? '' : `/${locale}`;
85
103
  sidebar.classList.add('show');
86
104
  } else {
87
105
  sidebar.classList.remove('collapsed');
106
+ // Show correct button on desktop
107
+ if (togglers.length >= 2) {
108
+ togglers[0].classList.remove('hidden'); // menu-fold
109
+ togglers[1].classList.add('hidden'); // menu-unfold
110
+ }
88
111
  }
89
112
  } else if (savedState === 'closed') {
90
113
  if (isMobile) {
91
114
  sidebar.classList.remove('show');
92
115
  } else {
93
116
  sidebar.classList.add('collapsed');
117
+ // Show correct button on desktop
118
+ if (togglers.length >= 2) {
119
+ togglers[0].classList.add('hidden'); // menu-fold
120
+ togglers[1].classList.remove('hidden'); // menu-unfold
121
+ }
94
122
  }
95
123
  }
96
124
  }
97
125
  });
98
126
  </script>
99
127
 
100
-
101
128
  <style>
102
- .category-toggler {
103
- right: -1px;
104
- bottom: -1px;
129
+ /* View toggle styles */
130
+ .view-grid {
131
+ @apply grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4;
132
+ }
133
+
134
+ .view-list {
135
+ @apply flex flex-col gap-4;
105
136
  }
106
- </style>
137
+ </style>
@@ -0,0 +1,107 @@
1
+ ---
2
+ import { Icon } from 'astro-icon/components';
3
+
4
+ interface Props {
5
+ showText: string; // "Show:"
6
+ listText: string; // "List"
7
+ gridText: string; // "Grid"
8
+ listAriaLabel: string; // "List view"
9
+ gridAriaLabel: string; // "Grid view"
10
+ showViewToggler: boolean;
11
+ }
12
+
13
+ const {
14
+ showText,
15
+ listText,
16
+ gridText,
17
+ listAriaLabel,
18
+ gridAriaLabel,
19
+ showViewToggler
20
+ } = Astro.props;
21
+ ---
22
+
23
+ {
24
+ showViewToggler &&
25
+ <div class="flex items-center gap-2 ml-auto">
26
+ <span class="text-slate-default text-sm">{showText}</span>
27
+ <div class="flex border rounded">
28
+ <button
29
+ data-view="list"
30
+ class="view-toggle flex items-center gap-1 px-3 py-1.5 transition-colors"
31
+ aria-label={listAriaLabel}
32
+ >
33
+ <Icon name="ant-design:bars-outlined" class="w-4 h-4" />
34
+ <span class="text-sm">{listText}</span>
35
+ </button>
36
+ <button
37
+ data-view="grid"
38
+ class="view-toggle flex items-center gap-1 px-3 py-1.5 transition-colors"
39
+ aria-label={gridAriaLabel}
40
+ >
41
+ <Icon name="ant-design:appstore-outlined" class="w-4 h-4" />
42
+ <span class="text-sm">{gridText}</span>
43
+ </button>
44
+ </div>
45
+ </div>
46
+ }
47
+
48
+ <script define:vars={{ showViewToggler }}>
49
+
50
+ // Initialize view state
51
+ function initializeView() {
52
+ const savedView = localStorage.getItem('categoryView') || 'list';
53
+ const buttons = document.querySelectorAll('.view-toggle');
54
+ const productsContainer = document.querySelector('.products-container');
55
+
56
+ // Set initial active state
57
+ buttons.forEach(button => {
58
+ if (button instanceof HTMLElement) {
59
+ const isActive = button.dataset.view === savedView;
60
+ button.classList.toggle('bg-neutral-lightest', isActive);
61
+ }
62
+ });
63
+
64
+ // Set initial view on products container
65
+ if (productsContainer) {
66
+ productsContainer.classList.remove('view-grid', 'view-list');
67
+ productsContainer.classList.add(`view-${savedView}`);
68
+ }
69
+ }
70
+
71
+ // Handle view changes
72
+ function setupViewToggle() {
73
+ const buttons = document.querySelectorAll('.view-toggle');
74
+
75
+ buttons.forEach(button => {
76
+ button.addEventListener('click', (e) => {
77
+ const clickedButton = e.currentTarget;
78
+ if (!(clickedButton instanceof HTMLElement)) return;
79
+
80
+ const view = clickedButton.dataset.view;
81
+ if (!view) return;
82
+
83
+ // Update localStorage
84
+ localStorage.setItem('categoryView', view);
85
+
86
+ // Update button states
87
+ buttons.forEach(btn => btn.classList.remove('bg-neutral-lightest'));
88
+ clickedButton.classList.add('bg-neutral-lightest');
89
+
90
+ // Update products container
91
+ const productsContainer = document.querySelector('.products-container');
92
+ if (productsContainer) {
93
+ productsContainer.classList.remove('view-grid', 'view-list');
94
+ productsContainer.classList.add(`view-${view}`);
95
+ }
96
+ });
97
+ });
98
+ }
99
+
100
+ // Setup on page load
101
+ document.addEventListener('astro:page-load', () => {
102
+ if (showViewToggler) {
103
+ initializeView();
104
+ setupViewToggle();
105
+ }
106
+ });
107
+ </script>
@@ -6,7 +6,7 @@ import Search from "astro-pagefind/components/Search";
6
6
  ---
7
7
 
8
8
  <header
9
- class="p-3 bg-blue-600 bg-opacity-10 backdrop-blur-md border-b text-slate-900"
9
+ class="p-3 bg-blue-medium bg-opacity-10 backdrop-blur-md border-b text-slate-900"
10
10
  >
11
11
  <SkipToContent />
12
12
  <nav
@@ -8,7 +8,7 @@ import Button from "../components/Button.vue";
8
8
  @apply fixed top-0 left-0 right-0 bottom-0;
9
9
 
10
10
  &::backdrop {
11
- @apply bg-gray-500/50 fixed;
11
+ @apply bg-slate-medium/50 fixed;
12
12
  top: 0px;
13
13
  right: 0px;
14
14
  bottom: 0px;