/** isEditable and isView are independent — both true shows edit and view actions side by side. */ export type ProfilePhotoViewerProps = { /** Source of the displayed image; a changed value replaces it, discarding a locally picked preview. */ photoUrl: string; /** Receives the raw File (not a URL, despite the param name) — fires only when isEditable and a file is picked. */ onPhotoChange: (photoUrl: File) => void; /** Also sets the height (maps to Chakra's boxSize) — there's no separate height prop; the frame is square. */ imageWidth?: string; imageAlt?: string; imageObjectFit?: "cover" | "contain" | "fill" | "none" | "scale-down"; imageBorderRadius?: string; isEditable?: boolean; editIconSize?: "xs" | "sm" | "md" | "lg" | "xl"; editIconPositionRight?: string; editIconPositionBottom?: string; /** Rounds only the edit/view IconButtons — the photo/avatar shape comes from imageBorderRadius, not this. */ isRound?: boolean; /** Inline style for the outer wrapper only — the edit/view buttons use the separate `style` prop below. */ boxStyle?: React.CSSProperties; isView?: boolean; /** Applied to BOTH edit and view IconButtons identically — no way to style them individually. */ style?: React.CSSProperties; /** Fires from the View IconButton — that button (and this handler) only renders when isView is true. */ handleIsView?: () => void; fallbackText?: string; /** When true (the actual default), edit/view icons stay hidden until hover; false keeps them always visible. */ revealOnHover?: boolean; };