Files
siftlode/frontend/src/components/ui/trackPosition.ts
T
peter 977ba244fa fix(clip): a time's error line sits in the flow, the remove button off the cut, and every player surface rings amber
- useTimecodeField holds a time field's draft for its caller, which places TimecodeError (role
  alert) in its own flow under the fields' row: it no longer lies over the crop row taking its
  clicks, runs out of the editor's card, or joins the field's <label> name.
- The editor's remove-cut buttons sit in a row under the track at their cut (trackLeft), off the
  cut's grab area, where a press drags it; RangeTrack's adornment slot is gone.
- media-focus re-points --focus to the media amber on the Plex player, the YouTube stage and every
  bg-media-chrome surface; a contract test holds each such class string to media-focus or
  media-scope, the field's focus edge to the focus token, and --color-focus to the inline theme.
- An upload's quota headline says the converted file does not fit, not "Storage full".
- DESIGN.md: the tokens paragraph says what is re-pointed where; the decision row measures all
  three colours on the chrome.
2026-10-10 21:29:55 +02:00

15 lines
711 B
TypeScript

import type { RangeWindow } from "./RangeTrack";
// Where a time sits along a `RangeTrack` over a window: the track draws its regions, playhead and
// handles by these, and a control laid beside the track (a cut's remove button under it) lines up
// with the handle drawn at the same time.
export const trackFrac = (t: number, win: RangeWindow) =>
(t - win.from) / Math.max(win.to - win.from, 1e-6);
/** A fraction of the track as a CSS length, held to the track. */
export const trackPct = (f: number) => `${(Math.max(0, Math.min(1, f)) * 100).toFixed(3)}%`;
/** A time's place along the track, as its CSS `left`. */
export const trackLeft = (t: number, win: RangeWindow) => trackPct(trackFrac(t, win));