diff --git a/src/app/Router.ts b/src/app/Router.ts index 3f79429c..818e1e7b 100644 --- a/src/app/Router.ts +++ b/src/app/Router.ts @@ -14,18 +14,21 @@ const router = async () => { const urlParams = new URLSearchParams(location.search) const target = document.getElementById('app')! - const view = new View() let title = locale('title.home') + let renderer = (view: View) => '' + let panel = 'home' if (urlParts.length === 0){ App.model.set({ id: '', name: 'Data Pack', category: true, minVersion: '1.15'}) - target.innerHTML = Home(view) + renderer = Home } else if (urlParts[0] === 'settings' && urlParts[1] === 'fields') { - target.innerHTML = FieldSettings(view) + panel = 'settings' + renderer = FieldSettings } else if (urlParts.length === 1 && categories.map(m => m.id).includes(urlParts[0])) { App.model.set(categories.find(m => m.id === urlParts[0])!) - target.innerHTML = Home(view) + renderer = Home } else { + panel = 'tree' App.model.set(config.models.find(m => m.id === urlParts.join('/'))!) if (urlParams.has('q')) { try { @@ -33,14 +36,16 @@ const router = async () => { Models[App.model.get()!.id].reset(JSON.parse(data)) } catch (e) {} } - target.innerHTML = Generator(view) + renderer = Generator if (App.model.get()) { title = locale('title.generator', [locale(App.model.get()!.id)]) } } document.title = locale('title.suffix', [title]) - view.mounted(target) + App.mobilePanel.set(panel) + const view = new View() + view.mount(target, renderer(view), true) } window.addEventListener("popstate", router); diff --git a/src/app/components/Header.ts b/src/app/components/Header.ts index 9a152ef3..dbe58038 100644 --- a/src/app/components/Header.ts +++ b/src/app/components/Header.ts @@ -6,14 +6,38 @@ import { Toggle } from './Toggle'; import { languages } from '../../config.json' import { Tracker } from '../Tracker'; -export const Header = (view: View, title: string, homeLink = '/', panelToggleVisible = false) => ` -
+export const Header = (view: View, title: string, homeLink = '/') => { + const panelTogglesId = view.register(el => { + const getPanelToggles = () => { + const panels = [['preview', 'play'], ['tree', 'note'], ['source', 'code']] + if (!panels.map(e => e[0]).includes(App.mobilePanel.get())) return '' + return panels + .filter(e => e[0] !== App.mobilePanel.get()) + .filter(e => e[0] !== 'preview' || App.preview.get() !== null) + .map(e => `
+ ${Octicon[e[1] as keyof typeof Octicon]} +
`).join('') + } + App.mobilePanel.watchRun(() => { + view.mount(el, getPanelToggles(), false) + }) + App.preview.watchRun((value, oldValue) => { + if (value === null && App.mobilePanel.get() === 'preview') { + App.mobilePanel.set('tree') + } + if (value === null || oldValue === null) { + view.mount(el, getPanelToggles(), false) + } + }) + }) + + return `
-
-` +
` +} diff --git a/src/app/views/Generator.ts b/src/app/views/Generator.ts index c049e03e..abebb8c1 100644 --- a/src/app/views/Generator.ts +++ b/src/app/views/Generator.ts @@ -59,7 +59,7 @@ export const Generator = (view: View): string => { }, 'generator') }) const homeLink = typeof App.model.get()!.category === 'string' ? `/${App.model.get()!.category}/` : undefined - return `${Header(view, `${App.model.get()!.name} Generator`, homeLink, true)} + return `${Header(view, `${App.model.get()!.name} Generator`, homeLink)}
${SplitGroup(view, { direction: "horizontal", sizes: [66, 34] }, [ TreePanel(view, model), diff --git a/src/styles/global.css b/src/styles/global.css index e7575b7f..051c7c85 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -55,11 +55,19 @@ header { justify-content: space-between; align-items: center; padding: 10px; + width: 100%; height: 56px; + z-index: 5; + background-color: var(--background); border-bottom: 2px solid var(--border); transition: border-color var(--style-transition), background-color var(--style-transition); } +body[data-panel="home"] header, +body[data-panel="settings"] header { + position: fixed; +} + .header-title { display: flex; align-items: center; @@ -70,6 +78,10 @@ header { transition: color var(--style-transition); } +.home { + padding-top: 56px; +} + .home-link { margin: 0 8px 0 0; height: 32px; @@ -83,12 +95,16 @@ header { padding: 2px; } +.panel-toggles { + display: none; +} + nav ul { display: flex; align-items: center; } -nav > .toggle, +.panel-toggles > *, nav li { display: flex; align-items: center; @@ -97,6 +113,7 @@ nav li { user-select: none; } +.panel-toggles > *:hover svg, .home-link:hover svg, header .toggle:hover svg, nav li:hover svg { @@ -115,6 +132,7 @@ nav li.dimmed:hover svg { fill: var(--nav-faded-hover); } +.panel-toggles svg, nav > .toggle svg, nav li > *, nav li svg { @@ -471,6 +489,7 @@ nav > .toggle span { .settings { padding: 20px; + padding-top: 56px; } .settings p { @@ -587,35 +606,49 @@ nav > .toggle span { @media screen and (max-width: 580px) { header { - flex-direction: column; - height: 92px; - width: 100%; - background-color: var(--background); - z-index: 5; position: fixed; } + + + .header-title h2 { + font-size: 22px; + } - nav { + .panel-toggles { + display: flex; + } + + body nav ul { + display: none; + } + + body[data-panel="home"] header { + flex-direction: column; + align-items: flex-start; + height: 92px; + } + body[data-panel="home"] nav { align-self: flex-end; } - .home, - .settings, + body[data-panel="home"] nav ul { + display: flex; + } + .content { - padding-top: 92px; + padding-top: 56px; } .content { height: unset; - /* min-height: calc(100vh - 92px); */ min-height: 100%; } textarea.source { - height: calc(100vh - 98px); + height: calc(100vh - 56px); } - .tree-panel + .gutter { + .gutter { display: none; } @@ -624,24 +657,36 @@ nav > .toggle span { width: 100% !important; } + .source-panel, + .preview-panel, + .preview-panel canvas { + height: 100% !important; + } + .tree-panel .panel-controls { - top: 97px; + top: 61px; right: 5px; position: fixed; } - nav > .toggle { - display: flex; - position: absolute; - left: 10px; + .btn.btn.large-input, + .panel-menu .result-list { + width: calc(100vw - 10px); } - body[data-panel="tree"] .content-output { + .tree-panel, + .content-output, + .source-panel, + .preview-panel { display: none; } - body[data-panel="source"] .tree-panel { - display: none; + body[data-panel="tree"] .tree-panel, + body[data-panel="source"] .source-panel, + body[data-panel="source"] .content-output, + body[data-panel="preview"] .preview-panel, + body[data-panel="preview"] .content-output { + display: block; } .home { @@ -677,8 +722,8 @@ nav > .toggle span { } } -@media screen and (min-width: 581px) and (max-width: 640px) { +@media screen and (min-width: 581px) and (max-width: 650px) { .header-title h2 { - font-size: 23px; + font-size: 22px; } } diff --git a/src/styles/nodes.css b/src/styles/nodes.css index 2519c247..fa31300e 100644 --- a/src/styles/nodes.css +++ b/src/styles/nodes.css @@ -95,6 +95,7 @@ font-size: 18px; padding: 0 9px; line-height: 1.94rem; + white-space: nowrap; user-select: none; cursor: pointer; background-color: var(--node-background-input);