srcdev-nuxt-components 9.3.6 → 9.3.8

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 (126) hide show
  1. package/.claude/hooks/check-component-update.sh +30 -1
  2. package/.claude/skills/components/accordian-core.md +7 -7
  3. package/.claude/skills/components/breadcrumb.md +49 -0
  4. package/.claude/skills/components/content-docs.md +2 -1
  5. package/.claude/skills/components/expanding-panel.md +5 -5
  6. package/.claude/skills/components/navigation-items.md +1 -0
  7. package/.claude/skills/components/responsive-header.md +1 -0
  8. package/.claude/skills/components/service-detail.md +156 -0
  9. package/.claude/skills/components/services-card-grid.md +9 -9
  10. package/.claude/skills/components/services-card.md +82 -30
  11. package/.claude/skills/index.md +3 -1
  12. package/.claude/skills/qa-panel.md +2 -2
  13. package/.vscode/srcdev-component-breadcrumb.code-snippets +14 -0
  14. package/.vscode/srcdev-component-service-detail.code-snippets +49 -0
  15. package/.vscode/srcdev-component-services-card.code-snippets +108 -0
  16. package/app/components/01.atoms/content-wrappers/docs-pages/ContentDocs.vue +22 -16
  17. package/app/components/01.atoms/navigation/breadcrumb/Breadcrumb.vue +94 -0
  18. package/app/components/01.atoms/navigation/breadcrumb/CONSUMER-STYLING.md +32 -0
  19. package/app/components/01.atoms/navigation/breadcrumb/stories/Breadcrumb.stories.ts +87 -0
  20. package/app/components/01.atoms/navigation/breadcrumb/tests/Breadcrumb.spec.ts +87 -0
  21. package/app/components/01.atoms/navigation/breadcrumb/tests/__snapshots__/Breadcrumb.spec.ts.snap +13 -0
  22. package/app/components/02.molecules/expandable/accordian/AccordianCore.vue +5 -1
  23. package/app/components/02.molecules/expandable/accordian/tests/AccordianCore.spec.ts +22 -14
  24. package/app/components/02.molecules/expandable/accordian/tests/__snapshots__/AccordianCore.spec.ts.snap +42 -28
  25. package/app/components/02.molecules/expandable/expanding-panel/CONSUMER-STYLING.md +8 -10
  26. package/app/components/02.molecules/expandable/expanding-panel/ExpandingPanel.vue +15 -47
  27. package/app/components/02.molecules/expandable/expanding-panel/tests/__snapshots__/ExpandingPanel.spec.ts.snap +4 -12
  28. package/app/components/03.organisms/responsive-header/NavigationItems.vue +91 -4
  29. package/app/components/03.organisms/responsive-header/ResponsiveHeader.vue +5 -1
  30. package/app/components/03.organisms/responsive-header/tests/NavigationItems.spec.ts +2 -2
  31. package/app/components/03.organisms/responsive-header/tests/__snapshots__/NavigationItems.spec.ts.snap +13 -13
  32. package/app/components/03.organisms/responsive-header/tests/__snapshots__/ResponsiveHeader.spec.ts.snap +13 -13
  33. package/app/components/03.organisms/services/service-detail/CONSUMER-STYLING.md +181 -0
  34. package/app/components/03.organisms/services/service-detail/ServiceDetail.vue +480 -0
  35. package/app/components/03.organisms/services/service-detail/stories/ServiceDetail.stories.ts +282 -0
  36. package/app/components/03.organisms/services/service-detail/tests/ServiceDetail.spec.ts +270 -0
  37. package/app/components/03.organisms/services/service-detail/tests/__snapshots__/ServiceDetail.spec.ts.snap +99 -0
  38. package/app/components/03.organisms/services/services-card/CONSUMER-STYLING.md +129 -0
  39. package/app/components/03.organisms/services/services-card/ServicesCard.vue +153 -39
  40. package/app/components/03.organisms/services/services-card/stories/ServicesCard.stories.ts +65 -0
  41. package/app/components/03.organisms/services/services-card/tests/ServicesCard.spec.ts +82 -0
  42. package/app/components/03.organisms/services/services-card/tests/__snapshots__/ServicesCard.spec.ts.snap +13 -5
  43. package/app/components/03.organisms/services/services-grids/ServicesCardGrid.vue +3 -7
  44. package/app/components/03.organisms/services/services-grids/stories/ServicesCardGrid.stories.ts +126 -2
  45. package/app/components/03.organisms/services/services-grids/stories/ServicesSectionGrid.stories.ts +6 -0
  46. package/app/components/03.organisms/services/services-grids/tests/__snapshots__/ServicesCardGrid.spec.ts.snap +51 -27
  47. package/app/components/03.organisms/services/services-section/ServicesSection.vue +19 -0
  48. package/app/components/03.organisms/services/services-section/tests/__snapshots__/ServicesSection.spec.ts.snap +8 -8
  49. package/app/types/components/breadcrumb.ts +4 -0
  50. package/app/types/components/index.ts +1 -0
  51. package/package.json +2 -2
  52. package/app/pages/auto-grid.vue +0 -328
  53. package/app/pages/banner-video.vue +0 -238
  54. package/app/pages/forms/examples/buttons/index.vue +0 -259
  55. package/app/pages/forms/examples/material/checkbox-radio-panels.vue +0 -244
  56. package/app/pages/forms/examples/material/cssbattle.vue +0 -60
  57. package/app/pages/forms/examples/material/text-fields.vue +0 -910
  58. package/app/pages/grid-stack.vue +0 -252
  59. package/app/pages/index.vue +0 -127
  60. package/app/pages/page-hero-highlights.vue +0 -204
  61. package/app/pages/samaritan.vue +0 -327
  62. package/app/pages/typography/hero-text.vue +0 -97
  63. package/app/pages/typography/index.vue +0 -39
  64. package/app/pages/typography/page-body.vue +0 -171
  65. package/app/pages/typography/page-heading.vue +0 -76
  66. package/app/pages/typography/page-link.vue +0 -103
  67. package/app/pages/ui/accordian.vue +0 -211
  68. package/app/pages/ui/anchor-scroll-tab-navigation.vue +0 -191
  69. package/app/pages/ui/anchor-scroll.vue +0 -367
  70. package/app/pages/ui/animated-svg-text.vue +0 -85
  71. package/app/pages/ui/block-decorators.vue +0 -142
  72. package/app/pages/ui/card-core.vue +0 -82
  73. package/app/pages/ui/carousel-basic.vue +0 -292
  74. package/app/pages/ui/carousel-flip.vue +0 -449
  75. package/app/pages/ui/carousel-infinite.vue +0 -260
  76. package/app/pages/ui/clipped-panels.vue +0 -101
  77. package/app/pages/ui/contact-section.vue +0 -323
  78. package/app/pages/ui/container-glow.vue +0 -106
  79. package/app/pages/ui/content-width.vue +0 -126
  80. package/app/pages/ui/deep-expanding-menu.vue +0 -138
  81. package/app/pages/ui/display-avatar.vue +0 -253
  82. package/app/pages/ui/display-banner.vue +0 -78
  83. package/app/pages/ui/display-chip.vue +0 -367
  84. package/app/pages/ui/display-details.vue +0 -171
  85. package/app/pages/ui/display-dialog.vue +0 -344
  86. package/app/pages/ui/display-pill.vue +0 -396
  87. package/app/pages/ui/display-prompt.vue +0 -284
  88. package/app/pages/ui/display-toast.vue +0 -311
  89. package/app/pages/ui/expanding-panel.vue +0 -326
  90. package/app/pages/ui/glowing-border.vue +0 -111
  91. package/app/pages/ui/layout-content-docs.vue +0 -72
  92. package/app/pages/ui/layout-grid-a.vue +0 -96
  93. package/app/pages/ui/layout-grid-b.vue +0 -132
  94. package/app/pages/ui/magnetic-navigation.vue +0 -50
  95. package/app/pages/ui/marquee-scroller.vue +0 -99
  96. package/app/pages/ui/mask-element.vue +0 -104
  97. package/app/pages/ui/masonry-columns.vue +0 -55
  98. package/app/pages/ui/masonry-grid-ordered-experiment.vue +0 -79
  99. package/app/pages/ui/masonry-grid-ordered.vue +0 -56
  100. package/app/pages/ui/masonry-grid-sorted.vue +0 -55
  101. package/app/pages/ui/masonry-grid.vue +0 -55
  102. package/app/pages/ui/navigation/navigation-horizontal.vue +0 -484
  103. package/app/pages/ui/navigation/site-navigation/about.vue +0 -36
  104. package/app/pages/ui/navigation/site-navigation/contact.vue +0 -39
  105. package/app/pages/ui/navigation/site-navigation/index.vue +0 -38
  106. package/app/pages/ui/navigation/site-navigation/portfolio.vue +0 -43
  107. package/app/pages/ui/navigation/site-navigation/services.vue +0 -42
  108. package/app/pages/ui/navigation/tab-navigation.vue +0 -493
  109. package/app/pages/ui/page-row.vue +0 -127
  110. package/app/pages/ui/price-list.vue +0 -65
  111. package/app/pages/ui/profile-section.vue +0 -142
  112. package/app/pages/ui/qr-code/[componentName].vue +0 -218
  113. package/app/pages/ui/rotating-carousel.vue +0 -154
  114. package/app/pages/ui/scroll-reveal-image.vue +0 -483
  115. package/app/pages/ui/section-parallax.vue +0 -54
  116. package/app/pages/ui/services/colour-finder.vue +0 -43
  117. package/app/pages/ui/services/services-cards.vue +0 -57
  118. package/app/pages/ui/services/services-section/[slug].vue +0 -61
  119. package/app/pages/ui/services/services-sections-compact.vue +0 -64
  120. package/app/pages/ui/settings.vue +0 -54
  121. package/app/pages/ui/simple-grid.vue +0 -55
  122. package/app/pages/ui/slider-gallery.vue +0 -261
  123. package/app/pages/ui/tabs-y.vue +0 -107
  124. package/app/pages/ui/tabs.vue +0 -189
  125. package/app/pages/ui/tooltips.vue +0 -104
  126. package/app/pages/ui/wipe-away-vertical.vue +0 -129
@@ -1,449 +0,0 @@
1
- <template>
2
- <div>
3
- <NuxtLayout name="default">
4
- <template #layout-content>
5
- <PageRow tag="div" variant="content" :style-class-passthrough="['mbe-20']">
6
- <h1 class="page-heading-2">Carousel</h1>
7
- </PageRow>
8
-
9
- <!-- ── QA Panel (dev only) ───────────────────────────────── -->
10
- <div v-if="isDev" class="qa-panel">
11
- <details class="qa-panel__details">
12
- <summary class="qa-panel__summary">
13
- <span class="qa-panel__title">QA — CarouselFlip</span>
14
- <code class="qa-panel__status">
15
- overflow:{{ qaAllowOverflow ? "on" : "off" }} · speed:{{ qaTransitionSpeed }}ms · flip:{{
16
- qaUseFlipAnimation ? "on" : "off"
17
- }}
18
- · spring:{{ qaUseSpringEffect ? "on" : "off" }} · {{ qaButtonLayout }} · controls:{{
19
- qaShowControls ? "on" : "off"
20
- }}
21
- </code>
22
- </summary>
23
- <div class="qa-panel__body">
24
- <div class="qa-panel__group">
25
- <span class="qa-panel__label">Allow Overflow</span>
26
- <div class="qa-panel__chips">
27
- <button
28
- v-for="opt in [true, false]"
29
- :key="String(opt)"
30
- class="qa-panel__chip"
31
- :class="{ 'is-active': qaAllowOverflow === opt }"
32
- @click="qaAllowOverflow = opt"
33
- >
34
- {{ opt ? "on" : "off" }}
35
- </button>
36
- </div>
37
- </div>
38
- <div class="qa-panel__group">
39
- <span class="qa-panel__label">Transition Speed</span>
40
- <div class="qa-panel__chips">
41
- <button
42
- v-for="preset in transitionSpeedPresets"
43
- :key="preset"
44
- class="qa-panel__chip"
45
- :class="{ 'is-active': qaTransitionSpeed === preset }"
46
- @click="qaTransitionSpeed = preset"
47
- >
48
- {{ preset }}ms
49
- </button>
50
- </div>
51
- </div>
52
- <div class="qa-panel__group">
53
- <span class="qa-panel__label">Flip Animation</span>
54
- <div class="qa-panel__chips">
55
- <button
56
- v-for="opt in [true, false]"
57
- :key="String(opt)"
58
- class="qa-panel__chip"
59
- :class="{ 'is-active': qaUseFlipAnimation === opt }"
60
- @click="qaUseFlipAnimation = opt"
61
- >
62
- {{ opt ? "on" : "off" }}
63
- </button>
64
- </div>
65
- </div>
66
- <div class="qa-panel__group">
67
- <span class="qa-panel__label">Spring Effect</span>
68
- <div class="qa-panel__chips">
69
- <button
70
- v-for="opt in [true, false]"
71
- :key="String(opt)"
72
- class="qa-panel__chip"
73
- :class="{ 'is-active': qaUseSpringEffect === opt }"
74
- @click="qaUseSpringEffect = opt"
75
- >
76
- {{ opt ? "on" : "off" }}
77
- </button>
78
- </div>
79
- </div>
80
- <div class="qa-panel__group">
81
- <span class="qa-panel__label">Button Layout</span>
82
- <div class="qa-panel__chips">
83
- <button
84
- v-for="layout in buttonLayoutPresets"
85
- :key="layout"
86
- class="qa-panel__chip"
87
- :class="{ 'is-active': qaButtonLayout === layout }"
88
- @click="qaButtonLayout = layout"
89
- >
90
- {{ layout }}
91
- </button>
92
- </div>
93
- </div>
94
- <div class="qa-panel__group">
95
- <span class="qa-panel__label">Show Controls</span>
96
- <div class="qa-panel__chips">
97
- <button
98
- v-for="opt in [true, false]"
99
- :key="String(opt)"
100
- class="qa-panel__chip"
101
- :class="{ 'is-active': qaShowControls === opt }"
102
- @click="qaShowControls = opt"
103
- >
104
- {{ opt ? "on" : "off" }}
105
- </button>
106
- </div>
107
- </div>
108
- </div>
109
- </details>
110
- </div>
111
-
112
- <CarouselFlip
113
- v-if="carouselStatus === 'success'"
114
- :carousel-data-ids
115
- :allow-carousel-overflow="qaAllowOverflow"
116
- :transition-speed="qaTransitionSpeed"
117
- :use-flip-animation="qaUseFlipAnimation"
118
- :use-spring-effect="qaUseSpringEffect"
119
- :button-layout="qaButtonLayout"
120
- :show-controls="qaShowControls"
121
- :style-class-passthrough="['carousel-flip-demo', 'mbe-20']"
122
- >
123
- <template v-for="(item, index) in carouselData?.items" :key="index" #[item.id]>
124
- <div class="custom-carousel-item">
125
- <h3>{{ index + 1 }}</h3>
126
- <p>{{ item.alt }}</p>
127
- </div>
128
- </template>
129
- </CarouselFlip>
130
- </template>
131
- </NuxtLayout>
132
- </div>
133
- </template>
134
-
135
- <script setup lang="ts">
136
- import type { ICarouselBasic } from "~/types/components";
137
-
138
- // ── QA controls (dev only) ────────────────────────────────────────
139
- const isDev = import.meta.dev;
140
- const qaAllowOverflow = ref(true);
141
- const qaTransitionSpeed = ref(1000);
142
- const qaUseFlipAnimation = ref(true);
143
- const qaUseSpringEffect = ref(false);
144
- const qaButtonLayout = ref<"sides" | "controls-flanking" | "controls-grouped-right" | "overlay">("sides");
145
- const qaShowControls = ref(true);
146
- const transitionSpeedPresets = [100, 200, 400, 600, 1000, 2000];
147
- const buttonLayoutPresets = ["sides", "controls-flanking", "controls-grouped-right", "overlay"] as const;
148
-
149
- definePageMeta({
150
- layout: false,
151
- });
152
-
153
- useHead({
154
- title: "Carousel (Basic)",
155
- meta: [{ name: "description", content: "Examples of Carousel (Basic)" }],
156
- bodyAttrs: {
157
- class: "carousel-flip-page",
158
- },
159
- });
160
-
161
- const { data: carouselData, status: carouselStatus } = await useFetch<ICarouselBasic>("/api/carousel", {
162
- immediate: true,
163
- });
164
-
165
- const carouselDataIds = computed(() => {
166
- return carouselData.value?.items.map((item) => item.id) || [];
167
- });
168
- </script>
169
-
170
- <style lang="css">
171
- .carousel-flip-page {
172
- /* ── QA Panel ──────────────────────────────────────────────────── */
173
-
174
- .qa-panel {
175
- background: oklch(15% 0 0);
176
- color: white;
177
- font-size: 1.3rem;
178
- }
179
-
180
- .qa-panel__details {
181
- padding: 1rem 2rem;
182
- }
183
-
184
- .qa-panel__summary {
185
- cursor: pointer;
186
- display: flex;
187
- align-items: center;
188
- gap: 1.6rem;
189
- list-style: none;
190
- user-select: none;
191
-
192
- &::-webkit-details-marker {
193
- display: none;
194
- }
195
- }
196
-
197
- .qa-panel__title {
198
- font-weight: 600;
199
- font-size: 1.1rem;
200
- text-transform: uppercase;
201
- letter-spacing: 0.08em;
202
- }
203
-
204
- .qa-panel__status {
205
- font-family: monospace;
206
- font-size: 1.2rem;
207
- background: oklch(0% 0 0 / 0.3);
208
- padding: 0.2rem 0.8rem;
209
- border-radius: 0.4rem;
210
- user-select: text;
211
- cursor: text;
212
- }
213
-
214
- .qa-panel__body {
215
- display: flex;
216
- flex-wrap: wrap;
217
- gap: 2.4rem;
218
- padding-block: 1.2rem 0.4rem;
219
- }
220
-
221
- .qa-panel__group {
222
- display: flex;
223
- flex-direction: column;
224
- gap: 0.6rem;
225
- }
226
-
227
- .qa-panel__label {
228
- font-size: 1.1rem;
229
- text-transform: uppercase;
230
- letter-spacing: 0.08em;
231
- opacity: 0.55;
232
- }
233
-
234
- .qa-panel__chips {
235
- display: flex;
236
- flex-wrap: wrap;
237
- gap: 0.4rem;
238
- }
239
-
240
- .qa-panel__chip {
241
- font-family: monospace;
242
- font-size: 1.2rem;
243
- color: white;
244
- background: oklch(0% 0 0 / 0.25);
245
- border: 1px solid oklch(100% 0 0 / 0.18);
246
- padding: 0.3rem 1rem;
247
- border-radius: 0.4rem;
248
- cursor: pointer;
249
- transition: background 0.15s;
250
-
251
- &:hover {
252
- background: oklch(0% 0 0 / 0.4);
253
- }
254
-
255
- &.is-active {
256
- background: oklch(55% 0.18 240);
257
- border-color: oklch(55% 0.18 240);
258
- }
259
- }
260
- }
261
-
262
- @property --glow-deg {
263
- syntax: "<angle>";
264
- inherits: true;
265
- initial-value: -90deg;
266
- }
267
-
268
- @keyframes glow {
269
- 100% {
270
- --glow-deg: 270deg;
271
- }
272
- }
273
-
274
- .carousel-flip-demo {
275
- &.carousel-flip {
276
- /* Var used in calcs */
277
- --_carousel-item-track-gap: 12px;
278
- --_carousel-container-max-inline-size: 800px;
279
- --_carousel-item-edge-preview-width: 12px; /* Must be at 2x var(--_carousel-item-track-gap) */
280
-
281
- @media (width >= 768px) {
282
- --_carousel-item-track-gap: 24px;
283
- --_carousel-item-edge-preview-width: 80px; /* Must be at 2x var(--_carousel-item-track-gap) */
284
- }
285
-
286
- .item-container {
287
- max-inline-size: 800px;
288
- margin-inline: auto;
289
-
290
- outline: 1px solid light-dark(var(--slate-08), var(--slate-01));
291
- padding-block: 6px;
292
- padding-inline: 6px;
293
-
294
- @media (width >= 768px) {
295
- padding-block: 12px;
296
- padding-inline: 12px;
297
- }
298
-
299
- .item {
300
- background-color: light-dark(var(--slate-05), var(--slate-06));
301
- contain: layout style paint;
302
-
303
- &:nth-child(odd) {
304
- background-color: light-dark(var(--slate-06), var(--slate-05));
305
- }
306
-
307
- .custom-carousel-item {
308
- flex-direction: column;
309
- align-items: center;
310
- justify-content: center;
311
-
312
- aspect-ratio: 4 / 3;
313
- inline-size: 100%;
314
-
315
- color: light-dark(#aaa, #333);
316
- padding-block: 10px;
317
- padding-inline: 10px;
318
- border-radius: 4px;
319
- outline: 1px solid light-dark(#00000090, #f00ff090);
320
- }
321
- }
322
- }
323
-
324
- .controls-container {
325
- gap: 20px;
326
- max-inline-size: 800px;
327
-
328
- .markers-container {
329
- --marker-height: 12px;
330
- --marker-width: 12px;
331
- --marker-border-radius: 100vw;
332
-
333
- @media (width >= 768px) {
334
- --marker-height: 22px;
335
- --marker-width: 22px;
336
- }
337
-
338
- .markers-list {
339
- .markers-item {
340
- width: var(--marker-width);
341
- height: var(--marker-height);
342
- border-radius: var(--marker-border-radius);
343
- line-height: var(--marker-height);
344
-
345
- .btn-marker {
346
- width: var(--marker-width);
347
- height: var(--marker-height);
348
- border-radius: var(--marker-border-radius);
349
- background-color: light-dark(var(--slate-05), var(--slate-07));
350
- line-height: 3px;
351
- transition: all 0.3s linear;
352
- border: 1px solid transparent;
353
- outline: 1px solid transparent;
354
-
355
- &.active {
356
- background-color: light-dark(var(--slate-10), var(--slate-00));
357
- will-change: background-color;
358
- }
359
-
360
- &:hover,
361
- &:focus-visible {
362
- outline-color: light-dark(#000, #fff);
363
- will-change: background-color, outline-color;
364
- }
365
- }
366
- }
367
- }
368
- }
369
-
370
- .buttons-container {
371
- display: flex;
372
- align-items: center;
373
- justify-content: end;
374
- gap: 20px;
375
-
376
- .btn-action {
377
- --gradient-glow-dark:
378
- var(--slate-07), var(--slate-05), var(--slate-08), var(--slate-06), var(--slate-07), var(--slate-08),
379
- var(--slate-07);
380
- --gradient-glow-light: var(--slate-04), var(--slate-06), var(--slate-00), var(--slate-06), var(--slate-04);
381
-
382
- padding-block: 6px;
383
- padding-inline: 6px;
384
- border-radius: 100%;
385
-
386
- border: 3px solid transparent;
387
- background:
388
- linear-gradient(var(--surface, canvas) 0 0) padding-box,
389
- conic-gradient(from var(--glow-deg), var(--gradient-glow-dark)) border-box;
390
- outline: 1px solid light-dark(var(--slate-09), var(--slate-07));
391
-
392
- position: relative;
393
- isolation: isolate;
394
-
395
- animation: glow 10s infinite linear;
396
- animation-play-state: paused;
397
- transition: outline-color 0.3s ease;
398
-
399
- @media (width >= 768px) {
400
- padding-block: 10px;
401
- padding-inline: 10px;
402
- }
403
-
404
- &::before,
405
- &::after {
406
- content: "";
407
- position: absolute;
408
- border-radius: inherit;
409
- }
410
-
411
- &::before {
412
- z-index: -1;
413
- background: var(--surface, canvas);
414
- inset: 0.5rem;
415
- scale: 1.2 1;
416
- transform-origin: right;
417
- filter: blur(var(--glow-size, 0.5rem));
418
- }
419
-
420
- &::after {
421
- z-index: -2;
422
- inset: -1.5rem;
423
- background: conic-gradient(from var(--glow-deg), var(--gradient-glow-dark));
424
- filter: blur(var(--glow-size, 1rem));
425
- opacity: var(--glow-intensity, 0.125);
426
- }
427
-
428
- &:hover,
429
- &:focus-visible {
430
- animation-play-state: running;
431
- outline-color: light-dark(var(--slate-09), var(--slate-04));
432
- will-change: transform, opacity, filter;
433
- }
434
-
435
- .arrows-icon {
436
- width: 16px;
437
- height: 16px;
438
-
439
- @media (width >= 768px) {
440
- width: 24px;
441
- height: 24px;
442
- }
443
- }
444
- }
445
- }
446
- }
447
- }
448
- }
449
- </style>
@@ -1,260 +0,0 @@
1
- <template>
2
- <div>
3
- <NuxtLayout name="default">
4
- <template #layout-content>
5
- <PageRow tag="div" variant="content" :style-class-passthrough="['mbe-20']">
6
- <h1 class="page-heading-2">Carousel (Infinite)</h1>
7
- </PageRow>
8
-
9
- <PageRow tag="div" variant="popout" :style-class-passthrough="['mbe-20']">
10
- <CarouselInfinite
11
- v-if="carouselStatus === 'success'"
12
- :carousel-data-ids
13
- :allow-carousel-overflow="true"
14
- :return-to-start="false"
15
- :transition-speed="1000"
16
- :style-class-passthrough="['carousel-infinite-demo', 'mbe-20']"
17
- >
18
- <template v-for="(item, index) in carouselData?.items" #[item.id]>
19
- <div class="case-study-item">
20
- <h3>{{ index }}</h3>
21
- <p>{{ item.alt }}</p>
22
- </div>
23
- </template>
24
- </CarouselInfinite>
25
- </PageRow>
26
- </template>
27
- </NuxtLayout>
28
- </div>
29
- </template>
30
-
31
- <script setup lang="ts">
32
- import type { ICarouselBasic } from "~/types/components";
33
-
34
- definePageMeta({
35
- layout: false,
36
- });
37
-
38
- useHead({
39
- title: "Carousel (Infinite) Example",
40
- meta: [{ name: "description", content: "Examples of Carousel (Infinite)" }],
41
- bodyAttrs: {
42
- class: "carousel-infinite-example-page",
43
- },
44
- });
45
-
46
- const {
47
- data: carouselData,
48
- execute: carouselExecute,
49
- status: carouselStatus, // See v-if on CarouselBasic
50
- error: carouselError,
51
- } = await useFetch<ICarouselBasic>("/api/carousel", {
52
- immediate: true,
53
- });
54
-
55
- const carouselDataStatic = {
56
- items: [
57
- {
58
- id: 1,
59
- url: "/images/spotlights/v2/dining-out.webp",
60
- alt: "Dining out",
61
- },
62
- {
63
- id: 2,
64
- url: "/images/spotlights/v2/beer-gardens.webp",
65
- alt: "Entertaining the kids",
66
- },
67
- {
68
- id: 3,
69
- url: "/images/spotlights/v2/will-it-rain.webp",
70
- alt: "Will it rain?",
71
- },
72
- {
73
- id: 4,
74
- url: "/images/spotlights/v2/nightlife.webp",
75
- alt: "Nightlife",
76
- },
77
- {
78
- id: 5,
79
- url: "/images/spotlights/v2/got-toothache-2.webp",
80
- alt: "Dental Services",
81
- },
82
- {
83
- id: 6,
84
- url: "/images/spotlights/v2/days-out.webp",
85
- alt: "Days Out",
86
- },
87
- ],
88
- total: 6,
89
- skip: 0,
90
- limit: 4,
91
- };
92
-
93
- const carouselDataIds = computed(() => {
94
- return carouselData.value?.items.map((item) => item.id) || [];
95
- // return carouselData?.items.map((item) => item.id) || [];
96
- });
97
- </script>
98
-
99
- <style lang="css">
100
- @property --glow-deg {
101
- syntax: "<angle>";
102
- inherits: true;
103
- initial-value: -90deg;
104
- }
105
-
106
- @keyframes glow {
107
- 100% {
108
- --glow-deg: 270deg;
109
- }
110
- }
111
-
112
- .carousel-infinite-demo {
113
- &.carousel-infinite {
114
- /* Var used in calcs */
115
- --_carousel-item-track-gap: 10px;
116
-
117
- .item-container {
118
- padding-block: 10px;
119
- padding-inline: 10px;
120
- outline: 1px solid light-dark(var(--slate-06), var(--slate-05));
121
-
122
- .item {
123
- max-inline-size: 800px;
124
-
125
- background-color: light-dark(var(--slate-05), var(--slate-06));
126
-
127
- &:nth-child(odd) {
128
- background-color: light-dark(var(--slate-06), var(--slate-05));
129
- }
130
-
131
- .case-study-item {
132
- flex-direction: column;
133
- align-items: center;
134
- justify-content: center;
135
-
136
- aspect-ratio: 4 / 3;
137
- inline-size: 100%;
138
-
139
- color: light-dark(#aaa, #333);
140
- padding-block: 10px;
141
- padding-inline: 10px;
142
- border-radius: 4px;
143
- outline: 1px solid light-dark(var(--slate-06), var(--slate-05));
144
- }
145
- }
146
- }
147
-
148
- .controls-container {
149
- gap: 20px;
150
-
151
- .markers-container {
152
- .markers-list {
153
- .markers-item {
154
- line-height: 3px;
155
-
156
- &.active {
157
- background-color: light-dark(var(--slate-06), var(--slate-05));
158
- }
159
-
160
- .btn-marker {
161
- width: 22px;
162
- height: 3px;
163
- background-color: lightgray;
164
- line-height: 3px;
165
-
166
- &.active {
167
- background-color: black;
168
- }
169
-
170
- &:focus-visible {
171
- outline: 1px solid light-dark(#000, #fff);
172
- }
173
- }
174
- }
175
- }
176
- }
177
-
178
- .buttons-container {
179
- display: flex;
180
- align-items: center;
181
- justify-content: end;
182
- gap: 20px;
183
-
184
- .btn-action {
185
- --gradient-glow-dark:
186
- var(--slate-07), var(--slate-05), var(--slate-08), var(--slate-06), var(--slate-07), var(--slate-08),
187
- var(--slate-07);
188
- --gradient-glow-light: var(--slate-04), var(--slate-06), var(--slate-00), var(--slate-06), var(--slate-04);
189
-
190
- padding-block: 10px;
191
- padding-inline: 10px;
192
- border-radius: 100%;
193
- /* background-color: light-dark(#000, #fff); */
194
- /* color: light-dark(#fff, #000); */
195
-
196
- border: 3px solid transparent;
197
- background:
198
- linear-gradient(var(--surface, canvas) 0 0) padding-box,
199
- conic-gradient(from var(--glow-deg), var(--gradient-glow-dark)) border-box;
200
- outline: 1px solid light-dark(var(--slate-09), var(--slate-07));
201
-
202
- position: relative;
203
- isolation: isolate;
204
-
205
- animation: glow 10s infinite linear;
206
- animation-play-state: paused;
207
- transition: outline-color 0.3s ease;
208
-
209
- &::before,
210
- &::after {
211
- content: "";
212
- position: absolute;
213
- border-radius: inherit;
214
- }
215
-
216
- &::before {
217
- z-index: -1;
218
- background: var(--surface, canvas);
219
- inset: 0.5rem;
220
- scale: 1.2 1;
221
- transform-origin: right;
222
- filter: blur(var(--glow-size, 0.5rem));
223
- }
224
-
225
- &::after {
226
- z-index: -2;
227
- inset: -1.5rem;
228
- background: conic-gradient(from var(--glow-deg), var(--gradient-glow-dark));
229
- filter: blur(var(--glow-size, 1rem));
230
- opacity: var(--glow-intensity, 0.125);
231
- }
232
-
233
- &:hover {
234
- animation-play-state: running;
235
- outline-color: light-dark(var(--slate-09), var(--slate-04));
236
- }
237
-
238
- .arrows-icon {
239
- width: 24px;
240
- height: 24px;
241
-
242
- /* &:hover {
243
- background-color: light-dark(#0009, #fff9);
244
- }
245
-
246
- &:active,
247
- &.active {
248
- background-color: light-dark(#0009, #fff9);
249
- }
250
-
251
- &:focus-visible {
252
- outline: 1px solid light-dark(#0f0, #f0f);
253
- } */
254
- }
255
- }
256
- }
257
- }
258
- }
259
- }
260
- </style>