"use client";
import {
type AnchorHTMLAttributes,
type HTMLAttributes,
type ReactElement,
type Ref,
} from "react";
import { type ComponentWithRippleProps } from "../interaction/types.js";
import { useElementInteraction } from "../interaction/useElementInteraction.js";
import { useHigherContrastChildren } from "../interaction/useHigherContrastChildren.js";
import { type CustomLinkComponent } from "../link/Link.js";
import { type PropsWithRef } from "../types.js";
import { ListItemChildren } from "./ListItemChildren.js";
import { getListItemHeight } from "./getListItemHeight.js";
import { type ListItemClassNameOptions, listItem } from "./listItemStyles.js";
import { type ListItemChildrenProps } from "./types.js";
export interface ListItemLinkProps
extends
AnchorHTMLAttributes,
ListItemClassNameOptions,
ListItemChildrenProps,
ComponentWithRippleProps {
ref?: Ref;
/** @defaultValue `"a"` */
as?: CustomLinkComponent;
/**
* This should only be used if the {@link as} {@link CustomLinkComponent}
* accepts a `to` prop instead of {@link href}.
*/
to?: string;
/**
* The link's href. Either this or the {@link to} prop **should** be provided.
*/
href?: string;
/**
* Any additional props to provide the wrapping `
` element such as
* `style`, `className`, and `ref`.
*/
liProps?: PropsWithRef>;
/**
* @defaultValue `disabled ? -1 : undefined`
*/
tabIndex?: number;
}
/**
* **Client Component**
*
* The `ListItemLink` should be used to render links within the `List`, `Menu`,
* or `DropdownMenu` components.
*
* @example Simple Example
* ```tsx
* import { List } from "@react-md/core/list/list";
* import { ListItemLink } from "@react-md/core/list/ListItemLink";
*
* function Example() {
* return (
*
* Some Link
*
* );
* }
* ```
*
* @example In Menus
* ```tsx
* import { ListItemLink } from "@react-md/core/list/ListItemLink";
* import { DropdownMenu } from "@react-md/core/menu/DropdownMenu";
*
* function Example() {
* return (
*
* Some Link
*
* );
* }
* ```
*
* @see {@link https://react-md.dev/components/list | List Demos}
*/
export function ListItemLink(props: ListItemLinkProps): ReactElement {
const {
ref,
as: Link = "a",
to,
href,
className,
liProps,
textProps,
textClassName,
secondaryTextClassName,
primaryText,
secondaryText,
secondaryTextProps,
disableTextChildren = false,
height: propHeight,
leftAddon,
leftAddonType = "icon",
leftAddonPosition = "middle",
leftAddonClassName,
leftAddonForceWrap,
rightAddon,
rightAddonType = "icon",
rightAddonPosition = "middle",
rightAddonClassName,
rightAddonForceWrap,
disableLeftAddonCenteredMedia = false,
disableRightAddonCenteredMedia = false,
multiline = false,
disabled = false,
disabledOpacity = false,
onBlur,
onClick,
onKeyDown,
onKeyUp,
onMouseDown,
onMouseUp,
onMouseLeave,
onDragStart,
onTouchStart,
onTouchEnd,
onTouchMove,
role,
tabIndex = disabled || role === "menuitem" ? -1 : undefined,
children: propChildren,
disableRipple,
...remaining
} = props;
const { pressedClassName, ripples, handlers } = useElementInteraction({
mode: disableRipple ? "none" : undefined,
onBlur,
onClick,
onKeyDown,
onKeyUp,
onMouseDown,
onMouseUp,
onMouseLeave,
onDragStart,
onTouchStart,
onTouchEnd,
onTouchMove,
disabled,
});
const children = useHigherContrastChildren(
propChildren,
!disableTextChildren
);
const height = getListItemHeight({
height: propHeight,
leftAddon,
leftAddonType,
rightAddon,
rightAddonType,
secondaryText,
});
return (