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.
Files changed (78) hide show
  1. package/.husky/pre-commit +17 -1
  2. package/.prettierrc +8 -4
  3. package/CHANGELOG.md +6 -0
  4. package/package.json +1 -1
  5. package/src/components/Badge.vue +1 -4
  6. package/src/components/Badges.vue +1 -4
  7. package/src/components/Breadcrumbs.vue +10 -44
  8. package/src/components/Button.vue +1 -5
  9. package/src/components/ButtonCopy.astro +2 -7
  10. package/src/components/ButtonCopy.vue +2 -9
  11. package/src/components/Card.astro +1 -4
  12. package/src/components/Category/CategoriesCarousel.astro +3 -11
  13. package/src/components/Category/CategoryDetails.astro +7 -32
  14. package/src/components/Category/CategoryLink.vue +1 -5
  15. package/src/components/Category/CategorySidebarToggler.vue +1 -5
  16. package/src/components/Category/CategoryTile.astro +2 -9
  17. package/src/components/Category/CategoryViewToggler.astro +3 -16
  18. package/src/components/Copyright.astro +1 -4
  19. package/src/components/Date.astro +1 -4
  20. package/src/components/Faq.astro +1 -5
  21. package/src/components/FaqItem.astro +3 -14
  22. package/src/components/FeaturesList.vue +2 -9
  23. package/src/components/FuckRussia.vue +9 -36
  24. package/src/components/HandDrive.astro +2 -12
  25. package/src/components/Header/Header.astro +3 -14
  26. package/src/components/Header/SkipToContent.astro +1 -5
  27. package/src/components/Input.vue +19 -31
  28. package/src/components/Jumbotron/index.astro +7 -41
  29. package/src/components/Jumbotron/variants/Default.astro +2 -17
  30. package/src/components/Jumbotron/variants/Hero.astro +3 -17
  31. package/src/components/Jumbotron/variants/Post.astro +3 -13
  32. package/src/components/Jumbotron/variants/PostSplit.astro +3 -13
  33. package/src/components/Jumbotron.astro +3 -12
  34. package/src/components/LanguageSuggestion.astro +3 -14
  35. package/src/components/MainColors.vue +7 -25
  36. package/src/components/MainInput.vue +2 -1
  37. package/src/components/Modal.astro +43 -41
  38. package/src/components/PageContent.astro +1 -4
  39. package/src/components/PartNumber.vue +1 -4
  40. package/src/components/PostHeader.astro +3 -13
  41. package/src/components/PrCode.vue +2 -2
  42. package/src/components/Product/ProductButton.vue +1 -4
  43. package/src/components/Product/ProductDetailName.vue +1 -4
  44. package/src/components/Product/ProductDetails.vue +19 -65
  45. package/src/components/Product/ProductDoc.vue +1 -4
  46. package/src/components/Product/ProductEngine.astro +27 -27
  47. package/src/components/Product/ProductEngineType.vue +1 -4
  48. package/src/components/Product/ProductEngines.astro +4 -4
  49. package/src/components/Product/ProductLink.astro +8 -32
  50. package/src/components/Product/ProductLink.vue +8 -36
  51. package/src/components/Product/ProductLinkInfo.astro +4 -19
  52. package/src/components/Product/ProductModel.vue +3 -5
  53. package/src/components/Product/ProductModels.vue +2 -10
  54. package/src/components/Product/ProductNumber.astro +6 -26
  55. package/src/components/Product/ProductPositions.vue +1 -5
  56. package/src/components/ProductCodes.vue +6 -14
  57. package/src/components/ProductDetailName.vue +2 -7
  58. package/src/components/ProductDetailsList.vue +7 -33
  59. package/src/components/ProductTile.astro +3 -13
  60. package/src/components/ReloadPrompt.astro +1 -5
  61. package/src/components/SlimBanner.vue +10 -15
  62. package/src/components/Table.vue +3 -15
  63. package/src/components/Translations.vue +1 -4
  64. package/src/components/layout/CallToAction.astro +2 -7
  65. package/src/components/layout/Container.astro +1 -3
  66. package/src/components/layout/Header.astro +2 -12
  67. package/src/layouts/Layout.astro +2 -9
  68. package/src/layouts/MainLayout.astro +4 -17
  69. package/src/layouts/partials/HeadCommon.astro +7 -24
  70. package/src/layouts/partials/HeadSEO.astro +12 -48
  71. package/src/pages/components/icons.astro +1 -4
  72. package/src/pages/core/typography.astro +2 -6
  73. package/src/pages/index.astro +16 -63
  74. package/src/styles/tippy-theme.css +4 -2
  75. package/src/utils/product/getEngineTooltipContent.ts +2 -7
  76. package/src/utils/product/getPriceFormatted.ts +2 -6
  77. package/src/utils/product/useFormatProductNumber.ts +1 -4
  78. 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
  }
@@ -1,5 +1 @@
1
- <a
2
- href="#article"
3
- class="sr-only focus:not-sr-only skiplink"
4
- ><span>Skip to Content</span></a
5
- >
1
+ <a href="#article" class="sr-only focus:not-sr-only skiplink"><span>Skip to Content</span></a>
@@ -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
- {...commonProps}
69
- small={small}
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
- name="intro"
11
- slot="intro"
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
- v-if="copiedItem === `${category}-${name}-hex`"
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
- {showTrigger && (
88
- <Button
89
- primary
90
- onclick={`window.${id}.showModal()`}
91
- >{open}</Button
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
- {showXButton && (
104
- <form method="dialog" class="inline">
105
- <button
106
- class="modal-close-x"
107
- aria-label="Close"
108
- type="submit"
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
- {showActions && (
120
- <div class="modal-actions">
121
- <slot name="actions">
122
- <form method="dialog" class="contents">
123
- <Button>{cancelText}</Button>
124
- </form>
125
- <Button primary={confirmPrimary} onclick={`document.getElementById('${id}').dispatchEvent(new CustomEvent('confirm', { detail: { id: '${id}' } }))`}>
126
- {confirmText}
127
- </Button>
128
- </slot>
129
- </div>
130
- )}
131
-
132
- {!showActions && (
133
- <form method="dialog">
134
- <slot name="close" />
135
- </form>
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', (e) => {
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', (e) => {
151
+ dialog?.addEventListener('keydown', e => {
150
152
  if (e.key === 'Escape') {
151
153
  dialog.close();
152
154
  }
@@ -1,7 +1,4 @@
1
- <article
2
- id="article"
3
- class="content"
4
- >
1
+ <article id="article" class="content">
5
2
  <section class="main-section">
6
3
  <slot />
7
4
  </section>
@@ -21,10 +21,7 @@ const props = defineProps({
21
21
  </script>
22
22
 
23
23
  <template>
24
- <component
25
- :is="props.as"
26
- :class="props.class"
27
- >
24
+ <component :is="props.as" :class="props.class">
28
25
  {{ props.number }}
29
26
  </component>
30
27
  </template>