@luciodale/docs-ui-kit 0.2.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 +607 -0
- package/package.json +46 -0
- package/src/components/Callout.astro +58 -0
- package/src/components/CodeBlock.astro +54 -0
- package/src/components/ContentSection.astro +14 -0
- package/src/components/DocsLayout.astro +28 -0
- package/src/components/Footer.astro +66 -0
- package/src/components/GithubIcon.astro +12 -0
- package/src/components/HeroSection.astro +59 -0
- package/src/components/LinkedInIcon.astro +12 -0
- package/src/components/Navbar.astro +189 -0
- package/src/components/PackageInfo.astro +92 -0
- package/src/components/PageLayout.astro +20 -0
- package/src/components/PropsTable.astro +45 -0
- package/src/components/SEO.astro +120 -0
- package/src/components/SearchModal.astro +278 -0
- package/src/components/SectionHeading.astro +11 -0
- package/src/components/Sidebar.astro +19 -0
- package/src/components/SidebarSection.astro +39 -0
- package/src/components/TableOfContents.astro +60 -0
- package/src/components/icons/DangerIcon.astro +9 -0
- package/src/components/icons/InfoIcon.astro +9 -0
- package/src/components/icons/TipIcon.astro +8 -0
- package/src/components/icons/WarningIcon.astro +9 -0
- package/src/styles/theme.css +78 -0
- package/src/types/config.ts +32 -0
- package/src/types/props.ts +7 -0
package/README.md
ADDED
|
@@ -0,0 +1,607 @@
|
|
|
1
|
+
# @luciodale/docs-ui-kit
|
|
2
|
+
|
|
3
|
+
Astro component library for building documentation sites. Dark theme, orange accent, Tailwind CSS v4. Ships source `.astro` files — no build step in the library, your Astro project processes them.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @luciodale/docs-ui-kit
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Peer dependency: `astro >= 5`.
|
|
12
|
+
|
|
13
|
+
Runtime dependency: `shiki` (build-time syntax highlighting in Astro frontmatter).
|
|
14
|
+
|
|
15
|
+
## Setup in your Astro project
|
|
16
|
+
|
|
17
|
+
### 1. CSS
|
|
18
|
+
|
|
19
|
+
Create a global CSS file and import the theme + tell Tailwind to scan the library's components:
|
|
20
|
+
|
|
21
|
+
```css
|
|
22
|
+
/* src/styles/global.css */
|
|
23
|
+
@import "tailwindcss";
|
|
24
|
+
@import "@luciodale/docs-ui-kit/styles.css";
|
|
25
|
+
|
|
26
|
+
/* Adjust the path to wherever node_modules lives relative to this file */
|
|
27
|
+
@source "../../node_modules/@luciodale/docs-ui-kit/src";
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The theme CSS defines Tailwind v4 `@theme` tokens (colors, fonts) and base body styles (`background: black; color: white`). It also provides a `.liquid-glass-border` utility class.
|
|
31
|
+
|
|
32
|
+
### 2. Fonts
|
|
33
|
+
|
|
34
|
+
The theme uses **Work Sans** (body) and **JetBrains Mono** (code). Load them in your base layout's `<head>`:
|
|
35
|
+
|
|
36
|
+
```html
|
|
37
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
38
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
39
|
+
<link href="https://fonts.googleapis.com/css2?family=Work+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 3. SiteConfig
|
|
43
|
+
|
|
44
|
+
Define a config object that drives all layout components:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
// src/config.ts
|
|
48
|
+
import type { SiteConfig } from "@luciodale/docs-ui-kit/types/config";
|
|
49
|
+
|
|
50
|
+
export const siteConfig: SiteConfig = {
|
|
51
|
+
title: "my-library",
|
|
52
|
+
description: "A short description of your library.",
|
|
53
|
+
siteUrl: "https://my-library-docs.pages.dev",
|
|
54
|
+
installCommand: "npm install my-library",
|
|
55
|
+
githubUrl: "https://github.com/you/my-library",
|
|
56
|
+
author: "Your Name",
|
|
57
|
+
// Optional:
|
|
58
|
+
// logoSrc: "/logo.svg",
|
|
59
|
+
// logoAlt: "My Library logo",
|
|
60
|
+
// ogImage: "/og.png",
|
|
61
|
+
// faviconSrc: "/favicon.ico",
|
|
62
|
+
// twitterHandle: "@you",
|
|
63
|
+
// copyright: "Your Name",
|
|
64
|
+
socialLinks: {
|
|
65
|
+
github: "https://github.com/you",
|
|
66
|
+
// linkedin: "https://linkedin.com/in/you",
|
|
67
|
+
},
|
|
68
|
+
navLinks: [
|
|
69
|
+
{ href: "/docs/getting-started", label: "Docs" },
|
|
70
|
+
{ href: "/demo/basic", label: "Demo" },
|
|
71
|
+
],
|
|
72
|
+
sidebarSections: [
|
|
73
|
+
{
|
|
74
|
+
title: "Getting Started",
|
|
75
|
+
links: [
|
|
76
|
+
{ href: "/docs/getting-started", label: "Introduction" },
|
|
77
|
+
{ href: "/docs/configuration", label: "Configuration" },
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
title: "Demos",
|
|
82
|
+
links: [
|
|
83
|
+
{ href: "/demo/basic", label: "Basic" },
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
};
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Types
|
|
91
|
+
|
|
92
|
+
### SiteConfig
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
import type { SiteConfig } from "@luciodale/docs-ui-kit/types/config";
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
| Field | Type | Required | Description |
|
|
99
|
+
|---|---|---|---|
|
|
100
|
+
| `title` | `string` | Yes | Site/library name. Shown in navbar, footer, SEO. |
|
|
101
|
+
| `description` | `string` | Yes | Default meta description. Fallback for pages without their own. |
|
|
102
|
+
| `siteUrl` | `string` | Yes | Canonical base URL (e.g. `https://docs.example.com`). Used by SEO + sitemap. |
|
|
103
|
+
| `installCommand` | `string` | Yes | Shown in HeroSection with copy button. |
|
|
104
|
+
| `githubUrl` | `string` | Yes | Links to the repo from navbar. |
|
|
105
|
+
| `socialLinks` | `{ github: string; linkedin?: string }` | Yes | Footer social icons. |
|
|
106
|
+
| `navLinks` | `Array<{ href: string; label: string }>` | Yes | Top navbar links. Active state based on `currentPath.startsWith(href)`. |
|
|
107
|
+
| `sidebarSections` | `Array<{ title: string; links: NavLink[] }>` | Yes | Left sidebar groups. Also shown in mobile menu. |
|
|
108
|
+
| `author` | `string` | No | Used in SEO meta tags and JSON-LD structured data. |
|
|
109
|
+
| `logoSrc` | `string` | No | Image URL for navbar/footer. Falls back to `title` text. |
|
|
110
|
+
| `logoAlt` | `string` | No | Alt text for logo. Falls back to `title`. |
|
|
111
|
+
| `ogImage` | `string` | No | Path to default Open Graph image (1200x630). |
|
|
112
|
+
| `faviconSrc` | `string` | No | Path to favicon. |
|
|
113
|
+
| `twitterHandle` | `string` | No | `@handle` for Twitter Card meta tags. |
|
|
114
|
+
| `copyright` | `string` | No | Footer copyright text. Falls back to `title`. |
|
|
115
|
+
|
|
116
|
+
### PropsTableRow
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
import type { PropsTableRow } from "@luciodale/docs-ui-kit/types/props";
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
| Field | Type | Required | Description |
|
|
123
|
+
|---|---|---|---|
|
|
124
|
+
| `name` | `string` | Yes | Prop name. |
|
|
125
|
+
| `type` | `string` | Yes | Type annotation string. |
|
|
126
|
+
| `description` | `string` | Yes | What the prop does. |
|
|
127
|
+
| `defaultValue` | `string` | No | Default value. Shows "—" if omitted. |
|
|
128
|
+
| `required` | `boolean` | No | Shows red asterisk if `true`. |
|
|
129
|
+
|
|
130
|
+
## Components
|
|
131
|
+
|
|
132
|
+
All components are imported from `@luciodale/docs-ui-kit/components/<Name>.astro`.
|
|
133
|
+
|
|
134
|
+
### Layout Components
|
|
135
|
+
|
|
136
|
+
#### DocsLayout
|
|
137
|
+
|
|
138
|
+
Three-column layout: left sidebar + content + right table of contents. Used for docs and demo pages.
|
|
139
|
+
|
|
140
|
+
```astro
|
|
141
|
+
---
|
|
142
|
+
import DocsLayout from "@luciodale/docs-ui-kit/components/DocsLayout.astro";
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
<DocsLayout config={siteConfig} currentPath={Astro.url.pathname}>
|
|
146
|
+
<!-- page content -->
|
|
147
|
+
</DocsLayout>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
| Prop | Type | Required | Description |
|
|
151
|
+
|---|---|---|---|
|
|
152
|
+
| `config` | `SiteConfig` | Yes | Site configuration object. |
|
|
153
|
+
| `currentPath` | `string` | Yes | Current URL pathname. Used for active link highlighting. |
|
|
154
|
+
|
|
155
|
+
Includes: Navbar (sticky, blur backdrop), Sidebar (sticky, collapsible sections, hidden on mobile), TableOfContents (auto-built from `ContentSection` components, hidden below `xl` breakpoint), Footer.
|
|
156
|
+
|
|
157
|
+
#### PageLayout
|
|
158
|
+
|
|
159
|
+
Simple layout without sidebars. Used for landing/home pages.
|
|
160
|
+
|
|
161
|
+
```astro
|
|
162
|
+
---
|
|
163
|
+
import PageLayout from "@luciodale/docs-ui-kit/components/PageLayout.astro";
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
<PageLayout config={siteConfig} currentPath="/">
|
|
167
|
+
<!-- page content -->
|
|
168
|
+
</PageLayout>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Same props as DocsLayout. Includes: Navbar, Footer. No sidebar or TOC.
|
|
172
|
+
|
|
173
|
+
### Content Components
|
|
174
|
+
|
|
175
|
+
#### ContentSection
|
|
176
|
+
|
|
177
|
+
Wraps a content section with an `<h2>` heading. Automatically registers in the right-side TableOfContents — no manual TOC config needed.
|
|
178
|
+
|
|
179
|
+
```astro
|
|
180
|
+
---
|
|
181
|
+
import ContentSection from "@luciodale/docs-ui-kit/components/ContentSection.astro";
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
<ContentSection label="Installation">
|
|
185
|
+
<p>Install the package...</p>
|
|
186
|
+
</ContentSection>
|
|
187
|
+
|
|
188
|
+
<ContentSection label="Quick Start">
|
|
189
|
+
<p>Create a manager...</p>
|
|
190
|
+
</ContentSection>
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
| Prop | Type | Required | Description |
|
|
194
|
+
|---|---|---|---|
|
|
195
|
+
| `label` | `string` | Yes | Section heading text. Also appears in the TOC. |
|
|
196
|
+
| `id` | `string` | No | Custom anchor ID. Auto-generated from `label` if omitted (slugified). |
|
|
197
|
+
|
|
198
|
+
Renders: `<section id="..." data-toc-label="..."><h2>...</h2><slot /></section>` with `scroll-mt-24` for smooth anchor scrolling past the sticky navbar.
|
|
199
|
+
|
|
200
|
+
#### SectionHeading
|
|
201
|
+
|
|
202
|
+
Standalone `<h2>` heading without TOC registration. Use when you want a heading that does NOT appear in the table of contents.
|
|
203
|
+
|
|
204
|
+
```astro
|
|
205
|
+
---
|
|
206
|
+
import SectionHeading from "@luciodale/docs-ui-kit/components/SectionHeading.astro";
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
<SectionHeading>My Heading</SectionHeading>
|
|
210
|
+
<SectionHeading class="text-xl">Smaller Heading</SectionHeading>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
| Prop | Type | Required | Description |
|
|
214
|
+
|---|---|---|---|
|
|
215
|
+
| `class` | `string` | No | Additional CSS classes. |
|
|
216
|
+
|
|
217
|
+
#### CodeBlock
|
|
218
|
+
|
|
219
|
+
Syntax-highlighted code block with copy button. Highlighting happens at build time via Shiki (zero client JS for highlighting). Uses `vitesse-dark` theme.
|
|
220
|
+
|
|
221
|
+
```astro
|
|
222
|
+
---
|
|
223
|
+
import CodeBlock from "@luciodale/docs-ui-kit/components/CodeBlock.astro";
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
<CodeBlock code="npm install my-lib" language="bash" filename="terminal" />
|
|
227
|
+
|
|
228
|
+
<CodeBlock
|
|
229
|
+
code={`const x: string = "hello";
|
|
230
|
+
console.log(x);`}
|
|
231
|
+
language="tsx"
|
|
232
|
+
filename="example.ts"
|
|
233
|
+
/>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
| Prop | Type | Required | Description |
|
|
237
|
+
|---|---|---|---|
|
|
238
|
+
| `code` | `string` | Yes | The source code string. Leading/trailing whitespace is trimmed. |
|
|
239
|
+
| `language` | `string` | No | Shiki language ID. Default: `"tsx"`. |
|
|
240
|
+
| `filename` | `string` | No | Shown in the header bar. Falls back to `language`. |
|
|
241
|
+
|
|
242
|
+
#### PropsTable
|
|
243
|
+
|
|
244
|
+
Renders a styled table for documenting component props or API options.
|
|
245
|
+
|
|
246
|
+
```astro
|
|
247
|
+
---
|
|
248
|
+
import PropsTable from "@luciodale/docs-ui-kit/components/PropsTable.astro";
|
|
249
|
+
import type { PropsTableRow } from "@luciodale/docs-ui-kit/types/props";
|
|
250
|
+
|
|
251
|
+
const rows: PropsTableRow[] = [
|
|
252
|
+
{ name: "url", type: "string", required: true, description: "WebSocket server URL." },
|
|
253
|
+
{ name: "debug", type: "boolean", defaultValue: "false", description: "Enable debug logging." },
|
|
254
|
+
];
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
<PropsTable title="Manager Options" rows={rows} />
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
| Prop | Type | Required | Description |
|
|
261
|
+
|---|---|---|---|
|
|
262
|
+
| `title` | `string` | No | Optional heading above the table. |
|
|
263
|
+
| `rows` | `Array<PropsTableRow>` | Yes | Table data. See PropsTableRow type above. |
|
|
264
|
+
|
|
265
|
+
#### HeroSection
|
|
266
|
+
|
|
267
|
+
Landing page hero with title, description, install command (with copy button), and optional extra content via slot.
|
|
268
|
+
|
|
269
|
+
```astro
|
|
270
|
+
---
|
|
271
|
+
import HeroSection from "@luciodale/docs-ui-kit/components/HeroSection.astro";
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
<HeroSection
|
|
275
|
+
title="my-library"
|
|
276
|
+
description="A short tagline."
|
|
277
|
+
installCommand="npm install my-library"
|
|
278
|
+
>
|
|
279
|
+
<!-- Optional: extra content below the install command -->
|
|
280
|
+
<div class="flex gap-4">
|
|
281
|
+
<a href="/docs" class="rounded-lg bg-accent px-5 py-2.5 text-sm text-white">Get Started</a>
|
|
282
|
+
</div>
|
|
283
|
+
</HeroSection>
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
| Prop | Type | Required | Description |
|
|
287
|
+
|---|---|---|---|
|
|
288
|
+
| `title` | `string` | Yes | Main heading (h1). |
|
|
289
|
+
| `description` | `string` | Yes | Subtitle paragraph. |
|
|
290
|
+
| `installCommand` | `string` | Yes | Shell command. Copy button copies this string. |
|
|
291
|
+
| `logoSrc` | `string` | No | Logo image above the title. |
|
|
292
|
+
| `logoAlt` | `string` | No | Alt text for logo. |
|
|
293
|
+
|
|
294
|
+
#### Callout
|
|
295
|
+
|
|
296
|
+
Info, warning, tip, or danger admonition boxes for calling out important information.
|
|
297
|
+
|
|
298
|
+
```astro
|
|
299
|
+
---
|
|
300
|
+
import Callout from "@luciodale/docs-ui-kit/components/Callout.astro";
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
<Callout type="info">This API is stable and ready for production.</Callout>
|
|
304
|
+
<Callout type="warning">This feature requires React 18+.</Callout>
|
|
305
|
+
<Callout type="tip" title="Performance">Use ref-counted subscriptions to avoid duplicate connections.</Callout>
|
|
306
|
+
<Callout type="danger">Calling dispose() is irreversible.</Callout>
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
| Prop | Type | Required | Description |
|
|
310
|
+
|---|---|---|---|
|
|
311
|
+
| `type` | `"info" \| "warning" \| "tip" \| "danger"` | No | Default: `"info"`. Controls color and icon. |
|
|
312
|
+
| `title` | `string` | No | Heading text. Defaults: "Note", "Warning", "Tip", "Danger". |
|
|
313
|
+
|
|
314
|
+
Renders a left-bordered aside with icon, title, and slot content. Supports links (`<a>`) and inline code (`<code>`) in the body.
|
|
315
|
+
|
|
316
|
+
#### PackageInfo
|
|
317
|
+
|
|
318
|
+
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).
|
|
319
|
+
|
|
320
|
+
```astro
|
|
321
|
+
---
|
|
322
|
+
import PackageInfo from "@luciodale/docs-ui-kit/components/PackageInfo.astro";
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
<PackageInfo packageName="@luciodale/react-socket" githubRepo="luciodale/react-socket" />
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
| Prop | Type | Required | Description |
|
|
329
|
+
|---|---|---|---|
|
|
330
|
+
| `packageName` | `string` | Yes | npm package name. Used to fetch version + license from registry. |
|
|
331
|
+
| `githubRepo` | `string` | No | GitHub `owner/repo`. Used to fetch star count. If omitted, stars badge is hidden. |
|
|
332
|
+
|
|
333
|
+
Renders a row of styled badges: version (accent color, links to npm), license, GitHub stars (links to repo), bundlephobia link.
|
|
334
|
+
|
|
335
|
+
### Search
|
|
336
|
+
|
|
337
|
+
#### SearchModal
|
|
338
|
+
|
|
339
|
+
Full-text search powered by [Pagefind](https://pagefind.app). Renders a search trigger button (for Navbar) + a dialog modal. Includes Cmd+K / Ctrl+K keyboard shortcut.
|
|
340
|
+
|
|
341
|
+
The component is automatically included in the Navbar — no manual placement needed. It loads Pagefind dynamically at runtime from `/_pagefind/pagefind.js`.
|
|
342
|
+
|
|
343
|
+
**Consumer setup:**
|
|
344
|
+
|
|
345
|
+
After building your Astro site, run Pagefind to generate the search index:
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
astro build && bunx pagefind --site dist/client
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
Or for static output:
|
|
352
|
+
|
|
353
|
+
```bash
|
|
354
|
+
astro build && bunx pagefind --site dist
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
Add this to your `package.json` scripts:
|
|
358
|
+
|
|
359
|
+
```json
|
|
360
|
+
{
|
|
361
|
+
"scripts": {
|
|
362
|
+
"build": "astro build && bunx pagefind --site dist/client"
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
**How it works:**
|
|
368
|
+
- Desktop: compact search button with "Search" label + `Cmd+K` badge, placed between nav links and GitHub icon
|
|
369
|
+
- Mobile: small search icon button next to the hamburger menu
|
|
370
|
+
- Cmd+K / Ctrl+K opens a centered modal dialog with backdrop blur
|
|
371
|
+
- Pagefind `sub_results` are flattened so each result links to a specific page section (anchor), not just the page
|
|
372
|
+
- Results show section title, parent page name, and highlighted excerpt (up to 10 results)
|
|
373
|
+
- Clicking a result navigates to the page + section anchor and closes the modal
|
|
374
|
+
- Search input is debounced (150ms)
|
|
375
|
+
- If Pagefind is not indexed, shows a helpful setup message
|
|
376
|
+
|
|
377
|
+
**No additional imports needed** — SearchModal is included by DocsLayout and PageLayout via the Navbar.
|
|
378
|
+
|
|
379
|
+
### SEO Component
|
|
380
|
+
|
|
381
|
+
#### SEO
|
|
382
|
+
|
|
383
|
+
Renders all meta tags, Open Graph, Twitter Cards, JSON-LD structured data, and breadcrumbs. Place in `<head>`.
|
|
384
|
+
|
|
385
|
+
```astro
|
|
386
|
+
---
|
|
387
|
+
import SEO from "@luciodale/docs-ui-kit/components/SEO.astro";
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
<head>
|
|
391
|
+
<SEO
|
|
392
|
+
config={siteConfig}
|
|
393
|
+
title="Getting Started"
|
|
394
|
+
description="How to install and configure the library."
|
|
395
|
+
currentPath={Astro.url.pathname}
|
|
396
|
+
type="article"
|
|
397
|
+
/>
|
|
398
|
+
</head>
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
| Prop | Type | Required | Description |
|
|
402
|
+
|---|---|---|---|
|
|
403
|
+
| `config` | `SiteConfig` | Yes | Site configuration. Provides `siteUrl`, `author`, `ogImage`, etc. |
|
|
404
|
+
| `title` | `string` | Yes | Page title. On `/` it's used as-is; elsewhere formatted as `Title \| SiteName`. |
|
|
405
|
+
| `description` | `string` | No | Page description. Falls back to `config.description`. |
|
|
406
|
+
| `currentPath` | `string` | Yes | URL pathname. Used for canonical URL and breadcrumbs. |
|
|
407
|
+
| `type` | `"website" \| "article"` | No | Default: `"website"`. Use `"article"` for docs pages (generates TechArticle JSON-LD). |
|
|
408
|
+
| `publishedDate` | `string` | No | ISO date string for article:published_time. |
|
|
409
|
+
| `modifiedDate` | `string` | No | ISO date string for article:modified_time. |
|
|
410
|
+
| `noindex` | `boolean` | No | Default: `false`. Set `true` to add `noindex, nofollow`. |
|
|
411
|
+
|
|
412
|
+
**What it renders:**
|
|
413
|
+
- `<title>` with smart formatting
|
|
414
|
+
- `<meta name="description">`, `<meta name="author">`, `<meta name="robots">`
|
|
415
|
+
- `<link rel="canonical">` (absolute URL from `siteUrl` + `currentPath`)
|
|
416
|
+
- `<link rel="icon">` (if `faviconSrc` set)
|
|
417
|
+
- Open Graph: `og:type`, `og:url`, `og:title`, `og:description`, `og:site_name`, `og:locale`, `og:image` (with dimensions + alt)
|
|
418
|
+
- Twitter Card: `twitter:card`, `twitter:title`, `twitter:description`, `twitter:image`, `twitter:site`, `twitter:creator`
|
|
419
|
+
- Article meta: `article:published_time`, `article:modified_time`, `article:author`
|
|
420
|
+
- `<meta name="theme-color" content="#000000">`, `<meta name="color-scheme" content="dark">`
|
|
421
|
+
- JSON-LD `WebSite` schema (on homepage) or `TechArticle` schema (on article pages)
|
|
422
|
+
- JSON-LD `BreadcrumbList` auto-generated from URL path segments (on non-root pages)
|
|
423
|
+
|
|
424
|
+
### Icon Components
|
|
425
|
+
|
|
426
|
+
#### GithubIcon / LinkedInIcon
|
|
427
|
+
|
|
428
|
+
SVG icon components. Used internally by Navbar and Footer, but exported for custom use.
|
|
429
|
+
|
|
430
|
+
```astro
|
|
431
|
+
---
|
|
432
|
+
import GithubIcon from "@luciodale/docs-ui-kit/components/GithubIcon.astro";
|
|
433
|
+
import LinkedInIcon from "@luciodale/docs-ui-kit/components/LinkedInIcon.astro";
|
|
434
|
+
---
|
|
435
|
+
|
|
436
|
+
<GithubIcon class="w-6 text-white" />
|
|
437
|
+
<LinkedInIcon class="w-6 text-white/50" />
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
| Prop | Type | Required | Description |
|
|
441
|
+
|---|---|---|---|
|
|
442
|
+
| `class` | `string` | No | CSS classes. Default: `"w-5 text-white"`. |
|
|
443
|
+
|
|
444
|
+
## Typical page structure
|
|
445
|
+
|
|
446
|
+
### Base layout (create in your project)
|
|
447
|
+
|
|
448
|
+
```astro
|
|
449
|
+
---
|
|
450
|
+
// src/layouts/Base.astro
|
|
451
|
+
import SEO from "@luciodale/docs-ui-kit/components/SEO.astro";
|
|
452
|
+
import { siteConfig } from "../config";
|
|
453
|
+
|
|
454
|
+
type Props = { title: string; description?: string; type?: "website" | "article" };
|
|
455
|
+
|
|
456
|
+
const { title, description, type = "website" } = Astro.props;
|
|
457
|
+
---
|
|
458
|
+
|
|
459
|
+
<!doctype html>
|
|
460
|
+
<html lang="en">
|
|
461
|
+
<head>
|
|
462
|
+
<meta charset="UTF-8" />
|
|
463
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
464
|
+
<!-- fonts -->
|
|
465
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
466
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
467
|
+
<link href="https://fonts.googleapis.com/css2?family=Work+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
|
|
468
|
+
<link rel="sitemap" href="/sitemap-index.xml" />
|
|
469
|
+
<SEO config={siteConfig} title={title} description={description} currentPath={Astro.url.pathname} type={type} />
|
|
470
|
+
</head>
|
|
471
|
+
<body>
|
|
472
|
+
<slot />
|
|
473
|
+
</body>
|
|
474
|
+
</html>
|
|
475
|
+
|
|
476
|
+
<style is:global>
|
|
477
|
+
@import "../styles/global.css";
|
|
478
|
+
</style>
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
### Docs layout wrapper (create in your project)
|
|
482
|
+
|
|
483
|
+
```astro
|
|
484
|
+
---
|
|
485
|
+
// src/layouts/DocsPage.astro
|
|
486
|
+
import DocsLayout from "@luciodale/docs-ui-kit/components/DocsLayout.astro";
|
|
487
|
+
import { siteConfig } from "../config";
|
|
488
|
+
import Base from "./Base.astro";
|
|
489
|
+
|
|
490
|
+
type Props = { title: string; description?: string };
|
|
491
|
+
|
|
492
|
+
const { title, description } = Astro.props;
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
<Base title={title} description={description} type="article">
|
|
496
|
+
<DocsLayout config={siteConfig} currentPath={Astro.url.pathname}>
|
|
497
|
+
<slot />
|
|
498
|
+
</DocsLayout>
|
|
499
|
+
</Base>
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### Home page
|
|
503
|
+
|
|
504
|
+
```astro
|
|
505
|
+
---
|
|
506
|
+
// src/pages/index.astro
|
|
507
|
+
import PageLayout from "@luciodale/docs-ui-kit/components/PageLayout.astro";
|
|
508
|
+
import HeroSection from "@luciodale/docs-ui-kit/components/HeroSection.astro";
|
|
509
|
+
import { siteConfig } from "../config";
|
|
510
|
+
import Base from "../layouts/Base.astro";
|
|
511
|
+
|
|
512
|
+
export const prerender = true;
|
|
513
|
+
---
|
|
514
|
+
|
|
515
|
+
<Base title={siteConfig.title}>
|
|
516
|
+
<PageLayout config={siteConfig} currentPath="/">
|
|
517
|
+
<HeroSection
|
|
518
|
+
title={siteConfig.title}
|
|
519
|
+
description={siteConfig.description}
|
|
520
|
+
installCommand={siteConfig.installCommand}
|
|
521
|
+
>
|
|
522
|
+
<a href="/docs/getting-started" class="rounded-lg bg-accent px-5 py-2.5 text-sm text-white">
|
|
523
|
+
Get Started
|
|
524
|
+
</a>
|
|
525
|
+
</HeroSection>
|
|
526
|
+
</PageLayout>
|
|
527
|
+
</Base>
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
### Docs page
|
|
531
|
+
|
|
532
|
+
```astro
|
|
533
|
+
---
|
|
534
|
+
// src/pages/docs/getting-started.astro
|
|
535
|
+
import CodeBlock from "@luciodale/docs-ui-kit/components/CodeBlock.astro";
|
|
536
|
+
import ContentSection from "@luciodale/docs-ui-kit/components/ContentSection.astro";
|
|
537
|
+
import DocsPage from "../../layouts/DocsPage.astro";
|
|
538
|
+
|
|
539
|
+
export const prerender = true;
|
|
540
|
+
---
|
|
541
|
+
|
|
542
|
+
<DocsPage title="Getting Started" description="Learn how to install and use the library.">
|
|
543
|
+
<ContentSection label="Installation">
|
|
544
|
+
<CodeBlock code="npm install my-library" language="bash" filename="terminal" />
|
|
545
|
+
</ContentSection>
|
|
546
|
+
|
|
547
|
+
<ContentSection label="Quick Start">
|
|
548
|
+
<p class="text-white/60 mb-4">Create an instance:</p>
|
|
549
|
+
<CodeBlock code={`import { MyLib } from "my-library";\nconst lib = new MyLib();`} language="tsx" filename="app.ts" />
|
|
550
|
+
</ContentSection>
|
|
551
|
+
</DocsPage>
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
Each `ContentSection` automatically appears in the right-side table of contents. No manual TOC array needed.
|
|
555
|
+
|
|
556
|
+
### Demo page with React island
|
|
557
|
+
|
|
558
|
+
```astro
|
|
559
|
+
---
|
|
560
|
+
// src/pages/demo/basic.astro
|
|
561
|
+
import ContentSection from "@luciodale/docs-ui-kit/components/ContentSection.astro";
|
|
562
|
+
import { MyDemo } from "../../components/MyDemo"; // React component
|
|
563
|
+
import DocsPage from "../../layouts/DocsPage.astro";
|
|
564
|
+
|
|
565
|
+
export const prerender = true;
|
|
566
|
+
---
|
|
567
|
+
|
|
568
|
+
<DocsPage title="Basic Demo" description="Live interactive demo.">
|
|
569
|
+
<ContentSection label="Demo">
|
|
570
|
+
<MyDemo client:load />
|
|
571
|
+
</ContentSection>
|
|
572
|
+
</DocsPage>
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
React islands require `@astrojs/react` in your Astro project. The docs-ui-kit itself has zero React dependency.
|
|
576
|
+
|
|
577
|
+
## Color palette
|
|
578
|
+
|
|
579
|
+
Defined in `theme.css` via Tailwind v4 `@theme` tokens:
|
|
580
|
+
|
|
581
|
+
| Token | Value | Usage |
|
|
582
|
+
|---|---|---|
|
|
583
|
+
| `--color-accent` | `#ef4723` | Primary accent. Links, active indicators, buttons. Tailwind: `text-accent`, `bg-accent`, `border-accent`. |
|
|
584
|
+
| `--color-accent-hover` | `#d63d1f` | Hover state for accent. Tailwind: `bg-accent-hover`. |
|
|
585
|
+
| `--color-primary` | `#42170c` | Deep brown. Available but rarely used directly. |
|
|
586
|
+
| `--color-secondary` | `#6b7280` | Gray. |
|
|
587
|
+
| `--color-surface` | `#f9fafb` | Light surface (for light-mode contexts). |
|
|
588
|
+
| `--color-border` | `#e5e7eb` | Light border. |
|
|
589
|
+
| `--color-muted` | `#848d9f` | Muted text. |
|
|
590
|
+
|
|
591
|
+
Body: `background: black`, `color: white`. All components use `white/` opacity variants for text hierarchy (`text-white/60`, `text-white/40`, `text-white/30`).
|
|
592
|
+
|
|
593
|
+
## Responsive behavior
|
|
594
|
+
|
|
595
|
+
| Breakpoint | Left Sidebar | Content | Right TOC | Mobile Menu |
|
|
596
|
+
|---|---|---|---|---|
|
|
597
|
+
| `< md` (mobile) | Hidden | Full width | Hidden | Hamburger → slide-in from right |
|
|
598
|
+
| `md` – `xl` | Visible (256px) | Flex | Hidden | N/A |
|
|
599
|
+
| `>= xl` | Visible (256px) | Flex | Visible (176px) | N/A |
|
|
600
|
+
|
|
601
|
+
## View Transitions compatibility
|
|
602
|
+
|
|
603
|
+
All client-side scripts (`<script>` in components) re-initialize on the `astro:after-swap` event, so everything works with Astro View Transitions out of the box.
|
|
604
|
+
|
|
605
|
+
## License
|
|
606
|
+
|
|
607
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@luciodale/docs-ui-kit",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Astro component library for documentation sites. Dark theme, orange accent.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
"./components/*": "./src/components/*",
|
|
8
|
+
"./types/config": "./src/types/config.ts",
|
|
9
|
+
"./types/props": "./src/types/props.ts",
|
|
10
|
+
"./styles.css": "./src/styles/theme.css"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"src"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"format": "biome format --write .",
|
|
17
|
+
"lint": "biome check .",
|
|
18
|
+
"lint:fix": "biome check --write .",
|
|
19
|
+
"npm": "npm publish --access public",
|
|
20
|
+
"npm:test": "npm pack --dry-run"
|
|
21
|
+
},
|
|
22
|
+
"peerDependencies": {
|
|
23
|
+
"astro": ">=5"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"shiki": "^4.0.2"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@biomejs/biome": "^2.4.7",
|
|
30
|
+
"astro": "^5.0.0",
|
|
31
|
+
"typescript": "^5.9.3"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"astro",
|
|
35
|
+
"documentation",
|
|
36
|
+
"components",
|
|
37
|
+
"dark-theme",
|
|
38
|
+
"tailwindcss"
|
|
39
|
+
],
|
|
40
|
+
"author": "Lucio D'Alessandro",
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "https://github.com/luciodale/docs-ui-kit"
|
|
45
|
+
}
|
|
46
|
+
}
|