@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
JavaScript
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