srcdev-nuxt-components 9.6.18 → 9.6.20
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.
- package/.claude/rules/consumer/css-relative-colour-calc.md +15 -0
- package/.claude/rules/consumer/ids-from-useid.md +3 -2
- package/.claude/rules/consumer/vue-dynamic-arg-no-spaces.md +16 -0
- package/.claude/skills/component-compliance-checklist.md +11 -1
- package/.claude/skills/component-dynamic-slots.md +2 -2
- package/.claude/skills/component-naming.md +1 -1
- package/.claude/skills/components/accordion-chat.md +99 -0
- package/.claude/skills/components/accordion-group.md +98 -0
- package/.claude/skills/components/action-menu.md +11 -5
- package/.claude/skills/components/auto-grid.md +3 -1
- package/.claude/skills/components/capture-qr-code.md +9 -5
- package/.claude/skills/components/carousel-flip.md +41 -30
- package/.claude/skills/components/column-flow-grid.md +2 -0
- package/.claude/skills/components/dashboard-quad-grid.md +7 -2
- package/.claude/skills/components/dashboard-stats-grid.md +4 -0
- package/.claude/skills/components/decode-qr-code.md +7 -2
- package/.claude/skills/components/deep-expanding-menu-classic.md +31 -30
- package/.claude/skills/components/deep-expanding-menu.md +22 -21
- package/.claude/skills/components/expanding-panel-classic.md +9 -7
- package/.claude/skills/components/expanding-panel.md +9 -8
- package/.claude/skills/components/grid-stack.md +2 -0
- package/.claude/skills/components/layout-grid-by-cols.md +2 -0
- package/.claude/skills/components/masonry-grid.md +9 -1
- package/.claude/skills/components/page-row.md +3 -0
- package/.claude/skills/components/samaritan-prompt.md +24 -8
- package/.claude/skills/components/site-header.md +16 -2
- package/.claude/skills/components/sparkle-effect.md +79 -0
- package/.claude/skills/index.md +16 -14
- package/.claude/skills/storybook-add-story.md +33 -0
- package/.claude/skills/testing-add-unit-test.md +26 -0
- package/.claude/skills/using-component-skills.md +1 -1
- package/.vscode/srcdev-component-accordion-chat.code-snippets +42 -0
- package/.vscode/srcdev-component-accordion-group.code-snippets +38 -0
- package/.vscode/srcdev-component-action-menu.code-snippets +3 -3
- package/.vscode/srcdev-component-capture-decode-qr-code.code-snippets +11 -2
- package/.vscode/srcdev-component-carousel-flip.code-snippets +22 -4
- package/.vscode/srcdev-component-deep-expanding-menu-classic.code-snippets +32 -2
- package/.vscode/srcdev-component-deep-expanding-menu.code-snippets +31 -1
- package/.vscode/srcdev-component-samaritan-prompt.code-snippets +5 -4
- package/.vscode/srcdev-component-site-header.code-snippets +13 -1
- package/.vscode/srcdev-component-sparkle-effect.code-snippets +33 -0
- package/app/components/01.atoms/animations/sparkle-effect/CONSUMER-STYLING.md +75 -0
- package/app/components/01.atoms/animations/sparkle-effect/SparkleEffect.vue +213 -0
- package/app/components/01.atoms/animations/sparkle-effect/stories/SparkleEffect.stories.ts +303 -0
- package/app/components/01.atoms/animations/sparkle-effect/tests/SparkleEffect.spec.ts +150 -0
- package/app/components/01.atoms/content-wrappers/docs-pages/ContentDocs.vue +1 -1
- package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-quad-grid/CONSUMER-STYLING.md +12 -2
- package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-quad-grid/DashboardQuadGrid.vue +19 -17
- package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-quad-grid/stories/DashboardQuadGrid.stories.ts +42 -0
- package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-quad-grid/tests/DashboardQuadGrid.spec.ts +31 -44
- package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-stats-grid/CONSUMER-STYLING.md +13 -1
- package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-stats-grid/DashboardStatsGrid.vue +40 -31
- package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-stats-grid/stories/DashboardStatsGrid.stories.ts +47 -0
- package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-stats-grid/tests/DashboardStatsGrid.spec.ts +51 -53
- package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/CONSUMER-STYLING.md +3 -0
- package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/LayoutGridByCols.vue +4 -0
- package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/stories/LayoutGridByCols.stories.ts +47 -2
- package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/tests/LayoutGridByCols.spec.ts +36 -23
- package/app/components/01.atoms/grids/auto-grid/AutoGrid.vue +7 -3
- package/app/components/01.atoms/grids/auto-grid/CONSUMER-STYLING.md +1 -1
- package/app/components/01.atoms/grids/auto-grid/stories/AutoGrid.stories.ts +46 -1
- package/app/components/01.atoms/grids/auto-grid/tests/AutoGrid.spec.ts +40 -27
- package/app/components/01.atoms/grids/auto-grid/tests/__snapshots__/AutoGrid.spec.ts.snap +1 -1
- package/app/components/01.atoms/grids/column-flow-grid/CONSUMER-STYLING.md +9 -0
- package/app/components/01.atoms/grids/column-flow-grid/ColumnFlowGrid.vue +3 -2
- package/app/components/01.atoms/grids/column-flow-grid/stories/ColumnFlowGrid.stories.ts +46 -0
- package/app/components/01.atoms/grids/column-flow-grid/tests/ColumnFlowGrid.spec.ts +24 -11
- package/app/components/01.atoms/grids/grid-stack/CONSUMER-STYLING.md +3 -0
- package/app/components/01.atoms/grids/grid-stack/GridStack.vue +2 -0
- package/app/components/01.atoms/grids/grid-stack/stories/GridStack.stories.ts +41 -0
- package/app/components/01.atoms/grids/grid-stack/tests/GridStack.spec.ts +26 -13
- package/app/components/01.atoms/grids/masonry-grid/CONSUMER-STYLING.md +15 -0
- package/app/components/01.atoms/grids/masonry-grid/MasonryGrid.vue +51 -31
- package/app/components/01.atoms/grids/masonry-grid/stories/MasonryGrid.stories.ts +48 -0
- package/app/components/01.atoms/grids/masonry-grid/tests/MasonryGrid.spec.ts +84 -29
- package/app/components/01.atoms/page-row/CONSUMER-STYLING.md +6 -1
- package/app/components/01.atoms/page-row/PageRow.vue +16 -15
- package/app/components/01.atoms/page-row/stories/PageRow.stories.ts +23 -0
- package/app/components/01.atoms/page-row/tests/PageRow.spec.ts +6 -5
- package/app/components/02.molecules/action-menu/ActionMenu.vue +6 -2
- package/app/components/02.molecules/action-menu/ActionMenuItem.vue +6 -3
- package/app/components/02.molecules/action-menu/CONSUMER-STYLING.md +11 -4
- package/app/components/02.molecules/action-menu/stories/ActionMenu.stories.ts +130 -18
- package/app/components/02.molecules/expandable/accordion-chat/AccordionChat.vue +227 -0
- package/app/components/02.molecules/expandable/accordion-chat/CONSUMER-STYLING.md +150 -0
- package/app/components/02.molecules/expandable/accordion-chat/stories/AccordionChat.stories.ts +347 -0
- package/app/components/02.molecules/expandable/accordion-chat/tests/AccordionChat.spec.ts +205 -0
- package/app/components/02.molecules/expandable/accordion-chat/tests/__snapshots__/AccordionChat.spec.ts.snap +40 -0
- package/app/components/02.molecules/expandable/{accordian/AccordianCore.vue → accordion-group/AccordionGroup.vue} +32 -20
- package/app/components/02.molecules/expandable/accordion-group/CONSUMER-STYLING.md +66 -0
- package/app/components/02.molecules/expandable/accordion-group/stories/AccordionGroup.stories.ts +238 -0
- package/app/components/02.molecules/expandable/accordion-group/tests/AccordionGroup.spec.ts +172 -0
- package/app/components/02.molecules/expandable/accordion-group/tests/__snapshots__/AccordionGroup.spec.ts.snap +45 -0
- package/app/components/02.molecules/expandable/expanding-panel/CONSUMER-STYLING.md +1 -0
- package/app/components/02.molecules/expandable/expanding-panel/ExpandingPanel.vue +11 -6
- package/app/components/02.molecules/expandable/expanding-panel/stories/ExpandingPanel.stories.ts +82 -1
- package/app/components/02.molecules/expandable/expanding-panel/tests/ExpandingPanel.spec.ts +24 -30
- package/app/components/02.molecules/expandable/expanding-panel/tests/__snapshots__/ExpandingPanel.spec.ts.snap +8 -8
- package/app/components/02.molecules/expandable/expanding-panel-classic/CONSUMER-STYLING.md +1 -0
- package/app/components/02.molecules/expandable/expanding-panel-classic/ExpandingPanelClassic.vue +10 -5
- package/app/components/02.molecules/expandable/expanding-panel-classic/stories/ExpandingPanelClassic.stories.ts +83 -1
- package/app/components/02.molecules/expandable/expanding-panel-classic/tests/ExpandingPanelClassic.spec.ts +24 -30
- package/app/components/02.molecules/expandable/expanding-panel-classic/tests/__snapshots__/ExpandingPanelClassic.spec.ts.snap +8 -8
- package/app/components/02.molecules/navigation/deep-expanding-menu/CONSUMER-STYLING.md +63 -44
- package/app/components/02.molecules/navigation/deep-expanding-menu/DeepExpandingMenu.vue +74 -37
- package/app/components/02.molecules/navigation/deep-expanding-menu/stories/DeepExpandingMenu.stories.ts +139 -19
- package/app/components/02.molecules/navigation/deep-expanding-menu/tests/DeepExpandingMenu.spec.ts +90 -27
- package/app/components/02.molecules/navigation/deep-expanding-menu/tests/__snapshots__/DeepExpandingMenu.spec.ts.snap +8 -8
- package/app/components/02.molecules/navigation/deep-expanding-menu-classic/CONSUMER-STYLING.md +58 -26
- package/app/components/02.molecules/navigation/deep-expanding-menu-classic/DeepExpandingMenuClassic.vue +113 -57
- package/app/components/02.molecules/navigation/deep-expanding-menu-classic/stories/DeepExpandingMenuClassic.stories.ts +139 -19
- package/app/components/02.molecules/navigation/deep-expanding-menu-classic/tests/DeepExpandingMenuClassic.spec.ts +140 -22
- package/app/components/02.molecules/navigation/deep-expanding-menu-classic/tests/__snapshots__/DeepExpandingMenuClassic.spec.ts.snap +9 -9
- package/app/components/02.molecules/qr-code/CONSUMER-STYLING.md +22 -7
- package/app/components/02.molecules/qr-code/CaptureQrCode.vue +63 -71
- package/app/components/02.molecules/qr-code/DecodeQrCode.vue +47 -10
- package/app/components/02.molecules/qr-code/stories/CaptureQrCode.stories.ts +114 -26
- package/app/components/02.molecules/qr-code/stories/DecodeQrCode.stories.ts +115 -24
- package/app/components/02.molecules/qr-code/tests/CaptureQrCode.spec.ts +124 -51
- package/app/components/02.molecules/qr-code/tests/DecodeQrCode.spec.ts +74 -25
- package/app/components/02.molecules/samaritan-prompt/CONSUMER-STYLING.md +22 -10
- package/app/components/02.molecules/samaritan-prompt/SamaritanPrompt.vue +30 -12
- package/app/components/02.molecules/samaritan-prompt/SamaritanPromptMixed.vue +34 -10
- package/app/components/02.molecules/samaritan-prompt/stories/SamaritanPrompt.stories.ts +55 -4
- package/app/components/02.molecules/samaritan-prompt/stories/SamaritanPromptMixed.stories.ts +67 -7
- package/app/components/02.molecules/samaritan-prompt/tests/SamaritanPrompt.spec.ts +113 -29
- package/app/components/02.molecules/samaritan-prompt/tests/SamaritanPromptMixed.spec.ts +92 -45
- package/app/components/03.organisms/image-galleries/carousel-flip/CONSUMER-STYLING.md +82 -29
- package/app/components/03.organisms/image-galleries/carousel-flip/CarouselFlip.vue +176 -113
- package/app/components/03.organisms/image-galleries/carousel-flip/stories/CarouselFlip.stories.ts +153 -23
- package/app/components/03.organisms/image-galleries/carousel-flip/tests/CarouselFlip.spec.ts +119 -63
- package/app/components/03.organisms/responsive-header/tests/__snapshots__/NavigationItems.spec.ts.snap +2 -2
- package/app/components/03.organisms/responsive-header/tests/__snapshots__/ResponsiveHeader.spec.ts.snap +2 -2
- package/app/components/03.organisms/services/service-detail/tests/ServiceDetail.spec.ts +8 -8
- package/app/components/03.organisms/services/service-detail/tests/__snapshots__/ServiceDetail.spec.ts.snap +4 -4
- package/app/components/03.organisms/site-header/CONSUMER-STYLING.md +41 -23
- package/app/components/03.organisms/site-header/SiteHeader.vue +16 -21
- package/app/components/03.organisms/site-header/stories/SiteHeader.stories.ts +138 -0
- package/app/components/03.organisms/site-header/tests/SiteHeader.spec.ts +53 -26
- package/app/components/03.organisms/site-header/tests/__snapshots__/SiteHeader.spec.ts.snap +2 -2
- package/app/types/components/qr-code.d.ts +12 -0
- package/app/utils/graphemes.ts +8 -0
- package/package.json +1 -1
- package/.claude/skills/components/accordian-core.md +0 -180
- package/.vscode/srcdev-component-accordian-core.code-snippets +0 -74
- package/app/components/01.atoms/animations/entry/.nuxt/app.config.mjs +0 -21
- package/app/components/01.atoms/animations/entry/.nuxt/components.d.ts +0 -66
- package/app/components/01.atoms/animations/entry/.nuxt/imports.d.ts +0 -30
- package/app/components/01.atoms/animations/entry/.nuxt/manifest/meta/test.json +0 -1
- package/app/components/01.atoms/animations/entry/.nuxt/types/app.config.d.ts +0 -35
- package/app/components/01.atoms/animations/entry/.nuxt/types/build.d.ts +0 -23
- package/app/components/01.atoms/animations/entry/.nuxt/types/builder-env.d.ts +0 -1
- package/app/components/01.atoms/animations/entry/.nuxt/types/components.d.ts +0 -71
- package/app/components/01.atoms/animations/entry/.nuxt/types/imports.d.ts +0 -386
- package/app/components/01.atoms/animations/entry/.nuxt/types/middleware.d.ts +0 -11
- package/app/components/01.atoms/animations/entry/.nuxt/types/modules.d.ts +0 -79
- package/app/components/01.atoms/animations/entry/.nuxt/types/nitro-layouts.d.ts +0 -17
- package/app/components/01.atoms/animations/entry/.nuxt/types/nitro-nuxt.d.ts +0 -64
- package/app/components/01.atoms/animations/entry/.nuxt/types/plugins.d.ts +0 -29
- package/app/components/01.atoms/animations/entry/.nuxt/types/runtime-config.d.ts +0 -32
- package/app/components/01.atoms/animations/entry/.nuxt/types/shared-imports.d.ts +0 -10
- package/app/components/01.atoms/animations/entry/.nuxt/types/vue-shim.d.ts +0 -0
- package/app/components/01.atoms/animations/entry/.nuxtrc +0 -1
- package/app/components/01.atoms/animations/entry/node_modules/.cache/nuxt/chrome-workspace.json +0 -1
- package/app/components/01.atoms/animations/entry/node_modules/.cache/vite/client/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/app/components/02.molecules/expandable/accordian/CONSUMER-STYLING.md +0 -100
- package/app/components/02.molecules/expandable/accordian/stories/AccordianCore.stories.ts +0 -272
- package/app/components/02.molecules/expandable/accordian/tests/AccordianCore.spec.ts +0 -257
- package/app/components/02.molecules/expandable/accordian/tests/__snapshots__/AccordianCore.spec.ts.snap +0 -95
- package/app/components/03.organisms/responsive-header/tests/.nuxt/app.config.mjs +0 -21
- package/app/components/03.organisms/responsive-header/tests/.nuxt/components.d.ts +0 -66
- package/app/components/03.organisms/responsive-header/tests/.nuxt/imports.d.ts +0 -30
- package/app/components/03.organisms/responsive-header/tests/.nuxt/manifest/meta/test.json +0 -1
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/app.config.d.ts +0 -35
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/build.d.ts +0 -23
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/builder-env.d.ts +0 -1
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/components.d.ts +0 -71
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/imports.d.ts +0 -386
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/middleware.d.ts +0 -11
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/modules.d.ts +0 -79
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/nitro-layouts.d.ts +0 -17
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/nitro-nuxt.d.ts +0 -64
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/plugins.d.ts +0 -29
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/runtime-config.d.ts +0 -32
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/shared-imports.d.ts +0 -10
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/vue-shim.d.ts +0 -0
- package/app/components/03.organisms/responsive-header/tests/node_modules/.cache/nuxt/chrome-workspace.json +0 -1
package/app/components/03.organisms/image-galleries/carousel-flip/stories/CarouselFlip.stories.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Meta, StoryFn } from "@nuxtjs/storybook";
|
|
2
|
-
import { computed } from "vue";
|
|
2
|
+
import { computed, ref } from "vue";
|
|
3
3
|
import StorybookComponent from "../CarouselFlip.vue";
|
|
4
|
+
import CanvasSwitcher from "../../../../01.atoms/canvas-switcher/CanvasSwitcher.vue";
|
|
5
|
+
import type { MediaCanvas } from "~/types/components";
|
|
4
6
|
|
|
5
7
|
// Define carousel item interface
|
|
6
8
|
interface CarouselItem {
|
|
@@ -16,7 +18,7 @@ interface CarouselFlipStoryArgs {
|
|
|
16
18
|
transitionSpeed: number;
|
|
17
19
|
useFlipAnimation: boolean;
|
|
18
20
|
useSpringEffect: boolean;
|
|
19
|
-
buttonLayout: "sides" | "controls-flanking" | "controls-grouped-right" | "overlay";
|
|
21
|
+
buttonLayout: "sides" | "controls-flanking" | "controls-grouped-right" | "overlay" | "track-edges";
|
|
20
22
|
showControls: boolean;
|
|
21
23
|
styleClassPassthrough: string[];
|
|
22
24
|
ariaLabel: string;
|
|
@@ -116,7 +118,7 @@ export default {
|
|
|
116
118
|
},
|
|
117
119
|
buttonLayout: {
|
|
118
120
|
control: { type: "select" },
|
|
119
|
-
options: ["sides", "controls-flanking", "controls-grouped-right", "overlay"],
|
|
121
|
+
options: ["sides", "controls-flanking", "controls-grouped-right", "overlay", "track-edges"],
|
|
120
122
|
description: "Placement of prev/next buttons relative to the carousel and controls bar",
|
|
121
123
|
table: {
|
|
122
124
|
category: "Layout",
|
|
@@ -195,6 +197,16 @@ export default {
|
|
|
195
197
|
},
|
|
196
198
|
},
|
|
197
199
|
},
|
|
200
|
+
parameters: {
|
|
201
|
+
docs: {
|
|
202
|
+
description: {
|
|
203
|
+
component:
|
|
204
|
+
"Carousel that reorders its items with a FLIP animation. Each id in `carouselDataIds` names a slot holding that item's content. " +
|
|
205
|
+
"Props: `carouselDataIds`, `buttonLayout`, `showControls`, `allowCarouselOverflow`, `useFlipAnimation`, `useSpringEffect`, `transitionSpeed`, and label props for every control. " +
|
|
206
|
+
"Slots: one per id, plus `prev-icon` and `next-icon`. Arrow keys move between items when the track or a marker has focus; swipe works on touch.",
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
},
|
|
198
210
|
args: {
|
|
199
211
|
carouselDataIds: [1, 2, 3, 4, 5],
|
|
200
212
|
allowCarouselOverflow: true,
|
|
@@ -249,6 +261,11 @@ const Template: StoryFn<CarouselFlipStoryArgs> = (args) => ({
|
|
|
249
261
|
--carousel-flip-edge-preview-width: 12px;
|
|
250
262
|
}
|
|
251
263
|
|
|
264
|
+
.button-offset-demo.carousel-flip {
|
|
265
|
+
--carousel-flip-button-inline-offset: 2.4rem;
|
|
266
|
+
--carousel-flip-button-align: end;
|
|
267
|
+
}
|
|
268
|
+
|
|
252
269
|
@media (width >= 768px) {
|
|
253
270
|
.carousel-flip-demo.carousel-flip {
|
|
254
271
|
--carousel-flip-gap: 24px;
|
|
@@ -256,7 +273,7 @@ const Template: StoryFn<CarouselFlipStoryArgs> = (args) => ({
|
|
|
256
273
|
}
|
|
257
274
|
}
|
|
258
275
|
|
|
259
|
-
.carousel-flip-demo.carousel-flip .
|
|
276
|
+
.carousel-flip-demo.carousel-flip .carousel-flip-track {
|
|
260
277
|
max-inline-size: 800px;
|
|
261
278
|
margin-inline: auto;
|
|
262
279
|
outline: 1px solid var(--slate-08, #666);
|
|
@@ -265,18 +282,18 @@ const Template: StoryFn<CarouselFlipStoryArgs> = (args) => ({
|
|
|
265
282
|
}
|
|
266
283
|
|
|
267
284
|
@media (width >= 768px) {
|
|
268
|
-
.carousel-flip-demo.carousel-flip .
|
|
285
|
+
.carousel-flip-demo.carousel-flip .carousel-flip-track {
|
|
269
286
|
padding-block: 12px;
|
|
270
287
|
padding-inline: 12px;
|
|
271
288
|
}
|
|
272
289
|
}
|
|
273
290
|
|
|
274
|
-
.carousel-flip-demo.carousel-flip .item {
|
|
291
|
+
.carousel-flip-demo.carousel-flip .carousel-flip-item {
|
|
275
292
|
background-color: var(--slate-05, #e5e5e5);
|
|
276
293
|
contain: layout style paint;
|
|
277
294
|
}
|
|
278
295
|
|
|
279
|
-
.carousel-flip-demo.carousel-flip .item:nth-child(odd) {
|
|
296
|
+
.carousel-flip-demo.carousel-flip .carousel-flip-item:nth-child(odd) {
|
|
280
297
|
background-color: var(--slate-06, #999);
|
|
281
298
|
}
|
|
282
299
|
|
|
@@ -294,32 +311,32 @@ const Template: StoryFn<CarouselFlipStoryArgs> = (args) => ({
|
|
|
294
311
|
outline: 1px solid #00000090;
|
|
295
312
|
}
|
|
296
313
|
|
|
297
|
-
.carousel-flip-demo.carousel-flip .controls
|
|
314
|
+
.carousel-flip-demo.carousel-flip .carousel-flip-controls {
|
|
298
315
|
gap: 20px;
|
|
299
316
|
max-inline-size: 800px;
|
|
300
317
|
}
|
|
301
318
|
|
|
302
|
-
.carousel-flip-demo.carousel-flip .markers
|
|
319
|
+
.carousel-flip-demo.carousel-flip .carousel-flip-markers {
|
|
303
320
|
--marker-height: 12px;
|
|
304
321
|
--marker-width: 12px;
|
|
305
322
|
--marker-border-radius: 100vw;
|
|
306
323
|
}
|
|
307
324
|
|
|
308
325
|
@media (width >= 768px) {
|
|
309
|
-
.carousel-flip-demo.carousel-flip .markers
|
|
326
|
+
.carousel-flip-demo.carousel-flip .carousel-flip-markers {
|
|
310
327
|
--marker-height: 22px;
|
|
311
328
|
--marker-width: 22px;
|
|
312
329
|
}
|
|
313
330
|
}
|
|
314
331
|
|
|
315
|
-
.carousel-flip-demo.carousel-flip .markers-item {
|
|
332
|
+
.carousel-flip-demo.carousel-flip .carousel-flip-markers-item {
|
|
316
333
|
width: var(--marker-width);
|
|
317
334
|
height: var(--marker-height);
|
|
318
335
|
border-radius: var(--marker-border-radius);
|
|
319
336
|
line-height: var(--marker-height);
|
|
320
337
|
}
|
|
321
338
|
|
|
322
|
-
.carousel-flip-demo.carousel-flip .
|
|
339
|
+
.carousel-flip-demo.carousel-flip .carousel-flip-marker {
|
|
323
340
|
width: var(--marker-width);
|
|
324
341
|
height: var(--marker-height);
|
|
325
342
|
border-radius: var(--marker-border-radius);
|
|
@@ -330,13 +347,13 @@ const Template: StoryFn<CarouselFlipStoryArgs> = (args) => ({
|
|
|
330
347
|
outline: 1px solid transparent;
|
|
331
348
|
}
|
|
332
349
|
|
|
333
|
-
.carousel-flip-demo.carousel-flip .
|
|
350
|
+
.carousel-flip-demo.carousel-flip .carousel-flip-marker[data-active] {
|
|
334
351
|
background-color: var(--slate-012, #000);
|
|
335
352
|
will-change: background-color;
|
|
336
353
|
}
|
|
337
354
|
|
|
338
|
-
.carousel-flip-demo.carousel-flip .
|
|
339
|
-
.carousel-flip-demo.carousel-flip .
|
|
355
|
+
.carousel-flip-demo.carousel-flip .carousel-flip-marker:hover,
|
|
356
|
+
.carousel-flip-demo.carousel-flip .carousel-flip-marker:focus-visible {
|
|
340
357
|
outline-color: #000;
|
|
341
358
|
will-change: background-color, outline-color;
|
|
342
359
|
}
|
|
@@ -442,6 +459,41 @@ NoOverflow.args = {
|
|
|
442
459
|
styleClassPassthrough: ["carousel-flip-demo", "no-overflow"],
|
|
443
460
|
};
|
|
444
461
|
|
|
462
|
+
export const TrackEdges = Template.bind({});
|
|
463
|
+
TrackEdges.storyName = "Button Layout: Track Edges";
|
|
464
|
+
TrackEdges.args = {
|
|
465
|
+
carouselDataIds: [1, 2, 3, 4, 5],
|
|
466
|
+
allowCarouselOverflow: true,
|
|
467
|
+
buttonLayout: "track-edges",
|
|
468
|
+
};
|
|
469
|
+
TrackEdges.parameters = {
|
|
470
|
+
docs: {
|
|
471
|
+
description: {
|
|
472
|
+
story:
|
|
473
|
+
"`buttonLayout=\"track-edges\"` overlays the buttons on the ends of the visible track, inset past the edge previews (`--carousel-flip-button-edge-inset`, default the preview width plus `0.8rem`). " +
|
|
474
|
+
"They stay on the active frame even with `allowCarouselOverflow` on, where `sides` would leave them over the neighbouring items.",
|
|
475
|
+
},
|
|
476
|
+
},
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
export const ButtonPlacementTokens = Template.bind({});
|
|
480
|
+
ButtonPlacementTokens.storyName = "Button Placement Tokens";
|
|
481
|
+
ButtonPlacementTokens.args = {
|
|
482
|
+
carouselDataIds: [1, 2, 3, 4, 5],
|
|
483
|
+
allowCarouselOverflow: true,
|
|
484
|
+
buttonLayout: "sides",
|
|
485
|
+
styleClassPassthrough: ["carousel-flip-demo", "button-offset-demo"],
|
|
486
|
+
};
|
|
487
|
+
ButtonPlacementTokens.parameters = {
|
|
488
|
+
docs: {
|
|
489
|
+
description: {
|
|
490
|
+
story:
|
|
491
|
+
"The `sides` layout with `--carousel-flip-button-inline-offset: 2.4rem` (pushes each button outward; negative pulls it inward) and `--carousel-flip-button-align: end` (bottom of the row). " +
|
|
492
|
+
"To reach the viewport edges from a centred carousel of known width, set the offset to `calc((100vw - <that width>) / 2 - 1.6rem)` (a percentage won't work: on `translate` it resolves against the button itself). `vw` includes the scrollbar, hence the margin.",
|
|
493
|
+
},
|
|
494
|
+
},
|
|
495
|
+
};
|
|
496
|
+
|
|
445
497
|
export const NoControls = Template.bind({});
|
|
446
498
|
NoControls.args = {
|
|
447
499
|
carouselDataIds: [1, 2, 3, 4, 5],
|
|
@@ -510,7 +562,7 @@ const RichContentTemplate: StoryFn<CarouselFlipStoryArgs> = (args) => ({
|
|
|
510
562
|
}
|
|
511
563
|
}
|
|
512
564
|
|
|
513
|
-
.carousel-flip-demo.carousel-flip .
|
|
565
|
+
.carousel-flip-demo.carousel-flip .carousel-flip-track {
|
|
514
566
|
max-inline-size: 800px;
|
|
515
567
|
margin-inline: auto;
|
|
516
568
|
outline: 1px solid var(--slate-08, #666);
|
|
@@ -519,18 +571,18 @@ const RichContentTemplate: StoryFn<CarouselFlipStoryArgs> = (args) => ({
|
|
|
519
571
|
}
|
|
520
572
|
|
|
521
573
|
@media (width >= 768px) {
|
|
522
|
-
.carousel-flip-demo.carousel-flip .
|
|
574
|
+
.carousel-flip-demo.carousel-flip .carousel-flip-track {
|
|
523
575
|
padding-block: 12px;
|
|
524
576
|
padding-inline: 12px;
|
|
525
577
|
}
|
|
526
578
|
}
|
|
527
579
|
|
|
528
|
-
.carousel-flip-demo.carousel-flip .item {
|
|
580
|
+
.carousel-flip-demo.carousel-flip .carousel-flip-item {
|
|
529
581
|
background-color: var(--slate-05, #e5e5e5);
|
|
530
582
|
contain: layout style paint;
|
|
531
583
|
}
|
|
532
584
|
|
|
533
|
-
.carousel-flip-demo.carousel-flip .item:nth-child(odd) {
|
|
585
|
+
.carousel-flip-demo.carousel-flip .carousel-flip-item:nth-child(odd) {
|
|
534
586
|
background-color: var(--slate-06, #999);
|
|
535
587
|
}
|
|
536
588
|
`;
|
|
@@ -624,7 +676,7 @@ const RichContentTemplate: StoryFn<CarouselFlipStoryArgs> = (args) => ({
|
|
|
624
676
|
border-radius: 50%;
|
|
625
677
|
transform: rotate(45deg);
|
|
626
678
|
"
|
|
627
|
-
|
|
679
|
+
></div>
|
|
628
680
|
</div>
|
|
629
681
|
</template>
|
|
630
682
|
</StorybookComponent>
|
|
@@ -682,13 +734,13 @@ const AnimationShowcaseTemplate: StoryFn<CarouselFlipStoryArgs> = (args) => ({
|
|
|
682
734
|
Testing different animation combinations and timing
|
|
683
735
|
</p>
|
|
684
736
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 8px; margin-bottom: 20px;">
|
|
685
|
-
<div style="padding: 8px; border: 1px solid #ccc; border-radius: 6px; text-align: center; font-size: 12px; color: #333; background: args.useFlipAnimation ? '#e7f5e7' : 'transparent'
|
|
737
|
+
<div style="padding: 8px; border: 1px solid #ccc; border-radius: 6px; text-align: center; font-size: 12px; color: #333;" :style="{ background: args.useFlipAnimation ? '#e7f5e7' : 'transparent' }">
|
|
686
738
|
Flip: {{ args.useFlipAnimation ? '✓' : '✗' }}
|
|
687
739
|
</div>
|
|
688
|
-
<div style="padding: 8px; border: 1px solid #ccc; border-radius: 6px; text-align: center; font-size: 12px; color: #333; background: args.useSpringEffect ? '#e7f5e7' : 'transparent'
|
|
740
|
+
<div style="padding: 8px; border: 1px solid #ccc; border-radius: 6px; text-align: center; font-size: 12px; color: #333;" :style="{ background: args.useSpringEffect ? '#e7f5e7' : 'transparent' }">
|
|
689
741
|
Spring: {{ args.useSpringEffect ? '✓' : '✗' }}
|
|
690
742
|
</div>
|
|
691
|
-
<div style="padding: 8px; border: 1px solid #ccc; border-radius: 6px; text-align: center; font-size: 12px; color: #333; background: args.allowCarouselOverflow ? '#e7f5e7' : 'transparent'
|
|
743
|
+
<div style="padding: 8px; border: 1px solid #ccc; border-radius: 6px; text-align: center; font-size: 12px; color: #333;" :style="{ background: args.allowCarouselOverflow ? '#e7f5e7' : 'transparent' }">
|
|
692
744
|
Overflow: {{ args.allowCarouselOverflow ? '✓' : '✗' }}
|
|
693
745
|
</div>
|
|
694
746
|
<div style="padding: 8px; border: 1px solid #ccc; border-radius: 6px; text-align: center; font-size: 12px; color: #333;">
|
|
@@ -755,3 +807,81 @@ AnimationShowcase.args = {
|
|
|
755
807
|
allowCarouselOverflow: true,
|
|
756
808
|
styleClassPassthrough: ["carousel-flip-demo", "animation-showcase"],
|
|
757
809
|
};
|
|
810
|
+
|
|
811
|
+
const stressItems = [
|
|
812
|
+
{ id: "short", title: "x", body: "" },
|
|
813
|
+
{
|
|
814
|
+
id: "unbroken",
|
|
815
|
+
title: "Supercalifragilisticexpialidociousandthensomemoretextwithoutanyspaces",
|
|
816
|
+
body: "https://example.com/a/very/long/unbroken/path/that/never/wraps/on/its/own",
|
|
817
|
+
},
|
|
818
|
+
{
|
|
819
|
+
id: "german",
|
|
820
|
+
title: "Unsere vollständige Übersicht aller Behandlungen in Northtown",
|
|
821
|
+
body: "Ein sehr langer Beschreibungstext, der auf schmalen Bildschirmen mehrfach umbrechen muss, ohne das Karussell zu sprengen.",
|
|
822
|
+
},
|
|
823
|
+
{ id: "emoji", title: "🙂 👍🏽 👨👩👧", body: "Emoji only" },
|
|
824
|
+
{ id: "html", title: "<b>Not bold</b>", body: "<script>alert(1)</script>" },
|
|
825
|
+
{ id: "rtl", title: "مرحبا بالعالم", body: "نص طويل من اليمين إلى اليسار" },
|
|
826
|
+
...Array.from({ length: 24 }, (_, i) => ({ id: `extra-${i + 1}`, title: `Item ${i + 7}`, body: "" })),
|
|
827
|
+
];
|
|
828
|
+
|
|
829
|
+
export const StressTest: StoryFn<CarouselFlipStoryArgs> = (args) => ({
|
|
830
|
+
components: { StorybookComponent, CanvasSwitcher },
|
|
831
|
+
setup() {
|
|
832
|
+
const canvasName = ref<MediaCanvas>("mobileCanvas");
|
|
833
|
+
const items = computed(() => stressItems.filter((item) => args.carouselDataIds.includes(item.id)));
|
|
834
|
+
return { args, canvasName, items };
|
|
835
|
+
},
|
|
836
|
+
template: `
|
|
837
|
+
<div style="padding: 1.2rem 1.6rem; border-block-end: 1px solid currentColor;">
|
|
838
|
+
<CanvasSwitcher v-model:canvas-name="canvasName" />
|
|
839
|
+
</div>
|
|
840
|
+
<div :class="canvasName" style="margin-inline: auto; padding: 2rem; outline: 1px dashed currentColor;">
|
|
841
|
+
<StorybookComponent
|
|
842
|
+
:carousel-data-ids="args.carouselDataIds"
|
|
843
|
+
:allow-carousel-overflow="args.allowCarouselOverflow"
|
|
844
|
+
:transition-speed="args.transitionSpeed"
|
|
845
|
+
:use-flip-animation="args.useFlipAnimation"
|
|
846
|
+
:use-spring-effect="args.useSpringEffect"
|
|
847
|
+
:button-layout="args.buttonLayout"
|
|
848
|
+
:show-controls="args.showControls"
|
|
849
|
+
:previous-label="args.previousLabel"
|
|
850
|
+
:next-label="args.nextLabel"
|
|
851
|
+
:jump-to-item-label="args.jumpToItemLabel"
|
|
852
|
+
>
|
|
853
|
+
<template v-for="(item, index) in items" #[item.id] :key="index">
|
|
854
|
+
<div style="display: grid; gap: 0.8rem; inline-size: 100%; padding: 1.6rem; aspect-ratio: 4 / 3; background: var(--theme-surface-subtle); outline: 1px solid currentColor;">
|
|
855
|
+
<h3 style="margin: 0;">{{ item.title }}</h3>
|
|
856
|
+
<p style="margin: 0;">{{ item.body }}</p>
|
|
857
|
+
</div>
|
|
858
|
+
</template>
|
|
859
|
+
</StorybookComponent>
|
|
860
|
+
</div>
|
|
861
|
+
`,
|
|
862
|
+
});
|
|
863
|
+
StressTest.storyName = "Stress Test (Worst-Case Data)";
|
|
864
|
+
StressTest.args = {
|
|
865
|
+
carouselDataIds: stressItems.map((item) => item.id),
|
|
866
|
+
allowCarouselOverflow: false,
|
|
867
|
+
transitionSpeed: 400,
|
|
868
|
+
useFlipAnimation: true,
|
|
869
|
+
buttonLayout: "controls-flanking",
|
|
870
|
+
previousLabel: "Zum vorherigen Element im Karussell wechseln",
|
|
871
|
+
nextLabel: "Zum nächsten Element im Karussell wechseln",
|
|
872
|
+
jumpToItemLabel: "Springe zu Element",
|
|
873
|
+
styleClassPassthrough: [],
|
|
874
|
+
};
|
|
875
|
+
StressTest.parameters = {
|
|
876
|
+
layout: "fullscreen",
|
|
877
|
+
docs: {
|
|
878
|
+
story: { inline: false, height: "720px" },
|
|
879
|
+
description: {
|
|
880
|
+
story:
|
|
881
|
+
"30 items with hostile content at every `CanvasSwitcher` width, in the `controls-flanking` layout. Check that: the 30 markers wrap onto several rows instead of overflowing; " +
|
|
882
|
+
"the unbroken title and URL wrap inside their item; the German text wraps; emoji, `<b>` and `<script>` render as text; the right-to-left item reads correctly; prev/next still cycle through all 30. " +
|
|
883
|
+
"In Controls, set `carouselDataIds` to `[]`: the carousel renders empty without freezing the tab (until 2026-10-21 an empty list hung it in an infinite loop). " +
|
|
884
|
+
"Set it to one id: the markers and prev/next buttons disappear, since there is nothing to move to.",
|
|
885
|
+
},
|
|
886
|
+
},
|
|
887
|
+
};
|