@designcrowd/fe-shared-lib 1.4.7 → 1.4.8-promocardv1

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 (31) hide show
  1. package/.storybook/main.ts +5 -4
  2. package/.storybook/preview.js +1 -0
  3. package/dist/css/tailwind-brandCrowd.css +0 -6
  4. package/dist/css/tailwind-brandPage.css +0 -6
  5. package/dist/css/tailwind-crazyDomains.css +0 -6
  6. package/dist/css/tailwind-designCom.css +0 -6
  7. package/dist/css/tailwind-designCrowd.css +0 -6
  8. package/index.js +1 -1
  9. package/package.json +10 -10
  10. package/public/css/tailwind-brandCrowd.css +2472 -0
  11. package/public/css/tailwind-brandPage.css +2156 -0
  12. package/public/css/tailwind-crazyDomains.css +2472 -0
  13. package/public/css/tailwind-designCom.css +2472 -0
  14. package/public/css/tailwind-designCrowd.css +2472 -0
  15. package/src/atoms/components/Carousel/Carousel.fixtures.js +18 -0
  16. package/src/atoms/components/Carousel/carousel.stories.js +448 -179
  17. package/src/atoms/components/PromoCard/PromoCard.stories.ts +265 -0
  18. package/src/atoms/components/PromoCard/PromoCard.vue +89 -0
  19. package/tailwind.config.js +7 -8
  20. package/src/atoms/components/SparkleIcon/SparkleIcon.stories.js +0 -182
  21. package/src/atoms/components/SparkleIcon/SparkleIcon.vue +0 -105
  22. package/src/atoms/components/SparkleIcon/assets/animations/state-01.svg +0 -5
  23. package/src/atoms/components/SparkleIcon/assets/animations/state-02.svg +0 -5
  24. package/src/atoms/components/SparkleIcon/assets/animations/state-03.svg +0 -5
  25. package/src/atoms/components/SparkleIcon/assets/animations/state-04.svg +0 -5
  26. package/src/atoms/components/SparkleIcon/assets/animations/state-05.svg +0 -5
  27. package/src/atoms/components/SparkleIcon/assets/animations/state-06.svg +0 -5
  28. package/src/atoms/components/SparkleIcon/assets/animations/state-07.svg +0 -5
  29. package/src/atoms/components/SparkleIcon/assets/animations/state-08.svg +0 -5
  30. package/src/atoms/components/SparkleIcon/assets/sparkle.svg +0 -3
  31. package/src/atoms/components/SparkleIcon/index.ts +0 -3
@@ -1,261 +1,530 @@
1
- import Carousel from './Carousel.vue';
2
1
  import Icon from '../Icon/Icon.vue';
3
- import { carouselProps, cards } from './Carousel.fixtures';
2
+ import { cards } from './Carousel.fixtures';
3
+ import Carousel from './Carousel.vue';
4
4
 
5
5
  export default {
6
6
  title: 'Components/Carousel',
7
7
  component: Carousel,
8
+ tags: ['autodocs'],
9
+ argTypes: {
10
+ cards: {
11
+ control: 'object',
12
+ description: 'Array of card data to display in the carousel',
13
+ table: {
14
+ type: { summary: 'Array<Object>' },
15
+ defaultValue: { summary: '[]' },
16
+ },
17
+ },
18
+ showControls: {
19
+ control: 'boolean',
20
+ description: 'Show/hide navigation arrows',
21
+ table: {
22
+ type: { summary: 'boolean' },
23
+ defaultValue: { summary: 'true' },
24
+ },
25
+ },
26
+ showBullets: {
27
+ control: 'boolean',
28
+ description: 'Show/hide pagination bullets',
29
+ table: {
30
+ type: { summary: 'boolean' },
31
+ defaultValue: { summary: 'true' },
32
+ },
33
+ },
34
+ hideBulletsOnMobile: {
35
+ control: 'boolean',
36
+ description: 'Hide pagination bullets on mobile devices',
37
+ table: {
38
+ type: { summary: 'boolean' },
39
+ defaultValue: { summary: 'true' },
40
+ },
41
+ },
42
+ navCarousel: {
43
+ control: 'boolean',
44
+ description: 'Use alternative navigation styling',
45
+ table: {
46
+ type: { summary: 'boolean' },
47
+ defaultValue: { summary: 'false' },
48
+ },
49
+ },
50
+ disableRightClick: {
51
+ control: 'boolean',
52
+ description: 'Disable right-click context menu',
53
+ table: {
54
+ type: { summary: 'boolean' },
55
+ defaultValue: { summary: 'false' },
56
+ },
57
+ },
58
+ options: {
59
+ control: 'object',
60
+ description: 'Swiper options object for customization',
61
+ table: {
62
+ type: { summary: 'Object' },
63
+ defaultValue: { summary: '{}' },
64
+ },
65
+ },
66
+ },
67
+ parameters: {
68
+ docs: {
69
+ description: {
70
+ component:
71
+ 'A flexible carousel component built with Swiper.js. Supports multiple slides, custom navigation, pagination, and various display options.',
72
+ },
73
+ },
74
+ },
8
75
  };
9
76
 
10
- export const Sample = () => {
11
- return {
77
+ // Default story with interactive controls
78
+ export const Default = {
79
+ args: {
80
+ cards,
81
+ showControls: true,
82
+ showBullets: true,
83
+ hideBulletsOnMobile: false,
84
+ navCarousel: false,
85
+ options: {
86
+ loop: true,
87
+ spaceBetween: 20,
88
+ slidesPerView: 1,
89
+ breakpoints: {
90
+ 640: {
91
+ slidesPerView: 2,
92
+ slidesPerGroup: 2,
93
+ },
94
+ 1024: {
95
+ slidesPerView: 3,
96
+ slidesPerGroup: 3,
97
+ },
98
+ },
99
+ },
100
+ },
101
+ render: (args) => ({
12
102
  components: { Carousel },
13
- data() {
14
- return {
15
- carouselProps,
16
- cards,
17
- };
103
+ setup() {
104
+ return { args };
18
105
  },
19
- methods: {
20
- alert(e) {
21
- // eslint-disable-next-line no-alert
22
- alert(`You have clicked the "${e.slide.name}" slide`);
23
- },
106
+ template: `
107
+ <div class="tw-p-8">
108
+ <Carousel
109
+ :cards="args.cards"
110
+ :show-controls="args.showControls"
111
+ :show-bullets="args.showBullets"
112
+ :hide-bullets-on-mobile="args.hideBulletsOnMobile"
113
+ :nav-carousel="args.navCarousel"
114
+ :options="args.options"
115
+ >
116
+ <template #slide="{ slide }">
117
+ <div class="tw-flex tw-flex-col tw-items-center tw-cursor-pointer tw-p-4 tw-bg-gray-50 tw-rounded-lg tw-h-full">
118
+ <img :src="slide.imageUrl" :alt="slide.name" class="tw-w-full tw-h-48 tw-object-contain tw-mb-4" />
119
+ <span class="tw-text-lg tw-font-semibold tw-text-center">{{ slide.name }}</span>
120
+ </div>
121
+ </template>
122
+ </Carousel>
123
+ </div>
124
+ `,
125
+ }),
126
+ };
127
+
128
+ // Single slide view
129
+ export const SingleSlide = {
130
+ args: {
131
+ cards,
132
+ showControls: true,
133
+ showBullets: true,
134
+ options: {
135
+ loop: false,
136
+ slidesPerView: 1,
137
+ slidesPerGroup: 1,
138
+ },
139
+ },
140
+ render: (args) => ({
141
+ components: { Carousel },
142
+ setup() {
143
+ return { args };
24
144
  },
25
145
  template: `
26
- <Carousel
27
- class="tw-p-8"
28
- :cards="cards"
29
- :options="carouselProps"
30
- :hide-bullets-on-mobile="false"
31
- @on-slide-click="alert"
32
- >
33
- <template #slide="{ slide }">
34
- <div class="tw-flex tw-flex-col tw-items-center tw-cursor-pointer">
35
- <img :src="slide.imageUrl" :alt="slide.name" class="tw-w-full" width="100px" />
36
- <span>{{ slide.name }}</span>
37
- </div>
38
- </template>
39
- </Carousel>
146
+ <div class="tw-p-8 tw-max-w-md tw-mx-auto">
147
+ <Carousel
148
+ :cards="args.cards"
149
+ :show-controls="args.showControls"
150
+ :show-bullets="args.showBullets"
151
+ :options="args.options"
152
+ >
153
+ <template #slide="{ slide }">
154
+ <div class="tw-flex tw-flex-col tw-items-center tw-p-6 tw-bg-white tw-rounded-xl tw-shadow-lg">
155
+ <img :src="slide.imageUrl" :alt="slide.name" class="tw-w-full tw-h-64 tw-object-contain tw-mb-4" />
156
+ <h3 class="tw-text-xl tw-font-bold tw-text-center">{{ slide.name }}</h3>
157
+ <p class="tw-text-gray-600 tw-text-center tw-mt-2">Click to learn more</p>
158
+ </div>
159
+ </template>
160
+ </Carousel>
161
+ </div>
40
162
  `,
41
- };
163
+ }),
164
+ parameters: {
165
+ docs: {
166
+ description: {
167
+ story: 'Display one slide at a time with navigation controls.',
168
+ },
169
+ },
170
+ },
42
171
  };
43
172
 
44
- export const CarouselDotsHidden = () => {
45
- return {
173
+ // Without navigation controls
174
+ export const WithoutControls = {
175
+ args: {
176
+ cards,
177
+ showControls: false,
178
+ showBullets: true,
179
+ options: {
180
+ loop: true,
181
+ autoplay: {
182
+ delay: 3000,
183
+ disableOnInteraction: false,
184
+ },
185
+ },
186
+ },
187
+ render: (args) => ({
46
188
  components: { Carousel },
47
- data() {
48
- return {
49
- carouselProps,
50
- cards,
51
- };
189
+ setup() {
190
+ return { args };
52
191
  },
53
- methods: {
54
- alert(e) {
55
- // eslint-disable-next-line no-alert
56
- alert(`You have clicked the "${e.slide.name}" slide`);
192
+ template: `
193
+ <div class="tw-p-8">
194
+ <Carousel
195
+ :cards="args.cards"
196
+ :show-controls="args.showControls"
197
+ :show-bullets="args.showBullets"
198
+ :options="args.options"
199
+ >
200
+ <template #slide="{ slide }">
201
+ <div class="tw-flex tw-flex-col tw-items-center tw-p-4">
202
+ <img :src="slide.imageUrl" :alt="slide.name" class="tw-w-full tw-h-40 tw-object-contain tw-mb-2" />
203
+ <span class="tw-text-center tw-font-medium">{{ slide.name }}</span>
204
+ </div>
205
+ </template>
206
+ </Carousel>
207
+ </div>
208
+ `,
209
+ }),
210
+ parameters: {
211
+ docs: {
212
+ description: {
213
+ story: 'Auto-playing carousel without navigation arrows. Uses only pagination bullets for navigation.',
57
214
  },
58
215
  },
216
+ },
217
+ };
218
+
219
+ // Without bullets
220
+ export const WithoutBullets = {
221
+ args: {
222
+ cards,
223
+ showControls: true,
224
+ showBullets: false,
225
+ options: {
226
+ loop: true,
227
+ slidesPerView: 2,
228
+ spaceBetween: 20,
229
+ },
230
+ },
231
+ render: (args) => ({
232
+ components: { Carousel },
233
+ setup() {
234
+ return { args };
235
+ },
59
236
  template: `
60
- <Carousel
61
- :cards="cards"
62
- :show-bullets="false"
63
- @on-slide-click="alert"
64
- >
65
- <template #slide="{ slide }">
66
- <div class="tw-flex tw-flex-col tw-items-center tw-cursor-pointer">
67
- <img :src="slide.imageUrl" :alt="slide.name" class="tw-w-full" />
68
- <span>{{ slide.name }}</span>
69
- </div>
70
- </template>
71
- </Carousel>
237
+ <div class="tw-p-8">
238
+ <Carousel
239
+ :cards="args.cards"
240
+ :show-controls="args.showControls"
241
+ :show-bullets="args.showBullets"
242
+ :options="args.options"
243
+ >
244
+ <template #slide="{ slide }">
245
+ <div class="tw-flex tw-flex-col tw-items-center tw-p-4 tw-bg-gray-100 tw-rounded">
246
+ <img :src="slide.imageUrl" :alt="slide.name" class="tw-w-full tw-h-32 tw-object-contain tw-mb-2" />
247
+ <span class="tw-text-center">{{ slide.name }}</span>
248
+ </div>
249
+ </template>
250
+ </Carousel>
251
+ </div>
72
252
  `,
73
- };
253
+ }),
254
+ parameters: {
255
+ docs: {
256
+ description: {
257
+ story: 'Carousel with arrow controls only, no pagination bullets.',
258
+ },
259
+ },
260
+ },
74
261
  };
75
262
 
76
- export const CustomArrows = () => {
77
- return {
263
+ // Custom arrow styling
264
+ export const CustomArrows = {
265
+ args: {
266
+ cards,
267
+ },
268
+ render: (args) => ({
78
269
  components: { Carousel, Icon },
79
- data() {
80
- return {
81
- carouselProps,
82
- cards,
83
- };
270
+ setup() {
271
+ return { args };
84
272
  },
85
273
  template: `
86
- <Carousel :cards="cards">
87
- <template #arrow-left>
88
- <Icon classes="left-arrow tw--mb-1 tw-mr-4 tw-cursor-pointer tw-transform tw-rotate-180" name="maker-youtube" color="secondary-500" size="3xl" />
89
- </template>
90
- <template #slide="{ slide }">
91
- <div class="tw-flex tw-flex-col tw-items-center">
92
- <img :src="slide.imageUrl" :alt="slide.name" class="tw-w-full" />
93
- <span>{{ slide.name }}</span>
94
- </div>
95
- </template>
96
- <template #arrow-right>
97
- <Icon classes="tw--mb-1 tw-ml-4 tw-cursor-pointer" name="maker-youtube" color="secondary-500" size="3xl" />
98
- </template>
99
- </Carousel>
274
+ <div class="tw-p-8">
275
+ <Carousel :cards="args.cards" :options="{ loop: true }">
276
+ <template #arrow-left>
277
+ <div class="tw-bg-blue-500 tw-text-white tw-rounded-full tw-p-3 tw-cursor-pointer hover:tw-bg-blue-600 tw-transition tw-shadow-lg">
278
+ <Icon classes="tw-transform tw-rotate-180" name="chevron-right" size="lg" color="white" />
279
+ </div>
280
+ </template>
281
+ <template #slide="{ slide }">
282
+ <div class="tw-flex tw-flex-col tw-items-center tw-p-4">
283
+ <img :src="slide.imageUrl" :alt="slide.name" class="tw-w-full tw-h-40 tw-object-contain tw-mb-2" />
284
+ <span class="tw-text-center tw-font-medium">{{ slide.name }}</span>
285
+ </div>
286
+ </template>
287
+ <template #arrow-right>
288
+ <div class="tw-bg-blue-500 tw-text-white tw-rounded-full tw-p-3 tw-cursor-pointer hover:tw-bg-blue-600 tw-transition tw-shadow-lg">
289
+ <Icon name="chevron-right" size="lg" color="white" />
290
+ </div>
291
+ </template>
292
+ </Carousel>
293
+ </div>
100
294
  `,
101
- };
295
+ }),
296
+ parameters: {
297
+ docs: {
298
+ description: {
299
+ story: 'Carousel with custom-styled navigation arrows using the arrow slots.',
300
+ },
301
+ },
302
+ },
102
303
  };
103
304
 
104
- export const CustomOptions = () => {
105
- return {
106
- components: { Carousel, Icon },
107
- data() {
108
- return {
109
- carouselProps,
110
- cards,
111
- options: {
112
- loop: false,
113
- breakpoints: {
114
- 1024: {
115
- pagination: false,
116
- slidesPerView: 4,
117
- slidesPerGroup: 4,
118
- },
119
- },
120
- },
121
- };
305
+ // Free mode (continuous scroll)
306
+ export const FreeMode = {
307
+ args: {
308
+ cards: [...cards, ...cards, ...cards],
309
+ },
310
+ render: (args) => ({
311
+ components: { Carousel },
312
+ setup() {
313
+ return { args };
122
314
  },
123
315
  template: `
124
- <Carousel :cards="cards" :options="options">
125
- <template #arrow-left>
126
- <Icon classes="tw--mb-1 tw-ml-4 tw-cursor-pointer" name="chevron-left" size="4xl" />
127
- </template>
128
- <template #slide="{ slide }">
129
- <div class="tw-flex tw-flex-col tw-items-center">
130
- <img :src="slide.imageUrl" :alt="slide.name" class="tw-w-full" />
131
- <span>{{ slide.name }}</span>
132
- </div>
133
- </template>
134
- <template #arrow-right>
135
- <Icon classes="tw--mb-1 tw-ml-4 tw-cursor-pointer" name="chevron-right" size="4xl" />
136
- </template>
137
- </Carousel>
316
+ <div class="tw-p-8">
317
+ <Carousel
318
+ :cards="args.cards"
319
+ :options="{
320
+ loop: false,
321
+ spaceBetween: 20,
322
+ freeMode: true,
323
+ slidesPerView: 'auto',
324
+ }"
325
+ >
326
+ <template #slide="{ slide }">
327
+ <div class="tw-flex tw-flex-col tw-items-center tw-p-4 tw-bg-white tw-rounded-lg tw-shadow" style="width: 200px;">
328
+ <img :src="slide.imageUrl" :alt="slide.name" class="tw-w-full tw-h-32 tw-object-contain tw-mb-2" />
329
+ <span class="tw-text-center tw-text-sm tw-font-medium">{{ slide.name }}</span>
330
+ </div>
331
+ </template>
332
+ </Carousel>
333
+ </div>
334
+ `,
335
+ }),
336
+ parameters: {
337
+ docs: {
338
+ description: {
339
+ story: 'Free scrolling mode where users can drag freely without snapping to slides.',
340
+ },
341
+ },
342
+ },
343
+ };
344
+
345
+ // Centered slides
346
+ export const CenteredSlides = {
347
+ args: {
348
+ cards: [...cards, ...cards],
349
+ },
350
+ render: (args) => ({
351
+ components: { Carousel },
352
+ setup() {
353
+ return { args };
354
+ },
355
+ template: `
356
+ <div class="tw-p-8">
357
+ <Carousel
358
+ :cards="args.cards"
359
+ :options="{
360
+ loop: true,
361
+ centeredSlides: true,
362
+ slidesPerView: 1.5,
363
+ spaceBetween: 30,
364
+ }"
365
+ >
366
+ <template #slide="{ slide }">
367
+ <div class="tw-flex tw-flex-col tw-items-center tw-p-6 tw-bg-gradient-to-br tw-from-purple-100 tw-to-blue-100 tw-rounded-xl">
368
+ <img :src="slide.imageUrl" :alt="slide.name" class="tw-w-full tw-h-48 tw-object-contain tw-mb-4" />
369
+ <span class="tw-text-center tw-text-lg tw-font-semibold">{{ slide.name }}</span>
370
+ </div>
371
+ </template>
372
+ </Carousel>
373
+ </div>
138
374
  `,
139
- };
375
+ }),
376
+ parameters: {
377
+ docs: {
378
+ description: {
379
+ story: 'Carousel with centered active slide and partial view of adjacent slides.',
380
+ },
381
+ },
382
+ },
140
383
  };
141
384
 
142
- export const SampleMultiple = () => {
143
- return {
385
+ // Multiple carousels on same page
386
+ export const MultipleCarousels = {
387
+ render: () => ({
144
388
  components: { Carousel },
145
- data() {
389
+ setup() {
146
390
  return {
147
- carouselProps,
148
391
  cards,
149
392
  swiperOne: {
150
393
  options: {
394
+ loop: true,
151
395
  navigation: {
152
- prevEl: `.carousel__button-prev--1`,
153
- nextEl: `.carousel__button-next--1`,
396
+ prevEl: '.carousel__button-prev--1',
397
+ nextEl: '.carousel__button-next--1',
154
398
  },
155
399
  pagination: {
156
- el: `.pagination--1`,
400
+ el: '.pagination--1',
157
401
  },
158
402
  },
159
403
  navigationUniqueIndexer: '1',
160
404
  },
161
405
  swiperTwo: {
162
406
  options: {
407
+ loop: true,
163
408
  navigation: {
164
- prevEl: `.carousel__button-prev--2`,
165
- nextEl: `.carousel__button-next--2`,
409
+ prevEl: '.carousel__button-prev--2',
410
+ nextEl: '.carousel__button-next--2',
166
411
  },
167
412
  pagination: {
168
- el: `.pagination--2`,
413
+ el: '.pagination--2',
169
414
  },
170
415
  },
171
416
  navigationUniqueIndexer: '2',
172
417
  },
173
418
  };
174
419
  },
175
- methods: {
176
- alert(slide) {
177
- // eslint-disable-next-line no-alert
178
- alert(`You have clicked the ${slide.name} slide`);
179
- },
180
- },
181
420
  template: `
182
- <div>
183
- <h1 class="tw-w-full tw-text-center">Have a look at the configuration of this story if you need multiple carousels on the same page.</h1>
184
- <div class="tw-flex tw-flex-col tw-justify-center tw-mx-8">
185
- <div class="tw-w-full tw-flex tw-items-center tw-justify-center">
186
- <div class="tw-w-1/2 md:tw-w-1/6">
187
- <Carousel
421
+ <div class="tw-p-8 tw-space-y-12">
422
+ <div>
423
+ <h3 class="tw-text-xl tw-font-bold tw-mb-4 tw-text-center">First Carousel</h3>
424
+ <div class="tw-max-w-md tw-mx-auto">
425
+ <Carousel
188
426
  :cards="cards"
189
427
  :show-bullets="true"
190
428
  :swiper-ref="swiperOne.navigationUniqueIndexer"
191
429
  :navigation-unique-indexer="swiperOne.navigationUniqueIndexer"
192
430
  :options="swiperOne.options"
193
- @on-slide-click="alert"
194
- >
195
- <template #slide="{ slide }">
196
- <div class="tw-flex tw-flex-col tw-items-center tw-cursor-pointer">
197
- <img :src="slide.imageUrl" :alt="slide.name" class="tw-w-full" />
198
- <span>{{ slide.name }}</span>
199
- </div>
200
- </template>
201
- </Carousel>
202
- </div>
431
+ >
432
+ <template #slide="{ slide }">
433
+ <div class="tw-flex tw-flex-col tw-items-center tw-p-4 tw-bg-blue-50 tw-rounded-lg">
434
+ <img :src="slide.imageUrl" :alt="slide.name" class="tw-w-full tw-h-40 tw-object-contain tw-mb-2" />
435
+ <span class="tw-text-center tw-font-medium">{{ slide.name }}</span>
436
+ </div>
437
+ </template>
438
+ </Carousel>
203
439
  </div>
204
- <div class="tw-w-full tw-flex tw-items-center tw-justify-center">
205
- <div class="tw-w-1/2 md:tw-w-1/6">
206
- <Carousel
440
+ </div>
441
+
442
+ <div>
443
+ <h3 class="tw-text-xl tw-font-bold tw-mb-4 tw-text-center">Second Carousel</h3>
444
+ <div class="tw-max-w-md tw-mx-auto">
445
+ <Carousel
207
446
  :cards="cards"
208
447
  :show-bullets="true"
209
448
  :swiper-ref="swiperTwo.navigationUniqueIndexer"
210
449
  :navigation-unique-indexer="swiperTwo.navigationUniqueIndexer"
211
450
  :options="swiperTwo.options"
212
- @on-slide-click="alert"
213
- >
214
- <template #slide="{ slide }">
215
- <div class="tw-flex tw-flex-col tw-items-center tw-cursor-pointer">
216
- <img :src="slide.imageUrl" :alt="slide.name" class="tw-w-full" />
217
- <span>{{ slide.name }}</span>
218
- </div>
219
- </template>
220
- </Carousel>
221
- </div>
451
+ >
452
+ <template #slide="{ slide }">
453
+ <div class="tw-flex tw-flex-col tw-items-center tw-p-4 tw-bg-green-50 tw-rounded-lg">
454
+ <img :src="slide.imageUrl" :alt="slide.name" class="tw-w-full tw-h-40 tw-object-contain tw-mb-2" />
455
+ <span class="tw-text-center tw-font-medium">{{ slide.name }}</span>
456
+ </div>
457
+ </template>
458
+ </Carousel>
222
459
  </div>
223
460
  </div>
224
461
  </div>
225
462
  `,
226
- };
463
+ }),
464
+ parameters: {
465
+ docs: {
466
+ description: {
467
+ story:
468
+ 'Example of multiple independent carousels on the same page. Each requires unique navigationUniqueIndexer.',
469
+ },
470
+ },
471
+ },
227
472
  };
228
473
 
229
- export const FreeMode = () => {
230
- return {
231
- components: { Carousel, Icon },
232
- data() {
233
- return {
234
- carouselProps,
235
- cards: [...cards, ...cards, ...cards],
236
- options: {
237
- loop: false,
238
- spaceBetween: 30,
239
- freeMode: true,
240
- slidesPerView: 'auto',
241
- },
242
- };
474
+ // Responsive breakpoints demo
475
+ export const ResponsiveBreakpoints = {
476
+ args: {
477
+ cards: [...cards, ...cards],
478
+ },
479
+ render: (args) => ({
480
+ components: { Carousel },
481
+ setup() {
482
+ return { args };
243
483
  },
244
484
  template: `
245
- <Carousel :cards="cards" :options="options">
246
- <template #arrow-left>
247
- <Icon classes="tw--mb-1 tw-ml-4 tw-cursor-pointer" name="chevron-left" size="4xl" />
248
- </template>
485
+ <div class="tw-p-8">
486
+ <div class="tw-mb-4 tw-p-4 tw-bg-blue-50 tw-rounded-lg">
487
+ <p class="tw-text-sm tw-font-semibold tw-mb-2">Responsive behavior:</p>
488
+ <ul class="tw-text-sm tw-space-y-1">
489
+ <li>• Mobile (< 640px): 1 slide</li>
490
+ <li>• Tablet (640px - 1023px): 2 slides</li>
491
+ <li>• Desktop (≥ 1024px): 4 slides</li>
492
+ </ul>
493
+ </div>
494
+ <Carousel
495
+ :cards="args.cards"
496
+ :options="{
497
+ loop: true,
498
+ spaceBetween: 20,
499
+ slidesPerView: 1,
500
+ slidesPerGroup: 1,
501
+ breakpoints: {
502
+ 640: {
503
+ slidesPerView: 2,
504
+ slidesPerGroup: 2,
505
+ },
506
+ 1024: {
507
+ slidesPerView: 4,
508
+ slidesPerGroup: 4,
509
+ },
510
+ },
511
+ }"
512
+ >
249
513
  <template #slide="{ slide }">
250
- <div class="tw-flex tw-flex-col tw-items-center">
251
- <img :src="slide.imageUrl" :alt="slide.name" class="tw-w-20" />
252
- <span>{{ slide.name }}</span>
514
+ <div class="tw-flex tw-flex-col tw-items-center tw-p-4 tw-bg-white tw-border tw-border-gray-200 tw-rounded-lg">
515
+ <img :src="slide.imageUrl" :alt="slide.name" class="tw-w-full tw-h-32 tw-object-contain tw-mb-2" />
516
+ <span class="tw-text-center tw-text-sm tw-font-medium">{{ slide.name }}</span>
253
517
  </div>
254
518
  </template>
255
- <template #arrow-right>
256
- <Icon classes="tw--mb-1 tw-ml-4 tw-cursor-pointer" name="chevron-right" size="4xl" />
257
- </template>
258
519
  </Carousel>
520
+ </div>
259
521
  `,
260
- };
522
+ }),
523
+ parameters: {
524
+ docs: {
525
+ description: {
526
+ story: 'Demonstrates responsive behavior with different numbers of slides at different screen sizes.',
527
+ },
528
+ },
529
+ },
261
530
  };