@publier/shell 2.1.1

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.
Files changed (141) hide show
  1. package/README.md +1 -0
  2. package/dist/build-integration.d.mts +7 -0
  3. package/dist/build-integration.mjs +1 -0
  4. package/dist/index-DWtFsw7E.d.mts +1033 -0
  5. package/dist/index.d.mts +33 -0
  6. package/dist/index.mjs +1 -0
  7. package/dist/integration-BIJIcnAT.mjs +99 -0
  8. package/dist/integration-CKjtSkwa.d.mts +183 -0
  9. package/dist/integration.d.mts +2 -0
  10. package/dist/integration.mjs +1 -0
  11. package/dist/loaders/index.d.mts +54 -0
  12. package/dist/loaders/index.mjs +1 -0
  13. package/dist/plugins/remark-asides.d.mts +8 -0
  14. package/dist/plugins/remark-asides.mjs +2 -0
  15. package/dist/plugins/remark-snippets.d.mts +11 -0
  16. package/dist/plugins/remark-snippets.mjs +1 -0
  17. package/dist/plugins/remark-structure.d.mts +13 -0
  18. package/dist/plugins/remark-structure.mjs +1 -0
  19. package/dist/plugins/remark-vars.d.mts +7 -0
  20. package/dist/plugins/remark-vars.mjs +1 -0
  21. package/dist/presets-C7z73xlB.d.mts +16 -0
  22. package/dist/presets-DL0qjtya.mjs +1 -0
  23. package/dist/runtime/code-group-sync.d.mts +30 -0
  24. package/dist/runtime/code-group-sync.mjs +103 -0
  25. package/dist/runtime/lazy-upgrade-registry.d.mts +29 -0
  26. package/dist/runtime/lazy-upgrade-registry.mjs +1 -0
  27. package/dist/runtime/tabs-sync.d.mts +25 -0
  28. package/dist/runtime/tabs-sync.mjs +106 -0
  29. package/dist/search/index.d.mts +92 -0
  30. package/dist/search/index.mjs +1 -0
  31. package/dist/tailwind/css-plugin.d.mts +16 -0
  32. package/dist/tailwind/css-plugin.mjs +1 -0
  33. package/dist/tailwind/index.d.mts +6 -0
  34. package/dist/tailwind/index.mjs +1 -0
  35. package/dist/tailwind/loader.d.mts +94 -0
  36. package/dist/tailwind/loader.mjs +2 -0
  37. package/dist/theme-toggle-element-DzFjxwpS.mjs +1 -0
  38. package/dist/themes/almond.css +115 -0
  39. package/dist/themes/aspen.css +95 -0
  40. package/dist/themes/catppuccin.css +98 -0
  41. package/dist/themes/dark.css +98 -0
  42. package/dist/themes/dusk.css +98 -0
  43. package/dist/themes/emerald.css +95 -0
  44. package/dist/themes/light.css +95 -0
  45. package/dist/themes/maple.css +119 -0
  46. package/dist/themes/neutral.css +73 -0
  47. package/dist/themes/ocean.css +98 -0
  48. package/dist/themes/purple.css +95 -0
  49. package/dist/themes/ruby.css +95 -0
  50. package/dist/themes/solar.css +98 -0
  51. package/dist/themes/vitepress.css +95 -0
  52. package/package.json +189 -0
  53. package/publier-gate +0 -0
  54. package/src/astro-modules.d.ts +20 -0
  55. package/src/components/LastModified.astro +25 -0
  56. package/src/components/announcement-banner.astro +25 -0
  57. package/src/components/aside.astro +17 -0
  58. package/src/components/ask-ai.tsx +146 -0
  59. package/src/components/badge.astro +18 -0
  60. package/src/components/breadcrumbs.astro +23 -0
  61. package/src/components/callouts/caution.astro +13 -0
  62. package/src/components/callouts/check.astro +13 -0
  63. package/src/components/callouts/danger.astro +13 -0
  64. package/src/components/callouts/info.astro +13 -0
  65. package/src/components/callouts/note.astro +13 -0
  66. package/src/components/callouts/tip.astro +13 -0
  67. package/src/components/callouts/warning.astro +13 -0
  68. package/src/components/card-grid.astro +14 -0
  69. package/src/components/card.astro +18 -0
  70. package/src/components/code-group.astro +55 -0
  71. package/src/components/columns.astro +18 -0
  72. package/src/components/docs-layout.astro +25 -0
  73. package/src/components/file-tree-node.astro +13 -0
  74. package/src/components/file-tree.astro +9 -0
  75. package/src/components/icon.astro +18 -0
  76. package/src/components/index.ts +155 -0
  77. package/src/components/link-button.astro +21 -0
  78. package/src/components/link-card.astro +21 -0
  79. package/src/components/open-in-ai.astro +13 -0
  80. package/src/components/package-install.astro +17 -0
  81. package/src/components/panels.astro +16 -0
  82. package/src/components/search-button.astro +21 -0
  83. package/src/components/sidebar.astro +12 -0
  84. package/src/components/skip-link.astro +12 -0
  85. package/src/components/steps.astro +13 -0
  86. package/src/components/table-of-contents.astro +22 -0
  87. package/src/components/tabs.astro +17 -0
  88. package/src/components/theme-storage.ts +5 -0
  89. package/src/components/theme-toggle-element.ts +85 -0
  90. package/src/components/theme-toggle.astro +25 -0
  91. package/src/components/tile-grid.astro +13 -0
  92. package/src/components/tile.astro +17 -0
  93. package/src/components/top-nav-mobile.astro +11 -0
  94. package/src/components/top-nav.astro +20 -0
  95. package/src/components/types.ts +510 -0
  96. package/src/components/ui/blur-image.astro +60 -0
  97. package/src/components/ui/changelog-entry.astro +56 -0
  98. package/src/components/ui/cta-band.astro +30 -0
  99. package/src/components/ui/feature-grid.astro +38 -0
  100. package/src/components/ui/feature-section.astro +85 -0
  101. package/src/components/ui/frame.astro +52 -0
  102. package/src/components/ui/hero.astro +47 -0
  103. package/src/components/ui/jobs-list.astro +53 -0
  104. package/src/components/ui/logo-cloud.astro +68 -0
  105. package/src/components/ui/press-gallery.astro +52 -0
  106. package/src/components/ui/pricing-comparison-table.astro +73 -0
  107. package/src/components/ui/pricing-section.astro +113 -0
  108. package/src/components/ui/pricing-table.astro +54 -0
  109. package/src/components/ui/status-indicator.astro +38 -0
  110. package/src/components/ui/team-grid.astro +63 -0
  111. package/src/components/ui/testimonial-card.astro +42 -0
  112. package/src/components/ui/types.ts +323 -0
  113. package/src/components/update-badge.astro +15 -0
  114. package/src/components/version-switcher.astro +20 -0
  115. package/src/icons/index.tsx +246 -0
  116. package/src/icons/resolve.tsx +45 -0
  117. package/src/layouts/base-layout.astro +63 -0
  118. package/src/qwik.ts +3 -0
  119. package/src/routes/blog-index.astro +20 -0
  120. package/src/routes/blog-rss.xml.ts +40 -0
  121. package/src/routes/blog-slug.astro +32 -0
  122. package/src/routes/changelog-index.astro +25 -0
  123. package/src/routes/changelog-rss.xml.ts +47 -0
  124. package/src/routes/docs-slug.astro +31 -0
  125. package/src/routes/not-found.astro +14 -0
  126. package/src/runtime/banner-init.ts +9 -0
  127. package/src/runtime/lazy-upgrade-init.ts +5 -0
  128. package/src/runtime/sidebar-scroll-init.ts +3 -0
  129. package/src/runtime/theme-init.ts +16 -0
  130. package/src/schemas/blog.ts +37 -0
  131. package/src/schemas/changelog.ts +28 -0
  132. package/src/schemas/common.ts +82 -0
  133. package/src/schemas/docs.ts +101 -0
  134. package/src/schemas/index.ts +14 -0
  135. package/src/schemas/pages.ts +22 -0
  136. package/src/styles/base.css +627 -0
  137. package/src/styles/expressive-code.css +41 -0
  138. package/src/styles/rules.css +66 -0
  139. package/src/styles/tailwind-sources.css +17 -0
  140. package/src/tailwind/preset.css +193 -0
  141. package/src/virtual-modules.d.ts +164 -0
@@ -0,0 +1,510 @@
1
+ /**
2
+ * Public prop types for the Astro-rendered shell components.
3
+ *
4
+ * These live in a separate `.ts` file (rather than inline in each `.astro`'s
5
+ * frontmatter) so the barrel `index.ts` can re-export them without relying
6
+ * on TypeScript's `.astro` module inference — which is only provided in
7
+ * Astro build contexts, not during our plain `tsc --noEmit` check.
8
+ */
9
+
10
+ // ---------------------------------------------------------------------------
11
+ // AnnouncementBanner
12
+ // ---------------------------------------------------------------------------
13
+
14
+ export type AnnouncementBannerVariant = 'info' | 'warning' | 'success';
15
+
16
+ export interface AnnouncementBannerProps {
17
+ /** Plain text message displayed inside the banner. */
18
+ message: string;
19
+ /** Optional URL; wraps the message in an anchor when provided. */
20
+ href?: string;
21
+ /** Semantic variant controlling the color scheme. Default: `'info'`. */
22
+ variant?: AnnouncementBannerVariant;
23
+ /** Whether the banner can be dismissed. Default: `true`. */
24
+ dismissible?: boolean;
25
+ /** localStorage key used to persist the dismissed state. Default: `'publier-banner-dismissed'`. */
26
+ storageKey?: string;
27
+ }
28
+
29
+ // ---------------------------------------------------------------------------
30
+ // Aside / callouts
31
+ // ---------------------------------------------------------------------------
32
+
33
+ export type AsideType = 'note' | 'tip' | 'caution' | 'danger';
34
+
35
+ export interface AsideProps {
36
+ /** Semantic variant. Default: `'note'`. */
37
+ type?: AsideType;
38
+ /** Title text. Defaults to a localized variant label (`Note`, `Tip`, ...). */
39
+ title?: string;
40
+ }
41
+
42
+ export interface CalloutProps {
43
+ /** Override the callout's header text. */
44
+ title?: string;
45
+ }
46
+
47
+ // ---------------------------------------------------------------------------
48
+ // Badge
49
+ // ---------------------------------------------------------------------------
50
+
51
+ export type BadgeVariant = 'default' | 'note' | 'tip' | 'caution' | 'danger' | 'success';
52
+ export type BadgeSize = 'small' | 'medium' | 'large';
53
+
54
+ export interface BadgeProps {
55
+ /** Text displayed inside the badge. Required. */
56
+ text: string;
57
+ /** Semantic variant. Default: `'default'`. */
58
+ variant?: BadgeVariant;
59
+ /** Size. Default: `'medium'`. */
60
+ size?: BadgeSize;
61
+ /** Additional class names to append. */
62
+ class?: string;
63
+ }
64
+
65
+ // ---------------------------------------------------------------------------
66
+ // Breadcrumbs
67
+ // ---------------------------------------------------------------------------
68
+
69
+ export interface BreadcrumbItem {
70
+ /** Visible text for the breadcrumb entry. */
71
+ label: string;
72
+ /**
73
+ * Destination URL. Omit for the last item — the current page — which is
74
+ * rendered as plain text with `aria-current="page"`.
75
+ */
76
+ href?: string;
77
+ }
78
+
79
+ export interface BreadcrumbsProps {
80
+ /** Ordered breadcrumb trail, outermost ancestor first. */
81
+ items: BreadcrumbItem[];
82
+ /** Accessible label for the <nav> landmark. Default: `'Breadcrumb'`. */
83
+ label?: string;
84
+ /** Additional class names to append to the root element. */
85
+ class?: string;
86
+ }
87
+
88
+ // ---------------------------------------------------------------------------
89
+ // Card / CardGrid
90
+ // ---------------------------------------------------------------------------
91
+
92
+ export type CardVariant = 'default' | 'note' | 'tip' | 'danger' | 'success';
93
+
94
+ export interface CardProps {
95
+ /** Title text rendered in the card's header row. Required. */
96
+ title: string;
97
+ /** Semantic variant; drives the accent border + icon tint. Default: `'default'`. */
98
+ variant?: CardVariant;
99
+ /** Additional class names to append. */
100
+ class?: string;
101
+ }
102
+
103
+ export interface CardGridProps {
104
+ /** Minimum column width before the grid wraps. Defaults to `'15rem'`. */
105
+ minColumnWidth?: string;
106
+ /** Additional class names to append. */
107
+ class?: string;
108
+ }
109
+
110
+ // ---------------------------------------------------------------------------
111
+ // CodeGroup
112
+ // ---------------------------------------------------------------------------
113
+
114
+ export interface CodeGroupItem {
115
+ /** Tab label. */
116
+ label: string;
117
+ /** Raw code string to display. */
118
+ code: string;
119
+ /** Language identifier for the `language-*` class. */
120
+ lang?: string;
121
+ /** Optional filename shown as a secondary label below the tab strip. */
122
+ filename?: string;
123
+ }
124
+
125
+ export interface CodeGroupProps {
126
+ /** Ordered code tabs. */
127
+ items: CodeGroupItem[];
128
+ /** Cross-page sync key — CodeGroup instances with the same key stay aligned. */
129
+ syncKey?: string;
130
+ }
131
+
132
+ // ---------------------------------------------------------------------------
133
+ // Columns
134
+ // ---------------------------------------------------------------------------
135
+
136
+ export type ColumnCount = 2 | 3 | 4;
137
+ export type ColumnGap = 'sm' | 'md' | 'lg';
138
+
139
+ export interface ColumnsProps {
140
+ /** Number of equal-width columns. Default: `2`. */
141
+ cols?: ColumnCount;
142
+ /** Gap size between columns. Default: `'md'`. */
143
+ gap?: ColumnGap;
144
+ /** Additional class names to append. */
145
+ class?: string;
146
+ }
147
+
148
+ // ---------------------------------------------------------------------------
149
+ // DocsLayout
150
+ // ---------------------------------------------------------------------------
151
+
152
+ export interface DocsLayoutProps {
153
+ /** Additional class names to append to the outermost wrapper. */
154
+ class?: string;
155
+ /** Optional breadcrumb trail rendered above the article slot. */
156
+ breadcrumbs?: BreadcrumbItem[];
157
+ /** Optional last-modified date rendered below breadcrumbs. */
158
+ lastModified?: Date | string | null;
159
+ }
160
+
161
+ // ---------------------------------------------------------------------------
162
+ // FileTree
163
+ // ---------------------------------------------------------------------------
164
+
165
+ export type FileTreeEntry = FileTreeFile | FileTreeDirectory | FileTreePlaceholder;
166
+
167
+ export interface FileTreeFile {
168
+ type: 'file';
169
+ /** Filename with extension (e.g. `README.md`, `index.test.ts`). */
170
+ name: string;
171
+ /** Render as the "highlighted" entry. */
172
+ highlight?: boolean;
173
+ /** Optional comment rendered after the filename. */
174
+ comment?: string;
175
+ }
176
+
177
+ export interface FileTreeDirectory {
178
+ type: 'directory';
179
+ /** Folder name (trailing slash is auto-added). */
180
+ name: string;
181
+ /** Children (files or sub-directories). */
182
+ children: FileTreeEntry[];
183
+ /** If `true`, the `<details>` opens on first render. Default: `true`. */
184
+ open?: boolean;
185
+ /** Render as the "highlighted" entry. */
186
+ highlight?: boolean;
187
+ /** Optional comment rendered after the folder name. */
188
+ comment?: string;
189
+ }
190
+
191
+ export interface FileTreePlaceholder {
192
+ type: 'placeholder';
193
+ /** Custom ellipsis text. Defaults to `'…'`. */
194
+ name?: string;
195
+ /** Optional comment rendered after the placeholder. */
196
+ comment?: string;
197
+ }
198
+
199
+ export interface FileTreeProps {
200
+ /** Top-level entries. */
201
+ tree: FileTreeEntry[];
202
+ /** Accessible label for the tree region. Default: `'File tree'`. */
203
+ label?: string;
204
+ /** Additional class names. */
205
+ class?: string;
206
+ }
207
+
208
+ // ---------------------------------------------------------------------------
209
+ // Icon
210
+ // ---------------------------------------------------------------------------
211
+
212
+ export interface IconProps {
213
+ /** Icon name from the Publier icon registry (case-sensitive). */
214
+ name: string;
215
+ /** Icon size in px. Default: `16`. */
216
+ size?: number;
217
+ /** Additional CSS class names on the wrapper span. */
218
+ class?: string;
219
+ }
220
+
221
+ // ---------------------------------------------------------------------------
222
+ // LinkButton / LinkCard
223
+ // ---------------------------------------------------------------------------
224
+
225
+ export type LinkButtonVariant = 'primary' | 'secondary' | 'minimal';
226
+ export type LinkButtonIconPlacement = 'start' | 'end';
227
+
228
+ export interface LinkButtonProps {
229
+ /** Destination URL. Required. */
230
+ href: string;
231
+ /** Visual style. Default: `'primary'`. */
232
+ variant?: LinkButtonVariant;
233
+ /** Optional icon placement relative to the label slot. Default: `'end'`. */
234
+ iconPlacement?: LinkButtonIconPlacement;
235
+ /** Optional rel attribute on the anchor. */
236
+ rel?: string;
237
+ /** Optional target attribute on the anchor. */
238
+ target?: '_blank' | '_self' | '_parent' | '_top';
239
+ /** Additional class names to append. */
240
+ class?: string;
241
+ }
242
+
243
+ export interface LinkCardProps {
244
+ /** Title text. Required. */
245
+ title: string;
246
+ /** Destination URL. Required. */
247
+ href: string;
248
+ /** Secondary descriptive text below the title. */
249
+ description?: string;
250
+ /** Optional rel attribute on the anchor. */
251
+ rel?: string;
252
+ /** Optional target attribute on the anchor. */
253
+ target?: '_blank' | '_self' | '_parent' | '_top';
254
+ /** Additional class names to append. */
255
+ class?: string;
256
+ }
257
+
258
+ // ---------------------------------------------------------------------------
259
+ // OpenInAI
260
+ // ---------------------------------------------------------------------------
261
+
262
+ export interface OpenInAIProps {
263
+ /** Full URL of the current page (pass `Astro.url.href` from the parent). */
264
+ pageUrl?: string;
265
+ /** Page title used in the "Copy as Markdown" action. */
266
+ pageTitle?: string;
267
+ }
268
+
269
+ // ---------------------------------------------------------------------------
270
+ // PackageInstall
271
+ // ---------------------------------------------------------------------------
272
+
273
+ export interface PackageInstallProps {
274
+ /** Package name to install. Used for 'prod' and 'dev' types. */
275
+ pkg?: string;
276
+ /** Install type: 'prod' (default), 'dev' (`-D`), or 'exec' (for `bunx`). */
277
+ type?: 'prod' | 'dev' | 'exec';
278
+ /** Raw command for exec type. Overrides pkg when set. */
279
+ command?: string;
280
+ /**
281
+ * Accepted for backward compatibility with pages written when
282
+ * `<PackageInstall>` rendered four package-manager tabs. The component is
283
+ * now single-PM (Publier uses pnpm as PM, bun as runtime) — there is no
284
+ * cross-instance selector to drive, so the value is ignored.
285
+ *
286
+ * @deprecated The component renders a single command (`pnpm add` for
287
+ * prod/dev, `bunx` for exec); sync keys no longer apply.
288
+ */
289
+ syncKey?: string;
290
+ }
291
+
292
+ // ---------------------------------------------------------------------------
293
+ // Panels
294
+ // ---------------------------------------------------------------------------
295
+
296
+ export type PanelVariant = 'default' | 'outlined' | 'filled';
297
+
298
+ export interface PanelsProps {
299
+ /** Optional panel heading rendered above the body. */
300
+ title?: string;
301
+ /** Visual variant. Default: `'default'`. */
302
+ variant?: PanelVariant;
303
+ /** Additional class names to append. */
304
+ class?: string;
305
+ }
306
+
307
+ // ---------------------------------------------------------------------------
308
+ // Sidebar
309
+ // ---------------------------------------------------------------------------
310
+
311
+ export interface SidebarLink {
312
+ type: 'link';
313
+ /** Display label. */
314
+ label: string;
315
+ /** Destination URL. */
316
+ href: string;
317
+ /** Optional short badge label rendered to the right of the link. */
318
+ badge?: { text: string; variant?: 'default' | 'note' | 'tip' | 'danger' | 'success' };
319
+ /** Mark link visible with muted styling (e.g. drafts). */
320
+ muted?: boolean;
321
+ }
322
+
323
+ export interface SidebarGroupEntry {
324
+ type: 'group';
325
+ /** Display label for the group header. */
326
+ label: string;
327
+ /** Child entries; may be nested further. */
328
+ children: SidebarEntry[];
329
+ /** Default collapsed state (user can toggle). Default: `false`. */
330
+ collapsed?: boolean;
331
+ /**
332
+ * When set, the group header is a single `<a>` that both navigates to
333
+ * the index page and toggles the group's expand/collapse state. When
334
+ * unset, the whole header is a pure toggle.
335
+ */
336
+ href?: string;
337
+ }
338
+
339
+ /**
340
+ * Non-interactive label above a flat list of child entries. Used for
341
+ * shallow groupings (<3 children without an index page) where a toggle
342
+ * would be more friction than it's worth.
343
+ */
344
+ export interface SidebarSection {
345
+ type: 'section';
346
+ /** Display label for the section header. */
347
+ label: string;
348
+ /** Child entries (typically links, rarely nested). */
349
+ children: SidebarEntry[];
350
+ }
351
+
352
+ export type SidebarEntry = SidebarLink | SidebarGroupEntry | SidebarSection;
353
+
354
+ export interface SidebarAnchor {
355
+ /** Display label for the anchor link. */
356
+ label: string;
357
+ /** Destination URL (may be external). */
358
+ href: string;
359
+ /** Icon name from the `Icon` component (e.g. `'github'`, `'discord'`). */
360
+ icon?: string;
361
+ /** Link target. Defaults to `'_self'`. Use `'_blank'` for external links. */
362
+ target?: '_blank' | '_self';
363
+ /** Optional small badge text (e.g. `'New'`, `'v2'`). */
364
+ badge?: string;
365
+ }
366
+
367
+ export interface SidebarProps {
368
+ /** Flat-tree navigation entries. */
369
+ items: SidebarEntry[];
370
+ /** Current pathname; used for active-link highlighting. */
371
+ currentPath?: string;
372
+ /** Optional accessible label for the nav; defaults to `'Primary'`. */
373
+ label?: string;
374
+ /** Additional class names. */
375
+ class?: string;
376
+ /**
377
+ * Version list for the version switcher. Rendered at the top of the
378
+ * sidebar, below the logo / site title. Omit (or pass an empty array)
379
+ * to hide the switcher entirely.
380
+ */
381
+ versions?: DocVersion[];
382
+ /**
383
+ * Persistent anchor links pinned to the bottom of the sidebar,
384
+ * separated from nav entries by a thin rule. Typically used for
385
+ * external resources (GitHub, Discord, Changelog, etc.) or key
386
+ * internal pages.
387
+ */
388
+ anchors?: SidebarAnchor[];
389
+ }
390
+
391
+ // ---------------------------------------------------------------------------
392
+ // SkipLink
393
+ // ---------------------------------------------------------------------------
394
+
395
+ export interface SkipLinkProps {
396
+ /** Target element id to skip to. Defaults to `publier-main`. */
397
+ targetId?: string;
398
+ /** Link label. Defaults to `Skip to content`. */
399
+ label?: string;
400
+ }
401
+
402
+ // ---------------------------------------------------------------------------
403
+ // Steps
404
+ // ---------------------------------------------------------------------------
405
+
406
+ export interface StepsProps {
407
+ /** Starting number (1 by default). */
408
+ start?: number;
409
+ /** Additional class names to append. */
410
+ class?: string;
411
+ }
412
+
413
+ // ---------------------------------------------------------------------------
414
+ // TableOfContents
415
+ // ---------------------------------------------------------------------------
416
+
417
+ export interface TocHeading {
418
+ /** URL fragment / `id` attribute of the heading element. */
419
+ slug: string;
420
+ /** Display text. */
421
+ text: string;
422
+ /** Heading level (2..6 typically; 1 is page title and usually excluded). */
423
+ depth: number;
424
+ }
425
+
426
+ export interface TableOfContentsProps {
427
+ /** Ordered headings to render; caller decides filtering (`minDepth` / `maxDepth`). */
428
+ headings: TocHeading[];
429
+ /** Heading label (visually shown above the list). Default: `'On this page'`. */
430
+ label?: string;
431
+ /** Minimum depth to indent from (subtracted from each entry's depth). Default: `2`. */
432
+ minDepth?: number;
433
+ /** Additional class names. */
434
+ class?: string;
435
+ }
436
+
437
+ // ---------------------------------------------------------------------------
438
+ // Tile / TileGrid
439
+ // ---------------------------------------------------------------------------
440
+
441
+ export interface TileProps {
442
+ /** Tile heading text. Required. */
443
+ title: string;
444
+ /** Optional description rendered below the title. */
445
+ description?: string;
446
+ /** When provided the entire tile surface becomes a link. */
447
+ href?: string;
448
+ /** Additional class names to append. */
449
+ class?: string;
450
+ }
451
+
452
+ export interface TileGridProps {
453
+ /** Minimum column width before the grid auto-fills another column. Defaults to `'200px'`. */
454
+ minColumnWidth?: string;
455
+ /** Additional class names to append. */
456
+ class?: string;
457
+ }
458
+
459
+ // ---------------------------------------------------------------------------
460
+ // TopNav / TopNavMobile
461
+ // ---------------------------------------------------------------------------
462
+
463
+ export interface TopNavProps {
464
+ /** Variant name from `publier.config.yaml` nav block. Default: `"default"`. */
465
+ variant?: string;
466
+ /** Current page path for active highlighting. Pass `Astro.url.pathname`. */
467
+ currentPath?: string;
468
+ }
469
+
470
+ export interface TopNavMobileProps {
471
+ variant?: string;
472
+ currentPath?: string;
473
+ }
474
+
475
+ // ---------------------------------------------------------------------------
476
+ // UpdateBadge
477
+ // ---------------------------------------------------------------------------
478
+
479
+ export type UpdateBadgeType = 'new' | 'improved' | 'fixed' | 'deprecated' | 'breaking';
480
+
481
+ export interface UpdateBadgeProps {
482
+ /** Semantic change type. Required. */
483
+ type: UpdateBadgeType;
484
+ /** Optional version string rendered adjacent to the type badge. */
485
+ version?: string;
486
+ /** Additional class names to append to the wrapper. */
487
+ class?: string;
488
+ }
489
+
490
+ // ---------------------------------------------------------------------------
491
+ // VersionSwitcher
492
+ // ---------------------------------------------------------------------------
493
+
494
+ export interface DocVersion {
495
+ /** Display label, e.g. "v2.0" or "latest". */
496
+ label: string;
497
+ /** Root path for this version, e.g. "/v2" or "/". */
498
+ path: string;
499
+ /** Optional semantic badge shown next to the label. */
500
+ badge?: 'stable' | 'beta' | 'deprecated' | 'legacy';
501
+ /** Which version is selected by default when no path match is found. */
502
+ default?: boolean;
503
+ }
504
+
505
+ export interface VersionSwitcherProps {
506
+ /** List of available versions to present. */
507
+ versions: DocVersion[];
508
+ /** Current page pathname. Used to detect the active version via prefix matching. */
509
+ currentPath?: string;
510
+ }
@@ -0,0 +1,60 @@
1
+ ---
2
+ interface Props {
3
+ src: string;
4
+ alt: string;
5
+ width?: number;
6
+ height?: number;
7
+ class?: string;
8
+ }
9
+
10
+ const { src, alt, width, height, class: cls } = Astro.props;
11
+
12
+ const classes = ['publier-blur-image', cls].filter(Boolean).join(' ');
13
+ ---
14
+
15
+ <img
16
+ src={src}
17
+ alt={alt}
18
+ width={width}
19
+ height={height}
20
+ loading="lazy"
21
+ data-publier-blur-image
22
+ class={classes}
23
+ />
24
+
25
+ <style>
26
+ .publier-blur-image {
27
+ filter: blur(12px) grayscale(0.6);
28
+ transform: scale(1.02);
29
+ transition: filter 500ms ease, transform 500ms ease;
30
+ }
31
+ .publier-blur-image[data-loaded="1"] {
32
+ filter: none;
33
+ transform: none;
34
+ }
35
+ @media (prefers-reduced-motion: reduce) {
36
+ .publier-blur-image {
37
+ transition: none;
38
+ }
39
+ }
40
+ </style>
41
+
42
+ <script>
43
+ function wire() {
44
+ const imgs = document.querySelectorAll<HTMLImageElement>(
45
+ 'img[data-publier-blur-image]:not([data-wired])',
46
+ );
47
+ for (const img of imgs) {
48
+ img.dataset.wired = '1';
49
+ if (img.complete && img.naturalWidth > 0) {
50
+ img.dataset.loaded = '1';
51
+ } else {
52
+ img.addEventListener('load', () => {
53
+ img.dataset.loaded = '1';
54
+ }, { once: true });
55
+ }
56
+ }
57
+ }
58
+ wire();
59
+ document.addEventListener('astro:page-load', wire);
60
+ </script>
@@ -0,0 +1,56 @@
1
+ ---
2
+ type ChangelogEntryType = 'feature' | 'fix' | 'breaking' | 'security' | 'deprecation';
3
+
4
+ interface Props {
5
+ date: string;
6
+ version?: string;
7
+ type?: ChangelogEntryType;
8
+ tags?: string[];
9
+ title: string;
10
+ }
11
+
12
+ const TYPE_BADGE: Record<ChangelogEntryType, string> = {
13
+ feature: 'badge-primary',
14
+ fix: 'badge-success',
15
+ breaking: 'badge-error',
16
+ security: 'badge-warning',
17
+ deprecation: 'badge-ghost',
18
+ };
19
+
20
+ const { date, version, type, tags, title } = Astro.props;
21
+ const displayTags = tags ?? (type ? [type] : []);
22
+ ---
23
+
24
+ <div class="relative py-10" style="grid-template-columns: 10rem 1fr; display: grid">
25
+
26
+ <div class="pr-6 pt-0.5 text-right">
27
+ <time datetime={date} class="block text-sm font-semibold text-primary leading-snug">
28
+ {date}
29
+ </time>
30
+ {version && (
31
+ <span class="mt-1.5 inline-block text-xs font-mono text-base-content/60">{version}</span>
32
+ )}
33
+ {displayTags.length > 0 && (
34
+ <ul class="mt-2 flex flex-col items-end gap-1.5 list-none p-0 m-0">
35
+ {displayTags.map((tag) => (
36
+ <li>
37
+ <span class={`badge ${TYPE_BADGE[tag as ChangelogEntryType] ?? 'badge-ghost'}`}>
38
+ {tag}
39
+ </span>
40
+ </li>
41
+ ))}
42
+ </ul>
43
+ )}
44
+ </div>
45
+
46
+
47
+ <div class="absolute top-0 bottom-0 w-px bg-base-300" style="left: 10rem" aria-hidden="true" />
48
+
49
+
50
+ <article class="pl-10">
51
+ <h3 class="text-lg font-semibold text-base-content mb-3 leading-snug">{title}</h3>
52
+ <div class="prose prose-sm text-base-content/80 max-w-none">
53
+ <slot />
54
+ </div>
55
+ </article>
56
+ </div>
@@ -0,0 +1,30 @@
1
+ ---
2
+ export type CtaBandVariant = 'primary' | 'muted';
3
+
4
+ interface Props {
5
+ title: string;
6
+ description?: string;
7
+ primaryCta: { label: string; href: string };
8
+ secondaryCta?: { label: string; href: string };
9
+ variant?: CtaBandVariant;
10
+ }
11
+
12
+ const { title, description, primaryCta, secondaryCta, variant = 'primary' } = Astro.props;
13
+
14
+ const bgCls = variant === 'primary' ? 'bg-primary text-primary-content' : 'bg-base-200 text-base-content';
15
+ const primaryBtnCls = variant === 'primary' ? 'btn btn-neutral' : 'btn btn-primary';
16
+ const secondaryBtnCls = variant === 'primary' ? 'btn btn-outline btn-neutral' : 'btn btn-outline';
17
+ ---
18
+
19
+ <section class={`${bgCls} py-14 md:py-20`}>
20
+ <div class="max-w-3xl mx-auto px-6 text-center">
21
+ <h2 class="text-3xl md:text-4xl font-bold">{title}</h2>
22
+ {description && <p class="mt-3 text-lg opacity-90">{description}</p>}
23
+ <div class="mt-7 flex flex-wrap justify-center gap-3">
24
+ <a class={primaryBtnCls} href={primaryCta.href}>{primaryCta.label}</a>
25
+ {secondaryCta && (
26
+ <a class={secondaryBtnCls} href={secondaryCta.href}>{secondaryCta.label}</a>
27
+ )}
28
+ </div>
29
+ </div>
30
+ </section>
@@ -0,0 +1,38 @@
1
+ ---
2
+ interface Item {
3
+ icon?: string;
4
+ title: string;
5
+ description: string;
6
+ href?: string;
7
+ }
8
+
9
+ interface Props {
10
+ items: Item[];
11
+ columns?: 2 | 3 | 4;
12
+ }
13
+
14
+ const { items, columns = 3 } = Astro.props;
15
+
16
+ const colCls = columns === 2
17
+ ? 'md:grid-cols-2'
18
+ : columns === 4
19
+ ? 'md:grid-cols-2 lg:grid-cols-4'
20
+ : 'md:grid-cols-2 lg:grid-cols-3';
21
+ ---
22
+
23
+ <div class={`grid gap-4 ${colCls}`}>
24
+ {items.map((item) => (
25
+ <article class="card bg-base-100 border border-base-300 hover:shadow-md transition-shadow relative">
26
+ <div class="card-body">
27
+ {item.icon && <div class="text-3xl leading-none" aria-hidden="true">{item.icon}</div>}
28
+ <h3 class="card-title text-lg text-base-content">{item.title}</h3>
29
+ <p class="text-base-content/70">{item.description}</p>
30
+ {item.href && (
31
+ <a class="absolute inset-0" href={item.href} aria-label={item.title}>
32
+ <span class="sr-only">Learn more about {item.title}</span>
33
+ </a>
34
+ )}
35
+ </div>
36
+ </article>
37
+ ))}
38
+ </div>