Skeleton, Breadcrumbs, Link, Button, Image, Meter, NumberField Floating components: Tooltip (hover/focus), Popover (click, with focus trap and dismiss), HoverCard (hover with safe area). Simple components: Alert (role=alert), Badge (role=status), Skeleton (loading placeholder with data attributes). Navigation: Breadcrumbs (nav>ol>li with separators), Link (accessible anchor with disabled), Button (with disabled click suppression). Data/Form: Image (Img+Fallback with loading status), Meter (like Progress for known ranges), NumberField (spinbutton with inc/dec). 302 tests across 46 files, typecheck clean, build produces 176 files.
58 lines
1.7 KiB
TypeScript
58 lines
1.7 KiB
TypeScript
import type { JSX } from "solid-js";
|
|
import { splitProps } from "solid-js";
|
|
import { useInternalHoverCardContext } from "./hover-card-context";
|
|
|
|
export interface HoverCardTriggerProps extends JSX.AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
children?: JSX.Element;
|
|
}
|
|
|
|
/**
|
|
* Anchor element that triggers the HoverCard on pointer enter.
|
|
* Renders as an `<a>` since hover cards are typically used on links.
|
|
*/
|
|
export function HoverCardTrigger(props: HoverCardTriggerProps): JSX.Element {
|
|
const [local, rest] = splitProps(props, [
|
|
"children",
|
|
"onPointerEnter",
|
|
"onPointerLeave",
|
|
"onFocus",
|
|
"onBlur",
|
|
]);
|
|
const ctx = useInternalHoverCardContext();
|
|
|
|
const handlePointerEnter: JSX.EventHandler<HTMLAnchorElement, PointerEvent> = (e) => {
|
|
if (typeof local.onPointerEnter === "function") local.onPointerEnter(e);
|
|
ctx.scheduleOpen();
|
|
};
|
|
|
|
const handlePointerLeave: JSX.EventHandler<HTMLAnchorElement, PointerEvent> = (e) => {
|
|
if (typeof local.onPointerLeave === "function") local.onPointerLeave(e);
|
|
ctx.scheduleClose();
|
|
};
|
|
|
|
const handleFocus: JSX.EventHandler<HTMLAnchorElement, FocusEvent> = (e) => {
|
|
if (typeof local.onFocus === "function") local.onFocus(e);
|
|
ctx.scheduleOpen();
|
|
};
|
|
|
|
const handleBlur: JSX.EventHandler<HTMLAnchorElement, FocusEvent> = (e) => {
|
|
if (typeof local.onBlur === "function") local.onBlur(e);
|
|
ctx.scheduleClose();
|
|
};
|
|
|
|
return (
|
|
<a
|
|
ref={(el) => ctx.setTriggerRef(el)}
|
|
id={ctx.triggerId}
|
|
data-state={ctx.isOpen() ? "open" : "closed"}
|
|
onPointerEnter={handlePointerEnter}
|
|
onPointerLeave={handlePointerLeave}
|
|
onFocus={handleFocus}
|
|
onBlur={handleBlur}
|
|
{...rest}
|
|
>
|
|
{local.children}
|
|
</a>
|
|
);
|
|
}
|