@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 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
+ }