@luciodale/docs-ui-kit 0.2.0 → 0.2.2
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 +47 -4
- package/package.json +1 -1
- package/src/components/Callout.astro +1 -1
- package/src/components/CodeBlock.astro +2 -2
- package/src/components/FeatureList.astro +42 -0
- package/src/components/Footer.astro +8 -7
- package/src/components/HeroSection.astro +2 -2
- package/src/components/Navbar.astro +17 -16
- package/src/components/PackageInfo.astro +3 -3
- package/src/components/PropsTable.astro +7 -7
- package/src/components/SearchModal.astro +8 -8
- package/src/components/SidebarSection.astro +4 -3
- package/src/components/TableOfContents.astro +2 -2
- package/src/utils/base-path.ts +10 -0
package/README.md
CHANGED
|
@@ -313,6 +313,46 @@ import Callout from "@luciodale/docs-ui-kit/components/Callout.astro";
|
|
|
313
313
|
|
|
314
314
|
Renders a left-bordered aside with icon, title, and slot content. Supports links (`<a>`) and inline code (`<code>`) in the body.
|
|
315
315
|
|
|
316
|
+
#### FeatureList
|
|
317
|
+
|
|
318
|
+
Highlighted feature list with colored dots and keywords. Designed for landing pages and feature summaries.
|
|
319
|
+
|
|
320
|
+
```astro
|
|
321
|
+
---
|
|
322
|
+
import FeatureList from "@luciodale/docs-ui-kit/components/FeatureList.astro";
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
<FeatureList features={[
|
|
326
|
+
{ highlight: "Type-safe", description: "Full TypeScript support out of the box" },
|
|
327
|
+
{ highlight: "Lightweight", description: "Zero runtime overhead", color: "green" },
|
|
328
|
+
{ highlight: "Dark theme", description: "Built for modern documentation sites" },
|
|
329
|
+
]} />
|
|
330
|
+
|
|
331
|
+
<!-- Or set a global color for all items -->
|
|
332
|
+
<FeatureList
|
|
333
|
+
color="cyan"
|
|
334
|
+
features={[
|
|
335
|
+
{ highlight: "Fast", description: "Build-time syntax highlighting via Shiki" },
|
|
336
|
+
{ highlight: "Searchable", description: "Full-text search powered by Pagefind" },
|
|
337
|
+
]}
|
|
338
|
+
/>
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
| Prop | Type | Required | Description |
|
|
342
|
+
|---|---|---|---|
|
|
343
|
+
| `features` | `Array<FeatureItem>` | Yes | List of feature items (see below). |
|
|
344
|
+
| `color` | `FeatureColor` | No | Default: `"accent"`. Global color for all items. Overridden by per-item `color`. |
|
|
345
|
+
|
|
346
|
+
**FeatureItem:**
|
|
347
|
+
|
|
348
|
+
| Field | Type | Required | Description |
|
|
349
|
+
|---|---|---|---|
|
|
350
|
+
| `highlight` | `string` | Yes | Colored keyword/phrase. Rendered in bold with the active color. |
|
|
351
|
+
| `description` | `string` | No | Text after the highlight, separated by an em dash. |
|
|
352
|
+
| `color` | `FeatureColor` | No | Per-item color override. |
|
|
353
|
+
|
|
354
|
+
**FeatureColor:** `"accent"` \| `"blue"` \| `"green"` \| `"purple"` \| `"yellow"` \| `"cyan"`
|
|
355
|
+
|
|
316
356
|
#### PackageInfo
|
|
317
357
|
|
|
318
358
|
Displays npm version, license, GitHub stars, and a bundlephobia link. Data is fetched at build time from the npm registry and GitHub API (3s timeout, graceful fallback).
|
|
@@ -506,6 +546,7 @@ const { title, description } = Astro.props;
|
|
|
506
546
|
// src/pages/index.astro
|
|
507
547
|
import PageLayout from "@luciodale/docs-ui-kit/components/PageLayout.astro";
|
|
508
548
|
import HeroSection from "@luciodale/docs-ui-kit/components/HeroSection.astro";
|
|
549
|
+
import FeatureList from "@luciodale/docs-ui-kit/components/FeatureList.astro";
|
|
509
550
|
import { siteConfig } from "../config";
|
|
510
551
|
import Base from "../layouts/Base.astro";
|
|
511
552
|
|
|
@@ -519,9 +560,11 @@ export const prerender = true;
|
|
|
519
560
|
description={siteConfig.description}
|
|
520
561
|
installCommand={siteConfig.installCommand}
|
|
521
562
|
>
|
|
522
|
-
<
|
|
523
|
-
|
|
524
|
-
|
|
563
|
+
<FeatureList features={[
|
|
564
|
+
{ highlight: "Type-safe", description: "Full TypeScript support" },
|
|
565
|
+
{ highlight: "Lightweight", description: "Zero runtime dependencies", color: "green" },
|
|
566
|
+
{ highlight: "Fast", description: "Build-time syntax highlighting", color: "cyan" },
|
|
567
|
+
]} />
|
|
525
568
|
</HeroSection>
|
|
526
569
|
</PageLayout>
|
|
527
570
|
</Base>
|
|
@@ -588,7 +631,7 @@ Defined in `theme.css` via Tailwind v4 `@theme` tokens:
|
|
|
588
631
|
| `--color-border` | `#e5e7eb` | Light border. |
|
|
589
632
|
| `--color-muted` | `#848d9f` | Muted text. |
|
|
590
633
|
|
|
591
|
-
Body: `background: black`, `color: white`. All components use `white/` opacity variants for text hierarchy (`text-white/60
|
|
634
|
+
Body: `background: black`, `color: white`. All components use `white/` opacity variants for text hierarchy (`text-white/70` body text, `text-white/60` secondary, `text-white/40` labels, `text-white/30` decorative).
|
|
592
635
|
|
|
593
636
|
## Responsive behavior
|
|
594
637
|
|
package/package.json
CHANGED
|
@@ -52,7 +52,7 @@ const heading = title ?? s.defaultTitle;
|
|
|
52
52
|
{type === "danger" && <DangerIcon />}
|
|
53
53
|
{heading}
|
|
54
54
|
</div>
|
|
55
|
-
<div class="text-sm text-white/
|
|
55
|
+
<div class="text-sm text-white/70 leading-relaxed [&_a]:text-accent [&_a]:underline [&_code]:text-white/80 [&_code]:font-mono [&_code]:text-xs">
|
|
56
56
|
<slot />
|
|
57
57
|
</div>
|
|
58
58
|
</aside>
|
|
@@ -17,10 +17,10 @@ const html = await codeToHtml(trimmed, {
|
|
|
17
17
|
|
|
18
18
|
<div class="rounded-lg border border-white/10 bg-[#161618] overflow-hidden my-4">
|
|
19
19
|
<div class="flex items-center justify-between px-4 py-2.5 border-b border-white/[0.06] bg-white/[0.02]">
|
|
20
|
-
<span class="text-xs text-white/
|
|
20
|
+
<span class="text-xs text-white/40 font-mono">{filename ?? language}</span>
|
|
21
21
|
<button
|
|
22
22
|
type="button"
|
|
23
|
-
class="copy-btn text-xs text-white/
|
|
23
|
+
class="copy-btn text-xs text-white/40 hover:text-white/70 transition-colors cursor-pointer"
|
|
24
24
|
data-code={trimmed}
|
|
25
25
|
>
|
|
26
26
|
<span class="copy-label">Copy</span>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
type FeatureColor = "accent" | "blue" | "green" | "purple" | "yellow" | "cyan";
|
|
3
|
+
|
|
4
|
+
type FeatureItem = {
|
|
5
|
+
highlight: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
color?: FeatureColor;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
type Props = {
|
|
11
|
+
features: FeatureItem[];
|
|
12
|
+
color?: FeatureColor;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const { features, color = "accent" } = Astro.props;
|
|
16
|
+
|
|
17
|
+
const colorMap: Record<FeatureColor, { text: string; dot: string }> = {
|
|
18
|
+
accent: { text: "text-accent", dot: "bg-accent" },
|
|
19
|
+
blue: { text: "text-blue-400", dot: "bg-blue-400" },
|
|
20
|
+
green: { text: "text-green-400", dot: "bg-green-400" },
|
|
21
|
+
purple: { text: "text-purple-400", dot: "bg-purple-400" },
|
|
22
|
+
yellow: { text: "text-yellow-400", dot: "bg-yellow-400" },
|
|
23
|
+
cyan: { text: "text-cyan-400", dot: "bg-cyan-400" },
|
|
24
|
+
};
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
<ul class="flex flex-col gap-3 list-none m-0 p-0">
|
|
28
|
+
{features.map((feature) => {
|
|
29
|
+
const c = colorMap[feature.color ?? color];
|
|
30
|
+
return (
|
|
31
|
+
<li class="flex items-start gap-3">
|
|
32
|
+
<span class:list={["mt-[7px] w-1.5 h-1.5 rounded-full shrink-0", c.dot]} />
|
|
33
|
+
<span class="text-base leading-relaxed">
|
|
34
|
+
<span class:list={["font-semibold", c.text]}>{feature.highlight}</span>
|
|
35
|
+
{feature.description && (
|
|
36
|
+
<span class="text-white/70">{" "}— {feature.description}</span>
|
|
37
|
+
)}
|
|
38
|
+
</span>
|
|
39
|
+
</li>
|
|
40
|
+
);
|
|
41
|
+
})}
|
|
42
|
+
</ul>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import type { SiteConfig } from "../types/config";
|
|
3
|
+
import { withBase } from "../utils/base-path";
|
|
3
4
|
import GithubIcon from "./GithubIcon.astro";
|
|
4
5
|
import LinkedInIcon from "./LinkedInIcon.astro";
|
|
5
6
|
|
|
@@ -17,15 +18,15 @@ const copyright = config.copyright ?? config.title;
|
|
|
17
18
|
<div class="flex flex-col md:flex-row items-center gap-6 md:gap-4">
|
|
18
19
|
<div class="flex items-center gap-3 md:w-1/3">
|
|
19
20
|
{config.logoSrc && (
|
|
20
|
-
<a href="/">
|
|
21
|
+
<a href={withBase("/")}>
|
|
21
22
|
<img
|
|
22
|
-
src={config.logoSrc}
|
|
23
|
+
src={withBase(config.logoSrc)}
|
|
23
24
|
alt={config.logoAlt ?? config.title}
|
|
24
25
|
class="w-8 h-auto opacity-60 hover:opacity-100 transition-opacity"
|
|
25
26
|
/>
|
|
26
27
|
</a>
|
|
27
28
|
)}
|
|
28
|
-
<span class="text-white/
|
|
29
|
+
<span class="text-white/50 text-sm">
|
|
29
30
|
© {year} {copyright}
|
|
30
31
|
</span>
|
|
31
32
|
</div>
|
|
@@ -33,8 +34,8 @@ const copyright = config.copyright ?? config.title;
|
|
|
33
34
|
<div class="flex gap-6 md:w-1/3 justify-center">
|
|
34
35
|
{config.navLinks.map((link) => (
|
|
35
36
|
<a
|
|
36
|
-
href={link.href}
|
|
37
|
-
class="text-white/
|
|
37
|
+
href={withBase(link.href)}
|
|
38
|
+
class="text-white/50 text-sm hover:text-white/80 transition-colors"
|
|
38
39
|
>
|
|
39
40
|
{link.label}
|
|
40
41
|
</a>
|
|
@@ -46,7 +47,7 @@ const copyright = config.copyright ?? config.title;
|
|
|
46
47
|
href={config.socialLinks.github}
|
|
47
48
|
target="_blank"
|
|
48
49
|
rel="noopener noreferrer"
|
|
49
|
-
class="text-white/
|
|
50
|
+
class="text-white/40 hover:text-white/70 transition-colors"
|
|
50
51
|
>
|
|
51
52
|
<GithubIcon class="w-5" />
|
|
52
53
|
</a>
|
|
@@ -55,7 +56,7 @@ const copyright = config.copyright ?? config.title;
|
|
|
55
56
|
href={config.socialLinks.linkedin}
|
|
56
57
|
target="_blank"
|
|
57
58
|
rel="noopener noreferrer"
|
|
58
|
-
class="text-white/
|
|
59
|
+
class="text-white/40 hover:text-white/70 transition-colors"
|
|
59
60
|
>
|
|
60
61
|
<LinkedInIcon class="w-5" />
|
|
61
62
|
</a>
|
|
@@ -18,7 +18,7 @@ const hasExtra = Astro.slots.has("default");
|
|
|
18
18
|
<h1 class="text-4xl md:text-5xl font-bold tracking-tight text-white leading-[1.1] mb-4">
|
|
19
19
|
{title}
|
|
20
20
|
</h1>
|
|
21
|
-
<p class="text-lg text-white/
|
|
21
|
+
<p class="text-lg text-white/60 leading-relaxed max-w-xl mb-10">{description}</p>
|
|
22
22
|
<button
|
|
23
23
|
type="button"
|
|
24
24
|
class="copy-btn group rounded-lg border border-white/10 bg-white/5 hover:bg-white/[0.08] px-5 py-3 font-mono text-sm text-white/70 transition-colors cursor-pointer"
|
|
@@ -26,7 +26,7 @@ const hasExtra = Astro.slots.has("default");
|
|
|
26
26
|
>
|
|
27
27
|
<span class="text-accent">$</span>
|
|
28
28
|
<span class="ml-2">{installCommand}</span>
|
|
29
|
-
<span class="ml-3 text-white/
|
|
29
|
+
<span class="ml-3 text-white/40 group-hover:text-white/60 transition-colors text-xs copy-label">
|
|
30
30
|
Copy
|
|
31
31
|
</span>
|
|
32
32
|
</button>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import type { SiteConfig } from "../types/config";
|
|
3
|
+
import { withBase } from "../utils/base-path";
|
|
3
4
|
import GithubIcon from "./GithubIcon.astro";
|
|
4
5
|
import SearchModal from "./SearchModal.astro";
|
|
5
6
|
|
|
@@ -13,9 +14,9 @@ const { config, currentPath } = Astro.props;
|
|
|
13
14
|
|
|
14
15
|
<header class="sticky top-0 z-50 h-16 border-b border-white/10 bg-black/80 backdrop-blur-md">
|
|
15
16
|
<div class="max-w-7xl h-full mx-auto px-6 md:px-8 flex items-center justify-between">
|
|
16
|
-
<a href="/" class="flex items-center gap-3 text-white hover:opacity-80 transition-opacity">
|
|
17
|
+
<a href={withBase("/")} class="flex items-center gap-3 text-white hover:opacity-80 transition-opacity">
|
|
17
18
|
{config.logoSrc ? (
|
|
18
|
-
<img src={config.logoSrc} alt={config.logoAlt ?? config.title} class="h-7" />
|
|
19
|
+
<img src={withBase(config.logoSrc)} alt={config.logoAlt ?? config.title} class="h-7" />
|
|
19
20
|
) : (
|
|
20
21
|
<span class="text-base font-semibold tracking-tight">{config.title}</span>
|
|
21
22
|
)}
|
|
@@ -24,12 +25,12 @@ const { config, currentPath } = Astro.props;
|
|
|
24
25
|
<nav class="hidden md:flex items-center gap-6">
|
|
25
26
|
{config.navLinks.map((link) => (
|
|
26
27
|
<a
|
|
27
|
-
href={link.href}
|
|
28
|
+
href={withBase(link.href)}
|
|
28
29
|
class:list={[
|
|
29
30
|
"text-sm font-medium transition-colors duration-150",
|
|
30
31
|
currentPath.startsWith(link.href)
|
|
31
32
|
? "text-white"
|
|
32
|
-
: "text-white/
|
|
33
|
+
: "text-white/60 hover:text-white/90",
|
|
33
34
|
]}
|
|
34
35
|
>
|
|
35
36
|
{link.label}
|
|
@@ -38,14 +39,14 @@ const { config, currentPath } = Astro.props;
|
|
|
38
39
|
<button
|
|
39
40
|
id="search-trigger"
|
|
40
41
|
type="button"
|
|
41
|
-
class="flex items-center gap-2 rounded-lg border border-white/10 bg-white/[0.03] hover:bg-white/[0.06] px-3 py-1.5 text-white/
|
|
42
|
+
class="flex items-center gap-2 rounded-lg border border-white/10 bg-white/[0.03] hover:bg-white/[0.06] px-3 py-1.5 text-white/50 hover:text-white/70 transition-colors cursor-pointer"
|
|
42
43
|
>
|
|
43
44
|
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
|
44
45
|
<circle cx="11" cy="11" r="7" />
|
|
45
46
|
<line x1="16.5" y1="16.5" x2="21" y2="21" />
|
|
46
47
|
</svg>
|
|
47
48
|
<span class="text-xs">Search</span>
|
|
48
|
-
<kbd class="ml-2 rounded border border-white/10 bg-white/[0.04] px-1.5 py-0.5 text-[10px] font-mono text-white/
|
|
49
|
+
<kbd class="ml-2 rounded border border-white/10 bg-white/[0.04] px-1.5 py-0.5 text-[10px] font-mono text-white/40">
|
|
49
50
|
<span class="text-[10px]">⌘</span>K
|
|
50
51
|
</kbd>
|
|
51
52
|
</button>
|
|
@@ -53,7 +54,7 @@ const { config, currentPath } = Astro.props;
|
|
|
53
54
|
href={config.githubUrl}
|
|
54
55
|
target="_blank"
|
|
55
56
|
rel="noopener noreferrer"
|
|
56
|
-
class="text-white/
|
|
57
|
+
class="text-white/50 hover:text-white/80 transition-colors duration-150"
|
|
57
58
|
>
|
|
58
59
|
<GithubIcon class="w-5" />
|
|
59
60
|
</a>
|
|
@@ -63,7 +64,7 @@ const { config, currentPath } = Astro.props;
|
|
|
63
64
|
<button
|
|
64
65
|
id="search-trigger-mobile"
|
|
65
66
|
type="button"
|
|
66
|
-
class="text-white/
|
|
67
|
+
class="text-white/60 hover:text-white transition-colors cursor-pointer"
|
|
67
68
|
aria-label="Search"
|
|
68
69
|
>
|
|
69
70
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
|
@@ -74,7 +75,7 @@ const { config, currentPath } = Astro.props;
|
|
|
74
75
|
<button
|
|
75
76
|
id="mobile-nav-toggle"
|
|
76
77
|
type="button"
|
|
77
|
-
class="text-white/
|
|
78
|
+
class="text-white/70 hover:text-white transition-colors cursor-pointer"
|
|
78
79
|
aria-label="Toggle menu"
|
|
79
80
|
>
|
|
80
81
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
@@ -96,7 +97,7 @@ const { config, currentPath } = Astro.props;
|
|
|
96
97
|
<button
|
|
97
98
|
id="mobile-nav-close"
|
|
98
99
|
type="button"
|
|
99
|
-
class="text-white/
|
|
100
|
+
class="text-white/70 hover:text-white transition-colors cursor-pointer"
|
|
100
101
|
aria-label="Close menu"
|
|
101
102
|
>
|
|
102
103
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
@@ -108,12 +109,12 @@ const { config, currentPath } = Astro.props;
|
|
|
108
109
|
<div class="px-6 py-4 flex flex-col gap-3 border-b border-white/10">
|
|
109
110
|
{config.navLinks.map((link) => (
|
|
110
111
|
<a
|
|
111
|
-
href={link.href}
|
|
112
|
+
href={withBase(link.href)}
|
|
112
113
|
class:list={[
|
|
113
114
|
"text-sm font-medium transition-colors",
|
|
114
115
|
currentPath.startsWith(link.href)
|
|
115
116
|
? "text-white"
|
|
116
|
-
: "text-white/
|
|
117
|
+
: "text-white/60 hover:text-white/90",
|
|
117
118
|
]}
|
|
118
119
|
>
|
|
119
120
|
{link.label}
|
|
@@ -125,18 +126,18 @@ const { config, currentPath } = Astro.props;
|
|
|
125
126
|
<div class="px-6 py-4">
|
|
126
127
|
{config.sidebarSections.map((section) => (
|
|
127
128
|
<div class="mb-5">
|
|
128
|
-
<div class="text-xs font-semibold uppercase tracking-widest text-white/
|
|
129
|
+
<div class="text-xs font-semibold uppercase tracking-widest text-white/40 mb-2">
|
|
129
130
|
{section.title}
|
|
130
131
|
</div>
|
|
131
132
|
<div class="flex flex-col">
|
|
132
133
|
{section.links.map((link) => (
|
|
133
134
|
<a
|
|
134
|
-
href={link.href}
|
|
135
|
+
href={withBase(link.href)}
|
|
135
136
|
class:list={[
|
|
136
137
|
"block py-1.5 pl-3 text-sm border-l-2 transition-colors",
|
|
137
138
|
currentPath === link.href
|
|
138
139
|
? "border-accent text-white font-medium"
|
|
139
|
-
: "border-transparent text-white/
|
|
140
|
+
: "border-transparent text-white/60 hover:text-white/90 hover:border-white/20",
|
|
140
141
|
]}
|
|
141
142
|
>
|
|
142
143
|
{link.label}
|
|
@@ -153,7 +154,7 @@ const { config, currentPath } = Astro.props;
|
|
|
153
154
|
href={config.socialLinks.github}
|
|
154
155
|
target="_blank"
|
|
155
156
|
rel="noopener noreferrer"
|
|
156
|
-
class="text-white/
|
|
157
|
+
class="text-white/40 hover:text-white/70 transition-colors"
|
|
157
158
|
>
|
|
158
159
|
<GithubIcon class="w-5" />
|
|
159
160
|
</a>
|
|
@@ -61,7 +61,7 @@ const [npm, github] = await Promise.all([fetchNpm(), fetchGithub()]);
|
|
|
61
61
|
</a>
|
|
62
62
|
)}
|
|
63
63
|
{npm?.license && (
|
|
64
|
-
<span class="inline-flex items-center rounded-md border border-white/10 bg-white/[0.03] px-2.5 py-1 text-white/
|
|
64
|
+
<span class="inline-flex items-center rounded-md border border-white/10 bg-white/[0.03] px-2.5 py-1 text-white/60">
|
|
65
65
|
{npm.license}
|
|
66
66
|
</span>
|
|
67
67
|
)}
|
|
@@ -70,7 +70,7 @@ const [npm, github] = await Promise.all([fetchNpm(), fetchGithub()]);
|
|
|
70
70
|
href={`https://github.com/${githubRepo}`}
|
|
71
71
|
target="_blank"
|
|
72
72
|
rel="noopener noreferrer"
|
|
73
|
-
class="inline-flex items-center gap-1.5 rounded-md border border-white/10 bg-white/[0.03] px-2.5 py-1 text-white/
|
|
73
|
+
class="inline-flex items-center gap-1.5 rounded-md border border-white/10 bg-white/[0.03] px-2.5 py-1 text-white/60 hover:bg-white/[0.06] transition-colors"
|
|
74
74
|
>
|
|
75
75
|
<svg class="w-3 h-3" fill="currentColor" viewBox="0 0 24 24">
|
|
76
76
|
<path d="M12 .587l3.668 7.568 8.332 1.151-6.064 5.828 1.48 8.279L12 19.771l-7.416 3.642 1.48-8.279L0 9.306l8.332-1.151z" />
|
|
@@ -82,7 +82,7 @@ const [npm, github] = await Promise.all([fetchNpm(), fetchGithub()]);
|
|
|
82
82
|
href={`https://bundlephobia.com/package/${packageName}${npm?.version ? `@${npm.version}` : ""}`}
|
|
83
83
|
target="_blank"
|
|
84
84
|
rel="noopener noreferrer"
|
|
85
|
-
class="inline-flex items-center gap-1.5 rounded-md border border-white/10 bg-white/[0.03] px-2.5 py-1 text-white/
|
|
85
|
+
class="inline-flex items-center gap-1.5 rounded-md border border-white/10 bg-white/[0.03] px-2.5 py-1 text-white/60 hover:bg-white/[0.06] transition-colors"
|
|
86
86
|
>
|
|
87
87
|
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
|
|
88
88
|
<path d="M21 16V8a2 2 0 00-1-1.73l-7-4a2 2 0 00-2 0l-7 4A2 2 0 002 8v8a2 2 0 001 1.73l7 4a2 2 0 002 0l7-4A2 2 0 0021 16z" />
|
|
@@ -16,10 +16,10 @@ const { title, rows } = Astro.props;
|
|
|
16
16
|
<table class="w-full text-left text-sm">
|
|
17
17
|
<thead>
|
|
18
18
|
<tr class="border-b border-white/10 bg-white/[0.02]">
|
|
19
|
-
<th class="py-3 px-4 text-xs font-medium text-white/
|
|
20
|
-
<th class="py-3 px-4 text-xs font-medium text-white/
|
|
21
|
-
<th class="py-3 px-4 text-xs font-medium text-white/
|
|
22
|
-
<th class="py-3 px-4 text-xs font-medium text-white/
|
|
19
|
+
<th class="py-3 px-4 text-xs font-medium text-white/50 uppercase tracking-wider">Prop</th>
|
|
20
|
+
<th class="py-3 px-4 text-xs font-medium text-white/50 uppercase tracking-wider">Type</th>
|
|
21
|
+
<th class="py-3 px-4 text-xs font-medium text-white/50 uppercase tracking-wider">Default</th>
|
|
22
|
+
<th class="py-3 px-4 text-xs font-medium text-white/50 uppercase tracking-wider">Description</th>
|
|
23
23
|
</tr>
|
|
24
24
|
</thead>
|
|
25
25
|
<tbody>
|
|
@@ -30,12 +30,12 @@ const { title, rows } = Astro.props;
|
|
|
30
30
|
{row.required && <span class="ml-1 text-red-400 text-xs">*</span>}
|
|
31
31
|
</td>
|
|
32
32
|
<td class="py-3 px-4">
|
|
33
|
-
<code class="text-white/
|
|
33
|
+
<code class="text-white/60 font-mono text-xs">{row.type}</code>
|
|
34
34
|
</td>
|
|
35
|
-
<td class="py-3 px-4 text-white/
|
|
35
|
+
<td class="py-3 px-4 text-white/45 text-xs font-mono">
|
|
36
36
|
{row.defaultValue ?? "\u2014"}
|
|
37
37
|
</td>
|
|
38
|
-
<td class="py-3 px-4 text-white/
|
|
38
|
+
<td class="py-3 px-4 text-white/70 text-sm">{row.description}</td>
|
|
39
39
|
</tr>
|
|
40
40
|
))}
|
|
41
41
|
</tbody>
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
.search-dialog-icon {
|
|
76
76
|
width: 0.875rem;
|
|
77
77
|
height: 0.875rem;
|
|
78
|
-
color: rgb(255 255 255 / 0.
|
|
78
|
+
color: rgb(255 255 255 / 0.4);
|
|
79
79
|
flex-shrink: 0;
|
|
80
80
|
}
|
|
81
81
|
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
.search-dialog-input::placeholder {
|
|
91
|
-
color: rgb(255 255 255 / 0.
|
|
91
|
+
color: rgb(255 255 255 / 0.4);
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
.search-dialog-kbd {
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
padding: 0.125rem 0.375rem;
|
|
99
99
|
font-size: 10px;
|
|
100
100
|
font-family: ui-monospace, monospace;
|
|
101
|
-
color: rgb(255 255 255 / 0.
|
|
101
|
+
color: rgb(255 255 255 / 0.4);
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
.search-dialog-results {
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
padding: 1.5rem 0.75rem;
|
|
112
112
|
text-align: center;
|
|
113
113
|
font-size: 0.875rem;
|
|
114
|
-
color: rgb(255 255 255 / 0.
|
|
114
|
+
color: rgb(255 255 255 / 0.4);
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
#search-results :global(mark) {
|
|
@@ -180,7 +180,7 @@
|
|
|
180
180
|
const container = document.getElementById("search-results");
|
|
181
181
|
if (!container) return;
|
|
182
182
|
|
|
183
|
-
const placeholderStyle = "padding: 1.5rem 0.75rem; text-align: center; font-size: 0.875rem; color: rgb(255 255 255 / 0.
|
|
183
|
+
const placeholderStyle = "padding: 1.5rem 0.75rem; text-align: center; font-size: 0.875rem; color: rgb(255 255 255 / 0.4);";
|
|
184
184
|
|
|
185
185
|
if (!query.trim()) {
|
|
186
186
|
container.innerHTML = `<p style="${placeholderStyle}">Type to search...</p>`;
|
|
@@ -200,9 +200,9 @@
|
|
|
200
200
|
<a href="${r.url}" style="display: block; border-radius: 0.5rem; padding: 0.625rem 0.75rem; transition: background-color 150ms; text-decoration: none;" onmouseenter="this.style.background='rgb(255 255 255 / 0.04)'" onmouseleave="this.style.background='transparent'" data-search-result>
|
|
201
201
|
<div style="display: flex; align-items: baseline; gap: 0.5rem; margin-bottom: 0.125rem;">
|
|
202
202
|
<span style="font-size: 0.875rem; font-weight: 500; color: rgb(255 255 255 / 0.8);">${r.title}</span>
|
|
203
|
-
${r.section ? `<span style="font-size: 11px; color: rgb(255 255 255 / 0.
|
|
203
|
+
${r.section ? `<span style="font-size: 11px; color: rgb(255 255 255 / 0.35);">${r.section}</span>` : ""}
|
|
204
204
|
</div>
|
|
205
|
-
<div style="font-size: 0.75rem; color: rgb(255 255 255 / 0.
|
|
205
|
+
<div style="font-size: 0.75rem; color: rgb(255 255 255 / 0.5); line-height: 1.625; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;">${r.excerpt}</div>
|
|
206
206
|
</a>`,
|
|
207
207
|
)
|
|
208
208
|
.join("");
|
|
@@ -215,7 +215,7 @@
|
|
|
215
215
|
if (!pf) {
|
|
216
216
|
const container = document.getElementById("search-results");
|
|
217
217
|
if (container) {
|
|
218
|
-
container.innerHTML = '<p style="padding: 1.5rem 0.75rem; text-align: center; font-size: 0.875rem; color: rgb(255 255 255 / 0.
|
|
218
|
+
container.innerHTML = '<p style="padding: 1.5rem 0.75rem; text-align: center; font-size: 0.875rem; color: rgb(255 255 255 / 0.4);">Search not available. Run <code style="font-family: ui-monospace, monospace; color: rgb(255 255 255 / 0.6);">npx pagefind</code> after building.</p>';
|
|
219
219
|
}
|
|
220
220
|
return;
|
|
221
221
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import type { SidebarSection } from "../types/config";
|
|
3
|
+
import { withBase } from "../utils/base-path";
|
|
3
4
|
|
|
4
5
|
type Props = {
|
|
5
6
|
section: SidebarSection;
|
|
@@ -10,7 +11,7 @@ const { section, currentPath } = Astro.props;
|
|
|
10
11
|
---
|
|
11
12
|
|
|
12
13
|
<details class="mb-6 group" open>
|
|
13
|
-
<summary class="flex items-center justify-between w-full py-1.5 text-xs font-semibold uppercase tracking-widest text-white/
|
|
14
|
+
<summary class="flex items-center justify-between w-full py-1.5 text-xs font-semibold uppercase tracking-widest text-white/40 hover:text-white/60 transition-colors cursor-pointer list-none [&::-webkit-details-marker]:hidden">
|
|
14
15
|
{section.title}
|
|
15
16
|
<svg
|
|
16
17
|
class="w-3 h-3 transition-transform duration-150 group-open:rotate-180"
|
|
@@ -24,12 +25,12 @@ const { section, currentPath } = Astro.props;
|
|
|
24
25
|
<div class="flex flex-col mt-2">
|
|
25
26
|
{section.links.map((link) => (
|
|
26
27
|
<a
|
|
27
|
-
href={link.href}
|
|
28
|
+
href={withBase(link.href)}
|
|
28
29
|
class:list={[
|
|
29
30
|
"block py-1.5 pl-3 text-sm border-l-2 transition-colors",
|
|
30
31
|
currentPath === link.href
|
|
31
32
|
? "border-accent text-white font-medium"
|
|
32
|
-
: "border-transparent text-white/
|
|
33
|
+
: "border-transparent text-white/60 hover:text-white/90 hover:border-white/20",
|
|
33
34
|
]}
|
|
34
35
|
>
|
|
35
36
|
{link.label}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
<nav id="toc" class="w-44 shrink-0 hidden xl:block sticky top-16 h-[calc(100dvh-4rem)] pt-8 pr-4 overflow-y-auto">
|
|
7
|
-
<div class="text-xs font-semibold uppercase tracking-widest text-white/
|
|
7
|
+
<div class="text-xs font-semibold uppercase tracking-widest text-white/40 mb-3">On this page</div>
|
|
8
8
|
<ul id="toc-list" class="flex flex-col gap-0.5"></ul>
|
|
9
9
|
</nav>
|
|
10
10
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
const ACTIVE_CLASS =
|
|
13
13
|
"block py-1 text-sm border-l-2 pl-3 transition-colors border-accent text-white font-medium";
|
|
14
14
|
const INACTIVE_CLASS =
|
|
15
|
-
"block py-1 text-sm border-l-2 pl-3 transition-colors border-transparent text-white/
|
|
15
|
+
"block py-1 text-sm border-l-2 pl-3 transition-colors border-transparent text-white/50 hover:text-white/70 hover:border-white/20";
|
|
16
16
|
|
|
17
17
|
function initToc() {
|
|
18
18
|
const tocList = document.getElementById("toc-list");
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prepends the Astro base path to an internal href.
|
|
3
|
+
* External URLs (http/https) are returned as-is.
|
|
4
|
+
*/
|
|
5
|
+
export function withBase(href: string): string {
|
|
6
|
+
if (href.startsWith("http://") || href.startsWith("https://")) return href;
|
|
7
|
+
const base = (import.meta.env.BASE_URL ?? "/").replace(/\/$/, "");
|
|
8
|
+
if (!base || base === "/") return href;
|
|
9
|
+
return `${base}${href.startsWith("/") ? href : `/${href}`}`;
|
|
10
|
+
}
|