forked from cms/tibi-svelte-starter
✨ feat: enhance accessibility with skip to main content button and improve navigation handling
🔧 fix: update navigation href resolution to include localized paths 🆕 feat: add new FeatureIcon component for feature boxes 🎨 style: improve styling for prose elements in richtext blocks 🛠️ refactor: streamline medialib image loading and caching logic 📦 chore: update mock data handling to support new medialib entries 🔄 chore: synchronize i18n initialization and locale management 📝 docs: update video tour descriptions to reflect recent changes
This commit is contained in:
+96
-2
@@ -1,4 +1,40 @@
|
||||
import type { SvelteComponent } from "svelte"
|
||||
import { mount, unmount, type Component, type SvelteComponent } from "svelte"
|
||||
import BlockRenderer from "./blocks/BlockRenderer.svelte"
|
||||
|
||||
const previewCssUrl = new URL("./index.css", import.meta.url).toString()
|
||||
|
||||
type BlockRenderContext = {
|
||||
namespace?: string
|
||||
apiBase?: string
|
||||
projectBase?: string
|
||||
}
|
||||
|
||||
type BlockHandle = {
|
||||
update(row: Record<string, any>, context?: BlockRenderContext): void
|
||||
destroy(): void
|
||||
}
|
||||
|
||||
type BlockDefinition = {
|
||||
render(container: HTMLElement | ShadowRoot, row: Record<string, any>, context?: BlockRenderContext): BlockHandle
|
||||
css?: string[]
|
||||
previewStyles?: Record<string, string>
|
||||
label?: string
|
||||
icon?: string
|
||||
color?: string
|
||||
}
|
||||
|
||||
type BlockPresentation = {
|
||||
label: string
|
||||
icon: string
|
||||
color: string
|
||||
}
|
||||
|
||||
function getAdminPreviewProps(props?: { [key: string]: any }) {
|
||||
return {
|
||||
isAdminPreview: true,
|
||||
...(props || {}),
|
||||
}
|
||||
}
|
||||
|
||||
function getRenderedElement(
|
||||
component: typeof SvelteComponent,
|
||||
@@ -33,13 +69,71 @@ function getRenderedElement(
|
||||
|
||||
new component({
|
||||
target: target,
|
||||
props: options?.props,
|
||||
props: getAdminPreviewProps(options?.props),
|
||||
})
|
||||
|
||||
return el
|
||||
}
|
||||
|
||||
function createContentBlockDefinition(presentation: BlockPresentation): BlockDefinition {
|
||||
return {
|
||||
css: [previewCssUrl],
|
||||
label: presentation.label,
|
||||
icon: presentation.icon,
|
||||
color: presentation.color,
|
||||
previewStyles: {
|
||||
"background-color": "white",
|
||||
position: "relative",
|
||||
},
|
||||
render(container, row, context) {
|
||||
const target = document.createElement("div")
|
||||
target.dataset.adminPreview = "true"
|
||||
container.appendChild(target)
|
||||
|
||||
let mountedComponent = mount(BlockRenderer as Component<any>, {
|
||||
target,
|
||||
props: {
|
||||
blocks: [row as ContentBlockEntry],
|
||||
isAdminPreview: true,
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
update(nextRow) {
|
||||
unmount(mountedComponent)
|
||||
target.innerHTML = ""
|
||||
mountedComponent = mount(BlockRenderer as Component<any>, {
|
||||
target,
|
||||
props: {
|
||||
blocks: [nextRow as ContentBlockEntry],
|
||||
isAdminPreview: true,
|
||||
},
|
||||
})
|
||||
},
|
||||
destroy() {
|
||||
unmount(mountedComponent)
|
||||
target.remove()
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const blockRegistry = {
|
||||
hero: createContentBlockDefinition({ label: "Hero", icon: "image", color: "#1d4ed8" }),
|
||||
features: createContentBlockDefinition({ label: "Features", icon: "view_quilt", color: "#0f766e" }),
|
||||
richtext: createContentBlockDefinition({ label: "Richtext", icon: "article", color: "#7c3aed" }),
|
||||
accordion: createContentBlockDefinition({ label: "Accordion", icon: "expand", color: "#b45309" }),
|
||||
"contact-form": createContentBlockDefinition({
|
||||
label: "Contact Form",
|
||||
icon: "mail",
|
||||
color: "#be185d",
|
||||
}),
|
||||
}
|
||||
|
||||
export {
|
||||
getAdminPreviewProps,
|
||||
getRenderedElement,
|
||||
blockRegistry,
|
||||
// pass also required svelte components here
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user