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,484 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<NuxtLayout name="default">
|
|
4
|
-
<template #layout-content>
|
|
5
|
-
<PageRow tag="div" variant="content" :style-class-passthrough="['mbe-20']">
|
|
6
|
-
<h2 class="page-heading-2">Navigation Horizontal</h2>
|
|
7
|
-
<p class="page-body-medium">This navigation has a reflective glow effect</p>
|
|
8
|
-
</PageRow>
|
|
9
|
-
|
|
10
|
-
<PageRow tag="div" variant="content" :style-class-passthrough="['mbe-20']">
|
|
11
|
-
<DisplayThemeSwitch />
|
|
12
|
-
</PageRow>
|
|
13
|
-
|
|
14
|
-
<PageRow tag="div" variant="full" :style-class-passthrough="['mbe-4']">
|
|
15
|
-
<PageRow tag="div" variant="content">
|
|
16
|
-
<h3 class="page-heading-3">User controllable</h3>
|
|
17
|
-
</PageRow>
|
|
18
|
-
<div class="nav-preview" :class="`theme-${theme}`" :style="navStyle">
|
|
19
|
-
<NavigationHorizontal :nav-item-data="navItemData" />
|
|
20
|
-
</div>
|
|
21
|
-
</PageRow>
|
|
22
|
-
|
|
23
|
-
<PageRow tag="div" variant="content" :style-class-passthrough="['mbe-20']">
|
|
24
|
-
<div class="nav-playground">
|
|
25
|
-
<fieldset>
|
|
26
|
-
<legend>Theme</legend>
|
|
27
|
-
<div class="control-row">
|
|
28
|
-
<label>Light / Dark</label>
|
|
29
|
-
<div class="theme-toggle">
|
|
30
|
-
<button :class="{ active: theme === 'light' }" @click="setTheme('light')">Light</button>
|
|
31
|
-
<button :class="{ active: theme === 'dark' }" @click="setTheme('dark')">Dark</button>
|
|
32
|
-
</div>
|
|
33
|
-
</div>
|
|
34
|
-
</fieldset>
|
|
35
|
-
|
|
36
|
-
<fieldset>
|
|
37
|
-
<legend>Colours</legend>
|
|
38
|
-
<div class="control-row">
|
|
39
|
-
<label for="active-colour">Active / glow colour</label>
|
|
40
|
-
<input id="active-colour" v-model="controls.activeColour" type="color" />
|
|
41
|
-
</div>
|
|
42
|
-
<div class="control-row">
|
|
43
|
-
<label for="link-colour">Link text colour</label>
|
|
44
|
-
<input id="link-colour" v-model="controls.linkColour" type="color" />
|
|
45
|
-
</div>
|
|
46
|
-
<div class="control-row">
|
|
47
|
-
<label for="link-bg">Link background</label>
|
|
48
|
-
<input id="link-bg" v-model="controls.linkBg" type="color" />
|
|
49
|
-
</div>
|
|
50
|
-
<div class="control-row">
|
|
51
|
-
<label for="border-colour">Border colour</label>
|
|
52
|
-
<input id="border-colour" v-model="controls.borderColour" type="color" />
|
|
53
|
-
</div>
|
|
54
|
-
<div class="control-row">
|
|
55
|
-
<label for="border-opacity">Border opacity — {{ controls.borderOpacity }}</label>
|
|
56
|
-
<input
|
|
57
|
-
id="border-opacity"
|
|
58
|
-
v-model.number="controls.borderOpacity"
|
|
59
|
-
type="range"
|
|
60
|
-
min="0"
|
|
61
|
-
max="1"
|
|
62
|
-
step="0.05"
|
|
63
|
-
/>
|
|
64
|
-
</div>
|
|
65
|
-
</fieldset>
|
|
66
|
-
|
|
67
|
-
<fieldset>
|
|
68
|
-
<legend>Borders</legend>
|
|
69
|
-
<div class="control-row">
|
|
70
|
-
<label for="border-start">Border top — {{ controls.borderStart }}px</label>
|
|
71
|
-
<input id="border-start" v-model.number="controls.borderStart" type="range" min="0" max="10" step="1" />
|
|
72
|
-
</div>
|
|
73
|
-
<div class="control-row">
|
|
74
|
-
<label for="border-end">Border bottom — {{ controls.borderEnd }}px</label>
|
|
75
|
-
<input id="border-end" v-model.number="controls.borderEnd" type="range" min="0" max="10" step="1" />
|
|
76
|
-
</div>
|
|
77
|
-
</fieldset>
|
|
78
|
-
|
|
79
|
-
<fieldset>
|
|
80
|
-
<legend>Layout</legend>
|
|
81
|
-
<div class="control-row">
|
|
82
|
-
<label for="list-padding">List padding — {{ controls.listPadding }}rem</label>
|
|
83
|
-
<input
|
|
84
|
-
id="list-padding"
|
|
85
|
-
v-model.number="controls.listPadding"
|
|
86
|
-
type="range"
|
|
87
|
-
min="0"
|
|
88
|
-
max="6"
|
|
89
|
-
step="0.5"
|
|
90
|
-
/>
|
|
91
|
-
</div>
|
|
92
|
-
<div class="control-row">
|
|
93
|
-
<label for="list-gap">List gap — {{ controls.listGap }}rem</label>
|
|
94
|
-
<input id="list-gap" v-model.number="controls.listGap" type="range" min="0" max="10" step="0.25" />
|
|
95
|
-
</div>
|
|
96
|
-
<div class="control-row">
|
|
97
|
-
<label for="link-padding-block">Link vertical padding — {{ controls.linkPaddingBlock }}rem</label>
|
|
98
|
-
<input
|
|
99
|
-
id="link-padding-block"
|
|
100
|
-
v-model.number="controls.linkPaddingBlock"
|
|
101
|
-
type="range"
|
|
102
|
-
min="0"
|
|
103
|
-
max="2"
|
|
104
|
-
step="0.1"
|
|
105
|
-
/>
|
|
106
|
-
</div>
|
|
107
|
-
<div class="control-row">
|
|
108
|
-
<label for="link-padding-inline">Link horizontal padding — {{ controls.linkPaddingInline }}rem</label>
|
|
109
|
-
<input
|
|
110
|
-
id="link-padding-inline"
|
|
111
|
-
v-model.number="controls.linkPaddingInline"
|
|
112
|
-
type="range"
|
|
113
|
-
min="0"
|
|
114
|
-
max="3"
|
|
115
|
-
step="0.1"
|
|
116
|
-
/>
|
|
117
|
-
</div>
|
|
118
|
-
<div class="control-row">
|
|
119
|
-
<label for="link-border-radius">Link border radius — {{ controls.linkBorderRadius }}rem</label>
|
|
120
|
-
<input
|
|
121
|
-
id="link-border-radius"
|
|
122
|
-
v-model.number="controls.linkBorderRadius"
|
|
123
|
-
type="range"
|
|
124
|
-
min="0"
|
|
125
|
-
max="2"
|
|
126
|
-
step="0.1"
|
|
127
|
-
/>
|
|
128
|
-
</div>
|
|
129
|
-
</fieldset>
|
|
130
|
-
|
|
131
|
-
<fieldset>
|
|
132
|
-
<legend>Glow Effect</legend>
|
|
133
|
-
<div class="control-row">
|
|
134
|
-
<label for="glow-pos-x">Origin X — {{ controls.glowPosX }}%</label>
|
|
135
|
-
<input id="glow-pos-x" v-model.number="controls.glowPosX" type="range" min="-100" max="100" step="1" />
|
|
136
|
-
</div>
|
|
137
|
-
<div class="control-row">
|
|
138
|
-
<label for="glow-pos-y">Origin Y — {{ controls.glowPosY }}%</label>
|
|
139
|
-
<input id="glow-pos-y" v-model.number="controls.glowPosY" type="range" min="-100" max="200" step="1" />
|
|
140
|
-
</div>
|
|
141
|
-
<div class="control-row">
|
|
142
|
-
<label for="glow-inner-stop">Inner gradient stop — {{ controls.glowInnerStop }}%</label>
|
|
143
|
-
<input
|
|
144
|
-
id="glow-inner-stop"
|
|
145
|
-
v-model.number="controls.glowInnerStop"
|
|
146
|
-
type="range"
|
|
147
|
-
min="0"
|
|
148
|
-
max="50"
|
|
149
|
-
step="1"
|
|
150
|
-
/>
|
|
151
|
-
</div>
|
|
152
|
-
<div class="control-row">
|
|
153
|
-
<label for="glow-outer-stop">Outer gradient stop — {{ controls.glowOuterStop }}%</label>
|
|
154
|
-
<input
|
|
155
|
-
id="glow-outer-stop"
|
|
156
|
-
v-model.number="controls.glowOuterStop"
|
|
157
|
-
type="range"
|
|
158
|
-
min="50"
|
|
159
|
-
max="100"
|
|
160
|
-
step="1"
|
|
161
|
-
/>
|
|
162
|
-
</div>
|
|
163
|
-
<div class="control-row">
|
|
164
|
-
<label for="glow-size">Glow spread — {{ controls.glowSize }}px</label>
|
|
165
|
-
<input id="glow-size" v-model.number="controls.glowSize" type="range" min="0" max="100" step="1" />
|
|
166
|
-
</div>
|
|
167
|
-
<div class="control-row">
|
|
168
|
-
<label for="glow-opacity">Glow opacity — {{ controls.glowOpacity }}</label>
|
|
169
|
-
<input
|
|
170
|
-
id="glow-opacity"
|
|
171
|
-
v-model.number="controls.glowOpacity"
|
|
172
|
-
type="range"
|
|
173
|
-
min="0"
|
|
174
|
-
max="1"
|
|
175
|
-
step="0.05"
|
|
176
|
-
/>
|
|
177
|
-
</div>
|
|
178
|
-
<div class="control-row">
|
|
179
|
-
<label for="anchor-offset">Anchor spread — {{ controls.anchorOffset }}px</label>
|
|
180
|
-
<input
|
|
181
|
-
id="anchor-offset"
|
|
182
|
-
v-model.number="controls.anchorOffset"
|
|
183
|
-
type="range"
|
|
184
|
-
min="0"
|
|
185
|
-
max="100"
|
|
186
|
-
step="1"
|
|
187
|
-
/>
|
|
188
|
-
</div>
|
|
189
|
-
</fieldset>
|
|
190
|
-
|
|
191
|
-
<fieldset>
|
|
192
|
-
<legend>Animation</legend>
|
|
193
|
-
<div class="control-row">
|
|
194
|
-
<label for="transition-duration">Transition — {{ controls.transitionDuration }}ms</label>
|
|
195
|
-
<input
|
|
196
|
-
id="transition-duration"
|
|
197
|
-
v-model.number="controls.transitionDuration"
|
|
198
|
-
type="range"
|
|
199
|
-
min="0"
|
|
200
|
-
max="1000"
|
|
201
|
-
step="50"
|
|
202
|
-
/>
|
|
203
|
-
</div>
|
|
204
|
-
</fieldset>
|
|
205
|
-
</div>
|
|
206
|
-
</PageRow>
|
|
207
|
-
|
|
208
|
-
<PageRow tag="div" variant="content" :style-class-passthrough="['mbe-20']">
|
|
209
|
-
<div class="css-snippet">
|
|
210
|
-
<div class="css-snippet-header">
|
|
211
|
-
<h3 class="page-heading-3">CSS Token Snippet</h3>
|
|
212
|
-
<button class="copy-btn" @click="copySnippet">{{ copied ? "Copied!" : "Copy" }}</button>
|
|
213
|
-
</div>
|
|
214
|
-
<pre class="css-snippet-code">{{ cssSnippet }}</pre>
|
|
215
|
-
</div>
|
|
216
|
-
</PageRow>
|
|
217
|
-
</template>
|
|
218
|
-
</NuxtLayout>
|
|
219
|
-
</div>
|
|
220
|
-
</template>
|
|
221
|
-
|
|
222
|
-
<script setup lang="ts">
|
|
223
|
-
import type { NavItemData } from "~/types/components/navigation-horizontal.d";
|
|
224
|
-
definePageMeta({
|
|
225
|
-
layout: false,
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
useHead({
|
|
229
|
-
title: "Navigation Horizontal",
|
|
230
|
-
meta: [
|
|
231
|
-
{
|
|
232
|
-
name: "description",
|
|
233
|
-
content: "Navigation Horizontal Meta description content",
|
|
234
|
-
},
|
|
235
|
-
],
|
|
236
|
-
bodyAttrs: {
|
|
237
|
-
class: "navigation-horizontal-page",
|
|
238
|
-
},
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
const navItemData: NavItemData = {
|
|
242
|
-
main: [
|
|
243
|
-
{ text: "Home", href: "#", isExternal: true, iconName: "home", cssName: "home-link" },
|
|
244
|
-
{ text: "About", href: "#", isExternal: true, iconName: "info", cssName: "about-link" },
|
|
245
|
-
{ text: "Services", href: "#", isExternal: true, iconName: "services", cssName: "services-link" },
|
|
246
|
-
{ text: "Contact", href: "#", isExternal: true, iconName: "contact", cssName: "contact-link" },
|
|
247
|
-
],
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
type Theme = "light" | "dark";
|
|
251
|
-
|
|
252
|
-
const themeDefaults: Record<
|
|
253
|
-
Theme,
|
|
254
|
-
{ linkColour: string; linkBg: string; borderColour: string; borderOpacity: number }
|
|
255
|
-
> = {
|
|
256
|
-
dark: { linkColour: "#ffffff", linkBg: "#333333", borderColour: "#ffffff", borderOpacity: 0.2 },
|
|
257
|
-
light: { linkColour: "#1a1a1a", linkBg: "#e8e8e8", borderColour: "#000000", borderOpacity: 0.15 },
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
const theme = ref<Theme>("dark");
|
|
261
|
-
|
|
262
|
-
const controls = reactive({
|
|
263
|
-
activeColour: "#00ff00",
|
|
264
|
-
linkColour: themeDefaults.dark.linkColour,
|
|
265
|
-
linkBg: themeDefaults.dark.linkBg,
|
|
266
|
-
borderColour: themeDefaults.dark.borderColour,
|
|
267
|
-
borderOpacity: themeDefaults.dark.borderOpacity,
|
|
268
|
-
borderStart: 0,
|
|
269
|
-
borderEnd: 3,
|
|
270
|
-
listPadding: 2,
|
|
271
|
-
listGap: 3,
|
|
272
|
-
linkPaddingBlock: 0.5,
|
|
273
|
-
linkPaddingInline: 1,
|
|
274
|
-
linkBorderRadius: 0.2,
|
|
275
|
-
glowPosX: 50,
|
|
276
|
-
glowPosY: 100,
|
|
277
|
-
glowInnerStop: 10,
|
|
278
|
-
glowOuterStop: 75,
|
|
279
|
-
glowSize: 32,
|
|
280
|
-
glowOpacity: 0.5,
|
|
281
|
-
anchorOffset: 40,
|
|
282
|
-
transitionDuration: 300,
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
const setTheme = (newTheme: Theme) => {
|
|
286
|
-
theme.value = newTheme;
|
|
287
|
-
const defaults = themeDefaults[newTheme];
|
|
288
|
-
controls.linkColour = defaults.linkColour;
|
|
289
|
-
controls.linkBg = defaults.linkBg;
|
|
290
|
-
controls.borderColour = defaults.borderColour;
|
|
291
|
-
controls.borderOpacity = defaults.borderOpacity;
|
|
292
|
-
};
|
|
293
|
-
|
|
294
|
-
const cssSnippet = computed(() => {
|
|
295
|
-
const borderColour = `color-mix(in srgb, ${controls.borderColour} ${Math.round(controls.borderOpacity * 100)}%, transparent)`;
|
|
296
|
-
return `.your-selector {
|
|
297
|
-
/* Colours */
|
|
298
|
-
--nav-active-colour: ${controls.activeColour};
|
|
299
|
-
--nav-link-colour: ${controls.linkColour};
|
|
300
|
-
--nav-link-bg: ${controls.linkBg};
|
|
301
|
-
--nav-border-colour: ${borderColour};
|
|
302
|
-
|
|
303
|
-
/* Borders */
|
|
304
|
-
--nav-border-start: ${controls.borderStart}px;
|
|
305
|
-
--nav-border-end: ${controls.borderEnd}px;
|
|
306
|
-
|
|
307
|
-
/* Layout */
|
|
308
|
-
--nav-list-padding: ${controls.listPadding}rem;
|
|
309
|
-
--nav-list-gap: ${controls.listGap}rem;
|
|
310
|
-
--nav-link-padding-block: ${controls.linkPaddingBlock}rem;
|
|
311
|
-
--nav-link-padding-inline: ${controls.linkPaddingInline}rem;
|
|
312
|
-
--nav-link-border-radius: ${controls.linkBorderRadius}rem;
|
|
313
|
-
|
|
314
|
-
/* Glow effect */
|
|
315
|
-
--nav-glow-pos-x: ${controls.glowPosX}%;
|
|
316
|
-
--nav-glow-pos-y: ${controls.glowPosY}%;
|
|
317
|
-
--nav-glow-inner-stop: ${controls.glowInnerStop}%;
|
|
318
|
-
--nav-glow-outer-stop: ${controls.glowOuterStop}%;
|
|
319
|
-
--nav-glow-size: ${controls.glowSize}px;
|
|
320
|
-
--nav-glow-opacity: ${controls.glowOpacity};
|
|
321
|
-
--nav-anchor-offset: ${controls.anchorOffset}px;
|
|
322
|
-
|
|
323
|
-
/* Animation */
|
|
324
|
-
--nav-transition-duration: ${controls.transitionDuration}ms;
|
|
325
|
-
}`;
|
|
326
|
-
});
|
|
327
|
-
|
|
328
|
-
const copied = ref(false);
|
|
329
|
-
const copySnippet = async () => {
|
|
330
|
-
await navigator.clipboard.writeText(cssSnippet.value);
|
|
331
|
-
copied.value = true;
|
|
332
|
-
setTimeout(() => {
|
|
333
|
-
copied.value = false;
|
|
334
|
-
}, 2000);
|
|
335
|
-
};
|
|
336
|
-
|
|
337
|
-
const navStyle = computed(() => ({
|
|
338
|
-
"--nav-active-colour": controls.activeColour,
|
|
339
|
-
"--nav-link-colour": controls.linkColour,
|
|
340
|
-
"--nav-link-bg": controls.linkBg,
|
|
341
|
-
"--nav-border-colour": `color-mix(in srgb, ${controls.borderColour} ${Math.round(controls.borderOpacity * 100)}%, transparent)`,
|
|
342
|
-
"--nav-border-start": `${controls.borderStart}px`,
|
|
343
|
-
"--nav-border-end": `${controls.borderEnd}px`,
|
|
344
|
-
"--nav-list-padding": `${controls.listPadding}rem`,
|
|
345
|
-
"--nav-list-gap": `${controls.listGap}rem`,
|
|
346
|
-
"--nav-link-padding-block": `${controls.linkPaddingBlock}rem`,
|
|
347
|
-
"--nav-link-padding-inline": `${controls.linkPaddingInline}rem`,
|
|
348
|
-
"--nav-link-border-radius": `${controls.linkBorderRadius}rem`,
|
|
349
|
-
"--nav-glow-pos-x": `${controls.glowPosX}%`,
|
|
350
|
-
"--nav-glow-pos-y": `${controls.glowPosY}%`,
|
|
351
|
-
"--nav-glow-inner-stop": `${controls.glowInnerStop}%`,
|
|
352
|
-
"--nav-glow-outer-stop": `${controls.glowOuterStop}%`,
|
|
353
|
-
"--nav-glow-size": `${controls.glowSize}px`,
|
|
354
|
-
"--nav-glow-opacity": String(controls.glowOpacity),
|
|
355
|
-
"--nav-anchor-offset": `${controls.anchorOffset}px`,
|
|
356
|
-
"--nav-transition-duration": `${controls.transitionDuration}ms`,
|
|
357
|
-
"color-scheme": theme.value,
|
|
358
|
-
}));
|
|
359
|
-
</script>
|
|
360
|
-
|
|
361
|
-
<style lang="css">
|
|
362
|
-
.navigation-horizontal-page {
|
|
363
|
-
.nav-preview {
|
|
364
|
-
padding: 4rem 0;
|
|
365
|
-
transition: background 300ms;
|
|
366
|
-
|
|
367
|
-
&.theme-dark {
|
|
368
|
-
--page-bg: hsl(0 0% 8%);
|
|
369
|
-
/* background: var(--page-bg); */
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
&.theme-light {
|
|
373
|
-
--page-bg: hsl(0 0% 95%);
|
|
374
|
-
/* background: var(--page-bg); */
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
.nav-playground {
|
|
379
|
-
display: grid;
|
|
380
|
-
grid-template-columns: repeat(auto-fit, minmax(30rem, 1fr));
|
|
381
|
-
gap: 2rem;
|
|
382
|
-
padding-block: 2rem;
|
|
383
|
-
|
|
384
|
-
fieldset {
|
|
385
|
-
border: 1px solid light-dark(var(--slate-04), var(--slate-06));
|
|
386
|
-
border-radius: 0.4rem;
|
|
387
|
-
padding: 1.6rem;
|
|
388
|
-
|
|
389
|
-
legend {
|
|
390
|
-
font-weight: bold;
|
|
391
|
-
padding: 0 0.8rem;
|
|
392
|
-
font-size: 1.4rem;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
.control-row {
|
|
396
|
-
display: grid;
|
|
397
|
-
grid-template-columns: 1fr 14rem;
|
|
398
|
-
gap: 1rem;
|
|
399
|
-
align-items: center;
|
|
400
|
-
padding: 0.5rem 0;
|
|
401
|
-
|
|
402
|
-
label {
|
|
403
|
-
font-size: 1.3rem;
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
input[type="range"] {
|
|
407
|
-
width: 100%;
|
|
408
|
-
cursor: pointer;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
input[type="color"] {
|
|
412
|
-
height: 3.2rem;
|
|
413
|
-
width: 100%;
|
|
414
|
-
padding: 0.2rem;
|
|
415
|
-
border: 1px solid light-dark(var(--slate-04), var(--slate-06));
|
|
416
|
-
border-radius: 0.2rem;
|
|
417
|
-
cursor: pointer;
|
|
418
|
-
background: transparent;
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
.theme-toggle {
|
|
424
|
-
display: flex;
|
|
425
|
-
gap: 0.4rem;
|
|
426
|
-
|
|
427
|
-
button {
|
|
428
|
-
padding: 0.4rem 1.6rem;
|
|
429
|
-
border: 1px solid light-dark(var(--slate-05), var(--slate-06));
|
|
430
|
-
border-radius: 0.2rem;
|
|
431
|
-
cursor: pointer;
|
|
432
|
-
background: transparent;
|
|
433
|
-
font-size: 1.3rem;
|
|
434
|
-
color: inherit;
|
|
435
|
-
|
|
436
|
-
&.active {
|
|
437
|
-
background: light-dark(var(--slate-03), var(--slate-07));
|
|
438
|
-
font-weight: bold;
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
.css-snippet {
|
|
445
|
-
border: 1px solid light-dark(var(--slate-04), var(--slate-06));
|
|
446
|
-
border-radius: 0.4rem;
|
|
447
|
-
overflow: hidden;
|
|
448
|
-
|
|
449
|
-
.css-snippet-header {
|
|
450
|
-
display: flex;
|
|
451
|
-
justify-content: space-between;
|
|
452
|
-
align-items: center;
|
|
453
|
-
padding: 1rem 1.6rem;
|
|
454
|
-
border-block-end: 1px solid light-dark(var(--slate-04), var(--slate-06));
|
|
455
|
-
/* background: light-dark(var(--slate-02), var(--slate-08)); */
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
.css-snippet-code {
|
|
459
|
-
margin: 0;
|
|
460
|
-
padding: 1.6rem;
|
|
461
|
-
font-family: monospace;
|
|
462
|
-
font-size: 1.3rem;
|
|
463
|
-
line-height: 1.6;
|
|
464
|
-
overflow-x: auto;
|
|
465
|
-
white-space: pre;
|
|
466
|
-
/* background: light-dark(var(--slate-01), var(--slate-09)); */
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
.copy-btn {
|
|
470
|
-
padding: 0.4rem 1.2rem;
|
|
471
|
-
border: 1px solid light-dark(var(--slate-05), var(--slate-06));
|
|
472
|
-
border-radius: 0.2rem;
|
|
473
|
-
cursor: pointer;
|
|
474
|
-
background: transparent;
|
|
475
|
-
font-size: 1.3rem;
|
|
476
|
-
color: inherit;
|
|
477
|
-
|
|
478
|
-
&:hover {
|
|
479
|
-
background: light-dark(var(--slate-03), var(--slate-07));
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
</style>
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="snav-demo-page">
|
|
3
|
-
<h1>About</h1>
|
|
4
|
-
<p>This is the About page. The active indicator in the navigation above should be sitting under "About". Lots of images below to simulate a content-heavy page.</p>
|
|
5
|
-
|
|
6
|
-
<div class="snav-demo-split">
|
|
7
|
-
<div class="snav-demo-split__text">
|
|
8
|
-
<h2>Our Story</h2>
|
|
9
|
-
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.</p>
|
|
10
|
-
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
|
11
|
-
<h2>Our Team</h2>
|
|
12
|
-
<p>We are a team of dedicated professionals committed to delivering the best experience. Our combined expertise spans design, development, and user experience research.</p>
|
|
13
|
-
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis.</p>
|
|
14
|
-
</div>
|
|
15
|
-
<NuxtImg src="/images/rotating-carousel/image-1.webp" alt="About hero" width="600" height="800" loading="eager" class="snav-demo-split__img" />
|
|
16
|
-
</div>
|
|
17
|
-
|
|
18
|
-
<h2>Gallery</h2>
|
|
19
|
-
<div class="snav-demo-grid">
|
|
20
|
-
<NuxtImg v-for="n in 9" :key="n" :src="`/images/rotating-carousel/image-${n}.webp`" :alt="`About gallery ${n}`" width="600" height="400" loading="lazy" class="snav-demo-img" />
|
|
21
|
-
</div>
|
|
22
|
-
|
|
23
|
-
<h2>Behind the scenes</h2>
|
|
24
|
-
<div class="snav-demo-grid snav-demo-grid--wide">
|
|
25
|
-
<NuxtImg src="/images/banners/banner-ginger.jpeg" alt="Behind the scenes 1" width="800" height="500" loading="lazy" class="snav-demo-img" />
|
|
26
|
-
<NuxtImg src="/images/banners/banner-mid-brown.webp" alt="Behind the scenes 2" width="800" height="500" loading="lazy" class="snav-demo-img" />
|
|
27
|
-
<NuxtImg src="/images/page/hero/hero-dark.jpg" alt="Behind the scenes 3" width="800" height="500" loading="lazy" class="snav-demo-img" />
|
|
28
|
-
<NuxtImg src="/images/page/hero/hero-red.jpg" alt="Behind the scenes 4" width="800" height="500" 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 — About" });
|
|
36
|
-
</script>
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="snav-demo-page">
|
|
3
|
-
<h1>Contact</h1>
|
|
4
|
-
<p>This is the Contact page. The active indicator in the navigation above should be sitting under "Contact".</p>
|
|
5
|
-
|
|
6
|
-
<div class="snav-demo-split">
|
|
7
|
-
<div class="snav-demo-split__text">
|
|
8
|
-
<h2>Get in Touch</h2>
|
|
9
|
-
<p>We'd love to hear from you. Whether you have a question about our services, want to book an appointment, or just want to say hello — our door is always open.</p>
|
|
10
|
-
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
|
|
11
|
-
<h3>Opening Hours</h3>
|
|
12
|
-
<ul>
|
|
13
|
-
<li>Monday – Friday: 9am – 7pm</li>
|
|
14
|
-
<li>Saturday: 9am – 5pm</li>
|
|
15
|
-
<li>Sunday: Closed</li>
|
|
16
|
-
</ul>
|
|
17
|
-
<h3>Address</h3>
|
|
18
|
-
<p>123 Example Street<br />London, UK<br />EC1A 1BB</p>
|
|
19
|
-
</div>
|
|
20
|
-
<NuxtImg src="/images/rotating-carousel/55-woman-garden-backdrop.webp" alt="Contact hero" width="600" height="800" loading="eager" class="snav-demo-split__img" />
|
|
21
|
-
</div>
|
|
22
|
-
|
|
23
|
-
<h2>Find Us</h2>
|
|
24
|
-
<div class="snav-demo-grid snav-demo-grid--wide">
|
|
25
|
-
<NuxtImg src="/images/rotating-carousel/image-5.webp" alt="Location 1" width="800" height="500" loading="lazy" class="snav-demo-img" />
|
|
26
|
-
<NuxtImg src="/images/rotating-carousel/image-6.webp" alt="Location 2" width="800" height="500" loading="lazy" class="snav-demo-img" />
|
|
27
|
-
</div>
|
|
28
|
-
|
|
29
|
-
<h2>Instagram</h2>
|
|
30
|
-
<div class="snav-demo-grid">
|
|
31
|
-
<NuxtImg v-for="n in [1, 2, 3, 7, 8, 9]" :key="n" :src="`/images/rotating-carousel/image-${n}.webp`" :alt="`Instagram post ${n}`" width="600" height="600" loading="lazy" class="snav-demo-img snav-demo-img--square" />
|
|
32
|
-
</div>
|
|
33
|
-
</div>
|
|
34
|
-
</template>
|
|
35
|
-
|
|
36
|
-
<script setup lang="ts">
|
|
37
|
-
definePageMeta({ layout: "site-navigation-demo" });
|
|
38
|
-
useHead({ title: "SiteNavigation Demo — Contact" });
|
|
39
|
-
</script>
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="snav-demo-page">
|
|
3
|
-
<h1>Home</h1>
|
|
4
|
-
<p>Welcome to the SiteNavigation component demo. Resize the window to see the burger menu collapse, and navigate between pages to see the active indicator update. This page is intentionally heavy with images to stress-test nav behaviour during loading.</p>
|
|
5
|
-
|
|
6
|
-
<NuxtImg
|
|
7
|
-
src="/images/banners/banner-ginger.jpeg"
|
|
8
|
-
alt="Hero banner"
|
|
9
|
-
width="1200"
|
|
10
|
-
height="600"
|
|
11
|
-
loading="eager"
|
|
12
|
-
class="snav-demo-hero"
|
|
13
|
-
/>
|
|
14
|
-
|
|
15
|
-
<h2>Featured Gallery</h2>
|
|
16
|
-
<div class="snav-demo-grid">
|
|
17
|
-
<NuxtImg v-for="n in 9" :key="n" :src="`/images/rotating-carousel/image-${n}.webp`" :alt="`Gallery image ${n}`" width="600" height="400" loading="lazy" class="snav-demo-img" />
|
|
18
|
-
</div>
|
|
19
|
-
|
|
20
|
-
<h2>More Images</h2>
|
|
21
|
-
<div class="snav-demo-grid snav-demo-grid--wide">
|
|
22
|
-
<NuxtImg src="/images/banners/banner-light-brunette.webp" alt="Banner light brunette" width="800" height="500" loading="lazy" class="snav-demo-img" />
|
|
23
|
-
<NuxtImg src="/images/banners/banner-mid-brown.webp" alt="Banner mid brown" width="800" height="500" loading="lazy" class="snav-demo-img" />
|
|
24
|
-
<NuxtImg src="/images/rotating-carousel/35-light-brown-highlights.webp" alt="Light brown highlights" width="800" height="500" loading="lazy" class="snav-demo-img" />
|
|
25
|
-
<NuxtImg src="/images/rotating-carousel/55-woman-garden-backdrop.webp" alt="Woman garden backdrop" width="800" height="500" loading="lazy" class="snav-demo-img" />
|
|
26
|
-
</div>
|
|
27
|
-
|
|
28
|
-
<h2>Hero Images</h2>
|
|
29
|
-
<div class="snav-demo-grid">
|
|
30
|
-
<NuxtImg v-for="hero in ['hero-blonde', 'hero-dark', 'hero-hair', 'hero-red']" :key="hero" :src="`/images/page/hero/${hero}.jpg`" :alt="hero" width="600" height="400" loading="lazy" class="snav-demo-img" />
|
|
31
|
-
</div>
|
|
32
|
-
</div>
|
|
33
|
-
</template>
|
|
34
|
-
|
|
35
|
-
<script setup lang="ts">
|
|
36
|
-
definePageMeta({ layout: "site-navigation-demo" });
|
|
37
|
-
useHead({ title: "SiteNavigation Demo — Home" });
|
|
38
|
-
</script>
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="snav-demo-page">
|
|
3
|
-
<h1>Portfolio</h1>
|
|
4
|
-
<p>This is the Portfolio page. The active indicator in the navigation above should be sitting under "Portfolio". Maximum image load to stress-test navigation behaviour.</p>
|
|
5
|
-
|
|
6
|
-
<h2>Spotlight Work</h2>
|
|
7
|
-
<div class="snav-demo-grid snav-demo-grid--dense">
|
|
8
|
-
<NuxtImg v-for="n in 9" :key="n" :src="`/images/rotating-carousel/image-${n}.webp`" :alt="`Portfolio piece ${n}`" width="600" height="600" loading="lazy" class="snav-demo-img snav-demo-img--square" />
|
|
9
|
-
</div>
|
|
10
|
-
|
|
11
|
-
<h2>Featured Looks</h2>
|
|
12
|
-
<div class="snav-demo-grid snav-demo-grid--wide">
|
|
13
|
-
<NuxtImg src="/images/banners/banner-ginger.jpeg" alt="Ginger look" width="800" height="500" loading="lazy" class="snav-demo-img" />
|
|
14
|
-
<NuxtImg src="/images/banners/banner-light-brunette.webp" alt="Light brunette look" width="800" height="500" loading="lazy" class="snav-demo-img" />
|
|
15
|
-
<NuxtImg src="/images/banners/banner-mid-brown.webp" alt="Mid brown look" width="800" height="500" loading="lazy" class="snav-demo-img" />
|
|
16
|
-
<NuxtImg src="/images/rotating-carousel/35-light-brown-highlights.webp" alt="Light brown highlights" width="800" height="500" loading="lazy" class="snav-demo-img" />
|
|
17
|
-
<NuxtImg src="/images/rotating-carousel/55-woman-garden-backdrop.webp" alt="Garden backdrop" width="800" height="500" loading="lazy" class="snav-demo-img" />
|
|
18
|
-
<NuxtImg src="/images/rotating-carousel/indian-pink-stripe.webp" alt="Pink stripe" width="800" height="500" loading="lazy" class="snav-demo-img" />
|
|
19
|
-
<NuxtImg src="/images/rotating-carousel/spanish-green-stripe.webp" alt="Green stripe" width="800" height="500" loading="lazy" class="snav-demo-img" />
|
|
20
|
-
</div>
|
|
21
|
-
|
|
22
|
-
<h2>Hero Series</h2>
|
|
23
|
-
<div class="snav-demo-grid">
|
|
24
|
-
<NuxtImg v-for="hero in ['hero-blonde', 'hero-dark', 'hero-hair', 'hero-red']" :key="hero" :src="`/images/page/hero/${hero}.jpg`" :alt="hero" width="600" height="400" loading="lazy" class="snav-demo-img" />
|
|
25
|
-
</div>
|
|
26
|
-
</div>
|
|
27
|
-
</template>
|
|
28
|
-
|
|
29
|
-
<script setup lang="ts">
|
|
30
|
-
definePageMeta({ layout: "site-navigation-demo" });
|
|
31
|
-
useHead({ title: "SiteNavigation Demo — Portfolio" });
|
|
32
|
-
</script>
|
|
33
|
-
|
|
34
|
-
<style lang="css">
|
|
35
|
-
.snav-demo-img--square {
|
|
36
|
-
aspect-ratio: 1 / 1;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
.snav-demo-grid--dense {
|
|
40
|
-
grid-template-columns: repeat(3, 1fr);
|
|
41
|
-
gap: 0.8rem;
|
|
42
|
-
}
|
|
43
|
-
</style>
|