astro-component-kit 0.4.1 → 0.5.0
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/README.md +35 -1
- package/bin/cli.js +67 -0
- package/bin/installer.js +179 -0
- package/package.json +22 -5
- package/src/components/lib/sections/ChangelogSection.astro +6 -0
- package/src/data/registry/app.ts +93 -0
- package/src/data/registry/buttons.ts +3279 -0
- package/src/data/registry/cards.ts +1753 -0
- package/src/data/registry/charts-svg.ts +557 -0
- package/src/data/registry/charts.ts +500 -0
- package/src/data/registry/data.ts +986 -0
- package/src/data/registry/ecommerce.ts +269 -0
- package/src/data/registry/feedback.ts +1824 -0
- package/src/data/registry/forms.ts +2513 -0
- package/src/data/registry/index.ts +64 -0
- package/src/data/registry/layout.ts +206 -0
- package/src/data/registry/navigation.ts +936 -0
- package/src/data/registry/overlays.ts +1133 -0
- package/src/data/registry/sections-extra.ts +397 -0
- package/src/data/registry/sections.ts +361 -0
- package/src/data/registry/sources.ts +41 -0
- package/src/data/registry/templates.ts +414 -0
- package/src/data/registry/types.ts +30 -0
- package/src/data/registry/typography.ts +777 -0
- package/src/mcp/http-server.ts +324 -0
- package/src/mcp/index.ts +67 -0
- package/src/mcp/installer.ts +178 -0
- package/src/mcp/registry-adapter.ts +278 -0
- package/src/mcp/stdio-server.ts +11 -0
- package/src/mcp/tools.ts +247 -0
- package/src/mcp/types.ts +53 -0
|
@@ -0,0 +1,936 @@
|
|
|
1
|
+
// src/data/registry/navigation.ts
|
|
2
|
+
import type { ComponentDoc } from './types';
|
|
3
|
+
|
|
4
|
+
export const navigation: ComponentDoc[] = [
|
|
5
|
+
{
|
|
6
|
+
slug: 'glass-navbar',
|
|
7
|
+
name: 'Glass Navbar',
|
|
8
|
+
description: 'A sticky top navigation bar with glassmorphism blur and smooth scroll behavior.',
|
|
9
|
+
category: 'navigation',
|
|
10
|
+
tags: ['navbar', 'navigation', 'glass', 'sticky'],
|
|
11
|
+
featured: true,
|
|
12
|
+
code: `---
|
|
13
|
+
interface Props { brand?: string; brandHref?: string; }
|
|
14
|
+
const { brand = 'Astro Components', brandHref = '/' } = Astro.props;
|
|
15
|
+
---
|
|
16
|
+
<header class="glass-nav">
|
|
17
|
+
<div class="glass-nav__inner">
|
|
18
|
+
<a href={brandHref} class="glass-nav__brand">{brand}</a>
|
|
19
|
+
<nav class="glass-nav__links"><slot name="links" /></nav>
|
|
20
|
+
<div class="glass-nav__actions"><slot name="actions" /></div>
|
|
21
|
+
</div>
|
|
22
|
+
</header>
|
|
23
|
+
<style>
|
|
24
|
+
.glass-nav { position: sticky; top: 0; z-index: 100; background: rgba(10, 10, 20, 0.7); backdrop-filter: blur(20px); border-bottom: 1px solid rgba(255, 255, 255, 0.07); }
|
|
25
|
+
.glass-nav__inner { max-width: 1200px; margin: 0 auto; padding: 0 1.5rem; height: 64px; display: flex; align-items: center; gap: 2rem; }
|
|
26
|
+
.glass-nav__brand { font-size: 1.1rem; font-weight: 800; color: #f1f5f9; text-decoration: none; background: linear-gradient(135deg, #818cf8, #c084fc); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
|
|
27
|
+
.glass-nav__links { display: flex; align-items: center; gap: 0.25rem; flex: 1; }
|
|
28
|
+
.glass-nav__links :global(a) { padding: 0.4rem 0.8rem; font-size: 0.875rem; font-weight: 500; color: #94a3b8; text-decoration: none; border-radius: 8px; transition: 0.2s; }
|
|
29
|
+
.glass-nav__links :global(a:hover) { color: #e2e8f0; background: rgba(255, 255, 255, 0.06); }
|
|
30
|
+
</style>
|
|
31
|
+
`,
|
|
32
|
+
usage: `---
|
|
33
|
+
import { GlassNavbar, GlassButton } from 'astro-component-kit';
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
<GlassNavbar brand="MyProject">
|
|
37
|
+
<div slot="links">
|
|
38
|
+
<a href="#">Home</a>
|
|
39
|
+
<a href="#">Components</a>
|
|
40
|
+
<a href="#">Showcase</a>
|
|
41
|
+
</div>
|
|
42
|
+
<div slot="actions">
|
|
43
|
+
<GlassButton variant="ghost" size="sm">Log in</GlassButton>
|
|
44
|
+
<GlassButton size="sm">Get Started</GlassButton>
|
|
45
|
+
</div>
|
|
46
|
+
</GlassNavbar>`,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
slug: 'minimal-sidebar',
|
|
50
|
+
name: 'Minimal Sidebar',
|
|
51
|
+
description: 'A vertical navigation sidebar for dashboard-style interfaces.',
|
|
52
|
+
category: 'navigation',
|
|
53
|
+
tags: ['sidebar', 'navigation', 'layout'],
|
|
54
|
+
code: `---
|
|
55
|
+
---
|
|
56
|
+
<aside class="sidebar">
|
|
57
|
+
<div class="sidebar-logo">AU</div>
|
|
58
|
+
<nav class="sidebar-nav">
|
|
59
|
+
<a href="#" class="active">Overview</a>
|
|
60
|
+
<a href="#">Projects</a>
|
|
61
|
+
<a href="#">Team</a>
|
|
62
|
+
<a href="#">Settings</a>
|
|
63
|
+
</nav>
|
|
64
|
+
</aside>
|
|
65
|
+
<style>
|
|
66
|
+
.sidebar { width: 240px; height: 100vh; background: #080b14; border-right: 1px solid rgba(255, 255, 255, 0.1); padding: 1.5rem; display: flex; flex-direction: column; gap: 2rem; }
|
|
67
|
+
.sidebar-logo { width: 40px; height: 40px; background: #6366f1; color: #fff; display: grid; place-items: center; border-radius: 10px; font-weight: 900; }
|
|
68
|
+
.sidebar-nav { display: flex; flex-direction: column; gap: 0.5rem; }
|
|
69
|
+
.sidebar-nav a { padding: 0.75rem 1rem; border-radius: 10px; color: #94a3b8; text-decoration: none; font-size: 0.9rem; font-weight: 500; transition: 0.2s; }
|
|
70
|
+
.sidebar-nav a:hover, .sidebar-nav a.active { background: rgba(255,255,255,0.05); color: #fff; }
|
|
71
|
+
</style>
|
|
72
|
+
`,
|
|
73
|
+
usage: `<MinimalSidebar>Content</MinimalSidebar>`,
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
slug: 'bottom-nav-mobile',
|
|
77
|
+
name: 'Floating Bottom Nav',
|
|
78
|
+
description: 'Icon-based navigation bar fixed to the bottom, optimized for mobile.',
|
|
79
|
+
category: 'navigation',
|
|
80
|
+
tags: ['mobile', 'navigation', 'bottom bar'],
|
|
81
|
+
code: `---
|
|
82
|
+
---
|
|
83
|
+
<div class="bottom-nav">
|
|
84
|
+
<a href="#" class="active">🏠</a>
|
|
85
|
+
<a href="#">🔍</a>
|
|
86
|
+
<a href="#">🔔</a>
|
|
87
|
+
<a href="#">👤</a>
|
|
88
|
+
</div>
|
|
89
|
+
<style>
|
|
90
|
+
.bottom-nav { position: fixed; bottom: 1.5rem; left: 50%; transform: translateX(-50%); width: 90%; max-width: 400px; height: 60px; background: rgba(15, 23, 42, 0.8); backdrop-filter: blur(20px); border: 1px solid rgba(255,255,255,0.1); border-radius: 30px; display: flex; justify-content: space-around; align-items: center; z-index: 1000; box-shadow: 0 10px 30px rgba(0,0,0,0.5); }
|
|
91
|
+
.bottom-nav a { font-size: 1.25rem; opacity: 0.5; text-decoration: none; transition: 0.3s; }
|
|
92
|
+
.bottom-nav a.active { opacity: 1; transform: translateY(-5px); }
|
|
93
|
+
</style>
|
|
94
|
+
`,
|
|
95
|
+
usage: `<BottomNavMobile>Content</BottomNavMobile>`,
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
slug: 'pagination-glass',
|
|
99
|
+
name: 'Glass Pagination',
|
|
100
|
+
description: 'Stylish page switcher with blurred background and active states.',
|
|
101
|
+
category: 'navigation',
|
|
102
|
+
tags: ['pagination', 'navigation', 'glass'],
|
|
103
|
+
code: `---
|
|
104
|
+
---
|
|
105
|
+
<nav class="pagination">
|
|
106
|
+
<button class="prev">←</button>
|
|
107
|
+
<div class="pages">
|
|
108
|
+
<a href="#" class="active">1</a>
|
|
109
|
+
<a href="#">2</a>
|
|
110
|
+
<a href="#">3</a>
|
|
111
|
+
<span>...</span>
|
|
112
|
+
<a href="#">12</a>
|
|
113
|
+
</div>
|
|
114
|
+
<button class="next">→</button>
|
|
115
|
+
</nav>
|
|
116
|
+
<style>
|
|
117
|
+
.pagination { display: flex; align-items: center; gap: 1rem; }
|
|
118
|
+
.pages { display: flex; gap: 0.5rem; background: rgba(0,0,0,0.2); padding: 4px; border-radius: 10px; border: 1px solid rgba(255, 255, 255, 0.1); }
|
|
119
|
+
.pages a, button { width: 34px; height: 34px; display: grid; place-items: center; border-radius: 8px; font-size: 0.8rem; font-weight: 700; color: #94a3b8; text-decoration: none; transition: 0.2s; border: none; background: none; cursor: pointer; }
|
|
120
|
+
.pages a.active { background: #6366f1; color: #fff; }
|
|
121
|
+
.pages a:hover:not(.active) { background: rgba(255,255,255,0.05); color: #fff; }
|
|
122
|
+
</style>
|
|
123
|
+
`,
|
|
124
|
+
usage: `<PaginationGlass>Content</PaginationGlass>`,
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
slug: 'breadcrumbs-minimal',
|
|
128
|
+
name: 'Minimal Breadcrumbs',
|
|
129
|
+
description: 'Lean navigation path indicator with subtle separators.',
|
|
130
|
+
category: 'navigation',
|
|
131
|
+
tags: ['breadcrumbs', 'navigation', 'ux'],
|
|
132
|
+
code: `---
|
|
133
|
+
---
|
|
134
|
+
<nav class="crumbs">
|
|
135
|
+
<a href="/">Home</a>
|
|
136
|
+
<span class="sep">/</span>
|
|
137
|
+
<a href="/docs">Documentation</a>
|
|
138
|
+
<span class="sep">/</span>
|
|
139
|
+
<span class="curr">Navigation</span>
|
|
140
|
+
</nav>
|
|
141
|
+
<style>
|
|
142
|
+
.crumbs { display: flex; gap: 0.6rem; font-size: 0.8rem; font-weight: 500; }
|
|
143
|
+
.crumbs a { color: #64748b; text-decoration: none; }
|
|
144
|
+
.crumbs a:hover { color: #fff; }
|
|
145
|
+
.sep { color: #334155; }
|
|
146
|
+
.curr { color: #818cf8; font-weight: 700; }
|
|
147
|
+
</style>
|
|
148
|
+
`,
|
|
149
|
+
usage: `---
|
|
150
|
+
import { BreadcrumbsMinimal } from 'astro-component-kit';
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
<BreadcrumbsMinimal>
|
|
154
|
+
<a href="/">Home</a>
|
|
155
|
+
<span class="sep">/</span>
|
|
156
|
+
<a href="/docs">Documentation</a>
|
|
157
|
+
<span class="sep">/</span>
|
|
158
|
+
<span class="curr">Navigation</span>
|
|
159
|
+
</BreadcrumbsMinimal>`,
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
slug: 'vertical-tabs',
|
|
163
|
+
name: 'Side Navigation Tabs',
|
|
164
|
+
description: 'Vertical list of tabs for settings or sub-navigation.',
|
|
165
|
+
category: 'navigation',
|
|
166
|
+
tags: ['tabs', 'navigation', 'vertical'],
|
|
167
|
+
code: `---
|
|
168
|
+
---
|
|
169
|
+
<div class="v-tabs">
|
|
170
|
+
<button class="v-tab active">General</button>
|
|
171
|
+
<button class="v-tab">Account</button>
|
|
172
|
+
<button class="v-tab">Security</button>
|
|
173
|
+
<button class="v-tab">Notifications</button>
|
|
174
|
+
</div>
|
|
175
|
+
<style>
|
|
176
|
+
.v-tabs { display: flex; flex-direction: column; width: 200px; border-left: 2px solid #1e293b; }
|
|
177
|
+
.v-tab { background: none; border: none; padding: 0.75rem 1.25rem; text-align: left; color: #64748b; font-weight: 600; font-size: 0.9rem; cursor: pointer; transition: 0.2s; border-left: 2px solid transparent; margin-left: -2px; }
|
|
178
|
+
.v-tab:hover { color: #fff; }
|
|
179
|
+
.v-tab.active { color: #6366f1; border-left-color: #6366f1; background: rgba(99,102,241,0.05); }
|
|
180
|
+
</style>
|
|
181
|
+
`,
|
|
182
|
+
usage: `<VerticalTabs>Content</VerticalTabs>`,
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
slug: 'scroll-progress-top',
|
|
186
|
+
name: 'Scroll Indicator',
|
|
187
|
+
description: 'Thin loading bar at the top of the page reflecting scroll depth.',
|
|
188
|
+
category: 'navigation',
|
|
189
|
+
tags: ['scroll', 'navigation', 'indicator'],
|
|
190
|
+
code: `---
|
|
191
|
+
---
|
|
192
|
+
<div class="scroll-ind" id="scroll-bar"></div>
|
|
193
|
+
<style>
|
|
194
|
+
.scroll-ind { position: fixed; top: 0; left: 0; width: 0%; height: 3px; background: #6366f1; z-index: 1000; box-shadow: 0 0 10px #6366f1; }
|
|
195
|
+
</style>
|
|
196
|
+
<script>
|
|
197
|
+
window.addEventListener('scroll', () => {
|
|
198
|
+
const bar = document.getElementById('scroll-bar');
|
|
199
|
+
const scroll = document.documentElement.scrollTop;
|
|
200
|
+
const height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
|
|
201
|
+
const scrolled = (scroll / height) * 100;
|
|
202
|
+
if (bar) bar.style.width = scrolled + '%';
|
|
203
|
+
});
|
|
204
|
+
</script>
|
|
205
|
+
`,
|
|
206
|
+
usage: `<ScrollProgressTop>Content</ScrollProgressTop>`,
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
slug: 'command-palette-ui',
|
|
210
|
+
name: 'Command Palette UI',
|
|
211
|
+
description: 'Visual placeholder for a searchable command interface.',
|
|
212
|
+
category: 'navigation',
|
|
213
|
+
tags: ['command', 'search', 'navigation'],
|
|
214
|
+
code: `---
|
|
215
|
+
---
|
|
216
|
+
<div class="cmd-palette">
|
|
217
|
+
<div class="cmd-search">🔍 Type a command...</div>
|
|
218
|
+
<div class="cmd-list">
|
|
219
|
+
<div class="cmd-item"><span>📄 Create new page</span><kbd>⌘N</kbd></div>
|
|
220
|
+
<div class="cmd-item"><span>🚀 Deploy to Vercel</span><kbd>⌘D</kbd></div>
|
|
221
|
+
<div class="cmd-item"><span>⚙️ Open settings</span><kbd>⌘,</kbd></div>
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
<style>
|
|
225
|
+
.cmd-palette { background: #0f172a; border: 1px solid #334155; border-radius: 12px; width: 100%; max-width: 500px; box-shadow: 0 30px 60px rgba(0,0,0,0.5); overflow: hidden; }
|
|
226
|
+
.cmd-search { padding: 1rem; border-bottom: 1px solid #334155; color: #64748b; font-size: 0.9rem; }
|
|
227
|
+
.cmd-item { display: flex; justify-content: space-between; padding: 0.75rem 1rem; cursor: pointer; transition: 0.2s; color: #fff; font-size: 0.85rem; }
|
|
228
|
+
.cmd-item:hover { background: #1e293b; }
|
|
229
|
+
kbd { background: #111; border: 1px solid #333; padding: 2px 5px; border-radius: 4px; font-size: 0.7rem; color: #94a3b8; }
|
|
230
|
+
</style>
|
|
231
|
+
`,
|
|
232
|
+
usage: `<CommandPaletteUi>Content</CommandPaletteUi>`,
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
slug: 'mega-menu-glass',
|
|
236
|
+
name: 'Mega Menu Layout',
|
|
237
|
+
description: 'Multi-column dropdown menu for large navigation systems.',
|
|
238
|
+
category: 'navigation',
|
|
239
|
+
tags: ['mega menu', 'dropdown', 'navigation'],
|
|
240
|
+
code: `---
|
|
241
|
+
---
|
|
242
|
+
<div class="mega-wrap">
|
|
243
|
+
<div class="mega-grid">
|
|
244
|
+
<div class="mega-col">
|
|
245
|
+
<h5>Products</h5>
|
|
246
|
+
<a href="#">Analytics</a>
|
|
247
|
+
<a href="#">CRM</a>
|
|
248
|
+
<a href="#">Support</a>
|
|
249
|
+
</div>
|
|
250
|
+
<div class="mega-col">
|
|
251
|
+
<h5>Resources</h5>
|
|
252
|
+
<a href="#">Documentation</a>
|
|
253
|
+
<a href="#">Tutorials</a>
|
|
254
|
+
<a href="#">Guides</a>
|
|
255
|
+
</div>
|
|
256
|
+
</div>
|
|
257
|
+
</div>
|
|
258
|
+
<style>
|
|
259
|
+
.mega-wrap { background: rgba(10, 10, 20, 0.9); backdrop-filter: blur(20px); border: 1px solid rgba(255,255,255,0.1); border-radius: 16px; padding: 2rem; width: 600px; }
|
|
260
|
+
.mega-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; }
|
|
261
|
+
h5 { color: #818cf8; font-size: 0.8rem; margin: 0 0 1rem; text-transform: uppercase; letter-spacing: 0.05em; }
|
|
262
|
+
.mega-col a { display: block; padding: 0.5rem 0; color: #e2e8f0; text-decoration: none; font-size: 0.9rem; }
|
|
263
|
+
.mega-col a:hover { color: #fff; }
|
|
264
|
+
</style>
|
|
265
|
+
`,
|
|
266
|
+
usage: `<MegaMenuGlass>Content</MegaMenuGlass>`,
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
slug: 'tab-underline',
|
|
270
|
+
name: 'Underline Tabs',
|
|
271
|
+
description: 'Clean tabbed navigation with an animated underline indicator.',
|
|
272
|
+
category: 'navigation',
|
|
273
|
+
tags: ['tabs', 'underline', 'animated'],
|
|
274
|
+
code: `---
|
|
275
|
+
---
|
|
276
|
+
<nav class="u-tabs">
|
|
277
|
+
<a href="#" class="active">Profile</a>
|
|
278
|
+
<a href="#">Password</a>
|
|
279
|
+
<a href="#">Sessions</a>
|
|
280
|
+
<div class="indicator"></div>
|
|
281
|
+
</nav>
|
|
282
|
+
<style>
|
|
283
|
+
.u-tabs { display: flex; gap: 2rem; border-bottom: 2px solid rgba(255,255,255,0.05); position: relative; }
|
|
284
|
+
.u-tabs a { padding: 1rem 0; color: #64748b; text-decoration: none; font-weight: 600; font-size: 0.9rem; transition: 0.3s; }
|
|
285
|
+
.u-tabs a.active { color: #fff; }
|
|
286
|
+
.indicator { position: absolute; bottom: -2px; left: 0; width: 50px; height: 2px; background: #6366f1; transition: 0.3s; }
|
|
287
|
+
</style>
|
|
288
|
+
`,
|
|
289
|
+
usage: `<TabUnderline>Content</TabUnderline>`,
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
slug: 'anchor-side-nav',
|
|
293
|
+
name: 'On-Page Anchor Nav',
|
|
294
|
+
description: 'Side menu for navigating between sections of a single page.',
|
|
295
|
+
category: 'navigation',
|
|
296
|
+
tags: ['anchor', 'scroll', 'side nav'],
|
|
297
|
+
code: `---
|
|
298
|
+
---
|
|
299
|
+
<ul class="anchor-nav">
|
|
300
|
+
<li><a href="#intro" class="active">Introduction</a></li>
|
|
301
|
+
<li><a href="#features">Features</a></li>
|
|
302
|
+
<li><a href="#pricing">Pricing</a></li>
|
|
303
|
+
<li><a href="#faq">FAQ</a></li>
|
|
304
|
+
</ul>
|
|
305
|
+
<style>
|
|
306
|
+
.anchor-nav { list-style: none; padding: 0.5rem; border-left: 1px solid rgba(255, 255, 255, 0.1); position: sticky; top: 100px; }
|
|
307
|
+
.anchor-nav a { display: block; padding: 0.4rem 1rem; color: #64748b; text-decoration: none; font-size: 0.85rem; border-left: 2px solid transparent; margin-left: -1.5px; }
|
|
308
|
+
.anchor-nav a.active { color: #818cf8; border-left-color: #6366f1; }
|
|
309
|
+
</style>
|
|
310
|
+
`,
|
|
311
|
+
usage: `<AnchorSideNav>Content</AnchorSideNav>`,
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
slug: 'retro-arcade-menu',
|
|
315
|
+
name: 'Retro Arcade Menu',
|
|
316
|
+
description: '8-bit style navigation with pixelated font and selection arrows.',
|
|
317
|
+
category: 'navigation',
|
|
318
|
+
tags: ['retro', 'navigation', 'game'],
|
|
319
|
+
code: `---
|
|
320
|
+
---
|
|
321
|
+
<div class="retro-menu">
|
|
322
|
+
<div class="item selected">▶ LOAD GAME</div>
|
|
323
|
+
<div class="item">OPTIONS</div>
|
|
324
|
+
<div class="item">EXIT</div>
|
|
325
|
+
</div>
|
|
326
|
+
<style>
|
|
327
|
+
.retro-menu { background: #000; border: 4px solid #fff; padding: 1.5rem; display: flex; flex-direction: column; gap: 1rem; width: fit-content; }
|
|
328
|
+
.item { font-family: 'Courier New', monospace; font-weight: 900; color: #fff; font-size: 1.2rem; cursor: pointer; }
|
|
329
|
+
.item.selected { color: #facc15; }
|
|
330
|
+
</style>
|
|
331
|
+
`,
|
|
332
|
+
usage: `<RetroArcadeMenu>Content</RetroArcadeMenu>`,
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
slug: 'dot-navigation-slider',
|
|
336
|
+
name: 'Dot Slide Indicators',
|
|
337
|
+
description: 'Abstract dot-based navigation for sliders or carousel components.',
|
|
338
|
+
category: 'navigation',
|
|
339
|
+
tags: ['dots', 'slider', 'carousel'],
|
|
340
|
+
code: `---
|
|
341
|
+
---
|
|
342
|
+
<div class="dot-nav">
|
|
343
|
+
<button class="active"></button>
|
|
344
|
+
<button></button>
|
|
345
|
+
<button></button>
|
|
346
|
+
<button></button>
|
|
347
|
+
</div>
|
|
348
|
+
<style>
|
|
349
|
+
.dot-nav { display: flex; gap: 10px; justify-content: center; }
|
|
350
|
+
.dot-nav button { width: 10px; height: 10px; border-radius: 50%; border: none; background: rgba(255,255,255,0.2); cursor: pointer; transition: 0.3s; }
|
|
351
|
+
.dot-nav button.active { width: 24px; border-radius: 5px; background: #6366f1; }
|
|
352
|
+
</style>
|
|
353
|
+
`,
|
|
354
|
+
usage: `<DotNavigationSlider>Content</DotNavigationSlider>`,
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
slug: 'radial-icon-menu',
|
|
358
|
+
name: 'Radial Radial Menu',
|
|
359
|
+
description: 'Circular navigation menu that expands icons around a center point.',
|
|
360
|
+
category: 'navigation',
|
|
361
|
+
tags: ['radial', 'menu', 'animated'],
|
|
362
|
+
code: `---
|
|
363
|
+
---
|
|
364
|
+
<div class="radial-wrap">
|
|
365
|
+
<div class="toggle">+</div>
|
|
366
|
+
<div class="icons">
|
|
367
|
+
<div style="--i:1">📷</div>
|
|
368
|
+
<div style="--i:2">📁</div>
|
|
369
|
+
<div style="--i:3">✉️</div>
|
|
370
|
+
</div>
|
|
371
|
+
</div>
|
|
372
|
+
<style>
|
|
373
|
+
.radial-wrap { position: relative; width: 60px; height: 60px; background: #6366f1; border-radius: 50%; display: grid; place-items: center; color: #fff; cursor: pointer; }
|
|
374
|
+
.icons div { position: absolute; left: 0; transform-origin: 30px; transition: 0.5s; transition-delay: calc(0.1s * var(--i)); transform: rotate(0deg) translateX(0px); opacity: 0; pointer-events: none; }
|
|
375
|
+
.radial-wrap:hover .icons div { transform: rotate(calc(360deg / 8 * var(--i))) translateX(80px); opacity: 1; pointer-events: auto; }
|
|
376
|
+
</style>
|
|
377
|
+
`,
|
|
378
|
+
usage: `<RadialIconMenu>Content</RadialIconMenu>`,
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
slug: 'burger-morph-icon',
|
|
382
|
+
name: 'Animated Burger Menu',
|
|
383
|
+
description: 'CSS burger icon that morphs into an ',
|
|
384
|
+
category: 'navigation',
|
|
385
|
+
tags: ['burger', 'icon', 'animated'],
|
|
386
|
+
code: `---
|
|
387
|
+
---
|
|
388
|
+
<button class="burger" onclick="this.classList.toggle('active')">
|
|
389
|
+
<span></span><span></span><span></span>
|
|
390
|
+
</button>
|
|
391
|
+
<style>
|
|
392
|
+
.burger { background: none; border: none; width: 30px; height: 24px; cursor: pointer; display: flex; flex-direction: column; justify-content: space-between; }
|
|
393
|
+
.burger span { width: 100%; height: 3px; background: #fff; border-radius: 2px; transition: 0.4s; }
|
|
394
|
+
.burger.active span:nth-child(1) { transform: translateY(10.5px) rotate(45deg); }
|
|
395
|
+
.burger.active span:nth-child(2) { opacity: 0; }
|
|
396
|
+
.burger.active span:nth-child(3) { transform: translateY(-10.5px) rotate(-45deg); }
|
|
397
|
+
</style>
|
|
398
|
+
`,
|
|
399
|
+
usage: `<BurgerMorphIcon>Content</BurgerMorphIcon>`,
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
slug: 'lang-switcher-pill',
|
|
403
|
+
name: 'Language Picker Pill',
|
|
404
|
+
description: 'Compact dropdown or group to switch between languages.',
|
|
405
|
+
category: 'navigation',
|
|
406
|
+
tags: ['language', 'picker', 'i18n'],
|
|
407
|
+
code: `---
|
|
408
|
+
---
|
|
409
|
+
<div class="lang-pill">
|
|
410
|
+
<span class="curr">EN</span>
|
|
411
|
+
<div class="list">
|
|
412
|
+
<span>ES</span>
|
|
413
|
+
<span>FR</span>
|
|
414
|
+
<span>JP</span>
|
|
415
|
+
</div>
|
|
416
|
+
</div>
|
|
417
|
+
<style>
|
|
418
|
+
.lang-pill { background: rgba(255,255,255,0.05); padding: 4px 10px; border-radius: 100px; color: #fff; font-size: 0.75rem; font-weight: 800; border: 1px solid rgba(255, 255, 255, 0.1); cursor: pointer; position: relative; }
|
|
419
|
+
.list { position: absolute; top: 110%; left: 0; background: #111; border-radius: 8px; border: 1px solid #333; display: none; flex-direction: column; z-index: 10; }
|
|
420
|
+
.lang-pill:hover .list { display: flex; }
|
|
421
|
+
.list span { padding: 5px 15px; }
|
|
422
|
+
.list span:hover { background: #6366f1; }
|
|
423
|
+
</style>
|
|
424
|
+
`,
|
|
425
|
+
usage: `<LangSwitcherPill>Content</LangSwitcherPill>`,
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
slug: 'user-profile-nav',
|
|
429
|
+
name: 'User Nav Dropdown',
|
|
430
|
+
description: 'Header link showing user avatar and quick actions menu.',
|
|
431
|
+
category: 'navigation',
|
|
432
|
+
tags: ['profile', 'user', 'dropdown'],
|
|
433
|
+
code: `---
|
|
434
|
+
---
|
|
435
|
+
<div class="u-nav">
|
|
436
|
+
<div class="u-avatar">JS</div>
|
|
437
|
+
<div class="u-menu">
|
|
438
|
+
<a href="#">Your Profile</a>
|
|
439
|
+
<a href="#">Settings</a>
|
|
440
|
+
<hr />
|
|
441
|
+
<a href="#" class="logout">Logout</a>
|
|
442
|
+
</div>
|
|
443
|
+
</div>
|
|
444
|
+
<style>
|
|
445
|
+
.u-nav { position: relative; cursor: pointer; }
|
|
446
|
+
.u-avatar { width: 34px; height: 34px; background: linear-gradient(135deg, #6366f1, #c084fc); border-radius: 50%; color: #fff; display: grid; place-items: center; font-size: 0.75rem; font-weight: 800; border: 2px solid #080b14; }
|
|
447
|
+
.u-menu { position: absolute; top: 120%; right: 0; background: #0f172a; border: 1px solid #334155; border-radius: 12px; width: 180px; display: none; flex-direction: column; overflow: hidden; z-index: 10; }
|
|
448
|
+
.u-nav:hover .u-menu { display: flex; }
|
|
449
|
+
.u-menu a { padding: 0.75rem 1rem; font-size: 0.85rem; color: #94a3b8; text-decoration: none; }
|
|
450
|
+
.u-menu a:hover { background: rgba(255,255,255,0.05); color: #fff; }
|
|
451
|
+
.logout { color: #f87171 !important; }
|
|
452
|
+
hr { border: none; border-top: 1px solid #334155; margin: 0; }
|
|
453
|
+
</style>
|
|
454
|
+
`,
|
|
455
|
+
usage: `<UserProfileNav>Content</UserProfileNav>`,
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
slug: 'pagination-infinite-ui',
|
|
459
|
+
name: 'Infinite Scroll UI',
|
|
460
|
+
description: 'Visual indicator for dynamic infinite loading lists.',
|
|
461
|
+
category: 'navigation',
|
|
462
|
+
tags: ['pagination', 'scroll', 'loading'],
|
|
463
|
+
code: `---
|
|
464
|
+
---
|
|
465
|
+
<div class="inf-load">
|
|
466
|
+
<div class="dot-spin"></div>
|
|
467
|
+
<span>Loading more items...</span>
|
|
468
|
+
</div>
|
|
469
|
+
<style>
|
|
470
|
+
.inf-load { display: flex; flex-direction: column; align-items: center; gap: 1rem; padding: 2rem; color: #64748b; font-size: 0.85rem; }
|
|
471
|
+
.dot-spin { width: 30px; height: 30px; border: 2px solid rgba(255,255,255,0.1); border-top-color: #6366f1; border-radius: 50%; animation: spin 0.8s linear infinite; }
|
|
472
|
+
@keyframes spin { to { transform: rotate(360deg); } }
|
|
473
|
+
</style>
|
|
474
|
+
`,
|
|
475
|
+
usage: `<PaginationInfiniteUi>Content</PaginationInfiniteUi>`,
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
slug: 'floating-tab-bar',
|
|
479
|
+
name: 'Floating Tab Bar',
|
|
480
|
+
description: 'Segmented navigation bar that sits above the content.',
|
|
481
|
+
category: 'navigation',
|
|
482
|
+
tags: ['tabs', 'navigation', 'floating'],
|
|
483
|
+
code: `---
|
|
484
|
+
---
|
|
485
|
+
<div class="float-tabs">
|
|
486
|
+
<button class="active">Discover</button>
|
|
487
|
+
<button>Trending</button>
|
|
488
|
+
<button>Following</button>
|
|
489
|
+
</div>
|
|
490
|
+
<style>
|
|
491
|
+
.float-tabs { display: flex; gap: 4px; background: rgba(0,0,0,0.4); padding: 5px; border-radius: 100px; backdrop-filter: blur(10px); border: 1px solid rgba(255,255,255,0.1); width: fit-content; margin: 2rem auto; }
|
|
492
|
+
.float-tabs button { background: none; border: none; padding: 0.6rem 1.4rem; color: #94a3b8; font-weight: 600; font-size: 0.85rem; border-radius: 100px; cursor: pointer; transition: 0.3s; }
|
|
493
|
+
.float-tabs button.active { background: #fff; color: #000; }
|
|
494
|
+
</style>
|
|
495
|
+
`,
|
|
496
|
+
usage: `<FloatingTabBar>Content</FloatingTabBar>`,
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
slug: 'simple-footer-glass',
|
|
500
|
+
name: 'Glass Footer',
|
|
501
|
+
description: 'Elegant bottom section with multi-column links and glass effect.',
|
|
502
|
+
category: 'navigation',
|
|
503
|
+
tags: ['footer', 'navigation', 'layout'],
|
|
504
|
+
code: `---
|
|
505
|
+
---
|
|
506
|
+
<footer class="glass-foot">
|
|
507
|
+
<div class="foot-grid">
|
|
508
|
+
<div class="foot-brand">Astro Components<p>Premium components for the next web.</p></div>
|
|
509
|
+
<div class="foot-links">
|
|
510
|
+
<div><h5>Project</h5><a href="#">Github</a><a href="#">License</a></div>
|
|
511
|
+
<div><h5>Support</h5><a href="#">Issues</a><a href="#">Discord</a></div>
|
|
512
|
+
</div>
|
|
513
|
+
</div>
|
|
514
|
+
</footer>
|
|
515
|
+
<style>
|
|
516
|
+
.glass-foot { background: rgba(255,255,255,0.02); border-top: 1px solid rgba(255, 255, 255, 0.1); padding: 4rem 1.5rem; }
|
|
517
|
+
.foot-grid { max-width: 1200px; margin: 0 auto; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 3rem; }
|
|
518
|
+
.foot-brand { font-weight: 800; font-size: 1.5rem; color: #fff; }
|
|
519
|
+
.foot-brand p { font-size: 0.9rem; color: #64748b; font-weight: 400; margin-top: 0.5rem; max-width: 250px; }
|
|
520
|
+
.foot-links { display: flex; gap: 4rem; }
|
|
521
|
+
h5 { color: #fff; font-size: 0.85rem; margin-bottom: 1.25rem; }
|
|
522
|
+
a { display: block; text-decoration: none; color: #64748b; margin-bottom: 0.6rem; font-size: 0.85rem; }
|
|
523
|
+
a:hover { color: #818cf8; }
|
|
524
|
+
</style>
|
|
525
|
+
`,
|
|
526
|
+
usage: `<SimpleFooterGlass>Content</SimpleFooterGlass>`,
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
slug: 'sub-navbar-pills',
|
|
530
|
+
name: 'Sub Navbar Pills',
|
|
531
|
+
description: 'A secondary sub-navigation pill bar with active glow background, badge indicators, and smooth scroll overflow for dashboards.',
|
|
532
|
+
category: 'navigation',
|
|
533
|
+
tags: ["navigation","navbar","pills","subnav","tabs"],
|
|
534
|
+
featured: true,
|
|
535
|
+
code: `---
|
|
536
|
+
/**
|
|
537
|
+
* SubNavbarPills — Secondary horizontal sub-navigation bar with scrollable pill links and badge counters.
|
|
538
|
+
*
|
|
539
|
+
* @param {Array<{label: string, href: string, count?: number, active?: boolean}>} items - Nav links list.
|
|
540
|
+
* @param {string} className - Optional CSS class.
|
|
541
|
+
*/
|
|
542
|
+
interface Props {
|
|
543
|
+
items?: Array<{ label: string; href: string; count?: number; active?: boolean }>;
|
|
544
|
+
className?: string;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
const {
|
|
548
|
+
items = [
|
|
549
|
+
{ label: 'All Items', href: '#all', count: 124, active: true },
|
|
550
|
+
{ label: 'Components', href: '#components', count: 86 },
|
|
551
|
+
{ label: 'Templates', href: '#templates', count: 18 },
|
|
552
|
+
{ label: 'Icons', href: '#icons', count: 20 },
|
|
553
|
+
{ label: 'Guides', href: '#guides' },
|
|
554
|
+
],
|
|
555
|
+
className = '',
|
|
556
|
+
} = Astro.props;
|
|
557
|
+
---
|
|
558
|
+
|
|
559
|
+
<nav class:list={['subnav-pills', className]} aria-label="Sub navigation">
|
|
560
|
+
<div class="subnav-pills__track">
|
|
561
|
+
{items.map((item) => (
|
|
562
|
+
<a
|
|
563
|
+
href={item.href}
|
|
564
|
+
class:list={['subnav-pills__link', { 'is-active': item.active }]}
|
|
565
|
+
aria-current={item.active ? 'page' : undefined}
|
|
566
|
+
>
|
|
567
|
+
<span>{item.label}</span>
|
|
568
|
+
{item.count !== undefined && (
|
|
569
|
+
<span class="subnav-pills__count">{item.count}</span>
|
|
570
|
+
)}
|
|
571
|
+
</a>
|
|
572
|
+
))}
|
|
573
|
+
</div>
|
|
574
|
+
</nav>
|
|
575
|
+
|
|
576
|
+
<style>
|
|
577
|
+
.subnav-pills {
|
|
578
|
+
display: flex;
|
|
579
|
+
align-items: center;
|
|
580
|
+
width: 100%;
|
|
581
|
+
overflow-x: auto;
|
|
582
|
+
scrollbar-width: none;
|
|
583
|
+
-ms-overflow-style: none;
|
|
584
|
+
padding: 0.5rem 0;
|
|
585
|
+
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
|
586
|
+
font-family: var(--font-sans, system-ui, sans-serif);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
.subnav-pills::-webkit-scrollbar {
|
|
590
|
+
display: none;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
.subnav-pills__track {
|
|
594
|
+
display: inline-flex;
|
|
595
|
+
align-items: center;
|
|
596
|
+
gap: 8px;
|
|
597
|
+
padding: 2px 4px;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
.subnav-pills__link {
|
|
601
|
+
display: inline-flex;
|
|
602
|
+
align-items: center;
|
|
603
|
+
gap: 8px;
|
|
604
|
+
padding: 0.45rem 1rem;
|
|
605
|
+
background: rgba(255, 255, 255, 0.03);
|
|
606
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
607
|
+
border-radius: var(--r-full, 9999px);
|
|
608
|
+
color: var(--c-text-2, #a3a3a3);
|
|
609
|
+
font-size: 0.85rem;
|
|
610
|
+
font-weight: 600;
|
|
611
|
+
text-decoration: none;
|
|
612
|
+
white-space: nowrap;
|
|
613
|
+
transition: all 0.2s ease;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
.subnav-pills__link:hover {
|
|
617
|
+
color: var(--c-text-1, #ffffff);
|
|
618
|
+
background: rgba(255, 255, 255, 0.08);
|
|
619
|
+
border-color: rgba(255, 255, 255, 0.15);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
.subnav-pills__link.is-active {
|
|
623
|
+
background: linear-gradient(135deg, rgba(184, 134, 11, 0.25), rgba(212, 160, 23, 0.25));
|
|
624
|
+
border-color: rgba(184, 134, 11, 0.5);
|
|
625
|
+
color: var(--c-accent, #fef3c7);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
.subnav-pills__count {
|
|
629
|
+
font-size: 0.7rem;
|
|
630
|
+
font-weight: 700;
|
|
631
|
+
background: rgba(0, 0, 0, 0.3);
|
|
632
|
+
padding: 1px 7px;
|
|
633
|
+
border-radius: var(--r-full, 9999px);
|
|
634
|
+
color: inherit;
|
|
635
|
+
}
|
|
636
|
+
</style>
|
|
637
|
+
`,
|
|
638
|
+
usage: `<SubNavbarPills items={[{ label: 'Overview', href: '#overview', active: true }, { label: 'Deployments', href: '#deploy', badge: '3' }, { label: 'Settings', href: '#settings' }]} />`,
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
slug: 'quick-jump-dock',
|
|
642
|
+
name: 'Quick Jump Dock',
|
|
643
|
+
description: 'Floating macOS inspired dock navigation featuring hover scale expansion, tooltips, and fast route shortcuts.',
|
|
644
|
+
category: 'navigation',
|
|
645
|
+
tags: ["navigation","dock","floating","shortcuts","macos"],
|
|
646
|
+
featured: true,
|
|
647
|
+
code: `---
|
|
648
|
+
/**
|
|
649
|
+
* QuickJumpDock — Floating desktop navigation dock bar with hover magnification and tooltips.
|
|
650
|
+
*
|
|
651
|
+
* @param {Array<{label: string, icon: string, href: string}>} items - List of dock actions.
|
|
652
|
+
*/
|
|
653
|
+
interface Props {
|
|
654
|
+
items?: Array<{ label: string; icon: string; href: string }>;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
const {
|
|
658
|
+
items = [
|
|
659
|
+
{
|
|
660
|
+
label: 'Home',
|
|
661
|
+
href: '/',
|
|
662
|
+
icon: \`<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>\`,
|
|
663
|
+
},
|
|
664
|
+
{
|
|
665
|
+
label: 'Components',
|
|
666
|
+
href: '/docs/glass-button',
|
|
667
|
+
icon: \`<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="18" x="3" y="3" rx="2"/><path d="M3 9h18"/><path d="M9 21V9"/></svg>\`,
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
label: 'Sections',
|
|
671
|
+
href: '/sections',
|
|
672
|
+
icon: \`<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="7" height="9" x="3" y="3" rx="1"/><rect width="7" height="5" x="14" y="3" rx="1"/><rect width="7" height="9" x="14" y="12" rx="1"/><rect width="7" height="5" x="3" y="16" rx="1"/></svg>\`,
|
|
673
|
+
},
|
|
674
|
+
{
|
|
675
|
+
label: 'Search',
|
|
676
|
+
href: '#search',
|
|
677
|
+
icon: \`<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>\`,
|
|
678
|
+
},
|
|
679
|
+
{
|
|
680
|
+
label: 'GitHub',
|
|
681
|
+
href: 'https://github.com/konstantinWDK/astro-components',
|
|
682
|
+
icon: \`<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"/></svg>\`,
|
|
683
|
+
},
|
|
684
|
+
],
|
|
685
|
+
} = Astro.props;
|
|
686
|
+
---
|
|
687
|
+
|
|
688
|
+
<nav class="quick-dock" aria-label="Quick dock navigation" data-dock>
|
|
689
|
+
{items.map((item) => (
|
|
690
|
+
<a href={item.href} class="quick-dock__item" aria-label={item.label}>
|
|
691
|
+
<span class="quick-dock__tooltip" aria-hidden="true">{item.label}</span>
|
|
692
|
+
<span class="quick-dock__icon" set:html={item.icon} />
|
|
693
|
+
</a>
|
|
694
|
+
))}
|
|
695
|
+
</nav>
|
|
696
|
+
|
|
697
|
+
<style>
|
|
698
|
+
.quick-dock {
|
|
699
|
+
display: inline-flex;
|
|
700
|
+
align-items: center;
|
|
701
|
+
gap: 8px;
|
|
702
|
+
padding: 8px 12px;
|
|
703
|
+
background: rgba(14, 14, 18, 0.85);
|
|
704
|
+
backdrop-filter: blur(20px);
|
|
705
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
706
|
+
border-radius: var(--r-full, 9999px);
|
|
707
|
+
box-shadow: 0 16px 48px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
.quick-dock__item {
|
|
711
|
+
position: relative;
|
|
712
|
+
display: flex;
|
|
713
|
+
align-items: center;
|
|
714
|
+
justify-content: center;
|
|
715
|
+
width: 42px;
|
|
716
|
+
height: 42px;
|
|
717
|
+
border-radius: 50%;
|
|
718
|
+
background: rgba(255, 255, 255, 0.04);
|
|
719
|
+
border: 1px solid rgba(255, 255, 255, 0.06);
|
|
720
|
+
color: var(--c-text-2, #a3a3a3);
|
|
721
|
+
text-decoration: none;
|
|
722
|
+
transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), background 0.2s ease, color 0.2s ease;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
.quick-dock__item:hover {
|
|
726
|
+
transform: translateY(-8px) scale(1.15);
|
|
727
|
+
background: rgba(184, 134, 11, 0.2);
|
|
728
|
+
border-color: rgba(184, 134, 11, 0.4);
|
|
729
|
+
color: var(--c-primary-light, #d4a017);
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
.quick-dock__icon {
|
|
733
|
+
display: flex;
|
|
734
|
+
align-items: center;
|
|
735
|
+
justify-content: center;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
.quick-dock__tooltip {
|
|
739
|
+
position: absolute;
|
|
740
|
+
bottom: calc(100% + 12px);
|
|
741
|
+
padding: 4px 10px;
|
|
742
|
+
background: #000000;
|
|
743
|
+
color: #ffffff;
|
|
744
|
+
font-family: var(--font-sans, system-ui, sans-serif);
|
|
745
|
+
font-size: 0.72rem;
|
|
746
|
+
font-weight: 700;
|
|
747
|
+
border-radius: 6px;
|
|
748
|
+
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
749
|
+
white-space: nowrap;
|
|
750
|
+
opacity: 0;
|
|
751
|
+
pointer-events: none;
|
|
752
|
+
transform: translateY(6px);
|
|
753
|
+
transition: opacity 0.2s ease, transform 0.2s ease;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
.quick-dock__tooltip::after {
|
|
757
|
+
content: '';
|
|
758
|
+
position: absolute;
|
|
759
|
+
top: 100%;
|
|
760
|
+
left: 50%;
|
|
761
|
+
transform: translateX(-50%);
|
|
762
|
+
border-width: 4px;
|
|
763
|
+
border-style: solid;
|
|
764
|
+
border-color: #000 transparent transparent transparent;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
.quick-dock__item:hover .quick-dock__tooltip {
|
|
768
|
+
opacity: 1;
|
|
769
|
+
transform: translateY(0);
|
|
770
|
+
}
|
|
771
|
+
</style>
|
|
772
|
+
`,
|
|
773
|
+
usage: `<QuickJumpDock items={[{ label: 'Home', href: '/', icon: 'home' }, { label: 'Docs', href: '/docs', icon: 'file' }, { label: 'Settings', href: '/settings', icon: 'settings' }]} />`,
|
|
774
|
+
},
|
|
775
|
+
{
|
|
776
|
+
slug: 'step-breadcrumb-bar',
|
|
777
|
+
name: 'Step Breadcrumb Bar',
|
|
778
|
+
description: 'Multi-step workflow progress breadcrumb indicating completed, current, and upcoming stages.',
|
|
779
|
+
category: 'navigation',
|
|
780
|
+
tags: ["navigation","breadcrumb","steps","workflow","wizard"],
|
|
781
|
+
featured: false,
|
|
782
|
+
code: `---
|
|
783
|
+
/**
|
|
784
|
+
* StepBreadcrumbBar — Stepped workflow breadcrumb indicator for checkout, multi-step forms, or wizards.
|
|
785
|
+
*
|
|
786
|
+
* @param {Array<{step: number, label: string, status: 'complete' | 'active' | 'upcoming', href?: string}>} steps - Step definitions.
|
|
787
|
+
*/
|
|
788
|
+
interface Props {
|
|
789
|
+
steps?: Array<{
|
|
790
|
+
step: number;
|
|
791
|
+
label: string;
|
|
792
|
+
status: 'complete' | 'active' | 'upcoming';
|
|
793
|
+
href?: string;
|
|
794
|
+
}>;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
const {
|
|
798
|
+
steps = [
|
|
799
|
+
{ step: 1, label: 'Account', status: 'complete', href: '#step-1' },
|
|
800
|
+
{ step: 2, label: 'Plan & Billing', status: 'active', href: '#step-2' },
|
|
801
|
+
{ step: 3, label: 'Preferences', status: 'upcoming', href: '#step-3' },
|
|
802
|
+
{ step: 4, label: 'Review', status: 'upcoming', href: '#step-4' },
|
|
803
|
+
],
|
|
804
|
+
} = Astro.props;
|
|
805
|
+
---
|
|
806
|
+
|
|
807
|
+
<nav class="step-nav" aria-label="Workflow progress">
|
|
808
|
+
<ol class="step-nav__list">
|
|
809
|
+
{steps.map((st, i) => (
|
|
810
|
+
<li class:list={['step-nav__item', \`step-nav__item--\${st.status}\`]}>
|
|
811
|
+
<a href={st.href || '#'} class="step-nav__link" aria-current={st.status === 'active' ? 'step' : undefined}>
|
|
812
|
+
<span class="step-nav__circle">
|
|
813
|
+
{st.status === 'complete' ? (
|
|
814
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
|
|
815
|
+
<polyline points="20 6 9 17 4 12" />
|
|
816
|
+
</svg>
|
|
817
|
+
) : (
|
|
818
|
+
st.step
|
|
819
|
+
)}
|
|
820
|
+
</span>
|
|
821
|
+
<span class="step-nav__label">{st.label}</span>
|
|
822
|
+
</a>
|
|
823
|
+
{i < steps.length - 1 && (
|
|
824
|
+
<div class="step-nav__line" aria-hidden="true"></div>
|
|
825
|
+
)}
|
|
826
|
+
</li>
|
|
827
|
+
))}
|
|
828
|
+
</ol>
|
|
829
|
+
</nav>
|
|
830
|
+
|
|
831
|
+
<style>
|
|
832
|
+
.step-nav {
|
|
833
|
+
width: 100%;
|
|
834
|
+
max-width: 680px;
|
|
835
|
+
font-family: var(--font-sans, system-ui, sans-serif);
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
.step-nav__list {
|
|
839
|
+
display: flex;
|
|
840
|
+
align-items: center;
|
|
841
|
+
list-style: none;
|
|
842
|
+
padding: 0;
|
|
843
|
+
margin: 0;
|
|
844
|
+
width: 100%;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
.step-nav__item {
|
|
848
|
+
display: flex;
|
|
849
|
+
align-items: center;
|
|
850
|
+
flex: 1;
|
|
851
|
+
position: relative;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
.step-nav__item:last-child {
|
|
855
|
+
flex: 0 0 auto;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
.step-nav__link {
|
|
859
|
+
display: inline-flex;
|
|
860
|
+
align-items: center;
|
|
861
|
+
gap: 10px;
|
|
862
|
+
text-decoration: none;
|
|
863
|
+
color: var(--c-text-3, #737373);
|
|
864
|
+
font-size: 0.82rem;
|
|
865
|
+
font-weight: 600;
|
|
866
|
+
white-space: nowrap;
|
|
867
|
+
transition: color 0.2s ease;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
.step-nav__link:hover {
|
|
871
|
+
color: var(--c-text-1, #ffffff);
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
.step-nav__circle {
|
|
875
|
+
display: grid;
|
|
876
|
+
place-items: center;
|
|
877
|
+
width: 28px;
|
|
878
|
+
height: 28px;
|
|
879
|
+
border-radius: 50%;
|
|
880
|
+
background: rgba(255, 255, 255, 0.04);
|
|
881
|
+
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
882
|
+
color: var(--c-text-2, #a3a3a3);
|
|
883
|
+
font-size: 0.78rem;
|
|
884
|
+
font-weight: 700;
|
|
885
|
+
flex-shrink: 0;
|
|
886
|
+
transition: all 0.25s ease;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
/* Status modifiers */
|
|
890
|
+
.step-nav__item--complete .step-nav__circle {
|
|
891
|
+
background: rgba(16, 185, 129, 0.15);
|
|
892
|
+
border-color: #10b981;
|
|
893
|
+
color: #10b981;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
.step-nav__item--complete .step-nav__label {
|
|
897
|
+
color: var(--c-text-1, #ffffff);
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
.step-nav__item--active .step-nav__circle {
|
|
901
|
+
background: linear-gradient(135deg, #d4a017, #b8860b);
|
|
902
|
+
border-color: #d4a017;
|
|
903
|
+
color: #050505;
|
|
904
|
+
box-shadow: 0 0 12px rgba(212, 160, 23, 0.4);
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
.step-nav__item--active .step-nav__label {
|
|
908
|
+
color: var(--c-primary-light, #d4a017);
|
|
909
|
+
font-weight: 700;
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
.step-nav__line {
|
|
913
|
+
flex: 1;
|
|
914
|
+
height: 2px;
|
|
915
|
+
background: rgba(255, 255, 255, 0.08);
|
|
916
|
+
margin: 0 12px;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
.step-nav__item--complete .step-nav__line {
|
|
920
|
+
background: #10b981;
|
|
921
|
+
opacity: 0.5;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
@media (max-width: 640px) {
|
|
925
|
+
.step-nav__label {
|
|
926
|
+
display: none;
|
|
927
|
+
}
|
|
928
|
+
.step-nav__line {
|
|
929
|
+
margin: 0 6px;
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
</style>
|
|
933
|
+
`,
|
|
934
|
+
usage: `<StepBreadcrumbBar steps={[{ label: 'Cart', status: 'completed' }, { label: 'Shipping', status: 'current' }, { label: 'Payment', status: 'upcoming' }]} />`,
|
|
935
|
+
},
|
|
936
|
+
];
|