blume 0.5.4 → 0.6.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 (57) hide show
  1. package/dist/cli/index.js +759 -406
  2. package/dist/cli/index.js.map +27 -25
  3. package/dist/types/core/config-input.d.ts +759 -0
  4. package/dist/types/core/config.d.ts +126 -3
  5. package/dist/types/core/data.d.ts +4 -0
  6. package/dist/types/core/i18n-ui.d.ts +50 -0
  7. package/dist/types/core/schema.d.ts +334 -62
  8. package/dist/types/core/types.d.ts +8 -0
  9. package/dist/types/index.d.ts +2 -1
  10. package/docs/advanced/changelog.mdx +10 -2
  11. package/docs/configuration/ai.mdx +56 -0
  12. package/docs/configuration/index.mdx +0 -2
  13. package/docs/configuration/seo.mdx +59 -1
  14. package/docs/configuration/theming.mdx +14 -9
  15. package/docs/content/meta.mdx +3 -17
  16. package/docs/content/navigation.mdx +41 -4
  17. package/docs/content/syntax.mdx +4 -8
  18. package/package.json +3 -1
  19. package/src/ai/agent-readability.ts +97 -0
  20. package/src/ai/ask-context.ts +131 -8
  21. package/src/ai/ask-data.ts +4 -1
  22. package/src/astro/generate.ts +40 -11
  23. package/src/astro/templates.ts +90 -10
  24. package/src/cli/commands/build.ts +41 -1
  25. package/src/cli/commands/dev.ts +31 -14
  26. package/src/cli/dev-lock.ts +94 -21
  27. package/src/components/content/GithubInfo.astro +11 -10
  28. package/src/components/content/TypeTable.astro +8 -3
  29. package/src/components/content/Update.astro +12 -2
  30. package/src/components/content/changelog-element.ts +62 -0
  31. package/src/components/islands/AskAI.astro +66 -2
  32. package/src/components/islands/ask-ai.tsx +289 -53
  33. package/src/components/layout/Header.astro +1 -1
  34. package/src/components/layout/NavTree.astro +1 -1
  35. package/src/components/layout/PageActions.astro +73 -30
  36. package/src/components/layout/RootLayout.astro +79 -10
  37. package/src/core/config-input.ts +933 -0
  38. package/src/core/config.ts +126 -3
  39. package/src/core/data.ts +4 -0
  40. package/src/core/graph.ts +7 -2
  41. package/src/core/i18n-ui.ts +5 -0
  42. package/src/core/nav-diagnostics.ts +7 -0
  43. package/src/core/navigation.ts +38 -12
  44. package/src/core/schema.ts +130 -22
  45. package/src/core/sources/filesystem.ts +5 -1
  46. package/src/core/sources/watch.ts +43 -12
  47. package/src/core/types.ts +9 -0
  48. package/src/deploy/adapter-output.ts +82 -0
  49. package/src/deploy/robots.ts +37 -4
  50. package/src/index.ts +1 -1
  51. package/src/markdown/index.ts +28 -30
  52. package/src/markdown/math.ts +3 -2
  53. package/src/openapi/scalar.ts +1 -1
  54. package/src/registry/eject.ts +21 -14
  55. package/src/search/documents.ts +9 -2
  56. package/src/theme/entry.ts +7 -3
  57. package/src/theme/palette.ts +21 -14
@@ -18,6 +18,7 @@ import Favicon from "./Favicon.astro";
18
18
  import Fonts from "./Fonts.astro";
19
19
  import { bannerInitScript, themeInitScript } from "./head-scripts.ts";
20
20
  import Header from "./Header.astro";
21
+ import Icon from "../Icon.astro";
21
22
  import {
22
23
  findBreadcrumbs,
23
24
  flattenPages,
@@ -125,6 +126,12 @@ interface Props {
125
126
  clientData?: BlumeClientData | null;
126
127
  /** Table-of-contents settings (`toc` config): visibility + heading range. */
127
128
  toc?: { enabled: boolean; maxLevel: number; minLevel: number };
129
+ /**
130
+ * Content-column preset. `"bare"` (the generated changelog index) drops both
131
+ * the sidebar and the table of contents and centers a single wide column;
132
+ * everything else uses the standard sidebar + content + TOC grid.
133
+ */
134
+ contentLayout?: "default" | "bare";
128
135
  }
129
136
 
130
137
  const {
@@ -168,6 +175,7 @@ const {
168
175
  layout = {},
169
176
  clientData,
170
177
  toc = { enabled: true, maxLevel: 3, minLevel: 2 },
178
+ contentLayout = "default",
171
179
  } = Astro.props;
172
180
 
173
181
  // Serialized once for island hooks; `<` escaped so content can't break the tag.
@@ -204,16 +212,28 @@ const searchLocale =
204
212
  // API operation pages own a two-column body (docs + request panel) and their own
205
213
  // right rail, so they drop the table of contents and widen the content column.
206
214
  const isApiOperation = pageType === "openapi-operation";
215
+ // A "bare" page (the changelog index) is a standalone landing: no sidebar, no
216
+ // TOC, just a wider centered column of content.
217
+ const isBare = contentLayout === "bare";
218
+ const showSidebar = !isBare;
219
+ const showToc = !(isApiOperation || isBare);
207
220
  const tocHeadings =
208
- toc.enabled && !isApiOperation
221
+ toc.enabled && showToc
209
222
  ? headings.filter((h) => h.depth >= toc.minLevel && h.depth <= toc.maxLevel)
210
223
  : [];
211
- const gridClass = isApiOperation
212
- ? "lg:grid-cols-[17.5rem_minmax(0,1fr)]"
213
- : "lg:grid-cols-[17.5rem_minmax(0,1fr)] xl:grid-cols-[17.5rem_minmax(0,1fr)_17.5rem]";
214
- const articleClass = isApiOperation
215
- ? "prose max-w-none"
216
- : "prose mx-auto max-w-[42rem]";
224
+ let gridClass =
225
+ "lg:grid-cols-[17.5rem_minmax(0,1fr)] xl:grid-cols-[17.5rem_minmax(0,1fr)_17.5rem]";
226
+ if (isBare) {
227
+ gridClass = "";
228
+ } else if (isApiOperation) {
229
+ gridClass = "lg:grid-cols-[17.5rem_minmax(0,1fr)]";
230
+ }
231
+ let articleClass = "prose mx-auto max-w-[42rem]";
232
+ if (isBare) {
233
+ articleClass = "prose mx-auto max-w-[54rem]";
234
+ } else if (isApiOperation) {
235
+ articleClass = "prose max-w-none";
236
+ }
217
237
  const pageTitle = page.title ? `${page.title} - ${site.title}` : site.title;
218
238
  const description = page.description ?? site.description;
219
239
 
@@ -342,11 +362,58 @@ const bannerScript = banner?.dismissible
342
362
  >
343
363
  <slot name="ask" slot="ask" />
344
364
  </HeaderSlot>
345
- <div class:list={["mx-auto grid grid-cols-1 items-start", gridClass]}>
365
+ <div
366
+ class:list={["mx-auto grid grid-cols-1 items-start", gridClass]}
367
+ data-blume-doc-grid
368
+ >
369
+ {
370
+ showSidebar && (
346
371
  <aside
347
372
  aria-label="Primary"
348
373
  class="fixed top-[var(--blume-drawer-top,4rem)] start-0 z-[35] h-[calc(100dvh-var(--blume-drawer-top,4rem))] w-64 max-w-[80vw] -translate-x-[105%] overflow-y-auto border-border border-e bg-background px-5 pt-4 pb-6 transition-transform rtl:translate-x-[105%] [:where([data-blume-nav-open])_&]:translate-x-0! lg:sticky lg:top-16 lg:z-auto lg:h-[calc(100dvh-4rem)] lg:w-auto lg:max-w-none lg:translate-x-0! lg:border-e-0 lg:bg-transparent lg:px-4"
349
374
  >
375
+ {
376
+ // Pinned links (blog, changelog, contact…) sit above every section on
377
+ // all breakpoints, outside the tab-scoped sidebar so they never change
378
+ // with the active tab. External hrefs open in a new tab.
379
+ navigation.featured.length > 0 && (
380
+ <nav aria-label="Featured" class="mb-4 border-border border-b pb-4">
381
+ <ul class="m-0 list-none p-0">
382
+ {navigation.featured.map((link) => {
383
+ const external = /^https?:\/\//u.test(link.href);
384
+ return (
385
+ <li>
386
+ <a
387
+ class="block rounded-[0.65rem] px-2.5 py-1.5 text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground"
388
+ href={link.href}
389
+ rel={external ? "noreferrer" : undefined}
390
+ target={external ? "_blank" : undefined}
391
+ >
392
+ <span class="flex items-center gap-2">
393
+ {link.icon && (
394
+ <Icon
395
+ class="shrink-0 text-muted-foreground"
396
+ name={link.icon}
397
+ size={14}
398
+ />
399
+ )}
400
+ <span class="flex-1 truncate">{link.label}</span>
401
+ {external && (
402
+ <Icon
403
+ class="shrink-0 text-muted-foreground opacity-60"
404
+ name="arrow-up-right"
405
+ size={12}
406
+ />
407
+ )}
408
+ </span>
409
+ </a>
410
+ </li>
411
+ );
412
+ })}
413
+ </ul>
414
+ </nav>
415
+ )
416
+ }
350
417
  {
351
418
  // The header's tab bar is hidden below `md`, so the drawer is the only
352
419
  // way to move between sections on mobile: list the tabs above the
@@ -392,6 +459,8 @@ const bannerScript = banner?.dismissible
392
459
  }
393
460
  </nav>
394
461
  </aside>
462
+ )
463
+ }
395
464
  <main class="px-6 pt-6 pb-10 lg:px-8 xl:px-10" id="blume-content">
396
465
  <BreadcrumbsSlot crumbs={crumbs} wide={isApiOperation} />
397
466
  <TableOfContentsSlot
@@ -423,10 +492,11 @@ const bannerScript = banner?.dismissible
423
492
  }
424
493
  </main>
425
494
  {
426
- !isApiOperation && (
495
+ showToc && (
427
496
  <aside
428
497
  aria-label={strings.toc.title}
429
498
  class="sticky top-16 hidden h-[calc(100dvh-4rem)] overflow-y-auto px-4 pt-6 pb-10 text-sm xl:block"
499
+ data-blume-toc
430
500
  >
431
501
  <TableOfContentsSlot
432
502
  headings={tocHeadings}
@@ -434,7 +504,6 @@ const bannerScript = banner?.dismissible
434
504
  variant="desktop"
435
505
  />
436
506
  <PageActions
437
- askEnabled={askEnabled}
438
507
  editUrl={editUrl}
439
508
  exportEpub={exportEpub}
440
509
  exportPdf={exportPdf}