@publish.os/nextjs 0.0.1-alpha.90 → 0.0.1-alpha.91
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/compiler-assets/nextjs/defaults/group/layout.tsx +1 -5
- package/compiler-assets/nextjs/defaults/group/page.tsx +31 -22
- package/compiler-assets/nextjs/defaults/project/next.config.mjs +19 -10
- package/compiler-assets/nextjs/defaults/project/tsconfig.json.template +10 -0
- package/compiler-assets/nextjs/defaults/root/css/components/code-block.css +18 -0
- package/compiler-assets/nextjs/shims/document.tsx +38 -0
- package/compiler-assets/nextjs/shims/generated-leaf-page.tsx +2 -0
- package/compiler-assets/nextjs/shims/global-layout.tsx +8 -42
- package/compiler-assets/nextjs/shims/global-not-found.tsx +69 -0
- package/compiler-assets/nextjs/shims/markdown-route.ts +2 -0
- package/compiler-assets/nextjs/shims/metadata-icons.tsx +39 -0
- package/compiler-assets/nextjs/shims/not-found-content.tsx +53 -0
- package/compiler-assets/nextjs/shims/not-found-navigation.tsx +60 -0
- package/compiler-assets/nextjs/shims/proxy.ts +126 -60
- package/compiler-assets/nextjs/shims/site-fenced-code-block.tsx +2 -6
- package/compiler-assets/nextjs/shims/site-mdx-components.tsx +28 -16
- package/compiler-assets/nextjs/shims/site-mdx.tsx +6 -1
- package/dist/{build-operation-2JAYBSKF.js → build-operation-5QMLXF7N.js} +29 -23
- package/dist/{button-c3WGnxIj.d.ts → button-BdCScEKi.d.ts} +3 -3
- package/dist/capture-local-source-WGGDIUU2.js +258 -0
- package/dist/chunk-22RSSUNV.js +13 -0
- package/dist/{chunk-WKTEO6RS.js → chunk-4BC2L2KA.js} +46 -12
- package/dist/{chunk-WDY4IK6Z.js → chunk-5J3YUNRY.js} +3 -10
- package/dist/chunk-5KAD7W53.js +248 -0
- package/dist/{chunk-DWA3ZRGW.js → chunk-6C65KV7O.js} +2 -2
- package/dist/{chunk-GGKFQ3MA.js → chunk-6D2E6UMD.js} +144 -70
- package/dist/{chunk-7OGTPSKI.js → chunk-7NY22B5U.js} +8 -3
- package/dist/chunk-EFO6AWXN.js +19 -0
- package/dist/{chunk-726GV2NF.js → chunk-F3AGNDF4.js} +100 -67
- package/dist/chunk-GBPLER5H.js +426 -0
- package/dist/chunk-IL4RJOKI.js +186 -0
- package/dist/{chunk-DLDFHU7Y.js → chunk-NNBJZPFM.js} +4 -2
- package/dist/{chunk-VO2I7MTM.js → chunk-ORIUWJBQ.js} +8 -6
- package/dist/{chunk-H6XILMZX.js → chunk-OXOFRXEI.js} +1806 -831
- package/dist/chunk-UYGCOWRF.js +1709 -0
- package/dist/{chunk-YLTOLYWM.js → chunk-WL75GQ5M.js} +6 -18
- package/dist/compiler.d.ts +15 -2
- package/dist/compiler.js +90 -21
- package/dist/components/blocks/agent-actions.d.ts +81 -0
- package/dist/components/blocks/agent-actions.js +594 -0
- package/dist/components/blocks/toc.d.ts +43 -0
- package/dist/components/blocks/toc.js +136 -0
- package/dist/components/ui/button.d.ts +5 -0
- package/dist/components/ui/button.js +94 -0
- package/dist/compose-CVBJRAF6.js +16 -0
- package/dist/config/createNextConfig.js +17 -3
- package/dist/{dev-operation-TZDVJCN7.js → dev-operation-OSHHWRWK.js} +121 -81
- package/dist/{framework-selection-X4U6Y6QC.js → framework-selection-ZVO323PK.js} +3 -2
- package/dist/ide-support-CU6Z5PVR.js +16 -0
- package/dist/index.d.ts +40 -1
- package/dist/jsx-dev-runtime.d.ts +6 -0
- package/dist/jsx-dev-runtime.js +100 -0
- package/dist/jsx-runtime.d.ts +7 -0
- package/dist/jsx-runtime.js +97 -0
- package/dist/kernel/components/blocks/AgentActions.d.ts +35 -6
- package/dist/kernel/components/blocks/AgentActions.js +383 -142
- package/dist/kernel/components/blocks/agent-actions.d.ts +5 -0
- package/dist/kernel/components/blocks/agent-actions.js +594 -0
- package/dist/kernel/components/blocks/animated-icon-swap.js +1 -1
- package/dist/kernel/components/blocks/color-palette.js +4 -4
- package/dist/kernel/components/blocks/logo-block.js +1 -1
- package/dist/kernel/components/blocks/nav-breadcrumb.js +2 -2
- package/dist/kernel/components/blocks/navbar.js +17 -17
- package/dist/kernel/components/blocks/navigation-progress.js +2 -2
- package/dist/kernel/components/blocks/next-prev.js +1 -1
- package/dist/kernel/components/blocks/page-list.js +2 -2
- package/dist/kernel/components/blocks/search.d.ts +1 -1
- package/dist/kernel/components/blocks/search.js +16 -17
- package/dist/kernel/components/blocks/sidebar-node.js +1 -1
- package/dist/kernel/components/blocks/sidebar.js +7 -4
- package/dist/kernel/components/blocks/theme-toggle.d.ts +1 -1
- package/dist/kernel/components/blocks/theme-toggle.js +5 -5
- package/dist/kernel/components/blocks/toc-client.d.ts +40 -0
- package/dist/kernel/components/blocks/toc-client.js +495 -0
- package/dist/kernel/components/blocks/toc.d.ts +19 -1
- package/dist/kernel/components/blocks/toc.js +121 -179
- package/dist/kernel/components/mdx/components/blockquote.js +1 -1
- package/dist/kernel/components/mdx/components/callout.js +1 -1
- package/dist/kernel/components/mdx/components/code-block.js +2 -2
- package/dist/kernel/components/mdx/components/copy-code-button.js +5 -4
- package/dist/kernel/components/mdx/components/figure-caption.d.ts +1 -1
- package/dist/kernel/components/mdx/components/figure-caption.js +3 -2
- package/dist/kernel/components/mdx/components/figure.d.ts +6 -2
- package/dist/kernel/components/mdx/components/figure.js +23 -13
- package/dist/kernel/components/mdx/components/footnotes.js +1 -1
- package/dist/kernel/components/mdx/components/heading-copy-link.js +1 -1
- package/dist/kernel/components/mdx/components/heading.js +6 -3
- package/dist/kernel/components/mdx/components/hr.js +2 -2
- package/dist/kernel/components/mdx/components/image-zoom.js +1 -1
- package/dist/kernel/components/mdx/components/image.d.ts +1 -1
- package/dist/kernel/components/mdx/components/image.js +21 -16
- package/dist/kernel/components/mdx/components/inline-code.js +1 -1
- package/dist/kernel/components/mdx/components/kbd.js +2 -2
- package/dist/kernel/components/mdx/components/link.d.ts +3 -3
- package/dist/kernel/components/mdx/components/link.js +2 -2
- package/dist/kernel/components/mdx/components/paragraph.js +1 -1
- package/dist/kernel/components/mdx/components/strikethrough.js +1 -1
- package/dist/kernel/components/mdx/components/table.js +2 -2
- package/dist/kernel/components/mdx/components/task-list.js +1 -1
- package/dist/kernel/components/mdx/components/video-player.d.ts +6 -2
- package/dist/kernel/components/mdx/components/video-player.js +6 -2
- package/dist/kernel/components/mdx/components/video.d.ts +5 -3
- package/dist/kernel/components/mdx/components/video.js +7 -5
- package/dist/kernel/components/mdx/error-boundary.d.ts +1 -1
- package/dist/kernel/components/mdx/error-boundary.js +2 -2
- package/dist/kernel/components/mdx/error-fallback.js +1 -1
- package/dist/kernel/components/mdx/mdx.d.ts +20 -10
- package/dist/kernel/components/mdx/mdx.js +231 -34
- package/dist/kernel/components/mdx/rehype-heading-ids.d.ts +1 -0
- package/dist/kernel/components/mdx/rehype-heading-ids.js +5 -3
- package/dist/kernel/components/mdx/types.d.ts +1 -1
- package/dist/kernel/components/next-image.d.ts +12 -0
- package/dist/kernel/components/next-image.js +61 -0
- package/dist/kernel/components/ui/accordion.js +1 -1
- package/dist/kernel/components/ui/breadcrumb-trail.d.ts +2 -2
- package/dist/kernel/components/ui/breadcrumb-trail.js +2 -2
- package/dist/kernel/components/ui/breadcrumb.d.ts +1 -1
- package/dist/kernel/components/ui/breadcrumb.js +4 -4
- package/dist/kernel/components/ui/button-group.d.ts +1 -1
- package/dist/kernel/components/ui/button-group.js +3 -3
- package/dist/kernel/components/ui/button.d.ts +56 -4
- package/dist/kernel/components/ui/button.js +43 -39
- package/dist/kernel/components/ui/card.js +1 -1
- package/dist/kernel/components/ui/dialog.js +1 -1
- package/dist/kernel/components/ui/drawer.js +1 -1
- package/dist/kernel/components/ui/input.d.ts +2 -2
- package/dist/kernel/components/ui/input.js +1 -1
- package/dist/kernel/components/ui/kbd.d.ts +1 -1
- package/dist/kernel/components/ui/kbd.js +1 -1
- package/dist/kernel/components/ui/link.d.ts +8 -2
- package/dist/kernel/components/ui/link.js +2 -2
- package/dist/kernel/components/ui/menu.js +1 -1
- package/dist/kernel/components/ui/mod-key.js +2 -2
- package/dist/kernel/components/ui/navigation-menu.js +1 -1
- package/dist/kernel/components/ui/popover.js +1 -1
- package/dist/kernel/components/ui/progress.js +1 -1
- package/dist/kernel/components/ui/scroll-area.d.ts +8 -8
- package/dist/kernel/components/ui/scroll-area.js +1 -1
- package/dist/kernel/components/ui/select.js +1 -1
- package/dist/kernel/components/ui/separator.js +1 -1
- package/dist/kernel/components/ui/table.js +1 -1
- package/dist/kernel/components/ui/tabs.js +1 -1
- package/dist/kernel/components/ui/tag.js +1 -1
- package/dist/kernel/components/ui/text.d.ts +1 -1
- package/dist/kernel/components/ui/text.js +1 -1
- package/dist/kernel/components/ui/toast.js +1 -1
- package/dist/kernel/components/ui/tooltip.js +1 -1
- package/dist/kernel/defaults.registry.d.ts +2 -15
- package/dist/kernel/defaults.registry.js +2 -17
- package/dist/kernel/routes/agent/markdown.d.ts +3 -0
- package/dist/kernel/routes/agent/markdown.js +219 -48
- package/dist/kernel/routes/layouts/group.d.ts +1 -1
- package/dist/kernel/routes/layouts/group.js +5 -7
- package/dist/kernel/routes/metadata/feed.d.ts +1 -1
- package/dist/kernel/routes/metadata/feed.js +109 -83
- package/dist/kernel/routes/metadata/llms.d.ts +11 -3
- package/dist/kernel/routes/metadata/llms.js +154 -57
- package/dist/kernel/routes/metadata/og-image.js +1 -1
- package/dist/kernel/routes/metadata/robots.d.ts +1 -1
- package/dist/kernel/routes/metadata/sitemap.d.ts +22 -3
- package/dist/kernel/routes/metadata/sitemap.js +183 -43
- package/dist/kernel/routes/not-found.d.ts +34 -0
- package/dist/kernel/routes/not-found.js +213 -0
- package/dist/kernel/routes/pages/group.d.ts +2 -2
- package/dist/kernel/routes/pages/group.js +1 -1
- package/dist/kernel/routes/pages/leaf.d.ts +30 -3
- package/dist/kernel/routes/pages/leaf.js +5 -4
- package/dist/kernel/routes/pages/root.d.ts +2 -2
- package/dist/kernel/routes/pages/root.js +1 -1
- package/dist/keyboard-shortcuts.js +1 -1
- package/dist/route-metadata-og-image-BeKKFHg7.d.ts +58 -0
- package/dist/search.js +7 -9
- package/dist/theme-scope.js +1 -1
- package/dist/{types-BzkZty3r.d.ts → types-J2w_puPF.d.ts} +1 -20
- package/dist/types-sM2g9nW0.d.ts +12 -0
- package/dist/types.d.ts +1 -0
- package/dist/utils/heading-ids.js +30 -11
- package/dist/utils/toc-selection.d.ts +7 -0
- package/dist/utils/toc-selection.js +14 -0
- package/dist/validate-local-source-SV44DBQT.js +16 -0
- package/dist/validate-publish-os-source-NZJF3TB2.js +14 -0
- package/init/seed/minimal/publish.os/assets/blog/hello-world.svg +13 -0
- package/init/seed/minimal/publish.os/assets/favicon.dark.svg +13 -0
- package/init/seed/minimal/publish.os/assets/favicon.svg +13 -0
- package/init/seed/minimal/publish.os/blog/content/hello-world.mdx +48 -0
- package/init/seed/minimal/publish.os/blog/content/series-a.mdx +11 -0
- package/init/seed/minimal/publish.os/blog/index.tsx +82 -0
- package/init/seed/minimal/publish.os/blog/layout.tsx +13 -0
- package/init/seed/minimal/publish.os/blog/page.tsx +76 -0
- package/init/seed/minimal/publish.os/components/blog/copy-link.tsx +64 -0
- package/init/seed/minimal/publish.os/docs/content/get-started.mdx +2 -3
- package/init/seed/minimal/publish.os/docs/content/groups.mdx +5 -6
- package/init/seed/minimal/publish.os/publish.os.config.json +6 -2
- package/init/seed/minimal/publish.os/theme.css +3 -3
- package/init/seed/minimal/seed.json +11 -4
- package/init/seed/scratch/publish.os/docs/content/get-started.mdx +1 -1
- package/init/seed/scratch/publish.os/publish.os.config.json +1 -1
- package/package.json +45 -20
- package/release/app/phosphor/package.json +3 -3
- package/release/app/phosphor/pnpm-lock.yaml.template +88 -75
- package/release/compiler/package.json +5 -3
- package/release/compiler/pnpm-lock.yaml.template +118 -74
- package/release/release.json +6 -6
- package/dist/button-CtzUJB8u.d.ts +0 -11
- package/dist/chunk-535TM4A5.js +0 -1455
- package/dist/chunk-B2V22WRT.js +0 -297
- package/dist/chunk-NECL5IBJ.js +0 -318
- package/dist/chunk-SVYGXXYR.js +0 -36
- package/dist/chunk-UF6ATARM.js +0 -1100
- package/dist/compose-NN23UJGC.js +0 -13
- package/dist/ide-support-ZNW7ODFY.js +0 -15
- package/dist/kernel/components/blocks/design-system-preview.d.ts +0 -61
- package/dist/kernel/components/blocks/design-system-preview.js +0 -667
- package/dist/kernel/components/blocks/link-playground.d.ts +0 -5
- package/dist/kernel/components/blocks/link-playground.js +0 -744
- package/dist/kernel/components/blocks/navigation-progress-playground.d.ts +0 -5
- package/dist/kernel/components/blocks/navigation-progress-playground.js +0 -629
- package/dist/kernel/components/ui/theme-toggle.d.ts +0 -24
- package/dist/kernel/components/ui/theme-toggle.js +0 -53
- package/dist/validate-local-source-XRL2Y7XE.js +0 -14
- package/dist/validate-publish-os-source-DAPZ4QGE.js +0 -12
- package/init/seed/minimal/publish.os/assets/favicon/favicon.dark.png +0 -0
- package/init/seed/minimal/publish.os/assets/favicon/favicon.png +0 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
type OgImageEntryLike = {
|
|
2
|
+
key: string;
|
|
3
|
+
routePath: string;
|
|
4
|
+
title: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
source: "asset" | "generated" | "remote";
|
|
7
|
+
url: string;
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
alt: string;
|
|
11
|
+
group?: string;
|
|
12
|
+
logo?: {
|
|
13
|
+
dataUri?: string;
|
|
14
|
+
height?: number;
|
|
15
|
+
kind: "logo" | "mark" | "wordmark";
|
|
16
|
+
url: string;
|
|
17
|
+
width?: number;
|
|
18
|
+
};
|
|
19
|
+
siteName?: string;
|
|
20
|
+
siteUrl?: string;
|
|
21
|
+
label?: string;
|
|
22
|
+
background?: string;
|
|
23
|
+
textPrimary?: string;
|
|
24
|
+
textSecondary?: string;
|
|
25
|
+
accent?: string;
|
|
26
|
+
stroke?: string;
|
|
27
|
+
theme?: "light" | "dark";
|
|
28
|
+
fonts?: {
|
|
29
|
+
main: OgFontRoleLike;
|
|
30
|
+
mono: OgFontRoleLike;
|
|
31
|
+
};
|
|
32
|
+
emoji?: Readonly<Record<string, string>>;
|
|
33
|
+
fallbackGlyphs?: Partial<Record<"main" | "mono", Readonly<Record<string, string>>>>;
|
|
34
|
+
fallbackFonts?: ReadonlyArray<{
|
|
35
|
+
family: string;
|
|
36
|
+
data: string;
|
|
37
|
+
style: "normal" | "italic";
|
|
38
|
+
weight: number;
|
|
39
|
+
}>;
|
|
40
|
+
};
|
|
41
|
+
type OgManifestLike = {
|
|
42
|
+
width: number;
|
|
43
|
+
height: number;
|
|
44
|
+
generated: Record<string, OgImageEntryLike>;
|
|
45
|
+
};
|
|
46
|
+
type OgFontRoleLike = {
|
|
47
|
+
family: string;
|
|
48
|
+
files?: ReadonlyArray<{
|
|
49
|
+
data: string;
|
|
50
|
+
path?: string;
|
|
51
|
+
probe?: string;
|
|
52
|
+
style: "normal" | "italic";
|
|
53
|
+
weight: number;
|
|
54
|
+
}>;
|
|
55
|
+
sourceType: "google" | "local";
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export type { OgManifestLike as O };
|
package/dist/search.js
CHANGED
|
@@ -16,11 +16,11 @@ import {
|
|
|
16
16
|
} from "react";
|
|
17
17
|
|
|
18
18
|
// src/lib/hosting/framework-paths.ts
|
|
19
|
-
var FRAMEWORK_PREFIX = "/publishos",
|
|
20
|
-
var OG_SERVICE_PREFIX = `${SITE_API_PREFIX}/og`,
|
|
19
|
+
var FRAMEWORK_PREFIX = "/publishos", SOURCE_ASSET_PREFIX = `${FRAMEWORK_PREFIX}/assets`, INTERNAL_PREFIX = `${FRAMEWORK_PREFIX}/internal`, SITE_API_PREFIX = `${FRAMEWORK_PREFIX}/api`, SEARCH_PREFIX = `${INTERNAL_PREFIX}/search`, PAGEFIND_MODULE_URL = `${SEARCH_PREFIX}/pagefind.js`, PAGEFIND_ENTRY_URL = `${SEARCH_PREFIX}/pagefind-entry.json`, IMAGE_OPTIMIZER_PATH = `${SITE_API_PREFIX}/image`;
|
|
20
|
+
var OG_SERVICE_PREFIX = `${SITE_API_PREFIX}/og`, PUBLIC_INTERNAL_DIRECTORY = INTERNAL_PREFIX.slice(1), PUBLIC_FONT_DIRECTORY = `${PUBLIC_INTERNAL_DIRECTORY}/fonts`, PUBLIC_SEARCH_DIRECTORY = `public/${PUBLIC_INTERNAL_DIRECTORY}/search`, FRAMEWORK_PROXY_MATCHER = `/((?!${FRAMEWORK_PREFIX.slice(1)}(?:/|$)|_next/static|_next/image|_next/webpack-hmr).*)`;
|
|
21
21
|
|
|
22
22
|
// src/modules/search/search.tsx
|
|
23
|
-
import { jsx } from "
|
|
23
|
+
import { jsx } from "@publish.os/nextjs/jsx-runtime";
|
|
24
24
|
var EMPTY_SEARCH_OUTPUT = {
|
|
25
25
|
items: [],
|
|
26
26
|
nextOffset: null,
|
|
@@ -176,20 +176,18 @@ async function runPagefindSearch(input) {
|
|
|
176
176
|
let status = await fetchSearchStatus(input.signal), blockedByStatus = status ? statusOutput(status) : null;
|
|
177
177
|
return blockedByStatus || await withPagefindIndex(status?.revision, async (pagefind) => {
|
|
178
178
|
let limit = normalized.limit ?? DEFAULT_SEARCH_LIMIT, offset = normalized.offset ?? 0, result = await pagefind.search(normalized.q, {
|
|
179
|
-
filters: pagefindFilters(normalized.filters)
|
|
180
|
-
limit,
|
|
181
|
-
offset
|
|
179
|
+
filters: pagefindFilters(normalized.filters)
|
|
182
180
|
});
|
|
183
181
|
if (!result) return EMPTY_SEARCH_OUTPUT;
|
|
184
|
-
let items = await Promise.all(
|
|
185
|
-
|
|
182
|
+
let total = result.results.length, page = result.results.slice(offset, offset + limit), items = await Promise.all(
|
|
183
|
+
page.map(
|
|
186
184
|
async (pagefindResult) => toSearchResult({
|
|
187
185
|
data: await pagefindResult.data(),
|
|
188
186
|
fallbackId: pagefindResult.id,
|
|
189
187
|
score: pagefindResult.score
|
|
190
188
|
})
|
|
191
189
|
)
|
|
192
|
-
),
|
|
190
|
+
), nextOffset = offset + limit < total ? offset + limit : null;
|
|
193
191
|
return {
|
|
194
192
|
items,
|
|
195
193
|
nextOffset,
|
package/dist/theme-scope.js
CHANGED
|
@@ -116,10 +116,6 @@ type ManifestLike = {
|
|
|
116
116
|
attribution?: Record<string, ResolvedAttribution>;
|
|
117
117
|
contentHash: string;
|
|
118
118
|
};
|
|
119
|
-
type RootPageProps = {
|
|
120
|
-
site: SiteData;
|
|
121
|
-
tree: TreeNode[];
|
|
122
|
-
};
|
|
123
119
|
type LayoutProps = {
|
|
124
120
|
children: React.ReactNode;
|
|
125
121
|
site: SiteData;
|
|
@@ -128,20 +124,5 @@ type LayoutProps = {
|
|
|
128
124
|
currentPath: string;
|
|
129
125
|
group: string;
|
|
130
126
|
};
|
|
131
|
-
type PageProps<TMeta extends Record<string, unknown> = Record<string, unknown>> = {
|
|
132
|
-
site: SiteData;
|
|
133
|
-
tree: TreeNode[];
|
|
134
|
-
node: TreeNode;
|
|
135
|
-
page: PageData<TMeta>;
|
|
136
|
-
currentPath: string;
|
|
137
|
-
group: string;
|
|
138
|
-
};
|
|
139
|
-
type IndexPageProps = {
|
|
140
|
-
site: SiteData;
|
|
141
|
-
tree: TreeNode[];
|
|
142
|
-
node: TreeNode;
|
|
143
|
-
currentPath: string;
|
|
144
|
-
group: string;
|
|
145
|
-
};
|
|
146
127
|
|
|
147
|
-
export type {
|
|
128
|
+
export type { LayoutProps as L, ManifestLike as M, PageStatus as P };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { MDXComponents as MDXComponents$1 } from 'mdx/types.js';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
type MDXComponents = MDXComponents$1;
|
|
5
|
+
type MdxErrorBoundaryProps = {
|
|
6
|
+
errorMessage?: string;
|
|
7
|
+
pageId?: string;
|
|
8
|
+
slug?: string;
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type { MdxErrorBoundaryProps as M, MDXComponents as a };
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,29 @@
|
|
|
1
1
|
// src/components/mdx/heading-ids.ts
|
|
2
2
|
import { isValidElement } from "react";
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
// src/components/mdx/heading-string.ts
|
|
5
|
+
var SELF_CLOSING_TAG_RE = /<[^>]+\/>/g, PAIRED_TAG_RE = /<\/?\w[^>]*>/g, MDX_BOLD_RE = /\*\*(.*?)\*\*/g, MDX_ITALIC_RE = /\*(.*?)\*/g, MDX_UNDERLINE_BOLD_RE = /__(.*?)__/g, MDX_UNDERLINE_ITALIC_RE = /_(.*?)_/g, MDX_STRIKETHROUGH_RE = /~~(.*?)~~/g, MDX_INLINE_CODE_RE = /`(.*?)`/g, MDX_LINK_RE = /\[(.*?)\]\(.*?\)/g, NON_ALPHANUMERIC_RE = /[^a-z0-9]+/g, LEADING_TRAILING_HYPHEN_RE = /^-+|-+$/g, LEADING_DIGIT_RE = /^(\d)/;
|
|
6
|
+
function cleanHeadingString(input) {
|
|
7
|
+
return input.replace(SELF_CLOSING_TAG_RE, "").replace(PAIRED_TAG_RE, "").replace(MDX_BOLD_RE, "$1").replace(MDX_ITALIC_RE, "$1").replace(MDX_UNDERLINE_BOLD_RE, "$1").replace(MDX_UNDERLINE_ITALIC_RE, "$1").replace(MDX_STRIKETHROUGH_RE, "$1").replace(MDX_INLINE_CODE_RE, "$1").replace(MDX_LINK_RE, "$1").trim();
|
|
8
|
+
}
|
|
9
|
+
function headingStringToHTMLId(input) {
|
|
10
|
+
let text = cleanHeadingString(input);
|
|
11
|
+
return text ? text.toLowerCase().replace(NON_ALPHANUMERIC_RE, "-").replace(LEADING_TRAILING_HYPHEN_RE, "").replace(LEADING_DIGIT_RE, "id-$1") || "heading" : "empty-heading";
|
|
12
|
+
}
|
|
13
|
+
function createHeadingStringIdGenerator() {
|
|
14
|
+
let nextSuffix = /* @__PURE__ */ new Map(), usedIds = /* @__PURE__ */ new Set();
|
|
15
|
+
return (input) => {
|
|
16
|
+
let baseId = headingStringToHTMLId(input);
|
|
17
|
+
if (baseId === "empty-heading") return baseId;
|
|
18
|
+
let suffix = nextSuffix.get(baseId) ?? 0, id = suffix === 0 ? baseId : `${baseId}-${suffix}`;
|
|
19
|
+
for (; usedIds.has(id); )
|
|
20
|
+
suffix += 1, id = `${baseId}-${suffix}`;
|
|
21
|
+
return nextSuffix.set(baseId, suffix + 1), usedIds.add(id), id;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/components/mdx/heading-ids.ts
|
|
26
|
+
var HEADING_RE = /^(#{1,6})[ \t]+(.+?)\s*#*\s*$/gm, FENCED_CODE_RE = /```[\s\S]*?```|~~~[\s\S]*?~~~/g;
|
|
4
27
|
function extractText(node) {
|
|
5
28
|
if (typeof node == "string") return node;
|
|
6
29
|
if (typeof node == "number") return String(node);
|
|
@@ -14,26 +37,22 @@ function extractText(node) {
|
|
|
14
37
|
return "";
|
|
15
38
|
}
|
|
16
39
|
function cleanHeadingText(input) {
|
|
17
|
-
|
|
40
|
+
let text = typeof input == "string" ? input : extractText(input);
|
|
41
|
+
return cleanHeadingString(text);
|
|
18
42
|
}
|
|
19
43
|
function slugify(text) {
|
|
20
|
-
return text
|
|
44
|
+
return headingStringToHTMLId(text);
|
|
21
45
|
}
|
|
22
46
|
function headingToHTMLId(input) {
|
|
23
47
|
try {
|
|
24
|
-
return slugify(cleanHeadingText(input)) || "empty-heading";
|
|
48
|
+
return slugify(cleanHeadingText(input)) || (cleanHeadingText(input) ? "heading" : "empty-heading");
|
|
25
49
|
} catch {
|
|
26
50
|
return "empty-heading";
|
|
27
51
|
}
|
|
28
52
|
}
|
|
29
53
|
function createHeadingIdGenerator() {
|
|
30
|
-
let
|
|
31
|
-
return (input) =>
|
|
32
|
-
let baseId = headingToHTMLId(input);
|
|
33
|
-
if (baseId === "empty-heading") return baseId;
|
|
34
|
-
let count = usedIds.get(baseId) ?? 0;
|
|
35
|
-
return usedIds.set(baseId, count + 1), count === 0 ? baseId : `${baseId}-${count}`;
|
|
36
|
-
};
|
|
54
|
+
let headingId = createHeadingStringIdGenerator();
|
|
55
|
+
return (input) => headingId(cleanHeadingText(input));
|
|
37
56
|
}
|
|
38
57
|
function extractMdxHeadings(content = "", levels) {
|
|
39
58
|
let [minDepth, maxDepth] = levels, headingId = createHeadingIdGenerator(), headings = [], searchableContent = content.replace(FENCED_CODE_RE, "");
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// src/components/block/toc/selection.ts
|
|
2
|
+
function findActiveHeadingIndex(headings, readingLine, isAtBottom = !1) {
|
|
3
|
+
if (headings.length === 0) return -1;
|
|
4
|
+
if (isAtBottom) return headings.length - 1;
|
|
5
|
+
let low = 0, high = headings.length;
|
|
6
|
+
for (; low < high; ) {
|
|
7
|
+
let middle = low + Math.floor((high - low) / 2), heading = headings[middle];
|
|
8
|
+
heading && heading.top <= readingLine ? low = middle + 1 : high = middle;
|
|
9
|
+
}
|
|
10
|
+
return Math.max(0, low - 1);
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
findActiveHeadingIndex
|
|
14
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
validateLocalSource
|
|
3
|
+
} from "./chunk-ORIUWJBQ.js";
|
|
4
|
+
import "./chunk-NNBJZPFM.js";
|
|
5
|
+
import "./chunk-F3AGNDF4.js";
|
|
6
|
+
import "./chunk-7NY22B5U.js";
|
|
7
|
+
import "./chunk-UYGCOWRF.js";
|
|
8
|
+
import "./chunk-EFO6AWXN.js";
|
|
9
|
+
import "./chunk-5KAD7W53.js";
|
|
10
|
+
import "./chunk-WL75GQ5M.js";
|
|
11
|
+
import "./chunk-AI2UULNX.js";
|
|
12
|
+
import "./chunk-5J3YUNRY.js";
|
|
13
|
+
import "./chunk-22RSSUNV.js";
|
|
14
|
+
export {
|
|
15
|
+
validateLocalSource
|
|
16
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
validatePublishOsSource
|
|
3
|
+
} from "./chunk-F3AGNDF4.js";
|
|
4
|
+
import "./chunk-7NY22B5U.js";
|
|
5
|
+
import "./chunk-UYGCOWRF.js";
|
|
6
|
+
import "./chunk-EFO6AWXN.js";
|
|
7
|
+
import "./chunk-5KAD7W53.js";
|
|
8
|
+
import "./chunk-WL75GQ5M.js";
|
|
9
|
+
import "./chunk-AI2UULNX.js";
|
|
10
|
+
import "./chunk-5J3YUNRY.js";
|
|
11
|
+
import "./chunk-22RSSUNV.js";
|
|
12
|
+
export {
|
|
13
|
+
validatePublishOsSource
|
|
14
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="800" viewBox="0 0 1600 800" fill="none">
|
|
2
|
+
<rect width="1600" height="800" fill="#101214"/>
|
|
3
|
+
<g stroke="#343A40" stroke-width="2">
|
|
4
|
+
<path d="M160 240H1440M160 320H1440M160 480H1440M160 560H1440"/>
|
|
5
|
+
<path d="M160 400H560C640 400 640 280 720 280H880C960 280 960 400 1040 400H1440"/>
|
|
6
|
+
<path d="M160 400H560C640 400 640 520 720 520H880C960 520 960 400 1040 400H1440"/>
|
|
7
|
+
</g>
|
|
8
|
+
<path d="M160 400H1440" stroke="#A9CFFF" stroke-width="3"/>
|
|
9
|
+
<circle cx="800" cy="400" r="50" fill="#101214" stroke="#A9CFFF" stroke-width="3"/>
|
|
10
|
+
<path d="m786 383-17 17 17 17m28-34 17 17-17 17" stroke="#A9CFFF" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
|
|
11
|
+
<g fill="#727C86"><circle cx="160" cy="240" r="4"/><circle cx="160" cy="320" r="4"/><circle cx="160" cy="480" r="4"/><circle cx="160" cy="560" r="4"/></g>
|
|
12
|
+
<circle cx="160" cy="400" r="4" fill="#A9CFFF"/>
|
|
13
|
+
</svg>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect width="512" height="512" rx="120" fill="#181818"/>
|
|
3
|
+
<rect x="6" y="6" width="500" height="500" rx="114" stroke="white" stroke-opacity="0.18" stroke-width="12"/>
|
|
4
|
+
<g clip-path="url(#clip0_1715_626)">
|
|
5
|
+
<path d="M273.137 237.996L306.335 157.85L343.538 173.259L310.7 252.535L372.044 191.192L400.518 219.666L339.839 280.343L419.988 247.145L435.398 284.348L307.078 337.498L312.354 339.684H196.574L201.851 337.498L73.5332 284.348L88.9434 247.145L166.473 279.258L106.881 219.666L135.354 191.192L194.937 250.774L162.829 173.259L200.032 157.85L232.869 237.124V152.184H273.137V237.996Z" fill="white"/>
|
|
6
|
+
<rect x="68.5" y="319.551" width="375" height="40.2685" fill="white"/>
|
|
7
|
+
</g>
|
|
8
|
+
<defs>
|
|
9
|
+
<clipPath id="clip0_1715_626">
|
|
10
|
+
<rect width="375" height="375" fill="white" transform="translate(68.5 68.5)"/>
|
|
11
|
+
</clipPath>
|
|
12
|
+
</defs>
|
|
13
|
+
</svg>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect width="512" height="512" rx="120" fill="white"/>
|
|
3
|
+
<rect x="6" y="6" width="500" height="500" rx="114" stroke="#291E00" stroke-opacity="0.2" stroke-width="12"/>
|
|
4
|
+
<g clip-path="url(#clip0_1715_611)">
|
|
5
|
+
<path d="M273.137 237.996L306.335 157.85L343.538 173.259L310.7 252.535L372.044 191.192L400.518 219.666L339.839 280.343L419.988 247.145L435.398 284.348L307.078 337.498L312.354 339.684H196.574L201.851 337.498L73.5332 284.348L88.9434 247.145L166.473 279.258L106.881 219.666L135.354 191.192L194.937 250.774L162.829 173.259L200.032 157.85L232.869 237.124V152.184H273.137V237.996Z" fill="#161000"/>
|
|
6
|
+
<rect x="68.5" y="319.551" width="375" height="40.2685" fill="#161000"/>
|
|
7
|
+
</g>
|
|
8
|
+
<defs>
|
|
9
|
+
<clipPath id="clip0_1715_611">
|
|
10
|
+
<rect width="375" height="375" fill="white" transform="translate(68.5 68.5)"/>
|
|
11
|
+
</clipPath>
|
|
12
|
+
</defs>
|
|
13
|
+
</svg>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Hello, world.
|
|
3
|
+
description: Publish your first post and make this blog your own.
|
|
4
|
+
publishedAt: 2026-10-20
|
|
5
|
+
authors: [Matthew B]
|
|
6
|
+
tags: [Press]
|
|
7
|
+
image:
|
|
8
|
+
src: /assets/blog/hello-world.svg
|
|
9
|
+
alt: A code symbol where several publishing paths meet.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Use this blog to share news, releases, and what you learn. Edit this post in `publish.os/blog/content/hello-world.mdx`.
|
|
13
|
+
|
|
14
|
+
## Add a post
|
|
15
|
+
|
|
16
|
+
Create another `.mdx` file in `publish.os/blog/content/`:
|
|
17
|
+
|
|
18
|
+
```mdx
|
|
19
|
+
---
|
|
20
|
+
title: A small beginning
|
|
21
|
+
description: Why this project exists.
|
|
22
|
+
publishedAt: 2026-10-21
|
|
23
|
+
authors: [Matthew B]
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
This project starts with one problem and one useful solution.
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The blog index shows published posts, newest first. Set `publishedAt` to edit the publication date.
|
|
30
|
+
|
|
31
|
+
## Customize the blog
|
|
32
|
+
|
|
33
|
+
Edit `index.tsx` to change the post list at `/blog`. Edit `page.tsx` to change individual posts. The shared [theme](/docs/themes) supplies colors and typography.
|
|
34
|
+
|
|
35
|
+
```txt
|
|
36
|
+
publish.os/blog/
|
|
37
|
+
├── layout.tsx
|
|
38
|
+
├── index.tsx
|
|
39
|
+
├── page.tsx
|
|
40
|
+
└── content/
|
|
41
|
+
├── hello-world.mdx
|
|
42
|
+
└── series-a.mdx
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
Edit `layout.tsx` to change the blog layout.
|
|
47
|
+
|
|
48
|
+
Add `tags` and an `image` with `src` and `alt` to a post's frontmatter to customize its header. Keep local images in `publish.os/assets/` and reference them with `/assets/` paths.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Our $5M Series A
|
|
3
|
+
description: A fictional funding announcement for your starter blog.
|
|
4
|
+
publishedAt: 2026-10-18
|
|
5
|
+
authors: [Matthew B]
|
|
6
|
+
tags: [Company news]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
Example Co. raised $5 million in Series A funding to help teams publish useful documentation. We will use the investment to grow the team and improve the product.
|
|
10
|
+
|
|
11
|
+
This is a fictional announcement for the starter site. Replace it with your own news.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
IndexPageProps,
|
|
3
|
+
PageNode,
|
|
4
|
+
TreeNode,
|
|
5
|
+
} from "@publish.os/nextjs/types";
|
|
6
|
+
import { prettyDate } from "@publish.os/nextjs/utils/pretty-date";
|
|
7
|
+
import Link from "next/link";
|
|
8
|
+
|
|
9
|
+
function pageNodes(nodes: TreeNode[]): PageNode[] {
|
|
10
|
+
return nodes.flatMap((node) => {
|
|
11
|
+
if (node.type === "page") return [node];
|
|
12
|
+
if (node.type === "section" || node.type === "folder") {
|
|
13
|
+
return pageNodes(node.children);
|
|
14
|
+
}
|
|
15
|
+
return [];
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default function BlogIndex({ node, tree }: IndexPageProps) {
|
|
20
|
+
const posts = pageNodes(tree)
|
|
21
|
+
.filter((page) => page.status === "published")
|
|
22
|
+
.sort(
|
|
23
|
+
(a, b) =>
|
|
24
|
+
(b.publishedAt ?? "").localeCompare(a.publishedAt ?? "") ||
|
|
25
|
+
a.path.localeCompare(b.path),
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<section className="w-full px-4 py-12 md:px-5 lg:px-6 lg:py-16">
|
|
30
|
+
<h1 className="mb-10 text-balance text-5xl font-medium leading-none tracking-tight text-foreground-1">
|
|
31
|
+
{node.title}
|
|
32
|
+
</h1>
|
|
33
|
+
{posts.length > 0 ? (
|
|
34
|
+
<ul>
|
|
35
|
+
{posts.map((post) => {
|
|
36
|
+
const authors = post.authors
|
|
37
|
+
.map((author) => author.name)
|
|
38
|
+
.join(", ");
|
|
39
|
+
const date = prettyDate(post.publishedAt);
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<li
|
|
43
|
+
className="border-b border-stroke-4 last:border-b-0"
|
|
44
|
+
key={post.path}
|
|
45
|
+
>
|
|
46
|
+
<Link
|
|
47
|
+
className="-mx-4 flex min-h-12 items-center gap-6 rounded-card px-4 py-4 text-sm text-foreground-1 hover:bg-surface-hover active:bg-surface-active focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-stroke"
|
|
48
|
+
href={post.path}
|
|
49
|
+
title={post.title}
|
|
50
|
+
>
|
|
51
|
+
<span className="min-w-0 flex-1 truncate">{post.title}</span>
|
|
52
|
+
<span className="hidden min-w-0 max-w-[45%] items-baseline gap-1.5 text-foreground-3 md:flex">
|
|
53
|
+
{authors ? (
|
|
54
|
+
<span className="truncate">{authors}</span>
|
|
55
|
+
) : null}
|
|
56
|
+
{authors && date ? <span aria-hidden="true">·</span> : null}
|
|
57
|
+
{date ? (
|
|
58
|
+
<time
|
|
59
|
+
className="shrink-0 whitespace-nowrap"
|
|
60
|
+
dateTime={post.publishedAt}
|
|
61
|
+
>
|
|
62
|
+
{date}
|
|
63
|
+
</time>
|
|
64
|
+
) : null}
|
|
65
|
+
</span>
|
|
66
|
+
<span
|
|
67
|
+
aria-hidden="true"
|
|
68
|
+
className="shrink-0 text-foreground-2 md:hidden rtl:rotate-180"
|
|
69
|
+
>
|
|
70
|
+
→
|
|
71
|
+
</span>
|
|
72
|
+
</Link>
|
|
73
|
+
</li>
|
|
74
|
+
);
|
|
75
|
+
})}
|
|
76
|
+
</ul>
|
|
77
|
+
) : (
|
|
78
|
+
<p className="text-sm text-foreground-2">No posts yet.</p>
|
|
79
|
+
)}
|
|
80
|
+
</section>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { LayoutProps } from "@publish.os/nextjs/types";
|
|
2
|
+
|
|
3
|
+
export default function BlogLayout({ children }: LayoutProps) {
|
|
4
|
+
return (
|
|
5
|
+
<main
|
|
6
|
+
className="mx-auto flex min-h-0 min-w-0 w-full max-w-(--layout-site-max-width) flex-1 flex-col border-x border-stroke-3 bg-surface-1"
|
|
7
|
+
id="main-content"
|
|
8
|
+
tabIndex={-1}
|
|
9
|
+
>
|
|
10
|
+
{children}
|
|
11
|
+
</main>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { CaretLeftIcon } from "@phosphor-icons/react/ssr";
|
|
2
|
+
import { MDX } from "@publish.os/nextjs/mdx";
|
|
3
|
+
import type { PageProps } from "@publish.os/nextjs/types";
|
|
4
|
+
import { prettyDate } from "@publish.os/nextjs/utils/pretty-date";
|
|
5
|
+
import Image from "next/image";
|
|
6
|
+
import Link from "next/link";
|
|
7
|
+
import { CopyLink } from "../components/blog/copy-link";
|
|
8
|
+
|
|
9
|
+
type BlogMeta = {
|
|
10
|
+
image?: { src: string; alt: string };
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default function BlogLeaf({ page }: PageProps<BlogMeta>) {
|
|
14
|
+
const authors = page.authors.map((author) => author.name).join(", ");
|
|
15
|
+
const date = prettyDate(page.publishedAt);
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<div className="flex min-h-0 min-w-0 flex-1 flex-col px-4 pt-6 md:px-5 lg:px-6 lg:pt-8">
|
|
19
|
+
<nav aria-label="Blog" className="mb-8 lg:mb-12">
|
|
20
|
+
<Link
|
|
21
|
+
className="-ms-2 inline-flex min-h-11 items-center gap-1.5 rounded-button px-2 text-sm text-foreground-3 hover:text-foreground-1 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-stroke"
|
|
22
|
+
href="/blog"
|
|
23
|
+
>
|
|
24
|
+
<CaretLeftIcon
|
|
25
|
+
aria-hidden="true"
|
|
26
|
+
className="size-3.5 shrink-0 rtl:rotate-180"
|
|
27
|
+
/>
|
|
28
|
+
Blog
|
|
29
|
+
</Link>
|
|
30
|
+
</nav>
|
|
31
|
+
<article className="mx-auto flex min-w-0 w-full max-w-4xl flex-1 flex-col wrap-anywhere">
|
|
32
|
+
<header>
|
|
33
|
+
<div className="mx-auto w-full max-w-2xl">
|
|
34
|
+
<h1 className="text-balance text-center text-4xl font-medium leading-tight tracking-tight text-foreground-1 md:text-5xl">
|
|
35
|
+
{page.title}
|
|
36
|
+
</h1>
|
|
37
|
+
</div>
|
|
38
|
+
{page.meta.image ? (
|
|
39
|
+
<Image
|
|
40
|
+
alt={page.meta.image.alt}
|
|
41
|
+
className="mt-10 aspect-2/1 w-full rounded-media border border-stroke-3 object-cover"
|
|
42
|
+
height={800}
|
|
43
|
+
priority
|
|
44
|
+
sizes="(max-width: 896px) 100vw, 896px"
|
|
45
|
+
src={page.meta.image.src}
|
|
46
|
+
width={1600}
|
|
47
|
+
/>
|
|
48
|
+
) : null}
|
|
49
|
+
<div className="mx-auto w-full max-w-2xl">
|
|
50
|
+
{page.description ? (
|
|
51
|
+
<p className="mt-12 text-pretty text-center text-base italic leading-7 text-foreground-2">
|
|
52
|
+
{page.description}
|
|
53
|
+
</p>
|
|
54
|
+
) : null}
|
|
55
|
+
<hr className="my-10 border-stroke-3" />
|
|
56
|
+
</div>
|
|
57
|
+
</header>
|
|
58
|
+
<div className="mx-auto flex w-full max-w-2xl flex-1 flex-col">
|
|
59
|
+
<div className="markdown-prose min-w-0 flex-1">
|
|
60
|
+
<MDX page={page} />
|
|
61
|
+
</div>
|
|
62
|
+
<div className="mx-auto mt-12 mb-24 flex w-full max-w-2xl flex-wrap items-center justify-between gap-3 border-t border-stroke-3 pt-6">
|
|
63
|
+
{authors || date ? (
|
|
64
|
+
<p className="flex flex-wrap items-baseline gap-x-1.5 text-sm text-foreground-3">
|
|
65
|
+
{authors ? <span>{authors}</span> : null}
|
|
66
|
+
{authors && date ? <span aria-hidden="true">·</span> : null}
|
|
67
|
+
{date ? <time dateTime={page.publishedAt}>{date}</time> : null}
|
|
68
|
+
</p>
|
|
69
|
+
) : null}
|
|
70
|
+
<CopyLink className="ms-auto" path={page.path} />
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
</article>
|
|
74
|
+
</div>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Link } from "@components/ui/link";
|
|
4
|
+
import { LinkSimpleIcon } from "@phosphor-icons/react/ssr";
|
|
5
|
+
import { useState } from "react";
|
|
6
|
+
|
|
7
|
+
export function CopyLink({
|
|
8
|
+
className,
|
|
9
|
+
path,
|
|
10
|
+
}: {
|
|
11
|
+
className?: string;
|
|
12
|
+
path: string;
|
|
13
|
+
}) {
|
|
14
|
+
const [status, setStatus] = useState<"idle" | "pending" | "copied" | "error">(
|
|
15
|
+
"idle",
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
async function copyLink() {
|
|
19
|
+
setStatus("pending");
|
|
20
|
+
try {
|
|
21
|
+
await navigator.clipboard.writeText(
|
|
22
|
+
new URL(path, window.location.origin).href,
|
|
23
|
+
);
|
|
24
|
+
setStatus("copied");
|
|
25
|
+
} catch {
|
|
26
|
+
setStatus("error");
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<div className={className}>
|
|
32
|
+
<Link
|
|
33
|
+
aria-busy={status === "pending" || undefined}
|
|
34
|
+
className="inline-flex min-h-11 items-center text-foreground-3 hover:text-foreground-1 active:text-foreground-1 motion-safe:transition-[color,scale] motion-safe:duration-150 motion-safe:active:scale-[0.96] motion-reduce:transition-none"
|
|
35
|
+
href={path}
|
|
36
|
+
leftIcon={<LinkSimpleIcon aria-hidden="true" />}
|
|
37
|
+
onClick={(event) => {
|
|
38
|
+
if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)
|
|
39
|
+
return;
|
|
40
|
+
event.preventDefault();
|
|
41
|
+
if (status !== "pending") void copyLink();
|
|
42
|
+
}}
|
|
43
|
+
prefetch={false}
|
|
44
|
+
size="xs"
|
|
45
|
+
>
|
|
46
|
+
Copy link
|
|
47
|
+
</Link>
|
|
48
|
+
<p
|
|
49
|
+
className={
|
|
50
|
+
status === "error"
|
|
51
|
+
? "mt-2 max-w-60 text-sm text-foreground-2"
|
|
52
|
+
: "sr-only"
|
|
53
|
+
}
|
|
54
|
+
role="status"
|
|
55
|
+
>
|
|
56
|
+
{status === "copied"
|
|
57
|
+
? "Link copied."
|
|
58
|
+
: status === "error"
|
|
59
|
+
? "Could not copy. Try again, or copy the address from your browser."
|
|
60
|
+
: ""}
|
|
61
|
+
</p>
|
|
62
|
+
</div>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Get started
|
|
3
3
|
description: Preview your site and make your first change.
|
|
4
|
-
order: 1
|
|
5
4
|
---
|
|
6
5
|
|
|
7
6
|
A publishOS site starts with a folder. The `publish.os/` folder contains your content, theme, and configuration.
|
|
@@ -30,7 +29,7 @@ Use Markdown for normal text. You can use **bold text**, _italic text_, and `cod
|
|
|
30
29
|
|
|
31
30
|
You can also use MDX components to add interactive elements to your pages.
|
|
32
31
|
|
|
33
|
-
Use [
|
|
32
|
+
Use the [blog](/blog) to share updates alongside your documentation.
|
|
34
33
|
|
|
35
34
|
You can show a keyboard shortcut such as <kbd>Ctrl</kbd>+<kbd>Enter</kbd>.
|
|
36
35
|
|
|
@@ -47,4 +46,4 @@ description: Add a page to your site.
|
|
|
47
46
|
Each MDX file contains one page.
|
|
48
47
|
```
|
|
49
48
|
|
|
50
|
-
Next
|
|
49
|
+
Next, organize your [groups](/docs/groups) or customize your [theme](/docs/themes).
|