srcdev-nuxt-components 9.3.7 → 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/breadcrumb.md +49 -0
- package/.claude/skills/components/content-docs.md +1 -1
- 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/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/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/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
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="snav-demo-page">
|
|
3
|
-
<h1>Services</h1>
|
|
4
|
-
<p>This is the Services page. The active indicator in the navigation above should be sitting under "Services".</p>
|
|
5
|
-
|
|
6
|
-
<NuxtImg
|
|
7
|
-
src="/images/banners/banner-light-brunette.webp"
|
|
8
|
-
alt="Services banner"
|
|
9
|
-
width="1200"
|
|
10
|
-
height="500"
|
|
11
|
-
loading="eager"
|
|
12
|
-
class="snav-demo-hero"
|
|
13
|
-
/>
|
|
14
|
-
|
|
15
|
-
<h2>What We Offer</h2>
|
|
16
|
-
<div class="snav-demo-services">
|
|
17
|
-
<div v-for="(service, i) in services" :key="i" class="snav-demo-service-card">
|
|
18
|
-
<NuxtImg :src="service.img" :alt="service.title" width="600" height="400" loading="lazy" class="snav-demo-img" />
|
|
19
|
-
<div class="snav-demo-service-card__body">
|
|
20
|
-
<h3>{{ service.title }}</h3>
|
|
21
|
-
<p>{{ service.description }}</p>
|
|
22
|
-
</div>
|
|
23
|
-
</div>
|
|
24
|
-
</div>
|
|
25
|
-
|
|
26
|
-
<h2>Our Work</h2>
|
|
27
|
-
<div class="snav-demo-grid">
|
|
28
|
-
<NuxtImg v-for="n in [4, 5, 6, 7, 8, 9]" :key="n" :src="`/images/rotating-carousel/image-${n}.webp`" :alt="`Work sample ${n}`" width="600" height="400" loading="lazy" class="snav-demo-img" />
|
|
29
|
-
</div>
|
|
30
|
-
</div>
|
|
31
|
-
</template>
|
|
32
|
-
|
|
33
|
-
<script setup lang="ts">
|
|
34
|
-
definePageMeta({ layout: "site-navigation-demo" });
|
|
35
|
-
useHead({ title: "SiteNavigation Demo — Services" });
|
|
36
|
-
|
|
37
|
-
const services = [
|
|
38
|
-
{ title: "Colour", img: "/images/rotating-carousel/image-1.webp", description: "From subtle highlights to bold transformations. Our colour specialists use only the finest products for vibrant, lasting results." },
|
|
39
|
-
{ title: "Cut & Style", img: "/images/rotating-carousel/image-2.webp", description: "Precision cuts tailored to your face shape and lifestyle. Walk out feeling confident every single time." },
|
|
40
|
-
{ title: "Treatment", img: "/images/rotating-carousel/image-3.webp", description: "Restore shine and health with our premium treatment range. Ideal for damaged, dry, or colour-treated hair." },
|
|
41
|
-
];
|
|
42
|
-
</script>
|
|
@@ -1,493 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<NuxtLayout name="default">
|
|
4
|
-
<template #layout-content>
|
|
5
|
-
<PageRow tag="div" variant="popout">
|
|
6
|
-
<h1 class="page-heading-2">TabNavigation</h1>
|
|
7
|
-
|
|
8
|
-
<!-- ── QA Panel (dev only) ───────────────────────────────── -->
|
|
9
|
-
<div v-if="isDev" class="qa-panel">
|
|
10
|
-
<details class="qa-panel__details" open>
|
|
11
|
-
<summary class="qa-panel__summary">
|
|
12
|
-
<span class="qa-panel__title">QA — TabNavigation</span>
|
|
13
|
-
<code class="qa-panel__status">
|
|
14
|
-
align:{{ navAlign }} · size:{{ qaLinkSize }}rem · gap:{{ qaGap }}rem ·
|
|
15
|
-
dur:{{ qaTransitionDuration }}ms
|
|
16
|
-
</code>
|
|
17
|
-
</summary>
|
|
18
|
-
<div class="qa-panel__body">
|
|
19
|
-
<!-- Props -->
|
|
20
|
-
<div class="qa-panel__group qa-panel__group--full">
|
|
21
|
-
<span class="qa-panel__section">Props</span>
|
|
22
|
-
</div>
|
|
23
|
-
|
|
24
|
-
<div class="qa-panel__group">
|
|
25
|
-
<span class="qa-panel__label">nav-align</span>
|
|
26
|
-
<div class="qa-panel__chips">
|
|
27
|
-
<button
|
|
28
|
-
v-for="a in ['left', 'center', 'right']"
|
|
29
|
-
:key="a"
|
|
30
|
-
class="qa-panel__chip"
|
|
31
|
-
:class="{ 'is-active': navAlign === a }"
|
|
32
|
-
@click="navAlign = a as 'left' | 'center' | 'right'"
|
|
33
|
-
>
|
|
34
|
-
{{ a }}
|
|
35
|
-
</button>
|
|
36
|
-
</div>
|
|
37
|
-
</div>
|
|
38
|
-
|
|
39
|
-
<div class="qa-panel__group">
|
|
40
|
-
<span class="qa-panel__label">container width</span>
|
|
41
|
-
<div class="qa-panel__chips">
|
|
42
|
-
<button
|
|
43
|
-
class="qa-panel__chip"
|
|
44
|
-
:class="{ 'is-active': !isNarrow }"
|
|
45
|
-
@click="isNarrow = false"
|
|
46
|
-
>
|
|
47
|
-
full
|
|
48
|
-
</button>
|
|
49
|
-
<button
|
|
50
|
-
class="qa-panel__chip"
|
|
51
|
-
:class="{ 'is-active': isNarrow }"
|
|
52
|
-
@click="isNarrow = true"
|
|
53
|
-
>
|
|
54
|
-
narrow (burger)
|
|
55
|
-
</button>
|
|
56
|
-
</div>
|
|
57
|
-
</div>
|
|
58
|
-
|
|
59
|
-
<!-- Link tokens -->
|
|
60
|
-
<div class="qa-panel__group qa-panel__group--full">
|
|
61
|
-
<span class="qa-panel__section">Link tokens</span>
|
|
62
|
-
</div>
|
|
63
|
-
|
|
64
|
-
<div class="qa-panel__group">
|
|
65
|
-
<span class="qa-panel__label">link-color</span>
|
|
66
|
-
<input v-model="qaLinkColor" type="color" class="qa-panel__color" />
|
|
67
|
-
</div>
|
|
68
|
-
|
|
69
|
-
<div class="qa-panel__group">
|
|
70
|
-
<span class="qa-panel__label">link-hover-color</span>
|
|
71
|
-
<input v-model="qaLinkHoverColor" type="color" class="qa-panel__color" />
|
|
72
|
-
</div>
|
|
73
|
-
|
|
74
|
-
<div class="qa-panel__group">
|
|
75
|
-
<span class="qa-panel__label">link-active-color</span>
|
|
76
|
-
<input v-model="qaLinkActiveColor" type="color" class="qa-panel__color" />
|
|
77
|
-
</div>
|
|
78
|
-
|
|
79
|
-
<div class="qa-panel__group">
|
|
80
|
-
<span class="qa-panel__label">link-size — {{ qaLinkSize }}rem</span>
|
|
81
|
-
<input
|
|
82
|
-
v-model.number="qaLinkSize"
|
|
83
|
-
type="range"
|
|
84
|
-
min="1.2"
|
|
85
|
-
max="2.4"
|
|
86
|
-
step="0.1"
|
|
87
|
-
class="qa-panel__range"
|
|
88
|
-
/>
|
|
89
|
-
</div>
|
|
90
|
-
|
|
91
|
-
<div class="qa-panel__group">
|
|
92
|
-
<span class="qa-panel__label">link-weight</span>
|
|
93
|
-
<div class="qa-panel__chips">
|
|
94
|
-
<button
|
|
95
|
-
v-for="w in [300, 400, 500, 600]"
|
|
96
|
-
:key="w"
|
|
97
|
-
class="qa-panel__chip"
|
|
98
|
-
:class="{ 'is-active': qaLinkWeight === w }"
|
|
99
|
-
@click="qaLinkWeight = w"
|
|
100
|
-
>
|
|
101
|
-
{{ w }}
|
|
102
|
-
</button>
|
|
103
|
-
</div>
|
|
104
|
-
</div>
|
|
105
|
-
|
|
106
|
-
<div class="qa-panel__group">
|
|
107
|
-
<span class="qa-panel__label">link-tracking — {{ qaLinkTracking }}em</span>
|
|
108
|
-
<input
|
|
109
|
-
v-model.number="qaLinkTracking"
|
|
110
|
-
type="range"
|
|
111
|
-
min="0"
|
|
112
|
-
max="0.2"
|
|
113
|
-
step="0.01"
|
|
114
|
-
class="qa-panel__range"
|
|
115
|
-
/>
|
|
116
|
-
</div>
|
|
117
|
-
|
|
118
|
-
<div class="qa-panel__group">
|
|
119
|
-
<span class="qa-panel__label">gap — {{ qaGap }}rem</span>
|
|
120
|
-
<input
|
|
121
|
-
v-model.number="qaGap"
|
|
122
|
-
type="range"
|
|
123
|
-
min="0.5"
|
|
124
|
-
max="5"
|
|
125
|
-
step="0.1"
|
|
126
|
-
class="qa-panel__range"
|
|
127
|
-
/>
|
|
128
|
-
</div>
|
|
129
|
-
|
|
130
|
-
<div class="qa-panel__group">
|
|
131
|
-
<span class="qa-panel__label">transition — {{ qaTransitionDuration }}ms</span>
|
|
132
|
-
<input
|
|
133
|
-
v-model.number="qaTransitionDuration"
|
|
134
|
-
type="range"
|
|
135
|
-
min="0"
|
|
136
|
-
max="800"
|
|
137
|
-
step="25"
|
|
138
|
-
class="qa-panel__range"
|
|
139
|
-
/>
|
|
140
|
-
</div>
|
|
141
|
-
|
|
142
|
-
<!-- Indicator tokens -->
|
|
143
|
-
<div class="qa-panel__group qa-panel__group--full">
|
|
144
|
-
<span class="qa-panel__section">Indicator tokens</span>
|
|
145
|
-
</div>
|
|
146
|
-
|
|
147
|
-
<div class="qa-panel__group">
|
|
148
|
-
<span class="qa-panel__label">indicator-color</span>
|
|
149
|
-
<input v-model="qaIndicatorColor" type="color" class="qa-panel__color" />
|
|
150
|
-
</div>
|
|
151
|
-
|
|
152
|
-
<div class="qa-panel__group">
|
|
153
|
-
<span class="qa-panel__label">hovered-bg color</span>
|
|
154
|
-
<input v-model="qaHoveredBgColor" type="color" class="qa-panel__color" />
|
|
155
|
-
</div>
|
|
156
|
-
|
|
157
|
-
<div class="qa-panel__group">
|
|
158
|
-
<span class="qa-panel__label">hovered-bg opacity — {{ qaHoveredBgOpacity }}</span>
|
|
159
|
-
<input
|
|
160
|
-
v-model.number="qaHoveredBgOpacity"
|
|
161
|
-
type="range"
|
|
162
|
-
min="0"
|
|
163
|
-
max="1"
|
|
164
|
-
step="0.05"
|
|
165
|
-
class="qa-panel__range"
|
|
166
|
-
/>
|
|
167
|
-
</div>
|
|
168
|
-
|
|
169
|
-
<!-- Panel tokens -->
|
|
170
|
-
<div class="qa-panel__group qa-panel__group--full">
|
|
171
|
-
<span class="qa-panel__section">Panel tokens (visible in narrow mode)</span>
|
|
172
|
-
</div>
|
|
173
|
-
|
|
174
|
-
<div class="qa-panel__group">
|
|
175
|
-
<span class="qa-panel__label">panel-bg</span>
|
|
176
|
-
<input v-model="qaPanelBg" type="color" class="qa-panel__color" />
|
|
177
|
-
</div>
|
|
178
|
-
|
|
179
|
-
<div class="qa-panel__group">
|
|
180
|
-
<span class="qa-panel__label">panel-link-color</span>
|
|
181
|
-
<input v-model="qaPanelLinkColor" type="color" class="qa-panel__color" />
|
|
182
|
-
</div>
|
|
183
|
-
|
|
184
|
-
<div class="qa-panel__group">
|
|
185
|
-
<span class="qa-panel__label">panel-slide-duration — {{ qaPanelSlideDuration }}ms</span>
|
|
186
|
-
<input
|
|
187
|
-
v-model.number="qaPanelSlideDuration"
|
|
188
|
-
type="range"
|
|
189
|
-
min="0"
|
|
190
|
-
max="800"
|
|
191
|
-
step="25"
|
|
192
|
-
class="qa-panel__range"
|
|
193
|
-
/>
|
|
194
|
-
</div>
|
|
195
|
-
|
|
196
|
-
<!-- Burger tokens -->
|
|
197
|
-
<div class="qa-panel__group qa-panel__group--full">
|
|
198
|
-
<span class="qa-panel__section">Burger tokens (visible in narrow mode)</span>
|
|
199
|
-
</div>
|
|
200
|
-
|
|
201
|
-
<div class="qa-panel__group">
|
|
202
|
-
<span class="qa-panel__label">burger-color</span>
|
|
203
|
-
<input v-model="qaBurgerColor" type="color" class="qa-panel__color" />
|
|
204
|
-
</div>
|
|
205
|
-
|
|
206
|
-
<div class="qa-panel__group">
|
|
207
|
-
<span class="qa-panel__label">burger-width — {{ qaBurgerWidth }}px</span>
|
|
208
|
-
<input
|
|
209
|
-
v-model.number="qaBurgerWidth"
|
|
210
|
-
type="range"
|
|
211
|
-
min="14"
|
|
212
|
-
max="36"
|
|
213
|
-
step="1"
|
|
214
|
-
class="qa-panel__range"
|
|
215
|
-
/>
|
|
216
|
-
</div>
|
|
217
|
-
|
|
218
|
-
<div class="qa-panel__group">
|
|
219
|
-
<span class="qa-panel__label">burger-gap — {{ qaBurgerGap }}px</span>
|
|
220
|
-
<input
|
|
221
|
-
v-model.number="qaBurgerGap"
|
|
222
|
-
type="range"
|
|
223
|
-
min="2"
|
|
224
|
-
max="12"
|
|
225
|
-
step="1"
|
|
226
|
-
class="qa-panel__range"
|
|
227
|
-
/>
|
|
228
|
-
</div>
|
|
229
|
-
</div>
|
|
230
|
-
</details>
|
|
231
|
-
</div>
|
|
232
|
-
|
|
233
|
-
<!-- ── Component stage ───────────────────────────────────── -->
|
|
234
|
-
<div class="tab-nav-demo-stage" :class="{ 'is-narrow': isNarrow }" :style="tokenStyles">
|
|
235
|
-
<TabNavigation :nav-item-data="navData" :nav-align="navAlign" />
|
|
236
|
-
</div>
|
|
237
|
-
</PageRow>
|
|
238
|
-
</template>
|
|
239
|
-
</NuxtLayout>
|
|
240
|
-
</div>
|
|
241
|
-
</template>
|
|
242
|
-
|
|
243
|
-
<script setup lang="ts">
|
|
244
|
-
import type { NavItemData } from "~/types/components";
|
|
245
|
-
|
|
246
|
-
definePageMeta({ layout: false });
|
|
247
|
-
useHead({
|
|
248
|
-
title: "TabNavigation — Component Demo",
|
|
249
|
-
bodyAttrs: { class: "tab-nav-demo-page" },
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
const isDev = import.meta.dev;
|
|
253
|
-
|
|
254
|
-
// ── Props ──────────────────────────────────────────────────────────────────
|
|
255
|
-
const navAlign = ref<"left" | "center" | "right">("left");
|
|
256
|
-
const isNarrow = ref(false);
|
|
257
|
-
|
|
258
|
-
// ── Link tokens ────────────────────────────────────────────────────────────
|
|
259
|
-
const qaLinkColor = ref("#e8e8e8");
|
|
260
|
-
const qaLinkHoverColor = ref("#999999");
|
|
261
|
-
const qaLinkActiveColor = ref("#e8e8e8");
|
|
262
|
-
const qaLinkSize = ref(1.6);
|
|
263
|
-
const qaLinkWeight = ref(400);
|
|
264
|
-
const qaLinkTracking = ref(0.06);
|
|
265
|
-
const qaGap = ref(2.2);
|
|
266
|
-
const qaTransitionDuration = ref(250);
|
|
267
|
-
|
|
268
|
-
// ── Indicator tokens ───────────────────────────────────────────────────────
|
|
269
|
-
const qaIndicatorColor = ref("#e8e8e8");
|
|
270
|
-
const qaHoveredBgColor = ref("#ffffff");
|
|
271
|
-
const qaHoveredBgOpacity = ref(0.08);
|
|
272
|
-
|
|
273
|
-
// ── Panel tokens ───────────────────────────────────────────────────────────
|
|
274
|
-
const qaPanelBg = ref("#1a1614");
|
|
275
|
-
const qaPanelLinkColor = ref("#e8e8e8");
|
|
276
|
-
const qaPanelSlideDuration = ref(350);
|
|
277
|
-
|
|
278
|
-
// ── Burger tokens ──────────────────────────────────────────────────────────
|
|
279
|
-
const qaBurgerColor = ref("#e8e8e8");
|
|
280
|
-
const qaBurgerWidth = ref(22);
|
|
281
|
-
const qaBurgerGap = ref(5);
|
|
282
|
-
|
|
283
|
-
function hexToRgbParts(hex: string) {
|
|
284
|
-
const r = parseInt(hex.slice(1, 3), 16);
|
|
285
|
-
const g = parseInt(hex.slice(3, 5), 16);
|
|
286
|
-
const b = parseInt(hex.slice(5, 7), 16);
|
|
287
|
-
return `${r} ${g} ${b}`;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
const tokenStyles = computed(() => ({
|
|
291
|
-
"--tab-nav-link-color": qaLinkColor.value,
|
|
292
|
-
"--tab-nav-link-hover-color": qaLinkHoverColor.value,
|
|
293
|
-
"--tab-nav-link-active-color": qaLinkActiveColor.value,
|
|
294
|
-
"--tab-nav-link-size": `${qaLinkSize.value}rem`,
|
|
295
|
-
"--tab-nav-link-weight": String(qaLinkWeight.value),
|
|
296
|
-
"--tab-nav-link-tracking": `${qaLinkTracking.value}em`,
|
|
297
|
-
"--tab-nav-gap": `${qaGap.value}rem`,
|
|
298
|
-
"--tab-nav-transition": `${qaTransitionDuration.value}ms ease`,
|
|
299
|
-
"--tab-nav-decorator-indicator-color": qaIndicatorColor.value,
|
|
300
|
-
"--tab-nav-decorator-hovered-bg": `rgb(${hexToRgbParts(qaHoveredBgColor.value)} / ${qaHoveredBgOpacity.value})`,
|
|
301
|
-
"--tab-nav-panel-bg": qaPanelBg.value,
|
|
302
|
-
"--tab-nav-panel-link-color": qaPanelLinkColor.value,
|
|
303
|
-
"--tab-nav-panel-slide-duration": `${qaPanelSlideDuration.value}ms`,
|
|
304
|
-
"--tab-nav-burger-color": qaBurgerColor.value,
|
|
305
|
-
"--tab-nav-burger-width": `${qaBurgerWidth.value}px`,
|
|
306
|
-
"--tab-nav-burger-gap": `${qaBurgerGap.value}px`,
|
|
307
|
-
}));
|
|
308
|
-
|
|
309
|
-
const navData: NavItemData = {
|
|
310
|
-
main: [
|
|
311
|
-
{ text: "Components", href: "/ui/anchor-scroll" },
|
|
312
|
-
{ text: "Layouts", href: "/ui/page-row" },
|
|
313
|
-
{ text: "Forms", href: "/forms/examples/buttons" },
|
|
314
|
-
{ text: "Typography", href: "/typography/hero-text" },
|
|
315
|
-
],
|
|
316
|
-
};
|
|
317
|
-
</script>
|
|
318
|
-
|
|
319
|
-
<style lang="css">
|
|
320
|
-
.tab-nav-demo-page {
|
|
321
|
-
.tab-nav-demo-stage {
|
|
322
|
-
margin-block-start: 2rem;
|
|
323
|
-
border: 1px solid oklch(100% 0 0 / 12%);
|
|
324
|
-
border-radius: 0.8rem;
|
|
325
|
-
padding: 2rem;
|
|
326
|
-
background-color: oklch(100% 0 0 / 3%);
|
|
327
|
-
position: relative;
|
|
328
|
-
transition: max-inline-size 0.3s ease;
|
|
329
|
-
|
|
330
|
-
&.is-narrow {
|
|
331
|
-
max-inline-size: 260px;
|
|
332
|
-
overflow: hidden;
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
.qa-panel {
|
|
337
|
-
background: oklch(15% 0 0);
|
|
338
|
-
color: white;
|
|
339
|
-
font-size: 1.3rem;
|
|
340
|
-
margin-block-start: 2rem;
|
|
341
|
-
border-radius: 0.6rem;
|
|
342
|
-
overflow: hidden;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
.qa-panel__details {
|
|
346
|
-
padding: 1rem 2rem;
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
.qa-panel__summary {
|
|
350
|
-
cursor: pointer;
|
|
351
|
-
display: flex;
|
|
352
|
-
align-items: center;
|
|
353
|
-
gap: 1.6rem;
|
|
354
|
-
list-style: none;
|
|
355
|
-
user-select: none;
|
|
356
|
-
|
|
357
|
-
&::-webkit-details-marker {
|
|
358
|
-
display: none;
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
.qa-panel__title {
|
|
363
|
-
font-weight: 600;
|
|
364
|
-
font-size: 1.1rem;
|
|
365
|
-
text-transform: uppercase;
|
|
366
|
-
letter-spacing: 0.08em;
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
.qa-panel__status {
|
|
370
|
-
font-family: monospace;
|
|
371
|
-
font-size: 1.2rem;
|
|
372
|
-
background: oklch(0% 0 0 / 0.3);
|
|
373
|
-
padding: 0.2rem 0.8rem;
|
|
374
|
-
border-radius: 0.4rem;
|
|
375
|
-
user-select: text;
|
|
376
|
-
cursor: text;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
.qa-panel__body {
|
|
380
|
-
display: flex;
|
|
381
|
-
flex-wrap: wrap;
|
|
382
|
-
gap: 2.4rem;
|
|
383
|
-
padding-block: 1.2rem 1.6rem;
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
.qa-panel__group {
|
|
387
|
-
display: flex;
|
|
388
|
-
flex-direction: column;
|
|
389
|
-
gap: 0.6rem;
|
|
390
|
-
|
|
391
|
-
&.qa-panel__group--full {
|
|
392
|
-
flex-basis: 100%;
|
|
393
|
-
margin-block-start: 0.8rem;
|
|
394
|
-
padding-block-end: 0.4rem;
|
|
395
|
-
border-block-end: 1px solid oklch(100% 0 0 / 0.1);
|
|
396
|
-
|
|
397
|
-
&:first-child {
|
|
398
|
-
margin-block-start: 0;
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
.qa-panel__section {
|
|
404
|
-
font-size: 1.1rem;
|
|
405
|
-
font-weight: 600;
|
|
406
|
-
text-transform: uppercase;
|
|
407
|
-
letter-spacing: 0.1em;
|
|
408
|
-
color: oklch(65% 0.18 240);
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
.qa-panel__label {
|
|
412
|
-
font-size: 1.1rem;
|
|
413
|
-
text-transform: uppercase;
|
|
414
|
-
letter-spacing: 0.08em;
|
|
415
|
-
opacity: 0.55;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
.qa-panel__chips {
|
|
419
|
-
display: flex;
|
|
420
|
-
flex-wrap: wrap;
|
|
421
|
-
gap: 0.4rem;
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
.qa-panel__chip {
|
|
425
|
-
font-family: monospace;
|
|
426
|
-
font-size: 1.2rem;
|
|
427
|
-
color: white;
|
|
428
|
-
background: oklch(0% 0 0 / 0.25);
|
|
429
|
-
border: 1px solid oklch(100% 0 0 / 0.18);
|
|
430
|
-
padding: 0.3rem 1rem;
|
|
431
|
-
border-radius: 0.4rem;
|
|
432
|
-
cursor: pointer;
|
|
433
|
-
transition: background 0.15s;
|
|
434
|
-
|
|
435
|
-
&:hover {
|
|
436
|
-
background: oklch(0% 0 0 / 0.4);
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
&.is-active {
|
|
440
|
-
background: oklch(55% 0.18 240);
|
|
441
|
-
border-color: oklch(55% 0.18 240);
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
.qa-panel__range {
|
|
446
|
-
appearance: none;
|
|
447
|
-
width: 18rem;
|
|
448
|
-
height: 0.4rem;
|
|
449
|
-
background: oklch(100% 0 0 / 0.18);
|
|
450
|
-
border-radius: 0.4rem;
|
|
451
|
-
outline: none;
|
|
452
|
-
cursor: pointer;
|
|
453
|
-
|
|
454
|
-
&::-webkit-slider-thumb {
|
|
455
|
-
appearance: none;
|
|
456
|
-
width: 1.4rem;
|
|
457
|
-
height: 1.4rem;
|
|
458
|
-
border-radius: 50%;
|
|
459
|
-
background: oklch(55% 0.18 240);
|
|
460
|
-
cursor: pointer;
|
|
461
|
-
transition: background 0.15s;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
&::-moz-range-thumb {
|
|
465
|
-
width: 1.4rem;
|
|
466
|
-
height: 1.4rem;
|
|
467
|
-
border: none;
|
|
468
|
-
border-radius: 50%;
|
|
469
|
-
background: oklch(55% 0.18 240);
|
|
470
|
-
cursor: pointer;
|
|
471
|
-
transition: background 0.15s;
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
&:hover::-webkit-slider-thumb {
|
|
475
|
-
background: oklch(62% 0.18 240);
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
&:hover::-moz-range-thumb {
|
|
479
|
-
background: oklch(62% 0.18 240);
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
.qa-panel__color {
|
|
484
|
-
width: 4rem;
|
|
485
|
-
height: 2.8rem;
|
|
486
|
-
border: 1px solid oklch(100% 0 0 / 0.18);
|
|
487
|
-
border-radius: 0.4rem;
|
|
488
|
-
background: none;
|
|
489
|
-
cursor: pointer;
|
|
490
|
-
padding: 0.2rem;
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
</style>
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<NuxtLayout name="default">
|
|
4
|
-
<template #layout-content>
|
|
5
|
-
<PageRow :style-class-passthrough="['mbe-4']">
|
|
6
|
-
<h1 class="page-heading-2">PageRow</h1>
|
|
7
|
-
<p>
|
|
8
|
-
Each
|
|
9
|
-
<code>PageRow</code>
|
|
10
|
-
is both a CSS grid container and a grid item. All direct children default to the
|
|
11
|
-
<strong>content</strong>
|
|
12
|
-
column (max 1064px). Nest a
|
|
13
|
-
<code>PageRow</code>
|
|
14
|
-
with a different
|
|
15
|
-
<code>variant</code>
|
|
16
|
-
to break out to a wider or narrower track.
|
|
17
|
-
</p>
|
|
18
|
-
</PageRow>
|
|
19
|
-
|
|
20
|
-
<!-- Direct content — defaults to content column -->
|
|
21
|
-
<PageRow tag="section" :style-class-passthrough="['mbe-20']">
|
|
22
|
-
<h2 class="page-heading-2">Default — content column</h2>
|
|
23
|
-
<pre>variant="content" (default)</pre>
|
|
24
|
-
<p>
|
|
25
|
-
Lorem ipsum odor amet, consectetuer adipiscing elit. Nec elementum maecenas placerat laoreet curae elit
|
|
26
|
-
convallis himenaeos. Tellus varius cursus convallis commodo suspendisse litora.
|
|
27
|
-
</p>
|
|
28
|
-
</PageRow>
|
|
29
|
-
|
|
30
|
-
<!-- Nesting: full-width background, constrained content -->
|
|
31
|
-
<PageRow
|
|
32
|
-
tag="section"
|
|
33
|
-
variant="full"
|
|
34
|
-
:style-class-passthrough="['mbe-20']"
|
|
35
|
-
style="background: #1e3a5f; color: white; padding-block: 4rem"
|
|
36
|
-
>
|
|
37
|
-
<h2 class="page-heading-2">Full-width background with constrained content</h2>
|
|
38
|
-
<pre style="color: #93c5fd">Outer: variant="full" — Inner: default content column</pre>
|
|
39
|
-
<p>
|
|
40
|
-
Wrap a
|
|
41
|
-
<code style="color: #93c5fd">PageRow</code>
|
|
42
|
-
in another with
|
|
43
|
-
<code style="color: #93c5fd">variant="full"</code>
|
|
44
|
-
to get a full-width background while keeping text in the content column. No extra wrapper divs required.
|
|
45
|
-
</p>
|
|
46
|
-
</PageRow>
|
|
47
|
-
|
|
48
|
-
<!-- Popout -->
|
|
49
|
-
<PageRow tag="section" :style-class-passthrough="['mbe-20']">
|
|
50
|
-
<PageRow variant="popout" :style-class-passthrough="['mbe-4']">
|
|
51
|
-
<h2 class="page-heading-2">Popout track (max 1400px)</h2>
|
|
52
|
-
<pre>variant="popout"</pre>
|
|
53
|
-
<p>
|
|
54
|
-
Lorem ipsum odor amet, consectetuer adipiscing elit. Nec elementum maecenas placerat laoreet curae elit
|
|
55
|
-
convallis himenaeos. Tellus varius cursus convallis commodo.
|
|
56
|
-
</p>
|
|
57
|
-
</PageRow>
|
|
58
|
-
</PageRow>
|
|
59
|
-
|
|
60
|
-
<!-- Inset content -->
|
|
61
|
-
<PageRow tag="section" :style-class-passthrough="['mbe-20']">
|
|
62
|
-
<PageRow variant="inset-content">
|
|
63
|
-
<h2 class="page-heading-2">Inset content track (max 840px)</h2>
|
|
64
|
-
<pre>variant="inset-content"</pre>
|
|
65
|
-
<p>
|
|
66
|
-
Lorem ipsum odor amet, consectetuer adipiscing elit. Nec elementum maecenas placerat laoreet curae elit
|
|
67
|
-
convallis himenaeos. Tellus varius cursus convallis commodo.
|
|
68
|
-
</p>
|
|
69
|
-
</PageRow>
|
|
70
|
-
</PageRow>
|
|
71
|
-
|
|
72
|
-
<!-- Mixed nesting: multiple tracks in one section -->
|
|
73
|
-
<PageRow
|
|
74
|
-
tag="section"
|
|
75
|
-
variant="full"
|
|
76
|
-
:style-class-passthrough="['mbe-20']"
|
|
77
|
-
style="background: #f00000; padding-block: 4rem"
|
|
78
|
-
>
|
|
79
|
-
<h2 class="page-heading-2">Mixed nesting</h2>
|
|
80
|
-
<p>Content column (default) alongside sibling rows at other tracks.</p>
|
|
81
|
-
|
|
82
|
-
<PageRow
|
|
83
|
-
variant="popout"
|
|
84
|
-
style="background: #00fc11; padding: 2rem; border-radius: 0.6rem; margin-block: 2rem"
|
|
85
|
-
>
|
|
86
|
-
<p>Popout sibling (max 1400px)</p>
|
|
87
|
-
</PageRow>
|
|
88
|
-
|
|
89
|
-
<PageRow variant="inset-content">
|
|
90
|
-
<p style="font-style: italic">Inset content sibling (max 840px) — ideal for pull-quotes or callouts.</p>
|
|
91
|
-
</PageRow>
|
|
92
|
-
</PageRow>
|
|
93
|
-
|
|
94
|
-
<!-- Semantic tags + landmark -->
|
|
95
|
-
<PageRow tag="section" is-landmark :style-class-passthrough="['mbe-20']">
|
|
96
|
-
<h2 class="page-heading-2">Semantic tag + landmark</h2>
|
|
97
|
-
<pre>tag="section" :is-landmark="true"</pre>
|
|
98
|
-
<p>
|
|
99
|
-
Any semantic HTML element is supported via the
|
|
100
|
-
<code>tag</code>
|
|
101
|
-
prop. Enabling
|
|
102
|
-
<code>isLandmark</code>
|
|
103
|
-
adds
|
|
104
|
-
<code>tabindex="0"</code>
|
|
105
|
-
and
|
|
106
|
-
<code>aria-label="Page Row"</code>
|
|
107
|
-
.
|
|
108
|
-
</p>
|
|
109
|
-
</PageRow>
|
|
110
|
-
</template>
|
|
111
|
-
</NuxtLayout>
|
|
112
|
-
</div>
|
|
113
|
-
</template>
|
|
114
|
-
|
|
115
|
-
<script setup lang="ts">
|
|
116
|
-
definePageMeta({
|
|
117
|
-
layout: false,
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
useHead({
|
|
121
|
-
title: "UI PageRow",
|
|
122
|
-
meta: [{ name: "description", content: "Examples of the PageRow layout component" }],
|
|
123
|
-
bodyAttrs: {
|
|
124
|
-
class: "home",
|
|
125
|
-
},
|
|
126
|
-
});
|
|
127
|
-
</script>
|