UNPKG

@carbon/ibm-products

Version:
183 lines (181 loc) 6.32 kB
/** * Copyright IBM Corp. 2020, 2026 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ const require_runtime = require("../../../_virtual/_rolldown/runtime.js"); const require_index = require("../../../node_modules/classnames/index.js"); const require_settings = require("../../../settings.js"); const require_CardContext = require("./CardContext.js"); const require_CardHeader = require("./CardHeader.js"); const require_CardBody = require("./CardBody.js"); const require_CardFooter = require("./CardFooter.js"); const require_CardHeaderMedia = require("./CardHeaderMedia.js"); const require_CardMedia = require("./CardMedia.js"); const require_CardTitle = require("./CardTitle.js"); const require_CardTitleMedia = require("./CardTitleMedia.js"); const require_CardActions = require("./CardActions.js"); const require_CardAction = require("./CardAction.js"); let react = require("react"); react = require_runtime.__toESM(react); let prop_types = require("prop-types"); prop_types = require_runtime.__toESM(prop_types); let _carbon_react = require("@carbon/react"); //#region src/components/Card/next/Card.tsx /** * Copyright IBM Corp. 2026 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ var import_classnames = /* @__PURE__ */ require_runtime.__toESM(require_index.default); const componentName = "Card"; const blockClass = `${require_settings.pkg.prefix}--card-next`; /** * Card component - Root container for composable card */ let CardComponent = (0, react.forwardRef)(({ clickable = false, onClick, onKeyDown, disabled = false, density = "productive", decorator, horizontal = false, className, children, ...rest }, ref) => { const hasAILabel = (0, react.useMemo)(() => (0, react.isValidElement)(decorator) && decorator.type === _carbon_react.AILabel, [decorator]); const contextValue = (0, react.useMemo)(() => ({ clickable, disabled, decorator, horizontal }), [ clickable, disabled, decorator, horizontal ]); const handleKeyDown = (0, react.useCallback)((event) => { if (clickable && !disabled && (event.key === "Enter" || event.key === " ")) { event.preventDefault(); onClick?.(event); } onKeyDown?.(event); }, [ clickable, disabled, onClick, onKeyDown ]); const handleClick = (0, react.useCallback)((event) => { if (!disabled) onClick?.(event); }, [disabled, onClick]); const cardClasses = (0, import_classnames.default)(blockClass, className, { [`${blockClass}--clickable`]: clickable && !disabled, [`${blockClass}--disabled`]: disabled, [`${blockClass}--${density}`]: density, [`${blockClass}--has-ai-label`]: hasAILabel, [`${blockClass}--horizontal`]: horizontal }); const cardProps = { ...rest, ref, className: cardClasses, ...clickable && { role: "button", tabIndex: disabled ? -1 : 0, onClick: handleClick, onKeyDown: handleKeyDown, "aria-disabled": disabled } }; const { mediaChildren, contentChildren, mediaIsFirst } = (0, react.useMemo)(() => { if (!horizontal) return { mediaChildren: [], contentChildren: [], mediaIsFirst: false }; const childArray = react.default.Children.toArray(children); const isMedia = (child) => react.default.isValidElement(child) && child.type === require_CardMedia.CardMedia; return { mediaChildren: childArray.filter(isMedia), contentChildren: childArray.filter((c) => !isMedia(c)), mediaIsFirst: childArray.findIndex(isMedia) < childArray.findIndex((c) => !isMedia(c)) }; }, [children, horizontal]); let renderedChildren = children; if (horizontal) { const contentWrapper = /* @__PURE__ */ react.default.createElement("div", { className: `${blockClass}__content` }, contentChildren); renderedChildren = mediaIsFirst ? /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, mediaChildren, contentWrapper) : /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, contentWrapper, mediaChildren); } return /* @__PURE__ */ react.default.createElement(require_CardContext.CardContext.Provider, { value: contextValue }, /* @__PURE__ */ react.default.createElement("div", cardProps, renderedChildren)); }); CardComponent.propTypes = { /** * Card content */ children: prop_types.default.node, /** * Additional CSS class names */ className: prop_types.default.string, /** * Makes the entire card clickable */ clickable: prop_types.default.bool, /** * Optional decorator component (typically AILabel from Carbon) */ decorator: prop_types.default.node, /** * Density variant: productive uses heading-compact-02, expressive uses heading-03 */ density: prop_types.default.oneOf(["productive", "expressive"]), /** * Disables the card and all interactive elements */ disabled: prop_types.default.bool, /** * When true, renders media on the left and content (header/body/footer) on the right */ horizontal: prop_types.default.bool, /** * Click handler for clickable cards */ onClick: prop_types.default.func, /** * Keyboard event handler for clickable cards */ onKeyDown: prop_types.default.func }; CardComponent = require_settings.pkg.checkComponentEnabled(CardComponent, componentName); CardComponent.displayName = componentName; /** * ------- * Exports * ------- */ const Header = require_CardHeader.CardHeader; Header.displayName = "Card.Header"; const Body = require_CardBody.CardBody; Body.displayName = "Card.Body"; const Footer = require_CardFooter.CardFooter; Footer.displayName = "Card.Footer"; const HeaderMedia = require_CardHeaderMedia.CardHeaderMedia; HeaderMedia.displayName = "Card.HeaderMedia"; const Media = require_CardMedia.CardMedia; Media.displayName = "Card.Media"; const Title = require_CardTitle.CardTitle; Title.displayName = "Card.Title"; const TitleMedia = require_CardTitleMedia.CardTitleMedia; TitleMedia.displayName = "Card.TitleMedia"; const Actions = require_CardActions.CardActions; Actions.displayName = "Card.Actions"; const Action = require_CardAction.CardAction; Action.displayName = "Card.Action"; const Card = Object.assign(CardComponent, { Header, Body, Footer, HeaderMedia, Media, Title, TitleMedia, Actions, Action }); //#endregion exports.Card = Card;