@rimelight/cms 0.0.4 → 0.0.5
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/dist/index.d.mts +17 -17
- package/dist/index.mjs +47 -47
- package/dist/schema/index.d.mts +13 -13
- package/dist/schema/sqlite.d.mts +12 -12
- package/package.json +9 -4
- package/src/admin/api/media-file.ts +1 -1
- package/src/admin/pages/assets.astro +11 -11
- package/src/admin/pages/pages-edit.astro +3 -3
- package/src/admin/pages/pages-index.astro +2 -2
- package/src/admin/pages/pages-preview.astro +3 -3
- package/src/admin/pages/pages-review.astro +2 -2
- package/src/admin/pages/templates-edit.astro +1 -1
- package/src/admin/pages/templates-index.astro +1 -1
- package/src/astro/BlockRenderer.astro +1 -1
- package/src/astro/blocks/CalloutBlock.astro +1 -1
- package/src/astro/blocks/OrderedListBlock.astro +2 -2
- package/src/astro/blocks/ParagraphBlock.astro +1 -1
- package/src/astro/blocks/TabsBlock.astro +5 -5
- package/src/astro/blocks/UnorderedListBlock.astro +2 -2
- package/src/auth/editor-guards.ts +1 -1
- package/src/cache/purge.ts +2 -2
- package/src/client/components/RimelightBlock.tsx +1 -1
- package/src/client/components/RimelightBlockPicker.tsx +1 -1
- package/src/client/components/RimelightPreview.tsx +27 -27
- package/src/client/components/RimelightPropertiesPanel.tsx +4 -4
- package/src/client/components/RimelightTemplateEditor.tsx +9 -5
- package/src/client/components/editors/CalloutEditor.tsx +10 -10
- package/src/client/components/editors/CardEditor.tsx +5 -5
- package/src/client/components/editors/CardsEditor.tsx +2 -2
- package/src/client/components/editors/CodeEditor.tsx +5 -5
- package/src/client/components/editors/DialogueEditor.tsx +6 -6
- package/src/client/components/editors/FileTreeEditor.tsx +1 -1
- package/src/client/components/editors/ImageEditor.tsx +9 -9
- package/src/client/components/editors/ParagraphEditor.tsx +1 -1
- package/src/client/components/editors/SceneEditor.tsx +9 -9
- package/src/client/components/editors/ScriptEditor.tsx +8 -8
- package/src/client/components/editors/SectionEditor.tsx +3 -3
- package/src/client/components/editors/StepItemEditor.tsx +6 -5
- package/src/client/components/editors/StepsEditor.tsx +1 -1
- package/src/client/components/editors/TabItemEditor.tsx +3 -3
- package/src/client/components/editors/TableEditor.tsx +4 -4
- package/src/client/components/editors/TabsEditor.tsx +1 -1
- package/src/client/state/editor-store.ts +23 -23
- package/src/client/utils/sortable.ts +13 -12
- package/src/client/utils/tree-sanitizer.ts +1 -1
- package/src/core/excerpt.ts +16 -16
- package/src/core/page-definitions.ts +2 -2
- package/src/docs/agent.ts +1 -1
- package/src/docs/routing.ts +2 -2
- package/src/loader/live.ts +1 -1
- package/src/markdown/serializer.ts +26 -26
|
@@ -15,7 +15,7 @@ import "../../client/styles/cms-editor.css";
|
|
|
15
15
|
export const prerender = false;
|
|
16
16
|
|
|
17
17
|
const currentLocale = Astro.currentLocale ?? "en";
|
|
18
|
-
const id = Astro.params
|
|
18
|
+
const id = Astro.params["id"];
|
|
19
19
|
|
|
20
20
|
let page: any = null;
|
|
21
21
|
let draft: any = null;
|
|
@@ -57,12 +57,12 @@ const extractedBlocks = Array.isArray(rawContent?.blocks)
|
|
|
57
57
|
|
|
58
58
|
const titleVal =
|
|
59
59
|
typeof page.title === "object" && page.title !== null
|
|
60
|
-
? (page.title as Record<string, string>)[currentLocale] || (page.title as Record<string, string>)
|
|
60
|
+
? (page.title as Record<string, string>)[currentLocale] || (page.title as Record<string, string>)["en"] || ""
|
|
61
61
|
: String(page.title || "");
|
|
62
62
|
|
|
63
63
|
const descVal =
|
|
64
64
|
typeof page.description === "object" && page.description !== null
|
|
65
|
-
? (page.description as Record<string, string>)[currentLocale] || (page.description as Record<string, string>)
|
|
65
|
+
? (page.description as Record<string, string>)[currentLocale] || (page.description as Record<string, string>)["en"] || ""
|
|
66
66
|
: String(page.description || "");
|
|
67
67
|
|
|
68
68
|
const pageType = (page as any).type || "blog";
|
|
@@ -29,7 +29,7 @@ if (db) {
|
|
|
29
29
|
const formattedPages = pagesList.map((page) => {
|
|
30
30
|
const titleVal =
|
|
31
31
|
typeof page.title === "object" && page.title !== null
|
|
32
|
-
? (page.title as Record<string, string>)
|
|
32
|
+
? (page.title as Record<string, string>)["en"] || ""
|
|
33
33
|
: String(page.title || "");
|
|
34
34
|
return {
|
|
35
35
|
id: page.id,
|
|
@@ -124,7 +124,7 @@ const columns: TableColumn[] = [
|
|
|
124
124
|
<script>
|
|
125
125
|
document.querySelectorAll(".delete-page-btn").forEach((btn) => {
|
|
126
126
|
btn.addEventListener("click", async () => {
|
|
127
|
-
const pageId = (btn as HTMLElement).dataset
|
|
127
|
+
const pageId = (btn as HTMLElement).dataset["pageId"];
|
|
128
128
|
if (!pageId) return;
|
|
129
129
|
if (!confirm("Are you sure you want to delete this page?")) return;
|
|
130
130
|
|
|
@@ -11,14 +11,14 @@ import { verifyPreviewToken } from "../../core/preview.ts";
|
|
|
11
11
|
export const prerender = false;
|
|
12
12
|
|
|
13
13
|
const currentLocale = Astro.currentLocale ?? "en";
|
|
14
|
-
const id = Astro.params
|
|
14
|
+
const id = Astro.params["id"];
|
|
15
15
|
|
|
16
16
|
if (!id) {
|
|
17
17
|
return Astro.redirect(getRelativeLocaleUrl(currentLocale, "/cms/pages"));
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
const token = Astro.url.searchParams.get("token");
|
|
21
|
-
const secret = process.env
|
|
21
|
+
const secret = process.env["CMS_PREVIEW_SECRET"] || "rimelight-preview-secret-key";
|
|
22
22
|
if (token) {
|
|
23
23
|
await verifyPreviewToken(id, token, secret);
|
|
24
24
|
}
|
|
@@ -48,7 +48,7 @@ const content = draft?.content ? parseContent(draft.content) : parseContent(page
|
|
|
48
48
|
|
|
49
49
|
const titleVal =
|
|
50
50
|
typeof page.title === "object" && page.title !== null
|
|
51
|
-
? (page.title as Record<string, string>)[currentLocale] || (page.title as Record<string, string>)
|
|
51
|
+
? (page.title as Record<string, string>)[currentLocale] || (page.title as Record<string, string>)["en"] || ""
|
|
52
52
|
: String(page.title || "");
|
|
53
53
|
---
|
|
54
54
|
|
|
@@ -11,7 +11,7 @@ import { diffPageSnapshots } from "../../core/diff.ts";
|
|
|
11
11
|
export const prerender = false;
|
|
12
12
|
|
|
13
13
|
const currentLocale = Astro.currentLocale ?? "en";
|
|
14
|
-
const id = Astro.params
|
|
14
|
+
const id = Astro.params["id"];
|
|
15
15
|
|
|
16
16
|
if (!id) {
|
|
17
17
|
return Astro.redirect(getRelativeLocaleUrl(currentLocale, "/cms/pages"));
|
|
@@ -52,7 +52,7 @@ const diffResult = diffPageSnapshots(publishedSnapshot, draftSnapshot);
|
|
|
52
52
|
|
|
53
53
|
const titleVal =
|
|
54
54
|
typeof page.title === "object" && page.title !== null
|
|
55
|
-
? (page.title as Record<string, string>)[currentLocale] || (page.title as Record<string, string>)
|
|
55
|
+
? (page.title as Record<string, string>)[currentLocale] || (page.title as Record<string, string>)["en"] || ""
|
|
56
56
|
: String(page.title || "");
|
|
57
57
|
---
|
|
58
58
|
|
|
@@ -12,7 +12,7 @@ import { getRelativeLocaleUrl } from "@rimelight/i18n";
|
|
|
12
12
|
export const prerender = false;
|
|
13
13
|
|
|
14
14
|
const currentLocale = Astro.currentLocale ?? "en";
|
|
15
|
-
const id = Astro.params
|
|
15
|
+
const id = Astro.params["id"];
|
|
16
16
|
|
|
17
17
|
let template: any = null;
|
|
18
18
|
if (db && id) {
|
|
@@ -74,7 +74,7 @@ if (db) {
|
|
|
74
74
|
<script>
|
|
75
75
|
document.querySelectorAll('.delete-template-btn').forEach((btn) => {
|
|
76
76
|
btn.addEventListener('click', async () => {
|
|
77
|
-
const id = (btn as HTMLElement).dataset
|
|
77
|
+
const id = (btn as HTMLElement).dataset["id"];
|
|
78
78
|
if (!id) return;
|
|
79
79
|
|
|
80
80
|
if (!confirm('Are you sure you want to delete this template?')) return;
|
|
@@ -19,7 +19,7 @@ const {
|
|
|
19
19
|
} = Astro.props
|
|
20
20
|
|
|
21
21
|
const Component = components[block.type] ?? defaultBlockComponents[block.type]
|
|
22
|
-
const rawChildren = block.children || block.props?.children || []
|
|
22
|
+
const rawChildren = block.children || block.props?.["children"] || []
|
|
23
23
|
const children = (Array.isArray(rawChildren) ? rawChildren : []) as BaseBlock[]
|
|
24
24
|
const nextDepth = block.type === "SectionBlock" ? Math.min(6, (sectionDepth || 2) + 1) : sectionDepth
|
|
25
25
|
---
|
|
@@ -8,7 +8,7 @@ interface Props {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
const { block } = Astro.props
|
|
11
|
-
const items = block.props?.items || block.children || []
|
|
11
|
+
const items = block.props?.["items"] || block.children || []
|
|
12
12
|
|
|
13
13
|
function escapeHtml(str: string): string {
|
|
14
14
|
return (str || "")
|
|
@@ -50,6 +50,6 @@ function renderNodesToHtml(nodes: InlineNode[]): string {
|
|
|
50
50
|
|
|
51
51
|
<ol class="cms-ordered-list list-decimal list-inside space-y-2 my-4 text-base text-neutral-800" data-block-id={block.id}>
|
|
52
52
|
{items.map((item: BaseBlock) => (
|
|
53
|
-
<li set:html={renderNodesToHtml(item.props?.content || [])} />
|
|
53
|
+
<li set:html={renderNodesToHtml(item.props?.["content"] || [])} />
|
|
54
54
|
))}
|
|
55
55
|
</ol>
|
|
@@ -7,15 +7,15 @@ interface Props {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
const { block } = Astro.props
|
|
10
|
-
const children: BaseBlock[] = block.children || block.props?.children || []
|
|
11
|
-
const defaultValue = block.props?.defaultValue || (children[0]?.props?.value || children[0]?.props?.label || "tab-0")
|
|
10
|
+
const children: BaseBlock[] = block.children || block.props?.["children"] || []
|
|
11
|
+
const defaultValue = block.props?.["defaultValue"] || (children[0]?.props?.["value"] || children[0]?.props?.["label"] || "tab-0")
|
|
12
12
|
const tabsId = `tabs-${block.id}`
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
<div class="cms-tabs my-6 border border-neutral-200 rounded-xl overflow-hidden" data-block-id={block.id} id={tabsId}>
|
|
16
16
|
<div class="flex items-center gap-1 border-b border-neutral-200 bg-neutral-50 px-3 pt-2">
|
|
17
17
|
{children.map((child, index) => {
|
|
18
|
-
const val = child.props?.value || child.props?.label || `tab-${index}`
|
|
18
|
+
const val = child.props?.["value"] || child.props?.["label"] || `tab-${index}`
|
|
19
19
|
const isDefault = val === defaultValue || (!defaultValue && index === 0)
|
|
20
20
|
return (
|
|
21
21
|
<button
|
|
@@ -27,8 +27,8 @@ const tabsId = `tabs-${block.id}`
|
|
|
27
27
|
}`}
|
|
28
28
|
data-tab-target={`${tabsId}-panel-${index}`}
|
|
29
29
|
>
|
|
30
|
-
{child.props?.icon && <span class={`${child.props
|
|
31
|
-
{child.props?.label || `Tab ${index + 1}`}
|
|
30
|
+
{child.props?.["icon"] && <span class={`${child.props["icon"]} mr-1.5 inline-block size-3.5 align-text-bottom`} />}
|
|
31
|
+
{child.props?.["label"] || `Tab ${index + 1}`}
|
|
32
32
|
</button>
|
|
33
33
|
)
|
|
34
34
|
})}
|
|
@@ -8,7 +8,7 @@ interface Props {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
const { block } = Astro.props
|
|
11
|
-
const items = block.props?.items || block.children || []
|
|
11
|
+
const items = block.props?.["items"] || block.children || []
|
|
12
12
|
|
|
13
13
|
function escapeHtml(str: string): string {
|
|
14
14
|
return (str || "")
|
|
@@ -50,6 +50,6 @@ function renderNodesToHtml(nodes: InlineNode[]): string {
|
|
|
50
50
|
|
|
51
51
|
<ul class="cms-unordered-list list-disc list-inside space-y-2 my-4 text-base text-neutral-800" data-block-id={block.id}>
|
|
52
52
|
{items.map((item: BaseBlock) => (
|
|
53
|
-
<li set:html={renderNodesToHtml(item.props?.content || [])} />
|
|
53
|
+
<li set:html={renderNodesToHtml(item.props?.["content"] || [])} />
|
|
54
54
|
))}
|
|
55
55
|
</ul>
|
|
@@ -114,7 +114,7 @@ export function validateServerBlockPayload(
|
|
|
114
114
|
|
|
115
115
|
function getChildren(b: BaseBlock): BaseBlock[] {
|
|
116
116
|
if (!b) return []
|
|
117
|
-
if (Array.isArray(b.props?.children)) return b.props
|
|
117
|
+
if (Array.isArray(b.props?.["children"])) return b.props["children"]
|
|
118
118
|
if (Array.isArray(b.children)) return b.children
|
|
119
119
|
return []
|
|
120
120
|
}
|
package/src/cache/purge.ts
CHANGED
|
@@ -8,8 +8,8 @@ export interface CachePurgeOptions {
|
|
|
8
8
|
|
|
9
9
|
export async function invalidatePageCache(options: CachePurgeOptions): Promise<boolean> {
|
|
10
10
|
const { slug, locales, domain = "rimelight.com", basePath = "", isEnterpriseCloudflare } = options
|
|
11
|
-
const zoneId = process.env
|
|
12
|
-
const apiToken = process.env
|
|
11
|
+
const zoneId = process.env["CLOUDFLARE_ZONE_ID"]
|
|
12
|
+
const apiToken = process.env["CLOUDFLARE_API_TOKEN"]
|
|
13
13
|
|
|
14
14
|
if (!zoneId || !apiToken) {
|
|
15
15
|
return false
|
|
@@ -84,7 +84,7 @@ export const RimelightBlock: Component<RimelightBlockProps> = (props) => {
|
|
|
84
84
|
|
|
85
85
|
const childrenList = () => {
|
|
86
86
|
if (Array.isArray(blockItem.children)) return blockItem.children
|
|
87
|
-
if (Array.isArray(blockItem.props?.children)) return blockItem.props
|
|
87
|
+
if (Array.isArray(blockItem.props?.["children"])) return blockItem.props["children"]
|
|
88
88
|
return []
|
|
89
89
|
}
|
|
90
90
|
|
|
@@ -137,7 +137,7 @@ export const RimelightBlockPicker: Component<RimelightBlockPickerProps> = (props
|
|
|
137
137
|
|
|
138
138
|
const allowedTypes = (): string[] => {
|
|
139
139
|
const parent = props.containerType || "Root"
|
|
140
|
-
return ALLOWED_CHILDREN_MAP[parent] || ALLOWED_CHILDREN_MAP
|
|
140
|
+
return ALLOWED_CHILDREN_MAP[parent] || ALLOWED_CHILDREN_MAP["Root"] || []
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
const filteredBlocks = () => {
|
|
@@ -25,8 +25,8 @@ export const RimelightPreview: Component<RimelightPreviewProps> = (props) => {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
const [blocks, setBlocks] = createSignal<BaseBlock[]>(getInitialBlocks())
|
|
28
|
-
const [title, setTitle] = createSignal<string>(props
|
|
29
|
-
const [description, setDescription] = createSignal<string>(props
|
|
28
|
+
const [title, setTitle] = createSignal<string>(props["title"] || "")
|
|
29
|
+
const [description, setDescription] = createSignal<string>(props["description"] || "")
|
|
30
30
|
const [banner, setBanner] = createSignal<string>(props.banner || "")
|
|
31
31
|
const [category, setCategory] = createSignal<string>(props.category || "")
|
|
32
32
|
|
|
@@ -120,14 +120,14 @@ function escapeHtml(str: string): string {
|
|
|
120
120
|
function getChildren(b: BaseBlock): BaseBlock[] {
|
|
121
121
|
if (!b) return []
|
|
122
122
|
if (Array.isArray(b.children)) return b.children
|
|
123
|
-
if (Array.isArray(b.props?.children)) return b.props
|
|
123
|
+
if (Array.isArray(b.props?.["children"])) return b.props["children"]
|
|
124
124
|
return []
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
function renderBlockPreviewHtml(b: BaseBlock, sectionDepth: number = 0): string {
|
|
128
128
|
if (!b) return ""
|
|
129
129
|
const props = b.props || {}
|
|
130
|
-
const rawText = props
|
|
130
|
+
const rawText = props["text"]
|
|
131
131
|
const textVal = typeof rawText === "object" && rawText !== null ? rawText.en || "" : rawText || ""
|
|
132
132
|
|
|
133
133
|
if (b.type === "ParagraphBlock") {
|
|
@@ -172,9 +172,9 @@ function renderBlockPreviewHtml(b: BaseBlock, sectionDepth: number = 0): string
|
|
|
172
172
|
|
|
173
173
|
if (b.type === "SectionBlock") {
|
|
174
174
|
const level = calculateHeadingLevel(sectionDepth)
|
|
175
|
-
const title = props
|
|
175
|
+
const title = props["title"] || "Untitled Section"
|
|
176
176
|
const slug = title.toLowerCase().replace(/\W+/g, "-")
|
|
177
|
-
const description = props
|
|
177
|
+
const description = props["description"]
|
|
178
178
|
let headingClasses = "font-bold text-neutral-900"
|
|
179
179
|
if (level === 2) headingClasses += " text-3xl mt-6 mb-3 border-b border-neutral-200 pb-2"
|
|
180
180
|
else if (level === 3) headingClasses += " text-2xl font-semibold mt-5 mb-2.5"
|
|
@@ -194,9 +194,9 @@ function renderBlockPreviewHtml(b: BaseBlock, sectionDepth: number = 0): string
|
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
if (b.type === "CalloutBlock") {
|
|
197
|
-
const variant = props
|
|
198
|
-
const to = props
|
|
199
|
-
const target = props
|
|
197
|
+
const variant = props["variant"] || "info"
|
|
198
|
+
const to = props["to"]
|
|
199
|
+
const target = props["target"] || "_self"
|
|
200
200
|
const icons: Record<string, string> = {
|
|
201
201
|
info: "ℹ️",
|
|
202
202
|
success: "✅",
|
|
@@ -206,7 +206,7 @@ function renderBlockPreviewHtml(b: BaseBlock, sectionDepth: number = 0): string
|
|
|
206
206
|
ideation: "💡",
|
|
207
207
|
source: "💻"
|
|
208
208
|
}
|
|
209
|
-
const icon = icons[variant] || icons
|
|
209
|
+
const icon = icons[variant] || icons["info"]
|
|
210
210
|
|
|
211
211
|
let variantClasses = "bg-info-50/50 border-info-200 text-info-800"
|
|
212
212
|
if (variant === "success") {
|
|
@@ -237,9 +237,9 @@ function renderBlockPreviewHtml(b: BaseBlock, sectionDepth: number = 0): string
|
|
|
237
237
|
}
|
|
238
238
|
|
|
239
239
|
if (b.type === "ImageBlock") {
|
|
240
|
-
const src = props
|
|
241
|
-
const alt = props
|
|
242
|
-
const caption = props
|
|
240
|
+
const src = props["src"] || props["url"] || ""
|
|
241
|
+
const alt = props["alt"] || "Image"
|
|
242
|
+
const caption = props["caption"]
|
|
243
243
|
return `<figure class="mx-auto my-6 flex flex-col items-center max-w-full">
|
|
244
244
|
<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}" class="h-auto max-w-full rounded-xl object-cover border border-neutral-200 shadow-sm" />
|
|
245
245
|
${caption ? `<figcaption class="mt-2 text-center text-xs text-neutral-500 italic">${escapeHtml(caption)}</figcaption>` : ""}
|
|
@@ -247,9 +247,9 @@ function renderBlockPreviewHtml(b: BaseBlock, sectionDepth: number = 0): string
|
|
|
247
247
|
}
|
|
248
248
|
|
|
249
249
|
if (b.type === "CodeBlock") {
|
|
250
|
-
const code = props
|
|
251
|
-
const language = props
|
|
252
|
-
const caption = props
|
|
250
|
+
const code = props["code"] || textVal
|
|
251
|
+
const language = props["language"] || "plaintext"
|
|
252
|
+
const caption = props["caption"]
|
|
253
253
|
return `<div class="cms-code my-4 rounded-lg bg-neutral-950 p-4 font-mono text-sm border border-neutral-800 overflow-x-auto">
|
|
254
254
|
<div class="text-xs text-neutral-500 uppercase mb-2 select-none">${escapeHtml(language)}</div>
|
|
255
255
|
<pre class="m-0"><code class="text-success-300 font-mono">${escapeHtml(code)}</code></pre>
|
|
@@ -258,9 +258,9 @@ function renderBlockPreviewHtml(b: BaseBlock, sectionDepth: number = 0): string
|
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
if (b.type === "ScriptBlock") {
|
|
261
|
-
const title = props
|
|
262
|
-
const synopsis = props
|
|
263
|
-
const chars = props
|
|
261
|
+
const title = props["title"] || "Untitled Script"
|
|
262
|
+
const synopsis = props["synopsis"]
|
|
263
|
+
const chars = props["characters"] || []
|
|
264
264
|
const { aPlot, bPlot, cPlot, stinger } = props
|
|
265
265
|
return `<div class="my-6 p-4 border-l-4 border-warning-400 bg-warning-50/20 rounded-r-lg">
|
|
266
266
|
<div class="mb-4">
|
|
@@ -307,10 +307,10 @@ function renderBlockPreviewHtml(b: BaseBlock, sectionDepth: number = 0): string
|
|
|
307
307
|
NONE: ""
|
|
308
308
|
}
|
|
309
309
|
|
|
310
|
-
const setting = settingLabels[props
|
|
311
|
-
const location = props
|
|
312
|
-
const tod = timeOfDayLabels[props
|
|
313
|
-
const transition = transitionLabels[props
|
|
310
|
+
const setting = settingLabels[props["setting"]] || props["setting"] || "INT."
|
|
311
|
+
const location = props["location"] || ""
|
|
312
|
+
const tod = timeOfDayLabels[props["timeOfDay"]] || props["timeOfDay"] || "Morning"
|
|
313
|
+
const transition = transitionLabels[props["transition"]] || ""
|
|
314
314
|
|
|
315
315
|
const parts: string[] = []
|
|
316
316
|
if (setting && setting !== "Other") parts.push(setting)
|
|
@@ -322,7 +322,7 @@ function renderBlockPreviewHtml(b: BaseBlock, sectionDepth: number = 0): string
|
|
|
322
322
|
${parts.map((p) => `<span>${escapeHtml(p)}</span>`).join("")}
|
|
323
323
|
${transition ? `<span class="ml-auto text-[10px] italic text-neutral-500">${escapeHtml(transition)}</span>` : ""}
|
|
324
324
|
</div>
|
|
325
|
-
${props
|
|
325
|
+
${props["description"] ? `<p class="text-sm text-neutral-700 mb-2">${escapeHtml(props["description"])}</p>` : ""}
|
|
326
326
|
<div class="mt-3">
|
|
327
327
|
${getChildren(b)
|
|
328
328
|
.map((c) => renderBlockPreviewHtml(c, sectionDepth))
|
|
@@ -332,9 +332,9 @@ function renderBlockPreviewHtml(b: BaseBlock, sectionDepth: number = 0): string
|
|
|
332
332
|
}
|
|
333
333
|
|
|
334
334
|
if (b.type === "DialogueBlock") {
|
|
335
|
-
const character = props
|
|
336
|
-
const parenthetical = props
|
|
337
|
-
const line = props
|
|
335
|
+
const character = props["character"] || "CHARACTER"
|
|
336
|
+
const parenthetical = props["parenthetical"]
|
|
337
|
+
const line = props["line"] || ""
|
|
338
338
|
return `<div class="my-3 mx-8 max-w-md">
|
|
339
339
|
<div class="text-sm font-bold text-center text-commentary-800">${escapeHtml(character)}</div>
|
|
340
340
|
${parenthetical ? `<div class="text-xs italic text-center text-neutral-500 mt-0.5">(${escapeHtml(parenthetical)})</div>` : ""}
|
|
@@ -49,13 +49,13 @@ export const RimelightPropertiesPanel: Component<RimelightPropertiesPanelProps>
|
|
|
49
49
|
const [expandedGroups, setExpandedGroups] = createSignal<Record<string, boolean>>({})
|
|
50
50
|
const [arrayInputs, setArrayInputs] = createSignal<Record<string, string>>({})
|
|
51
51
|
const [links, setLinks] = createSignal<Array<{ label: string; to: string; icon?: string }>>(
|
|
52
|
-
componentProps.initialProperties?.links || []
|
|
52
|
+
componentProps.initialProperties?.["links"] || []
|
|
53
53
|
)
|
|
54
54
|
|
|
55
55
|
// Bylines state
|
|
56
56
|
const [availableBylines, setAvailableBylines] = createSignal<BylineItem[]>([])
|
|
57
57
|
const [bylines, setBylines] = createSignal<BylineItem[]>(
|
|
58
|
-
componentProps.bylines || componentProps.initialProperties?.bylines || []
|
|
58
|
+
componentProps.bylines || componentProps.initialProperties?.["bylines"] || []
|
|
59
59
|
)
|
|
60
60
|
const [isBylineModalOpen, setIsBylineModalOpen] = createSignal(false)
|
|
61
61
|
const [editingBylineIndex, setEditingBylineIndex] = createSignal<number | null>(null)
|
|
@@ -71,10 +71,10 @@ export const RimelightPropertiesPanel: Component<RimelightPropertiesPanelProps>
|
|
|
71
71
|
Array<{ id: string; name: string; slug: string }>
|
|
72
72
|
>([])
|
|
73
73
|
const [selectedCategory, setSelectedCategory] = createSignal<string>(
|
|
74
|
-
componentProps.initialProperties?.category || ""
|
|
74
|
+
componentProps.initialProperties?.["category"] || ""
|
|
75
75
|
)
|
|
76
76
|
const [tagsList, setTagsList] = createSignal<string[]>(
|
|
77
|
-
componentProps.tags || componentProps.initialProperties?.tags || []
|
|
77
|
+
componentProps.tags || componentProps.initialProperties?.["tags"] || []
|
|
78
78
|
)
|
|
79
79
|
const [newTagInput, setNewTagInput] = createSignal("")
|
|
80
80
|
|
|
@@ -163,7 +163,11 @@ export const RimelightTemplateEditor: Component<RimelightTemplateEditorProps> =
|
|
|
163
163
|
<For each={blocks()}>
|
|
164
164
|
{(block, index) => {
|
|
165
165
|
const rawText =
|
|
166
|
-
block.props
|
|
166
|
+
block.props["text"] ||
|
|
167
|
+
block.props["title"] ||
|
|
168
|
+
block.props["code"] ||
|
|
169
|
+
block.props["src"] ||
|
|
170
|
+
""
|
|
167
171
|
const textVal = typeof rawText === "object" ? rawText.en || "" : rawText || ""
|
|
168
172
|
|
|
169
173
|
return (
|
|
@@ -220,10 +224,10 @@ export const RimelightTemplateEditor: Component<RimelightTemplateEditorProps> =
|
|
|
220
224
|
onInput={(e: InputEvent & { currentTarget: HTMLInputElement }) => {
|
|
221
225
|
const val = e.currentTarget.value
|
|
222
226
|
updateBlockItem(block.id, (b) => {
|
|
223
|
-
if (b.type === "SectionBlock") b.props
|
|
224
|
-
else if (b.type === "CodeBlock") b.props
|
|
225
|
-
else if (b.type === "ImageBlock") b.props
|
|
226
|
-
else b.props
|
|
227
|
+
if (b.type === "SectionBlock") b.props["title"] = val
|
|
228
|
+
else if (b.type === "CodeBlock") b.props["code"] = val
|
|
229
|
+
else if (b.type === "ImageBlock") b.props["src"] = val
|
|
230
|
+
else b.props["text"] = { en: val }
|
|
227
231
|
})
|
|
228
232
|
}}
|
|
229
233
|
size="sm"
|
|
@@ -37,17 +37,17 @@ const TARGET_OPTIONS = [
|
|
|
37
37
|
]
|
|
38
38
|
|
|
39
39
|
export const CalloutEditor: Component<CalloutEditorProps> = (componentProps) => {
|
|
40
|
-
const [linkSettingsOpen, setLinkSettingsOpen] = createSignal(!!componentProps.props
|
|
40
|
+
const [linkSettingsOpen, setLinkSettingsOpen] = createSignal(!!componentProps.props["to"])
|
|
41
41
|
let childrenContainer: HTMLDivElement | undefined = undefined
|
|
42
42
|
let sortableInstance: any = null
|
|
43
43
|
|
|
44
|
-
const variant = () => componentProps.props
|
|
44
|
+
const variant = () => componentProps.props["variant"] || "info"
|
|
45
45
|
|
|
46
46
|
const childrenBlocks = (): BaseBlock[] => {
|
|
47
47
|
if (typeof componentProps.children === "function") {
|
|
48
48
|
return componentProps.children() || []
|
|
49
49
|
}
|
|
50
|
-
return componentProps.children || componentProps.props
|
|
50
|
+
return componentProps.children || componentProps.props["children"] || []
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
onMount(() => {
|
|
@@ -89,8 +89,8 @@ export const CalloutEditor: Component<CalloutEditorProps> = (componentProps) =>
|
|
|
89
89
|
const saveLinkProps = (to?: string, target?: string) => {
|
|
90
90
|
componentProps.onPropsChange({
|
|
91
91
|
...componentProps.props,
|
|
92
|
-
to: to !== undefined ? to : componentProps.props
|
|
93
|
-
target: target !== undefined ? target : componentProps.props
|
|
92
|
+
to: to !== undefined ? to : componentProps.props["to"],
|
|
93
|
+
target: target !== undefined ? target : componentProps.props["target"]
|
|
94
94
|
})
|
|
95
95
|
}
|
|
96
96
|
|
|
@@ -125,7 +125,7 @@ export const CalloutEditor: Component<CalloutEditorProps> = (componentProps) =>
|
|
|
125
125
|
onClick={() => setLinkSettingsOpen(!linkSettingsOpen())}
|
|
126
126
|
title="Link settings"
|
|
127
127
|
leadingIcon="link"
|
|
128
|
-
label={componentProps.props
|
|
128
|
+
label={componentProps.props["to"] ? "Linked" : "Add Link"}
|
|
129
129
|
/>
|
|
130
130
|
</div>
|
|
131
131
|
|
|
@@ -135,9 +135,9 @@ export const CalloutEditor: Component<CalloutEditorProps> = (componentProps) =>
|
|
|
135
135
|
<RLSInput
|
|
136
136
|
type="text"
|
|
137
137
|
placeholder="Link URL (e.g. https://... or /slug)"
|
|
138
|
-
value={componentProps.props
|
|
138
|
+
value={componentProps.props["to"] || ""}
|
|
139
139
|
onBlur={(e: FocusEvent & { currentTarget: HTMLInputElement }) =>
|
|
140
|
-
saveLinkProps(e.currentTarget.value, componentProps.props
|
|
140
|
+
saveLinkProps(e.currentTarget.value, componentProps.props["target"])
|
|
141
141
|
}
|
|
142
142
|
size="sm"
|
|
143
143
|
/>
|
|
@@ -145,9 +145,9 @@ export const CalloutEditor: Component<CalloutEditorProps> = (componentProps) =>
|
|
|
145
145
|
<div class="w-32">
|
|
146
146
|
<RLSSelect
|
|
147
147
|
items={TARGET_OPTIONS}
|
|
148
|
-
value={componentProps.props
|
|
148
|
+
value={componentProps.props["target"] || "_self"}
|
|
149
149
|
onChange={(e: Event & { currentTarget: HTMLSelectElement }) =>
|
|
150
|
-
saveLinkProps(componentProps.props
|
|
150
|
+
saveLinkProps(componentProps.props["to"], e.currentTarget.value)
|
|
151
151
|
}
|
|
152
152
|
size="xs"
|
|
153
153
|
/>
|
|
@@ -20,14 +20,14 @@ export const CardEditor: Component<CardEditorProps> = (componentProps) => {
|
|
|
20
20
|
<RLSInput
|
|
21
21
|
type="text"
|
|
22
22
|
placeholder="Card Title"
|
|
23
|
-
value={componentProps.props
|
|
23
|
+
value={componentProps.props["title"] || ""}
|
|
24
24
|
onBlur={(e) => save("title", e.currentTarget.value)}
|
|
25
25
|
size="sm"
|
|
26
26
|
/>
|
|
27
27
|
<RLSInput
|
|
28
28
|
type="text"
|
|
29
29
|
placeholder="Link (href e.g. /docs/getting-started)"
|
|
30
|
-
value={componentProps.props
|
|
30
|
+
value={componentProps.props["href"] || ""}
|
|
31
31
|
onBlur={(e) => save("href", e.currentTarget.value)}
|
|
32
32
|
size="sm"
|
|
33
33
|
/>
|
|
@@ -35,7 +35,7 @@ export const CardEditor: Component<CardEditorProps> = (componentProps) => {
|
|
|
35
35
|
<RLSInput
|
|
36
36
|
type="text"
|
|
37
37
|
placeholder="Card Description"
|
|
38
|
-
value={componentProps.props
|
|
38
|
+
value={componentProps.props["description"] || ""}
|
|
39
39
|
onBlur={(e) => save("description", e.currentTarget.value)}
|
|
40
40
|
size="sm"
|
|
41
41
|
/>
|
|
@@ -43,14 +43,14 @@ export const CardEditor: Component<CardEditorProps> = (componentProps) => {
|
|
|
43
43
|
<RLSInput
|
|
44
44
|
type="text"
|
|
45
45
|
placeholder="Icon (e.g. i-lucide-book-open)"
|
|
46
|
-
value={componentProps.props
|
|
46
|
+
value={componentProps.props["icon"] || ""}
|
|
47
47
|
onBlur={(e) => save("icon", e.currentTarget.value)}
|
|
48
48
|
size="sm"
|
|
49
49
|
/>
|
|
50
50
|
<RLSInput
|
|
51
51
|
type="text"
|
|
52
52
|
placeholder="Badge (optional e.g. New, Beta)"
|
|
53
|
-
value={componentProps.props
|
|
53
|
+
value={componentProps.props["badge"] || ""}
|
|
54
54
|
onBlur={(e) => save("badge", e.currentTarget.value)}
|
|
55
55
|
size="sm"
|
|
56
56
|
/>
|
|
@@ -30,7 +30,7 @@ export const CardsEditor: Component<CardsEditorProps> = (componentProps) => {
|
|
|
30
30
|
if (typeof componentProps.children === "function") {
|
|
31
31
|
return componentProps.children() || []
|
|
32
32
|
}
|
|
33
|
-
return componentProps.children || componentProps.props
|
|
33
|
+
return componentProps.children || componentProps.props["children"] || []
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
onMount(() => {
|
|
@@ -84,7 +84,7 @@ export const CardsEditor: Component<CardsEditorProps> = (componentProps) => {
|
|
|
84
84
|
<div class="w-32">
|
|
85
85
|
<RLSSelect
|
|
86
86
|
items={COLUMN_OPTIONS}
|
|
87
|
-
value={String(componentProps.props
|
|
87
|
+
value={String(componentProps.props["columns"] || 2)}
|
|
88
88
|
onChange={(e: Event & { currentTarget: HTMLSelectElement }) =>
|
|
89
89
|
setColumns(e.currentTarget.value)
|
|
90
90
|
}
|
|
@@ -37,15 +37,15 @@ export const CodeEditor: Component<CodeEditorProps> = (componentProps) => {
|
|
|
37
37
|
const saveProps = (lang?: string, code?: string, caption?: string) => {
|
|
38
38
|
componentProps.onPropsChange({
|
|
39
39
|
...componentProps.props,
|
|
40
|
-
language: lang !== undefined ? lang : componentProps.props
|
|
40
|
+
language: lang !== undefined ? lang : componentProps.props["language"] || "typescript",
|
|
41
41
|
code: code !== undefined ? code : codeTextarea?.value || "",
|
|
42
|
-
caption: caption !== undefined ? caption : componentProps.props
|
|
42
|
+
caption: caption !== undefined ? caption : componentProps.props["caption"] || ""
|
|
43
43
|
})
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
onMount(() => {
|
|
47
47
|
if (codeTextarea) {
|
|
48
|
-
codeTextarea.value = componentProps.props
|
|
48
|
+
codeTextarea.value = componentProps.props["code"] || ""
|
|
49
49
|
autoResize()
|
|
50
50
|
}
|
|
51
51
|
})
|
|
@@ -58,7 +58,7 @@ export const CodeEditor: Component<CodeEditorProps> = (componentProps) => {
|
|
|
58
58
|
<div class="w-36">
|
|
59
59
|
<RLSSelect
|
|
60
60
|
items={LANGUAGES}
|
|
61
|
-
value={componentProps.props
|
|
61
|
+
value={componentProps.props["language"] || "typescript"}
|
|
62
62
|
onChange={(e) => saveProps(e.currentTarget.value)}
|
|
63
63
|
size="xs"
|
|
64
64
|
/>
|
|
@@ -89,7 +89,7 @@ export const CodeEditor: Component<CodeEditorProps> = (componentProps) => {
|
|
|
89
89
|
<RLSInput
|
|
90
90
|
type="text"
|
|
91
91
|
data-field="caption"
|
|
92
|
-
value={componentProps.props
|
|
92
|
+
value={componentProps.props["caption"] || ""}
|
|
93
93
|
onBlur={(e) => saveProps(undefined, undefined, e.currentTarget.value)}
|
|
94
94
|
size="sm"
|
|
95
95
|
placeholder="Caption (optional)"
|