spoko-design-system 1.9.1 → 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/.husky/pre-commit +17 -1
- package/.prettierrc +8 -4
- package/CHANGELOG.md +6 -0
- package/package.json +1 -1
- 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 +27 -27
- package/src/components/Product/ProductEngineType.vue +1 -4
- package/src/components/Product/ProductEngines.astro +4 -4
- 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/core/typography.astro +2 -6
- package/src/pages/index.astro +16 -63
- package/src/styles/tippy-theme.css +4 -2
- package/src/utils/product/getEngineTooltipContent.ts +2 -7
- package/src/utils/product/getPriceFormatted.ts +2 -6
- package/src/utils/product/useFormatProductNumber.ts +1 -4
- package/src/utils/seo/getShorterDescription.ts +1 -4
|
@@ -7,10 +7,7 @@ import Search from 'astro-pagefind/components/Search';
|
|
|
7
7
|
|
|
8
8
|
<header class="p-3 bg-blue-medium bg-opacity-10 backdrop-blur-md border-b text-slate-900">
|
|
9
9
|
<SkipToContent />
|
|
10
|
-
<nav
|
|
11
|
-
title="Top Navigation"
|
|
12
|
-
class="mx-auto flex justify-between items-center px-4"
|
|
13
|
-
>
|
|
10
|
+
<nav title="Top Navigation" class="mx-auto flex justify-between items-center px-4">
|
|
14
11
|
<div class="flex flex-nowrap">
|
|
15
12
|
<MenuIcon class="w-4 h-4 text-gray-800 lg:hidden mr-4" />
|
|
16
13
|
<a
|
|
@@ -39,11 +36,7 @@ import Search from 'astro-pagefind/components/Search';
|
|
|
39
36
|
class="opacity-80 hover:opacity-100 hover:bg-slate-200 p-2 rounded-full transition-colors"
|
|
40
37
|
href={'https://github.com/' + SITE.github}
|
|
41
38
|
>
|
|
42
|
-
<img
|
|
43
|
-
class="h-7"
|
|
44
|
-
src="/github.svg"
|
|
45
|
-
alt="github logo"
|
|
46
|
-
/>
|
|
39
|
+
<img class="h-7" src="/github.svg" alt="github logo" />
|
|
47
40
|
</a>
|
|
48
41
|
)
|
|
49
42
|
}
|
|
@@ -54,11 +47,7 @@ import Search from 'astro-pagefind/components/Search';
|
|
|
54
47
|
class="opacity-80 hover:opacity-100 hover:bg-blue-50 p-2 rounded-full transition-colors"
|
|
55
48
|
href={'https://linkedin.com/in/' + SITE.linkedin}
|
|
56
49
|
>
|
|
57
|
-
<img
|
|
58
|
-
class="h-7"
|
|
59
|
-
src="/linkedin.svg"
|
|
60
|
-
alt="linkedin logo"
|
|
61
|
-
/>
|
|
50
|
+
<img class="h-7" src="/linkedin.svg" alt="linkedin logo" />
|
|
62
51
|
</a>
|
|
63
52
|
)
|
|
64
53
|
}
|
package/src/components/Input.vue
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
/* global Event, HTMLInputElement, HTMLTextAreaElement, FocusEvent */
|
|
2
3
|
import { computed, useAttrs } from 'vue';
|
|
3
4
|
|
|
4
5
|
interface InputProps {
|
|
@@ -30,7 +31,7 @@ const props = withDefaults(defineProps<InputProps>(), {
|
|
|
30
31
|
error: false,
|
|
31
32
|
success: false,
|
|
32
33
|
size: 'md',
|
|
33
|
-
class: ''
|
|
34
|
+
class: '',
|
|
34
35
|
});
|
|
35
36
|
|
|
36
37
|
const emit = defineEmits(['update:modelValue', 'input', 'focus', 'blur']);
|
|
@@ -45,7 +46,7 @@ const wrapperClass = computed(() => `relative input-wrapper-${props.variant}`);
|
|
|
45
46
|
const inputClass = computed(() => {
|
|
46
47
|
// Base classes
|
|
47
48
|
const classes = ['input-base', `input-${props.variant}`];
|
|
48
|
-
|
|
49
|
+
|
|
49
50
|
// Focus and placeholder behavior - using direct arbitrary selectors
|
|
50
51
|
classes.push('[&:focus~label]:text-blue-light');
|
|
51
52
|
classes.push('[&:focus~label]:dark:text-blue-lightest');
|
|
@@ -53,7 +54,7 @@ const inputClass = computed(() => {
|
|
|
53
54
|
classes.push('[&:placeholder-shown~label]:scale-100');
|
|
54
55
|
classes.push('[&:placeholder-shown~label]:translate-y-0');
|
|
55
56
|
classes.push('[&:not(:placeholder-shown)~label]:scale-75');
|
|
56
|
-
|
|
57
|
+
|
|
57
58
|
// Variant-specific behaviors
|
|
58
59
|
if (props.variant === 'standard') {
|
|
59
60
|
classes.push('[&:focus~label]:-translate-y-6');
|
|
@@ -63,14 +64,14 @@ const inputClass = computed(() => {
|
|
|
63
64
|
classes.push('[&:focus~label]:-translate-y-4');
|
|
64
65
|
classes.push('[&:not(:placeholder-shown)~label]:-translate-y-4');
|
|
65
66
|
}
|
|
66
|
-
|
|
67
|
+
|
|
67
68
|
// Additional classes
|
|
68
69
|
if (props.size) classes.push(`input-${props.size}`);
|
|
69
70
|
if (props.type === 'textarea') classes.push('input-textarea');
|
|
70
71
|
if (props.error) classes.push('input-error');
|
|
71
72
|
else if (props.success) classes.push('input-success');
|
|
72
73
|
if (props.class) classes.push(props.class);
|
|
73
|
-
|
|
74
|
+
|
|
74
75
|
return classes.join(' ');
|
|
75
76
|
});
|
|
76
77
|
|
|
@@ -78,7 +79,7 @@ const inputClass = computed(() => {
|
|
|
78
79
|
const labelClass = computed(() => {
|
|
79
80
|
// Base classes
|
|
80
81
|
const classes = ['input-label-base', `input-label-${props.variant}`];
|
|
81
|
-
|
|
82
|
+
|
|
82
83
|
// Explicitly add transform for initial state to ensure consistency
|
|
83
84
|
if (props.variant === 'standard') {
|
|
84
85
|
// Start in position and let focus/content move it
|
|
@@ -87,12 +88,12 @@ const labelClass = computed(() => {
|
|
|
87
88
|
// Start in position and let focus/content move it
|
|
88
89
|
classes.push('translate-y-0');
|
|
89
90
|
}
|
|
90
|
-
|
|
91
|
+
|
|
91
92
|
// Additional classes
|
|
92
93
|
if (props.size) classes.push(`input-label-${props.size}`);
|
|
93
94
|
if (props.error) classes.push('input-label-error');
|
|
94
95
|
else if (props.success) classes.push('input-label-success');
|
|
95
|
-
|
|
96
|
+
|
|
96
97
|
return classes.join(' ');
|
|
97
98
|
});
|
|
98
99
|
|
|
@@ -125,7 +126,7 @@ const handleBlur = (event: FocusEvent) => emit('blur', event);
|
|
|
125
126
|
@focus="handleFocus"
|
|
126
127
|
@blur="handleBlur"
|
|
127
128
|
/>
|
|
128
|
-
|
|
129
|
+
|
|
129
130
|
<!-- Input field -->
|
|
130
131
|
<input
|
|
131
132
|
v-else
|
|
@@ -140,35 +141,22 @@ const handleBlur = (event: FocusEvent) => emit('blur', event);
|
|
|
140
141
|
@input="handleInput"
|
|
141
142
|
@focus="handleFocus"
|
|
142
143
|
@blur="handleBlur"
|
|
143
|
-
|
|
144
|
-
|
|
144
|
+
/>
|
|
145
|
+
|
|
145
146
|
<!-- Label with guaranteed correct transform origin -->
|
|
146
|
-
<label
|
|
147
|
-
:for="id"
|
|
148
|
-
:class="labelClass"
|
|
149
|
-
style="transform-origin: top left;"
|
|
150
|
-
>
|
|
147
|
+
<label :for="id" :class="labelClass" style="transform-origin: top left">
|
|
151
148
|
{{ label }}
|
|
152
|
-
<span
|
|
153
|
-
v-if="required"
|
|
154
|
-
class="text-red-500 ml-1"
|
|
155
|
-
>*</span>
|
|
149
|
+
<span v-if="required" class="text-red-500 ml-1">*</span>
|
|
156
150
|
</label>
|
|
157
|
-
|
|
151
|
+
|
|
158
152
|
<!-- Error message -->
|
|
159
|
-
<div
|
|
160
|
-
v-if="error && typeof error === 'string'"
|
|
161
|
-
class="input-error-message"
|
|
162
|
-
>
|
|
153
|
+
<div v-if="error && typeof error === 'string'" class="input-error-message">
|
|
163
154
|
{{ error }}
|
|
164
155
|
</div>
|
|
165
|
-
|
|
156
|
+
|
|
166
157
|
<!-- Success message -->
|
|
167
|
-
<div
|
|
168
|
-
v-if="success && typeof success === 'string'"
|
|
169
|
-
class="input-success-message"
|
|
170
|
-
>
|
|
158
|
+
<div v-if="success && typeof success === 'string'" class="input-success-message">
|
|
171
159
|
{{ success }}
|
|
172
160
|
</div>
|
|
173
161
|
</div>
|
|
174
|
-
</template>
|
|
162
|
+
</template>
|
|
@@ -64,55 +64,21 @@ const commonProps = {
|
|
|
64
64
|
|
|
65
65
|
{
|
|
66
66
|
variant === 'default' && (
|
|
67
|
-
<DefaultVariant
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
<slot
|
|
72
|
-
name="intro"
|
|
73
|
-
slot="intro"
|
|
74
|
-
/>
|
|
75
|
-
<slot
|
|
76
|
-
name="subtitle"
|
|
77
|
-
slot="subtitle"
|
|
78
|
-
/>
|
|
79
|
-
<slot
|
|
80
|
-
name="cta-content"
|
|
81
|
-
slot="cta-content"
|
|
82
|
-
/>
|
|
67
|
+
<DefaultVariant {...commonProps} small={small}>
|
|
68
|
+
<slot name="intro" slot="intro" />
|
|
69
|
+
<slot name="subtitle" slot="subtitle" />
|
|
70
|
+
<slot name="cta-content" slot="cta-content" />
|
|
83
71
|
</DefaultVariant>
|
|
84
72
|
)
|
|
85
73
|
}
|
|
86
74
|
|
|
87
|
-
{
|
|
88
|
-
variant === 'hero' && (
|
|
89
|
-
<HeroVariant
|
|
90
|
-
{...commonProps}
|
|
91
|
-
description={description}
|
|
92
|
-
info={info}
|
|
93
|
-
/>
|
|
94
|
-
)
|
|
95
|
-
}
|
|
75
|
+
{variant === 'hero' && <HeroVariant {...commonProps} description={description} info={info} />}
|
|
96
76
|
|
|
97
|
-
{
|
|
98
|
-
variant === 'post' && (
|
|
99
|
-
<PostVariant
|
|
100
|
-
{...commonProps}
|
|
101
|
-
author={author}
|
|
102
|
-
date={date}
|
|
103
|
-
categories={categories}
|
|
104
|
-
/>
|
|
105
|
-
)
|
|
106
|
-
}
|
|
77
|
+
{variant === 'post' && <PostVariant {...commonProps} author={author} date={date} categories={categories} />}
|
|
107
78
|
|
|
108
79
|
{
|
|
109
80
|
variant === 'post-split' && (
|
|
110
|
-
<PostSplitVariant
|
|
111
|
-
{...commonProps}
|
|
112
|
-
author={author}
|
|
113
|
-
date={date}
|
|
114
|
-
categories={categories}
|
|
115
|
-
/>
|
|
81
|
+
<PostSplitVariant {...commonProps} author={author} date={date} categories={categories} />
|
|
116
82
|
)
|
|
117
83
|
}
|
|
118
84
|
|
|
@@ -8,13 +8,7 @@ interface Props {
|
|
|
8
8
|
hasCtaContent: boolean;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
const {
|
|
12
|
-
title = '',
|
|
13
|
-
small = false,
|
|
14
|
-
hasIntroContent,
|
|
15
|
-
hasSubtitleContent,
|
|
16
|
-
hasCtaContent,
|
|
17
|
-
} = Astro.props;
|
|
11
|
+
const { title = '', small = false, hasIntroContent, hasSubtitleContent, hasCtaContent } = Astro.props;
|
|
18
12
|
---
|
|
19
13
|
|
|
20
14
|
<header
|
|
@@ -24,16 +18,7 @@ const {
|
|
|
24
18
|
small ? 'jumbotron-container-small' : 'jumbotron-container-large', // wariant rozmiaru
|
|
25
19
|
]}
|
|
26
20
|
>
|
|
27
|
-
{
|
|
28
|
-
hasIntroContent ? (
|
|
29
|
-
<slot name="intro" />
|
|
30
|
-
) : (
|
|
31
|
-
<h1
|
|
32
|
-
class="jumbotron-title-default"
|
|
33
|
-
set:html={title}
|
|
34
|
-
/>
|
|
35
|
-
)
|
|
36
|
-
}
|
|
21
|
+
{hasIntroContent ? <slot name="intro" /> : <h1 class="jumbotron-title-default" set:html={title} />}
|
|
37
22
|
|
|
38
23
|
{hasSubtitleContent && <slot name="subtitle" />}
|
|
39
24
|
|
|
@@ -16,11 +16,7 @@ const { title = '', image, description, info, backgroundClass } = Astro.props;
|
|
|
16
16
|
image && (
|
|
17
17
|
<div class="absolute inset-0 w-full h-full">
|
|
18
18
|
<div class="absolute inset-0 bg-gradient-to-r from-blue-900 to-transparent opacity-90 z-1" />
|
|
19
|
-
<img
|
|
20
|
-
class="w-full h-full object-cover"
|
|
21
|
-
src={image}
|
|
22
|
-
alt={title}
|
|
23
|
-
/>
|
|
19
|
+
<img class="w-full h-full object-cover" src={image} alt={title} />
|
|
24
20
|
</div>
|
|
25
21
|
)
|
|
26
22
|
}
|
|
@@ -33,20 +29,10 @@ const { title = '', image, description, info, backgroundClass } = Astro.props;
|
|
|
33
29
|
/>
|
|
34
30
|
{
|
|
35
31
|
description && (
|
|
36
|
-
<div
|
|
37
|
-
class="mb-1 line-clamp-3 text-base sm:text-lg leading-none mt-4"
|
|
38
|
-
set:html={description}
|
|
39
|
-
/>
|
|
40
|
-
)
|
|
41
|
-
}
|
|
42
|
-
{
|
|
43
|
-
info && (
|
|
44
|
-
<div
|
|
45
|
-
class="font-medium mb-4 line-clamp-1 text-base sm:text-lg mt-2"
|
|
46
|
-
set:html={info}
|
|
47
|
-
/>
|
|
32
|
+
<div class="mb-1 line-clamp-3 text-base sm:text-lg leading-none mt-4" set:html={description} />
|
|
48
33
|
)
|
|
49
34
|
}
|
|
35
|
+
{info && <div class="font-medium mb-4 line-clamp-1 text-base sm:text-lg mt-2" set:html={info} />}
|
|
50
36
|
</header>
|
|
51
37
|
</div>
|
|
52
38
|
</div>
|
|
@@ -41,10 +41,7 @@ const {
|
|
|
41
41
|
{
|
|
42
42
|
hasCategories && (
|
|
43
43
|
<div class="order-1">
|
|
44
|
-
<PostCategories
|
|
45
|
-
categories={categories}
|
|
46
|
-
lang={lang}
|
|
47
|
-
/>
|
|
44
|
+
<PostCategories categories={categories} lang={lang} />
|
|
48
45
|
</div>
|
|
49
46
|
)
|
|
50
47
|
}
|
|
@@ -53,10 +50,7 @@ const {
|
|
|
53
50
|
hasMetadata && (
|
|
54
51
|
<div class="order-3 flex items-center text-gray-100">
|
|
55
52
|
{author && (
|
|
56
|
-
<span
|
|
57
|
-
class="text-sm"
|
|
58
|
-
title={author.firstName}
|
|
59
|
-
>
|
|
53
|
+
<span class="text-sm" title={author.firstName}>
|
|
60
54
|
{author.name}
|
|
61
55
|
</span>
|
|
62
56
|
)}
|
|
@@ -69,10 +63,6 @@ const {
|
|
|
69
63
|
</div>
|
|
70
64
|
|
|
71
65
|
<div class="featured-image-overlay">
|
|
72
|
-
<img
|
|
73
|
-
src={image}
|
|
74
|
-
alt={title}
|
|
75
|
-
class="w-full h-full object-cover block max-w-full"
|
|
76
|
-
/>
|
|
66
|
+
<img src={image} alt={title} class="w-full h-full object-cover block max-w-full" />
|
|
77
67
|
</div>
|
|
78
68
|
</header>
|
|
@@ -42,18 +42,12 @@ const cleanTitle = stripHtml(title);
|
|
|
42
42
|
class="heading flex flex-wrap text-white relative items-center justify-center mt-auto w-full z-[2]"
|
|
43
43
|
>
|
|
44
44
|
<div class="jumbotron-split-content">
|
|
45
|
-
<h1
|
|
46
|
-
class="jumbotron-split-title"
|
|
47
|
-
set:html={title}
|
|
48
|
-
/>
|
|
45
|
+
<h1 class="jumbotron-split-title" set:html={title} />
|
|
49
46
|
|
|
50
47
|
{
|
|
51
48
|
hasCategories && (
|
|
52
49
|
<div class="jumbotron-categories">
|
|
53
|
-
<PostCategories
|
|
54
|
-
categories={categories}
|
|
55
|
-
lang={lang}
|
|
56
|
-
/>
|
|
50
|
+
<PostCategories categories={categories} lang={lang} />
|
|
57
51
|
</div>
|
|
58
52
|
)
|
|
59
53
|
}
|
|
@@ -62,11 +56,7 @@ const cleanTitle = stripHtml(title);
|
|
|
62
56
|
hasMetadata && (
|
|
63
57
|
<div class="jumbotron-split-meta">
|
|
64
58
|
{author && (
|
|
65
|
-
<span
|
|
66
|
-
class="text-sm"
|
|
67
|
-
title={author.firstName}
|
|
68
|
-
data-pagefind-ignore
|
|
69
|
-
>
|
|
59
|
+
<span class="text-sm" title={author.firstName} data-pagefind-ignore>
|
|
70
60
|
{author.name}
|
|
71
61
|
</span>
|
|
72
62
|
)}
|
|
@@ -6,16 +6,7 @@ const props = Astro.props as Props;
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
<BaseJumbotron {...props}>
|
|
9
|
-
<slot
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
/>
|
|
13
|
-
<slot
|
|
14
|
-
name="subtitle"
|
|
15
|
-
slot="subtitle"
|
|
16
|
-
/>
|
|
17
|
-
<slot
|
|
18
|
-
name="cta-content"
|
|
19
|
-
slot="cta-content"
|
|
20
|
-
/>
|
|
9
|
+
<slot name="intro" slot="intro" />
|
|
10
|
+
<slot name="subtitle" slot="subtitle" />
|
|
11
|
+
<slot name="cta-content" slot="cta-content" />
|
|
21
12
|
</BaseJumbotron>
|
|
@@ -8,13 +8,7 @@ interface Props {
|
|
|
8
8
|
showIcon?: boolean;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
const {
|
|
12
|
-
position = 'bottom',
|
|
13
|
-
className = '',
|
|
14
|
-
customPath,
|
|
15
|
-
dismissTimeout,
|
|
16
|
-
showIcon = true,
|
|
17
|
-
} = Astro.props;
|
|
11
|
+
const { position = 'bottom', className = '', customPath, dismissTimeout, showIcon = true } = Astro.props;
|
|
18
12
|
|
|
19
13
|
const currentLocale = Astro.currentLocale;
|
|
20
14
|
const preferredLocale = Astro.preferredLocale;
|
|
@@ -33,10 +27,7 @@ const targetPath = customPath
|
|
|
33
27
|
]}
|
|
34
28
|
role="alert"
|
|
35
29
|
>
|
|
36
|
-
<a
|
|
37
|
-
href={targetPath}
|
|
38
|
-
class="flex items-center gap-2 font-medium hover:underline"
|
|
39
|
-
>
|
|
30
|
+
<a href={targetPath} class="flex items-center gap-2 font-medium hover:underline">
|
|
40
31
|
{showIcon && <span class="material-icons-outlined text-sm">translate</span>}
|
|
41
32
|
{new Intl.DisplayNames([preferredLocale], { type: 'language' }).of(preferredLocale)}
|
|
42
33
|
</a>
|
|
@@ -51,9 +42,7 @@ const targetPath = customPath
|
|
|
51
42
|
|
|
52
43
|
<script define:vars={{ currentLocale, preferredLocale, dismissTimeout }}>
|
|
53
44
|
const shouldShow =
|
|
54
|
-
preferredLocale &&
|
|
55
|
-
preferredLocale !== currentLocale &&
|
|
56
|
-
!localStorage.getItem('languageSuggestDenied');
|
|
45
|
+
preferredLocale && preferredLocale !== currentLocale && !localStorage.getItem('languageSuggestDenied');
|
|
57
46
|
|
|
58
47
|
if (shouldShow) {
|
|
59
48
|
const popup = document.getElementById('languageSuggestion');
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
/* global navigator, setTimeout */
|
|
2
3
|
import { ref } from 'vue';
|
|
3
4
|
import { colors } from './../../uno-config/theme/colors';
|
|
4
5
|
|
|
@@ -29,19 +30,12 @@ const getColorClass = (category: string, name: string) => {
|
|
|
29
30
|
|
|
30
31
|
<template>
|
|
31
32
|
<div class="flex flex-col space-y-12">
|
|
32
|
-
<div
|
|
33
|
-
v-for="[category, shades] in colorCategories"
|
|
34
|
-
:key="category"
|
|
35
|
-
>
|
|
33
|
+
<div v-for="[category, shades] in colorCategories" :key="category">
|
|
36
34
|
<h3 class="capitalize text-xl font-bold mb-4">
|
|
37
35
|
{{ category }}
|
|
38
36
|
</h3>
|
|
39
37
|
<div class="grid grid-cols-2 md:grid-cols-4 xl:grid-cols-5 gap-x-6 gap-y-10">
|
|
40
|
-
<div
|
|
41
|
-
v-for="(value, name) in shades"
|
|
42
|
-
:key="name"
|
|
43
|
-
class="group relative"
|
|
44
|
-
>
|
|
38
|
+
<div v-for="(value, name) in shades" :key="name" class="group relative">
|
|
45
39
|
<!-- Color Swatch -->
|
|
46
40
|
<button
|
|
47
41
|
class="w-full h-10 rounded-lg shadow-md transition-all duration-200 hover:shadow-xl hover:scale-105 cursor-pointer relative overflow-hidden"
|
|
@@ -73,14 +67,8 @@ const getColorClass = (category: string, name: string) => {
|
|
|
73
67
|
:title="`Copy hex: ${value}`"
|
|
74
68
|
@click="copyToClipboard(value, `${category}-${name}-hex`)"
|
|
75
69
|
>
|
|
76
|
-
<span
|
|
77
|
-
|
|
78
|
-
class="text-green-600"
|
|
79
|
-
>✓</span>
|
|
80
|
-
<span
|
|
81
|
-
v-else
|
|
82
|
-
class="uppercase text-xs"
|
|
83
|
-
>{{ value }}</span>
|
|
70
|
+
<span v-if="copiedItem === `${category}-${name}-hex`" class="text-green-600">✓</span>
|
|
71
|
+
<span v-else class="uppercase text-xs">{{ value }}</span>
|
|
84
72
|
</button>
|
|
85
73
|
|
|
86
74
|
<!-- Copy Class Name (text-*) -->
|
|
@@ -89,10 +77,7 @@ const getColorClass = (category: string, name: string) => {
|
|
|
89
77
|
:title="`Copy class: text-${getColorClass(category, name)}`"
|
|
90
78
|
@click="copyToClipboard(`text-${getColorClass(category, name)}`, `${category}-${name}-class`)"
|
|
91
79
|
>
|
|
92
|
-
<span
|
|
93
|
-
v-if="copiedItem === `${category}-${name}-class`"
|
|
94
|
-
class="text-green-600"
|
|
95
|
-
>✓</span>
|
|
80
|
+
<span v-if="copiedItem === `${category}-${name}-class`" class="text-green-600">✓</span>
|
|
96
81
|
<span v-else>text-</span>
|
|
97
82
|
</button>
|
|
98
83
|
|
|
@@ -102,10 +87,7 @@ const getColorClass = (category: string, name: string) => {
|
|
|
102
87
|
:title="`Copy class: bg-${getColorClass(category, name)}`"
|
|
103
88
|
@click="copyToClipboard(`bg-${getColorClass(category, name)}`, `${category}-${name}-bg`)"
|
|
104
89
|
>
|
|
105
|
-
<span
|
|
106
|
-
v-if="copiedItem === `${category}-${name}-bg`"
|
|
107
|
-
class="text-green-600"
|
|
108
|
-
>✓</span>
|
|
90
|
+
<span v-if="copiedItem === `${category}-${name}-bg`" class="text-green-600">✓</span>
|
|
109
91
|
<span v-else>bg-</span>
|
|
110
92
|
</button>
|
|
111
93
|
</div>
|
|
@@ -8,8 +8,9 @@ const props = defineProps<{
|
|
|
8
8
|
<label class="group text-left w-full max-w-xs flex flex-col">
|
|
9
9
|
<span
|
|
10
10
|
class="group-hover:text-blue-medium ml-2 text-slate-600 text-sm group-focus-within:text-blue-medium"
|
|
11
|
-
>{{ props.label }}</span
|
|
12
11
|
>
|
|
12
|
+
{{ props.label }}
|
|
13
|
+
</span>
|
|
13
14
|
<input
|
|
14
15
|
class="group-hover:border-blue-lightest border px-4 py-2 transition-colors rounded-md w-full focus:ring focus:outline-none focus:border-blue-medium"
|
|
15
16
|
type="text"
|
|
@@ -84,31 +84,26 @@ const {
|
|
|
84
84
|
}
|
|
85
85
|
</style>
|
|
86
86
|
|
|
87
|
-
{
|
|
88
|
-
|
|
89
|
-
primary
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
<dialog
|
|
96
|
-
id={id}
|
|
97
|
-
class="p-6"
|
|
98
|
-
>
|
|
87
|
+
{
|
|
88
|
+
showTrigger && (
|
|
89
|
+
<Button primary onclick={`window.${id}.showModal()`}>
|
|
90
|
+
{open}
|
|
91
|
+
</Button>
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
<dialog id={id} class="p-6">
|
|
99
96
|
<div class="modal-header">
|
|
100
97
|
{title && <h2 class="text-2xl font-bold pr-8">{title}</h2>}
|
|
101
98
|
<slot name="header" />
|
|
102
99
|
|
|
103
|
-
{
|
|
104
|
-
|
|
105
|
-
<
|
|
106
|
-
class="modal-close-x"
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
</form>
|
|
111
|
-
)}
|
|
100
|
+
{
|
|
101
|
+
showXButton && (
|
|
102
|
+
<form method="dialog" class="inline">
|
|
103
|
+
<button class="modal-close-x" aria-label="Close" type="submit" />
|
|
104
|
+
</form>
|
|
105
|
+
)
|
|
106
|
+
}
|
|
112
107
|
</div>
|
|
113
108
|
|
|
114
109
|
<div class="modal-content">
|
|
@@ -116,37 +111,44 @@ const {
|
|
|
116
111
|
<slot />
|
|
117
112
|
</div>
|
|
118
113
|
|
|
119
|
-
{
|
|
120
|
-
|
|
121
|
-
<
|
|
122
|
-
<
|
|
123
|
-
<
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
114
|
+
{
|
|
115
|
+
showActions && (
|
|
116
|
+
<div class="modal-actions">
|
|
117
|
+
<slot name="actions">
|
|
118
|
+
<form method="dialog" class="contents">
|
|
119
|
+
<Button>{cancelText}</Button>
|
|
120
|
+
</form>
|
|
121
|
+
<Button
|
|
122
|
+
primary={confirmPrimary}
|
|
123
|
+
onclick={`document.getElementById('${id}').dispatchEvent(new CustomEvent('confirm', { detail: { id: '${id}' } }))`}
|
|
124
|
+
>
|
|
125
|
+
{confirmText}
|
|
126
|
+
</Button>
|
|
127
|
+
</slot>
|
|
128
|
+
</div>
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
{
|
|
133
|
+
!showActions && (
|
|
134
|
+
<form method="dialog">
|
|
135
|
+
<slot name="close" />
|
|
136
|
+
</form>
|
|
137
|
+
)
|
|
138
|
+
}
|
|
137
139
|
</dialog>
|
|
138
140
|
|
|
139
141
|
<script define:vars={{ id }}>
|
|
140
142
|
// Close on backdrop click
|
|
141
143
|
const dialog = document.getElementById(id);
|
|
142
|
-
dialog?.addEventListener('click',
|
|
144
|
+
dialog?.addEventListener('click', e => {
|
|
143
145
|
if (e.target === dialog) {
|
|
144
146
|
dialog.close();
|
|
145
147
|
}
|
|
146
148
|
});
|
|
147
149
|
|
|
148
150
|
// Close on Escape key
|
|
149
|
-
dialog?.addEventListener('keydown',
|
|
151
|
+
dialog?.addEventListener('keydown', e => {
|
|
150
152
|
if (e.key === 'Escape') {
|
|
151
153
|
dialog.close();
|
|
152
154
|
}
|