diff options
| author | Josh Kingsley <josh@joshkingsley.me> | 2025-11-23 19:27:57 +0200 |
|---|---|---|
| committer | Josh Kingsley <josh@joshkingsley.me> | 2025-11-23 19:27:57 +0200 |
| commit | 602145c956bb594ca0d0e10601cc4ad1a71cf70d (patch) | |
| tree | d9f9980bd2054cff5819d01379f5c1c55f8eb66d /packages/web/src/components/toolbar | |
| parent | c2a6efb1b761014a90d90373cad47a14054af40b (diff) | |
feat: integrate web and doc packages
Diffstat (limited to 'packages/web/src/components/toolbar')
| -rw-r--r-- | packages/web/src/components/toolbar/index.css | 48 | ||||
| -rw-r--r-- | packages/web/src/components/toolbar/index.ts | 70 |
2 files changed, 118 insertions, 0 deletions
diff --git a/packages/web/src/components/toolbar/index.css b/packages/web/src/components/toolbar/index.css new file mode 100644 index 0000000..653c326 --- /dev/null +++ b/packages/web/src/components/toolbar/index.css @@ -0,0 +1,48 @@ +@layer components { + ntv-toolbar { + display: flex; + border-radius: 99999px; + background: var(--color-neutral-900); + width: min-content; + } + + ntv-toolbar > section { + display: flex; + gap: 0.25rem; + padding: 0.325rem; + } + + ntv-toolbar button { + border-radius: 99999px; + background: var(--color-neutral-800); + padding: 0 0.5rem; + height: 1.25rem; + color: white; + font-weight: 600; + font-size: 0.75rem; + } + + ntv-toolbar button:hover { + background: var(--color-green-400); + color: var(--color-neutral-900); + } + + ntv-toolbar button[data-icon] { + display: flex; + justify-content: center; + align-items: center; + aspect-ratio: 1; + height: 1.25rem; + } + + ntv-toolbar input { + border: 1px solid var(--color-neutral-700); + border-radius: 4px; + background: var(--color-neutral-900); + width: 2.5rem; + height: 1.25rem; + color: white; + font-size: 0.75rem; + text-align: center; + } +} diff --git a/packages/web/src/components/toolbar/index.ts b/packages/web/src/components/toolbar/index.ts new file mode 100644 index 0000000..b8a383d --- /dev/null +++ b/packages/web/src/components/toolbar/index.ts @@ -0,0 +1,70 @@ +import NotiveElement, { customElement, eventHandler } from "../../element"; +import h from "../../html"; +import { minus16Icon, plus16Icon } from "../icons"; +import "./index.css"; + +export class SubdivisionsChangeEvent extends Event { + static readonly TYPE = "ntv:toolbar:subdivisionschange"; + + constructor(public subdivisions: number | undefined) { + super(SubdivisionsChangeEvent.TYPE); + } +} + +@customElement("ntv-toolbar") +class NotiveToolbarElement extends NotiveElement { + #subdivisionsInputEl: HTMLInputElement = h.input({ + title: "Subdivisions", + disabled: true, + }); + + get subdivisions(): number | undefined { + if (this.#subdivisionsInputEl.value === "") return; + return parseInt(this.#subdivisionsInputEl.value); + } + + set subdivisions(n: number | undefined) { + const m = n && Math.max(n, 1); + this.#subdivisionsInputEl.value = m === undefined ? "" : m.toString(); + } + + @eventHandler(SubdivisionsChangeEvent.TYPE) + onsubdivisionschange?: (event: SubdivisionsChangeEvent) => any; + + connectedCallback() { + this.append( + h.section( + h.button( + { + dataset: { icon: "" }, + onclick: () => { + if (!this.subdivisions) return; + this.subdivisions = this.subdivisions - 1; + this.dispatchEvent( + new SubdivisionsChangeEvent(this.subdivisions), + ); + }, + }, + h.span(minus16Icon()), + ), + this.#subdivisionsInputEl, + h.button( + { + dataset: { icon: "" }, + onclick: () => { + if (!this.subdivisions) return; + this.subdivisions = this.subdivisions + 1; + this.dispatchEvent( + new SubdivisionsChangeEvent(this.subdivisions), + ); + }, + }, + h.span(plus16Icon()), + ), + ), + h.section(h.button("Play")), + ); + } +} + +export default NotiveToolbarElement.makeFactory(); |
