caracms 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +57 -2
- package/bin/caracms.mjs +174 -0
- package/bin/gate.mjs +275 -0
- package/bin/init.mjs +712 -0
- package/bin/media.mjs +662 -0
- package/bin/site-runner.mjs +61 -0
- package/bin/templates/Page.astro.txt +31 -0
- package/bin/templates/TextBlock.astro.txt +13 -0
- package/bin/templates/caracms.config.ts.txt +22 -0
- package/bin/templates/catch-all.astro.txt +25 -0
- package/bin/templates/health.ts.txt +6 -0
- package/bin/templates/railway.ts.txt +147 -0
- package/package.json +66 -4
- package/skills/caracms-adopt/SKILL.md +508 -0
- package/skills/caracms-adopt/look-same.mjs +957 -0
- package/skills/caracms-blocks/SKILL.md +376 -0
- package/skills/caracms-content/SKILL.md +201 -0
- package/skills/caracms-tina/SKILL.md +427 -0
- package/skills/caracms-tina/field-kinds.md +88 -0
- package/skills/caracms-tina/tina-to-caracms.mjs +1011 -0
- package/src/block-runs.ts +84 -0
- package/src/cards.ts +158 -0
- package/src/cli/schemas.ts +122 -0
- package/src/cli/site.ts +66 -0
- package/src/cli/validate.ts +471 -0
- package/src/code-routes-disk.ts +67 -0
- package/src/code-routes.ts +134 -0
- package/src/columns.ts +39 -0
- package/src/components/Block.astro +46 -0
- package/src/components/BlockRunTree.astro +45 -0
- package/src/components/Blocks.astro +139 -0
- package/src/components/Buttons.astro +116 -0
- package/src/components/Fonts.astro +14 -0
- package/src/components/Form.astro +221 -0
- package/src/components/Head.astro +62 -0
- package/src/components/Link.astro +68 -0
- package/src/components/Lockup.astro +116 -0
- package/src/components/Media.astro +124 -0
- package/src/components/MediaPlayer.astro +102 -0
- package/src/components/RenderDocument.astro +64 -0
- package/src/components/RichText.astro +59 -0
- package/src/components/Text.astro +81 -0
- package/src/components/attributes.ts +33 -0
- package/src/components/descriptor.ts +45 -0
- package/src/components/form-client.ts +182 -0
- package/src/components/media-player.ts +46 -0
- package/src/components/media-props.ts +35 -0
- package/src/components/sitemap.xml.ts +36 -0
- package/src/config.ts +825 -0
- package/src/content-schema.ts +166 -0
- package/src/content.ts +422 -0
- package/src/document.ts +579 -0
- package/src/editor/README.md +405 -0
- package/src/editor/addresses.ts +61 -0
- package/src/editor/brand.ts +118 -0
- package/src/editor/client/block-list/BlockList.tsx +342 -0
- package/src/editor/client/block-list/Picker.tsx +105 -0
- package/src/editor/client/block-list/UnknownBlock.tsx +119 -0
- package/src/editor/client/block-list/insert-points.ts +56 -0
- package/src/editor/client/block-list/link.ts +71 -0
- package/src/editor/client/block-list/reorder.ts +105 -0
- package/src/editor/client/block-list/summary.ts +118 -0
- package/src/editor/client/collections/CollectionGrid.tsx +143 -0
- package/src/editor/client/collections/CollectionTable.tsx +406 -0
- package/src/editor/client/collections/table.ts +270 -0
- package/src/editor/client/context.tsx +27 -0
- package/src/editor/client/documents/DocMenu.tsx +154 -0
- package/src/editor/client/documents/actions.ts +192 -0
- package/src/editor/client/documents/dialogs.tsx +687 -0
- package/src/editor/client/editor.ts +995 -0
- package/src/editor/client/fields/ButtonsField.tsx +87 -0
- package/src/editor/client/fields/DateField.tsx +200 -0
- package/src/editor/client/fields/FieldControl.tsx +61 -0
- package/src/editor/client/fields/FieldFrame.tsx +109 -0
- package/src/editor/client/fields/GroupField.tsx +113 -0
- package/src/editor/client/fields/HiddenToggle.tsx +51 -0
- package/src/editor/client/fields/LinkField.tsx +307 -0
- package/src/editor/client/fields/ListField.tsx +642 -0
- package/src/editor/client/fields/LockupField.tsx +365 -0
- package/src/editor/client/fields/MediaField.tsx +823 -0
- package/src/editor/client/fields/PageFields.tsx +82 -0
- package/src/editor/client/fields/ReferenceField.tsx +209 -0
- package/src/editor/client/fields/RichTextField.tsx +306 -0
- package/src/editor/client/fields/SelectField.tsx +63 -0
- package/src/editor/client/fields/SeoGroup.tsx +282 -0
- package/src/editor/client/fields/SimpleFields.tsx +89 -0
- package/src/editor/client/fields/TextField.tsx +51 -0
- package/src/editor/client/fields/date.ts +73 -0
- package/src/editor/client/fields/host.tsx +172 -0
- package/src/editor/client/fields/list-summary.ts +85 -0
- package/src/editor/client/fields/lockup-rules.ts +181 -0
- package/src/editor/client/fields/parts.tsx +458 -0
- package/src/editor/client/fields/rich-text-commands.ts +183 -0
- package/src/editor/client/fields/rich-text-doc.ts +156 -0
- package/src/editor/client/fields/rich-text-schema.ts +224 -0
- package/src/editor/client/fields/stale.ts +58 -0
- package/src/editor/client/inbox/InboxStage.tsx +272 -0
- package/src/editor/client/inbox/store.ts +311 -0
- package/src/editor/client/live/format.ts +77 -0
- package/src/editor/client/live/marks.tsx +90 -0
- package/src/editor/client/live/notices.tsx +213 -0
- package/src/editor/client/live/publish.tsx +617 -0
- package/src/editor/client/live/session.tsx +162 -0
- package/src/editor/client/main.tsx +12 -0
- package/src/editor/client/media/LibraryStage.tsx +75 -0
- package/src/editor/client/media/ReplaceDialog.tsx +355 -0
- package/src/editor/client/media/store.ts +618 -0
- package/src/editor/client/nav/DocRow.tsx +122 -0
- package/src/editor/client/nav/search.ts +71 -0
- package/src/editor/client/nav/tree.ts +93 -0
- package/src/editor/client/overlays/OverlayMount.tsx +26 -0
- package/src/editor/client/overlays/editor-marks.ts +159 -0
- package/src/editor/client/overlays/index.ts +50 -0
- package/src/editor/client/overlays/layer.ts +437 -0
- package/src/editor/client/overlays/overlay-css.ts +177 -0
- package/src/editor/client/overlays/rich-text-bar.ts +717 -0
- package/src/editor/client/pane/Pane.tsx +91 -0
- package/src/editor/client/pane/levels/BlockLevel.tsx +123 -0
- package/src/editor/client/pane/levels/CollectionLevel.tsx +115 -0
- package/src/editor/client/pane/levels/DocumentLevel.tsx +93 -0
- package/src/editor/client/pane/levels/DocumentsLevel.tsx +390 -0
- package/src/editor/client/pane/levels/FileLevel.tsx +132 -0
- package/src/editor/client/pane/levels/FormLevel.tsx +550 -0
- package/src/editor/client/pane/levels/MediaLevel.tsx +657 -0
- package/src/editor/client/pane/levels/SettingsM6.tsx +299 -0
- package/src/editor/client/pane/levels/SubmissionsLevel.tsx +185 -0
- package/src/editor/client/pane/parts.tsx +179 -0
- package/src/editor/client/pane/switcher.tsx +165 -0
- package/src/editor/client/preview/driver.ts +640 -0
- package/src/editor/client/preview/field-text.ts +71 -0
- package/src/editor/client/preview/follow-links.ts +234 -0
- package/src/editor/client/preview/layout.ts +37 -0
- package/src/editor/client/preview/link-target.ts +50 -0
- package/src/editor/client/preview/markers.ts +86 -0
- package/src/editor/client/preview/page-edit.ts +632 -0
- package/src/editor/client/preview/page-editor-registry.ts +63 -0
- package/src/editor/client/preview/page-editor.ts +235 -0
- package/src/editor/client/preview/render-sequencer.ts +113 -0
- package/src/editor/client/preview/selection.ts +116 -0
- package/src/editor/client/preview/warnings.ts +61 -0
- package/src/editor/client/shell/App.tsx +101 -0
- package/src/editor/client/shell/Bar.tsx +197 -0
- package/src/editor/client/shell/Brand.tsx +33 -0
- package/src/editor/client/shell/Icons.tsx +87 -0
- package/src/editor/client/shell/NarrowNote.tsx +47 -0
- package/src/editor/client/shell/Popovers.tsx +47 -0
- package/src/editor/client/shell/Stage.tsx +132 -0
- package/src/editor/client/shell/Toast.tsx +61 -0
- package/src/editor/client/state/document-store.ts +465 -0
- package/src/editor/client/state/keeper.ts +713 -0
- package/src/editor/client/state/live.ts +257 -0
- package/src/editor/client/state/schema.ts +42 -0
- package/src/editor/client/state/store.ts +39 -0
- package/src/editor/fonts/OFL-GeistMono.txt +93 -0
- package/src/editor/fonts/OFL-InstrumentSans.txt +93 -0
- package/src/editor/fonts/geist-mono-latin-ext-wght-normal.woff2 +0 -0
- package/src/editor/fonts/geist-mono-latin-wght-normal.woff2 +0 -0
- package/src/editor/fonts/instrument-sans-latin-ext-wght-normal.woff2 +0 -0
- package/src/editor/fonts/instrument-sans-latin-wght-normal.woff2 +0 -0
- package/src/editor/middleware.ts +62 -0
- package/src/editor/routes/_live.ts +26 -0
- package/src/editor/routes/admin.astro +80 -0
- package/src/editor/routes/create.ts +19 -0
- package/src/editor/routes/delete.ts +19 -0
- package/src/editor/routes/document.ts +39 -0
- package/src/editor/routes/documents.ts +30 -0
- package/src/editor/routes/github.ts +23 -0
- package/src/editor/routes/history.ts +9 -0
- package/src/editor/routes/lock.ts +9 -0
- package/src/editor/routes/login/assets.d.ts +10 -0
- package/src/editor/routes/login/login.ts +43 -0
- package/src/editor/routes/media.ts +16 -0
- package/src/editor/routes/move.ts +17 -0
- package/src/editor/routes/notice.ts +9 -0
- package/src/editor/routes/preview.astro +77 -0
- package/src/editor/routes/publish.ts +9 -0
- package/src/editor/routes/status.ts +9 -0
- package/src/editor/routes/submissions.ts +16 -0
- package/src/editor/routes/try-again.ts +9 -0
- package/src/editor/routes/write.ts +18 -0
- package/src/editor/server/admin-props.ts +151 -0
- package/src/editor/server/cards.ts +61 -0
- package/src/editor/server/create.ts +414 -0
- package/src/editor/server/drafts-store.ts +127 -0
- package/src/editor/server/media/alt.ts +107 -0
- package/src/editor/server/media/bucket.ts +295 -0
- package/src/editor/server/media/config.ts +78 -0
- package/src/editor/server/media/handler.ts +221 -0
- package/src/editor/server/media/library.ts +254 -0
- package/src/editor/server/media/memory.ts +184 -0
- package/src/editor/server/media/mux.ts +241 -0
- package/src/editor/server/media/sniff.ts +599 -0
- package/src/editor/server/media/upload.ts +175 -0
- package/src/editor/server/mode.ts +63 -0
- package/src/editor/server/move.ts +295 -0
- package/src/editor/server/render.tsx +9 -0
- package/src/editor/server/replace.ts +72 -0
- package/src/editor/server/settings.ts +35 -0
- package/src/editor/server/write.ts +366 -0
- package/src/editor/styles/editor.css +502 -0
- package/src/editor/styles/fonts.css +40 -0
- package/src/editor/styles/levels/README.md +4 -0
- package/src/editor/styles/levels/collections.css +99 -0
- package/src/editor/styles/levels/document-level.css +10 -0
- package/src/editor/styles/levels/documents.css +9 -0
- package/src/editor/styles/levels/fields.css +171 -0
- package/src/editor/styles/levels/files.css +95 -0
- package/src/editor/styles/levels/live.css +10 -0
- package/src/editor/styles/levels/m5a-documents.css +51 -0
- package/src/editor/styles/levels/m6.css +82 -0
- package/src/editor/styles/levels/media.css +175 -0
- package/src/editor/styles/levels/switcher.css +3 -0
- package/src/editor/styles/tokens.css +114 -0
- package/src/editor/tsconfig.json +16 -0
- package/src/editor/types.ts +881 -0
- package/src/editor/ui-state.ts +113 -0
- package/src/email.ts +67 -0
- package/src/fields.ts +1129 -0
- package/src/files-route.ts +201 -0
- package/src/files.ts +116 -0
- package/src/forms/email.ts +149 -0
- package/src/forms/endpoint.ts +347 -0
- package/src/forms/inbox.ts +273 -0
- package/src/forms/rate-limit.ts +130 -0
- package/src/forms/route.ts +24 -0
- package/src/forms/rules.ts +278 -0
- package/src/forms/store.ts +486 -0
- package/src/head.ts +125 -0
- package/src/index.ts +434 -0
- package/src/json-source.ts +116 -0
- package/src/links.ts +121 -0
- package/src/live/README.md +43 -0
- package/src/live/auth/allow-rules.ts +70 -0
- package/src/live/auth/allow.ts +128 -0
- package/src/live/auth/auth.ts +155 -0
- package/src/live/auth/email.ts +84 -0
- package/src/live/auth/guard.ts +111 -0
- package/src/live/auth/index.ts +68 -0
- package/src/live/auth/links.ts +101 -0
- package/src/live/auth/login.ts +245 -0
- package/src/live/auth/middleware.ts +53 -0
- package/src/live/auth/request.ts +56 -0
- package/src/live/auth/routes.ts +9 -0
- package/src/live/auth/session.ts +181 -0
- package/src/live/auth/views.ts +355 -0
- package/src/live/autosaves.ts +306 -0
- package/src/live/backend.ts +652 -0
- package/src/live/branches.ts +19 -0
- package/src/live/drafts-store.ts +591 -0
- package/src/live/editor.ts +465 -0
- package/src/live/git.ts +1021 -0
- package/src/live/github.ts +271 -0
- package/src/live/locals.ts +24 -0
- package/src/live/locks.ts +273 -0
- package/src/live/merge.ts +197 -0
- package/src/live/messages.ts +151 -0
- package/src/live/mode.ts +210 -0
- package/src/live/redis.ts +533 -0
- package/src/live/runtime.ts +164 -0
- package/src/live/status.ts +109 -0
- package/src/live/sweep.ts +228 -0
- package/src/live/timings.ts +47 -0
- package/src/live/webhook.ts +39 -0
- package/src/lockup-css.ts +58 -0
- package/src/measure.ts +145 -0
- package/src/media-value.ts +239 -0
- package/src/media.ts +255 -0
- package/src/read.ts +256 -0
- package/src/redirect-middleware.ts +49 -0
- package/src/redirects.ts +76 -0
- package/src/relink.ts +293 -0
- package/src/reserved.ts +24 -0
- package/src/rich-text.ts +690 -0
- package/src/schema-key.ts +63 -0
- package/src/seo.ts +124 -0
- package/src/serialize.ts +697 -0
- package/src/skipped.ts +35 -0
- package/src/slug.ts +121 -0
- package/src/text-styles.ts +62 -0
- package/src/virtual.d.ts +28 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ⌘K document switcher (the mockup's #switcher and #switcher-find): a popover
|
|
3
|
+
* over the bar that opens upward, **searching every document's title and address,
|
|
4
|
+
* collections included, grouped by collection** (Decision 9; client/nav/search.ts).
|
|
5
|
+
*
|
|
6
|
+
* Unfiltered it lists Recent (this browser's, from the cookie), every page in tree
|
|
7
|
+
* order, then the first few of each other collection, then (M5a) Shared blocks and Site
|
|
8
|
+
* Settings. Typing filters; ↑/↓ move the
|
|
9
|
+
* highlight, Enter opens it, Esc closes (App.tsx). The bar's trigger and ⌘K open it
|
|
10
|
+
* (`editor.setPop('switcher')`); Popovers.tsx renders it while `view.pop === 'switcher'`.
|
|
11
|
+
*/
|
|
12
|
+
import { useEffect, useMemo, useRef, useState, type KeyboardEvent } from 'react';
|
|
13
|
+
import { useEditor, useStore } from '../context.tsx';
|
|
14
|
+
import { Icon } from '../shell/Icons.tsx';
|
|
15
|
+
import { DocRow } from '../nav/DocRow.tsx';
|
|
16
|
+
import { parentLabel, searchDocuments } from '../nav/search.ts';
|
|
17
|
+
import { docId, type ListedDocument } from '../../types.ts';
|
|
18
|
+
|
|
19
|
+
export const SWITCHER_READY = true;
|
|
20
|
+
|
|
21
|
+
/** How many of a flat collection the unfiltered list shows before "N more: type to find one". */
|
|
22
|
+
const FIRST = 5;
|
|
23
|
+
const MAX_HITS = 12;
|
|
24
|
+
|
|
25
|
+
interface Section {
|
|
26
|
+
key: string;
|
|
27
|
+
heading: string;
|
|
28
|
+
items: { doc: ListedDocument; crumb: string }[];
|
|
29
|
+
more: string | null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function Switcher() {
|
|
33
|
+
const editor = useEditor();
|
|
34
|
+
const documents = useStore(editor.documents);
|
|
35
|
+
const recent = useStore(editor.ui, (u) => u.recent);
|
|
36
|
+
const [query, setQuery] = useState('');
|
|
37
|
+
const [active, setActive] = useState(0);
|
|
38
|
+
const input = useRef<HTMLInputElement>(null);
|
|
39
|
+
const pop = useRef<HTMLDivElement>(null);
|
|
40
|
+
|
|
41
|
+
const sections = useMemo<Section[]>(() => {
|
|
42
|
+
const crumbOf = (d: ListedDocument) => (editor.site.collections.find((c) => c.name === d.collection)?.nested ? parentLabel(d, documents) : '');
|
|
43
|
+
if (query.trim()) {
|
|
44
|
+
return searchDocuments(query, documents, editor.site.collections).map((g) => ({
|
|
45
|
+
key: g.collection.name,
|
|
46
|
+
heading: `${g.collection.label} · ${g.collection.nested || g.hits.length === g.total ? g.hits.length : `${g.hits.length} of ${g.total}`}`,
|
|
47
|
+
items: g.hits.slice(0, MAX_HITS),
|
|
48
|
+
more: g.hits.length > MAX_HITS ? `${g.hits.length - MAX_HITS} more: keep typing` : null,
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
const out: Section[] = [];
|
|
52
|
+
const recentDocs = recent
|
|
53
|
+
.map((id) => documents.find((d) => docId(d) === id))
|
|
54
|
+
.filter((d): d is ListedDocument => !!d && !d.warning)
|
|
55
|
+
.slice(0, 3);
|
|
56
|
+
if (recentDocs.length) out.push({ key: 'recent', heading: 'Recent', items: recentDocs.map((d) => ({ doc: d, crumb: crumbOf(d) })), more: null });
|
|
57
|
+
for (const c of editor.site.collections) {
|
|
58
|
+
const docs = documents.filter((d) => d.collection === c.name);
|
|
59
|
+
if (!docs.length) continue;
|
|
60
|
+
const shown = c.nested ? docs : docs.slice(0, FIRST);
|
|
61
|
+
// Shared blocks and Site Settings (M5a) are named without a count, as the mockup has them.
|
|
62
|
+
const reserved = c.kind === 'shared' || c.kind === 'settings';
|
|
63
|
+
out.push({
|
|
64
|
+
key: c.name,
|
|
65
|
+
heading: c.nested || reserved ? c.label : `${c.label} · ${docs.length}`,
|
|
66
|
+
items: shown.map((d) => ({ doc: d, crumb: crumbOf(d) })),
|
|
67
|
+
more: docs.length > shown.length ? `${docs.length - shown.length} more: type to find one` : null,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return out;
|
|
71
|
+
}, [query, documents, recent, editor.site.collections]);
|
|
72
|
+
|
|
73
|
+
const flat = sections.flatMap((s) => s.items);
|
|
74
|
+
const activeIndex = flat.length ? Math.min(active, flat.length - 1) : -1;
|
|
75
|
+
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
input.current?.focus();
|
|
78
|
+
}, []);
|
|
79
|
+
useEffect(() => setActive(0), [query]);
|
|
80
|
+
// Keep the highlight in view.
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
pop.current?.querySelector('.drow.is-active')?.scrollIntoView({ block: 'nearest' });
|
|
83
|
+
}, [activeIndex]);
|
|
84
|
+
// A click outside closes it (the bar's trigger toggles it itself).
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
const onDown = (event: MouseEvent) => {
|
|
87
|
+
const target = event.target as Element | null;
|
|
88
|
+
if (!target || pop.current?.contains(target) || target.closest?.('.docbtn')) return;
|
|
89
|
+
editor.setPop(null);
|
|
90
|
+
};
|
|
91
|
+
document.addEventListener('mousedown', onDown);
|
|
92
|
+
return () => document.removeEventListener('mousedown', onDown);
|
|
93
|
+
}, [editor]);
|
|
94
|
+
|
|
95
|
+
const onKey = (event: KeyboardEvent<HTMLInputElement>) => {
|
|
96
|
+
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
97
|
+
event.preventDefault();
|
|
98
|
+
if (!flat.length) return;
|
|
99
|
+
const step = event.key === 'ArrowDown' ? 1 : -1;
|
|
100
|
+
setActive((activeIndex + step + flat.length) % flat.length);
|
|
101
|
+
} else if (event.key === 'Enter') {
|
|
102
|
+
event.preventDefault();
|
|
103
|
+
const hit = flat[activeIndex];
|
|
104
|
+
if (!hit) return;
|
|
105
|
+
if (hit.doc.warning) {
|
|
106
|
+
editor.announce(`${hit.doc.label} can't be opened. ${hit.doc.warning.message}`);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
editor.setPop(null);
|
|
110
|
+
void editor.openDocument({ collection: hit.doc.collection, path: hit.doc.path });
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
let n = -1;
|
|
115
|
+
return (
|
|
116
|
+
<div
|
|
117
|
+
ref={pop}
|
|
118
|
+
className="pop switcher"
|
|
119
|
+
role="dialog"
|
|
120
|
+
aria-label="Go to a document"
|
|
121
|
+
style={{ left: 8, width: 380, height: 'min(540px, calc(100% - var(--bar-h) - 24px))' }}
|
|
122
|
+
>
|
|
123
|
+
<div className="sw-in">
|
|
124
|
+
<Icon name="search" />
|
|
125
|
+
<input
|
|
126
|
+
ref={input}
|
|
127
|
+
id="swq"
|
|
128
|
+
placeholder="Go to a document"
|
|
129
|
+
aria-label="Go to a document"
|
|
130
|
+
aria-controls="swlist"
|
|
131
|
+
aria-activedescendant={activeIndex >= 0 ? `sw-${activeIndex}` : undefined}
|
|
132
|
+
autoComplete="off"
|
|
133
|
+
spellCheck={false}
|
|
134
|
+
value={query}
|
|
135
|
+
onChange={(e) => setQuery(e.target.value)}
|
|
136
|
+
onKeyDown={onKey}
|
|
137
|
+
/>
|
|
138
|
+
<kbd>esc</kbd>
|
|
139
|
+
</div>
|
|
140
|
+
<div className="sw-list" id="swlist">
|
|
141
|
+
{sections.length === 0 ? <div className="sw-more">Nothing called “{query.trim()}”.</div> : null}
|
|
142
|
+
{sections.map((s) => (
|
|
143
|
+
<div key={s.key} role="group" aria-label={s.heading} data-sw-group={s.key}>
|
|
144
|
+
<div className="sw-h">{s.heading}</div>
|
|
145
|
+
{s.items.map((item) => {
|
|
146
|
+
n += 1;
|
|
147
|
+
const i = n;
|
|
148
|
+
return (
|
|
149
|
+
<DocRow
|
|
150
|
+
key={`${s.key}:${docId(item.doc)}`}
|
|
151
|
+
id={`sw-${i}`}
|
|
152
|
+
doc={item.doc}
|
|
153
|
+
crumb={item.crumb}
|
|
154
|
+
active={i === activeIndex}
|
|
155
|
+
onOpen={() => editor.setPop(null)}
|
|
156
|
+
/>
|
|
157
|
+
);
|
|
158
|
+
})}
|
|
159
|
+
{s.more ? <div className="sw-more">{s.more}</div> : null}
|
|
160
|
+
</div>
|
|
161
|
+
))}
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
);
|
|
165
|
+
}
|