vojo/src/app/components/stream-header/geometry.ts

62 lines
3.2 KiB
TypeScript

// ────────────────────────────────────────────────────────────────────
// StreamHeader geometry — shared constants for the curtain layout.
//
// Mental model: the chats card is a curtain layered ABOVE the header
// (z-index higher). The curtain's `top` is the visible part of the
// header below the always-pinned tabs row. When the curtain is fully
// closed it sits flush under the tabs row (covering chips + form area
// beneath). Dragging it DOWN reveals more of the header from underneath.
// Dragging UP raises the curtain back over the header.
//
// Snap stops (curtain.top, px):
// closed = TABS_ROW_PX
// peek = TABS_ROW_PX + 2·CHIP_ROW_PX + CHIP_GAP_PX
// + CURTAIN_BREATHER_PX
// form:* = TABS_ROW_PX + formHeight + CURTAIN_BREATHER_PX
// ────────────────────────────────────────────────────────────────────
// Tabs row height. Always visible above the curtain.
export const TABS_ROW_PX = 64;
// Each peek-chip row. Reveals one chip's pill (h=48) + 8px top breather.
export const CHIP_ROW_PX = 56;
// Vertical gap BETWEEN two consecutive chip rows. Separate from
// `CURTAIN_BREATHER_PX` so the inter-chip spacing can read tighter
// than the breather between the last chip and the curtain's rounded
// top (the curtain's straight edge against a chip pill needs more
// air to avoid feeling «clamped», while two pills sitting in a
// vertical stack want to read as a pair).
export const CHIP_GAP_PX = 14;
// Initial estimate for the search form's outer height. The actual
// height is measured at runtime via ResizeObserver and adapts to the
// available viewport so the form never overflows the chats card.
export const SEARCH_FORM_BASE_PX = 360;
// Breathing strip between the bottom of any header content (revealed
// chip pill, form's last actionable element) and the top of the
// curtain. Painted by the header's `SurfaceVariant.Container` (light-
// blue) so the chip / Create button / search results never visually
// touch the curtain's rounded top — the user reads chips that sit
// flush with the curtain as «зажатые» rather than two separate
// affordances. Not applied at `closed` (nothing to breathe to).
export const CURTAIN_BREATHER_PX = 20;
// Curtain snap transition. Tuned tight for an in-app reveal —
// emphasized-decelerate territory.
export const CURTAIN_SNAP_MS = 280;
export const CURTAIN_SNAP_EASING = 'cubic-bezier(0.22, 1, 0.36, 1)';
// Curtain card top-corner radius. Matches the composer card and the
// horseshoe surfaces elsewhere in the app.
export const CURTAIN_RADIUS_PX = 24;
// Touch gesture tuning. RUBBER_BAND dampens finger→curtain motion so
// the chip reveal feels resistive; COMMIT_THRESHOLD is the fraction of
// a stage the user must cross on release to advance.
export const RUBBER_BAND = 0.65;
export const DIRECTION_DEAD_ZONE_PX = 10;
export const COMMIT_THRESHOLD = 0.65;
// Pull-up distance (raw finger px) required to close an active form.
export const ACTIVE_CLOSE_THRESHOLD_PX = 100;