feat(studio): MY PHOTOS, FAVORITED, PHOTO STYLE and RECIPES read as a list of names, and their column is the visitor's
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { keep, recall } from '../remember';
|
||||
|
||||
// One strip at a time — the same shape as the phone's AdjustmentPanel: a ruler
|
||||
// row for the open slider, an options strip for the open group, then the tab's
|
||||
@@ -62,10 +63,13 @@ export interface SliderDef {
|
||||
|
||||
// `grid` lays the row out as the table a set of same-kind values is read as
|
||||
// (WB's presets, LIGHT's two Color Chromes) instead of the wrapping strip the
|
||||
// option rows use.
|
||||
export function ChipRow({ chips, grid, grid3 }: { chips: ChipDef[]; grid?: boolean; grid3?: boolean }) {
|
||||
// option rows use. `list` is the other end of it: the rows that are a LIST OF
|
||||
// NAMES — MY PHOTOS' frames, FAVORITED and RECIPES' looks, PHOTO STYLE's sims —
|
||||
// drop the button's chrome and read as plain text, with only the accent marking
|
||||
// the one in force (see .chip-row.list).
|
||||
export function ChipRow({ chips, grid, grid3, list }: { chips: ChipDef[]; grid?: boolean; grid3?: boolean; list?: boolean }) {
|
||||
return (
|
||||
<div className={`chip-row${grid3 ? ' grid-3' : grid ? ' grid' : ''}`}>
|
||||
<div className={`chip-row${list ? ' list' : ''}${grid3 ? ' grid-3' : grid ? ' grid' : ''}`}>
|
||||
{chips.map((chip) =>
|
||||
chip.divider ? (
|
||||
<span key={chip.key} className="chip-rule" role="separator" aria-orientation="horizontal" />
|
||||
@@ -114,6 +118,48 @@ export function ChipRow({ chips, grid, grid3 }: { chips: ChipDef[]; grid?: boole
|
||||
);
|
||||
}
|
||||
|
||||
// The edge of a column you can drag: the width is written on the column itself
|
||||
// and remembered (remember.ts), so the next visit opens at the size it was left
|
||||
// at. Drag, not a panel: the grip appears where the column's edge already is.
|
||||
// ponytail: the DOM takes the width and React never learns it — a column width
|
||||
// is presentation, not state, and a re-render carrying it would fight the drag.
|
||||
export function ColGrip({ col, min = 110, max = 560 }: { col: string; min?: number; max?: number }) {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const key = `studio-col-${col}`;
|
||||
useEffect(() => {
|
||||
const box = ref.current?.parentElement;
|
||||
const kept = recall(key);
|
||||
if (box && kept) box.style.width = kept;
|
||||
}, [key]);
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className="col-grip"
|
||||
data-key={`col-grip-${col}`}
|
||||
role="separator"
|
||||
aria-orientation="vertical"
|
||||
aria-label={`resize ${col}`}
|
||||
onPointerDown={(e) => {
|
||||
const box = ref.current?.parentElement;
|
||||
if (!box) return;
|
||||
e.preventDefault();
|
||||
const from = e.clientX;
|
||||
const start = box.getBoundingClientRect().width;
|
||||
const move = (m: PointerEvent) => {
|
||||
box.style.width = `${Math.round(Math.min(max, Math.max(min, start + m.clientX - from)))}px`;
|
||||
};
|
||||
const up = () => {
|
||||
window.removeEventListener('pointermove', move);
|
||||
window.removeEventListener('pointerup', up);
|
||||
keep(key, box.style.width);
|
||||
};
|
||||
window.addEventListener('pointermove', move);
|
||||
window.addEventListener('pointerup', up);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function SliderRow({ slider }: { slider: SliderDef }) {
|
||||
// The wheel belongs to the open ruler: one notch is one step, held inside the
|
||||
// parameter's own range. The listener is native because React's is passive —
|
||||
|
||||
Reference in New Issue
Block a user