@atlaskit/lozenge
Version:
A lozenge is a visual indicator used to highlight an item's status for quick recognition.
213 lines (211 loc) • 11.8 kB
JavaScript
/* lozenge-base.tsx generated by @compiled/babel-plugin v0.39.1 */
import _extends from "@babel/runtime/helpers/extends";
import "./lozenge-base.compiled.css";
import * as React from 'react';
import { ax, ix } from "@compiled/react/runtime";
import { forwardRef, memo } from 'react';
import Badge from '@atlaskit/badge';
import { cx } from '@atlaskit/css';
import ChevronDownIcon from '@atlaskit/icon/core/chevron-down';
import Pressable from '@atlaskit/primitives/pressable';
import Spinner from '@atlaskit/spinner';
import IconRenderer from './icon-renderer';
import { getThemeStyles, resolveLozengeColor } from './utils';
// Get the pressed background color for the selected lozenge dropdown trigger
const pressedBackgroundMapping = {
success: "var(--ds-background-success-subtler-pressed, #B3DF72)",
warning: "var(--ds-background-warning-subtler-pressed, #FBC828)",
danger: "var(--ds-background-danger-subtler-pressed, #FD9891)",
information: "var(--ds-background-information-subtler-pressed, #8FB8F6)",
neutral: "var(--ds-background-neutral-pressed, #080F214A)",
discovery: "var(--ds-background-discovery-subtler-pressed, #D8A0F7)",
'accent-red': "var(--ds-background-accent-red-subtler-pressed, #FD9891)",
'accent-orange': "var(--ds-background-accent-orange-subtler-pressed, #FBC828)",
'accent-yellow': "var(--ds-background-accent-yellow-subtler-pressed, #EED12B)",
'accent-lime': "var(--ds-background-accent-lime-subtler-pressed, #B3DF72)",
'accent-green': "var(--ds-background-accent-green-subtler-pressed, #7EE2B8)",
'accent-teal': "var(--ds-background-accent-teal-subtler-pressed, #9DD9EE)",
'accent-blue': "var(--ds-background-accent-blue-subtler-pressed, #8FB8F6)",
'accent-purple': "var(--ds-background-accent-purple-subtler-pressed, #D8A0F7)",
'accent-magenta': "var(--ds-background-accent-magenta-subtler-pressed, #F797D2)",
'accent-gray': "var(--ds-background-accent-gray-subtlest-pressed, #B7B9BE)"
};
const styles = {
container: "_2rko12b0 _1reo15vq _18m915vq _189ee4h9 _1dqonqa1 _1h6d1j28 _kqswh2mm _1e0c116y _4cvr1h6o _vchhusvi _4t3i1k92 _1q51v77o _85i5v77o _bozg1b66 _y4ti1b66",
containerSpacious: "_2rko1qi0 _1tkeviql _1q511b66 _85i51b66 _bozgutpp _y4tiutpp",
containerBadgePadding: "_y4ti303w",
text: "_11c8wadc _1reo15vq _18m915vq _1bto1l2s _o5721q9c",
textSpacious: "_11c8fhey _k48p1wq8",
textSelected: "_syaz6x5g",
loadingOverlay: "_1reo15vq _18m915vq _1e0c1txw _kqswstnw _4cvr1h6o _1bah1h6o _u7coze3t _152tze3t _rjxpze3t _1e02ze3t _lcxvglyw",
metricBadgeWrapper: "_1e0c1txw",
'metric.semantic.success': "_1bn8d6jc _4ayg1wl5",
'metric.semantic.warning': "_1bn8bkku _4aygzr32",
'metric.semantic.danger': "_1bn8jkmi _4ayg1r4b",
'metric.semantic.information': "_1bn8ar1y _4ayg1c1j",
'metric.semantic.neutral': "_1bn814je _4ayg1fkg _iymy8hz0 _16burnys",
'metric.semantic.discovery': "_1bn85usi _4ayg18vq",
'metric.inverse': "_1bn8vuon _4aygvuon",
'semantic.success': "_1b3i4pcx _3wu01mps _bfhk14j0 _syaz1p1e",
'semantic.warning': "_1b3iervl _3wu01xiv _bfhk10f4 _syazmgs1",
'semantic.danger': "_1b3is4qr _3wu01bqt _bfhk18wg _syaz1blx",
'semantic.information': "_1b3iyhbg _3wu0vbh5 _bfhk8lbg _syaz1qd9",
'semantic.neutral': "_1b3i1cv2 _3wu01ihb _bfhki8nm _syazi7uo",
'semantic.discovery': "_1b3iqm1h _3wu0v30g _bfhke670 _syaz1g72",
'accent.red': "_1b3inbxb _3wu016y8 _bfhk1rtt _syazhwvp",
'accent.orange': "_1b3i1j6y _3wu01b2s _bfhk165s _syaz7i1p",
'accent.yellow': "_1b3i1oqg _3wu0feiv _bfhk1773 _syazekll",
'accent.lime': "_1b3i8645 _3wu0nf89 _bfhkz2ec _syaz1ik3",
'accent.green': "_1b3i17hp _3wu01crs _bfhk1wnw _syaz1y78",
'accent.teal': "_1b3i8uof _3wu01h3o _bfhk1a17 _syaz12v7",
'accent.blue': "_1b3i6txe _3wu01w55 _bfhk1dy8 _syaz1kyx",
'accent.purple': "_1b3iuq3u _3wu01hqq _bfhk1nm4 _syaz1mn1",
'accent.magenta': "_1b3iv8hk _3wu0uwd0 _bfhkv9ra _syaz1qur",
'accent.gray': "_1b3i1diz _3wu08yml _bfhkysee _syaz1tmo",
'interactive.semantic.success': "_irr31r82 _1di6d6jc",
'interactive.semantic.warning': "_irr31yx4 _1di6bkku",
'interactive.semantic.danger': "_irr370oi _1di6jkmi",
'interactive.semantic.information': "_irr315aw _1di6ar1y",
'interactive.semantic.neutral': "_irr3plhp _1di61gdz",
'interactive.semantic.discovery': "_irr3rumk _1di65usi",
'interactive.accent.red': "_irr3affd _1di61j5a",
'interactive.accent.orange': "_irr31ei0 _1di6dpo3",
'interactive.accent.yellow': "_irr31uw7 _1di61r9w",
'interactive.accent.lime': "_irr31gf0 _1di62kxc",
'interactive.accent.green': "_irr31e2h _1di6ybhx",
'interactive.accent.teal': "_irr3kwwr _1di61jb0",
'interactive.accent.blue': "_irr3815t _1di6rwxf",
'interactive.accent.purple': "_irr3attl _1di63nfk",
'interactive.accent.magenta': "_irr31axx _1di642ri",
'interactive.accent.gray': "_irr3wejn _1di618ut",
iconBorderFilter: "_1h6dzs9d _4uq11yqs _1k671038 _m71tr3uz _13muu67f _168qx19p _oe6mmko7 _189qkb7n _u8p61h4e _1t75u67f _hg5mr3uz _1f28f1ug _1xe213rw _1easxmrh _1r9r1ss3",
iconBorderInteractiveFilter: "_1iel6xdd _111i1h4e _18dicjiy _hyog26zw _fdt01r5k _46v5hwvj _ylgq1r5k _bg3q9by0 _196p1btq _18mn783i _l0666xdd _pclnn8xv _ockq1r5k _aewt1n8h _4cvx7ddx _1cp21w66 _q4zt1csi _1gqs1mvc _75gv2l9f _1lh71sfd _ui3h1ct7 _11o31cha",
containerSelected: "_1xe213kw",
content: "_zulp1b66 _1e0c116y _4cvr1h6o",
contentSpacious: "_zulp12x7",
loadingContent: "_tzy4idpf",
containerBadge: "_1ftrbpke",
containerBadgeInteractive: "_1axm1bqy"
};
/**
* __New Lozenge__
*
* A lozenge is a visual indicator used to highlight an item's status for quick recognition.
* This is the updated version with the new North Star visual language.
*/
const LozengeBase = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
children,
testId,
appearance,
iconBefore,
trailingMetric,
trailingMetricAppearance,
maxWidth = 200,
spacing = 'default',
isSelected,
// for dropdown trigger
isLoading = false,
// for dropdown trigger
onClick,
// for dropdown trigger
style,
analyticsContext,
interactionName,
'aria-controls': ariaControls,
'aria-expanded': ariaExpanded,
'aria-haspopup': ariaHaspopup,
'aria-label': ariaLabel
}, ref) => {
const isInteractive = typeof onClick === 'function';
// Determine the effective color, with fallback logic for legacy appearances
const resolvedColor = resolveLozengeColor(appearance) || 'neutral';
const {
category,
key
} = getThemeStyles(resolvedColor);
const colorStyleKey = `${category}.${key}`;
const interactiveStyleKey = `interactive.${category}.${key}`;
const maxWidthValue = typeof maxWidth === 'string' ? maxWidth : `${maxWidth}px`;
const maxWidthIsPc = typeof maxWidth === 'string' && /%$/.test(maxWidth);
const resolvedTrailingMetricAppearance = trailingMetricAppearance ? trailingMetricAppearance === 'inverse' ? 'inverse' : resolveLozengeColor(trailingMetricAppearance) : resolvedColor;
const metricBadgeAppearance = resolvedTrailingMetricAppearance === 'inverse' ? 'inverse' : resolvedTrailingMetricAppearance != null && resolvedTrailingMetricAppearance.startsWith('accent-') ? 'neutral' : resolvedTrailingMetricAppearance !== null && resolvedTrailingMetricAppearance !== void 0 ? resolvedTrailingMetricAppearance : 'neutral';
const metricStyleKey = resolvedTrailingMetricAppearance === 'inverse' ? 'metric.inverse' : resolvedTrailingMetricAppearance != null && !resolvedTrailingMetricAppearance.startsWith('accent-') ? `metric.semantic.${getThemeStyles(resolvedTrailingMetricAppearance).key}` : 'metric.semantic.neutral';
const commonStyleOverrides = {
backgroundColor: style === null || style === void 0 ? void 0 : style.backgroundColor,
maxWidth: maxWidthIsPc ? maxWidth : '100%'
};
const hasTrailingMetric = trailingMetric != null && trailingMetric !== '';
const innerContent = /*#__PURE__*/React.createElement("span", {
style: {
// When maxWidth is a percentage, constrain the content wrapper
// so text truncation works correctly within the flex layout
maxWidth: maxWidthIsPc ? '100%' : undefined
},
className: ax([styles.content, spacing === 'spacious' && styles.contentSpacious, isLoading && styles.loadingContent])
}, iconBefore && /*#__PURE__*/React.createElement(IconRenderer, {
size: spacing === 'spacious' ? 'medium' : 'small',
icon: iconBefore,
color: resolvedColor,
testId: testId && `${testId}--icon`
}), /*#__PURE__*/React.createElement("span", {
style: {
maxWidth: maxWidthIsPc ? undefined : `calc(${maxWidthValue} - ${"var(--ds-space-100, 8px)"})`,
color: style === null || style === void 0 ? void 0 : style.color
},
"data-testid": testId && `${testId}--text`,
className: ax([styles.text, spacing === 'spacious' && styles.textSpacious])
}, children), hasTrailingMetric && !resolvedColor.startsWith('accent-') && /*#__PURE__*/React.createElement("span", {
"data-lozenge-metric-wrapper": true,
"data-testid": testId && `${testId}--metric`,
className: ax([styles.metricBadgeWrapper])
}, /*#__PURE__*/React.createElement(Badge, {
appearance: metricBadgeAppearance
}, trailingMetric)), isInteractive && /*#__PURE__*/React.createElement(ChevronDownIcon, {
label: "",
size: "small",
color: 'currentColor',
testId: testId && `${testId}--chevron`
}));
if (isInteractive) {
return /*#__PURE__*/React.createElement(Pressable, _extends({
ref: ref,
xcss: cx(styles.container, spacing === 'spacious' && styles.containerSpacious, !isSelected && styles.iconBorderFilter, !isLoading && styles.iconBorderInteractiveFilter, styles[colorStyleKey], !isLoading && styles[interactiveStyleKey], isSelected && styles.containerSelected, hasTrailingMetric && styles.containerBadge, hasTrailingMetric && styles.containerBadgeInteractive, hasTrailingMetric && styles[metricStyleKey])
}, isLoading && {
'aria-busy': true,
'aria-disabled': true,
isDisabled: true
}, {
"aria-label": isLoading ? 'Loading' : ariaLabel,
"aria-controls": ariaControls,
"aria-expanded": ariaExpanded,
"aria-haspopup": ariaHaspopup,
onClick: isLoading ? undefined : onClick,
style: {
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
...commonStyleOverrides,
// Specified because Pressable has a default border:none which overrides the border specified on the container
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
border: `solid ${"var(--ds-border-width, 1px)"} ${isSelected ? 'oklch(from var(--border-color) calc(l * var(--border-pressed-l-factor)) c h) !important' : 'transparent'}`,
backgroundColor: isSelected ? pressedBackgroundMapping[resolvedColor] : undefined,
cursor: isLoading ? 'progress' : 'pointer'
},
testId: testId,
analyticsContext: analyticsContext,
interactionName: interactionName,
componentName: "LozengeDropdownTrigger"
}), innerContent, isLoading && /*#__PURE__*/React.createElement("span", {
className: ax([styles.loadingOverlay])
}, /*#__PURE__*/React.createElement(Spinner, {
size: spacing === 'spacious' ? 'small' : 'xsmall',
label: ", Loading",
testId: testId ? `${testId}--loading-spinner` : undefined
})));
}
return /*#__PURE__*/React.createElement("span", {
ref: ref,
style: commonStyleOverrides,
"data-testid": testId,
className: ax([styles.container, spacing === 'spacious' && styles.containerSpacious, spacing !== 'spacious' && hasTrailingMetric && styles.containerBadgePadding, styles[colorStyleKey], hasTrailingMetric && styles[metricStyleKey], styles.iconBorderFilter, styles.containerBadge])
}, innerContent);
}));
export default LozengeBase;