import "./mark_stack.css"; import type * as React from "react"; import { useRender } from "@base-ui/react/use-render"; import { type AvatarSize } from "./avatar"; import { type StyleProps } from "./style_props"; /** How far one FACE tucks under the one before it, as a fraction of the rung — * a fraction, not a pixel constant, so the stack is the same object at every * rung. Just under a third leaves each mark's whole leading edge. */ export declare const FACE_OVERLAP_RATIO = 0.3; /** * The same tuck for a stack of THINGS — deliberately shallower. A face is * edge-anchored and a product shot is CENTRED with studio margin, so at the face * ratio the remainder lands on top of the last photograph and reads as covering * it. Shallow rather than zero, because the marks still read as one object. */ export declare const THING_OVERLAP_RATIO = 0.15; /** * One subject in the stack. A PERSON takes the disc; a GROUP takes the rounded * square, which is `Avatar`'s own subject axis; a THING takes its picture, and * never initials — with no picture it renders the neutral glyph and the label * carries the meaning. */ export interface StackedMark { /** Stable identity — the React key. Never the display name: two colleagues * share a name far more often than they share an id. */ id: string; /** What this is, in words — the mark's accessible name. */ name: string; kind: "person" | "group" | "thing"; /** A person's photo or a thing's picture; absent falls back to the kind's * own empty face. A group has no likeness of its own. */ image?: string | null; } export interface MarkStackProps extends StyleProps { marks: readonly StackedMark[]; /** Marks shown before the remainder becomes `+N`. Default 3. */ max?: number; /** Silence the marks for assistive tech — they become decoration. The DEFAULT * is to announce each `name`, the opposite of `Avatar`'s, because an avatar * almost always sits beside its name and a stack often does not. Pass this * where the row ALREADY names the subjects in text. */ decorative?: boolean; /** A rung on the shared avatar scale — the SAME scale and default (`md`) as * `Avatar` and `MemberChip`. Everything inside derives from it, so a stack at * `lg` is the same object as one at `sm`. */ size?: AvatarSize; testID?: string; ref?: React.Ref; render?: useRender.RenderProp; } /** * A SET as marks — who is on this, or what this order is of, in one cell. The * rules that make it a component rather than a `.map()`: * * **It resolves before it caps** — the overflow is counted from what will * actually render, so `+2` never counts a mark the reader can see is missing. * * **A group is ONE mark bearing the group's NAME**, never its members' faces, * which would state a membership the reader may not be entitled to. * * **The marks OVERLAP, and the remainder is the last mark in the stack**, so the * set reads as one object. The first mark sits on top and each one after tucks * beneath it. * * **A stack holding a THING tucks shallower**, for the reason the two ratios * state above, and it is a property of the set rather than of one mark. * * **It is INERT.** No peek, no press — a row that already presses must not hold * a second destination four pixels to the left (`member_peek.tsx`). * * Pure: pass resolved names and images in. */ export declare function MarkStack(props: MarkStackProps): React.ReactElement> | null;