|
|
|
@ -18,7 +18,8 @@ import { provideBlockId } from './context' |
|
|
|
|
import { |
|
|
|
|
align, |
|
|
|
|
background, |
|
|
|
|
bordering, clip, |
|
|
|
|
bordering, |
|
|
|
|
clip, |
|
|
|
|
gap, |
|
|
|
|
insets, |
|
|
|
|
radii, |
|
|
|
@ -41,11 +42,26 @@ export type WidgetRenderFunction = (widget: Widget, view: View, axis?: Axis) => |
|
|
|
|
*/ |
|
|
|
|
const widgets: Record<string, WidgetRenderFunction> = {} |
|
|
|
|
|
|
|
|
|
const views: Record<string, Component> = { |
|
|
|
|
text: DddTextView, |
|
|
|
|
image: DddImageView, |
|
|
|
|
audio: DddAudioView, |
|
|
|
|
video: DddAudioView, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
export function registerWidget(some: Record<string, WidgetRenderFunction>): void { |
|
|
|
|
for (const [key, func] of Object.entries(some)) |
|
|
|
|
widgets[key] = func |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function renderWidget(widget: Widget, view: View, axis?: Axis): VNodeChild { |
|
|
|
|
const func = widgets[widget.name] |
|
|
|
|
if (typeof func !== 'function') |
|
|
|
|
throw new Error(`unknown widget: ${widget.name}`) |
|
|
|
|
|
|
|
|
|
return func(widget, view, axis) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const isWidget = (s: any): s is Widget => s != null && 'name' in s |
|
|
|
|
|
|
|
|
|
function isRefer(s: any): s is DataRefer { |
|
|
|
@ -56,6 +72,24 @@ function isRefer(s: any): s is DataRefer { |
|
|
|
|
&& typeof s.key === 'string' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function renderRefer(refer: DataRefer, axis?: Axis): VNodeChild { |
|
|
|
|
const { key, type, ...attrs } = refer |
|
|
|
|
const component = views[type] |
|
|
|
|
if (component) { |
|
|
|
|
return h(component, { |
|
|
|
|
source: key, |
|
|
|
|
axis, |
|
|
|
|
...attrs, |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
return h('b', { |
|
|
|
|
style: { |
|
|
|
|
color: 'red', |
|
|
|
|
fontSize: '36px', |
|
|
|
|
}, |
|
|
|
|
}, 'unimplemented') |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
export function isFlexible(theme: Theme) { |
|
|
|
|
return theme.axis != null |
|
|
|
|
|| theme.mainAlign != null |
|
|
|
@ -74,51 +108,11 @@ export function render(view?: ViewChildren, axis?: Axis): VNodeChild { |
|
|
|
|
if (Array.isArray(view)) |
|
|
|
|
return view.map(v => render(v, axis)) |
|
|
|
|
|
|
|
|
|
if (isRefer(view)) { |
|
|
|
|
const { key, ...attrs } = view |
|
|
|
|
let component: Component | undefined |
|
|
|
|
switch (view.type) { |
|
|
|
|
case 'text': |
|
|
|
|
component = DddTextView |
|
|
|
|
return h(DddTextView, { |
|
|
|
|
source: view.key, |
|
|
|
|
}) |
|
|
|
|
case 'image': |
|
|
|
|
component = DddImageView |
|
|
|
|
return h(DddImageView, { |
|
|
|
|
source: key, |
|
|
|
|
...attrs, |
|
|
|
|
}) |
|
|
|
|
case 'audio': |
|
|
|
|
component = DddAudioView |
|
|
|
|
return h(DddAudioView, { |
|
|
|
|
source: view.key, |
|
|
|
|
title: view.title, |
|
|
|
|
}) |
|
|
|
|
case 'video': |
|
|
|
|
// todo ...
|
|
|
|
|
} |
|
|
|
|
if (component) { |
|
|
|
|
return h(component, { |
|
|
|
|
source: key, |
|
|
|
|
...attrs, |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
return h('b', { |
|
|
|
|
style: { |
|
|
|
|
color: 'red', |
|
|
|
|
fontSize: '36px', |
|
|
|
|
}, |
|
|
|
|
}, 'unimplemented') |
|
|
|
|
} |
|
|
|
|
if (isWidget(view.theme)) { |
|
|
|
|
const func = widgets[view.theme.name] |
|
|
|
|
if (typeof func !== 'function') |
|
|
|
|
throw new Error(`unknown widget: ${view.theme.name}`) |
|
|
|
|
if (isRefer(view)) |
|
|
|
|
return renderRefer(view) |
|
|
|
|
|
|
|
|
|
const widget = view.theme |
|
|
|
|
return func(widget, view, axis) |
|
|
|
|
} |
|
|
|
|
if (isWidget(view.theme)) |
|
|
|
|
return renderWidget(view.theme, view, axis) |
|
|
|
|
|
|
|
|
|
const theme = view.theme |
|
|
|
|
const css: CSSProperties = { |
|
|
|
|