@vespercms/admin 0.0.0-stage → 0.1.0-next.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.
- package/README.md +119 -2
- package/dist/BodyEditor-_mkh0BSQ.js +3047 -0
- package/dist/a11y/FieldNotes.d.ts +23 -0
- package/dist/a11y/NotesDrawer.d.ts +23 -0
- package/dist/a11y/pdf.d.ts +3 -0
- package/dist/a11y/run.d.ts +3 -0
- package/dist/a11y/useNotes.d.ts +28 -0
- package/dist/app/App.d.ts +2 -0
- package/dist/app/Screen.d.ts +88 -0
- package/dist/app/UserMenu.d.ts +7 -0
- package/dist/app/api.d.ts +75 -0
- package/dist/app/appearance.d.ts +10 -0
- package/dist/app/browser-api.d.ts +17 -0
- package/dist/app/collection-icon.d.ts +12 -0
- package/dist/app/context.d.ts +23 -0
- package/dist/app/entries-changed.d.ts +11 -0
- package/dist/app/file-url.d.ts +13 -0
- package/dist/app/format.d.ts +4 -0
- package/dist/app/idb.d.ts +7 -0
- package/dist/app/load.d.ts +16 -0
- package/dist/app/media.d.ts +5 -0
- package/dist/app/navigation.d.ts +4 -0
- package/dist/app/pane-context.d.ts +19 -0
- package/dist/app/panes.d.ts +14 -0
- package/dist/app/router.d.ts +62 -0
- package/dist/body/BodyEditor.d.ts +42 -0
- package/dist/body/TableView.d.ts +2 -0
- package/dist/body/catalog.d.ts +47 -0
- package/dist/body/checks.d.ts +15 -0
- package/dist/body/chips.d.ts +31 -0
- package/dist/body/commands.d.ts +31 -0
- package/dist/body/document.d.ts +42 -0
- package/dist/body/insert.d.ts +69 -0
- package/dist/body/nodes.d.ts +38 -0
- package/dist/body/reveal.d.ts +13 -0
- package/dist/body/scroll.d.ts +16 -0
- package/dist/body/settings.d.ts +19 -0
- package/dist/body/shortcuts.d.ts +13 -0
- package/dist/body/table.d.ts +31 -0
- package/dist/body/ui.d.ts +30 -0
- package/dist/body/views.d.ts +9 -0
- package/dist/checks-C-0xDu-I.js +57 -0
- package/dist/cloud/CloudGate.d.ts +14 -0
- package/dist/cloud/access.d.ts +14 -0
- package/dist/cloud/changes.d.ts +26 -0
- package/dist/cloud/connection.d.ts +100 -0
- package/dist/cloud/editor.d.ts +44 -0
- package/dist/cloud/session.d.ts +62 -0
- package/dist/cloud/storage.d.ts +45 -0
- package/dist/editor/Field.d.ts +24 -0
- package/dist/editor/PagePicker.d.ts +20 -0
- package/dist/editor/arrange.d.ts +13 -0
- package/dist/editor/context.d.ts +23 -0
- package/dist/editor/copy.d.ts +9 -0
- package/dist/editor/reveal.d.ts +7 -0
- package/dist/editor/target.d.ts +21 -0
- package/dist/editor/values.d.ts +18 -0
- package/dist/geo-map-CT3OGD7O.js +110 -0
- package/dist/github/GitHubGate.d.ts +15 -0
- package/dist/github/api.d.ts +20 -0
- package/dist/github/cache.d.ts +2 -0
- package/dist/github/session.d.ts +35 -0
- package/dist/index.d.ts +3 -0
- package/dist/markdown-4fVeej3c.js +211 -0
- package/dist/media/MediaPicker.d.ts +28 -0
- package/dist/media/file-icon.d.ts +3 -0
- package/dist/media/formats.d.ts +23 -0
- package/dist/media/hygiene.d.ts +37 -0
- package/dist/media/upload.d.ts +31 -0
- package/dist/mount.d.ts +3 -0
- package/dist/pdf-m5s_uXJ3.js +24 -0
- package/dist/run-y4XRkg17.js +7 -0
- package/dist/schedule/ScheduleDialog.d.ts +28 -0
- package/dist/schedule/ScheduleSummary.d.ts +12 -0
- package/dist/schedule/ScheduledView.d.ts +8 -0
- package/dist/schedule/cloud.d.ts +21 -0
- package/dist/schedule/now.d.ts +5 -0
- package/dist/schedule/times.d.ts +35 -0
- package/dist/screens/EntryEditor.d.ts +13 -0
- package/dist/screens/EntryList.d.ts +16 -0
- package/dist/screens/Home.d.ts +6 -0
- package/dist/screens/ListPane.d.ts +6 -0
- package/dist/screens/MediaBrowser.d.ts +7 -0
- package/dist/screens/NotFound.d.ts +3 -0
- package/dist/screens/PageTree.d.ts +10 -0
- package/dist/screens/Redirects.d.ts +1 -0
- package/dist/screens/Unavailable.d.ts +8 -0
- package/dist/screens/status.d.ts +36 -0
- package/dist/shortcuts-CarKeDqp.js +4666 -0
- package/dist/studio.css +3 -0
- package/dist/studio.js +6449 -0
- package/dist/types.d.ts +76 -0
- package/dist/widgets/basic.d.ts +25 -0
- package/dist/widgets/blank-date.d.ts +8 -0
- package/dist/widgets/crops.d.ts +43 -0
- package/dist/widgets/focal-point.d.ts +15 -0
- package/dist/widgets/geo-map.d.ts +10 -0
- package/dist/widgets/geo.d.ts +16 -0
- package/dist/widgets/group.d.ts +41 -0
- package/dist/widgets/icon.d.ts +9 -0
- package/dist/widgets/image.d.ts +16 -0
- package/dist/widgets/markdown-lazy.d.ts +2 -0
- package/dist/widgets/markdown.d.ts +2 -0
- package/dist/widgets/reference.d.ts +12 -0
- package/dist/widgets/registry.d.ts +32 -0
- package/dist/widgets/special.d.ts +20 -0
- package/dist/widgets/union.d.ts +36 -0
- package/package.json +63 -4
- package/src/a11y/FieldNotes.tsx +56 -0
- package/src/a11y/NotesDrawer.tsx +81 -0
- package/src/a11y/pdf.ts +45 -0
- package/src/a11y/run.ts +12 -0
- package/src/a11y/useNotes.ts +139 -0
- package/src/app/App.tsx +156 -0
- package/src/app/Screen.tsx +416 -0
- package/src/app/UserMenu.tsx +95 -0
- package/src/app/api.ts +176 -0
- package/src/app/appearance.ts +54 -0
- package/src/app/browser-api.ts +173 -0
- package/src/app/collection-icon.ts +15 -0
- package/src/app/context.tsx +32 -0
- package/src/app/entries-changed.ts +48 -0
- package/src/app/file-url.tsx +44 -0
- package/src/app/format.ts +39 -0
- package/src/app/idb.ts +82 -0
- package/src/app/load.ts +40 -0
- package/src/app/media.ts +20 -0
- package/src/app/navigation.ts +4 -0
- package/src/app/pane-context.ts +25 -0
- package/src/app/panes.tsx +513 -0
- package/src/app/router.ts +158 -0
- package/src/body/BodyEditor.tsx +1139 -0
- package/src/body/TableView.tsx +700 -0
- package/src/body/catalog.ts +198 -0
- package/src/body/checks.ts +83 -0
- package/src/body/chips.ts +150 -0
- package/src/body/commands.ts +191 -0
- package/src/body/document.ts +388 -0
- package/src/body/insert.tsx +301 -0
- package/src/body/nodes.ts +287 -0
- package/src/body/reveal.ts +93 -0
- package/src/body/scroll.ts +53 -0
- package/src/body/settings.tsx +510 -0
- package/src/body/shortcuts.ts +31 -0
- package/src/body/table.ts +192 -0
- package/src/body/ui.ts +77 -0
- package/src/body/views.tsx +268 -0
- package/src/build.ts +6 -0
- package/src/cloud/CloudGate.tsx +245 -0
- package/src/cloud/access.ts +52 -0
- package/src/cloud/changes.tsx +474 -0
- package/src/cloud/connection.ts +281 -0
- package/src/cloud/editor.tsx +250 -0
- package/src/cloud/session.ts +289 -0
- package/src/cloud/storage.ts +212 -0
- package/src/editor/Field.tsx +182 -0
- package/src/editor/PagePicker.tsx +102 -0
- package/src/editor/arrange.ts +98 -0
- package/src/editor/context.tsx +31 -0
- package/src/editor/copy.ts +30 -0
- package/src/editor/reveal.ts +38 -0
- package/src/editor/target.ts +104 -0
- package/src/editor/values.ts +71 -0
- package/src/github/GitHubGate.tsx +298 -0
- package/src/github/api.ts +81 -0
- package/src/github/cache.ts +64 -0
- package/src/github/session.ts +146 -0
- package/src/index.ts +10 -0
- package/src/media/MediaPicker.tsx +302 -0
- package/src/media/file-icon.ts +17 -0
- package/src/media/formats.ts +262 -0
- package/src/media/hygiene.ts +220 -0
- package/src/media/upload.ts +47 -0
- package/src/mount.tsx +20 -0
- package/src/schedule/ScheduleDialog.tsx +303 -0
- package/src/schedule/ScheduleSummary.tsx +59 -0
- package/src/schedule/ScheduledView.tsx +294 -0
- package/src/schedule/cloud.ts +66 -0
- package/src/schedule/now.ts +18 -0
- package/src/schedule/times.ts +122 -0
- package/src/screens/EntryEditor.tsx +1817 -0
- package/src/screens/EntryList.tsx +272 -0
- package/src/screens/Home.tsx +131 -0
- package/src/screens/ListPane.tsx +477 -0
- package/src/screens/MediaBrowser.tsx +253 -0
- package/src/screens/NotFound.tsx +19 -0
- package/src/screens/PageTree.tsx +738 -0
- package/src/screens/Redirects.tsx +522 -0
- package/src/screens/Unavailable.tsx +27 -0
- package/src/screens/status.tsx +104 -0
- package/src/studio.css +168 -0
- package/src/types.ts +82 -0
- package/src/widgets/basic.tsx +315 -0
- package/src/widgets/blank-date.ts +32 -0
- package/src/widgets/crops.tsx +399 -0
- package/src/widgets/focal-point.tsx +240 -0
- package/src/widgets/geo-map.tsx +160 -0
- package/src/widgets/geo.tsx +170 -0
- package/src/widgets/group.tsx +827 -0
- package/src/widgets/icon.tsx +47 -0
- package/src/widgets/image.tsx +407 -0
- package/src/widgets/markdown-lazy.tsx +22 -0
- package/src/widgets/markdown.tsx +267 -0
- package/src/widgets/reference.tsx +196 -0
- package/src/widgets/registry.ts +104 -0
- package/src/widgets/special.tsx +290 -0
- package/src/widgets/union.tsx +233 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { A11yNote } from '@vespercms/core';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
/** A note's words: what it's about, the problem, and why it matters (spec §6.18). */
|
|
4
|
+
export declare function NoteText({ note }: {
|
|
5
|
+
note: A11yNote;
|
|
6
|
+
}): import("react").JSX.Element;
|
|
7
|
+
/**
|
|
8
|
+
* Accessibility notes under the field they're about. Text, never a coloured
|
|
9
|
+
* badge (spec §10.4): the small warning mark is the only colour, and the
|
|
10
|
+
* words say what it is. The list is part of the control's description.
|
|
11
|
+
*/
|
|
12
|
+
export declare function FieldNotes({ id, notes }: {
|
|
13
|
+
id: string;
|
|
14
|
+
notes: readonly A11yNote[];
|
|
15
|
+
}): import("react").JSX.Element;
|
|
16
|
+
/**
|
|
17
|
+
* One note the studio writes itself, not from a rule (a replaced image's alt
|
|
18
|
+
* text), in the same words and mark as the rules' notes beside a field.
|
|
19
|
+
*/
|
|
20
|
+
export declare function FieldNote({ id, children }: {
|
|
21
|
+
id: string;
|
|
22
|
+
children: ReactNode;
|
|
23
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { A11yNote } from '@vespercms/core';
|
|
2
|
+
/** The notes about one field (or the body), under its name. */
|
|
3
|
+
export type NoteGroup = {
|
|
4
|
+
key: string;
|
|
5
|
+
label: string;
|
|
6
|
+
notes: A11yNote[];
|
|
7
|
+
};
|
|
8
|
+
/** "2 accessibility notes", and how many refuse a save under the site's gate. */
|
|
9
|
+
export declare function notesCount(notes: number, blocking: number): string;
|
|
10
|
+
/**
|
|
11
|
+
* Every accessibility note on the entry (spec §6.18), opened from the count
|
|
12
|
+
* in the top bar: grouped under each field's name in form order, each with
|
|
13
|
+
* why it matters and "Go to field". A modal drawer: focus moves in, Escape
|
|
14
|
+
* closes it, and focus returns to the count.
|
|
15
|
+
*/
|
|
16
|
+
export declare function NotesDrawer({ isOpen, onOpenChange, groups, isBlocking, onGo, }: {
|
|
17
|
+
isOpen: boolean;
|
|
18
|
+
onOpenChange: (open: boolean) => void;
|
|
19
|
+
groups: readonly NoteGroup[];
|
|
20
|
+
isBlocking: (note: A11yNote) => boolean;
|
|
21
|
+
/** Closes the drawer and takes focus to the note's field. */
|
|
22
|
+
onGo: (note: A11yNote) => void;
|
|
23
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type A11yNote, type BodyFormat, type CollectionManifest, type DataObject, type Manifest, type PdfTarget } from '@vespercms/core';
|
|
2
|
+
export type EntryNotes = {
|
|
3
|
+
/** Field notes in form order, then the body's, then the PDFs'. */
|
|
4
|
+
notes: A11yNote[];
|
|
5
|
+
/** PDFs the entry points at. */
|
|
6
|
+
pdfs: PdfTarget[];
|
|
7
|
+
};
|
|
8
|
+
export type EntryNotesResult = EntryNotes & {
|
|
9
|
+
/** Checks the current values now, without the pause (for a save). PDFs keep their last result. */
|
|
10
|
+
recheck: () => Promise<A11yNote[]>;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* The entry's accessibility notes (spec §6.18, layer 1), checked a moment
|
|
14
|
+
* after typing stops, the same pause as the body's validation. PDFs are read
|
|
15
|
+
* with PDF.js, and their notes join when they have been.
|
|
16
|
+
*/
|
|
17
|
+
export declare function useEntryNotes(options: {
|
|
18
|
+
manifest: Manifest;
|
|
19
|
+
collection: CollectionManifest;
|
|
20
|
+
values: DataObject;
|
|
21
|
+
/** The body without its leading line breaks, as the body editor has it. */
|
|
22
|
+
body: string | undefined;
|
|
23
|
+
format: BodyFormat;
|
|
24
|
+
/** The entry's file, which relative PDF paths are resolved against. */
|
|
25
|
+
entryPath: string;
|
|
26
|
+
/** Where the studio reads a site file from. */
|
|
27
|
+
fileUrl: (path: string) => Promise<string>;
|
|
28
|
+
}): EntryNotesResult;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { type IconName, type IconNode } from '@vespercms/ui';
|
|
2
|
+
import { type ReactNode, type Ref, type RefObject, type UIEvent } from 'react';
|
|
3
|
+
export type ScreenProps = {
|
|
4
|
+
/** The screen's one `h1`, and the start of the page title. */
|
|
5
|
+
title: string;
|
|
6
|
+
/** Visually hide the `h1` when the screen shows its title another way (the editor's title field). */
|
|
7
|
+
hideTitle?: boolean;
|
|
8
|
+
/** Replaces the top bar's middle and right side (the editor's bar, spec §10.3). */
|
|
9
|
+
bar?: ReactNode;
|
|
10
|
+
/** The accent's wash at the top of a welcoming screen: home and empty states, never a form. */
|
|
11
|
+
afterglow?: boolean;
|
|
12
|
+
/** Line the heading up with the editor's 720px column. */
|
|
13
|
+
column?: boolean;
|
|
14
|
+
/** An icon before the heading: a collection's. */
|
|
15
|
+
icon?: {
|
|
16
|
+
node: IconNode;
|
|
17
|
+
} | {
|
|
18
|
+
name: IconName;
|
|
19
|
+
};
|
|
20
|
+
children: ReactNode;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Every screen's frame: the skip link, the top bar, and `<main>` with one
|
|
24
|
+
* `h1` (spec §10.6). After an in-app navigation, focus moves to the new
|
|
25
|
+
* screen's heading, so keyboard and screen-reader users land on the content
|
|
26
|
+
* they asked for instead of at the top of the page.
|
|
27
|
+
*
|
|
28
|
+
* Inside the pane shell (app/panes.tsx) a screen is the deepest pane
|
|
29
|
+
* instead: its heading and bar head the pane, and it scrolls on its own,
|
|
30
|
+
* beneath them.
|
|
31
|
+
*/
|
|
32
|
+
export declare function Screen({ title, hideTitle, bar, afterglow, column, icon, children, }: ScreenProps): import("react").JSX.Element;
|
|
33
|
+
/**
|
|
34
|
+
* The pane, or the screen, that leads names the browser tab, and takes focus
|
|
35
|
+
* after an in-app navigation (spec §10.6). Among panes that's the deepest.
|
|
36
|
+
*/
|
|
37
|
+
export declare function useLeadHeading(title: string, heading: RefObject<HTMLElement | null>): void;
|
|
38
|
+
/**
|
|
39
|
+
* An element's width or height in pixels, kept current as it wraps or the
|
|
40
|
+
* window changes: give it the returned ref. A callback ref, never a ref
|
|
41
|
+
* object, because what's measured may be replaced or come and go: the top
|
|
42
|
+
* bar among panes leaves as the window narrows and comes back new as it
|
|
43
|
+
* widens, and a ref object went on measuring the bar that left, at 0, so
|
|
44
|
+
* every pane's header sat beneath the new one. The editor's bar moves from
|
|
45
|
+
* the top bar into a pane's header the same way.
|
|
46
|
+
*/
|
|
47
|
+
export declare function useMeasure(side: 'width' | 'height', fallback: number): [(element: HTMLElement | null) => void, number];
|
|
48
|
+
/**
|
|
49
|
+
* A pane's frame: a landmark named by its heading, a header with the heading,
|
|
50
|
+
* the pane's actions and its collapse button (and the list's tools, as
|
|
51
|
+
* `toolbar`), then the pane's body. The deepest pane is the page's `main`,
|
|
52
|
+
* with its `h1`; the others are navigation, or a region, with `h2`s. The
|
|
53
|
+
* element stays the same as a pane's role changes, so what's in it isn't
|
|
54
|
+
* drawn afresh when an entry opens beside it.
|
|
55
|
+
*
|
|
56
|
+
* The frame is the pane's scroller, and it starts at the window's top: its
|
|
57
|
+
* body scrolls beneath its own header and the top bar, which are glass, so
|
|
58
|
+
* the content stays present beneath what floats (DECISIONS.md, "Panes scroll
|
|
59
|
+
* beneath glass"). Its scroll padding keeps a focused control clear of both.
|
|
60
|
+
*/
|
|
61
|
+
export declare function PaneFrame({ title, headingRef, hideTitle, icon, actions, toolbar, scrollRef, onScroll, className, children, }: {
|
|
62
|
+
title: string;
|
|
63
|
+
headingRef: RefObject<HTMLHeadingElement | null>;
|
|
64
|
+
hideTitle?: boolean;
|
|
65
|
+
icon?: {
|
|
66
|
+
node: IconNode;
|
|
67
|
+
} | {
|
|
68
|
+
name: IconName;
|
|
69
|
+
} | undefined;
|
|
70
|
+
actions?: ReactNode;
|
|
71
|
+
/** Below the heading, in the header that stays put: the list's search, Sort and Show. */
|
|
72
|
+
toolbar?: ReactNode;
|
|
73
|
+
scrollRef?: RefObject<HTMLDivElement | null>;
|
|
74
|
+
onScroll?: (event: UIEvent<HTMLDivElement>) => void;
|
|
75
|
+
className?: string | false | undefined;
|
|
76
|
+
children: ReactNode;
|
|
77
|
+
}): import("react").JSX.Element;
|
|
78
|
+
/**
|
|
79
|
+
* The skip link and the top bar. One screen at a time, it holds the screen's
|
|
80
|
+
* bar (the menus, or the editor's own); among panes it spans the full width
|
|
81
|
+
* and holds what's the person's, since the structure pane holds the site's.
|
|
82
|
+
*/
|
|
83
|
+
export declare function StudioHeader({ bar, headerRef, homeLink, }: {
|
|
84
|
+
bar?: ReactNode;
|
|
85
|
+
headerRef?: Ref<HTMLElement>;
|
|
86
|
+
/** False drops the site's name, the link home, on a narrow screen (the editor's bar). */
|
|
87
|
+
homeLink?: boolean;
|
|
88
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The user menu at the end of the top bar (spec §10.3): who is signed in and
|
|
3
|
+
* the way out in GitHub mode and the cloud (spec §6.9), and Appearance in
|
|
4
|
+
* every mode, local mode included, named by git's user there (DECISIONS.md,
|
|
5
|
+
* "Appearance is in the user menu, and local mode has a user menu").
|
|
6
|
+
*/
|
|
7
|
+
export declare function UserMenu(): import("react").JSX.Element;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { CollectionSummary, EntryDocument, EntrySummary, MediaItem, MoveRequest, MoveResult, PageLink, ScheduledChange, PageTree, RedirectsDocument, ReorderEntryRequest, ReorderEntryResult, ReorderRequest, ReorderResult, SaveRedirectsRequest, SaveRedirectsResult, SaveRequest, SaveResponse, UploadResponse } from '@vespercms/core';
|
|
2
|
+
/**
|
|
3
|
+
* Everything the studio needs from a storage back end. Local mode talks to
|
|
4
|
+
* the dev middleware; GitHub and cloud modes (Phases 3 and 4) implement the
|
|
5
|
+
* same interface, so screens never know which mode they're in.
|
|
6
|
+
*/
|
|
7
|
+
export interface StudioApi {
|
|
8
|
+
summary(): Promise<CollectionSummary[]>;
|
|
9
|
+
listEntries(collection: string): Promise<EntrySummary[]>;
|
|
10
|
+
readEntry(collection: string, id: string): Promise<EntryDocument>;
|
|
11
|
+
saveEntry(request: SaveRequest): Promise<SaveResponse>;
|
|
12
|
+
deleteEntry(collection: string, id: string, version: string): Promise<SaveResponse>;
|
|
13
|
+
listMedia(): Promise<MediaItem[]>;
|
|
14
|
+
/**
|
|
15
|
+
* Stores an upload. `withNextSave`: where saving publishes, the file waits
|
|
16
|
+
* and goes out with the next save, so an entry and its image are one
|
|
17
|
+
* commit (spec §6.8). Local mode writes it at once either way.
|
|
18
|
+
*/
|
|
19
|
+
upload(file: Blob, name: string, folder: string, options?: {
|
|
20
|
+
withNextSave?: boolean;
|
|
21
|
+
}): Promise<UploadResponse>;
|
|
22
|
+
deleteMedia(path: string): Promise<SaveResponse>;
|
|
23
|
+
/** Site-relative paths of the Markdoc and Markdown files a `{% partial %}` can point at. */
|
|
24
|
+
listPartials(): Promise<string[]>;
|
|
25
|
+
/**
|
|
26
|
+
* A URL the studio can show a file from, given its site-relative path.
|
|
27
|
+
* Asynchronous: GitHub mode fetches the blob and hands back an object URL.
|
|
28
|
+
*/
|
|
29
|
+
fileUrl(path: string): Promise<string>;
|
|
30
|
+
/** Every page with a URL, in every collection, for the link picker (spec §6.15.6). */
|
|
31
|
+
listPages(): Promise<PageLink[]>;
|
|
32
|
+
/** Every change still to come in the site's scheduled collections, soonest first (spec §6.17). */
|
|
33
|
+
listScheduled(): Promise<ScheduledChange[]>;
|
|
34
|
+
/** A tree collection's outline (spec §6.15.2). */
|
|
35
|
+
pageTree(collection: string): Promise<PageTree>;
|
|
36
|
+
/** Moves a page and everything under it; `dryRun` only describes what would happen. */
|
|
37
|
+
movePage(request: MoveRequest, options?: {
|
|
38
|
+
dryRun?: boolean;
|
|
39
|
+
}): Promise<MoveResult>;
|
|
40
|
+
reorderPage(request: ReorderRequest): Promise<ReorderResult>;
|
|
41
|
+
/** Puts an entry of a collection with `orderBy` in a new place, by writing its order numbers. */
|
|
42
|
+
reorderEntry(request: ReorderEntryRequest): Promise<ReorderEntryResult>;
|
|
43
|
+
/** Creates the missing section page of a folder in the tree. */
|
|
44
|
+
createSection(collection: string, path: string): Promise<SaveResponse>;
|
|
45
|
+
readRedirects(): Promise<RedirectsDocument>;
|
|
46
|
+
saveRedirects(request: SaveRedirectsRequest): Promise<SaveRedirectsResult>;
|
|
47
|
+
/**
|
|
48
|
+
* Whether Save publishes (GitHub and cloud modes) or only writes the file on
|
|
49
|
+
* this computer (local mode), where the site's publish gate can be saved past.
|
|
50
|
+
*/
|
|
51
|
+
publishesOnSave(): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Local mode only: who is editing, from git's `user.name` on this computer,
|
|
54
|
+
* for the user menu (DECISIONS.md, "Appearance is in the user menu").
|
|
55
|
+
*/
|
|
56
|
+
person?(): Promise<{
|
|
57
|
+
name: string | null;
|
|
58
|
+
}>;
|
|
59
|
+
}
|
|
60
|
+
export declare class ApiError extends Error {
|
|
61
|
+
readonly status: number;
|
|
62
|
+
constructor(status: number, message: string);
|
|
63
|
+
}
|
|
64
|
+
/** The header every studio request carries (spec §6.7). */
|
|
65
|
+
export declare const STUDIO_HEADER = "X-Vesper";
|
|
66
|
+
/**
|
|
67
|
+
* The local-mode client (spec §6.7). Every request carries the `X-Vesper`
|
|
68
|
+
* header: the dev middleware refuses requests without it, so another site
|
|
69
|
+
* open in the same browser can't reach it with a simple cross-origin request.
|
|
70
|
+
*
|
|
71
|
+
* Saves answer with a `SaveResponse` even when they fail (a conflict or an
|
|
72
|
+
* invalid value is an answer, not an error). Anything else that isn't 2xx
|
|
73
|
+
* throws an `ApiError`.
|
|
74
|
+
*/
|
|
75
|
+
export declare function createLocalApi(base: string, fetcher?: typeof fetch): StudioApi;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type Appearance = 'system' | 'light' | 'dark';
|
|
2
|
+
export declare const APPEARANCE_KEY = "vesper:appearance";
|
|
3
|
+
export declare const APPEARANCES: readonly {
|
|
4
|
+
id: Appearance;
|
|
5
|
+
label: string;
|
|
6
|
+
}[];
|
|
7
|
+
export declare function readAppearance(): Appearance;
|
|
8
|
+
export declare function applyAppearance(appearance: Appearance): void;
|
|
9
|
+
export declare function saveAppearance(appearance: Appearance): void;
|
|
10
|
+
export declare function useAppearance(): [Appearance, (appearance: Appearance) => void];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type Manifest, type StorageAdapter, type UrlEntry } from '@vespercms/core';
|
|
2
|
+
import { type StudioApi } from './api.ts';
|
|
3
|
+
export type BrowserApiOptions = {
|
|
4
|
+
storage: StorageAdapter;
|
|
5
|
+
manifest: Manifest;
|
|
6
|
+
/** The site's schemas built for the browser. */
|
|
7
|
+
schemas: string;
|
|
8
|
+
loadMdxProps: () => Promise<Readonly<Record<string, unknown>>>;
|
|
9
|
+
loadUrlFunctions?: () => Promise<Readonly<Record<string, (entry: UrlEntry) => unknown>>>;
|
|
10
|
+
/** The site's static routes at build, for collision checks. */
|
|
11
|
+
routes?: readonly (readonly [string, string])[];
|
|
12
|
+
/** Whether a save publishes (GitHub mode) or keeps a draft (the cloud). */
|
|
13
|
+
publishesOnSave: boolean;
|
|
14
|
+
/** The storage's own errors in the studio's terms. */
|
|
15
|
+
mapError: (error: unknown) => unknown;
|
|
16
|
+
};
|
|
17
|
+
export declare function createBrowserApi(options: BrowserApiOptions): StudioApi;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CollectionManifest } from '@vespercms/core';
|
|
2
|
+
import type { IconName, IconNode } from '@vespercms/ui';
|
|
3
|
+
/**
|
|
4
|
+
* A collection's icon: the Lucide icon vesper.config.ts names for it,
|
|
5
|
+
* resolved into the manifest at build, or a default by kind (DECISIONS.md,
|
|
6
|
+
* "A collection's icon is named in vesper.config.ts").
|
|
7
|
+
*/
|
|
8
|
+
export declare function collectionIcon(collection: CollectionManifest): {
|
|
9
|
+
node: IconNode;
|
|
10
|
+
} | {
|
|
11
|
+
name: IconName;
|
|
12
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { CollectionManifest, Manifest } from '@vespercms/core';
|
|
2
|
+
import type { Account, WidgetComponent } from '../types.ts';
|
|
3
|
+
import type { CloudConnection } from '../cloud/connection.ts';
|
|
4
|
+
import type { StudioApi } from './api.ts';
|
|
5
|
+
export type Studio = {
|
|
6
|
+
manifest: Manifest;
|
|
7
|
+
api: StudioApi;
|
|
8
|
+
/** Custom widgets, as lazy components: each loads the first time a field uses it. */
|
|
9
|
+
widgets: Record<string, WidgetComponent>;
|
|
10
|
+
/** Loads declared MDX components' Zod props schemas, from vesper.config.ts (spec §6.5.2). */
|
|
11
|
+
loadMdxProps: () => Promise<Readonly<Record<string, unknown>>>;
|
|
12
|
+
siteName: string;
|
|
13
|
+
siteUrl: string | undefined;
|
|
14
|
+
collection: (name: string) => CollectionManifest | undefined;
|
|
15
|
+
/** The signed-in editor, in GitHub mode or the cloud. */
|
|
16
|
+
account?: Account;
|
|
17
|
+
/** The cloud, when the studio is connected to it. Absent, every cloud feature is absent (spec §6.9). */
|
|
18
|
+
cloud?: CloudConnection;
|
|
19
|
+
};
|
|
20
|
+
/** The name the studio shows when the site gives none: Vesper's own, set lowercase as its wordmark. */
|
|
21
|
+
export declare const VESPER_NAME = "Vesper";
|
|
22
|
+
export declare const StudioContext: import("react").Context<Studio | null>;
|
|
23
|
+
export declare function useStudio(): Studio;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function entriesChanged(collection: string): void;
|
|
2
|
+
/**
|
|
3
|
+
* Entries rewritten from outside their editor: a move in the list writes
|
|
4
|
+
* order numbers into them, and an editor open on one reads it again, or its
|
|
5
|
+
* next save would find a version it didn't start from.
|
|
6
|
+
*/
|
|
7
|
+
export declare function entriesRewritten(collection: string, ids: readonly string[]): void;
|
|
8
|
+
/** Calls `listener` with the IDs whenever entries in `collection` are rewritten; returns the way to stop. */
|
|
9
|
+
export declare function onEntriesRewritten(collection: string, listener: (ids: readonly string[]) => void): () => void;
|
|
10
|
+
/** Calls `listener` after each save in `collection`; returns the way to stop. */
|
|
11
|
+
export declare function onEntriesChanged(collection: string, listener: () => void): () => void;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A URL the studio can show a site file from, or `''` until it's ready. In
|
|
3
|
+
* local mode it's the dev API's `/file`; in GitHub mode an object URL for
|
|
4
|
+
* the blob, since a private repository's files have no address a browser
|
|
5
|
+
* can load without the token.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useFileUrl(path: string | null): string;
|
|
8
|
+
/** A site image, shown once its URL is ready. Decorative: whatever lists it names it. */
|
|
9
|
+
export declare function FileImage({ path, className, loading, }: {
|
|
10
|
+
path: string;
|
|
11
|
+
className?: string;
|
|
12
|
+
loading?: 'lazy' | 'eager';
|
|
13
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** "just now", "5 minutes ago", "yesterday", "3 weeks ago". */
|
|
2
|
+
export declare function formatRelative(iso: string, now?: Date, locale?: string): string;
|
|
3
|
+
/** "1 entry", "12 entries". */
|
|
4
|
+
export declare function formatCount(count: number, singular: string, plural: string, locale?: string): string;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type KeyValueStore<T> = {
|
|
2
|
+
get(key: string): Promise<T | undefined>;
|
|
3
|
+
put(key: string, value: T): Promise<void>;
|
|
4
|
+
delete(key: string): Promise<void>;
|
|
5
|
+
keys(): Promise<string[]>;
|
|
6
|
+
};
|
|
7
|
+
export declare function keyValueStore<T>(database: string, store: string): KeyValueStore<T>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type Load<T> = {
|
|
2
|
+
state: 'loading';
|
|
3
|
+
} | {
|
|
4
|
+
state: 'ready';
|
|
5
|
+
value: T;
|
|
6
|
+
} | {
|
|
7
|
+
state: 'failed';
|
|
8
|
+
message: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Loads data for a screen. The loader runs again when `key` changes, or when
|
|
12
|
+
* `reload()` is called (after a save, for example); a reload keeps showing
|
|
13
|
+
* the old value until the new one arrives. A response that arrives after
|
|
14
|
+
* the key moved on is dropped.
|
|
15
|
+
*/
|
|
16
|
+
export declare function useLoad<T>(loader: () => Promise<T>, key?: string): [Load<T>, () => void];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Where a screen sits among the panes (app/panes.tsx), or null one screen at a time. */
|
|
2
|
+
export type PaneInfo = {
|
|
3
|
+
/**
|
|
4
|
+
* `main` for the deepest pane, `nav` for the ones that lead to it, and
|
|
5
|
+
* `region` for a pane beside the deepest that leads nowhere (the cloud's
|
|
6
|
+
* waiting drafts on Home).
|
|
7
|
+
*/
|
|
8
|
+
landmark: 'main' | 'nav' | 'region';
|
|
9
|
+
/** The deepest pane's title is the page's `h1`; the others are `h2`s. */
|
|
10
|
+
level: 1 | 2;
|
|
11
|
+
/** The deepest pane takes focus after a navigation, and names the browser tab. */
|
|
12
|
+
focusTarget: boolean;
|
|
13
|
+
/** How wide it is: the narrow panes get tighter padding and a smaller heading. */
|
|
14
|
+
width: 'structure' | 'list' | 'flex';
|
|
15
|
+
/** Folds the pane into a strip, when people may: every pane but the deepest. */
|
|
16
|
+
onCollapse?: () => void;
|
|
17
|
+
};
|
|
18
|
+
export declare const PaneContext: import("react").Context<PaneInfo | null>;
|
|
19
|
+
export declare function usePane(): PaneInfo | null;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Studio } from './context.tsx';
|
|
2
|
+
import { type Route } from './router.ts';
|
|
3
|
+
/** Wide enough for panes: below it, one screen at a time. */
|
|
4
|
+
export declare const PANES = "(min-width: 48rem)";
|
|
5
|
+
/**
|
|
6
|
+
* The studio's screens. Wide, they're panes; narrow, the deepest pane alone
|
|
7
|
+
* is the screen. Both are the same tree, so crossing the width keeps the
|
|
8
|
+
* open entry as it is, unsaved changes included.
|
|
9
|
+
*/
|
|
10
|
+
export declare function PaneShell({ route, studio, wide, }: {
|
|
11
|
+
route: Route;
|
|
12
|
+
studio: Studio;
|
|
13
|
+
wide: boolean;
|
|
14
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export type Route = {
|
|
2
|
+
screen: 'home';
|
|
3
|
+
} | {
|
|
4
|
+
screen: 'list';
|
|
5
|
+
collection: string;
|
|
6
|
+
} | {
|
|
7
|
+
screen: 'edit';
|
|
8
|
+
collection: string;
|
|
9
|
+
id: string;
|
|
10
|
+
} | {
|
|
11
|
+
screen: 'new';
|
|
12
|
+
collection: string;
|
|
13
|
+
parent?: string;
|
|
14
|
+
}
|
|
15
|
+
/** A new entry that starts as a copy of another (Duplicate, spec §10.3). */
|
|
16
|
+
| {
|
|
17
|
+
screen: 'copy';
|
|
18
|
+
collection: string;
|
|
19
|
+
id: string;
|
|
20
|
+
} | {
|
|
21
|
+
screen: 'media';
|
|
22
|
+
} | {
|
|
23
|
+
screen: 'redirects';
|
|
24
|
+
}
|
|
25
|
+
/** Every change still to come across the site (spec §6.17). */
|
|
26
|
+
| {
|
|
27
|
+
screen: 'scheduled';
|
|
28
|
+
}
|
|
29
|
+
/** Home with the cloud's Changes open: review emails link here. Home alone elsewhere. */
|
|
30
|
+
| {
|
|
31
|
+
screen: 'changes';
|
|
32
|
+
} | {
|
|
33
|
+
screen: 'not-found';
|
|
34
|
+
path: string;
|
|
35
|
+
};
|
|
36
|
+
export type KnownRoute = Exclude<Route, {
|
|
37
|
+
screen: 'not-found';
|
|
38
|
+
}>;
|
|
39
|
+
export declare function parseRoute(hash: string): Route;
|
|
40
|
+
export declare function hrefFor(route: KnownRoute): string;
|
|
41
|
+
/** Goes to a route. `replace` swaps the current history entry (after creating an entry, say). */
|
|
42
|
+
export declare function navigate(route: KnownRoute, options?: {
|
|
43
|
+
replace?: boolean;
|
|
44
|
+
}): void;
|
|
45
|
+
export declare function setLeaveGuard(hasUnsavedChanges: () => boolean): () => void;
|
|
46
|
+
/** Whether the open screen has unsaved changes. */
|
|
47
|
+
export declare function hasUnsavedChanges(): boolean;
|
|
48
|
+
export type RouterState = {
|
|
49
|
+
route: Route;
|
|
50
|
+
/** A navigation held back because the open screen has unsaved changes. */
|
|
51
|
+
pending: string | null;
|
|
52
|
+
/** Leave anyway, discarding the changes. */
|
|
53
|
+
leave: () => void;
|
|
54
|
+
/** Stay on the current screen. */
|
|
55
|
+
stay: () => void;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* The current route. Every in-app navigation is a hash change, so this is
|
|
59
|
+
* also where unsaved changes are protected: when the guard says so, the
|
|
60
|
+
* hash is put back and the navigation waits for `leave()` or `stay()`.
|
|
61
|
+
*/
|
|
62
|
+
export declare function useRouter(): RouterState;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type Editor } from '@tiptap/core';
|
|
2
|
+
import { type A11yNote, type BodyFormat, type BodyIssue } from '@vespercms/core';
|
|
3
|
+
import { type RefObject } from 'react';
|
|
4
|
+
export type BodyEditorProps = {
|
|
5
|
+
/** The body text, LF line endings, without the line breaks after the frontmatter. */
|
|
6
|
+
value: string;
|
|
7
|
+
onChange: (value: string) => void;
|
|
8
|
+
format: BodyFormat;
|
|
9
|
+
disabled: boolean;
|
|
10
|
+
/** The entry's file, so images are stored relative to it. */
|
|
11
|
+
entryPath: string;
|
|
12
|
+
/** Where images uploaded into the body go. */
|
|
13
|
+
imageFolder: string;
|
|
14
|
+
/** Files a Markdoc partial can point at, once loaded (Markdoc bodies only). */
|
|
15
|
+
partials?: readonly string[] | null;
|
|
16
|
+
/** Problems in the whole body, from the last check: listed under the source view. */
|
|
17
|
+
issues?: readonly BodyIssue[];
|
|
18
|
+
/** Accessibility notes about the body (spec §6.18), listed under it. */
|
|
19
|
+
notes?: readonly A11yNote[];
|
|
20
|
+
/** Filled with the editor's actions, for the entry's notes drawer. */
|
|
21
|
+
apiRef?: RefObject<BodyApi | null>;
|
|
22
|
+
/** The level the body's top headings should have (the collection's `headingStart`); 2 when absent. */
|
|
23
|
+
headingStart?: number;
|
|
24
|
+
};
|
|
25
|
+
/** What the rest of the entry editor can ask of the body editor. */
|
|
26
|
+
export type BodyApi = {
|
|
27
|
+
/** Puts the cursor on the place a note points at, in whichever view is open, and focuses it. */
|
|
28
|
+
reveal: (note: A11yNote) => void;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* The body editor (spec §6.5): a writing view and a source view. The writing
|
|
32
|
+
* view owns only the blocks it can show faithfully, and saves splice changed
|
|
33
|
+
* blocks into the original text, so untouched blocks never change. Markdoc
|
|
34
|
+
* tags and declared MDX components are blocks with settings (spec §6.5.1,
|
|
35
|
+
* §6.5.2); everything else it can't show is a protected source block.
|
|
36
|
+
*/
|
|
37
|
+
export declare function BodyEditor(props: BodyEditorProps): import("react").JSX.Element;
|
|
38
|
+
export declare function LinkDialog({ editor, isOpen, onOpenChange, }: {
|
|
39
|
+
editor: Editor;
|
|
40
|
+
isOpen: boolean;
|
|
41
|
+
onOpenChange: (open: boolean) => void;
|
|
42
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type BodyFormat, type FieldModel, type Manifest } from '@vespercms/core';
|
|
2
|
+
export type BlockShape = 'container' | 'card' | 'inline';
|
|
3
|
+
export type BlockKind = {
|
|
4
|
+
/** `markdoc:callout`, `mdx:Callout`. */
|
|
5
|
+
key: string;
|
|
6
|
+
syntax: 'markdoc' | 'mdx';
|
|
7
|
+
name: string;
|
|
8
|
+
label: string;
|
|
9
|
+
summary?: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
/** How a new one is inserted at a block position, or null when it can only go inline. */
|
|
12
|
+
block: Exclude<BlockShape, 'inline'> | null;
|
|
13
|
+
/** Whether it can go inside a line of text. */
|
|
14
|
+
inline: boolean;
|
|
15
|
+
/** Written without content (`/%}`, `/>`). */
|
|
16
|
+
selfClosing: boolean;
|
|
17
|
+
/** Markdoc's allowed child node types (containers); absent means anything. */
|
|
18
|
+
children?: string[];
|
|
19
|
+
/** The settings form. */
|
|
20
|
+
fields: FieldModel[];
|
|
21
|
+
/** Attribute order, for placing new attributes and writing new tags. */
|
|
22
|
+
order: string[];
|
|
23
|
+
/** Built-in constructs the studio handles itself: partials, conditions and pipe tables. */
|
|
24
|
+
builtin?: 'partial' | 'if' | 'else' | 'table';
|
|
25
|
+
};
|
|
26
|
+
export type Catalog = {
|
|
27
|
+
format: BodyFormat;
|
|
28
|
+
kinds: Map<string, BlockKind>;
|
|
29
|
+
/** The kind for a tag or component name in this body's syntax. */
|
|
30
|
+
find: (syntax: 'markdoc' | 'mdx', name: string) => BlockKind | undefined;
|
|
31
|
+
};
|
|
32
|
+
export declare function catalogOf(manifest: Manifest, format: BodyFormat): Catalog;
|
|
33
|
+
/** Kinds a person can insert (built-in conditions are protected, so they aren't offered). */
|
|
34
|
+
/**
|
|
35
|
+
* A pipe table, insertable in every format (PLAN.md, call T4). It isn't one
|
|
36
|
+
* of the catalog's kinds, so Markdoc's own `{% table %}` is never taken for it.
|
|
37
|
+
*/
|
|
38
|
+
export declare const TABLE_KIND: BlockKind;
|
|
39
|
+
export declare function insertable(catalog: Catalog): BlockKind[];
|
|
40
|
+
/** A new tag's text in house style: attributes in schema order, empty and default values left out. */
|
|
41
|
+
export declare function newTagText(kind: BlockKind, attributes: Readonly<Record<string, unknown>>, shape: BlockShape, inner?: string): {
|
|
42
|
+
open: string;
|
|
43
|
+
close: string;
|
|
44
|
+
whole: string;
|
|
45
|
+
};
|
|
46
|
+
/** A friendly name for a tag nobody described: the humanized name, or the component's own. */
|
|
47
|
+
export declare function fallbackLabel(syntax: 'markdoc' | 'mdx', name: string): string;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type BodyFormat, type BodyIssue, type Manifest } from '@vespercms/core';
|
|
2
|
+
export type BodyChecks = {
|
|
3
|
+
/** Validates a whole body, or one block's text, as the site's build would. */
|
|
4
|
+
validate: (text: string) => Promise<BodyIssue[]>;
|
|
5
|
+
/** The same, synchronously, for Markdoc (MDX props schemas load on first use). */
|
|
6
|
+
validateSync: (text: string) => BodyIssue[] | null;
|
|
7
|
+
};
|
|
8
|
+
export declare function bodyChecks(options: {
|
|
9
|
+
manifest: Manifest;
|
|
10
|
+
format: BodyFormat;
|
|
11
|
+
/** Declared MDX components' Zod props schemas, loaded when first needed. */
|
|
12
|
+
loadMdxProps: () => Promise<Readonly<Record<string, unknown>>>;
|
|
13
|
+
partials: readonly string[] | null;
|
|
14
|
+
entryPath: string;
|
|
15
|
+
}): BodyChecks;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type InlineChip } from '@vespercms/core';
|
|
2
|
+
export declare function chipPlaceholder(source: string): string;
|
|
3
|
+
export declare function decodeHex(hex: string): string;
|
|
4
|
+
/** Text with every placeholder replaced by the chip source it holds. */
|
|
5
|
+
export declare function restoreChips(text: string): string;
|
|
6
|
+
/** A block's text with its chips (offsets relative to the text) replaced by placeholders. */
|
|
7
|
+
export declare function withPlaceholders(text: string, chips: readonly {
|
|
8
|
+
start: number;
|
|
9
|
+
end: number;
|
|
10
|
+
}[]): string;
|
|
11
|
+
/** True when the text holds a private-use character the placeholders rely on. */
|
|
12
|
+
export declare function hasPlaceholderCharacters(text: string): boolean;
|
|
13
|
+
export type TagValues = {
|
|
14
|
+
/** Attribute values the settings form can edit. */
|
|
15
|
+
values: Record<string, unknown>;
|
|
16
|
+
/** Attributes set by code (variables, functions, JSX expressions): shown, never edited. */
|
|
17
|
+
code: Record<string, string>;
|
|
18
|
+
};
|
|
19
|
+
/** A tag's attributes, read from its opening (Markdoc) or its opening or whole element (MDX). */
|
|
20
|
+
export declare function tagValues(syntax: 'markdoc' | 'mdx', text: string): TagValues;
|
|
21
|
+
export type ChipInfo = {
|
|
22
|
+
syntax: 'markdoc' | 'mdx';
|
|
23
|
+
kind: InlineChip['kind'];
|
|
24
|
+
name?: string;
|
|
25
|
+
/** For tags and components: the opening, the content between, and the closing. */
|
|
26
|
+
open?: string;
|
|
27
|
+
inner?: string;
|
|
28
|
+
close?: string;
|
|
29
|
+
};
|
|
30
|
+
/** What a chip's source is: its kind, name and parts. */
|
|
31
|
+
export declare function chipInfo(source: string): ChipInfo;
|