create-modulo
Version:
Starter projects for Modulo.html - Ready for all uses - Markdown-SSG / SSR / API-backed SPA
215 lines (192 loc) • 6.17 kB
HTML
<script src=../Modulo.html></script><template type=f>
<Props
mode
value
demo
name
usage
splitusage
></Props>
<Template
-name="template_modulo_component"
-src="demos/modulo_component_demo.html"
></Template>
<Template
-name="template_modulo"
-src="demos/modulo_component_demo.html"
></Template>
<Template
-name="template_modulo_embed"
-src="demos/modulo_embed_demo.html"
></Template>
<Template
-name="template_html_demo"
-src="demos/html_demo.html"
></Template>
<Template>
<div class="editor-layout" style="--demo-width: {{ state.demo|yesno:'250,0' }}px;">
{% if state.menu %}
<div class="toolbar">
</div>
{% elif not state.demo %}
<x-SyntaxHighlighter
mode="{{ props.mode }}"
value="{{ props.value }}"
style="font-size: {{ editor_settings.font-size }}px"
></x-SyntaxHighlighter>
{% else %}
<x-MirrorEditor
state.bind
name="value"
mode="{{ props.mode }}"
></x-MirrorEditor>
{% endif %}
<div class="toolbar toolbar--small {% if not state.menu %}toolbar--autohide{% endif %}
{% if not state.demo %}toolbar--snippet{% endif %}">
{% if state.demo %}
<button on.click=script.copy><span alt="Clipboard icon">📋</span> Copy</button>
<button on.click=script.run><span alt="Refresh arrow in circle">⟳</span> Run</button>
<button on.click=script.save><span alt="Download arrow downward">⤓</span> Save</button>
{% else %}
<button on.click=script.copy><span alt="Clipboard icon">📋</span> Copy</button>
{% endif %}
</div>
{% if state.demo %}<iframe></iframe>{% endif %}
</div>
<div class="overlay"></div>
</Template>
<State
-store=editor_settings
-name=editor_settings
font-size:=18
demo-run-count:=0
></State>
<State
value:=null
demo:=null
menu:=false
modulo-src="../static/Modulo.html"
count:=0
last-run:=0
doctype="<!DOCTYPE HTML>"
usage="<x-App></x-App>"
name="App"
inputs:='["name","usage","doctype"]'
></State>
<Script>
//const EXAMPLE_START = '<!--%%%'
//const EXAMPLE_END = '%%%-->'
/*else if (props.value.includes(EXAMPLE_START)) {
state.value = props.value.split(EXAMPLE_START)[0]
state.name = props.value.split(EXAMPLE_START)[1]
.split(EXAMPLE_END)[0].trim()
state.usage = props.value.split(EXAMPLE_END)[1]
}*/
const REMOTE_MODULO_SRC = 'https://modu.lol'
function prepareCallback(renderObj) {
if (state.demo === null) { // First time, self-configure
state.value = props.value // Prepopulate state with demo
state.demo = false
if (props.demo) {
state.demo = 'template_' + props.demo
run() // ensure demo starts as run
}
if (props.name) {
state.name = props.name
}
if (props.usage) {
state.value = props.value.split(props.usage)[0]
state.usage = props.value.split(props.usage)[1]
}
}
}
function run() { // Mark as run (runs only after update, during callback)
state.count++
}
function buildCallback() {
//element.removeAttribute('value')
//element.removeAttribute('usage')
element.innerHTML = '' // TODO fix
}
function updateCallback() {
if (state.count > state.lastRun) {
refreshDemo()
state.lastRun = state.count // catch up
}
}
function render(extra = { }) {
const renderObj = parts.component.getCurrentRenderObj()
if (!(state.demo in renderObj)) { // No preview / demo for this!
return '<b>ERROR:</b> QuickDemo has no template: ' + state.demo
}
const ctx = Object.assign({ }, state, editor_settings, extra)
return renderObj[state.demo].render(ctx)
}
function copy() {
navigator.clipboard.writeText(state.value || props.value)
}
function refreshDemo() {
editor_settings.demoRunCount++
const text = render()
const oldIframe = element.querySelector('iframe') // Delete existing
const parentNode = oldIframe.parentNode
oldIframe.remove()
const iframe = document.createElement('iframe')
parentNode.append(iframe) // add new one back
iframe.contentWindow.document.open()
iframe.contentWindow.document.write(text)
iframe.contentWindow.document.close()
}
function toggle() {
state.menu = !state.menu
}
function save() {
const filename = state.name + '.html'
const text = render({ moduloSrc: REMOTE_MODULO_SRC })
const a = document.createElement('a')
const href = 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)
a.setAttribute('href', href)
a.setAttribute('download', filename)
element.append(a)
a.click()
a.remove(a)
}
</Script>
<Style>
:root {
--divider-width: 45px;
--divider-height: 35px;
display: block;
position: relative;
}
.overlay {
position: absolute;
width: var(--demo-width);
right: 0;
}
.editor-layout {
display: grid;
grid-template-columns: auto var(--divider-width) var(--demo-width);
}
iframe {
/* Always hardcode color defaults regardless of scheme */
border: none;
width: var(--demo-width);
background: #eee;
color: black;
min-height: 200px;
border-radius: 0 5px 5px 0;
}
@media (max-width: 992px) {
.editor-layout,
textarea,
:root {
display: block;
min-height: 200px;
}
iframe {
width: 99%;
}
}
</Style>
<Style -src="./QuickDemo-toolbar.css.htm"></Style>