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

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 (37) hide show
  1. package/.storybook/main.ts +4 -5
  2. package/.storybook/preview.js +0 -1
  3. package/dist/css/tailwind-brandCrowd.css +6 -0
  4. package/dist/css/tailwind-brandPage.css +6 -0
  5. package/dist/css/tailwind-crazyDomains.css +6 -0
  6. package/dist/css/tailwind-designCom.css +6 -0
  7. package/dist/css/tailwind-designCrowd.css +6 -0
  8. package/index.js +1 -1
  9. package/package.json +10 -10
  10. package/src/atoms/components/Carousel/Carousel.fixtures.js +0 -18
  11. package/src/atoms/components/Carousel/carousel.stories.js +179 -448
  12. package/src/atoms/components/Icon/Icon.stories.js +3 -0
  13. package/src/atoms/components/Icon/Icon.vue +6 -0
  14. package/src/atoms/components/Icon/icons/badge.vue +8 -0
  15. package/src/atoms/components/Icon/icons/briefcase.vue +7 -0
  16. package/src/atoms/components/Icon/icons/clipboard-check.vue +7 -0
  17. package/src/atoms/components/Price/Price.vue +5 -5
  18. package/src/atoms/components/SparkleIcon/SparkleIcon.stories.js +182 -0
  19. package/src/atoms/components/SparkleIcon/SparkleIcon.vue +105 -0
  20. package/src/atoms/components/SparkleIcon/assets/animations/state-01.svg +5 -0
  21. package/src/atoms/components/SparkleIcon/assets/animations/state-02.svg +5 -0
  22. package/src/atoms/components/SparkleIcon/assets/animations/state-03.svg +5 -0
  23. package/src/atoms/components/SparkleIcon/assets/animations/state-04.svg +5 -0
  24. package/src/atoms/components/SparkleIcon/assets/animations/state-05.svg +5 -0
  25. package/src/atoms/components/SparkleIcon/assets/animations/state-06.svg +5 -0
  26. package/src/atoms/components/SparkleIcon/assets/animations/state-07.svg +5 -0
  27. package/src/atoms/components/SparkleIcon/assets/animations/state-08.svg +5 -0
  28. package/src/atoms/components/SparkleIcon/assets/sparkle.svg +3 -0
  29. package/src/atoms/components/SparkleIcon/index.ts +3 -0
  30. package/tailwind.config.js +8 -7
  31. package/public/css/tailwind-brandCrowd.css +0 -2472
  32. package/public/css/tailwind-brandPage.css +0 -2156
  33. package/public/css/tailwind-crazyDomains.css +0 -2472
  34. package/public/css/tailwind-designCom.css +0 -2472
  35. package/public/css/tailwind-designCrowd.css +0 -2472
  36. package/src/atoms/components/PromoCard/PromoCard.stories.ts +0 -265
  37. package/src/atoms/components/PromoCard/PromoCard.vue +0 -89
@@ -1,530 +1,261 @@
1
- import Icon from '../Icon/Icon.vue';
2
- import { cards } from './Carousel.fixtures';
3
1
  import Carousel from './Carousel.vue';
2
+ import Icon from '../Icon/Icon.vue';
3
+ import { carouselProps, cards } from './Carousel.fixtures';
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
- },
75
8
  };
76
9
 
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) => ({
10
+ export const Sample = () => {
11
+ return {
102
12
  components: { Carousel },
103
- setup() {
104
- return { args };
105
- },
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 };
144
- },
145
- template: `
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>
162
- `,
163
- }),
164
- parameters: {
165
- docs: {
166
- description: {
167
- story: 'Display one slide at a time with navigation controls.',
168
- },
13
+ data() {
14
+ return {
15
+ carouselProps,
16
+ cards,
17
+ };
169
18
  },
170
- },
171
- };
172
-
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,
19
+ methods: {
20
+ alert(e) {
21
+ // eslint-disable-next-line no-alert
22
+ alert(`You have clicked the "${e.slide.name}" slide`);
184
23
  },
185
24
  },
186
- },
187
- render: (args) => ({
188
- components: { Carousel },
189
- setup() {
190
- return { args };
191
- },
192
25
  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>
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>
208
40
  `,
209
- }),
210
- parameters: {
211
- docs: {
212
- description: {
213
- story: 'Auto-playing carousel without navigation arrows. Uses only pagination bullets for navigation.',
214
- },
215
- },
216
- },
41
+ };
217
42
  };
218
43
 
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) => ({
44
+ export const CarouselDotsHidden = () => {
45
+ return {
232
46
  components: { Carousel },
233
- setup() {
234
- return { args };
47
+ data() {
48
+ return {
49
+ carouselProps,
50
+ cards,
51
+ };
235
52
  },
236
- template: `
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>
252
- `,
253
- }),
254
- parameters: {
255
- docs: {
256
- description: {
257
- story: 'Carousel with arrow controls only, no pagination bullets.',
53
+ methods: {
54
+ alert(e) {
55
+ // eslint-disable-next-line no-alert
56
+ alert(`You have clicked the "${e.slide.name}" slide`);
258
57
  },
259
58
  },
260
- },
261
- };
262
-
263
- // Custom arrow styling
264
- export const CustomArrows = {
265
- args: {
266
- cards,
267
- },
268
- render: (args) => ({
269
- components: { Carousel, Icon },
270
- setup() {
271
- return { args };
272
- },
273
59
  template: `
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>
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>
294
72
  `,
295
- }),
296
- parameters: {
297
- docs: {
298
- description: {
299
- story: 'Carousel with custom-styled navigation arrows using the arrow slots.',
300
- },
301
- },
302
- },
73
+ };
303
74
  };
304
75
 
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 };
76
+ export const CustomArrows = () => {
77
+ return {
78
+ components: { Carousel, Icon },
79
+ data() {
80
+ return {
81
+ carouselProps,
82
+ cards,
83
+ };
314
84
  },
315
85
  template: `
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>
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>
334
100
  `,
335
- }),
336
- parameters: {
337
- docs: {
338
- description: {
339
- story: 'Free scrolling mode where users can drag freely without snapping to slides.',
340
- },
341
- },
342
- },
101
+ };
343
102
  };
344
103
 
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 };
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
+ };
354
122
  },
355
123
  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>
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>
374
138
  `,
375
- }),
376
- parameters: {
377
- docs: {
378
- description: {
379
- story: 'Carousel with centered active slide and partial view of adjacent slides.',
380
- },
381
- },
382
- },
139
+ };
383
140
  };
384
141
 
385
- // Multiple carousels on same page
386
- export const MultipleCarousels = {
387
- render: () => ({
142
+ export const SampleMultiple = () => {
143
+ return {
388
144
  components: { Carousel },
389
- setup() {
145
+ data() {
390
146
  return {
147
+ carouselProps,
391
148
  cards,
392
149
  swiperOne: {
393
150
  options: {
394
- loop: true,
395
151
  navigation: {
396
- prevEl: '.carousel__button-prev--1',
397
- nextEl: '.carousel__button-next--1',
152
+ prevEl: `.carousel__button-prev--1`,
153
+ nextEl: `.carousel__button-next--1`,
398
154
  },
399
155
  pagination: {
400
- el: '.pagination--1',
156
+ el: `.pagination--1`,
401
157
  },
402
158
  },
403
159
  navigationUniqueIndexer: '1',
404
160
  },
405
161
  swiperTwo: {
406
162
  options: {
407
- loop: true,
408
163
  navigation: {
409
- prevEl: '.carousel__button-prev--2',
410
- nextEl: '.carousel__button-next--2',
164
+ prevEl: `.carousel__button-prev--2`,
165
+ nextEl: `.carousel__button-next--2`,
411
166
  },
412
167
  pagination: {
413
- el: '.pagination--2',
168
+ el: `.pagination--2`,
414
169
  },
415
170
  },
416
171
  navigationUniqueIndexer: '2',
417
172
  },
418
173
  };
419
174
  },
175
+ methods: {
176
+ alert(slide) {
177
+ // eslint-disable-next-line no-alert
178
+ alert(`You have clicked the ${slide.name} slide`);
179
+ },
180
+ },
420
181
  template: `
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
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
426
188
  :cards="cards"
427
189
  :show-bullets="true"
428
190
  :swiper-ref="swiperOne.navigationUniqueIndexer"
429
191
  :navigation-unique-indexer="swiperOne.navigationUniqueIndexer"
430
192
  :options="swiperOne.options"
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>
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>
439
203
  </div>
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
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
446
207
  :cards="cards"
447
208
  :show-bullets="true"
448
209
  :swiper-ref="swiperTwo.navigationUniqueIndexer"
449
210
  :navigation-unique-indexer="swiperTwo.navigationUniqueIndexer"
450
211
  :options="swiperTwo.options"
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>
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>
459
222
  </div>
460
223
  </div>
461
224
  </div>
462
225
  `,
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
- },
226
+ };
472
227
  };
473
228
 
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 };
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
+ };
483
243
  },
484
244
  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
- >
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>
513
249
  <template #slide="{ slide }">
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>
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>
517
253
  </div>
518
254
  </template>
255
+ <template #arrow-right>
256
+ <Icon classes="tw--mb-1 tw-ml-4 tw-cursor-pointer" name="chevron-right" size="4xl" />
257
+ </template>
519
258
  </Carousel>
520
- </div>
521
259
  `,
522
- }),
523
- parameters: {
524
- docs: {
525
- description: {
526
- story: 'Demonstrates responsive behavior with different numbers of slides at different screen sizes.',
527
- },
528
- },
529
- },
260
+ };
530
261
  };