srcdev-nuxt-components 9.6.19 → 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/ids-from-useid.md +3 -2
- package/.claude/skills/component-compliance-checklist.md +5 -0
- 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/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/index.md +12 -12
- package/.claude/skills/storybook-add-story.md +25 -0
- package/.claude/skills/testing-add-unit-test.md +26 -0
- 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/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/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/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/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/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
|
@@ -2,65 +2,76 @@
|
|
|
2
2
|
|
|
3
3
|
## Public token API
|
|
4
4
|
|
|
5
|
+
> Changed 2026-10-21: colour defaults now come from `--theme-*` tokens (were `--blue-10`, `white`,
|
|
6
|
+
> `black`, `--slate-10`), and the structural classes are prefixed (see State hooks).
|
|
7
|
+
|
|
8
|
+
### Top-level row
|
|
9
|
+
|
|
5
10
|
| Token | Default | Controls |
|
|
6
11
|
|---|---|---|
|
|
7
|
-
| `--deep-expanding-menu-gap` | `2.4rem` | Gap between top-level items |
|
|
8
|
-
| `--deep-expanding-menu-link-border-width` | `0.2rem` | Bottom border width on links
|
|
12
|
+
| `--deep-expanding-menu-gap` | `2.4rem` | Gap between top-level items (row and column, the row wraps) |
|
|
13
|
+
| `--deep-expanding-menu-link-border-width` | `0.2rem` | Bottom border width on links, group toggles and child links |
|
|
9
14
|
| `--deep-expanding-menu-link-padding-block` | `0.8rem` | Vertical padding on links and group toggles |
|
|
10
|
-
| `--deep-expanding-menu-link-border-colour-hover` | `var(--
|
|
15
|
+
| `--deep-expanding-menu-link-border-colour-hover` | `var(--theme-border)` | Bottom border colour on hover/focus |
|
|
16
|
+
| `--deep-expanding-menu-focus-outline-width` | `0.2rem` | Keyboard focus ring width on links and toggles |
|
|
17
|
+
| `--deep-expanding-menu-focus-outline-colour` | `var(--theme-ring, currentcolor)` | Keyboard focus ring colour |
|
|
11
18
|
| `--deep-expanding-menu-icon-size` | `1.2rem` | Caret icon size |
|
|
12
|
-
| `--deep-expanding-menu-panel-width` | `min(100%, 50vw)` | Popover panel width |
|
|
13
|
-
| `--deep-expanding-menu-panel-background-colour` | `white` | Popover panel background |
|
|
14
|
-
| `--deep-expanding-menu-panel-border-width` | `0.1rem` | Popover panel border width |
|
|
15
|
-
| `--deep-expanding-menu-panel-border-colour` | `black` | Popover panel border colour |
|
|
16
|
-
| `--deep-expanding-menu-panel-border-radius` | `1.2rem` | Popover panel corner radius |
|
|
17
|
-
| `--deep-expanding-menu-panel-shadow` | `0 0 1rem rgba(0, 0, 0, 0.1)` | Popover panel box-shadow |
|
|
18
|
-
| `--deep-expanding-menu-panel-padding` | `1.2rem` | Popover panel padding |
|
|
19
|
-
| `--deep-expanding-menu-panel-heading-colour` | `var(--slate-10)` | `childLinksTitle` heading colour inside the panel |
|
|
20
|
-
| `--deep-expanding-menu-panel-list-gap` | `1.2rem` | Gap between child link grid items |
|
|
21
|
-
| `--deep-expanding-menu-group-link-colour` | `var(--slate-10)` | Child link text colour |
|
|
22
|
-
| `--deep-expanding-menu-group-link-border-colour-hover` | `var(--slate-10)` | Child link bottom border colour on hover/focus |
|
|
23
|
-
| `--deep-expanding-menu-panel-z-index` | `999999` | Panel stacking order in browsers without CSS anchor positioning. Ignored where the panel renders in the top layer |
|
|
24
19
|
|
|
25
|
-
|
|
26
|
-
.my-page {
|
|
27
|
-
--deep-expanding-menu-panel-background-colour: #1a1a1a;
|
|
28
|
-
--deep-expanding-menu-panel-border-colour: transparent;
|
|
29
|
-
--deep-expanding-menu-group-link-colour: white;
|
|
30
|
-
}
|
|
31
|
-
```
|
|
20
|
+
### Panel
|
|
32
21
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
22
|
+
| Token | Default | Controls |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| `--deep-expanding-menu-panel-width` | `min(100%, 50vw)` | Panel width |
|
|
25
|
+
| `--deep-expanding-menu-panel-max-height` | `70dvh` | Panel max height; longer lists scroll inside it |
|
|
26
|
+
| `--deep-expanding-menu-panel-text-colour` | `var(--theme-text)` | Panel text colour |
|
|
27
|
+
| `--deep-expanding-menu-panel-background-colour` | `var(--theme-surface-subtle)` | Panel background |
|
|
28
|
+
| `--deep-expanding-menu-panel-border-width` | `0.1rem` | Panel border width |
|
|
29
|
+
| `--deep-expanding-menu-panel-border-colour` | `var(--theme-border)` | Panel border colour |
|
|
30
|
+
| `--deep-expanding-menu-panel-border-radius` | `1.2rem` | Panel corner radius |
|
|
31
|
+
| `--deep-expanding-menu-panel-shadow` | `0 0 1rem rgba(0, 0, 0, 0.1)` | Panel box-shadow |
|
|
32
|
+
| `--deep-expanding-menu-panel-padding` | `1.2rem` | Panel padding |
|
|
33
|
+
| `--deep-expanding-menu-panel-heading-colour` | `var(--theme-text)` | `childLinksTitle` heading colour |
|
|
34
|
+
| `--deep-expanding-menu-panel-heading-line-clamp` | `none` | Lines of `childLinksTitle` before an ellipsis. `1` is single-line ellipsis, `none` shows everything |
|
|
35
|
+
| `--deep-expanding-menu-panel-list-gap` | `1.2rem` | Gap between child link grid items |
|
|
36
|
+
| `--deep-expanding-menu-group-link-colour` | `var(--theme-text)` | Child link text colour |
|
|
37
|
+
| `--deep-expanding-menu-group-link-border-colour-hover` | `var(--theme-text)` | Child link bottom border colour on hover/focus |
|
|
38
|
+
| `--deep-expanding-menu-panel-z-index` | `999999` | Panel stacking order in browsers without CSS anchor positioning. Ignored where the panel renders in the top layer |
|
|
42
39
|
|
|
43
|
-
|
|
44
|
-
-
|
|
45
|
-
|
|
40
|
+
Private tokens (not public API): `--_anchor-name` (per-group anchor, set inline),
|
|
41
|
+
`--_icon-transform` (caret flip), and `--_anchor-bottom`, `--_anchor-left`,
|
|
42
|
+
`--_anchor-top-inverse` (written by `useAnchoredPopover` in the fallback).
|
|
46
43
|
|
|
47
|
-
|
|
44
|
+
Not tokenised: the `1rem` gap between a toggle and its panel, and the `12rem` minimum child link
|
|
45
|
+
column. Anchor names and popover target ids come from `useId()`.
|
|
48
46
|
|
|
49
|
-
##
|
|
47
|
+
## State hooks
|
|
50
48
|
|
|
51
49
|
| Hook | Meaning |
|
|
52
50
|
|---|---|
|
|
53
|
-
| `.
|
|
54
|
-
| `.
|
|
51
|
+
| `.deep-expanding-menu-group-toggle[aria-expanded="true"]` | Group open, every browser (flips the caret) |
|
|
52
|
+
| `.deep-expanding-menu-group-panel:popover-open` | Panel open, Popover API browsers |
|
|
55
53
|
| `.deep-expanding-menu-panel-open` | Panel open, browsers without the Popover API (Safari 16 and older). Style it in a **separate rule** from `:popover-open`: a selector list containing `:popover-open` is dropped whole where it's unsupported |
|
|
56
|
-
| `.
|
|
54
|
+
| `.deep-expanding-menu-group-panel[data-placement="top"]` | Flipped above the toggle, browsers without CSS anchor positioning only |
|
|
55
|
+
|
|
56
|
+
Inner elements: `.deep-expanding-menu-inner` (the flex row), `.deep-expanding-menu-link` (direct
|
|
57
|
+
link), `.deep-expanding-menu-group`, `.deep-expanding-menu-group-toggle`,
|
|
58
|
+
`.deep-expanding-menu-group-label`, `.deep-expanding-menu-group-icon`,
|
|
59
|
+
`.deep-expanding-menu-group-panel`, `.deep-expanding-menu-group-heading`,
|
|
60
|
+
`.deep-expanding-menu-group-list`, `.deep-expanding-menu-group-item`,
|
|
61
|
+
`.deep-expanding-menu-group-link`.
|
|
57
62
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
with `transform`, `filter` or `contain` becomes its containing block and can misplace it.
|
|
63
|
+
> Changed 2026-10-21: these were `.inner`, `.navigation-link`, `.navigation-group`,
|
|
64
|
+
> `.navigation-group-toggle`, `.icon`, `.navigation-group-panel`, `.navigation-group-list`,
|
|
65
|
+
> `.navigation-group-item` and `.navigation-group-link`. The heading had no class of its own.
|
|
62
66
|
|
|
63
|
-
|
|
67
|
+
## Browser support and placement
|
|
68
|
+
|
|
69
|
+
Where CSS anchor positioning is supported, a panel that would overflow the right edge flips to
|
|
70
|
+
align with its toggle's right edge (`position-try-fallbacks: flip-inline`). Without anchor
|
|
71
|
+
positioning (e.g. Safari 17–18) the panel is placed with `position: fixed` from the toggle's
|
|
72
|
+
measured position. Without the Popover API (Safari 16) the panel also opens and closes in JS and
|
|
73
|
+
isn't in the top layer, so `--deep-expanding-menu-panel-z-index` applies, and an ancestor with
|
|
74
|
+
`transform`, `filter` or `contain` becomes its containing block and can misplace it.
|
|
64
75
|
|
|
65
76
|
## Local overrides
|
|
66
77
|
|
|
@@ -69,3 +80,11 @@ Set the tokens above on an element you own (a page or section class, or a class
|
|
|
69
80
|
`@layer` wrapper) so it beats the library's `@layer components`. If your own file uses
|
|
70
81
|
`<style scoped>`, tokens set on your element still work, but selectors that reach inside the component need
|
|
71
82
|
`:deep()`. Patterns and examples: `.claude/skills/component-local-style-override.md`.
|
|
83
|
+
|
|
84
|
+
**Caveat:** in browsers with the Popover API the panel renders in the top layer but stays a DOM
|
|
85
|
+
descendant of the menu, so tokens set on an ancestor still reach it.
|
|
86
|
+
|
|
87
|
+
## Class passthrough
|
|
88
|
+
|
|
89
|
+
`style-class-passthrough` adds classes to the root element (the `<nav>` by default). It's the
|
|
90
|
+
usual place to scope token overrides to one instance.
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<component :is="tag" ref="rootRef" class="deep-expanding-menu" :class="[elementClasses]">
|
|
3
|
-
<div class="inner">
|
|
2
|
+
<component :is="tag" ref="rootRef" class="deep-expanding-menu" :class="[elementClasses]" :aria-label="ariaLabel">
|
|
3
|
+
<div class="deep-expanding-menu-inner">
|
|
4
4
|
<template v-for="(link, key) in navLinks" :key="key">
|
|
5
|
-
<NuxtLink v-if="link.path" :to="link.path" class="
|
|
5
|
+
<NuxtLink v-if="link.path" :to="link.path" class="deep-expanding-menu-link">{{ link.name }}</NuxtLink>
|
|
6
6
|
|
|
7
|
-
<div v-else class="
|
|
7
|
+
<div v-else class="deep-expanding-menu-group" :style="`--_anchor-name: --anchor-${uid}-${key};`">
|
|
8
8
|
<button
|
|
9
9
|
:ref="(el) => setElement(triggerEls, key, el)"
|
|
10
10
|
type="button"
|
|
11
11
|
:popovertarget="`popovertarget-${uid}-${key}`"
|
|
12
|
-
class="
|
|
12
|
+
class="deep-expanding-menu-group-toggle"
|
|
13
13
|
:aria-expanded="isOpen && activeKey === key"
|
|
14
14
|
@click="handleGroupClick(key)"
|
|
15
15
|
>
|
|
16
|
-
<span>{{ link.name }}</span>
|
|
17
|
-
<Icon name="bi:caret-down-fill" class="icon" />
|
|
16
|
+
<span class="deep-expanding-menu-group-label">{{ link.name }}</span>
|
|
17
|
+
<Icon name="bi:caret-down-fill" class="deep-expanding-menu-group-icon" aria-hidden="true" />
|
|
18
18
|
</button>
|
|
19
19
|
|
|
20
20
|
<div
|
|
21
21
|
:id="`popovertarget-${uid}-${key}`"
|
|
22
22
|
:ref="(el) => setElement(panelEls, key, el)"
|
|
23
|
-
class="
|
|
23
|
+
class="deep-expanding-menu-group-panel"
|
|
24
24
|
:class="{ 'deep-expanding-menu-panel-open': usesFallbackPopover && isOpen && activeKey === key }"
|
|
25
25
|
:style="activeKey === key ? positionStyle : undefined"
|
|
26
26
|
:data-placement="activeKey === key ? popoverPlacement : undefined"
|
|
@@ -28,10 +28,16 @@
|
|
|
28
28
|
@beforetoggle="handlePanelBeforeToggle(key, $event)"
|
|
29
29
|
@toggle="handlePanelToggle(key, $event)"
|
|
30
30
|
>
|
|
31
|
-
<h4 class="page-heading-4 mb-6">
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
<h4 v-if="link.childLinksTitle" class="deep-expanding-menu-group-heading page-heading-4 mb-6">
|
|
32
|
+
{{ link.childLinksTitle }}
|
|
33
|
+
</h4>
|
|
34
|
+
<ul v-if="link.childLinks?.length" class="deep-expanding-menu-group-list" role="list">
|
|
35
|
+
<li
|
|
36
|
+
v-for="(childLink, childIndex) in link.childLinks"
|
|
37
|
+
:key="`${childIndex}-${childLink.name}`"
|
|
38
|
+
class="deep-expanding-menu-group-item"
|
|
39
|
+
>
|
|
40
|
+
<NuxtLink :to="childLink.path" class="deep-expanding-menu-group-link">{{ childLink.name }}</NuxtLink>
|
|
35
41
|
</li>
|
|
36
42
|
</ul>
|
|
37
43
|
</div>
|
|
@@ -41,19 +47,22 @@
|
|
|
41
47
|
</component>
|
|
42
48
|
</template>
|
|
43
49
|
|
|
50
|
+
|
|
44
51
|
<script setup lang="ts">
|
|
45
52
|
import type { ComponentPublicInstance } from "vue";
|
|
46
53
|
import type { ResponsiveHeaderNavItem } from "~/types/components";
|
|
47
54
|
|
|
48
55
|
interface Props {
|
|
49
|
-
tag?: "div" | "section" | "nav"
|
|
56
|
+
tag?: "div" | "section" | "nav";
|
|
50
57
|
navLinks?: ResponsiveHeaderNavItem[];
|
|
58
|
+
ariaLabel?: string;
|
|
51
59
|
styleClassPassthrough?: string | string[];
|
|
52
60
|
}
|
|
53
61
|
|
|
54
62
|
const props = withDefaults(defineProps<Props>(), {
|
|
55
63
|
tag: "nav",
|
|
56
64
|
navLinks: () => [],
|
|
65
|
+
ariaLabel: undefined,
|
|
57
66
|
styleClassPassthrough: () => [],
|
|
58
67
|
});
|
|
59
68
|
|
|
@@ -126,15 +135,19 @@ watch(
|
|
|
126
135
|
display: grid;
|
|
127
136
|
grid-template-areas: "element-stack";
|
|
128
137
|
|
|
129
|
-
.inner {
|
|
138
|
+
.deep-expanding-menu-inner {
|
|
130
139
|
grid-area: element-stack;
|
|
131
140
|
display: flex;
|
|
141
|
+
flex-wrap: wrap;
|
|
132
142
|
gap: var(--deep-expanding-menu-gap, 2.4rem);
|
|
133
143
|
align-items: center;
|
|
144
|
+
min-inline-size: 0;
|
|
134
145
|
|
|
135
|
-
.
|
|
136
|
-
.
|
|
146
|
+
.deep-expanding-menu-link,
|
|
147
|
+
.deep-expanding-menu-group-toggle {
|
|
137
148
|
all: unset;
|
|
149
|
+
min-inline-size: 0;
|
|
150
|
+
overflow-wrap: anywhere;
|
|
138
151
|
border-bottom: var(--deep-expanding-menu-link-border-width, 0.2rem) solid transparent;
|
|
139
152
|
padding-block: var(--deep-expanding-menu-link-padding-block, 0.8rem);
|
|
140
153
|
|
|
@@ -144,26 +157,35 @@ watch(
|
|
|
144
157
|
&:focus,
|
|
145
158
|
&:focus-visible {
|
|
146
159
|
cursor: pointer;
|
|
147
|
-
border-color: var(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
160
|
+
border-color: var(--deep-expanding-menu-link-border-colour-hover, var(--theme-border));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
&:focus-visible {
|
|
164
|
+
outline: var(--deep-expanding-menu-focus-outline-width, 0.2rem) solid
|
|
165
|
+
var(--deep-expanding-menu-focus-outline-colour, var(--theme-ring, currentcolor));
|
|
166
|
+
outline-offset: 0.2rem;
|
|
151
167
|
}
|
|
152
168
|
}
|
|
153
169
|
|
|
154
|
-
.
|
|
170
|
+
.deep-expanding-menu-group {
|
|
155
171
|
--_icon-transform: scaleY(1);
|
|
156
172
|
position: relative;
|
|
173
|
+
min-inline-size: 0;
|
|
157
174
|
|
|
158
|
-
.
|
|
175
|
+
.deep-expanding-menu-group-toggle {
|
|
159
176
|
anchor-name: var(--_anchor-name);
|
|
160
177
|
|
|
161
178
|
display: flex;
|
|
162
179
|
align-items: center;
|
|
163
180
|
gap: 1.2rem;
|
|
164
181
|
|
|
165
|
-
.
|
|
182
|
+
.deep-expanding-menu-group-label {
|
|
183
|
+
min-inline-size: 0;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.deep-expanding-menu-group-icon {
|
|
166
187
|
display: block;
|
|
188
|
+
flex-shrink: 0;
|
|
167
189
|
font-size: var(--deep-expanding-menu-icon-size, 1.2rem);
|
|
168
190
|
|
|
169
191
|
transform: var(--_icon-transform);
|
|
@@ -171,10 +193,11 @@ watch(
|
|
|
171
193
|
}
|
|
172
194
|
}
|
|
173
195
|
|
|
174
|
-
.
|
|
196
|
+
.deep-expanding-menu-group-panel {
|
|
175
197
|
display: none;
|
|
176
198
|
position: absolute;
|
|
177
199
|
position-anchor: var(--_anchor-name);
|
|
200
|
+
position-try-fallbacks: flip-inline;
|
|
178
201
|
margin: 0;
|
|
179
202
|
top: calc(anchor(bottom) + 1rem);
|
|
180
203
|
left: calc(anchor(left) + 0rem);
|
|
@@ -187,14 +210,17 @@ watch(
|
|
|
187
210
|
transition-behavior: allow-discrete;
|
|
188
211
|
|
|
189
212
|
width: var(--deep-expanding-menu-panel-width, min(100%, 50vw));
|
|
213
|
+
max-block-size: var(--deep-expanding-menu-panel-max-height, 70dvh);
|
|
190
214
|
|
|
191
|
-
|
|
215
|
+
color: var(--deep-expanding-menu-panel-text-colour, var(--theme-text));
|
|
216
|
+
background-color: var(--deep-expanding-menu-panel-background-colour, var(--theme-surface-subtle));
|
|
192
217
|
border: var(--deep-expanding-menu-panel-border-width, 0.1rem) solid
|
|
193
|
-
var(--deep-expanding-menu-panel-border-colour,
|
|
218
|
+
var(--deep-expanding-menu-panel-border-colour, var(--theme-border));
|
|
194
219
|
border-radius: var(--deep-expanding-menu-panel-border-radius, 1.2rem);
|
|
195
220
|
box-shadow: var(--deep-expanding-menu-panel-shadow, 0 0 1rem rgba(0, 0, 0, 0.1));
|
|
196
221
|
padding: var(--deep-expanding-menu-panel-padding, 1.2rem);
|
|
197
|
-
overflow: clip;
|
|
222
|
+
overflow-x: clip;
|
|
223
|
+
overflow-y: auto;
|
|
198
224
|
|
|
199
225
|
&:popover-open {
|
|
200
226
|
display: block;
|
|
@@ -224,23 +250,33 @@ watch(
|
|
|
224
250
|
}
|
|
225
251
|
}
|
|
226
252
|
|
|
227
|
-
|
|
228
|
-
color: var(--deep-expanding-menu-panel-heading-colour, var(--
|
|
253
|
+
.deep-expanding-menu-group-heading {
|
|
254
|
+
color: var(--deep-expanding-menu-panel-heading-colour, var(--theme-text));
|
|
255
|
+
overflow-wrap: anywhere;
|
|
256
|
+
display: -webkit-box;
|
|
257
|
+
-webkit-box-orient: vertical;
|
|
258
|
+
overflow: hidden;
|
|
259
|
+
-webkit-line-clamp: var(--deep-expanding-menu-panel-heading-line-clamp, none);
|
|
260
|
+
line-clamp: var(--deep-expanding-menu-panel-heading-line-clamp, none);
|
|
229
261
|
}
|
|
230
262
|
|
|
231
|
-
.
|
|
263
|
+
.deep-expanding-menu-group-list {
|
|
232
264
|
display: grid;
|
|
233
|
-
grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
|
|
265
|
+
grid-template-columns: repeat(auto-fill, minmax(min(100%, 12rem), 1fr));
|
|
234
266
|
gap: var(--deep-expanding-menu-panel-list-gap, 1.2rem);
|
|
267
|
+
list-style: none;
|
|
235
268
|
padding-inline-start: 0;
|
|
236
|
-
margin-block
|
|
269
|
+
margin-block: 0 0.8rem;
|
|
237
270
|
|
|
238
|
-
.
|
|
271
|
+
.deep-expanding-menu-group-item {
|
|
239
272
|
display: block;
|
|
273
|
+
min-inline-size: 0;
|
|
240
274
|
|
|
241
|
-
a.
|
|
275
|
+
a.deep-expanding-menu-group-link {
|
|
242
276
|
display: inline-block;
|
|
243
|
-
|
|
277
|
+
max-inline-size: 100%;
|
|
278
|
+
overflow-wrap: anywhere;
|
|
279
|
+
color: var(--deep-expanding-menu-group-link-colour, var(--theme-text));
|
|
244
280
|
text-decoration: none;
|
|
245
281
|
padding-block: 0.8rem;
|
|
246
282
|
|
|
@@ -251,14 +287,14 @@ watch(
|
|
|
251
287
|
&:hover,
|
|
252
288
|
&:focus-visible {
|
|
253
289
|
cursor: pointer;
|
|
254
|
-
border-color: var(--deep-expanding-menu-group-link-border-colour-hover, var(--
|
|
290
|
+
border-color: var(--deep-expanding-menu-group-link-border-colour-hover, var(--theme-text));
|
|
255
291
|
}
|
|
256
292
|
}
|
|
257
293
|
}
|
|
258
294
|
}
|
|
259
295
|
}
|
|
260
296
|
|
|
261
|
-
&:has(> .
|
|
297
|
+
&:has(> .deep-expanding-menu-group-toggle[aria-expanded="true"]) {
|
|
262
298
|
--_icon-transform: scaleY(-1);
|
|
263
299
|
}
|
|
264
300
|
}
|
|
@@ -267,3 +303,4 @@ watch(
|
|
|
267
303
|
}
|
|
268
304
|
}
|
|
269
305
|
</style>
|
|
306
|
+
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { computed, ref } from "vue";
|
|
1
2
|
import DeepExpandingMenu from "../DeepExpandingMenu.vue";
|
|
3
|
+
import CanvasSwitcher from "../../../../01.atoms/canvas-switcher/CanvasSwitcher.vue";
|
|
2
4
|
import type { Meta, StoryObj } from "@nuxtjs/storybook";
|
|
3
|
-
import type { ResponsiveHeaderNavItem } from "~/types/components";
|
|
5
|
+
import type { MediaCanvas, ResponsiveHeaderNavItem } from "~/types/components";
|
|
4
6
|
|
|
5
7
|
const navLinks: ResponsiveHeaderNavItem[] = [
|
|
6
8
|
{ name: "Home", path: "/" },
|
|
@@ -16,63 +18,181 @@ const navLinks: ResponsiveHeaderNavItem[] = [
|
|
|
16
18
|
{ name: "Contact", path: "/contact" },
|
|
17
19
|
];
|
|
18
20
|
|
|
19
|
-
const
|
|
21
|
+
const stressNavLinks: ResponsiveHeaderNavItem[] = [
|
|
22
|
+
{ name: "H", path: "/" },
|
|
23
|
+
{
|
|
24
|
+
name: "Dienstleistungsangebotsübersichtsseite",
|
|
25
|
+
childLinksTitle:
|
|
26
|
+
"Unsere vollständige Übersicht aller Dienstleistungen, Behandlungen und Pflegeangebote für Haut und Haar in Northtown",
|
|
27
|
+
childLinks: [
|
|
28
|
+
{ name: "Haarschnitt", path: "/services/haircuts" },
|
|
29
|
+
{ name: "https://example.com/a/very/long/unbroken/path/that/never/wraps/on/its/own", path: "/long-url" },
|
|
30
|
+
{ name: "🎨 Colouring", path: "/services/colouring" },
|
|
31
|
+
{ name: "Styling", path: "/services/styling-1" },
|
|
32
|
+
{ name: "Styling", path: "/services/styling-2" },
|
|
33
|
+
{ name: "<b>Not bold</b>", path: "/services/html" },
|
|
34
|
+
{ name: "قص الشعر", path: "/services/rtl" },
|
|
35
|
+
...Array.from({ length: 24 }, (_, i) => ({ name: `Treatment ${i + 1}`, path: `/services/treatment-${i + 1}` })),
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
{ name: "Gruppe ohne Titel", childLinks: [{ name: "Only link", path: "/only" }] },
|
|
39
|
+
{ name: "Empty group", childLinksTitle: "Nothing here yet", childLinks: [] },
|
|
40
|
+
{ name: "Supercalifragilisticexpialidociousandthensomemoretext", path: "/unbroken" },
|
|
41
|
+
{ name: "🙂", path: "/emoji" },
|
|
42
|
+
{ name: "Contact", path: "/contact" },
|
|
43
|
+
{ name: "Contact", path: "/contact" },
|
|
44
|
+
{
|
|
45
|
+
name: "About us and our story",
|
|
46
|
+
childLinksTitle: "About Alex Morgan",
|
|
47
|
+
childLinks: [
|
|
48
|
+
{ name: "Team", path: "/about/team" },
|
|
49
|
+
{ name: "History", path: "/about/history" },
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
type LineClamp = "none" | "1" | "2" | "3";
|
|
55
|
+
|
|
56
|
+
// Story-only arg: drives a CSS token, not a DeepExpandingMenu prop. See the argTypes entry.
|
|
57
|
+
type StoryArgs = InstanceType<typeof DeepExpandingMenu>["$props"] & {
|
|
58
|
+
headingLineClamp: LineClamp;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const meta: Meta<StoryArgs> = {
|
|
20
62
|
title: "Molecules/DeepExpandingMenu",
|
|
21
63
|
component: DeepExpandingMenu,
|
|
22
64
|
argTypes: {
|
|
65
|
+
headingLineClamp: {
|
|
66
|
+
control: "select",
|
|
67
|
+
options: ["none", "1", "2", "3"] satisfies LineClamp[],
|
|
68
|
+
description:
|
|
69
|
+
"**Story control, not a prop.** Sets the `--deep-expanding-menu-panel-heading-line-clamp` CSS token on a wrapper so you can try it here. " +
|
|
70
|
+
"To use it in an app, set the token in your own CSS, e.g. `.site-nav { --deep-expanding-menu-panel-heading-line-clamp: 1; }`. " +
|
|
71
|
+
"`1` is single-line ellipsis, `none` (the default) shows everything.",
|
|
72
|
+
table: { category: "CSS tokens (story only, set in your CSS)", defaultValue: { summary: "none" } },
|
|
73
|
+
},
|
|
23
74
|
tag: {
|
|
24
75
|
control: { type: "select" },
|
|
25
|
-
options: ["div", "section", "nav"
|
|
76
|
+
options: ["div", "section", "nav"],
|
|
26
77
|
description: "Root element tag",
|
|
78
|
+
table: { category: "Basic", defaultValue: { summary: "nav" } },
|
|
79
|
+
},
|
|
80
|
+
ariaLabel: {
|
|
81
|
+
control: "text",
|
|
82
|
+
description: "Accessible name for the root. Set it when the page has more than one `<nav>`",
|
|
27
83
|
table: { category: "Basic" },
|
|
28
84
|
},
|
|
29
|
-
navLinks: {
|
|
85
|
+
navLinks: {
|
|
86
|
+
control: "object",
|
|
87
|
+
description: "Top-level items: `path` renders a link, `childLinks` renders a toggle and panel",
|
|
88
|
+
table: { category: "Content" },
|
|
89
|
+
},
|
|
30
90
|
styleClassPassthrough: { table: { disable: true } },
|
|
31
91
|
},
|
|
32
92
|
args: {
|
|
33
93
|
tag: "nav",
|
|
34
94
|
navLinks,
|
|
95
|
+
headingLineClamp: "none",
|
|
35
96
|
},
|
|
97
|
+
decorators: [
|
|
98
|
+
(story, context) => ({
|
|
99
|
+
components: { story, CanvasSwitcher },
|
|
100
|
+
setup() {
|
|
101
|
+
const canvasName = ref<MediaCanvas>(context.parameters.initialCanvas ?? "fullWidthCanvas");
|
|
102
|
+
return { canvasName };
|
|
103
|
+
},
|
|
104
|
+
template: `
|
|
105
|
+
<div style="padding: 1.2rem 1.6rem; border-block-end: 1px solid currentColor;">
|
|
106
|
+
<CanvasSwitcher v-model:canvas-name="canvasName" />
|
|
107
|
+
</div>
|
|
108
|
+
<div :class="canvasName" style="margin-inline: auto; padding: 2rem; outline: 1px dashed currentColor;">
|
|
109
|
+
<story />
|
|
110
|
+
</div>
|
|
111
|
+
`,
|
|
112
|
+
}),
|
|
113
|
+
],
|
|
36
114
|
parameters: {
|
|
115
|
+
layout: "fullscreen",
|
|
37
116
|
docs: {
|
|
38
117
|
description: {
|
|
39
118
|
component:
|
|
40
|
-
"
|
|
119
|
+
"Top-level nav row where each item is a direct link (`path`) or a toggle that opens a panel of child links (`childLinks`, with an optional `childLinksTitle` heading). " +
|
|
120
|
+
"Built on CSS anchor positioning and the Popover API, with a JS fallback for Safari 16-18. Props: `navLinks`, `tag`, `ariaLabel`. " +
|
|
121
|
+
"See `DeepExpandingMenuClassic` for the `<details>`-based alternative.",
|
|
41
122
|
},
|
|
42
123
|
},
|
|
43
124
|
},
|
|
44
125
|
};
|
|
45
126
|
|
|
46
127
|
export default meta;
|
|
47
|
-
type Story = StoryObj<
|
|
128
|
+
type Story = StoryObj<StoryArgs>;
|
|
129
|
+
|
|
130
|
+
function useStorySetup(args: StoryArgs) {
|
|
131
|
+
const componentArgs = computed(() => {
|
|
132
|
+
const { headingLineClamp: _headingLineClamp, ...rest } = args;
|
|
133
|
+
return rest;
|
|
134
|
+
});
|
|
135
|
+
const tokenStyles = computed(() => ({
|
|
136
|
+
"--deep-expanding-menu-panel-heading-line-clamp": args.headingLineClamp,
|
|
137
|
+
}));
|
|
138
|
+
return { componentArgs, tokenStyles };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const render = (args: StoryArgs) => ({
|
|
142
|
+
components: { DeepExpandingMenu },
|
|
143
|
+
setup() {
|
|
144
|
+
return useStorySetup(args);
|
|
145
|
+
},
|
|
146
|
+
template: `<div :style="tokenStyles"><DeepExpandingMenu v-bind="componentArgs" /></div>`,
|
|
147
|
+
});
|
|
48
148
|
|
|
49
149
|
export const Default: Story = {
|
|
50
|
-
render
|
|
51
|
-
components: { DeepExpandingMenu },
|
|
52
|
-
setup() {
|
|
53
|
-
return { args };
|
|
54
|
-
},
|
|
55
|
-
template: `<DeepExpandingMenu v-bind="args" style="padding: 4rem;" />`,
|
|
56
|
-
}),
|
|
150
|
+
render,
|
|
57
151
|
};
|
|
58
152
|
|
|
59
153
|
export const CustomColours: Story = {
|
|
154
|
+
name: "Custom Colours",
|
|
60
155
|
render: (args) => ({
|
|
61
156
|
components: { DeepExpandingMenu },
|
|
62
157
|
setup() {
|
|
63
|
-
return
|
|
158
|
+
return useStorySetup(args);
|
|
64
159
|
},
|
|
65
160
|
template: `
|
|
66
|
-
<
|
|
67
|
-
|
|
68
|
-
style="
|
|
69
|
-
|
|
161
|
+
<div
|
|
162
|
+
:style="tokenStyles"
|
|
163
|
+
style="--deep-expanding-menu-panel-background-colour: #1a1a1a; --deep-expanding-menu-panel-border-colour: transparent; --deep-expanding-menu-group-link-colour: white; --deep-expanding-menu-group-link-border-colour-hover: white; --deep-expanding-menu-panel-heading-colour: #aaaaaa;"
|
|
164
|
+
>
|
|
165
|
+
<DeepExpandingMenu v-bind="componentArgs" />
|
|
166
|
+
</div>
|
|
70
167
|
`,
|
|
71
168
|
}),
|
|
72
169
|
parameters: {
|
|
73
170
|
docs: {
|
|
74
171
|
description: {
|
|
75
|
-
story: "Overriding the public
|
|
172
|
+
story: "Overriding the public `--deep-expanding-menu-*` tokens on a wrapper element.",
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
export const StressTest: Story = {
|
|
179
|
+
name: "Stress Test (Worst-Case Data)",
|
|
180
|
+
args: {
|
|
181
|
+
navLinks: stressNavLinks,
|
|
182
|
+
},
|
|
183
|
+
render,
|
|
184
|
+
parameters: {
|
|
185
|
+
initialCanvas: "mobileCanvas",
|
|
186
|
+
docs: {
|
|
187
|
+
story: { inline: false, height: "720px" },
|
|
188
|
+
description: {
|
|
189
|
+
story:
|
|
190
|
+
"Hostile nav data at every `CanvasSwitcher` width. Check that: the top-level row wraps instead of overflowing; " +
|
|
191
|
+
"the long German label and the unbroken word break inside the canvas; the caret stays beside a wrapped toggle label; " +
|
|
192
|
+
"the first panel's long heading wraps (try the story-only `headingLineClamp` CSS token control), its unbroken URL link stays inside the panel, " +
|
|
193
|
+
"`<b>Not bold</b>` renders as text, the right-to-left link reads correctly, and its 31 links scroll inside the panel; " +
|
|
194
|
+
"duplicate `Styling` and `Contact` items both render; a group without a title shows its list only; " +
|
|
195
|
+
"an empty group opens with its heading and no list; the last group's panel flips to stay on screen near the right edge.",
|
|
76
196
|
},
|
|
77
197
|
},
|
|
78
198
|
},
|