Skip to content

Commit

Permalink
refactor: demo configuration, allow async ConfigCallback
Browse files Browse the repository at this point in the history
  • Loading branch information
tpluscode committed Dec 3, 2024
1 parent 781fc5e commit 00c91e1
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 95 deletions.
176 changes: 93 additions & 83 deletions demos/lit-html/src/configure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { DescriptionTooltip } from '@hydrofoil/shaperone-playground-examples/Des
import * as vaadinComponents from '@hydrofoil/shaperone-wc-vaadin/components.js'
import * as shoelaceComponents from '@hydrofoil/shaperone-wc-shoelace/components.js'
import { settings as shoelaceSettings } from '@hydrofoil/shaperone-wc-shoelace/settings.js'
import type { ConfigCallback } from '@hydrofoil/shaperone-wc/configure.js'
import { configure } from '@hydrofoil/shaperone-wc/configure.js'
import { dash } from '@tpluscode/rdf-ns-builders'
import type { Decorate, RenderTemplate } from '@hydrofoil/shaperone-wc/templates.js'
Expand All @@ -25,30 +26,53 @@ import type { RendererState } from './state/models/renderer.js'
setBasePath('https://unpkg.com/@shoelace-style/shoelace/dist')
shoelaceSettings.hoist = false

const { editors, components, validation, renderer } = configure($rdf)

export const componentSets: Record<ComponentsState['components'], Record<string, Component>> = {
native: { ...nativeComponents, starRating },
material: { ...nativeComponents, ...mwcComponents, languages: LanguageSelect.component('material'), starRating },
vaadin: { ...nativeComponents, ...vaadinComponents, languages: LanguageSelect.component('lumo'), starRating },
shoelace: { ...nativeComponents, ...shoelaceComponents, starRating },
}

editors.addMetadata(env => [...LanguageSelect.metadata(env), ...StarRating.metadata(env)])
editors.addMatchers({
languages: LanguageSelect.matcher,
starRating: StarRating.matcher,
})
shaperoneHydra({ editors, components })
components.decorate(DescriptionTooltip)
function * focusNodeDecorators(labs: RendererState['labs']) {
if (labs?.xone) {
yield xone.focusNode
}
if (labs?.errorSummary) {
yield errorSummary
}
yield MaterialRenderStrategy.focusNode
}

let focusNodeTemplate = templates.focusNode

validation.setValidator(validate)
const initialRenderStrategy = {
...templates,
...MaterialRenderStrategy,
focusNode: [...focusNodeDecorators({})].reduce(combineDecorators, focusNodeTemplate),
}

configure($rdf, ({ editors, components, validation, renderer }) => {
editors.addMetadata(env => [...LanguageSelect.metadata(env), ...StarRating.metadata(env)])
editors.addMatchers({
languages: LanguageSelect.matcher,
starRating: StarRating.matcher,
})
shaperoneHydra({
editors,
components,
})
components.decorate(DescriptionTooltip)

validation.setValidator(validate)

renderer.setTemplates(initialRenderStrategy)
})

export const selectComponents = (() => {
let currentComponents = componentSets.native
let previousComponents: ComponentsState['components'] | undefined

return (name: ComponentsState['components']) => {
return (name: ComponentsState['components']): ConfigCallback => ({ components }) => {
if (previousComponents === name) return
previousComponents = name

Expand All @@ -64,91 +88,77 @@ function combineDecorators<Template extends RenderTemplate>(combined: Template,
}

export const configureRenderer = (() => {
function * focusNodeDecorators(labs: RendererState['labs']) {
if (labs?.xone) {
yield xone.focusNode
}
if (labs?.errorSummary) {
yield errorSummary
}
yield MaterialRenderStrategy.focusNode
}

let focusNodeTemplate = templates.focusNode

const initialStrategy = {
...templates,
...MaterialRenderStrategy,
focusNode: [...focusNodeDecorators({})].reduce(combineDecorators, focusNodeTemplate),
}

renderer.setTemplates(initialStrategy)

let previousNesting: RendererState['nesting']
let previousGrouping: RendererState['grouping']
let previousLabs: RendererState['labs']

return {
async switchNesting({ nesting }: RendererState) {
if (previousNesting === nesting) return
previousNesting = nesting

if (nesting === 'always one') {
const { topmostFocusNodeFormRenderer } = await import('@hydrofoil/shaperone-playground-examples/NestedShapesIndividually/renderer.js')
const nestingComponents = await import('@hydrofoil/shaperone-playground-examples/NestedShapesIndividually/components.js')

renderer.setTemplates({
form: topmostFocusNodeFormRenderer(initialStrategy.form),
})
components.pushComponents(nestingComponents)
} else if (nesting === 'inline') {
const nestingComponents = await import('@hydrofoil/shaperone-playground-examples/InlineNestedShapes')
components.pushComponents(nestingComponents)
} else {
renderer.setTemplates({ form: initialStrategy.form })
components.removeComponents([dash.DetailsEditor])
switchNesting({ nesting }: RendererState): ConfigCallback {
return async ({ renderer, components }) => {
if (previousNesting === nesting) return
previousNesting = nesting

if (nesting === 'always one') {
const { topmostFocusNodeFormRenderer } = await import('@hydrofoil/shaperone-playground-examples/NestedShapesIndividually/renderer.js')
const nestingComponents = await import('@hydrofoil/shaperone-playground-examples/NestedShapesIndividually/components.js')

renderer.setTemplates({
form: topmostFocusNodeFormRenderer(initialRenderStrategy.form),
})
components.pushComponents(nestingComponents)
} else if (nesting === 'inline') {
const nestingComponents = await import('@hydrofoil/shaperone-playground-examples/InlineNestedShapes')
components.pushComponents(nestingComponents)
} else {
renderer.setTemplates({ form: initialRenderStrategy.form })
components.removeComponents([dash.DetailsEditor])
}
}
},

async switchLayout({ grouping, labs }: RendererState) {
if (previousGrouping === grouping) return
previousGrouping = grouping

const strategy = {
focusNode: initialStrategy.focusNode,
group: initialStrategy.group,
switchLayout({ grouping, labs }: RendererState): ConfigCallback {
return async ({ renderer }) => {
if (previousGrouping === grouping) return
previousGrouping = grouping

const strategy = {
focusNode: initialRenderStrategy.focusNode,
group: initialRenderStrategy.group,
}

if (grouping === 'vaadin accordion') {
const {
AccordionGroupingRenderer,
AccordionFocusNodeRenderer,
} = await import('@hydrofoil/shaperone-wc-vaadin/renderer/accordion.js')

strategy.group = AccordionGroupingRenderer
focusNodeTemplate = AccordionFocusNodeRenderer
} else if (grouping === 'material tabs') {
const {
TabsGroupRenderer,
TabsFocusNodeRenderer,
} = await import('@hydrofoil/shaperone-wc-material/renderer/tabs.js')

strategy.group = TabsGroupRenderer
focusNodeTemplate = TabsFocusNodeRenderer
}

strategy.focusNode = [...focusNodeDecorators(labs)].reduce(combineDecorators, focusNodeTemplate)
renderer.setTemplates(strategy)
}

if (grouping === 'vaadin accordion') {
const {
AccordionGroupingRenderer,
AccordionFocusNodeRenderer,
} = await import('@hydrofoil/shaperone-wc-vaadin/renderer/accordion.js')

strategy.group = AccordionGroupingRenderer
focusNodeTemplate = AccordionFocusNodeRenderer
} else if (grouping === 'material tabs') {
const {
TabsGroupRenderer,
TabsFocusNodeRenderer,
} = await import('@hydrofoil/shaperone-wc-material/renderer/tabs.js')

strategy.group = TabsGroupRenderer
focusNodeTemplate = TabsFocusNodeRenderer
}

strategy.focusNode = [...focusNodeDecorators(labs)].reduce(combineDecorators, focusNodeTemplate)
renderer.setTemplates(strategy)
},

async setLabs({ labs }: RendererState) {
if (JSON.stringify(previousLabs) === JSON.stringify(labs)) return
setLabs({ labs }: RendererState): ConfigCallback {
return ({ renderer }) => {
if (JSON.stringify(previousLabs) === JSON.stringify(labs)) return

previousLabs = labs
previousLabs = labs

renderer.setTemplates({
focusNode: [...focusNodeDecorators(labs)].reduce(combineDecorators, focusNodeTemplate),
})
renderer.setTemplates({
focusNode: [...focusNodeDecorators(labs)].reduce(combineDecorators, focusNodeTemplate),
})
}
},
}
})()
11 changes: 5 additions & 6 deletions demos/lit-html/src/shaperone-playground-lit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import '@vaadin/vaadin-item/vaadin-item.js'
import '@material/mwc-icon/mwc-icon.js'
import '@vaadin-component-factory/vcf-tooltip'
import type { ShaperoneForm } from '@hydrofoil/shaperone-wc'
import '@hydrofoil/shaperone-wc/shaperone-form'
import '@rdfjs-elements/rdf-editor'
import '@rdfjs-elements/rdf-editor/rdf-editor.js'
import '@github/clipboard-copy-element'
import { connect } from '@captaincodeman/rdx'
import type { Quad } from '@rdfjs/types'
Expand Down Expand Up @@ -334,10 +333,10 @@ export class ShaperonePlayground extends connect(store(), LitElement) {
}

mapState(state: State) {
selectComponents(state.componentsSettings.components)
configureRenderer.switchLayout(state.rendererSettings)
configureRenderer.switchNesting(state.rendererSettings)
configureRenderer.setLabs(state.rendererSettings)
this.form.configure(selectComponents(state.componentsSettings.components))
this.form.configure(configureRenderer.switchLayout(state.rendererSettings))
this.form.configure(configureRenderer.switchNesting(state.rendererSettings))
this.form.configure(configureRenderer.setLabs(state.rendererSettings))

return {
components: state.componentsSettings,
Expand Down
4 changes: 2 additions & 2 deletions packages/wc/configure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export interface ConfigCallback {
renderer: typeof renderer
editors: typeof editors
validation: typeof validation
}): void
}): void | Promise<void>
}

export async function configure(): Promise<void>
Expand All @@ -50,7 +50,7 @@ export async function configure(first?: RequiredEnvironment | ConfigCallback, se
components.pushComponents(nativeComponents)
await editors.loadDash()

userConfigure?.({ components, renderer, editors, validation })
await userConfigure?.({ components, renderer, editors, validation })

await import('./lib/shaperone-form.js')
}
12 changes: 8 additions & 4 deletions packages/wc/demo/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import 'api-viewer-element/lib/api-docs.js'
import '../shaperone-form.js'
import { configure } from '../index.js'

(async () => {
await configure()

const { default: { tags } } = await import('../custom-elements.json')

import('../custom-elements.json').then((data: any) => {
const demoViewer = document.querySelector('api-docs')
if (demoViewer) {
demoViewer.elements = data.tags
demoViewer.elements = tags as any
}
})
})()

0 comments on commit 00c91e1

Please sign in to comment.