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.
- package/.claude/hooks/check-component-update.sh +30 -1
- package/.claude/skills/components/accordian-core.md +7 -7
- package/.claude/skills/components/breadcrumb.md +49 -0
- package/.claude/skills/components/content-docs.md +2 -1
- package/.claude/skills/components/expanding-panel.md +5 -5
- package/.claude/skills/components/navigation-items.md +1 -0
- package/.claude/skills/components/responsive-header.md +1 -0
- package/.claude/skills/components/service-detail.md +156 -0
- package/.claude/skills/components/services-card-grid.md +9 -9
- package/.claude/skills/components/services-card.md +82 -30
- package/.claude/skills/index.md +3 -1
- package/.claude/skills/qa-panel.md +2 -2
- package/.vscode/srcdev-component-breadcrumb.code-snippets +14 -0
- package/.vscode/srcdev-component-service-detail.code-snippets +49 -0
- package/.vscode/srcdev-component-services-card.code-snippets +108 -0
- package/app/components/01.atoms/content-wrappers/docs-pages/ContentDocs.vue +22 -16
- package/app/components/01.atoms/navigation/breadcrumb/Breadcrumb.vue +94 -0
- package/app/components/01.atoms/navigation/breadcrumb/CONSUMER-STYLING.md +32 -0
- package/app/components/01.atoms/navigation/breadcrumb/stories/Breadcrumb.stories.ts +87 -0
- package/app/components/01.atoms/navigation/breadcrumb/tests/Breadcrumb.spec.ts +87 -0
- package/app/components/01.atoms/navigation/breadcrumb/tests/__snapshots__/Breadcrumb.spec.ts.snap +13 -0
- package/app/components/02.molecules/expandable/accordian/AccordianCore.vue +5 -1
- package/app/components/02.molecules/expandable/accordian/tests/AccordianCore.spec.ts +22 -14
- package/app/components/02.molecules/expandable/accordian/tests/__snapshots__/AccordianCore.spec.ts.snap +42 -28
- package/app/components/02.molecules/expandable/expanding-panel/CONSUMER-STYLING.md +8 -10
- package/app/components/02.molecules/expandable/expanding-panel/ExpandingPanel.vue +15 -47
- package/app/components/02.molecules/expandable/expanding-panel/tests/__snapshots__/ExpandingPanel.spec.ts.snap +4 -12
- package/app/components/03.organisms/responsive-header/NavigationItems.vue +91 -4
- package/app/components/03.organisms/responsive-header/ResponsiveHeader.vue +5 -1
- package/app/components/03.organisms/responsive-header/tests/NavigationItems.spec.ts +2 -2
- package/app/components/03.organisms/responsive-header/tests/__snapshots__/NavigationItems.spec.ts.snap +13 -13
- package/app/components/03.organisms/responsive-header/tests/__snapshots__/ResponsiveHeader.spec.ts.snap +13 -13
- package/app/components/03.organisms/services/service-detail/CONSUMER-STYLING.md +181 -0
- package/app/components/03.organisms/services/service-detail/ServiceDetail.vue +480 -0
- package/app/components/03.organisms/services/service-detail/stories/ServiceDetail.stories.ts +282 -0
- package/app/components/03.organisms/services/service-detail/tests/ServiceDetail.spec.ts +270 -0
- package/app/components/03.organisms/services/service-detail/tests/__snapshots__/ServiceDetail.spec.ts.snap +99 -0
- package/app/components/03.organisms/services/services-card/CONSUMER-STYLING.md +129 -0
- package/app/components/03.organisms/services/services-card/ServicesCard.vue +153 -39
- package/app/components/03.organisms/services/services-card/stories/ServicesCard.stories.ts +65 -0
- package/app/components/03.organisms/services/services-card/tests/ServicesCard.spec.ts +82 -0
- package/app/components/03.organisms/services/services-card/tests/__snapshots__/ServicesCard.spec.ts.snap +13 -5
- package/app/components/03.organisms/services/services-grids/ServicesCardGrid.vue +3 -7
- package/app/components/03.organisms/services/services-grids/stories/ServicesCardGrid.stories.ts +126 -2
- package/app/components/03.organisms/services/services-grids/stories/ServicesSectionGrid.stories.ts +6 -0
- package/app/components/03.organisms/services/services-grids/tests/__snapshots__/ServicesCardGrid.spec.ts.snap +51 -27
- package/app/components/03.organisms/services/services-section/ServicesSection.vue +19 -0
- package/app/components/03.organisms/services/services-section/tests/__snapshots__/ServicesSection.spec.ts.snap +8 -8
- package/app/types/components/breadcrumb.ts +4 -0
- package/app/types/components/index.ts +1 -0
- package/package.json +2 -2
- package/app/pages/auto-grid.vue +0 -328
- package/app/pages/banner-video.vue +0 -238
- package/app/pages/forms/examples/buttons/index.vue +0 -259
- package/app/pages/forms/examples/material/checkbox-radio-panels.vue +0 -244
- package/app/pages/forms/examples/material/cssbattle.vue +0 -60
- package/app/pages/forms/examples/material/text-fields.vue +0 -910
- package/app/pages/grid-stack.vue +0 -252
- package/app/pages/index.vue +0 -127
- package/app/pages/page-hero-highlights.vue +0 -204
- package/app/pages/samaritan.vue +0 -327
- package/app/pages/typography/hero-text.vue +0 -97
- package/app/pages/typography/index.vue +0 -39
- package/app/pages/typography/page-body.vue +0 -171
- package/app/pages/typography/page-heading.vue +0 -76
- package/app/pages/typography/page-link.vue +0 -103
- package/app/pages/ui/accordian.vue +0 -211
- package/app/pages/ui/anchor-scroll-tab-navigation.vue +0 -191
- package/app/pages/ui/anchor-scroll.vue +0 -367
- package/app/pages/ui/animated-svg-text.vue +0 -85
- package/app/pages/ui/block-decorators.vue +0 -142
- package/app/pages/ui/card-core.vue +0 -82
- package/app/pages/ui/carousel-basic.vue +0 -292
- package/app/pages/ui/carousel-flip.vue +0 -449
- package/app/pages/ui/carousel-infinite.vue +0 -260
- package/app/pages/ui/clipped-panels.vue +0 -101
- package/app/pages/ui/contact-section.vue +0 -323
- package/app/pages/ui/container-glow.vue +0 -106
- package/app/pages/ui/content-width.vue +0 -126
- package/app/pages/ui/deep-expanding-menu.vue +0 -138
- package/app/pages/ui/display-avatar.vue +0 -253
- package/app/pages/ui/display-banner.vue +0 -78
- package/app/pages/ui/display-chip.vue +0 -367
- package/app/pages/ui/display-details.vue +0 -171
- package/app/pages/ui/display-dialog.vue +0 -344
- package/app/pages/ui/display-pill.vue +0 -396
- package/app/pages/ui/display-prompt.vue +0 -284
- package/app/pages/ui/display-toast.vue +0 -311
- package/app/pages/ui/expanding-panel.vue +0 -326
- package/app/pages/ui/glowing-border.vue +0 -111
- package/app/pages/ui/layout-content-docs.vue +0 -72
- package/app/pages/ui/layout-grid-a.vue +0 -96
- package/app/pages/ui/layout-grid-b.vue +0 -132
- package/app/pages/ui/magnetic-navigation.vue +0 -50
- package/app/pages/ui/marquee-scroller.vue +0 -99
- package/app/pages/ui/mask-element.vue +0 -104
- package/app/pages/ui/masonry-columns.vue +0 -55
- package/app/pages/ui/masonry-grid-ordered-experiment.vue +0 -79
- package/app/pages/ui/masonry-grid-ordered.vue +0 -56
- package/app/pages/ui/masonry-grid-sorted.vue +0 -55
- package/app/pages/ui/masonry-grid.vue +0 -55
- package/app/pages/ui/navigation/navigation-horizontal.vue +0 -484
- package/app/pages/ui/navigation/site-navigation/about.vue +0 -36
- package/app/pages/ui/navigation/site-navigation/contact.vue +0 -39
- package/app/pages/ui/navigation/site-navigation/index.vue +0 -38
- package/app/pages/ui/navigation/site-navigation/portfolio.vue +0 -43
- package/app/pages/ui/navigation/site-navigation/services.vue +0 -42
- package/app/pages/ui/navigation/tab-navigation.vue +0 -493
- package/app/pages/ui/page-row.vue +0 -127
- package/app/pages/ui/price-list.vue +0 -65
- package/app/pages/ui/profile-section.vue +0 -142
- package/app/pages/ui/qr-code/[componentName].vue +0 -218
- package/app/pages/ui/rotating-carousel.vue +0 -154
- package/app/pages/ui/scroll-reveal-image.vue +0 -483
- package/app/pages/ui/section-parallax.vue +0 -54
- package/app/pages/ui/services/colour-finder.vue +0 -43
- package/app/pages/ui/services/services-cards.vue +0 -57
- package/app/pages/ui/services/services-section/[slug].vue +0 -61
- package/app/pages/ui/services/services-sections-compact.vue +0 -64
- package/app/pages/ui/settings.vue +0 -54
- package/app/pages/ui/simple-grid.vue +0 -55
- package/app/pages/ui/slider-gallery.vue +0 -261
- package/app/pages/ui/tabs-y.vue +0 -107
- package/app/pages/ui/tabs.vue +0 -189
- package/app/pages/ui/tooltips.vue +0 -104
- package/app/pages/ui/wipe-away-vertical.vue +0 -129
|
@@ -74,11 +74,11 @@ describe("AccordianCore", () => {
|
|
|
74
74
|
|
|
75
75
|
// ─── Item count ───────────────────────────────────────────────────────────
|
|
76
76
|
|
|
77
|
-
it("renders the correct number of
|
|
77
|
+
it("renders the correct number of panel components", async () => {
|
|
78
78
|
const wrapper = await mountSuspended(AccordianCore, {
|
|
79
79
|
props: { itemCount: 4 },
|
|
80
80
|
});
|
|
81
|
-
expect(wrapper.findAll(".
|
|
81
|
+
expect(wrapper.findAll(".accordian-item")).toHaveLength(4);
|
|
82
82
|
});
|
|
83
83
|
|
|
84
84
|
it("renders no ExpandingPanel components when itemCount is 0", async () => {
|
|
@@ -95,15 +95,15 @@ describe("AccordianCore", () => {
|
|
|
95
95
|
|
|
96
96
|
// ─── variant ──────────────────────────────────────────────────────────────
|
|
97
97
|
|
|
98
|
-
it("renders
|
|
98
|
+
it("renders ExpandingPanelClassic by default (variant: classic)", async () => {
|
|
99
99
|
const wrapper = await mountSuspended(AccordianCore, {
|
|
100
100
|
props: { itemCount: 2 },
|
|
101
101
|
});
|
|
102
|
-
expect(wrapper.findAllComponents({ name: "
|
|
103
|
-
expect(wrapper.findAllComponents({ name: "
|
|
102
|
+
expect(wrapper.findAllComponents({ name: "ExpandingPanelClassic" })).toHaveLength(2);
|
|
103
|
+
expect(wrapper.findAllComponents({ name: "ExpandingPanel" })).toHaveLength(0);
|
|
104
104
|
});
|
|
105
105
|
|
|
106
|
-
it("renders ExpandingPanelClassic when variant is classic", async () => {
|
|
106
|
+
it("renders ExpandingPanelClassic when variant is classic (explicit)", async () => {
|
|
107
107
|
const wrapper = await mountSuspended(AccordianCore, {
|
|
108
108
|
props: { itemCount: 2, variant: "classic" },
|
|
109
109
|
});
|
|
@@ -111,6 +111,14 @@ describe("AccordianCore", () => {
|
|
|
111
111
|
expect(wrapper.findAllComponents({ name: "ExpandingPanel" })).toHaveLength(0);
|
|
112
112
|
});
|
|
113
113
|
|
|
114
|
+
it("renders ExpandingPanel when variant is modern", async () => {
|
|
115
|
+
const wrapper = await mountSuspended(AccordianCore, {
|
|
116
|
+
props: { itemCount: 2, variant: "modern" },
|
|
117
|
+
});
|
|
118
|
+
expect(wrapper.findAllComponents({ name: "ExpandingPanel" })).toHaveLength(2);
|
|
119
|
+
expect(wrapper.findAllComponents({ name: "ExpandingPanelClassic" })).toHaveLength(0);
|
|
120
|
+
});
|
|
121
|
+
|
|
114
122
|
it("forwards props identically to ExpandingPanelClassic when variant is classic", async () => {
|
|
115
123
|
const wrapper = await mountSuspended(AccordianCore, {
|
|
116
124
|
props: { itemCount: 2, name: "classic-accordian", animationDuration: 500, variant: "classic" },
|
|
@@ -122,11 +130,11 @@ describe("AccordianCore", () => {
|
|
|
122
130
|
});
|
|
123
131
|
});
|
|
124
132
|
|
|
125
|
-
// ─── Props forwarded to ExpandingPanel
|
|
133
|
+
// ─── Props forwarded to ExpandingPanel (variant: modern) ─────────────────
|
|
126
134
|
|
|
127
135
|
it("forwards animationDuration to every ExpandingPanel", async () => {
|
|
128
136
|
const wrapper = await mountSuspended(AccordianCore, {
|
|
129
|
-
props: { itemCount: 3, animationDuration: 500 },
|
|
137
|
+
props: { itemCount: 3, animationDuration: 500, variant: "modern" },
|
|
130
138
|
});
|
|
131
139
|
wrapper.findAllComponents({ name: "ExpandingPanel" }).forEach((panel) => {
|
|
132
140
|
expect(panel.props("animationDuration")).toBe(500);
|
|
@@ -135,7 +143,7 @@ describe("AccordianCore", () => {
|
|
|
135
143
|
|
|
136
144
|
it("forwards name to every ExpandingPanel", async () => {
|
|
137
145
|
const wrapper = await mountSuspended(AccordianCore, {
|
|
138
|
-
props: { itemCount: 2, name: "test-accordian" },
|
|
146
|
+
props: { itemCount: 2, name: "test-accordian", variant: "modern" },
|
|
139
147
|
});
|
|
140
148
|
wrapper.findAllComponents({ name: "ExpandingPanel" }).forEach((panel) => {
|
|
141
149
|
expect(panel.props("name")).toBe("test-accordian");
|
|
@@ -144,7 +152,7 @@ describe("AccordianCore", () => {
|
|
|
144
152
|
|
|
145
153
|
it("passes accordian-item styleClassPassthrough to every ExpandingPanel", async () => {
|
|
146
154
|
const wrapper = await mountSuspended(AccordianCore, {
|
|
147
|
-
props: { itemCount: 2 },
|
|
155
|
+
props: { itemCount: 2, variant: "modern" },
|
|
148
156
|
});
|
|
149
157
|
wrapper.findAllComponents({ name: "ExpandingPanel" }).forEach((panel) => {
|
|
150
158
|
expect(panel.props("styleClassPassthrough")).toEqual(["accordian-item"]);
|
|
@@ -153,11 +161,11 @@ describe("AccordianCore", () => {
|
|
|
153
161
|
|
|
154
162
|
// ─── Default prop values ──────────────────────────────────────────────────
|
|
155
163
|
|
|
156
|
-
it("defaults animationDuration to 300 on
|
|
164
|
+
it("defaults animationDuration to 300 on ExpandingPanelClassic when not provided", async () => {
|
|
157
165
|
const wrapper = await mountSuspended(AccordianCore, {
|
|
158
166
|
props: { itemCount: 1 },
|
|
159
167
|
});
|
|
160
|
-
const panel = wrapper.findComponent({ name: "
|
|
168
|
+
const panel = wrapper.findComponent({ name: "ExpandingPanelClassic" });
|
|
161
169
|
expect(panel.props("animationDuration")).toBe(300);
|
|
162
170
|
});
|
|
163
171
|
|
|
@@ -167,7 +175,7 @@ describe("AccordianCore", () => {
|
|
|
167
175
|
expect(vm.name).toBeUndefined();
|
|
168
176
|
expect(vm.itemCount).toBe(0);
|
|
169
177
|
expect(vm.animationDuration).toBe(300);
|
|
170
|
-
expect(vm.variant).toBe("
|
|
178
|
+
expect(vm.variant).toBe("classic");
|
|
171
179
|
expect(vm.styleClassPassthrough).toEqual([]);
|
|
172
180
|
});
|
|
173
181
|
|
|
@@ -241,7 +249,7 @@ describe("AccordianCore", () => {
|
|
|
241
249
|
"accordian-2-summary": "<span>Gamma</span>",
|
|
242
250
|
},
|
|
243
251
|
});
|
|
244
|
-
const panels = wrapper.findAllComponents({ name: "
|
|
252
|
+
const panels = wrapper.findAllComponents({ name: "ExpandingPanelClassic" });
|
|
245
253
|
expect(panels[0]?.text()).toContain("Alpha");
|
|
246
254
|
expect(panels[1]?.text()).toContain("Beta");
|
|
247
255
|
expect(panels[2]?.text()).toContain("Gamma");
|
|
@@ -2,78 +2,92 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`AccordianCore > renders correct HTML structure with all props set 1`] = `
|
|
4
4
|
"<div class="display-accordian extra-class">
|
|
5
|
-
<div class="expanding-panel accordian-item" icon-size="medium">
|
|
6
|
-
<details class="expanding-panel-details" name="snapshot-accordian">
|
|
7
|
-
<summary id="id-snapshot-accordian-trigger" class="expanding-panel-summary" aria-controls="id-snapshot-accordian-content" aria-expanded="false">
|
|
5
|
+
<div class="expanding-panel-classic accordian-item" icon-size="medium">
|
|
6
|
+
<details class="expanding-panel-classic-details" name="snapshot-accordian">
|
|
7
|
+
<summary id="id-snapshot-accordian-trigger" class="expanding-panel-classic-summary" aria-controls="id-snapshot-accordian-content" aria-expanded="false">
|
|
8
8
|
<div class="label-wrapper"></div>
|
|
9
9
|
<div class="icon-wrapper"><span class="iconify i-bi:caret-down-fill icon" aria-hidden="true"></span></div>
|
|
10
10
|
</summary>
|
|
11
|
-
<div id="id-snapshot-accordian-content" class="expanding-panel-content" aria-labelledby="id-snapshot-accordian-trigger" role="region"><div class="inner"></div></div>
|
|
12
11
|
</details>
|
|
12
|
+
<div id="id-snapshot-accordian-content" class="expanding-panel-classic-content" aria-labelledby="id-snapshot-accordian-trigger" role="region">
|
|
13
|
+
<div class="inner"></div>
|
|
14
|
+
</div>
|
|
13
15
|
</div>
|
|
14
|
-
<div class="expanding-panel accordian-item" icon-size="medium">
|
|
15
|
-
<details class="expanding-panel-details" name="snapshot-accordian">
|
|
16
|
-
<summary id="id-snapshot-accordian-trigger" class="expanding-panel-summary" aria-controls="id-snapshot-accordian-content" aria-expanded="false">
|
|
16
|
+
<div class="expanding-panel-classic accordian-item" icon-size="medium">
|
|
17
|
+
<details class="expanding-panel-classic-details" name="snapshot-accordian">
|
|
18
|
+
<summary id="id-snapshot-accordian-trigger" class="expanding-panel-classic-summary" aria-controls="id-snapshot-accordian-content" aria-expanded="false">
|
|
17
19
|
<div class="label-wrapper"></div>
|
|
18
20
|
<div class="icon-wrapper"><span class="iconify i-bi:caret-down-fill icon" aria-hidden="true"></span></div>
|
|
19
21
|
</summary>
|
|
20
|
-
<div id="id-snapshot-accordian-content" class="expanding-panel-content" aria-labelledby="id-snapshot-accordian-trigger" role="region"><div class="inner"></div></div>
|
|
21
22
|
</details>
|
|
23
|
+
<div id="id-snapshot-accordian-content" class="expanding-panel-classic-content" aria-labelledby="id-snapshot-accordian-trigger" role="region">
|
|
24
|
+
<div class="inner"></div>
|
|
25
|
+
</div>
|
|
22
26
|
</div>
|
|
23
|
-
<div class="expanding-panel accordian-item" icon-size="medium">
|
|
24
|
-
<details class="expanding-panel-details" name="snapshot-accordian">
|
|
25
|
-
<summary id="id-snapshot-accordian-trigger" class="expanding-panel-summary" aria-controls="id-snapshot-accordian-content" aria-expanded="false">
|
|
27
|
+
<div class="expanding-panel-classic accordian-item" icon-size="medium">
|
|
28
|
+
<details class="expanding-panel-classic-details" name="snapshot-accordian">
|
|
29
|
+
<summary id="id-snapshot-accordian-trigger" class="expanding-panel-classic-summary" aria-controls="id-snapshot-accordian-content" aria-expanded="false">
|
|
26
30
|
<div class="label-wrapper"></div>
|
|
27
31
|
<div class="icon-wrapper"><span class="iconify i-bi:caret-down-fill icon" aria-hidden="true"></span></div>
|
|
28
32
|
</summary>
|
|
29
|
-
<div id="id-snapshot-accordian-content" class="expanding-panel-content" aria-labelledby="id-snapshot-accordian-trigger" role="region"><div class="inner"></div></div>
|
|
30
33
|
</details>
|
|
34
|
+
<div id="id-snapshot-accordian-content" class="expanding-panel-classic-content" aria-labelledby="id-snapshot-accordian-trigger" role="region">
|
|
35
|
+
<div class="inner"></div>
|
|
36
|
+
</div>
|
|
31
37
|
</div>
|
|
32
38
|
</div>"
|
|
33
39
|
`;
|
|
34
40
|
|
|
35
41
|
exports[`AccordianCore > renders correct HTML structure with default props 1`] = `
|
|
36
42
|
"<div class="display-accordian">
|
|
37
|
-
<div class="expanding-panel accordian-item" icon-size="medium">
|
|
38
|
-
<details class="expanding-panel-details" name="v-0-0-0">
|
|
39
|
-
<summary id="id-v-0-0-0-trigger" class="expanding-panel-summary" aria-controls="id-v-0-0-0-content" aria-expanded="false">
|
|
43
|
+
<div class="expanding-panel-classic accordian-item" icon-size="medium">
|
|
44
|
+
<details class="expanding-panel-classic-details" name="v-0-0-0">
|
|
45
|
+
<summary id="id-v-0-0-0-trigger" class="expanding-panel-classic-summary" aria-controls="id-v-0-0-0-content" aria-expanded="false">
|
|
40
46
|
<div class="label-wrapper"></div>
|
|
41
47
|
<div class="icon-wrapper"><span class="iconify i-bi:caret-down-fill icon" aria-hidden="true"></span></div>
|
|
42
48
|
</summary>
|
|
43
|
-
<div id="id-v-0-0-0-content" class="expanding-panel-content" aria-labelledby="id-v-0-0-0-trigger" role="region"><div class="inner"></div></div>
|
|
44
49
|
</details>
|
|
50
|
+
<div id="id-v-0-0-0-content" class="expanding-panel-classic-content" aria-labelledby="id-v-0-0-0-trigger" role="region">
|
|
51
|
+
<div class="inner"></div>
|
|
52
|
+
</div>
|
|
45
53
|
</div>
|
|
46
|
-
<div class="expanding-panel accordian-item" icon-size="medium">
|
|
47
|
-
<details class="expanding-panel-details" name="v-0-0-1">
|
|
48
|
-
<summary id="id-v-0-0-1-trigger" class="expanding-panel-summary" aria-controls="id-v-0-0-1-content" aria-expanded="false">
|
|
54
|
+
<div class="expanding-panel-classic accordian-item" icon-size="medium">
|
|
55
|
+
<details class="expanding-panel-classic-details" name="v-0-0-1">
|
|
56
|
+
<summary id="id-v-0-0-1-trigger" class="expanding-panel-classic-summary" aria-controls="id-v-0-0-1-content" aria-expanded="false">
|
|
49
57
|
<div class="label-wrapper"></div>
|
|
50
58
|
<div class="icon-wrapper"><span class="iconify i-bi:caret-down-fill icon" aria-hidden="true"></span></div>
|
|
51
59
|
</summary>
|
|
52
|
-
<div id="id-v-0-0-1-content" class="expanding-panel-content" aria-labelledby="id-v-0-0-1-trigger" role="region"><div class="inner"></div></div>
|
|
53
60
|
</details>
|
|
61
|
+
<div id="id-v-0-0-1-content" class="expanding-panel-classic-content" aria-labelledby="id-v-0-0-1-trigger" role="region">
|
|
62
|
+
<div class="inner"></div>
|
|
63
|
+
</div>
|
|
54
64
|
</div>
|
|
55
65
|
</div>"
|
|
56
66
|
`;
|
|
57
67
|
|
|
58
68
|
exports[`AccordianCore > renders correct HTML structure with populated slots 1`] = `
|
|
59
69
|
"<div class="display-accordian">
|
|
60
|
-
<div class="expanding-panel accordian-item" icon-size="medium">
|
|
61
|
-
<details class="expanding-panel-details" name="v-0-0-0">
|
|
62
|
-
<summary id="id-v-0-0-0-trigger" class="expanding-panel-summary" aria-controls="id-v-0-0-0-content" aria-expanded="false">
|
|
70
|
+
<div class="expanding-panel-classic accordian-item" icon-size="medium">
|
|
71
|
+
<details class="expanding-panel-classic-details" name="v-0-0-0">
|
|
72
|
+
<summary id="id-v-0-0-0-trigger" class="expanding-panel-classic-summary" aria-controls="id-v-0-0-0-content" aria-expanded="false">
|
|
63
73
|
<div class="label-wrapper"><span>Summary 0</span></div>
|
|
64
74
|
<div class="icon-wrapper"><span>Icon 0</span></div>
|
|
65
75
|
</summary>
|
|
66
|
-
<div id="id-v-0-0-0-content" class="expanding-panel-content" aria-labelledby="id-v-0-0-0-trigger" role="region"><div class="inner"><span>Content 0</span></div></div>
|
|
67
76
|
</details>
|
|
77
|
+
<div id="id-v-0-0-0-content" class="expanding-panel-classic-content" aria-labelledby="id-v-0-0-0-trigger" role="region">
|
|
78
|
+
<div class="inner"><span>Content 0</span></div>
|
|
79
|
+
</div>
|
|
68
80
|
</div>
|
|
69
|
-
<div class="expanding-panel accordian-item" icon-size="medium">
|
|
70
|
-
<details class="expanding-panel-details" name="v-0-0-1">
|
|
71
|
-
<summary id="id-v-0-0-1-trigger" class="expanding-panel-summary" aria-controls="id-v-0-0-1-content" aria-expanded="false">
|
|
81
|
+
<div class="expanding-panel-classic accordian-item" icon-size="medium">
|
|
82
|
+
<details class="expanding-panel-classic-details" name="v-0-0-1">
|
|
83
|
+
<summary id="id-v-0-0-1-trigger" class="expanding-panel-classic-summary" aria-controls="id-v-0-0-1-content" aria-expanded="false">
|
|
72
84
|
<div class="label-wrapper"><span>Summary 1</span></div>
|
|
73
85
|
<div class="icon-wrapper"><span>Icon 1</span></div>
|
|
74
86
|
</summary>
|
|
75
|
-
<div id="id-v-0-0-1-content" class="expanding-panel-content" aria-labelledby="id-v-0-0-1-trigger" role="region"><div class="inner"><span>Content 1</span></div></div>
|
|
76
87
|
</details>
|
|
88
|
+
<div id="id-v-0-0-1-content" class="expanding-panel-classic-content" aria-labelledby="id-v-0-0-1-trigger" role="region">
|
|
89
|
+
<div class="inner"><span>Content 1</span></div>
|
|
90
|
+
</div>
|
|
77
91
|
</div>
|
|
78
92
|
</div>"
|
|
79
93
|
`;
|
|
@@ -90,16 +90,14 @@ visual style, pass a modifier class:
|
|
|
90
90
|
- `--expanding-panel-content-gap` and `--expanding-panel-content-z-index` only take effect when
|
|
91
91
|
`contentIsOnTop` is `true` — they're no-ops for the default (in-flow) layout.
|
|
92
92
|
- `background-color`, `padding`, `border`, and shadow are all safe to set directly on
|
|
93
|
-
`.expanding-panel-content`.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
detail of the collapse mechanism, not a styling hook) but styling on `.expanding-panel-content`
|
|
102
|
-
itself still works correctly, same as the `::details-content` path.
|
|
93
|
+
`.expanding-panel-content`. The open/close animation clips via `overflow: clip` on
|
|
94
|
+
`::details-content`, and `.expanding-panel-content` is a child of it, so its own box is
|
|
95
|
+
correctly clipped to the animated height while closed/closing. A wrapper inside the `#content`
|
|
96
|
+
slot works equally well if you prefer to keep the styling scoped to your own markup.
|
|
97
|
+
- **WebKit (Safari/iOS) doesn't support `::details-content` at all**, and `ExpandingPanel` has no
|
|
98
|
+
fallback for it (an `@supports`-based CSS fallback was tried and reverted 2026-08-22 — it didn't
|
|
99
|
+
reliably work). If this panel needs to work correctly on real Apple devices, use
|
|
100
|
+
`ExpandingPanelClassic` instead — see its own `CONSUMER-STYLING.md`.
|
|
103
101
|
- Don't stack multiple `contentIsOnTop` panels as direct siblings (linked via a shared `name` or
|
|
104
102
|
not). The overlay is absolutely positioned so it doesn't push the next element down — which
|
|
105
103
|
means a sibling `ExpandingPanel` placed right after it sits exactly where the overlay renders,
|
|
@@ -23,9 +23,7 @@
|
|
|
23
23
|
:aria-labelledby="`id-${name}-trigger`"
|
|
24
24
|
role="region"
|
|
25
25
|
>
|
|
26
|
-
<
|
|
27
|
-
<slot name="content"></slot>
|
|
28
|
-
</div>
|
|
26
|
+
<slot name="content"></slot>
|
|
29
27
|
</div>
|
|
30
28
|
</details>
|
|
31
29
|
</div>
|
|
@@ -66,6 +64,20 @@ onClickOutside(rootEl, () => {
|
|
|
66
64
|
});
|
|
67
65
|
|
|
68
66
|
if (import.meta.dev) {
|
|
67
|
+
// ::details-content (the animation/positioning mechanism this component relies on) is not
|
|
68
|
+
// supported in WebKit (Safari/iOS) as of 2026-08 — confirmed via real-device testing, not
|
|
69
|
+
// reproducible in Chrome's device-emulation mode since that's still the Blink engine. An
|
|
70
|
+
// earlier @supports-based fallback attempt (2026-08-22) turned out not to reliably kick in
|
|
71
|
+
// either. Prefer ExpandingPanelClassic (or a consumer's own `classic` prop, where offered —
|
|
72
|
+
// see AccordianCore) for anything that needs to work correctly on real Apple devices today.
|
|
73
|
+
console.warn(
|
|
74
|
+
`ExpandingPanel${props.name ? ` "${props.name}"` : ""}: this variant depends on ` +
|
|
75
|
+
"::details-content, which WebKit (Safari/iOS) does not support — the animation and, more " +
|
|
76
|
+
"seriously, contentIsOnTop's overlay positioning silently fail there with no console error. " +
|
|
77
|
+
"Use ExpandingPanelClassic instead if this panel needs to work correctly on real Apple " +
|
|
78
|
+
"devices."
|
|
79
|
+
);
|
|
80
|
+
|
|
69
81
|
watch(
|
|
70
82
|
() => props.contentIsOnTop,
|
|
71
83
|
(value) => {
|
|
@@ -189,50 +201,6 @@ const onDetailsToggle = (event: Event) => {
|
|
|
189
201
|
}
|
|
190
202
|
}
|
|
191
203
|
}
|
|
192
|
-
|
|
193
|
-
/* ::details-content isn't supported in WebKit (Safari/iOS) as of 2026-08 — the two rule
|
|
194
|
-
blocks above are silently dropped there entirely (no error, no animation, and crucially
|
|
195
|
-
content-is-on-top's position: absolute never applies, so the overlay renders in normal
|
|
196
|
-
document flow instead). This reproduces both using ExpandingPanelClassic's
|
|
197
|
-
grid-template-rows technique (broadly supported, including Safari), targeting the real
|
|
198
|
-
.expanding-panel-content element (and its .inner child, matching Classic's structure —
|
|
199
|
-
.inner's own overflow:hidden is what lets the grid row actually collapse to 0, since a
|
|
200
|
-
plain block child's default min-height:auto would otherwise floor it at content height)
|
|
201
|
-
instead of the pseudo-element. */
|
|
202
|
-
@supports not selector(::details-content) {
|
|
203
|
-
.expanding-panel-details {
|
|
204
|
-
.expanding-panel-content {
|
|
205
|
-
display: grid;
|
|
206
|
-
grid-template-rows: 0fr;
|
|
207
|
-
transition: grid-template-rows v-bind(animationDurationStr) ease-in-out;
|
|
208
|
-
will-change: grid-template-rows;
|
|
209
|
-
|
|
210
|
-
.inner {
|
|
211
|
-
overflow: hidden;
|
|
212
|
-
margin-top: 0;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
&[open] .expanding-panel-content {
|
|
217
|
-
grid-template-rows: 1fr;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
&.content-is-on-top {
|
|
223
|
-
@supports not selector(::details-content) {
|
|
224
|
-
.expanding-panel-details {
|
|
225
|
-
position: relative;
|
|
226
|
-
|
|
227
|
-
.expanding-panel-content {
|
|
228
|
-
position: absolute;
|
|
229
|
-
top: calc(100% + var(--expanding-panel-content-gap, 0px));
|
|
230
|
-
inset-inline: 0;
|
|
231
|
-
z-index: var(--expanding-panel-content-z-index, 10);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
204
|
}
|
|
237
205
|
}
|
|
238
206
|
</style>
|
|
@@ -7,9 +7,7 @@ exports[`ExpandingPanel > renders correct HTML structure with all props set 1`]
|
|
|
7
7
|
<div class="label-wrapper"></div>
|
|
8
8
|
<div class="icon-wrapper icon-wrapper--hidden"><span class="iconify i-bi:caret-down-fill icon" aria-hidden="true"></span></div>
|
|
9
9
|
</summary>
|
|
10
|
-
<div id="id-snap-all-content" class="expanding-panel-content" aria-labelledby="id-snap-all-trigger" role="region">
|
|
11
|
-
<div class="inner"></div>
|
|
12
|
-
</div>
|
|
10
|
+
<div id="id-snap-all-content" class="expanding-panel-content" aria-labelledby="id-snap-all-trigger" role="region"></div>
|
|
13
11
|
</details>
|
|
14
12
|
</div>"
|
|
15
13
|
`;
|
|
@@ -21,9 +19,7 @@ exports[`ExpandingPanel > renders correct HTML structure with contentIsOnTop tru
|
|
|
21
19
|
<div class="label-wrapper"></div>
|
|
22
20
|
<div class="icon-wrapper"><span class="iconify i-bi:caret-down-fill icon" aria-hidden="true"></span></div>
|
|
23
21
|
</summary>
|
|
24
|
-
<div id="id-snap-content-on-top-content" class="expanding-panel-content" aria-labelledby="id-snap-content-on-top-trigger" role="region">
|
|
25
|
-
<div class="inner"></div>
|
|
26
|
-
</div>
|
|
22
|
+
<div id="id-snap-content-on-top-content" class="expanding-panel-content" aria-labelledby="id-snap-content-on-top-trigger" role="region"></div>
|
|
27
23
|
</details>
|
|
28
24
|
</div>"
|
|
29
25
|
`;
|
|
@@ -35,9 +31,7 @@ exports[`ExpandingPanel > renders correct HTML structure with default props 1`]
|
|
|
35
31
|
<div class="label-wrapper"></div>
|
|
36
32
|
<div class="icon-wrapper"><span class="iconify i-bi:caret-down-fill icon" aria-hidden="true"></span></div>
|
|
37
33
|
</summary>
|
|
38
|
-
<div id="id-snap-default-content" class="expanding-panel-content" aria-labelledby="id-snap-default-trigger" role="region">
|
|
39
|
-
<div class="inner"></div>
|
|
40
|
-
</div>
|
|
34
|
+
<div id="id-snap-default-content" class="expanding-panel-content" aria-labelledby="id-snap-default-trigger" role="region"></div>
|
|
41
35
|
</details>
|
|
42
36
|
</div>"
|
|
43
37
|
`;
|
|
@@ -50,9 +44,7 @@ exports[`ExpandingPanel > renders correct HTML structure with populated slots 1`
|
|
|
50
44
|
<div class="icon-wrapper"><span>▸</span></div>
|
|
51
45
|
</summary>
|
|
52
46
|
<div id="id-snap-slots-content" class="expanding-panel-content" aria-labelledby="id-snap-slots-trigger" role="region">
|
|
53
|
-
<
|
|
54
|
-
<p>Content text</p>
|
|
55
|
-
</div>
|
|
47
|
+
<p>Content text</p>
|
|
56
48
|
</div>
|
|
57
49
|
</details>
|
|
58
50
|
</div>"
|
|
@@ -56,7 +56,8 @@
|
|
|
56
56
|
role="none"
|
|
57
57
|
@mouseenter="hoveredItemKey = `${String(groupKey)}-${localIndex}`"
|
|
58
58
|
>
|
|
59
|
-
<
|
|
59
|
+
<component
|
|
60
|
+
:is="panelComponent"
|
|
60
61
|
v-model="panelOpenStates[`${String(groupKey)}-${localIndex}`]"
|
|
61
62
|
name="overflow-navigation-group"
|
|
62
63
|
:animation-duration="DETAILS_ANIMATION_DURATION"
|
|
@@ -96,7 +97,7 @@
|
|
|
96
97
|
<div aria-hidden="true" class="overflow-sub-nav-indicator-hovered"></div>
|
|
97
98
|
</div>
|
|
98
99
|
</template>
|
|
99
|
-
</
|
|
100
|
+
</component>
|
|
100
101
|
</li>
|
|
101
102
|
</template>
|
|
102
103
|
</ul>
|
|
@@ -107,17 +108,26 @@
|
|
|
107
108
|
|
|
108
109
|
<script setup lang="ts">
|
|
109
110
|
import type { ResponsiveHeaderState, ResponsiveHeaderNavItem } from "../../../types/components";
|
|
111
|
+
import ExpandingPanel from "../../02.molecules/expandable/expanding-panel/ExpandingPanel.vue";
|
|
112
|
+
import ExpandingPanelClassic from "../../02.molecules/expandable/expanding-panel-classic/ExpandingPanelClassic.vue";
|
|
110
113
|
|
|
111
114
|
interface Props {
|
|
112
115
|
mainNavigationState?: ResponsiveHeaderState;
|
|
116
|
+
panelVariant?: "modern" | "classic";
|
|
113
117
|
styleClassPassthrough?: string | string[];
|
|
114
118
|
}
|
|
115
119
|
|
|
116
120
|
const props = withDefaults(defineProps<Props>(), {
|
|
117
121
|
mainNavigationState: () => ({ clonedNavLinks: {}, navListVisibility: {}, hasSecondNav: false }),
|
|
122
|
+
// Defaults to "classic" — see ExpandingPanel's own dev-mode warning and CLAUDE.md pitfall #19:
|
|
123
|
+
// its ::details-content-based implementation doesn't work correctly on WebKit (Safari/iOS).
|
|
124
|
+
// "modern" is opt-in.
|
|
125
|
+
panelVariant: "classic",
|
|
118
126
|
styleClassPassthrough: () => [],
|
|
119
127
|
});
|
|
120
128
|
|
|
129
|
+
const panelComponent = computed(() => (props.panelVariant === "modern" ? ExpandingPanel : ExpandingPanelClassic));
|
|
130
|
+
|
|
121
131
|
const hoveredItemKey = ref<string | null>(null);
|
|
122
132
|
const hoveredChildKey = ref<string | null>(null);
|
|
123
133
|
|
|
@@ -231,6 +241,12 @@ watch(
|
|
|
231
241
|
}
|
|
232
242
|
|
|
233
243
|
.overflow-navigation-details {
|
|
244
|
+
/* Two variants share this styling, one full block each rather than a merged
|
|
245
|
+
selector list — their DOM shapes differ (modern nests .expanding-panel-content
|
|
246
|
+
*inside* .expanding-panel-details; classic renders .expanding-panel-classic-content
|
|
247
|
+
as a *sibling* of .expanding-panel-classic-details), so the [open] + ... sibling
|
|
248
|
+
combinator below is only structurally correct for the classic block. See
|
|
249
|
+
ExpandingPanel vs ExpandingPanelClassic's own templates. */
|
|
234
250
|
&.expanding-panel {
|
|
235
251
|
margin-block-end: 0;
|
|
236
252
|
|
|
@@ -293,6 +309,69 @@ watch(
|
|
|
293
309
|
}
|
|
294
310
|
}
|
|
295
311
|
}
|
|
312
|
+
|
|
313
|
+
&.expanding-panel-classic {
|
|
314
|
+
margin-block-end: 0;
|
|
315
|
+
|
|
316
|
+
.expanding-panel-classic-details {
|
|
317
|
+
.expanding-panel-classic-summary {
|
|
318
|
+
padding-block: var(--overflow-nav-items-padding-block, 0.8rem);
|
|
319
|
+
padding-inline: var(--overflow-nav-padding-inline, 0.8rem);
|
|
320
|
+
gap: 1rem;
|
|
321
|
+
color: var(--overflow-nav-link-color, inherit);
|
|
322
|
+
border-bottom: 0.1rem solid var(--overflow-nav-link-border-color, #efefef75);
|
|
323
|
+
|
|
324
|
+
.label-wrapper {
|
|
325
|
+
.overflow-navigation-text {
|
|
326
|
+
text-wrap: nowrap;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
.icon-wrapper {
|
|
330
|
+
padding: 0;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
&[open] {
|
|
335
|
+
.expanding-panel-classic-summary {
|
|
336
|
+
border-bottom: 0.1rem solid transparent;
|
|
337
|
+
}
|
|
338
|
+
+ .expanding-panel-classic-content {
|
|
339
|
+
border-bottom: 0.1rem solid var(--overflow-nav-link-border-color, #efefef75);
|
|
340
|
+
.overflow-navigation-sub-nav-inner {
|
|
341
|
+
margin-top: var(--overflow-nav-items-gap, 0px);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
.expanding-panel-classic-content {
|
|
348
|
+
border-bottom: 0.1rem solid transparent;
|
|
349
|
+
|
|
350
|
+
.overflow-navigation-sub-nav-inner {
|
|
351
|
+
margin-top: 0;
|
|
352
|
+
position: relative;
|
|
353
|
+
|
|
354
|
+
.overflow-navigation-sub-nav-list {
|
|
355
|
+
display: flex;
|
|
356
|
+
flex-direction: column;
|
|
357
|
+
gap: 2px;
|
|
358
|
+
|
|
359
|
+
.overflow-navigation-sub-nav-item {
|
|
360
|
+
padding-block: var(--overflow-nav-items-padding-block, 0.8rem);
|
|
361
|
+
padding-inline: var(--overflow-nav-padding-inline, 0.8rem);
|
|
362
|
+
font-size: var(--overflow-nav-sub-item-font-size, inherit);
|
|
363
|
+
color: var(--overflow-nav-sub-item-color, inherit);
|
|
364
|
+
|
|
365
|
+
.overflow-navigation-sub-nav-link {
|
|
366
|
+
display: block;
|
|
367
|
+
text-decoration: none;
|
|
368
|
+
color: inherit;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
296
375
|
}
|
|
297
376
|
}
|
|
298
377
|
}
|
|
@@ -325,7 +404,11 @@ watch(
|
|
|
325
404
|
.overflow-navigation-wrapper
|
|
326
405
|
.overflow-navigation-item.is-hovered
|
|
327
406
|
.overflow-navigation-details
|
|
328
|
-
.expanding-panel-summary
|
|
407
|
+
.expanding-panel-summary,
|
|
408
|
+
.overflow-navigation-wrapper
|
|
409
|
+
.overflow-navigation-item.is-hovered
|
|
410
|
+
.overflow-navigation-details
|
|
411
|
+
.expanding-panel-classic-summary {
|
|
329
412
|
anchor-name: --overflow-nav-indicator;
|
|
330
413
|
}
|
|
331
414
|
|
|
@@ -340,7 +423,11 @@ watch(
|
|
|
340
423
|
.overflow-navigation-wrapper:not(:has(.overflow-navigation-item.is-hovered))
|
|
341
424
|
.overflow-navigation-item.is-active
|
|
342
425
|
.overflow-navigation-details
|
|
343
|
-
.expanding-panel-summary
|
|
426
|
+
.expanding-panel-summary,
|
|
427
|
+
.overflow-navigation-wrapper:not(:has(.overflow-navigation-item.is-hovered))
|
|
428
|
+
.overflow-navigation-item.is-active
|
|
429
|
+
.overflow-navigation-details
|
|
430
|
+
.expanding-panel-classic-summary {
|
|
344
431
|
anchor-name: --overflow-nav-indicator;
|
|
345
432
|
}
|
|
346
433
|
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
/>
|
|
101
101
|
</summary>
|
|
102
102
|
<div class="overflow-details-nav" role="menu">
|
|
103
|
-
<NavigationItems :main-navigation-state="mainNavigationState" />
|
|
103
|
+
<NavigationItems :main-navigation-state="mainNavigationState" :panel-variant="panelVariant" />
|
|
104
104
|
</div>
|
|
105
105
|
</details>
|
|
106
106
|
<slot v-if="slots.secondaryNavigation" name="secondaryNavigation"></slot>
|
|
@@ -125,6 +125,7 @@ interface Props {
|
|
|
125
125
|
collapseAtMainNavIntersection?: boolean;
|
|
126
126
|
styleClassPassthrough?: string | string[];
|
|
127
127
|
allowExpandOnGesture?: boolean;
|
|
128
|
+
panelVariant?: "modern" | "classic";
|
|
128
129
|
}
|
|
129
130
|
|
|
130
131
|
const props = withDefaults(defineProps<Props>(), {
|
|
@@ -138,6 +139,9 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
138
139
|
collapseAtMainNavIntersection: false,
|
|
139
140
|
styleClassPassthrough: () => [],
|
|
140
141
|
allowExpandOnGesture: true,
|
|
142
|
+
// Forwarded to NavigationItems' overflow submenu panels — see its own default for why
|
|
143
|
+
// "classic" is the safe default (CLAUDE.md pitfall #19).
|
|
144
|
+
panelVariant: "classic",
|
|
141
145
|
});
|
|
142
146
|
|
|
143
147
|
const collapseNavigationBelowWidth = computed(
|
|
@@ -138,10 +138,10 @@ describe("NavigationItems", () => {
|
|
|
138
138
|
const wrapper = await mountSuspended(NavigationItems, {
|
|
139
139
|
props: { mainNavigationState },
|
|
140
140
|
});
|
|
141
|
-
const details = wrapper.find(".expanding-panel-details");
|
|
141
|
+
const details = wrapper.find(".expanding-panel-classic-details");
|
|
142
142
|
expect(details.attributes("open")).toBeUndefined();
|
|
143
143
|
|
|
144
|
-
await wrapper.find(".expanding-panel-summary").trigger("click");
|
|
144
|
+
await wrapper.find(".expanding-panel-classic-summary").trigger("click");
|
|
145
145
|
await nextTick();
|
|
146
146
|
expect(details.attributes("open")).toBe("");
|
|
147
147
|
});
|
|
@@ -6,24 +6,24 @@ exports[`NavigationItems > renders correct HTML structure with default props 1`]
|
|
|
6
6
|
<li class="overflow-navigation-item is-active" style="--_main-navigation-item-width: 0px;" data-group-key="firstNav" data-local-index="0" role="none"><a href="/" class="overflow-navigation-link" role="menuitem"><span class="overflow-navigation-text">Home</span></a></li>
|
|
7
7
|
<li class="overflow-navigation-item visible" style="--_main-navigation-item-width: 0px;" data-group-key="firstNav" data-local-index="1" role="none"><a href="/about" class="overflow-navigation-link" role="menuitem"><span class="overflow-navigation-text">About</span></a></li>
|
|
8
8
|
<li class="overflow-navigation-item visible" style="--_main-navigation-item-width: 0px;" data-group-key="firstNav" data-local-index="2" role="none">
|
|
9
|
-
<div class="expanding-panel overflow-navigation-details">
|
|
10
|
-
<details class="expanding-panel-details" name="overflow-navigation-group">
|
|
11
|
-
<summary id="id-overflow-navigation-group-trigger" class="expanding-panel-summary" aria-controls="id-overflow-navigation-group-content" aria-expanded="false">
|
|
9
|
+
<div class="expanding-panel-classic overflow-navigation-details">
|
|
10
|
+
<details class="expanding-panel-classic-details" name="overflow-navigation-group">
|
|
11
|
+
<summary id="id-overflow-navigation-group-trigger" class="expanding-panel-classic-summary" aria-controls="id-overflow-navigation-group-content" aria-expanded="false">
|
|
12
12
|
<div class="label-wrapper"><span class="overflow-navigation-text" aria-label="UI Components submenu" role="menuitem" aria-haspopup="true">UI Components</span></div>
|
|
13
13
|
<div class="icon-wrapper"><span class="iconify i-mdi:chevron-down icon" aria-hidden="true"></span></div>
|
|
14
14
|
</summary>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
</
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
</details>
|
|
16
|
+
<div id="id-overflow-navigation-group-content" class="expanding-panel-classic-content" aria-labelledby="id-overflow-navigation-group-trigger" role="region">
|
|
17
|
+
<div class="inner">
|
|
18
|
+
<div class="overflow-navigation-sub-nav-inner">
|
|
19
|
+
<ul class="overflow-navigation-sub-nav-list">
|
|
20
|
+
<li class="overflow-navigation-sub-nav-item"><a href="/forms/examples/buttons" class="overflow-navigation-sub-nav-link" role="menuitem"><span class="overflow-navigation-sub-nav-text">Buttons</span></a></li>
|
|
21
|
+
<li class="overflow-navigation-sub-nav-item"><a href="/ui/tabs" class="overflow-navigation-sub-nav-link" role="menuitem"><span class="overflow-navigation-sub-nav-text">Tabs</span></a></li>
|
|
22
|
+
</ul>
|
|
23
|
+
<div aria-hidden="true" class="overflow-sub-nav-indicator-hovered"></div>
|
|
24
24
|
</div>
|
|
25
25
|
</div>
|
|
26
|
-
</
|
|
26
|
+
</div>
|
|
27
27
|
</div>
|
|
28
28
|
</li>
|
|
29
29
|
</ul>
|