UNPKG

@grafana/ui

Version:
316 lines (309 loc) • 10.2 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var jsxRuntime = require('react/jsx-runtime'); var css = require('@emotion/css'); var React = require('react'); var e2eSelectors = require('@grafana/e2e-selectors'); var i18n = require('@grafana/i18n'); var ThemeContext = require('../../themes/ThemeContext.cjs'); var mixins = require('../../themes/mixins.cjs'); var CardContainer = require('./CardContainer.cjs'); function _interopNamespaceCompat(e) { if (e && typeof e === 'object' && 'default' in e) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var React__namespace = /*#__PURE__*/_interopNamespaceCompat(React); "use strict"; const CardContext = React__namespace.createContext(null); const Card = ({ disabled, href, onClick, children, isSelected, isCompact, className, noMargin, ...htmlProps }) => { const hasHeadingComponent = React.useMemo( () => React__namespace.Children.toArray(children).some((c) => React__namespace.isValidElement(c) && c.type === Heading), [children] ); const hasDescriptionComponent = React.useMemo( () => React__namespace.Children.toArray(children).some((c) => React__namespace.isValidElement(c) && c.type === Description), [children] ); const hasTagsComponent = React.useMemo( () => React__namespace.Children.toArray(children).some((c) => React__namespace.isValidElement(c) && c.type === Tags), [children] ); const disableHover = disabled || !onClick && !href; const onCardClick = onClick && !disabled ? onClick : void 0; const styles = ThemeContext.useStyles2( CardContainer.getCardContainerStyles, disabled, disableHover, hasDescriptionComponent, hasTagsComponent, isSelected, isCompact, noMargin ); return /* @__PURE__ */ jsxRuntime.jsx( CardContainer.CardContainer, { disableEvents: disabled, disableHover, isSelected, className: css.cx(styles.container, className), noMargin, hasDescriptionComponent, hasTagsComponent, ...htmlProps, children: /* @__PURE__ */ jsxRuntime.jsxs(CardContext.Provider, { value: { href, onClick: onCardClick, disabled, isSelected }, children: [ !hasHeadingComponent && /* @__PURE__ */ jsxRuntime.jsx(Heading, {}), children ] }) } ); }; Card.displayName = "Card"; const Heading = ({ children, className, "aria-label": ariaLabel }) => { const context = React.useContext(CardContext); const styles = ThemeContext.useStyles2(getHeadingStyles); const { href, onClick, isSelected } = context != null ? context : { href: void 0, onClick: void 0, isSelected: void 0 }; const optionLabel = i18n.t("grafana-ui.card.option", "option"); const headingId = React.useId(); const hasHeadingContent = React__namespace.Children.count(children) > 0; return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-testid": e2eSelectors.selectors.components.Card.heading, className: css.cx(styles.heading, className), children: [ href ? /* @__PURE__ */ jsxRuntime.jsx("a", { id: headingId, href, className: styles.linkHack, "aria-label": ariaLabel, onClick, children }) : onClick ? /* @__PURE__ */ jsxRuntime.jsx("button", { id: headingId, onClick, className: styles.linkHack, "aria-label": ariaLabel, type: "button", children }) : /* @__PURE__ */ jsxRuntime.jsx("span", { id: headingId, children }), isSelected !== void 0 && /* @__PURE__ */ jsxRuntime.jsx( "input", { ...hasHeadingContent ? { "aria-labelledby": headingId } : { "aria-label": optionLabel }, type: "radio", checked: isSelected, readOnly: true } ) ] }); }; Heading.displayName = "Heading"; const getHeadingStyles = (theme) => ({ heading: css.css({ gridArea: "Heading", justifySelf: "start", display: "flex", justifyContent: "space-between", alignItems: "center", width: "100%", marginBottom: 0, fontSize: theme.typography.size.md, letterSpacing: "inherit", lineHeight: theme.typography.body.lineHeight, color: theme.colors.text.primary, fontWeight: theme.typography.fontWeightMedium, "& input[readonly]": { cursor: "inherit" } }), linkHack: css.css({ all: "unset", "&::after": { position: "absolute", content: '""', top: 0, bottom: 0, left: 0, right: 0, borderRadius: theme.shape.radius.default }, "&:focus-visible": { outline: "none", outlineOffset: 0, boxShadow: "none", "&::after": { ...mixins.getFocusStyles(theme), zIndex: 1 } } }) }); const Tags = ({ children, className }) => { const styles = ThemeContext.useStyles2(getTagStyles); return /* @__PURE__ */ jsxRuntime.jsx("div", { className: css.cx(styles.tagList, className), children }); }; Tags.displayName = "Tags"; const getTagStyles = (theme) => ({ tagList: css.css({ position: "relative", gridArea: "Tags", alignSelf: "center" }) }); const Description = ({ children, className }) => { const styles = ThemeContext.useStyles2(getDescriptionStyles); const Element = typeof children === "string" ? "p" : "div"; return /* @__PURE__ */ jsxRuntime.jsx(Element, { className: css.cx(styles.description, className), children }); }; Description.displayName = "Description"; const getDescriptionStyles = (theme) => ({ description: css.css({ width: "100%", gridArea: "Description", margin: theme.spacing(1, 0, 0), color: theme.colors.text.secondary, lineHeight: theme.typography.body.lineHeight }) }); const Figure = ({ children, align = "start", className }) => { const styles = ThemeContext.useStyles2(getFigureStyles); return /* @__PURE__ */ jsxRuntime.jsx( "div", { className: css.cx( styles.media, className, css.css({ alignSelf: align }) ), children } ); }; Figure.displayName = "Figure"; const getFigureStyles = (theme) => ({ media: css.css({ position: "relative", gridArea: "Figure", marginRight: theme.spacing(2), width: "40px", "> img": { width: "100%" }, "&:empty": { display: "none" } }) }); const Meta = React.memo(({ children, className, separator = "|" }) => { const styles = ThemeContext.useStyles2(getMetaStyles); let meta = children; const filtered = React__namespace.Children.toArray(children).filter(Boolean); if (!filtered.length) { return null; } meta = filtered.map((element, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles.metadataItem, children: element }, `element_${i}`)); if (filtered.length > 1 && separator) { meta = filtered.reduce((prev, curr, i) => [ prev, /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles.separator, children: separator }, `separator_${i}`), curr ]); } return /* @__PURE__ */ jsxRuntime.jsx("div", { className: css.cx(styles.metadata, className), children: meta }); }); Meta.displayName = "Meta"; const getMetaStyles = (theme) => ({ metadata: css.css({ gridArea: "Meta", display: "flex", alignItems: "center", width: "100%", fontSize: theme.typography.size.sm, color: theme.colors.text.secondary, margin: theme.spacing(0.5, 0, 0), lineHeight: theme.typography.bodySmall.lineHeight, overflowWrap: "anywhere" }), metadataItem: css.css({ // Needed to allow for clickable children in metadata zIndex: 0 }), separator: css.css({ margin: `0 ${theme.spacing(1)}` }) }); const BaseActions = ({ children, disabled, variant, className }) => { const styles = ThemeContext.useStyles2(getActionStyles); const context = React.useContext(CardContext); const isDisabled = (context == null ? void 0 : context.disabled) || disabled; const css2 = variant === "primary" ? styles.actions : styles.secondaryActions; return /* @__PURE__ */ jsxRuntime.jsx("div", { className: css.cx(css2, className), children: React__namespace.Children.map(children, (child) => { return React__namespace.isValidElement(child) ? React.cloneElement(child, child.type !== React__namespace.Fragment ? { disabled: isDisabled, ...child.props } : void 0) : null; }) }); }; const getActionStyles = (theme) => ({ actions: css.css({ display: "flex", flexDirection: "row", flexWrap: "wrap", gap: theme.spacing(1), gridArea: "Actions", marginTop: theme.spacing(2) }), secondaryActions: css.css({ alignSelf: "center", color: theme.colors.text.secondary, display: "flex", flexDirection: "row", flexWrap: "wrap", gap: theme.spacing(1), gridArea: "Secondary", marginTop: theme.spacing(2) }) }); const Actions = ({ children, disabled, className }) => { return /* @__PURE__ */ jsxRuntime.jsx(BaseActions, { variant: "primary", disabled, className, children }); }; Actions.displayName = "Actions"; const SecondaryActions = ({ children, disabled, className }) => { return /* @__PURE__ */ jsxRuntime.jsx(BaseActions, { variant: "secondary", disabled, className, children }); }; SecondaryActions.displayName = "SecondaryActions"; const getCardStyles = (theme) => { return { inner: css.css({ display: "flex", justifyContent: "space-between", alignItems: "center", width: "100%", flexWrap: "wrap" }), ...getHeadingStyles(theme), ...getMetaStyles(theme), ...getDescriptionStyles(theme), ...getFigureStyles(theme), ...getActionStyles(theme), ...getTagStyles(theme) }; }; Card.Heading = Heading; Card.Tags = Tags; Card.Figure = Figure; Card.Meta = Meta; Card.Actions = Actions; Card.SecondaryActions = SecondaryActions; Card.Description = Description; exports.Card = Card; exports.getCardStyles = getCardStyles; //# sourceMappingURL=Card.cjs.map