Initial commit
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
// Demo page behaviour. Not a build input — see src/demo/demo.scss.
|
||||
import '../sass/main.scss'
|
||||
import './demo.scss'
|
||||
|
||||
// -- Colour swatches ---------------------------------------------------------
|
||||
//
|
||||
// Read from the emitted custom properties rather than from a hand-kept list, so
|
||||
// the demo cannot drift from the stylesheet: delete a token and its swatch
|
||||
// disappears on reload.
|
||||
|
||||
function emittedTokens (group) {
|
||||
const names = new Set()
|
||||
for (const sheet of document.styleSheets) {
|
||||
let rules
|
||||
try { rules = sheet.cssRules } catch { continue } // cross-origin
|
||||
for (const rule of rules) {
|
||||
if (rule.selectorText !== ':root') continue
|
||||
for (const prop of rule.style) {
|
||||
if (prop.startsWith(`--tlig-${group}-`)) names.add(prop)
|
||||
}
|
||||
}
|
||||
}
|
||||
return [...names]
|
||||
}
|
||||
|
||||
function renderSwatches () {
|
||||
const root = getComputedStyle(document.documentElement)
|
||||
const html = emittedTokens('color').map((name) => {
|
||||
const value = root.getPropertyValue(name).trim()
|
||||
const short = name.replace('--tlig-color-', '')
|
||||
return `<figure class="swatch">
|
||||
<div class="swatch__chip"><div class="swatch__fill" style="background:${value}"></div></div>
|
||||
<figcaption class="swatch__meta">
|
||||
<div class="swatch__name">${short}</div>
|
||||
<div class="swatch__value">${value}</div>
|
||||
</figcaption>
|
||||
</figure>`
|
||||
}).join('')
|
||||
document.querySelector('#swatches').innerHTML = html
|
||||
document.querySelector('#swatch-count').textContent = emittedTokens('color').length
|
||||
}
|
||||
|
||||
// -- Script switcher ---------------------------------------------------------
|
||||
//
|
||||
// The point of this control: all four papyrus files share one family name and
|
||||
// are separated by unicode-range, so switching scripts changes no CSS at all.
|
||||
// The browser picks the font file by codepoint.
|
||||
|
||||
const SAMPLES = {
|
||||
en: {
|
||||
label: 'English',
|
||||
heading: 'True Life in God',
|
||||
line: 'Peace be with you — I am the Alpha and the Omega.',
|
||||
note: 'Latin — PapyrusLETBold, the original file.',
|
||||
},
|
||||
hu: {
|
||||
// The pangram, not the site's own title: "Igaz Élet Istenben" contains no
|
||||
// codepoint above U+00FF, so it would be served by the Latin file and
|
||||
// would demonstrate nothing. ő (U+0151) and ű (U+0171) are the test.
|
||||
label: 'Magyar',
|
||||
heading: 'Árvíztűrő tükörfúrógép',
|
||||
line: 'Igaz Élet Istenben — ő and ű are what the Latin-Extended cut is for.',
|
||||
note: 'Latin Extended-A — the hu file. The original PapyrusLETBold has no ő or ű.',
|
||||
},
|
||||
bg: {
|
||||
label: 'Български',
|
||||
heading: 'Истински живот в Бога',
|
||||
line: 'Мир на вас — Аз съм Алфа и Омега.',
|
||||
note: 'Cyrillic — the cyrillic and bulgarian cuts.',
|
||||
},
|
||||
ru: {
|
||||
label: 'Русский',
|
||||
heading: 'Истинная жизнь в Боге',
|
||||
line: 'Мир вам — Я есмь Альфа и Омега.',
|
||||
note: 'Cyrillic — same file as Bulgarian, no extra rule.',
|
||||
},
|
||||
el: {
|
||||
label: 'Ελληνικά',
|
||||
heading: 'Αληθινή εν Θεώ Ζωή',
|
||||
line: 'Ειρήνη υμίν — Εγώ ειμι το Άλφα και το Ωμέγα.',
|
||||
note: 'No papyrus cut exists for Greek — this is the fallback face, shown honestly.',
|
||||
},
|
||||
}
|
||||
|
||||
function setScript (code) {
|
||||
const sample = SAMPLES[code]
|
||||
if (!sample) return
|
||||
document.querySelector('#script-heading').textContent = sample.heading
|
||||
document.querySelector('#script-line').textContent = sample.line
|
||||
document.querySelector('#script-note').textContent = sample.note
|
||||
document.querySelector('#script-heading').lang = code
|
||||
for (const button of document.querySelectorAll('[data-script]')) {
|
||||
button.setAttribute('aria-pressed', String(button.dataset.script === code))
|
||||
}
|
||||
}
|
||||
|
||||
// -- Breakpoint readout ------------------------------------------------------
|
||||
|
||||
function trackViewport () {
|
||||
const output = document.querySelector('#viewport')
|
||||
const update = () => {
|
||||
const width = window.innerWidth
|
||||
const name = width >= 1200 ? 'wide' : width >= 800 ? 'tablet' : 'phone'
|
||||
output.textContent = `${width}px · ${name}`
|
||||
}
|
||||
window.addEventListener('resize', update, { passive: true })
|
||||
update()
|
||||
}
|
||||
|
||||
// -- Wire up -----------------------------------------------------------------
|
||||
|
||||
renderSwatches()
|
||||
trackViewport()
|
||||
|
||||
// `?script=bg` opens straight onto a given script, so a particular cut can be
|
||||
// linked to or screenshotted without clicking.
|
||||
const requested = new URLSearchParams(location.search).get('script')
|
||||
setScript(requested in SAMPLES ? requested : 'en')
|
||||
|
||||
for (const button of document.querySelectorAll('[data-script]')) {
|
||||
button.addEventListener('click', () => setScript(button.dataset.script))
|
||||
}
|
||||
|
||||
const boxes = document.querySelector('#toggle-boxes')
|
||||
boxes.addEventListener('click', () => {
|
||||
const on = document.body.classList.toggle('show-boxes')
|
||||
boxes.setAttribute('aria-pressed', String(on))
|
||||
})
|
||||
Reference in New Issue
Block a user