@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.
Files changed (51) hide show
  1. package/dist/index.d.mts +17 -17
  2. package/dist/index.mjs +47 -47
  3. package/dist/schema/index.d.mts +13 -13
  4. package/dist/schema/sqlite.d.mts +12 -12
  5. package/package.json +9 -4
  6. package/src/admin/api/media-file.ts +1 -1
  7. package/src/admin/pages/assets.astro +11 -11
  8. package/src/admin/pages/pages-edit.astro +3 -3
  9. package/src/admin/pages/pages-index.astro +2 -2
  10. package/src/admin/pages/pages-preview.astro +3 -3
  11. package/src/admin/pages/pages-review.astro +2 -2
  12. package/src/admin/pages/templates-edit.astro +1 -1
  13. package/src/admin/pages/templates-index.astro +1 -1
  14. package/src/astro/BlockRenderer.astro +1 -1
  15. package/src/astro/blocks/CalloutBlock.astro +1 -1
  16. package/src/astro/blocks/OrderedListBlock.astro +2 -2
  17. package/src/astro/blocks/ParagraphBlock.astro +1 -1
  18. package/src/astro/blocks/TabsBlock.astro +5 -5
  19. package/src/astro/blocks/UnorderedListBlock.astro +2 -2
  20. package/src/auth/editor-guards.ts +1 -1
  21. package/src/cache/purge.ts +2 -2
  22. package/src/client/components/RimelightBlock.tsx +1 -1
  23. package/src/client/components/RimelightBlockPicker.tsx +1 -1
  24. package/src/client/components/RimelightPreview.tsx +27 -27
  25. package/src/client/components/RimelightPropertiesPanel.tsx +4 -4
  26. package/src/client/components/RimelightTemplateEditor.tsx +9 -5
  27. package/src/client/components/editors/CalloutEditor.tsx +10 -10
  28. package/src/client/components/editors/CardEditor.tsx +5 -5
  29. package/src/client/components/editors/CardsEditor.tsx +2 -2
  30. package/src/client/components/editors/CodeEditor.tsx +5 -5
  31. package/src/client/components/editors/DialogueEditor.tsx +6 -6
  32. package/src/client/components/editors/FileTreeEditor.tsx +1 -1
  33. package/src/client/components/editors/ImageEditor.tsx +9 -9
  34. package/src/client/components/editors/ParagraphEditor.tsx +1 -1
  35. package/src/client/components/editors/SceneEditor.tsx +9 -9
  36. package/src/client/components/editors/ScriptEditor.tsx +8 -8
  37. package/src/client/components/editors/SectionEditor.tsx +3 -3
  38. package/src/client/components/editors/StepItemEditor.tsx +6 -5
  39. package/src/client/components/editors/StepsEditor.tsx +1 -1
  40. package/src/client/components/editors/TabItemEditor.tsx +3 -3
  41. package/src/client/components/editors/TableEditor.tsx +4 -4
  42. package/src/client/components/editors/TabsEditor.tsx +1 -1
  43. package/src/client/state/editor-store.ts +23 -23
  44. package/src/client/utils/sortable.ts +13 -12
  45. package/src/client/utils/tree-sanitizer.ts +1 -1
  46. package/src/core/excerpt.ts +16 -16
  47. package/src/core/page-definitions.ts +2 -2
  48. package/src/docs/agent.ts +1 -1
  49. package/src/docs/routing.ts +2 -2
  50. package/src/loader/live.ts +1 -1
  51. 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.id;
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>).en || ""
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>).en || ""
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>).en || ""
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.pageId;
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.id;
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.CMS_PREVIEW_SECRET || "rimelight-preview-secret-key";
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>).en || ""
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.id;
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>).en || ""
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.id;
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.id;
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
  ---
@@ -61,7 +61,7 @@ const variantConfigs: Record<
61
61
  }
62
62
  }
63
63
 
64
- const config = (variantConfigs[variant as CalloutVariant] || variantConfigs.info)!
64
+ const config = (variantConfigs[variant as CalloutVariant] || variantConfigs["info"])!
65
65
  const Tag = to ? "a" : "div"
66
66
  ---
67
67
 
@@ -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>
@@ -8,7 +8,7 @@ interface Props {
8
8
  }
9
9
 
10
10
  const { block, locale = "en" } = Astro.props
11
- const rawText = block.props?.text
11
+ const rawText = block.props?.["text"]
12
12
 
13
13
  function escapeHtml(str: string): string {
14
14
  return (str || "")
@@ -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.icon} mr-1.5 inline-block size-3.5 align-text-bottom`} />}
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.children
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
  }
@@ -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.CLOUDFLARE_ZONE_ID
12
- const apiToken = process.env.CLOUDFLARE_API_TOKEN
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.children
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.Root || []
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.title || "")
29
- const [description, setDescription] = createSignal<string>(props.description || "")
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.children
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.text
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.title || "Untitled Section"
175
+ const title = props["title"] || "Untitled Section"
176
176
  const slug = title.toLowerCase().replace(/\W+/g, "-")
177
- const description = props.description
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.variant || "info"
198
- const to = props.to
199
- const target = props.target || "_self"
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.info
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.src || props.url || ""
241
- const alt = props.alt || "Image"
242
- const caption = props.caption
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.code || textVal
251
- const language = props.language || "plaintext"
252
- const caption = props.caption
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.title || "Untitled Script"
262
- const synopsis = props.synopsis
263
- const chars = props.characters || []
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.setting] || props.setting || "INT."
311
- const location = props.location || ""
312
- const tod = timeOfDayLabels[props.timeOfDay] || props.timeOfDay || "Morning"
313
- const transition = transitionLabels[props.transition] || ""
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.description ? `<p class="text-sm text-neutral-700 mb-2">${escapeHtml(props.description)}</p>` : ""}
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.character || "CHARACTER"
336
- const parenthetical = props.parenthetical
337
- const line = props.line || ""
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.text || block.props.title || block.props.code || block.props.src || ""
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.title = val
224
- else if (b.type === "CodeBlock") b.props.code = val
225
- else if (b.type === "ImageBlock") b.props.src = val
226
- else b.props.text = { en: val }
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.to)
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.variant || "info"
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.children || []
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.to,
93
- target: target !== undefined ? target : componentProps.props.target
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.to ? "Linked" : "Add Link"}
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.to || ""}
138
+ value={componentProps.props["to"] || ""}
139
139
  onBlur={(e: FocusEvent & { currentTarget: HTMLInputElement }) =>
140
- saveLinkProps(e.currentTarget.value, componentProps.props.target)
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.target || "_self"}
148
+ value={componentProps.props["target"] || "_self"}
149
149
  onChange={(e: Event & { currentTarget: HTMLSelectElement }) =>
150
- saveLinkProps(componentProps.props.to, e.currentTarget.value)
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.title || ""}
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.href || ""}
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.description || ""}
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.icon || ""}
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.badge || ""}
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.children || []
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.columns || 2)}
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.language || "typescript",
40
+ language: lang !== undefined ? lang : componentProps.props["language"] || "typescript",
41
41
  code: code !== undefined ? code : codeTextarea?.value || "",
42
- caption: caption !== undefined ? caption : componentProps.props.caption || ""
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.code || ""
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.language || "typescript"}
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.caption || ""}
92
+ value={componentProps.props["caption"] || ""}
93
93
  onBlur={(e) => saveProps(undefined, undefined, e.currentTarget.value)}
94
94
  size="sm"
95
95
  placeholder="Caption (optional)"