@yatoday/astro-ui 0.13.1 → 0.13.3

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.
@@ -62,6 +62,8 @@ const { selector = '#header', scrollOffset = 450 } = Astro.props;
62
62
  data-yt-scroll
63
63
  data-yt-scroll-offset={scrollOffset}
64
64
  data-yt-scroll-selector={selector}
65
+ aria-label="Back to top"
66
+ title="Back to top"
65
67
  >
66
68
  <svg viewBox="0 0 40 40" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
67
69
  <circle cx="20" cy="20" r="19" fill="none" stroke="currentColor" stroke-width="1.5" stroke-miterlimit="10"></circle>
@@ -12,6 +12,7 @@ const {
12
12
  title = await Astro.slots.render('title'),
13
13
  description = await Astro.slots.render('description'),
14
14
  callToAction,
15
+ isFirstSlide = false,
15
16
  } = Astro.props;
16
17
 
17
18
  const urlForImage = Array.isArray(callToAction)
@@ -103,8 +104,9 @@ const WrapperHeaderTag = asHeader;
103
104
  height={400}
104
105
  sizes="(max-width: 900px) 400px, 900px"
105
106
  layout="cover"
106
- loading="lazy"
107
- decoding="async"
107
+ loading={isFirstSlide ? "eager" : "lazy"}
108
+ fetchpriority={isFirstSlide ? "high" : undefined}
109
+ decoding={isFirstSlide ? "sync" : "async"}
108
110
  {...image}
109
111
  />
110
112
  )}
@@ -121,8 +123,9 @@ const WrapperHeaderTag = asHeader;
121
123
  height={400}
122
124
  sizes="(max-width: 900px) 400px, 900px"
123
125
  layout="cover"
124
- loading="lazy"
125
- decoding="async"
126
+ loading={isFirstSlide ? "eager" : "lazy"}
127
+ fetchpriority={isFirstSlide ? "high" : undefined}
128
+ decoding={isFirstSlide ? "sync" : "async"}
126
129
  {...image}
127
130
  />
128
131
  )}
@@ -11,6 +11,7 @@ export type HeroSectionProps = {
11
11
  image: Image | string;
12
12
  callToAction?: string | ToAction | Array<string | ToAction>;
13
13
  classes?: Record<string, string>;
14
+ isFirstSlide?: boolean;
14
15
  };
15
16
 
16
17
  export type SvelteHeroSectionProps = WithElementRef<HTMLAttributes<HTMLDivElement>> &
@@ -19,7 +19,7 @@
19
19
 
20
20
  onMount(async () => {
21
21
  const { register } = await import('swiper/element/bundle');
22
- const { on, get } = await import('~/utils');
22
+ const { on, get } = await import('../../utils');
23
23
 
24
24
  register();
25
25
 
@@ -24,6 +24,13 @@ const {
24
24
  prevEl: `#btn-prev-${id}`,
25
25
  })
26
26
  : false}
27
+ a11y={JSON.stringify({
28
+ enabled: true,
29
+ prevSlideMessage: 'Previous slide',
30
+ nextSlideMessage: 'Next slide',
31
+ firstSlideMessage: 'This is the first slide',
32
+ lastSlideMessage: 'This is the last slide',
33
+ })}
27
34
  breakpoints={JSON.stringify({
28
35
  // 640: sm
29
36
  // 768: sm
@@ -58,6 +65,8 @@ const {
58
65
  type="button"
59
66
  id={`btn-prev-${id}`}
60
67
  class="btn-shadow hidden md:flex items-center justify-center cursor-pointer absolute -left-5 top-1/2 -translate-y-1/2 z-10 w-12 h-12 bg-white text-black rounded-full transition-opacity opacity-0"
68
+ aria-label="Previous slide"
69
+ title="Previous slide"
61
70
  >
62
71
  <Icon name="tabler:chevron-left" class="w-7 h-7" />
63
72
  </button>
@@ -65,6 +74,8 @@ const {
65
74
  type="button"
66
75
  id={`btn-next-${id}`}
67
76
  class="btn-shadow hidden md:flex items-center justify-center cursor-pointer absolute -right-5 top-1/2 -translate-y-1/2 z-10 w-12 h-12 bg-white text-black rounded-full transition-opacity "
77
+ aria-label="Next slide"
78
+ title="Next slide"
68
79
  >
69
80
  <Icon name="tabler:chevron-right" class="w-7 h-7" />
70
81
  </button>
@@ -88,23 +99,30 @@ const {
88
99
  elem.addEventListener(
89
100
  'swiperreachend',
90
101
  () => {
91
- removeClasses(`#btn-next-${id}`, 'opacity-100');
92
- addClasses(`#btn-next-${id}`, 'opacity-0');
102
+ // Use requestAnimationFrame to batch DOM updates and prevent forced reflow
103
+ requestAnimationFrame(() => {
104
+ removeClasses(`#btn-next-${id}`, 'opacity-100');
105
+ addClasses(`#btn-next-${id}`, 'opacity-0');
106
+ });
93
107
  },
94
108
  false
95
109
  );
96
110
  elem.addEventListener(
97
111
  'swiperreachbeginning',
98
112
  () => {
99
- addClasses(`#btn-prev-${id}`, 'opacity-0');
113
+ requestAnimationFrame(() => {
114
+ addClasses(`#btn-prev-${id}`, 'opacity-0');
115
+ });
100
116
  },
101
117
  false
102
118
  );
103
119
  elem.addEventListener(
104
120
  'swiperfromedge',
105
121
  () => {
106
- removeClasses(`#btn-prev-${id}`, 'opacity-0');
107
- addClasses(`#btn-next-${id}`, 'opacity-100');
122
+ requestAnimationFrame(() => {
123
+ removeClasses(`#btn-prev-${id}`, 'opacity-0');
124
+ addClasses(`#btn-next-${id}`, 'opacity-100');
125
+ });
108
126
  },
109
127
  false
110
128
  );
@@ -130,6 +130,13 @@ const {
130
130
  prevEl: `#btn-prev-${id}`,
131
131
  })
132
132
  : false}
133
+ a11y={JSON.stringify({
134
+ enabled: true,
135
+ prevSlideMessage: 'Previous slide',
136
+ nextSlideMessage: 'Next slide',
137
+ firstSlideMessage: 'This is the first slide',
138
+ lastSlideMessage: 'This is the last slide',
139
+ })}
133
140
  breakpoints={JSON.stringify({
134
141
  // 640: sm
135
142
  // 768: sm
@@ -145,11 +152,12 @@ const {
145
152
  {...rest}
146
153
  >
147
154
  {
148
- items.map((item) => (
155
+ items.map((item, index) => (
149
156
  <swiper-slide>
150
157
  <HeroSection
151
158
  {...item}
152
159
  classes={{ ...item?.classes, container: cn('rounded-xl', item?.classes?.container, height) }}
160
+ isFirstSlide={index === 0}
153
161
  />
154
162
  </swiper-slide>
155
163
  ))
@@ -164,11 +172,15 @@ const {
164
172
  type="button"
165
173
  id={`btn-prev-${id}`}
166
174
  class="btn-navigation btn-prev hidden lg:block cursor-pointer absolute z-10 w-10 h-10 bg-transparent border-2 border-white rounded-full shadow-sm transition-opacity opacity-20 hover:opacity-100 group-hover:opacity-100"
175
+ aria-label="Previous slide"
176
+ title="Previous slide"
167
177
  />
168
178
  <button
169
179
  type="button"
170
180
  id={`btn-next-${id}`}
171
181
  class="btn-navigation btn-next hidden lg:block cursor-pointer absolute z-10 w-10 h-10 bg-transparent border-2 border-white rounded-full shadow-sm transition-opacity opacity-20 hover:opacity-100 group-hover:opacity-100"
182
+ aria-label="Next slide"
183
+ title="Next slide"
172
184
  />
173
185
  </Fragment>
174
186
  )
@@ -193,11 +193,14 @@ const currentPath = `/${trimSlash(new URL(Astro.url).pathname)}`;
193
193
  let ticking = true;
194
194
 
195
195
  attachEvent('[data-yt-toggle-menu]', 'click', (_: Event, elem: HTMLElement) => {
196
- toggleClasses(elem, 'expanded');
197
- toggleClasses(document.body, 'overflow-hidden');
198
- toggleClasses(document.getElementById('header'), 'h-screen', 'expanded');
199
- toggleClasses('[data-yt-sticky-header] nav', 'hidden');
200
- toggleClasses('[data-yt-actions]', 'hidden');
196
+ // Batch DOM updates to prevent forced reflow
197
+ requestAnimationFrame(() => {
198
+ toggleClasses(elem, 'expanded');
199
+ toggleClasses(document.body, 'overflow-hidden');
200
+ toggleClasses(document.getElementById('header'), 'h-screen', 'expanded');
201
+ toggleClasses('[data-yt-sticky-header] nav', 'hidden');
202
+ toggleClasses('[data-yt-actions]', 'hidden');
203
+ });
201
204
  });
202
205
 
203
206
  attachEvent('[data-yt-sticky-header] nav', 'click', () => {
@@ -209,11 +212,14 @@ const currentPath = `/${trimSlash(new URL(Astro.url).pathname)}`;
209
212
  });
210
213
 
211
214
  function hiddenNav() {
212
- removeClasses('[data-yt-toggle-menu]', 'expanded');
213
- removeClasses(document.body, 'overflow-hidden');
214
- removeClasses(document.getElementById('header'), 'h-screen', 'expanded');
215
- addClasses('[data-yt-sticky-header] nav', 'hidden');
216
- addClasses('[data-yt-actions]', 'hidden');
215
+ // Batch DOM updates to prevent forced reflow
216
+ requestAnimationFrame(() => {
217
+ removeClasses('[data-yt-toggle-menu]', 'expanded');
218
+ removeClasses(document.body, 'overflow-hidden');
219
+ removeClasses(document.getElementById('header'), 'h-screen', 'expanded');
220
+ addClasses('[data-yt-sticky-header] nav', 'hidden');
221
+ addClasses('[data-yt-actions]', 'hidden');
222
+ });
217
223
  }
218
224
 
219
225
  function applyHeaderStylesOnScroll() {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@yatoday/astro-ui",
3
3
  "type": "module",
4
- "version": "0.13.1",
4
+ "version": "0.13.3",
5
5
  "scripts": {
6
6
  "prepare": "husky",
7
7
  "pre-commit": "lint-staged",