feat(design): one media card, and Home's hero and shelves as cards (E28 S3h)
- ui/MediaCard + mediaCardStyles: one frame for every video, Plex title and Home tile; the meta line pinned to the bottom edge, the length a badge on the picture, the media Play only where the click plays, the hover row at the picture's bottom-right (the owner's pick C). - Shelf density: on any strip a one-line title over one meta line; mixed Home shelves are landscape; rails turn content-visibility off (a card's reserved height had become the strip's). Home slot 232px, so the Play and the hover row no longer touch; a landscape shelf takes the small Play. - Home hero is a card (hover row, the whole menu, a touch "…"), three quarters wide and centred; channel / playlist tiles get Play, open and "…"; a show tile acts on its next episode, ⓘ opens the show. - Plex preview: a ~0.9 s mouse rest opens a passive panel with the whole title, facts and synopsis (popover `pointerOnly`); the synopsis and title tooltips are gone. - Compact list row B: the title leads, "…" at the end, toggles over the date on hover. - Media-info layout B (collections, crew, cast beside the facts sidebar; an empty column is not drawn); filtering values are chips there and on the show page; "Cast" over the cast-only strips. - Browse tiles hover like a card; prose capped by the `measure` utility.
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import { useState, type HTMLAttributes } from "react";
|
||||
import { useAnchoredPopover } from "./anchoredPopoverHooks";
|
||||
|
||||
// The hover wiring of a media card's preview (./MediaPreview has the why).
|
||||
|
||||
/** How long the pointer must rest on a card: long enough that a sweep across a grid opens nothing. */
|
||||
const MEDIA_PREVIEW_DELAY = 900;
|
||||
|
||||
export function useMediaPreview(enabled = true) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const pop = useAnchoredPopover({
|
||||
open: open && enabled,
|
||||
onOpenChange: setOpen,
|
||||
mode: "hover",
|
||||
placement: "right-start",
|
||||
offset: 8,
|
||||
hoverDelay: { open: MEDIA_PREVIEW_DELAY, close: 0 },
|
||||
pointerOnly: true,
|
||||
});
|
||||
return {
|
||||
popover: pop,
|
||||
/** The card root's props: the anchor, the hover wiring, and a close on any press — merged with
|
||||
* the root's own (its menu's right-click and long-press). */
|
||||
rootProps: (own: HTMLAttributes<HTMLDivElement> & Record<string, unknown> = {}) => ({
|
||||
...(pop.getReferenceProps({
|
||||
...own,
|
||||
onPointerDown: (e: React.PointerEvent<HTMLDivElement>) => {
|
||||
setOpen(false);
|
||||
(own.onPointerDown as ((e: React.PointerEvent<HTMLDivElement>) => void) | undefined)?.(e);
|
||||
},
|
||||
onContextMenu: (e: React.MouseEvent<HTMLDivElement>) => {
|
||||
setOpen(false);
|
||||
(own.onContextMenu as ((e: React.MouseEvent<HTMLDivElement>) => void) | undefined)?.(e);
|
||||
},
|
||||
}) as HTMLAttributes<HTMLDivElement> & Record<string, unknown>),
|
||||
ref: pop.refs.setReference,
|
||||
}),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user