UNPKG

@veracity/vui

Version:

Veracity UI is a React component library crafted for use within Veracity applications and pages. Based on Styled Components and @xstyled.

129 lines (125 loc) 4.13 kB
import { isReactText, isString } from "../utils/assertion.js"; import { filterUndefined } from "../utils/object.js"; import { cs } from "../utils/styles.js"; import { useStyleConfig } from "../core/theme.js"; import styled from "../core/styled.js"; import vui from "../core/vui.js"; import { useListContext } from "./context.js"; import { ListIcon } from "./listIcon.js"; import { Link } from "../link/link.js"; import { ListText } from "./listText.js"; import { Fragment, useEffect } from "react"; import { jsx, jsxs } from "react/jsx-runtime"; //#region src/list/listItem.tsx /** Used as optional content wrapper when list item should be a link. */ const ListItemLink = vui((props, ref) => /* @__PURE__ */ jsx(Link, { borderRadius: "none", className: "vui-listItemLink vui-linkNoUnderline", focusRing: 0, h: "100%", px: 2, ref, variant: "plain", w: "100%", ...props })); const ListItemBase = styled.liBox` display: flex; line-height: normal; outline: none; transition-duration: fast; &[aria-disabled='true'] { cursor: not-allowed; user-select: none; opacity: 0.5; } &:focus-visible { z-index: 1; } `; /** * Displays a list item with text and optional icons. Can be shown as interactive or selected. * Optionally wraps the content with an <a> element when rendering a link. */ const ListItem = vui((props, ref) => { const { children, center, centerH, centerV = true, className, column, disabled, startIcon, endIcon, iconLeft, iconRight, isInteractive: isInteractiveProp, isSelected, isTruncated, itemLeft, itemRight, linkProps, onClick, text, ...rest } = { ...useListContext(), ...props }; const resolvedStartIcon = startIcon ?? iconLeft; const resolvedEndIcon = endIcon ?? iconRight; const { activeBg, hoverBg, selectedBg, ...itemStyles } = useStyleConfig("List", useListContext()).item; const isLinkItem = linkProps !== void 0; const isInteractive = isInteractiveProp || isLinkItem || onClick !== void 0; const alignItems = (center || (column ? centerH : centerV)) && "center"; const flexDirection = column && "column"; const justifyContent = (center || (column ? centerV : centerH)) && "center"; const ContentWrapper = isLinkItem ? ListItemLink : Fragment; const contentWrapperProps = isLinkItem ? { alignItems: "center", display: "inline-flex" } : {}; const interactiveProps = !disabled && isInteractive ? { cursor: "pointer", ...isLinkItem ? { focusWithinRing: 2, focusWithinRingInset: true } : { focusVisibleRing: 2, focusVisibleRingInset: true }, hoverBg, activeBg, tabIndex: !isLinkItem ? 0 : void 0, userSelect: "none" } : {}; const aliasedProps = filterUndefined({ alignItems, bg: isSelected ? selectedBg : void 0, "aria-disabled": disabled, flexDirection, justifyContent, px: isLinkItem ? 0 : void 0 }); useEffect(() => { if (iconLeft !== void 0) console.warn("[List.Item] `iconLeft` is deprecated. Use `startIcon` instead."); if (iconRight !== void 0) console.warn("[List.Item] `iconRight` is deprecated. Use `endIcon` instead."); }, [iconLeft, iconRight]); return /* @__PURE__ */ jsx(ListItemBase, { bg: disabled ? rest.disabledBg || "sandstone.95" : void 0, className: cs("vui-listItem", className), onClick: !disabled ? onClick : void 0, ref, ...itemStyles, ...interactiveProps, ...aliasedProps, ...rest, children: /* @__PURE__ */ jsxs(ContentWrapper, { ...linkProps, ...contentWrapperProps, children: [ itemLeft, isString(resolvedStartIcon) ? /* @__PURE__ */ jsx(ListIcon, { mr: 1, name: resolvedStartIcon, verticalAlign: "middle" }) : resolvedStartIcon, children ?? (isReactText(text) ? /* @__PURE__ */ jsx(ListText, { isTruncated, text }) : text), isString(resolvedEndIcon) ? /* @__PURE__ */ jsx(ListIcon, { ml: "auto", name: resolvedEndIcon, verticalAlign: "middle" }) : resolvedEndIcon, itemRight ] }) }); }); ListItem.displayName = "ListItem"; //#endregion export { ListItem, ListItem as default, ListItemBase }; globalThis.__vuiVersion__ = "5.3.1" //# sourceMappingURL=listItem.js.map