srcdev-nuxt-components 2.1.22 → 2.1.23

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.
@@ -0,0 +1,435 @@
1
+ <template>
2
+ <div class="carousel" ref="carouselDom">
3
+ <!-- list item -->
4
+ <div class="list" ref="SliderDom">
5
+ <div v-for="item in galleryData" class="item" ref="SliderItemsDom">
6
+ <img :src="item.src" />
7
+ <div class="content">
8
+ <div class="author">{{ item.stylist }}</div>
9
+ <div class="title">{{ item.title }}</div>
10
+ <div class="topic">{{ item.category }}</div>
11
+ <div class="des">{{ item.description }}</div>
12
+ <div class="buttons">
13
+ <button>SEE MORE</button>
14
+ </div>
15
+ </div>
16
+ </div>
17
+ </div>
18
+ <!-- list thumnail -->
19
+ <div class="thumbnail" ref="thumbnailBorderDom">
20
+ <div v-for="item in galleryData" class="item" ref="thumbnailItemsDom">
21
+ <img :src="item.src" />
22
+ <div class="content">
23
+ <div class="title">Name Slider</div>
24
+ <div class="description">Description</div>
25
+ </div>
26
+ </div>
27
+ </div>
28
+ <!-- next prev -->
29
+
30
+ <div class="arrows">
31
+ <button id="prev" ref="prevDom" @click.prevent="doPrevious()"><</button>
32
+ <button id="next" ref="nextDom" @click.prevent="doNext()">></button>
33
+ </div>
34
+ <!-- time running -->
35
+ <div class="time" ref="timeDom"></div>
36
+ </div>
37
+ </template>
38
+
39
+ <script setup lang="ts">
40
+ const props = defineProps({
41
+ // galleryData: {
42
+ // type: Array as PropType<{ src: string; alt: string }[]>,
43
+ // default: () => [],
44
+ // },
45
+ styleClassPassthrough: {
46
+ type: Array as PropType<string[]>,
47
+ default: () => [],
48
+ },
49
+ });
50
+
51
+ interface IGalleryData {
52
+ src: string;
53
+ alt: string;
54
+ stylist?: string;
55
+ title?: string;
56
+ category?: string;
57
+ description?: string;
58
+ }
59
+
60
+ const { elementClasses, resetElementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
61
+ const galleryData = defineModel<IGalleryData[]>('galleryData');
62
+
63
+ //step 1: get DOM
64
+ const nextDom = useTemplateRef('nextDom');
65
+ const prevDom = useTemplateRef('prevDom');
66
+
67
+ const carouselDom = useTemplateRef('carouselDom');
68
+ const SliderDom = useTemplateRef('SliderDom');
69
+ const thumbnailBorderDom = useTemplateRef('thumbnailBorderDom');
70
+ // let thumbnailItemsDom = useTemplateRef('thumbnailItemsDom');
71
+ const timeDom = useTemplateRef('timeDom');
72
+
73
+ // setup showSlider DOM
74
+ const SliderItemsDom = useTemplateRef('SliderItemsDom');
75
+ const thumbnailItemsDom = useTemplateRef('thumbnailItemsDom');
76
+
77
+ // thumbnailBorderDom.value.appendChild(thumbnailItemsDom.value[0]);
78
+ const timeRunning = 3000;
79
+ const timeAutoNext = 7000;
80
+
81
+ const doNext = () => {
82
+ showSlider('next');
83
+ };
84
+
85
+ const doPrevious = () => {
86
+ showSlider('prev');
87
+ };
88
+
89
+ let runTimeOut: any;
90
+ let runNextAuto = setTimeout(() => {
91
+ doNext();
92
+ }, timeAutoNext);
93
+
94
+ function showSlider(type: string) {
95
+ // Get fresh references to all items by querying the DOM directly
96
+ const currentSliderItems = Array.from(SliderDom.value?.children || []);
97
+ const currentThumbnailItems = Array.from(thumbnailBorderDom.value?.children || []);
98
+
99
+ if (type === 'next') {
100
+ // Move the first item to the end
101
+ if (currentSliderItems.length) {
102
+ const firstItem = currentSliderItems[0];
103
+ SliderDom.value?.appendChild(firstItem);
104
+ }
105
+
106
+ if (currentThumbnailItems.length) {
107
+ const firstThumb = currentThumbnailItems[0];
108
+ thumbnailBorderDom.value?.appendChild(firstThumb);
109
+ }
110
+
111
+ carouselDom.value?.classList.add('next');
112
+ } else {
113
+ // Move the last item to the beginning
114
+ if (currentSliderItems.length) {
115
+ const lastItem = currentSliderItems[currentSliderItems.length - 1];
116
+ SliderDom.value?.prepend(lastItem);
117
+ }
118
+
119
+ if (currentThumbnailItems.length) {
120
+ const lastThumb = currentThumbnailItems[currentThumbnailItems.length - 1];
121
+ thumbnailBorderDom.value?.prepend(lastThumb);
122
+ }
123
+
124
+ carouselDom.value?.classList.add('prev');
125
+ }
126
+
127
+ clearTimeout(runTimeOut);
128
+ runTimeOut = setTimeout(() => {
129
+ if (carouselDom.value) {
130
+ carouselDom.value.classList.remove('next');
131
+ carouselDom.value.classList.remove('prev');
132
+ }
133
+ }, timeRunning);
134
+
135
+ clearTimeout(runNextAuto);
136
+ runNextAuto = setTimeout(() => {
137
+ doNext();
138
+ }, timeAutoNext);
139
+ }
140
+
141
+ watch(
142
+ () => props.styleClassPassthrough,
143
+ () => {
144
+ resetElementClasses(props.styleClassPassthrough);
145
+ }
146
+ );
147
+ </script>
148
+
149
+ <style lang="css">
150
+ /* carousel */
151
+ .carousel {
152
+ height: 100vh;
153
+ /* margin-top: -50px; */
154
+ width: 100vw;
155
+ overflow: hidden;
156
+ position: absolute;
157
+ inset: 0 0 0 0;
158
+ }
159
+ .carousel .list .item {
160
+ width: 100%;
161
+ height: 100%;
162
+ position: absolute;
163
+ inset: 0 0 0 0;
164
+ }
165
+ .carousel .list .item img {
166
+ width: 100%;
167
+ height: 100%;
168
+ object-fit: cover;
169
+ }
170
+ .carousel .list .item .content {
171
+ position: absolute;
172
+ top: 20%;
173
+ width: 1140px;
174
+ max-width: 80%;
175
+ left: 50%;
176
+ transform: translateX(-50%);
177
+ padding-right: 30%;
178
+ box-sizing: border-box;
179
+ color: #fff;
180
+ text-shadow: 0 5px 10px #0004;
181
+ }
182
+ .carousel .list .item .author {
183
+ font-weight: bold;
184
+ letter-spacing: 10px;
185
+ }
186
+ .carousel .list .item .title,
187
+ .carousel .list .item .topic {
188
+ font-size: 5em;
189
+ font-weight: bold;
190
+ line-height: 1.3em;
191
+ }
192
+ .carousel .list .item .topic {
193
+ color: #f1683a;
194
+ }
195
+ .carousel .list .item .buttons {
196
+ display: grid;
197
+ grid-template-columns: repeat(2, 130px);
198
+ grid-template-rows: 40px;
199
+ gap: 5px;
200
+ margin-top: 20px;
201
+ }
202
+ .carousel .list .item .buttons button {
203
+ background-color: #99999975;
204
+ border: 1px solid #fff;
205
+ color: #fff;
206
+ letter-spacing: 3px;
207
+ font-weight: 500;
208
+ }
209
+ /* .carousel .list .item .buttons button:nth-child(2) {
210
+ background-color: transparent;
211
+ border: 1px solid #fff;
212
+ color: #eee;
213
+ } */
214
+ /* thumbail */
215
+ .thumbnail {
216
+ position: absolute;
217
+ bottom: 50px;
218
+ left: 50%;
219
+ width: max-content;
220
+ z-index: 100;
221
+ display: flex;
222
+ gap: 20px;
223
+ }
224
+ .thumbnail .item {
225
+ width: 150px;
226
+ height: 220px;
227
+ flex-shrink: 0;
228
+ position: relative;
229
+ }
230
+ .thumbnail .item img {
231
+ width: 100%;
232
+ height: 100%;
233
+ object-fit: cover;
234
+ border-radius: 20px;
235
+ }
236
+ .thumbnail .item .content {
237
+ color: #fff;
238
+ position: absolute;
239
+ bottom: 10px;
240
+ left: 10px;
241
+ right: 10px;
242
+ }
243
+ .thumbnail .item .content .title {
244
+ font-weight: 500;
245
+ }
246
+ .thumbnail .item .content .description {
247
+ font-weight: 300;
248
+ }
249
+ /* arrows */
250
+ .arrows {
251
+ position: absolute;
252
+ top: 80%;
253
+ right: 52%;
254
+ z-index: 100;
255
+ width: 300px;
256
+ max-width: 30%;
257
+ display: flex;
258
+ gap: 10px;
259
+ align-items: center;
260
+ }
261
+ .arrows button {
262
+ width: 40px;
263
+ height: 40px;
264
+ border-radius: 50%;
265
+ background-color: #eee4;
266
+ border: none;
267
+ color: #fff;
268
+ font-family: monospace;
269
+ font-weight: bold;
270
+ transition: 0.5s;
271
+ }
272
+ .arrows button:hover {
273
+ background-color: #fff;
274
+ color: #000;
275
+ }
276
+
277
+ /* animation */
278
+ .carousel .list .item:nth-child(1) {
279
+ z-index: 1;
280
+ }
281
+
282
+ /* animation text in first item */
283
+
284
+ .carousel .list .item:nth-child(1) .content .author,
285
+ .carousel .list .item:nth-child(1) .content .title,
286
+ .carousel .list .item:nth-child(1) .content .topic,
287
+ .carousel .list .item:nth-child(1) .content .des,
288
+ .carousel .list .item:nth-child(1) .content .buttons {
289
+ transform: translateY(50px);
290
+ filter: blur(20px);
291
+ opacity: 0;
292
+ animation: showContent 0.5s 1s linear 1 forwards;
293
+ }
294
+ @keyframes showContent {
295
+ to {
296
+ transform: translateY(0px);
297
+ filter: blur(0px);
298
+ opacity: 1;
299
+ }
300
+ }
301
+ .carousel .list .item:nth-child(1) .content .title {
302
+ animation-delay: 1.2s !important;
303
+ }
304
+ .carousel .list .item:nth-child(1) .content .topic {
305
+ animation-delay: 1.4s !important;
306
+ }
307
+ .carousel .list .item:nth-child(1) .content .des {
308
+ animation-delay: 1.6s !important;
309
+ }
310
+ .carousel .list .item:nth-child(1) .content .buttons {
311
+ animation-delay: 1.8s !important;
312
+ }
313
+ /* create animation when next click */
314
+ .carousel.next .list .item:nth-child(1) img {
315
+ width: 150px;
316
+ height: 220px;
317
+ position: absolute;
318
+ bottom: 50px;
319
+ left: 50%;
320
+ border-radius: 30px;
321
+ animation: showImage 0.5s linear 1 forwards;
322
+ }
323
+ @keyframes showImage {
324
+ to {
325
+ bottom: 0;
326
+ left: 0;
327
+ width: 100%;
328
+ height: 100%;
329
+ border-radius: 0;
330
+ }
331
+ }
332
+
333
+ .carousel.next .thumbnail .item:nth-last-child(1) {
334
+ overflow: hidden;
335
+ animation: showThumbnail 0.5s linear 1 forwards;
336
+ }
337
+ .carousel.prev .list .item img {
338
+ z-index: 100;
339
+ }
340
+ @keyframes showThumbnail {
341
+ from {
342
+ width: 0;
343
+ opacity: 0;
344
+ }
345
+ }
346
+ .carousel.next .thumbnail {
347
+ animation: effectNext 0.5s linear 1 forwards;
348
+ }
349
+
350
+ @keyframes effectNext {
351
+ from {
352
+ transform: translateX(150px);
353
+ }
354
+ }
355
+
356
+ /* running time */
357
+
358
+ .carousel .time {
359
+ position: absolute;
360
+ z-index: 1000;
361
+ width: 0%;
362
+ height: 3px;
363
+ background-color: #f1683a;
364
+ left: 0;
365
+ top: 0;
366
+ }
367
+
368
+ .carousel.next .time,
369
+ .carousel.prev .time {
370
+ animation: runningTime 3s linear 1 forwards;
371
+ }
372
+ @keyframes runningTime {
373
+ from {
374
+ width: 100%;
375
+ }
376
+ to {
377
+ width: 0;
378
+ }
379
+ }
380
+
381
+ /* prev click */
382
+
383
+ .carousel.prev .list .item:nth-child(2) {
384
+ z-index: 2;
385
+ }
386
+
387
+ .carousel.prev .list .item:nth-child(2) img {
388
+ animation: outFrame 0.5s linear 1 forwards;
389
+ position: absolute;
390
+ bottom: 0;
391
+ left: 0;
392
+ }
393
+ @keyframes outFrame {
394
+ to {
395
+ width: 150px;
396
+ height: 220px;
397
+ bottom: 50px;
398
+ left: 50%;
399
+ border-radius: 20px;
400
+ }
401
+ }
402
+
403
+ .carousel.prev .thumbnail .item:nth-child(1) {
404
+ overflow: hidden;
405
+ opacity: 0;
406
+ animation: showThumbnail 0.5s linear 1 forwards;
407
+ }
408
+ .carousel.next .arrows button,
409
+ .carousel.prev .arrows button {
410
+ pointer-events: none;
411
+ }
412
+ .carousel.prev .list .item:nth-child(2) .content .author,
413
+ .carousel.prev .list .item:nth-child(2) .content .title,
414
+ .carousel.prev .list .item:nth-child(2) .content .topic,
415
+ .carousel.prev .list .item:nth-child(2) .content .des,
416
+ .carousel.prev .list .item:nth-child(2) .content .buttons {
417
+ animation: contentOut 1.5s linear 1 forwards !important;
418
+ }
419
+
420
+ @keyframes contentOut {
421
+ to {
422
+ transform: translateY(-150px);
423
+ filter: blur(20px);
424
+ opacity: 0;
425
+ }
426
+ }
427
+ @media screen and (max-width: 678px) {
428
+ .carousel .list .item .content {
429
+ padding-right: 0;
430
+ }
431
+ .carousel .list .item .content .title {
432
+ font-size: 30px;
433
+ }
434
+ }
435
+ </style>
package/nuxt.config.ts CHANGED
@@ -30,6 +30,8 @@ export default defineNuxtConfig({
30
30
  vue: {
31
31
  runtimeCompiler: true,
32
32
  },
33
- // plugins: ['css-anchor-positioning'],
34
33
  compatibilityDate: '2024-07-13',
34
+ typescript: {
35
+ includeWorkspace: true,
36
+ },
35
37
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "srcdev-nuxt-components",
3
3
  "type": "module",
4
- "version": "2.1.22",
4
+ "version": "2.1.23",
5
5
  "main": "nuxt.config.ts",
6
6
  "scripts": {
7
7
  "clean": "rm -rf .nuxt && rm -rf .output && rm -rf .playground/.nuxt && rm -rf .playground/.output",