spoko-design-system 0.5.3 → 0.5.5

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 (173) hide show
  1. package/.astro/settings.json +4 -4
  2. package/.github/dependabot.yml +11 -11
  3. package/.github/todo.yml +3 -3
  4. package/.github/workflows/deploy.yml +39 -39
  5. package/.stackblitzrc +5 -5
  6. package/.vscode/extensions.json +5 -5
  7. package/.vscode/launch.json +11 -11
  8. package/.vscode/settings.json +5 -5
  9. package/LICENSE +21 -21
  10. package/README.md +114 -114
  11. package/astro-i18next.config.mjs +17 -17
  12. package/astro-i18next.config.ts +10 -10
  13. package/astro.config.mjs +86 -86
  14. package/dev-dist/sw.js +91 -91
  15. package/dev-dist/workbox-c676b6d3.js +3391 -3391
  16. package/icon.config.ts +278 -278
  17. package/index.ts +65 -65
  18. package/package.json +8 -8
  19. package/public/fonts/lg.svg +53 -53
  20. package/public/fonts/vwhead-bold-demo.html +549 -549
  21. package/public/fonts/vwhead-regular-demo.html +549 -549
  22. package/public/fonts/vwtext-bold-demo.html +549 -549
  23. package/public/fonts/vwtext-regular-demo.html +549 -549
  24. package/public/github.svg +3 -3
  25. package/public/grid_dot.svg +4 -4
  26. package/public/linkedin.svg +44 -44
  27. package/public/locales/en/translation.json +8 -8
  28. package/public/locales/pl/translation.json +8 -8
  29. package/public/make-scrollable-code-focusable.js +3 -3
  30. package/public/pagefind.yml +3 -3
  31. package/public/polo.blue.svg +29 -29
  32. package/public/spoko.space.svg +71 -71
  33. package/public/twitter.svg +46 -46
  34. package/renovate.json +6 -6
  35. package/sandbox.config.json +11 -11
  36. package/src/MyComponent.astro +8 -8
  37. package/src/components/Badge.vue +19 -19
  38. package/src/components/Badges.vue +21 -21
  39. package/src/components/Breadcrumbs.vue +107 -107
  40. package/src/components/Button.vue +101 -87
  41. package/src/components/ButtonCopy.astro +183 -183
  42. package/src/components/ButtonCopy.vue +36 -36
  43. package/src/components/Card.astro +27 -27
  44. package/src/components/Carousel.astro +26 -26
  45. package/src/components/Category/CategoriesCarousel.astro +101 -101
  46. package/src/components/Category/CategoryDetails.astro +169 -169
  47. package/src/components/Category/CategorySidebarToggler.vue +9 -9
  48. package/src/components/Category/CategoryTile.astro +38 -38
  49. package/src/components/Category/CategoryViewToggler.astro +89 -89
  50. package/src/components/Category/SubCategoryLink.vue +19 -19
  51. package/src/components/Copyright.astro +12 -12
  52. package/src/components/Date.astro +7 -7
  53. package/src/components/Faq.astro +33 -33
  54. package/src/components/FaqItem.astro +80 -80
  55. package/src/components/FeaturesList.vue +41 -41
  56. package/src/components/FuckRussia.vue +62 -62
  57. package/src/components/HandDrive.astro +29 -29
  58. package/src/components/Header/Header.astro +210 -210
  59. package/src/components/Header/SkipToContent.astro +1 -1
  60. package/src/components/Headline.vue +48 -48
  61. package/src/components/Image.astro +30 -30
  62. package/src/components/Jumbotron/variants/Post.astro +2 -2
  63. package/src/components/Jumbotron/variants/PostSplit.astro +2 -2
  64. package/src/components/LeftSidebar.astro +53 -53
  65. package/src/components/MainColors.vue +22 -22
  66. package/src/components/MainInput.vue +15 -15
  67. package/src/components/Modal.astro +27 -27
  68. package/src/components/PageContent.astro +5 -5
  69. package/src/components/PartNumber.vue +27 -27
  70. package/src/components/Post/PostCategories.astro +38 -0
  71. package/src/components/Post/PostCategories.vue +39 -0
  72. package/src/components/PostHeader.astro +103 -103
  73. package/src/components/PrCode.vue +141 -141
  74. package/src/components/Product/ProductButton.vue +18 -18
  75. package/src/components/Product/ProductCarousel.astro +35 -35
  76. package/src/components/Product/ProductCodes.vue +174 -174
  77. package/src/components/Product/ProductEngineType.vue +42 -42
  78. package/src/components/Product/ProductImage.astro +40 -40
  79. package/src/components/Product/ProductLink.astro +101 -101
  80. package/src/components/Product/ProductLink.vue +59 -59
  81. package/src/components/Product/ProductLinkInfo.astro +37 -37
  82. package/src/components/Product/ProductNumber.astro +60 -60
  83. package/src/components/ProductCarousel.astro +38 -38
  84. package/src/components/ProductCodes.vue +39 -39
  85. package/src/components/ProductDetailName.vue +52 -52
  86. package/src/components/ProductDetailsList.vue +65 -65
  87. package/src/components/ProductTile.astro +48 -48
  88. package/src/components/Quote.vue +23 -23
  89. package/src/components/ReloadPrompt.astro +50 -50
  90. package/src/components/SlimBanner.vue +72 -72
  91. package/src/components/Table.vue +32 -32
  92. package/src/components/TableOfContents.astro +15 -15
  93. package/src/components/Translations.vue +23 -23
  94. package/src/components/flags/FlagPL.vue +3 -3
  95. package/src/components/flags/FlagUA.vue +2 -2
  96. package/src/components/layout/Container.astro +7 -7
  97. package/src/components/layout/Header.astro +80 -80
  98. package/src/config.ts +56 -56
  99. package/src/design.config.ts +98 -98
  100. package/src/env.d.ts +6 -6
  101. package/src/layouts/Layout.astro +61 -61
  102. package/src/layouts/MainLayout.astro +81 -81
  103. package/src/layouts/partials/FooterCommon.astro +4 -4
  104. package/src/layouts/partials/HeadCommon.astro +44 -44
  105. package/src/layouts/partials/HeadSEO.astro +41 -41
  106. package/src/pages/components/badges.mdx +57 -57
  107. package/src/pages/components/breadcrumbs.mdx +139 -139
  108. package/src/pages/components/buttons.mdx +360 -360
  109. package/src/pages/components/card.mdx +294 -294
  110. package/src/pages/components/carousel.mdx +62 -62
  111. package/src/pages/components/copyright.mdx +42 -42
  112. package/src/pages/components/details-list.mdx +115 -115
  113. package/src/pages/components/features-list.mdx +37 -37
  114. package/src/pages/components/flags.mdx +49 -49
  115. package/src/pages/components/fuck-russia.mdx +39 -39
  116. package/src/pages/components/hand-drive.mdx +38 -38
  117. package/src/pages/components/headline.mdx +152 -152
  118. package/src/pages/components/icons.astro +135 -135
  119. package/src/pages/components/image.mdx +513 -513
  120. package/src/pages/components/input.mdx +47 -47
  121. package/src/pages/components/jumbotron.mdx +359 -359
  122. package/src/pages/components/modal.mdx +64 -64
  123. package/src/pages/components/post-header.mdx +60 -60
  124. package/src/pages/components/pr-code.mdx +65 -65
  125. package/src/pages/components/product-number.mdx +58 -58
  126. package/src/pages/components/product-tile.mdx +51 -51
  127. package/src/pages/components/quote.mdx +33 -33
  128. package/src/pages/components/slimbanner.mdx +35 -35
  129. package/src/pages/components/table.mdx +108 -108
  130. package/src/pages/core/colors.mdx +10 -10
  131. package/src/pages/core/grid.mdx +89 -89
  132. package/src/pages/core/introduction.mdx +77 -77
  133. package/src/pages/core/shadows.astro +20 -20
  134. package/src/pages/core/typography.astro +49 -49
  135. package/src/pages/index.astro +130 -130
  136. package/src/pages/patterns/introduction.mdx +60 -60
  137. package/src/pwa.ts +12 -12
  138. package/src/styles/_variables.scss +70 -70
  139. package/src/styles/base/base.css +184 -184
  140. package/src/styles/base/grid.css +92 -92
  141. package/src/styles/base/typography.css +70 -70
  142. package/src/styles/content.css +73 -73
  143. package/src/styles/main.css +7 -7
  144. package/src/types/Product.ts +31 -31
  145. package/src/types/astro.d.ts +3 -3
  146. package/src/utils/product/getPriceFormatted.ts +15 -15
  147. package/src/utils/product/getProductChecklist.ts +17 -17
  148. package/src/utils/product/useFormatProductNumber.ts +41 -41
  149. package/src/utils/seo/getShorterDescription.ts +14 -14
  150. package/src/utils/text/formatDate.ts +5 -5
  151. package/src/utils/text/formatLocaleNumber.ts +6 -6
  152. package/src/utils/text/formatPad.ts +12 -12
  153. package/src/utils/text/getNumberFormatted.ts +33 -33
  154. package/src/utils/text/getTranslatedLink.ts +5 -5
  155. package/src/utils/text.ts +19 -19
  156. package/tailwind.config.cjs +8 -8
  157. package/tsconfig.json +28 -28
  158. package/uno-config/index.ts +61 -61
  159. package/uno-config/theme/breakpoints.ts +9 -9
  160. package/uno-config/theme/colors.ts +64 -64
  161. package/uno-config/theme/dimensions.ts +17 -17
  162. package/uno-config/theme/effects.ts +14 -14
  163. package/uno-config/theme/grid.ts +10 -10
  164. package/uno-config/theme/index.ts +28 -28
  165. package/uno-config/theme/shortcuts/buttons.ts +53 -53
  166. package/uno-config/theme/shortcuts/components.ts +92 -92
  167. package/uno-config/theme/shortcuts/index.ts +18 -18
  168. package/uno-config/theme/shortcuts/jumbotron.ts +1 -1
  169. package/uno-config/theme/shortcuts/layout.ts +64 -64
  170. package/uno-config/theme/typography.ts +29 -29
  171. package/uno.config.ts +2 -2
  172. package/src/components/Category/CategoryLink.vue +0 -23
  173. package/src/components/CategoryLink.astro +0 -18
@@ -1,101 +1,101 @@
1
- ---
2
- const { activeCategorySlug, locale, class: className } = Astro.props;
3
-
4
- import { getTranslatedLink } from "@utils/text/getTranslatedLink"
5
- import { getMainCategoryList } from "@utils/category/getMainCategoryList"
6
- import { Image } from 'astro:assets'
7
-
8
- import i18next, { t } from "i18next";
9
- const categories = await getMainCategoryList()
10
- const imgDomain = 'https://api.polo.blue/img/';
11
-
12
- const activeIndex = activeCategorySlug && categories ? categories.map(a => a.slug).findIndex(e => e === activeCategorySlug) : 0
13
- ---
14
- <!-- <div class={`cat-menu ${className ? className : ''}`}
15
- data-pagefind-ignore
16
- itemscope itemtype="https://schema.org/SiteNavigationElement"
17
- transition:persist={`catcarousel${activeIndex}`}
18
- transition:animate="none"
19
- > -->
20
- <swiper-container
21
- class={`categories-carousel flex pb-1 sm:pb-0 bg-white cat-menu ${className ? className : ''}`}
22
- data-pagefind-ignore
23
- itemscope itemtype="https://schema.org/SiteNavigationElement"
24
- transition:persist={`catcarousel${activeIndex}`}
25
- transition:animate="none"
26
- data-active={activeIndex}
27
- initial-slide={activeIndex}
28
- space-between="0"
29
- slides-per-view="auto"
30
- scrollbar="true"
31
- draggable="true"
32
- keyboard
33
- free-mode
34
- data-off-observer
35
- run-callbacks-on-init="false"
36
- >
37
- {
38
- categories.map((category, index) => (
39
- <swiper-slide itemprop="hasPart" role="presentation"
40
- class={`swiper-slide cats-slide group ${category.slug === activeCategorySlug ? 'active': ''}`}
41
- >
42
- <a href={getTranslatedLink(`/${category.slug}/`)}
43
- class="carousel-item"
44
- >
45
- {
46
- // itemprop="url"
47
- // role="menuitem"
48
- // aria-label={ t(`cat.${category.slug}.name`) }
49
- }
50
-
51
- <Image
52
- src={`${imgDomain}${category.photo}`}
53
- alt={t(`cat.${category.slug}.desc`).split('. ', 1)[0]}
54
- height="70"
55
- width="70"
56
- format="avif"
57
- loading="eager"
58
- onerror="this.style.display='none';"
59
- class="cats-img"
60
- />
61
- <div class="swiper-lazy-preloader"></div>
62
-
63
- <div class="cat-name"
64
- // itemprop="name"
65
- >
66
- { t(`cat.${category.slug}.name`) }
67
- </div>
68
- </a>
69
- </swiper-slide>
70
- ))
71
- }
72
-
73
- </swiper-container>
74
- <!-- </div> -->
75
-
76
- <style >
77
- .active {
78
- @apply bg-blue-darker text-white bg-opacity-100;
79
-
80
- &:not(:hover) .cats-img {
81
- filter: invert(100%);
82
- /* // @apply filter-invert; */
83
- }
84
-
85
- }
86
-
87
- .categories-carousel {
88
- @apply overflow-hidden;
89
-
90
- &.swiper-initialized {
91
- .img-preloader {
92
- display: none;
93
- }
94
- }
95
- }
96
-
97
- .swiper-slide {
98
- @apply transition w-[calc(100%/3.55)] min-w-[calc(100%/3.55)] sm:w-35 sm:min-w-35 3xl:min-w-[calc(100%/12.5-4px)];
99
- }
100
-
101
- </style>
1
+ ---
2
+ const { activeCategorySlug, locale, class: className } = Astro.props;
3
+
4
+ import { getTranslatedLink } from "@utils/text/getTranslatedLink"
5
+ import { getMainCategoryList } from "@utils/category/getMainCategoryList"
6
+ import { Image } from 'astro:assets'
7
+
8
+ import i18next, { t } from "i18next";
9
+ const categories = await getMainCategoryList()
10
+ const imgDomain = 'https://api.polo.blue/img/';
11
+
12
+ const activeIndex = activeCategorySlug && categories ? categories.map(a => a.slug).findIndex(e => e === activeCategorySlug) : 0
13
+ ---
14
+ <!-- <div class={`cat-menu ${className ? className : ''}`}
15
+ data-pagefind-ignore
16
+ itemscope itemtype="https://schema.org/SiteNavigationElement"
17
+ transition:persist={`catcarousel${activeIndex}`}
18
+ transition:animate="none"
19
+ > -->
20
+ <swiper-container
21
+ class={`categories-carousel flex pb-1 sm:pb-0 bg-white cat-menu ${className ? className : ''}`}
22
+ data-pagefind-ignore
23
+ itemscope itemtype="https://schema.org/SiteNavigationElement"
24
+ transition:persist={`catcarousel${activeIndex}`}
25
+ transition:animate="none"
26
+ data-active={activeIndex}
27
+ initial-slide={activeIndex}
28
+ space-between="0"
29
+ slides-per-view="auto"
30
+ scrollbar="true"
31
+ draggable="true"
32
+ keyboard
33
+ free-mode
34
+ data-off-observer
35
+ run-callbacks-on-init="false"
36
+ >
37
+ {
38
+ categories.map((category, index) => (
39
+ <swiper-slide itemprop="hasPart" role="presentation"
40
+ class={`swiper-slide cats-slide group ${category.slug === activeCategorySlug ? 'active': ''}`}
41
+ >
42
+ <a href={getTranslatedLink(`/${category.slug}/`)}
43
+ class="carousel-item"
44
+ >
45
+ {
46
+ // itemprop="url"
47
+ // role="menuitem"
48
+ // aria-label={ t(`cat.${category.slug}.name`) }
49
+ }
50
+
51
+ <Image
52
+ src={`${imgDomain}${category.photo}`}
53
+ alt={t(`cat.${category.slug}.desc`).split('. ', 1)[0]}
54
+ height="70"
55
+ width="70"
56
+ format="avif"
57
+ loading="eager"
58
+ onerror="this.style.display='none';"
59
+ class="cats-img"
60
+ />
61
+ <div class="swiper-lazy-preloader"></div>
62
+
63
+ <div class="cat-name"
64
+ // itemprop="name"
65
+ >
66
+ { t(`cat.${category.slug}.name`) }
67
+ </div>
68
+ </a>
69
+ </swiper-slide>
70
+ ))
71
+ }
72
+
73
+ </swiper-container>
74
+ <!-- </div> -->
75
+
76
+ <style >
77
+ .active {
78
+ @apply bg-blue-darker text-white bg-opacity-100;
79
+
80
+ &:not(:hover) .cats-img {
81
+ filter: invert(100%);
82
+ /* // @apply filter-invert; */
83
+ }
84
+
85
+ }
86
+
87
+ .categories-carousel {
88
+ @apply overflow-hidden;
89
+
90
+ &.swiper-initialized {
91
+ .img-preloader {
92
+ display: none;
93
+ }
94
+ }
95
+ }
96
+
97
+ .swiper-slide {
98
+ @apply transition w-[calc(100%/3.55)] min-w-[calc(100%/3.55)] sm:w-35 sm:min-w-35 3xl:min-w-[calc(100%/12.5-4px)];
99
+ }
100
+
101
+ </style>
@@ -1,170 +1,170 @@
1
- ---
2
- import CategorySidebarToggler from './CategorySidebarToggler.vue';
3
- import CategoryViewToggler from './CategoryViewToggler.astro';
4
- import { Icon } from 'astro-icon/components';
5
- import { t } from "i18next";
6
-
7
- const {
8
- category,
9
- subcategory,
10
- subtitle,
11
- subsubtitle,
12
- titleSmall,
13
- locale,
14
- showViewToggler,
15
- viewerLabels
16
- } = Astro.props;
17
-
18
- const baseURL = locale === 'en' ? '' : `/${locale}`;
19
- ---
20
-
21
- <div
22
- 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"
23
- transition:name="category-details"
24
- transition:animate="fade"
25
- >
26
- <CategorySidebarToggler class="category-sidebar-toggler w-12 md:w-8" data-state="desktop">
27
- <div class="desktop-icons hidden md:block">
28
- <!-- Desktop icons container -->
29
- <Icon
30
- name="ant-design:menu-fold-outlined"
31
- class="toggler-btn w-6 expanded-icon"
32
- aria-hidden="true"
33
- />
34
- <Icon
35
- name="ant-design:menu-unfold-outlined"
36
- class="toggler-btn w-6 collapsed-icon hidden"
37
- aria-hidden="true"
38
- />
39
- </div>
40
- <!-- Mobile icon in separate container -->
41
- <div class="mobile-icon block md:hidden">
42
- <Icon
43
- name="ant-design:menu-outlined"
44
- class="toggler-btn w-6"
45
- aria-hidden="true"
46
- />
47
- </div>
48
- </CategorySidebarToggler>
49
-
50
-
51
- <div class="overflow-x-auto overflow-y-hidden flex max-w-full items-center">
52
- {subtitle ? (
53
- <>
54
- <a class="text-lg font-vw-headregular whitespace-nowrap block" href={`${baseURL}/${category.slug}/`}>
55
- {category.name}
56
- {titleSmall && <small>{titleSmall}</small>}
57
- </a>
58
- <span class="text-neutral-lighter text-lg inline-block px-1 font-headlight">/</span>
59
- {!subsubtitle ? (
60
- <h1 class="text-lg py-2.5 sm:py-0 whitespace-nowrap underline underline-offset-6 decoration-blue-300 decoration-0.5">
61
- {subtitle} <span class="sr-only"> {t('catalog.extra-short')}</span>
62
- </h1>
63
- ) : (
64
- <>
65
- <div class="text-lg py-2.5 sm:py-0 whitespace-nowrap">
66
- <a href={`${baseURL}/${category.slug}/${subcategory.slug}/`}>
67
- {subtitle}
68
- </a>
69
- </div>
70
- <span class="text-neutral-lighter text-lg inline-block px-1 font-headlight">/</span>
71
- <h1 class="text-lg py-2.5 sm:py-0 whitespace-nowrap underline underline-offset-6 decoration-blue-300 decoration-0.5">
72
- {subsubtitle} <span class="sr-only"> {t('catalog.extra-short')}</span>
73
- </h1>
74
- </>
75
- )}
76
- </>
77
- ) : (
78
- <h1 class="text-lg py-2.5 sm:py-0 whitespace-nowrap">
79
- {category.name}
80
- {titleSmall && <small>{titleSmall}</small>}
81
- <span class="sr-only"> {t('catalog.extra-short')}</span>
82
- </h1>
83
- )}
84
- </div>
85
-
86
- {showViewToggler && (
87
- <CategoryViewToggler
88
- {...viewerLabels}
89
- class="hidden lg:flex items-center gap-2 ml-auto"
90
- />
91
- )}
92
- </div>
93
-
94
- <script>
95
- function initializeSidebar() {
96
- const sidebar = document.getElementById('sidebar');
97
- const savedState = localStorage.getItem('sidebarState') || 'open';
98
-
99
- if (sidebar) {
100
- sidebar.classList.toggle('collapsed', savedState === 'closed');
101
- updateTogglers(savedState === 'closed');
102
- }
103
- }
104
-
105
- function updateTogglers(isCollapsed) {
106
- document.querySelectorAll('.category-sidebar-toggler').forEach(toggler => {
107
- const expandedIcon = toggler.querySelector('.expanded-icon');
108
- const collapsedIcon = toggler.querySelector('.collapsed-icon');
109
-
110
- if (expandedIcon && collapsedIcon) {
111
- expandedIcon.classList.toggle('hidden', isCollapsed);
112
- collapsedIcon.classList.toggle('hidden', !isCollapsed);
113
- }
114
- });
115
- }
116
-
117
- function toggleSidebar() {
118
- const sidebar = document.getElementById('sidebar');
119
- const isMobile = window.matchMedia("(max-width: 768px)").matches;
120
-
121
- if (sidebar) {
122
- if (isMobile) {
123
- const isShown = sidebar.classList.toggle('show');
124
- document.body.classList.toggle('overflow-hidden', isShown);
125
- } else {
126
- const isCollapsed = sidebar.classList.toggle('collapsed');
127
- document.body.classList.remove('overflow-hidden');
128
- localStorage.setItem('sidebarState', isCollapsed ? 'closed' : 'open');
129
- updateTogglers(isCollapsed);
130
- }
131
- }
132
- }
133
-
134
- function setupTogglers() {
135
- document.querySelectorAll('.category-sidebar-toggler').forEach(toggler => {
136
- toggler.removeEventListener('click', toggleSidebar);
137
- toggler.addEventListener('click', toggleSidebar);
138
- });
139
- }
140
-
141
- // Initialize on page load
142
- document.addEventListener('astro:page-load', () => {
143
- initializeSidebar();
144
- setupTogglers();
145
- });
146
-
147
- // Preserve state during view transitions
148
- document.addEventListener('astro:before-swap', () => {
149
- const sidebarState = localStorage.getItem('sidebarState');
150
- if (sidebarState) {
151
- sessionStorage.setItem('tempSidebarState', sidebarState);
152
- }
153
- });
154
-
155
- document.addEventListener('astro:after-swap', () => {
156
- const tempState = sessionStorage.getItem('tempSidebarState');
157
- if (tempState) {
158
- localStorage.setItem('sidebarState', tempState);
159
- sessionStorage.removeItem('tempSidebarState');
160
- initializeSidebar();
161
- }
162
- });
163
- </script>
164
-
165
-
166
- <style>
167
- .toggler-btn {
168
- @apply md:-mt-0.5;
169
- }
1
+ ---
2
+ import CategorySidebarToggler from './CategorySidebarToggler.vue';
3
+ import CategoryViewToggler from './CategoryViewToggler.astro';
4
+ import { Icon } from 'astro-icon/components';
5
+ import { t } from "i18next";
6
+
7
+ const {
8
+ category,
9
+ subcategory,
10
+ subtitle,
11
+ subsubtitle,
12
+ titleSmall,
13
+ locale,
14
+ showViewToggler,
15
+ viewerLabels
16
+ } = Astro.props;
17
+
18
+ const baseURL = locale === 'en' ? '' : `/${locale}`;
19
+ ---
20
+
21
+ <div
22
+ 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"
23
+ transition:name="category-details"
24
+ transition:animate="fade"
25
+ >
26
+ <CategorySidebarToggler class="category-sidebar-toggler w-12 md:w-8" data-state="desktop">
27
+ <div class="desktop-icons hidden md:block">
28
+ <!-- Desktop icons container -->
29
+ <Icon
30
+ name="ant-design:menu-fold-outlined"
31
+ class="toggler-btn w-6 expanded-icon"
32
+ aria-hidden="true"
33
+ />
34
+ <Icon
35
+ name="ant-design:menu-unfold-outlined"
36
+ class="toggler-btn w-6 collapsed-icon hidden"
37
+ aria-hidden="true"
38
+ />
39
+ </div>
40
+ <!-- Mobile icon in separate container -->
41
+ <div class="mobile-icon block md:hidden">
42
+ <Icon
43
+ name="ant-design:menu-outlined"
44
+ class="toggler-btn w-6"
45
+ aria-hidden="true"
46
+ />
47
+ </div>
48
+ </CategorySidebarToggler>
49
+
50
+
51
+ <div class="overflow-x-auto overflow-y-hidden flex max-w-full items-center">
52
+ {subtitle ? (
53
+ <>
54
+ <a class="text-lg font-vw-headregular whitespace-nowrap block" href={`${baseURL}/${category.slug}/`}>
55
+ {category.name}
56
+ {titleSmall && <small>{titleSmall}</small>}
57
+ </a>
58
+ <span class="text-neutral-lighter text-lg inline-block px-1 font-headlight">/</span>
59
+ {!subsubtitle ? (
60
+ <h1 class="text-lg py-2.5 sm:py-0 whitespace-nowrap underline underline-offset-6 decoration-blue-300 decoration-0.5">
61
+ {subtitle} <span class="sr-only"> {t('catalog.extra-short')}</span>
62
+ </h1>
63
+ ) : (
64
+ <>
65
+ <div class="text-lg py-2.5 sm:py-0 whitespace-nowrap">
66
+ <a href={`${baseURL}/${category.slug}/${subcategory.slug}/`}>
67
+ {subtitle}
68
+ </a>
69
+ </div>
70
+ <span class="text-neutral-lighter text-lg inline-block px-1 font-headlight">/</span>
71
+ <h1 class="text-lg py-2.5 sm:py-0 whitespace-nowrap underline underline-offset-6 decoration-blue-300 decoration-0.5">
72
+ {subsubtitle} <span class="sr-only"> {t('catalog.extra-short')}</span>
73
+ </h1>
74
+ </>
75
+ )}
76
+ </>
77
+ ) : (
78
+ <h1 class="text-lg py-2.5 sm:py-0 whitespace-nowrap">
79
+ {category.name}
80
+ {titleSmall && <small>{titleSmall}</small>}
81
+ <span class="sr-only"> {t('catalog.extra-short')}</span>
82
+ </h1>
83
+ )}
84
+ </div>
85
+
86
+ {showViewToggler && (
87
+ <CategoryViewToggler
88
+ {...viewerLabels}
89
+ class="hidden lg:flex items-center gap-2 ml-auto"
90
+ />
91
+ )}
92
+ </div>
93
+
94
+ <script>
95
+ function initializeSidebar() {
96
+ const sidebar = document.getElementById('sidebar');
97
+ const savedState = localStorage.getItem('sidebarState') || 'open';
98
+
99
+ if (sidebar) {
100
+ sidebar.classList.toggle('collapsed', savedState === 'closed');
101
+ updateTogglers(savedState === 'closed');
102
+ }
103
+ }
104
+
105
+ function updateTogglers(isCollapsed) {
106
+ document.querySelectorAll('.category-sidebar-toggler').forEach(toggler => {
107
+ const expandedIcon = toggler.querySelector('.expanded-icon');
108
+ const collapsedIcon = toggler.querySelector('.collapsed-icon');
109
+
110
+ if (expandedIcon && collapsedIcon) {
111
+ expandedIcon.classList.toggle('hidden', isCollapsed);
112
+ collapsedIcon.classList.toggle('hidden', !isCollapsed);
113
+ }
114
+ });
115
+ }
116
+
117
+ function toggleSidebar() {
118
+ const sidebar = document.getElementById('sidebar');
119
+ const isMobile = window.matchMedia("(max-width: 768px)").matches;
120
+
121
+ if (sidebar) {
122
+ if (isMobile) {
123
+ const isShown = sidebar.classList.toggle('show');
124
+ document.body.classList.toggle('overflow-hidden', isShown);
125
+ } else {
126
+ const isCollapsed = sidebar.classList.toggle('collapsed');
127
+ document.body.classList.remove('overflow-hidden');
128
+ localStorage.setItem('sidebarState', isCollapsed ? 'closed' : 'open');
129
+ updateTogglers(isCollapsed);
130
+ }
131
+ }
132
+ }
133
+
134
+ function setupTogglers() {
135
+ document.querySelectorAll('.category-sidebar-toggler').forEach(toggler => {
136
+ toggler.removeEventListener('click', toggleSidebar);
137
+ toggler.addEventListener('click', toggleSidebar);
138
+ });
139
+ }
140
+
141
+ // Initialize on page load
142
+ document.addEventListener('astro:page-load', () => {
143
+ initializeSidebar();
144
+ setupTogglers();
145
+ });
146
+
147
+ // Preserve state during view transitions
148
+ document.addEventListener('astro:before-swap', () => {
149
+ const sidebarState = localStorage.getItem('sidebarState');
150
+ if (sidebarState) {
151
+ sessionStorage.setItem('tempSidebarState', sidebarState);
152
+ }
153
+ });
154
+
155
+ document.addEventListener('astro:after-swap', () => {
156
+ const tempState = sessionStorage.getItem('tempSidebarState');
157
+ if (tempState) {
158
+ localStorage.setItem('sidebarState', tempState);
159
+ sessionStorage.removeItem('tempSidebarState');
160
+ initializeSidebar();
161
+ }
162
+ });
163
+ </script>
164
+
165
+
166
+ <style>
167
+ .toggler-btn {
168
+ @apply md:-mt-0.5;
169
+ }
170
170
  </style>
@@ -1,10 +1,10 @@
1
-
2
- <template>
3
- <button
4
- class="category-toggler md:w-8"
5
- type="button"
6
- aria-label="toggle menu"
7
- >
8
- <slot />
9
- </button>
1
+
2
+ <template>
3
+ <button
4
+ class="category-toggler md:w-8"
5
+ type="button"
6
+ aria-label="toggle menu"
7
+ >
8
+ <slot />
9
+ </button>
10
10
  </template>
@@ -1,39 +1,39 @@
1
- ---
2
- import { Image } from "astro:assets";
3
-
4
- interface Props {
5
- CategoryObject: {
6
- photo: string;
7
- desc: string;
8
- alt: string;
9
- name: string;
10
- slug: string;
11
- height?: number;
12
- width?: number;
13
- class?: string;
14
- };
15
- locale?: string;
16
- }
17
-
18
- const { CategoryObject, locale = 'en' } = Astro.props;
19
- const { height = 70, width = 70 } = CategoryObject;
20
- ---
21
-
22
- <a
23
- href={`/${CategoryObject.slug}/`}
24
- class="carousel-item"
25
- data-astro-prefetch
26
- >
27
- <Image
28
- src={CategoryObject.photo}
29
- alt={CategoryObject.alt}
30
- {height}
31
- {width}
32
- format="avif"
33
- loading="eager"
34
- onerror="this.style.display='none';"
35
- class="cats-img"
36
- />
37
- <div class="swiper-lazy-preloader" />
38
- <div class="cat-name" itemprop="name">{CategoryObject.name}</div>
1
+ ---
2
+ import { Image } from "astro:assets";
3
+
4
+ interface Props {
5
+ CategoryObject: {
6
+ photo: string;
7
+ desc: string;
8
+ alt: string;
9
+ name: string;
10
+ slug: string;
11
+ height?: number;
12
+ width?: number;
13
+ class?: string;
14
+ };
15
+ locale?: string;
16
+ }
17
+
18
+ const { CategoryObject, locale = 'en' } = Astro.props;
19
+ const { height = 70, width = 70 } = CategoryObject;
20
+ ---
21
+
22
+ <a
23
+ href={`/${CategoryObject.slug}/`}
24
+ class="carousel-item"
25
+ data-astro-prefetch
26
+ >
27
+ <Image
28
+ src={CategoryObject.photo}
29
+ alt={CategoryObject.alt}
30
+ {height}
31
+ {width}
32
+ format="avif"
33
+ loading="eager"
34
+ onerror="this.style.display='none';"
35
+ class="cats-img"
36
+ />
37
+ <div class="swiper-lazy-preloader" />
38
+ <div class="cat-name" itemprop="name">{CategoryObject.name}</div>
39
39
  </a>