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.
- package/.claude/settings.json +1 -1
- package/.husky/pre-commit +17 -1
- package/.prettierrc +8 -4
- package/CHANGELOG.md +35 -0
- package/index.ts +8 -2
- package/package.json +4 -3
- package/src/components/Badge.vue +1 -4
- package/src/components/Badges.vue +1 -4
- package/src/components/Breadcrumbs.vue +10 -44
- package/src/components/Button.vue +1 -5
- package/src/components/ButtonCopy.astro +2 -7
- package/src/components/ButtonCopy.vue +2 -9
- package/src/components/Card.astro +1 -4
- package/src/components/Category/CategoriesCarousel.astro +3 -11
- package/src/components/Category/CategoryDetails.astro +7 -32
- package/src/components/Category/CategoryLink.vue +1 -5
- package/src/components/Category/CategorySidebarToggler.vue +1 -5
- package/src/components/Category/CategoryTile.astro +2 -9
- package/src/components/Category/CategoryViewToggler.astro +3 -16
- package/src/components/Copyright.astro +1 -4
- package/src/components/Date.astro +1 -4
- package/src/components/Faq.astro +1 -5
- package/src/components/FaqItem.astro +3 -14
- package/src/components/FeaturesList.vue +2 -9
- package/src/components/FuckRussia.vue +9 -36
- package/src/components/HandDrive.astro +2 -12
- package/src/components/Header/Header.astro +3 -14
- package/src/components/Header/SkipToContent.astro +1 -5
- package/src/components/Input.vue +19 -31
- package/src/components/Jumbotron/index.astro +7 -41
- package/src/components/Jumbotron/variants/Default.astro +2 -17
- package/src/components/Jumbotron/variants/Hero.astro +3 -17
- package/src/components/Jumbotron/variants/Post.astro +3 -13
- package/src/components/Jumbotron/variants/PostSplit.astro +3 -13
- package/src/components/Jumbotron.astro +3 -12
- package/src/components/LanguageSuggestion.astro +3 -14
- package/src/components/MainColors.vue +7 -25
- package/src/components/MainInput.vue +2 -1
- package/src/components/Modal.astro +43 -41
- package/src/components/PageContent.astro +1 -4
- package/src/components/PartNumber.vue +1 -4
- package/src/components/PostHeader.astro +3 -13
- package/src/components/PrCode.vue +2 -2
- package/src/components/Product/ProductButton.vue +1 -4
- package/src/components/Product/ProductDetailName.vue +1 -4
- package/src/components/Product/ProductDetails.vue +19 -65
- package/src/components/Product/ProductDoc.vue +1 -4
- package/src/components/Product/ProductEngine.astro +67 -0
- package/src/components/Product/ProductEngineType.vue +1 -4
- package/src/components/Product/ProductEngines.astro +43 -0
- package/src/components/Product/ProductLink.astro +8 -32
- package/src/components/Product/ProductLink.vue +8 -36
- package/src/components/Product/ProductLinkInfo.astro +4 -19
- package/src/components/Product/ProductModel.vue +3 -5
- package/src/components/Product/ProductModels.vue +2 -10
- package/src/components/Product/ProductNumber.astro +6 -26
- package/src/components/Product/ProductPositions.vue +1 -5
- package/src/components/ProductCodes.vue +6 -14
- package/src/components/ProductDetailName.vue +2 -7
- package/src/components/ProductDetailsList.vue +7 -33
- package/src/components/ProductTile.astro +3 -13
- package/src/components/ReloadPrompt.astro +1 -5
- package/src/components/SlimBanner.vue +10 -15
- package/src/components/Table.vue +3 -15
- package/src/components/Translations.vue +1 -4
- package/src/components/layout/CallToAction.astro +2 -7
- package/src/components/layout/Container.astro +1 -3
- package/src/components/layout/Header.astro +2 -12
- package/src/layouts/Layout.astro +2 -9
- package/src/layouts/MainLayout.astro +4 -17
- package/src/layouts/partials/HeadCommon.astro +7 -24
- package/src/layouts/partials/HeadSEO.astro +12 -48
- package/src/pages/components/icons.astro +1 -4
- package/src/pages/components/product-engine.mdx +75 -31
- package/src/pages/core/typography.astro +2 -6
- package/src/pages/index.astro +16 -63
- package/src/scripts/tooltips.ts +33 -28
- package/src/styles/main.css +4 -0
- package/src/styles/tippy-theme.css +4 -2
- package/src/utils/product/getEngineTooltipContent.ts +158 -0
- package/src/utils/product/getPriceFormatted.ts +2 -6
- package/src/utils/product/useFormatProductNumber.ts +1 -4
- package/src/utils/seo/getShorterDescription.ts +1 -4
- package/uno-config/index.ts +1 -1
- package/src/components/Product/ProductEngine.vue +0 -240
- package/src/components/Product/ProductEngines.vue +0 -116
|
@@ -10,11 +10,9 @@ const props = defineProps({
|
|
|
10
10
|
});
|
|
11
11
|
</script>
|
|
12
12
|
<template>
|
|
13
|
-
<strong
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
>{{ props.carModel.name }}</strong
|
|
17
|
-
>
|
|
13
|
+
<strong class="product-model" :data-pagefind-filter="`model:${props.carModel.name}`">
|
|
14
|
+
{{ props.carModel.name }}
|
|
15
|
+
</strong>
|
|
18
16
|
</template>
|
|
19
17
|
<style>
|
|
20
18
|
.product-model:not(:last-child) {
|
|
@@ -11,16 +11,8 @@ const props = defineProps({
|
|
|
11
11
|
</script>
|
|
12
12
|
|
|
13
13
|
<template>
|
|
14
|
-
<div
|
|
15
|
-
|
|
16
|
-
flex-wrap
|
|
17
|
-
max-w-max
|
|
18
|
-
>
|
|
19
|
-
<span
|
|
20
|
-
v-for="(modelId, index) in props.modelIds"
|
|
21
|
-
:key="index"
|
|
22
|
-
class="product-model block"
|
|
23
|
-
>
|
|
14
|
+
<div inline-flex flex-wrap max-w-max>
|
|
15
|
+
<span v-for="(modelId, index) in props.modelIds" :key="index" class="product-model block">
|
|
24
16
|
<ProductModel :id="modelId" />
|
|
25
17
|
</span>
|
|
26
18
|
</div>
|
|
@@ -15,9 +15,7 @@ const {
|
|
|
15
15
|
const { formattedNumbers: formatted } = useFormatProductNumber(productNumber);
|
|
16
16
|
|
|
17
17
|
// Define classes dynamically
|
|
18
|
-
const classNames = ['product-number', big ? 'text-4.5' : 'number-big', customClass]
|
|
19
|
-
.filter(Boolean)
|
|
20
|
-
.join(' ');
|
|
18
|
+
const classNames = ['product-number', big ? 'text-4.5' : 'number-big', customClass].filter(Boolean).join(' ');
|
|
21
19
|
|
|
22
20
|
const trackingClass = small ? 'tracking-wide' : 'tracking-tight';
|
|
23
21
|
|
|
@@ -29,37 +27,19 @@ const FormattedWrapper = isPdp ? 'h3' : 'div';
|
|
|
29
27
|
{
|
|
30
28
|
productNumber && formatted && (
|
|
31
29
|
<div class={classNames}>
|
|
32
|
-
<div
|
|
33
|
-
|
|
34
|
-
itemprop="identifier"
|
|
35
|
-
>
|
|
36
|
-
<ProductWrapper
|
|
37
|
-
id={productNumber}
|
|
38
|
-
class="product-code"
|
|
39
|
-
>
|
|
30
|
+
<div class={['p-number', small ? 'w-full' : ''].join(' ')} itemprop="identifier">
|
|
31
|
+
<ProductWrapper id={productNumber} class="product-code">
|
|
40
32
|
{productNumber}
|
|
41
33
|
</ProductWrapper>
|
|
42
34
|
|
|
43
|
-
{big &&
|
|
44
|
-
<ButtonCopy
|
|
45
|
-
productNumber={productNumber}
|
|
46
|
-
texts={buttonTexts}
|
|
47
|
-
tooltipClasses=""
|
|
48
|
-
/>
|
|
49
|
-
)}
|
|
35
|
+
{big && <ButtonCopy productNumber={productNumber} texts={buttonTexts} tooltipClasses="" />}
|
|
50
36
|
</div>
|
|
51
37
|
|
|
52
38
|
<div class={['code-formatted', trackingClass].join(' ')}>
|
|
53
|
-
<div
|
|
54
|
-
class="relative inset-0"
|
|
55
|
-
data-pagefind-ignore
|
|
56
|
-
>
|
|
39
|
+
<div class="relative inset-0" data-pagefind-ignore>
|
|
57
40
|
{formatted.dot}
|
|
58
41
|
</div>
|
|
59
|
-
<div
|
|
60
|
-
class="absolute inset-0"
|
|
61
|
-
data-pagefind-ignore
|
|
62
|
-
>
|
|
42
|
+
<div class="absolute inset-0" data-pagefind-ignore>
|
|
63
43
|
{formatted.dash}
|
|
64
44
|
</div>
|
|
65
45
|
<FormattedWrapper class="number-secondary">{formatted.standard}</FormattedWrapper>
|
|
@@ -16,11 +16,7 @@ const props = defineProps({
|
|
|
16
16
|
</script>
|
|
17
17
|
|
|
18
18
|
<template>
|
|
19
|
-
<span
|
|
20
|
-
v-for="position in props.positions"
|
|
21
|
-
:key="position.sort"
|
|
22
|
-
class="product-position"
|
|
23
|
-
>
|
|
19
|
+
<span v-for="position in props.positions" :key="position.sort" class="product-position">
|
|
24
20
|
{{ position.name }}
|
|
25
21
|
</span>
|
|
26
22
|
</template>
|
|
@@ -10,7 +10,7 @@ interface PrCodeObject {
|
|
|
10
10
|
variant_category?: string;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
defineProps({
|
|
14
14
|
prcodes: {
|
|
15
15
|
type: Array as PropType<PrCodeObject[]>,
|
|
16
16
|
default: () => [],
|
|
@@ -33,11 +33,11 @@ const variantCategoryMap: Record<string, string> = {
|
|
|
33
33
|
'0NH': 'GTI',
|
|
34
34
|
'1ZR': 'GTI',
|
|
35
35
|
// WRC
|
|
36
|
-
|
|
36
|
+
E5M: 'WRC',
|
|
37
37
|
'1KD': 'WRC',
|
|
38
38
|
'1ZP': 'WRC',
|
|
39
39
|
'2JQ': 'WRC',
|
|
40
|
-
|
|
40
|
+
TA2: 'WRC',
|
|
41
41
|
// CROSS
|
|
42
42
|
'2JK': 'CROSS',
|
|
43
43
|
// BLUEGT
|
|
@@ -56,17 +56,9 @@ const getVariantCategory = (code: string, fallback?: string): string | undefined
|
|
|
56
56
|
</script>
|
|
57
57
|
|
|
58
58
|
<template>
|
|
59
|
-
<span
|
|
60
|
-
v-for="(prcode, index) in prcodes"
|
|
61
|
-
:key="prcode?.id || index"
|
|
62
|
-
class="not-last:mr-1"
|
|
63
|
-
>
|
|
59
|
+
<span v-for="(prcode, index) in prcodes" :key="prcode?.id || index" class="not-last:mr-1">
|
|
64
60
|
<template v-if="prcode?.code">
|
|
65
|
-
<PrCode
|
|
66
|
-
v-if="!prcode.code.includes('+')"
|
|
67
|
-
:prcode="prcode"
|
|
68
|
-
:isPdp="isPdp"
|
|
69
|
-
/>
|
|
61
|
+
<PrCode v-if="!prcode.code.includes('+')" :prcode="prcode" :isPdp="isPdp" />
|
|
70
62
|
<span v-else class="inline-flex items-center gap-1">
|
|
71
63
|
<template v-for="(code, idx) in prcode.code.split('+')" :key="idx">
|
|
72
64
|
<span v-if="idx > 0" class="text-sm opacity-75">+</span>
|
|
@@ -75,7 +67,7 @@ const getVariantCategory = (code: string, fallback?: string): string | undefined
|
|
|
75
67
|
code: code.trim(),
|
|
76
68
|
group: prcode.group,
|
|
77
69
|
description: null,
|
|
78
|
-
variant_category: getVariantCategory(code.trim(), prcode.variant_category)
|
|
70
|
+
variant_category: getVariantCategory(code.trim(), prcode.variant_category),
|
|
79
71
|
}"
|
|
80
72
|
:isPdp="isPdp"
|
|
81
73
|
/>
|
|
@@ -3,9 +3,7 @@ import { PropType } from 'vue';
|
|
|
3
3
|
|
|
4
4
|
const props = defineProps({
|
|
5
5
|
as: {
|
|
6
|
-
type: String as PropType<
|
|
7
|
-
'th' | 'td' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'div' | 'span'
|
|
8
|
-
>,
|
|
6
|
+
type: String as PropType<'th' | 'td' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'div' | 'span'>,
|
|
9
7
|
default: 'div',
|
|
10
8
|
required: true,
|
|
11
9
|
},
|
|
@@ -23,10 +21,7 @@ const props = defineProps({
|
|
|
23
21
|
</script>
|
|
24
22
|
|
|
25
23
|
<template>
|
|
26
|
-
<component
|
|
27
|
-
:is="props.as"
|
|
28
|
-
class="font-bold detail-name w-full sm:w-50 flex 2xl:w-64"
|
|
29
|
-
>
|
|
24
|
+
<component :is="props.as" class="font-bold detail-name w-full sm:w-50 flex 2xl:w-64">
|
|
30
25
|
<span :class="styles && styles.length ? styles : 'mt-auto'">
|
|
31
26
|
<b class="bg-white z-1 colon-after pr-1">{{ props.text }}</b>
|
|
32
27
|
</span>
|
|
@@ -84,22 +84,11 @@ const validatedItems = computed(() => {
|
|
|
84
84
|
<col class="details-table-col" />
|
|
85
85
|
</colgroup>
|
|
86
86
|
<tbody>
|
|
87
|
-
<tr
|
|
88
|
-
|
|
89
|
-
:key="index"
|
|
90
|
-
class="details-table-row"
|
|
91
|
-
>
|
|
92
|
-
<ProductDetailName
|
|
93
|
-
as="th"
|
|
94
|
-
:text="getHeaderText(row)"
|
|
95
|
-
class="details-table-header"
|
|
96
|
-
/>
|
|
87
|
+
<tr v-for="(row, index) in validatedItems" :key="index" class="details-table-row">
|
|
88
|
+
<ProductDetailName as="th" :text="getHeaderText(row)" class="details-table-header" />
|
|
97
89
|
|
|
98
90
|
<!-- Links Array -->
|
|
99
|
-
<td
|
|
100
|
-
v-if="isLinksArray(row)"
|
|
101
|
-
class="details-table-cell"
|
|
102
|
-
>
|
|
91
|
+
<td v-if="isLinksArray(row)" class="details-table-cell">
|
|
103
92
|
<ul class="list-none p-0 m-0">
|
|
104
93
|
<li
|
|
105
94
|
v-for="(link, linkIndex) in row.value as Link[]"
|
|
@@ -112,12 +101,7 @@ const validatedItems = computed(() => {
|
|
|
112
101
|
'leading-none inline-block mr-2 w-4 min-w-4 h-4 text-gray-400',
|
|
113
102
|
]"
|
|
114
103
|
/>
|
|
115
|
-
<a
|
|
116
|
-
:href="link.url"
|
|
117
|
-
target="_blank"
|
|
118
|
-
rel="noopener noreferrer"
|
|
119
|
-
class="link-primary"
|
|
120
|
-
>
|
|
104
|
+
<a :href="link.url" target="_blank" rel="noopener noreferrer" class="link-primary">
|
|
121
105
|
{{ link.anchor }}
|
|
122
106
|
</a>
|
|
123
107
|
</li>
|
|
@@ -125,10 +109,7 @@ const validatedItems = computed(() => {
|
|
|
125
109
|
</td>
|
|
126
110
|
|
|
127
111
|
<!-- Generic String Array -->
|
|
128
|
-
<td
|
|
129
|
-
v-else-if="isGenericArray(row)"
|
|
130
|
-
class="details-table-cell"
|
|
131
|
-
>
|
|
112
|
+
<td v-else-if="isGenericArray(row)" class="details-table-cell">
|
|
132
113
|
<ul class="list-none p-0 m-0">
|
|
133
114
|
<li
|
|
134
115
|
v-for="(item, itemIndex) in row.value as string[]"
|
|
@@ -142,17 +123,10 @@ const validatedItems = computed(() => {
|
|
|
142
123
|
</td>
|
|
143
124
|
|
|
144
125
|
<!-- HTML Value -->
|
|
145
|
-
<td
|
|
146
|
-
v-else-if="isHtmlValue(row.value)"
|
|
147
|
-
class="details-table-cell"
|
|
148
|
-
v-html="row.value"
|
|
149
|
-
/>
|
|
126
|
+
<td v-else-if="isHtmlValue(row.value)" class="details-table-cell" v-html="row.value" />
|
|
150
127
|
|
|
151
128
|
<!-- Slot or Default Value -->
|
|
152
|
-
<slot
|
|
153
|
-
v-else
|
|
154
|
-
:name="row.id"
|
|
155
|
-
>
|
|
129
|
+
<slot v-else :name="row.id">
|
|
156
130
|
<td class="details-table-cell">
|
|
157
131
|
{{ row.value }}
|
|
158
132
|
</td>
|
|
@@ -19,11 +19,7 @@ import ProductNumber from './Product/ProductNumber.astro';
|
|
|
19
19
|
}}
|
|
20
20
|
/>
|
|
21
21
|
) : (
|
|
22
|
-
<img
|
|
23
|
-
src="/1x1.png"
|
|
24
|
-
class="bg-gray-100/70"
|
|
25
|
-
alt={productObject.name}
|
|
26
|
-
/>
|
|
22
|
+
<img src="/1x1.png" class="bg-gray-100/70" alt={productObject.name} />
|
|
27
23
|
)}
|
|
28
24
|
</div>
|
|
29
25
|
|
|
@@ -45,14 +41,8 @@ import ProductNumber from './Product/ProductNumber.astro';
|
|
|
45
41
|
|
|
46
42
|
{index !== null && (
|
|
47
43
|
<>
|
|
48
|
-
<meta
|
|
49
|
-
|
|
50
|
-
content={String(index)}
|
|
51
|
-
/>
|
|
52
|
-
<meta
|
|
53
|
-
itemprop="name"
|
|
54
|
-
content={productObject.name}
|
|
55
|
-
/>
|
|
44
|
+
<meta itemprop="position" content={String(index)} />
|
|
45
|
+
<meta itemprop="name" content={productObject.name} />
|
|
56
46
|
</>
|
|
57
47
|
)}
|
|
58
48
|
</div>
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
+
/* global localStorage */
|
|
2
3
|
import { ref, onMounted } from 'vue';
|
|
3
4
|
|
|
4
5
|
const props = defineProps({
|
|
5
6
|
// Primary state (visible by default)
|
|
6
7
|
message: {
|
|
7
8
|
type: String,
|
|
8
|
-
default:
|
|
9
|
+
default:
|
|
10
|
+
'We stand with our friends and colleagues in Ukraine. To support Ukraine in their time of need visit',
|
|
9
11
|
},
|
|
10
12
|
linkText: {
|
|
11
13
|
type: String,
|
|
@@ -51,7 +53,8 @@ const props = defineProps({
|
|
|
51
53
|
},
|
|
52
54
|
iconClass: {
|
|
53
55
|
type: String,
|
|
54
|
-
default:
|
|
56
|
+
default:
|
|
57
|
+
'inline-block text-4xl w-6 h-3.5 min-w-[1.25rem] mr-3 bg-gradient-to-b stops-[#0057b7_50%,50%,#ffd700_100%]',
|
|
55
58
|
},
|
|
56
59
|
|
|
57
60
|
// LocalStorage persistence
|
|
@@ -90,7 +93,7 @@ onMounted(() => {
|
|
|
90
93
|
// Still valid, keep hidden
|
|
91
94
|
isHidden.value = true;
|
|
92
95
|
}
|
|
93
|
-
} catch
|
|
96
|
+
} catch {
|
|
94
97
|
// Invalid data, remove it
|
|
95
98
|
localStorage.removeItem(props.storageKey);
|
|
96
99
|
}
|
|
@@ -109,9 +112,8 @@ const closePermanently = () => {
|
|
|
109
112
|
const data = {
|
|
110
113
|
closed: true,
|
|
111
114
|
timestamp: new Date().getTime(),
|
|
112
|
-
expires:
|
|
113
|
-
? new Date().getTime() +
|
|
114
|
-
: null,
|
|
115
|
+
expires:
|
|
116
|
+
props.expirationDays > 0 ? new Date().getTime() + props.expirationDays * 24 * 60 * 60 * 1000 : null,
|
|
115
117
|
};
|
|
116
118
|
localStorage.setItem(props.storageKey, JSON.stringify(data));
|
|
117
119
|
}
|
|
@@ -120,16 +122,9 @@ const closePermanently = () => {
|
|
|
120
122
|
|
|
121
123
|
<template>
|
|
122
124
|
<template v-if="!isHidden">
|
|
123
|
-
<div
|
|
124
|
-
v-if="isShow"
|
|
125
|
-
data-pagefind-ignore
|
|
126
|
-
class="slimbanner"
|
|
127
|
-
>
|
|
125
|
+
<div v-if="isShow" data-pagefind-ignore class="slimbanner">
|
|
128
126
|
<slot name="icon">
|
|
129
|
-
<span
|
|
130
|
-
v-if="props.showIcon"
|
|
131
|
-
:class="props.iconClass"
|
|
132
|
-
/>
|
|
127
|
+
<span v-if="props.showIcon" :class="props.iconClass" />
|
|
133
128
|
</slot>
|
|
134
129
|
|
|
135
130
|
<span class="leading-none inline-flex">
|
package/src/components/Table.vue
CHANGED
|
@@ -14,26 +14,14 @@ const capitalizeFirstLetter = (text: string) => {
|
|
|
14
14
|
<table class="table-auto text-left border bg-white shadow-md">
|
|
15
15
|
<thead class="bg-gray-500 text-white">
|
|
16
16
|
<tr class="border">
|
|
17
|
-
<th
|
|
18
|
-
v-for="(thead, index) in theads"
|
|
19
|
-
:key="index"
|
|
20
|
-
class="px-4 py-2 font-semibold"
|
|
21
|
-
>
|
|
17
|
+
<th v-for="(thead, index) in theads" :key="index" class="px-4 py-2 font-semibold">
|
|
22
18
|
{{ capitalizeFirstLetter(thead) }}
|
|
23
19
|
</th>
|
|
24
20
|
</tr>
|
|
25
21
|
</thead>
|
|
26
22
|
<tbody>
|
|
27
|
-
<tr
|
|
28
|
-
v-for="(row
|
|
29
|
-
:key="index"
|
|
30
|
-
class="border"
|
|
31
|
-
>
|
|
32
|
-
<td
|
|
33
|
-
v-for="key in Object.keys(row)"
|
|
34
|
-
:key="key"
|
|
35
|
-
class="px-4 py-2"
|
|
36
|
-
>
|
|
23
|
+
<tr v-for="(row, index) in props.data" :key="index" class="border">
|
|
24
|
+
<td v-for="key in Object.keys(row)" :key="key" class="px-4 py-2">
|
|
37
25
|
{{ row[key] }}
|
|
38
26
|
</td>
|
|
39
27
|
</tr>
|
|
@@ -18,10 +18,7 @@ const props = defineProps({
|
|
|
18
18
|
</script>
|
|
19
19
|
|
|
20
20
|
<template>
|
|
21
|
-
<div
|
|
22
|
-
v-if="props.translations !== null && props.translations.uri"
|
|
23
|
-
data-pagefind-ignore
|
|
24
|
-
>
|
|
21
|
+
<div v-if="props.translations !== null && props.translations.uri" data-pagefind-ignore>
|
|
25
22
|
<a
|
|
26
23
|
aria-label="Change language"
|
|
27
24
|
type="button"
|
|
@@ -24,10 +24,7 @@ const hasDescriptionSlotContent = Astro.slots.has('description');
|
|
|
24
24
|
>
|
|
25
25
|
<div class="flex-shrink-0 hidden md:block">
|
|
26
26
|
<slot name="icon">
|
|
27
|
-
<span
|
|
28
|
-
i-ph:sparkle-thin
|
|
29
|
-
class="mr-1 text-8 md:text-10 text-brand-secondary"
|
|
30
|
-
></span>
|
|
27
|
+
<span i-ph:sparkle-thin class="mr-1 text-8 md:text-10 text-brand-secondary"></span>
|
|
31
28
|
</slot>
|
|
32
29
|
</div>
|
|
33
30
|
<div class="flex-1 text-center md:text-left">
|
|
@@ -39,9 +36,7 @@ const hasDescriptionSlotContent = Astro.slots.has('description');
|
|
|
39
36
|
{
|
|
40
37
|
(propDescription || hasDescriptionSlotContent) && (
|
|
41
38
|
<p class="text-blue-darker mt-1">
|
|
42
|
-
<slot name="description">
|
|
43
|
-
{propDescription || 'Domyślny opis, który zachęca do działania.'}
|
|
44
|
-
</slot>
|
|
39
|
+
<slot name="description">{propDescription || 'Domyślny opis, który zachęca do działania.'}</slot>
|
|
45
40
|
</p>
|
|
46
41
|
)
|
|
47
42
|
}
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
const { class: className, isFullWidth } = Astro.props;
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
<div
|
|
6
|
-
class:list={[`${isFullWidth ? 'max-w-full' : 'max-w-screen-xl'} mx-auto px-5 py-4`, className]}
|
|
7
|
-
>
|
|
5
|
+
<div class:list={[`${isFullWidth ? 'max-w-full' : 'max-w-screen-xl'} mx-auto px-5 py-4`, className]}>
|
|
8
6
|
<slot />
|
|
9
7
|
</div>
|
|
@@ -30,10 +30,7 @@ const navItemsLeft = [
|
|
|
30
30
|
<slot name="logo" />
|
|
31
31
|
|
|
32
32
|
<div class="hidden sm:block sm:ml-6">
|
|
33
|
-
<div
|
|
34
|
-
class="flex space-x-4"
|
|
35
|
-
itemprop="hasPart"
|
|
36
|
-
>
|
|
33
|
+
<div class="flex space-x-4" itemprop="hasPart">
|
|
37
34
|
{
|
|
38
35
|
navItemsLeft.map(({ title, description, url }) => (
|
|
39
36
|
<a
|
|
@@ -60,14 +57,7 @@ const navItemsLeft = [
|
|
|
60
57
|
itemscope
|
|
61
58
|
itemtype="http://schema.org/SiteNavigationElement"
|
|
62
59
|
>
|
|
63
|
-
<a
|
|
64
|
-
class="icon-btn mx-2"
|
|
65
|
-
title=""
|
|
66
|
-
aria-label=""
|
|
67
|
-
href="#"
|
|
68
|
-
itemprop="url"
|
|
69
|
-
data-astro-reload
|
|
70
|
-
>
|
|
60
|
+
<a class="icon-btn mx-2" title="" aria-label="" href="#" itemprop="url" data-astro-reload>
|
|
71
61
|
<Icon name="carbon:language" />
|
|
72
62
|
</a>
|
|
73
63
|
</div>
|
package/src/layouts/Layout.astro
CHANGED
|
@@ -9,17 +9,10 @@ const { content = {} } = Astro.props;
|
|
|
9
9
|
const canonicalURL = new URL(Astro.url.pathname, Astro.site).toString();
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
<html
|
|
13
|
-
dir={content.dir ?? 'ltr'}
|
|
14
|
-
lang={content.lang ?? 'en-us'}
|
|
15
|
-
class="initial"
|
|
16
|
-
>
|
|
12
|
+
<html dir={content.dir ?? 'ltr'} lang={content.lang ?? 'en-us'} class="initial">
|
|
17
13
|
<head>
|
|
18
14
|
<HeadCommon />
|
|
19
|
-
<HeadSEO
|
|
20
|
-
{content}
|
|
21
|
-
canonicalURL={canonicalURL}
|
|
22
|
-
/>
|
|
15
|
+
<HeadSEO {content} canonicalURL={canonicalURL} />
|
|
23
16
|
<title>
|
|
24
17
|
{content.title ? `${content.title} 🚀 ${CONFIG.SITE.title}` : CONFIG.SITE.title}
|
|
25
18
|
</title>
|
|
@@ -25,17 +25,10 @@ const canonicalURL = new URL(Astro.url.pathname, Astro.site).toString();
|
|
|
25
25
|
import '../scripts/tooltips.ts';
|
|
26
26
|
</script>
|
|
27
27
|
|
|
28
|
-
<html
|
|
29
|
-
dir={content.dir ?? 'ltr'}
|
|
30
|
-
lang={content.lang ?? 'en-us'}
|
|
31
|
-
class="initial"
|
|
32
|
-
>
|
|
28
|
+
<html dir={content.dir ?? 'ltr'} lang={content.lang ?? 'en-us'} class="initial">
|
|
33
29
|
<head>
|
|
34
30
|
<HeadCommon />
|
|
35
|
-
<HeadSEO
|
|
36
|
-
content={content}
|
|
37
|
-
canonicalURL={canonicalURL}
|
|
38
|
-
/>
|
|
31
|
+
<HeadSEO content={content} canonicalURL={canonicalURL} />
|
|
39
32
|
<title>
|
|
40
33
|
{content.title ? `${content.title} 🚀 ${CONFIG.SITE.title}` : CONFIG.SITE.title}
|
|
41
34
|
</title>
|
|
@@ -48,18 +41,12 @@ const canonicalURL = new URL(Astro.url.pathname, Astro.site).toString();
|
|
|
48
41
|
|
|
49
42
|
<div class="flex bg-white z-10 mb-11 relative">
|
|
50
43
|
<div class="sticky top-0 flex lg:(h-screen w-64) z-50">
|
|
51
|
-
<div
|
|
52
|
-
class="mr-auto"
|
|
53
|
-
transition:name="sidebar"
|
|
54
|
-
>
|
|
44
|
+
<div class="mr-auto" transition:name="sidebar">
|
|
55
45
|
<LeftSidebar currentPage={currentPage} />
|
|
56
46
|
</div>
|
|
57
47
|
</div>
|
|
58
48
|
<main class="pb-4 px-4 sm:px-8 col-auto sm:(pb-32) overflow-auto w-full">
|
|
59
|
-
<PageContent
|
|
60
|
-
content={content}
|
|
61
|
-
transition:name="content"
|
|
62
|
-
>
|
|
49
|
+
<PageContent content={content} transition:name="content">
|
|
63
50
|
<slot />
|
|
64
51
|
</PageContent>
|
|
65
52
|
</main>
|
|
@@ -5,26 +5,12 @@ import { pwaInfo } from 'virtual:pwa-info';
|
|
|
5
5
|
|
|
6
6
|
<!-- Global Metadata -->
|
|
7
7
|
<meta charset="utf-8" />
|
|
8
|
-
<meta
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
/>
|
|
12
|
-
|
|
13
|
-
<link
|
|
14
|
-
rel="icon"
|
|
15
|
-
type="image/svg+xml"
|
|
16
|
-
href="/favicon.svg"
|
|
17
|
-
/>
|
|
18
|
-
<link
|
|
19
|
-
rel="alternate icon"
|
|
20
|
-
type="image/x-icon"
|
|
21
|
-
href="/favicon.ico"
|
|
22
|
-
/>
|
|
23
|
-
|
|
24
|
-
<link
|
|
25
|
-
rel="sitemap"
|
|
26
|
-
href="/sitemap-index.xml"
|
|
27
|
-
/>
|
|
8
|
+
<meta name="viewport" content="width=device-width" />
|
|
9
|
+
|
|
10
|
+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
11
|
+
<link rel="alternate icon" type="image/x-icon" href="/favicon.ico" />
|
|
12
|
+
|
|
13
|
+
<link rel="sitemap" href="/sitemap-index.xml" />
|
|
28
14
|
|
|
29
15
|
<!-- Preload Fonts -->
|
|
30
16
|
<!-- <link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
@@ -32,10 +18,7 @@ import { pwaInfo } from 'virtual:pwa-info';
|
|
|
32
18
|
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital@0;1&display=swap" rel="stylesheet" /> -->
|
|
33
19
|
|
|
34
20
|
<!-- Scrollable a11y code helper -->
|
|
35
|
-
<script
|
|
36
|
-
src="/make-scrollable-code-focusable.js"
|
|
37
|
-
is:inline
|
|
38
|
-
></script>
|
|
21
|
+
<script src="/make-scrollable-code-focusable.js" is:inline></script>
|
|
39
22
|
|
|
40
23
|
<!-- This is intentionally inlined to avoid FOUC -->
|
|
41
24
|
<script is:inline>
|
|
@@ -13,65 +13,29 @@ const imageAlt = content?.image?.alt ?? OPEN_GRAPH.image.alt;
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
<!-- Page Metadata -->
|
|
16
|
-
<link
|
|
17
|
-
rel="canonical"
|
|
18
|
-
href={canonicalURL}
|
|
19
|
-
/>
|
|
16
|
+
<link rel="canonical" href={canonicalURL} />
|
|
20
17
|
|
|
21
18
|
<!-- OpenGraph Tags -->
|
|
22
|
-
<meta
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
/>
|
|
26
|
-
<meta
|
|
27
|
-
property="og:type"
|
|
28
|
-
content="article"
|
|
29
|
-
/>
|
|
30
|
-
<meta
|
|
31
|
-
property="og:url"
|
|
32
|
-
content={canonicalURL}
|
|
33
|
-
/>
|
|
34
|
-
<meta
|
|
35
|
-
property="og:locale"
|
|
36
|
-
content={content.ogLocale ?? SITE.defaultLanguage}
|
|
37
|
-
/>
|
|
19
|
+
<meta property="og:title" content={formattedContentTitle} />
|
|
20
|
+
<meta property="og:type" content="article" />
|
|
21
|
+
<meta property="og:url" content={canonicalURL} />
|
|
22
|
+
<meta property="og:locale" content={content.ogLocale ?? SITE.defaultLanguage} />
|
|
38
23
|
<!-- <meta property="og:image" content={canonicalImageSrc} /> -->
|
|
39
|
-
<meta
|
|
40
|
-
property="og:image:alt"
|
|
41
|
-
content={imageAlt}
|
|
42
|
-
/>
|
|
24
|
+
<meta property="og:image:alt" content={imageAlt} />
|
|
43
25
|
<meta
|
|
44
26
|
name="description"
|
|
45
27
|
property="og:description"
|
|
46
28
|
content={content.description ? content.description : SITE.description}
|
|
47
29
|
/>
|
|
48
|
-
<meta
|
|
49
|
-
property="og:site_name"
|
|
50
|
-
content={SITE.title}
|
|
51
|
-
/>
|
|
30
|
+
<meta property="og:site_name" content={SITE.title} />
|
|
52
31
|
|
|
53
32
|
<!-- Twitter Tags -->
|
|
54
|
-
<meta
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
/>
|
|
58
|
-
<meta
|
|
59
|
-
name="twitter:site"
|
|
60
|
-
content={OPEN_GRAPH.twitter}
|
|
61
|
-
/>
|
|
62
|
-
<meta
|
|
63
|
-
name="twitter:title"
|
|
64
|
-
content={formattedContentTitle}
|
|
65
|
-
/>
|
|
66
|
-
<meta
|
|
67
|
-
name="twitter:description"
|
|
68
|
-
content={content.description ? content.description : SITE.description}
|
|
69
|
-
/>
|
|
33
|
+
<meta name="twitter:card" content="summary_large_image" />
|
|
34
|
+
<meta name="twitter:site" content={OPEN_GRAPH.twitter} />
|
|
35
|
+
<meta name="twitter:title" content={formattedContentTitle} />
|
|
36
|
+
<meta name="twitter:description" content={content.description ? content.description : SITE.description} />
|
|
70
37
|
<!-- <meta name="twitter:image" content={canonicalImageSrc} /> -->
|
|
71
|
-
<meta
|
|
72
|
-
name="twitter:image:alt"
|
|
73
|
-
content={imageAlt}
|
|
74
|
-
/>
|
|
38
|
+
<meta name="twitter:image:alt" content={imageAlt} />
|
|
75
39
|
|
|
76
40
|
<!--
|
|
77
41
|
TODO: Add json+ld data, maybe https://schema.org/APIReference makes sense?
|
|
@@ -57,10 +57,7 @@ const sortedIconCollections = Object.entries(ICONS)
|
|
|
57
57
|
>
|
|
58
58
|
<div class="flex flex-col items-center">
|
|
59
59
|
<div class="p-4 bg-gray-50 rounded-lg mb-2 w-full flex justify-center items-center min-h-[64px]">
|
|
60
|
-
<Icon
|
|
61
|
-
name={`${name}:${iconName}`}
|
|
62
|
-
class="text-3xl text-blue-medium"
|
|
63
|
-
/>
|
|
60
|
+
<Icon name={`${name}:${iconName}`} class="text-3xl text-blue-medium" />
|
|
64
61
|
</div>
|
|
65
62
|
<code class="text-sm text-gray-600 text-center break-all">
|
|
66
63
|
{name}:{iconName}
|