aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/autoComplete.ts115
-rw-r--r--src/lib/base.ts32
-rw-r--r--src/lib/button.ts29
-rw-r--r--src/lib/color.ts36
-rw-r--r--src/lib/contextMenu.ts35
-rw-r--r--src/lib/dom.ts6
-rw-r--r--src/lib/form.ts54
-rw-r--r--src/lib/h.ts31
-rw-r--r--src/lib/icons.ts66
-rw-r--r--src/lib/layout.ts15
-rw-r--r--src/lib/modal.ts28
11 files changed, 0 insertions, 447 deletions
diff --git a/src/lib/autoComplete.ts b/src/lib/autoComplete.ts
deleted file mode 100644
index b0a79eb..0000000
--- a/src/lib/autoComplete.ts
+++ /dev/null
@@ -1,115 +0,0 @@
-import { h, Children, concatClassName } from 'lib/h'
-import * as Button from 'lib/button'
-
-export function create(
- attrs: object,
- id: string,
- keys: string[],
- renderEntry: (entry: string) => Element,
- onInput: (value: string) => void
-): Element {
- const completion = h('div', {})
-
- const updateCompletion = (target: EventTarget, value: string) => {
- const entries = search(value, keys)
- mountOn(
- completion,
- renderCompletion(
- renderEntry,
- selected => {
- (target as HTMLInputElement).value = selected
- completion.remove
- removeChildren(completion)
- onInput(selected)
- },
- entries
- )
- )
- }
-
- const input = h('input',
- concatClassName(
- { ...attrs,
- id,
- autocomplete: 'off',
- onfocus: (e: Event) => {
- if (e.target !== null) {
- const target = e.target as HTMLInputElement
- updateCompletion(target, target.value)
- }
- },
- oninput: (e: Event) => {
- if (e.target !== null) {
- const target = e.target as HTMLInputElement
- updateCompletion(target, target.value)
- onInput(target.value)
- }
- }
- },
- 'g-AutoComplete__Input'
- )
- ) as HTMLInputElement
-
- input.addEventListener('blur', (e: MouseEvent) => {
- if (e.relatedTarget === null) {
- removeChildren(completion)
- }
- })
-
- return h('div',
- { className: 'g-AutoComplete' },
- input,
- completion,
- Button.raw(
- { className: 'g-AutoComplete__Clear',
- type: 'button',
- onclick: () => {
- onInput('')
- input.value = ''
- input.focus()
- }
- },
- 'x'
- )
- )
-}
-
-function renderCompletion(
- renderEntry: (entry: string) => Element,
- onSelect: (entry: string) => void,
- entries: string[]
-): Element {
- return h('div',
- { className: 'g-AutoComplete__Completion' },
- ...entries.map(c =>
- Button.raw(
- { className: 'g-AutoComplete__Entry',
- type: 'button',
- onclick: (e: Event) => {
- e.stopPropagation()
- e.preventDefault()
- onSelect(c)
- }
- },
- renderEntry(c)
- )
- )
- )
-}
-
-function search(s: string, xs: string[]): string[] {
- return xs.filter(x => x.includes(s))
-}
-
-function mountOn(base: Element, ...children: Element[]) {
- removeChildren(base)
- children.forEach(child => base.appendChild(child))
-}
-
-function removeChildren(base: Element) {
- const firstChild = base.firstChild
- if (firstChild !== null) {
- base.removeChild(firstChild)
- removeChildren(base)
- }
-}
diff --git a/src/lib/base.ts b/src/lib/base.ts
deleted file mode 100644
index 59c91cc..0000000
--- a/src/lib/base.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-export const b2: string[] =
- '01'.split('')
-
-export const b16: string[] =
- '0123456789abcdef'.split('')
-
-export const b62: string[] =
- '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('')
-
-export function encode(n: bigint, charset: string[]): string {
- const base = BigInt(charset.length)
-
- if (n == BigInt(0)) {
- return '0'
- } else {
- var xs = []
- while (n > BigInt(0)) {
- xs.push(charset[Number(n % base)])
- n = n / base
- }
- return xs.reverse().join('')
- }
-}
-
-export function decode(xs: string, charset: string[]): bigint {
- const base = BigInt(charset.length)
-
- return xs
- .split('')
- .reverse()
- .reduce((acc, x, i) => acc + (BigInt(charset.indexOf(x)) * (base ** BigInt(i))), BigInt(0))
-}
diff --git a/src/lib/button.ts b/src/lib/button.ts
deleted file mode 100644
index 794df35..0000000
--- a/src/lib/button.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { h, Children, concatClassName } from 'lib/h'
-
-export function raw(attrs: object, ...children: Children): Element {
- return h('button',
- concatClassName(attrs, 'g-Button__Raw'),
- ...children
- )
-}
-
-export function text(attrs: object, ...children: Children): Element {
- return h('button',
- concatClassName(attrs, 'g-Button__Text'),
- ...children
- )
-}
-
-export function action(attrs: object, ...children: Children): Element {
- return h('button',
- concatClassName(attrs, 'g-Button__Action'),
- ...children
- )
-}
-
-export function cancel(attrs: object, ...children: Children): Element {
- return h('button',
- concatClassName(attrs, 'g-Button__Cancel'),
- ...children
- )
-}
diff --git a/src/lib/color.ts b/src/lib/color.ts
deleted file mode 100644
index 59b320d..0000000
--- a/src/lib/color.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-interface Color {
- red: number,
- green: number,
- blue: number,
-}
-
-export function parse(str: string): Color {
- return {
- red: parseInt(str.slice(1,3), 16),
- green: parseInt(str.slice(3,5), 16),
- blue: parseInt(str.slice(5,7), 16),
- }
-}
-
-// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrastratio
-export function contrastRatio(c1: Color, c2: Color): number {
- const r1 = relativeLuminance(c1)
- const r2 = relativeLuminance(c2)
-
- return r1 > r2
- ? (r1 + 0.05) / (r2 + 0.05)
- : (r2 + 0.05) / (r1 + 0.05)
-}
-
-function relativeLuminance(c: Color): number {
- return (
- 0.2126 * fromSRGB(c.red / 255)
- + 0.7152 * fromSRGB(c.green / 255)
- + 0.0722 * fromSRGB(c.blue / 255))
-}
-
-function fromSRGB(sRGB: number): number {
- return sRGB <= 0.03928
- ? sRGB / 12.92
- : Math.pow(((sRGB + 0.055) / 1.055), 2.4)
-}
diff --git a/src/lib/contextMenu.ts b/src/lib/contextMenu.ts
deleted file mode 100644
index 6edd567..0000000
--- a/src/lib/contextMenu.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { h } from 'lib/h'
-
-interface Action {
- label: string,
- action: () => void
-}
-
-export function show(event: MouseEvent, actions: Action[]) {
- const menu = h('div',
- { id: 'g-ContextMenu',
- style: `left: ${event.pageX.toString()}px; top: ${event.pageY.toString()}px`
- },
- ...actions.map(({ label, action }) =>
- h('div',
- { className: 'g-ContextMenu__Entry',
- onclick: () => action()
- },
- label
- )
- )
- )
-
- document.body.appendChild(menu)
-
- // Remove on click or context menu
- setTimeout(() => {
- const f = () => {
- document.body.removeChild(menu)
- document.body.removeEventListener('click', f)
- document.body.removeEventListener('contextmenu', f)
- }
- document.body.addEventListener('click', f)
- document.body.addEventListener('contextmenu', f)
- }, 0)
-}
diff --git a/src/lib/dom.ts b/src/lib/dom.ts
deleted file mode 100644
index 2ab4de5..0000000
--- a/src/lib/dom.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export function replaceChildren(parent: Element, ...newChildren: Element[]) {
- while (parent.lastChild) {
- parent.removeChild(parent.lastChild)
- }
- newChildren.forEach(c => parent.appendChild(c))
-}
diff --git a/src/lib/form.ts b/src/lib/form.ts
deleted file mode 100644
index 04a2654..0000000
--- a/src/lib/form.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import { h } from 'lib/h'
-import * as Layout from 'lib/layout'
-import * as Button from 'lib/button'
-
-interface InputParams {
- label: string,
- attrs: object,
-}
-
-export function input({ label, attrs }: InputParams): Element {
- return h('label',
- { className: 'g-Form__Field' },
- label,
- h('input', attrs),
- )
-}
-
-interface ColorInputParams {
- colors: string[],
- label: string,
- initValue: string,
- onInput: (value: string) => void,
-}
-
-export function colorInput({ colors, label, initValue, onInput }: ColorInputParams): Element {
- const input = h('input',
- { value: initValue,
- type: 'color',
- oninput: (e: Event) => {
- if (e.target !== null) {
- onInput((e.target as HTMLInputElement).value)
- }
- }
- }
- ) as HTMLInputElement
- return h('label',
- { className: 'g-Form__Field' },
- label,
- Layout.line(
- {},
- input,
- ...colors.map(color =>
- Button.raw({ className: 'g-Form__Color',
- style: `background-color: ${color}`,
- type: 'button',
- onclick: () => {
- input.value = color
- onInput(color)
- }
- })
- )
- )
- )
-}
diff --git a/src/lib/h.ts b/src/lib/h.ts
deleted file mode 100644
index 7e93311..0000000
--- a/src/lib/h.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-type Child = Element | Text | string | number
-
-export type Children = Child[]
-
-export function h(tagName: string, attrs: object, ...children: Children): Element {
- let elem = document.createElement(tagName)
- elem = Object.assign(elem, attrs)
- appendChildren(elem, ...children)
- return elem
-}
-
-export function s(tagName: string, attrs: object, ...children: Children): Element {
- let elem = document.createElementNS('http://www.w3.org/2000/svg', tagName)
- Object.entries(attrs).forEach(([key, value]) => elem.setAttribute(key, value))
- appendChildren(elem, ...children)
- return elem
-}
-
-function appendChildren(elem: Element, ...children: Children) {
- for (const child of children) {
- if (typeof child === 'number')
- elem.append(child.toString())
- else
- elem.append(child)
- }
-}
-
-export function concatClassName(attrs: any, className: string): object {
- const existingClassName = 'className' in attrs ? attrs['className'] : undefined
- return { ...attrs, className: `${className} ${existingClassName}` }
-}
diff --git a/src/lib/icons.ts b/src/lib/icons.ts
deleted file mode 100644
index 8db4e17..0000000
--- a/src/lib/icons.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import { h, s } from 'lib/h'
-
-export function get(key: string, attrs: object = {}): Element {
- const elem = fromKey(key)
- if (elem !== undefined) {
- Object.entries(attrs).forEach(([key, value]) => {
- elem.setAttribute(key, value)
- })
- return elem
- } else {
- return h('span', {})
- }
-}
-
-// https://yqnn.github.io/svg-path-editor/
-function fromKey(key: string): Element | undefined {
- if (key == 'house') {
- return s('svg',
- { viewBox: '0 0 10 10' },
- s('g', { 'stroke': 'none' },
- s('path', { d: 'M0 4V5H1.5V10H4V7C4.4 6.5 5.6 6.5 6 7V10H8.5V5H10V4L5 0Z' })
- )
- )
- } else if (key == 'music') {
- return s('svg',
- { viewBox: '0 0 10 10' },
- s('g', { 'stroke': 'none' },
- s('ellipse', { cx: '2', cy: '8.5', rx: '2', ry: '1.5' }),
- s('ellipse', { cx: '8', cy: '7', rx: '2', ry: '1.5' }),
- s('path', { d: 'M2.5 8.5 H4 V4.5 L8.5 3 V7 H10 V0 L2.5 2.5 Z' }),
- )
- )
- } else if (key == 'shopping-cart') {
- return s('svg',
- { viewBox: '0 0 10 10' },
- s('circle', { cx: '3.3', cy: '8.5', r: '0.8' }),
- s('circle', { cx: '7.3', cy: '8.5', r: '0.8' }),
- s('path', { d: 'M.5.6C1.3.6 1.8.7 2.1 1L2.3 6H8.5', fill: 'transparent' }),
- s('path', { d: 'M2.3 1.9H9.4L8.6 4H2.4' }),
- )
- } else if (key == 'medical') {
- return s('svg',
- { viewBox: '0 0 10 10' },
- s('path', { d: 'M5 1V9M1 5H9', style: 'stroke-width: 3' }),
- )
- } else if (key == 'envelope') {
- return s('svg',
- { viewBox: '0 0 10 10' },
- s('path', { d: 'M.5 2.5H9.5V7.5H.5ZM.5 3.4 3.5 5Q5 5.8 6.6 5L9.5 3.4', style: 'fill: transparent' }),
- )
- }
-}
-
-// Good to add:
-// - loisir / cinéma / piscine
-// - école
-// - gare
-// - bus
-export function keys(): string[] {
- return [ 'house',
- 'music',
- 'shopping-cart',
- 'medical',
- 'envelope',
- ]
-}
diff --git a/src/lib/layout.ts b/src/lib/layout.ts
deleted file mode 100644
index 1e38bfd..0000000
--- a/src/lib/layout.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { h, Children, concatClassName } from 'lib/h'
-
-export function section(attrs: object, ...children: Children): Element {
- return h('div',
- concatClassName(attrs, 'g-Layout__Section'),
- ...children
- )
-}
-
-export function line(attrs: object, ...children: Children): Element {
- return h('div',
- concatClassName(attrs, 'g-Layout__Line'),
- ...children
- )
-}
diff --git a/src/lib/modal.ts b/src/lib/modal.ts
deleted file mode 100644
index 8454e1c..0000000
--- a/src/lib/modal.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { h } from 'lib/h'
-import * as Button from 'lib/button'
-
-export function show(content: Element) {
- document.body.appendChild(h('div',
- { id: 'g-Modal' },
- h('div',
- { className: 'g-Modal__Curtain',
- onclick: () => hide()
- }
- ),
- h('div',
- { className: 'g-Modal__Window' },
- Button.raw(
- { className: 'g-Modal__Close',
- onclick: () => hide()
- },
- 'x'
- ),
- content
- )
- ))
-}
-
-export function hide() {
- const modal = document.querySelector('#g-Modal')
- modal && document.body.removeChild(modal)
-}