added wireframes
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
* Add a new entry here and wire its language in ConfigNode to add a new config type.
|
||||
*/
|
||||
|
||||
export type ConfigTypeId = 'plantuml' | 'markdown'
|
||||
export type ConfigTypeId = 'plantuml' | 'markdown' | 'wireframe'
|
||||
|
||||
/** A single insert option (label + snippet to insert at cursor). */
|
||||
export type InsertBlock = { label: string; snippet: string }
|
||||
@@ -18,6 +18,9 @@ function isGroup(b: InsertBlockOrGroup): b is InsertBlockGroup {
|
||||
return 'items' in b && Array.isArray((b as InsertBlockGroup).items)
|
||||
}
|
||||
|
||||
/** Optional options passed to render (e.g. node size for wireframe SVG). */
|
||||
export type RenderOptions = { width?: number; height?: number }
|
||||
|
||||
export type ConfigType = {
|
||||
id: ConfigTypeId
|
||||
label: string
|
||||
@@ -26,7 +29,7 @@ export type ConfigType = {
|
||||
/** Options under Insert → [type-specific]. Can be flat blocks or groups. */
|
||||
insertBlocks: InsertBlockOrGroup[]
|
||||
/** Render resolved content (after Nunjucks) to HTML/SVG string for the renderer. */
|
||||
render: (content: string) => Promise<string>
|
||||
render: (content: string, options?: RenderOptions) => Promise<string>
|
||||
}
|
||||
|
||||
const KROKI_PLANTUML_SVG = '/api/kroki/plantuml/svg'
|
||||
@@ -74,6 +77,30 @@ const MARKDOWN_INSERT_BLOCKS: InsertBlockOrGroup[] = [
|
||||
},
|
||||
]
|
||||
|
||||
/** Wireweave DSL: https://github.com/wireweave/core */
|
||||
const WIREFRAME_INSERT_BLOCKS: InsertBlockOrGroup[] = [
|
||||
{ label: 'Page', snippet: 'page "Title" {\n \n}' },
|
||||
{ label: 'Card', snippet: 'card p=4 {\n \n}' },
|
||||
{ label: 'Title', snippet: 'title "' },
|
||||
{ label: 'Text', snippet: 'text "' },
|
||||
{ label: 'Button', snippet: 'button "Label"' },
|
||||
{ label: 'Primary button', snippet: 'button "Label" primary' },
|
||||
{ label: 'Input', snippet: 'input placeholder=""' },
|
||||
{ label: 'Row', snippet: 'row {\n col span=6 { }\n}' },
|
||||
{ label: 'Col', snippet: 'col span=6 { }' },
|
||||
{ label: 'Header / Main / Footer', snippet: 'header { }\nmain { }\nfooter { }' },
|
||||
{ label: 'Image', snippet: 'image "" w=400 h=300' },
|
||||
{
|
||||
label: 'Templating',
|
||||
items: [
|
||||
{ label: 'Variable {{ }}', snippet: '{{ }}' },
|
||||
{ label: 'if / endif', snippet: '{% if %}\n \n{% endif %}' },
|
||||
{ label: 'for / endfor', snippet: '{% for in %}\n \n{% endfor %}' },
|
||||
{ label: 'set', snippet: '{% set = %}' },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
/** Markdown to HTML using dynamic import to avoid loading if only PlantUML is used. */
|
||||
async function renderMarkdown(content: string): Promise<string> {
|
||||
const { marked } = await import('marked')
|
||||
@@ -81,6 +108,17 @@ async function renderMarkdown(content: string): Promise<string> {
|
||||
return typeof html === 'string' ? html : String(html)
|
||||
}
|
||||
|
||||
/** Wireweave DSL to HTML+CSS; theme from document dark mode. See https://www.wireweave.org/ */
|
||||
async function renderWireframe(content: string): Promise<string> {
|
||||
const { parse, render } = await import('@wireweave/core')
|
||||
const doc = parse(content)
|
||||
const isDark =
|
||||
typeof document !== 'undefined' &&
|
||||
document.documentElement?.classList?.contains('dark')
|
||||
const { html, css } = render(doc, { theme: isDark ? 'dark' : 'light' })
|
||||
return `<style>${css}</style>${html}`
|
||||
}
|
||||
|
||||
export const CONFIG_TYPES: ConfigType[] = [
|
||||
{
|
||||
id: 'plantuml',
|
||||
@@ -107,6 +145,13 @@ export const CONFIG_TYPES: ConfigType[] = [
|
||||
insertBlocks: MARKDOWN_INSERT_BLOCKS,
|
||||
render: renderMarkdown,
|
||||
},
|
||||
{
|
||||
id: 'wireframe',
|
||||
label: 'Wireframe',
|
||||
language: 'markdown',
|
||||
insertBlocks: WIREFRAME_INSERT_BLOCKS,
|
||||
render: renderWireframe,
|
||||
},
|
||||
]
|
||||
|
||||
export const CONFIG_TYPE_IDS = CONFIG_TYPES.map((t) => t.id)
|
||||
@@ -121,6 +166,15 @@ export function getConfigType(id: ConfigTypeId): ConfigType {
|
||||
export function getDefaultContentForConfigType(configTypeId: ConfigTypeId): string {
|
||||
if (configTypeId === 'plantuml') return '@startuml\n\n@enduml\n'
|
||||
if (configTypeId === 'markdown') return ''
|
||||
if (configTypeId === 'wireframe') {
|
||||
return `page "Hello" {
|
||||
card p=4 {
|
||||
title "Welcome"
|
||||
text "Hello, wireweave!"
|
||||
button "Get Started" primary
|
||||
}
|
||||
}`
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user