UNPKG

@atlaskit/tag

Version:

A tag labels UI objects for quick recognition and navigation.

225 lines (207 loc) • 9.08 kB
/* avatar-tag.tsx generated by @compiled/babel-plugin v3.0.2 */ import _extends from "@babel/runtime/helpers/extends"; import "./avatar-tag.compiled.css"; import * as React from 'react'; import { ax, ix } from "@compiled/react/runtime"; // Clips avatar-tag text during motion and restores measured truncation after it settles. import { cloneElement, forwardRef, isValidElement, memo, useCallback } from 'react'; import StatusVerifiedIcon from '@atlaskit/icon/core/status-verified'; import { fg } from '@atlaskit/platform-feature-flags/fg'; import { LinkWrapper } from './link-wrapper'; import { RemovableWrapper } from './removable-wrapper'; import { TagMotion } from './tag-motion'; import { markAsTagMotionCapable } from './tag-motion-capability'; import { useButtonInteraction } from './use-button-interaction'; import { useLink } from './use-link'; import { useRemoveButton } from './use-remove-button'; import { useTagRemoval } from './use-tag-removal'; /** * The type values that AvatarTag accepts. */ /** * Props controlled by AvatarTag that will be passed to the avatar component. * These props are managed internally by AvatarTag. */ /** * Common props shared across all AvatarTag types. */ /** * Props for user avatar tags with circular avatars. */ /** * Props for other/teams avatar tags with square avatars. */ /** * Props for agent avatar tags with hexagonal avatars. */ /** * Props for AvatarTag component. Uses discriminated union based on `type`. */ const styles = { baseStyles: "_zulpv77o _2rko1rr0 _11c8wadc _1dqonqa1 _189ee4h9 _1rjcze3t _1mou1b66 _195g1b66 _1e0c116y _vchhusvi _1ul9idpf _p12ff6dh _4t3iv47k _kqswh2mm _4cvr1h6o _s7n4nkob _bfhksm61 _syazi7uo _80om73ad _y4tii2wt _bozgze3t _1rfu1q9c", noMarginStyles: "_1mouze3t _195gze3t", otherBaseStyles: "_2rko12b0 _y4ti1b66", agentBaseStyles: "_2rko12b0 _y4ti1b66", removableStyles: "_y4ti1l7b _1ul98pqr", userRemovableStyles: "_y4ti1l7b _1ul98pqr", avatarStyles: "_4bfu1r31 _1hmsglyw _ajmmnqa1 _2rko1rr0 _1reo15vq _18m915vq _1e0c116y _4cvr1h6o _1o9zidpf _ahbq1n1a", otherAvatarStyles: "_2rko12b0", agentAvatarStyles: "_2rkoidpf", textStyles: "_1reo15vq _18m915vq _16jlkb7n _1o9zkb7n _i0dlf1ug _o5721q9c _1ul9idpf _syazi7uo", textEllipsis: "_1bto1l2s", textClip: "_1btozryt", afterStyles: "_16jlidpf _1o9zidpf _i0dl1wug _1e0c1txw _4cvr1h6o _lcxv1wug _ahbqv77o _kqswh2mm", afterMotionStyles: "_1ul9utpp", verifiedIconStyles: "_1e0c116y _4cvr1h6o _1o9zidpf _syaz6txe _ahbqt94y", focusRingStyles: "_1ygbdfik _1ah3v77o", childFocusRingStyles: "_1a37dfik _1cwgv77o", interactiveBaseStyles: "_80omtlke _7nm0v77o _59381r31 _yha2glyw _1nmznqa1 _1ufy15vq _turg15vq _jr6g1snc _1ymragmp _1y1s10yn _1hw7116y _6wji1h6o _1k6fidpf _43dsjdj5 _jwdiagmp _1cayjdj5 _102s1snc _yi8hagmp _h79h10yn _9m7f1r31 _w7swglyw _15a9nqa1 _jxlhagmp", interactiveHoverStyles: "_fs7a1r31 _1uxk8stv _12u8nqa1 _irr31dpa _oxk4jdj5 _1di6fcek", interactiveMotionStyles: "_v564k6bl _1ggl5xtf", activeMotionStyles: "_1reo15vq _18m915vq" }; /* eslint-disable @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/design-system/no-nested-styles, @atlaskit/ui-styling-standard/no-important-styles */ // Border color style - gray only for AvatarTag. // Uses the new color.border.accent.gray.subtle token directly so no OKLCH/color-mix // runtime transforms are needed. const borderColorStyles = { root: "_119bmsup" }; // Border filter styles - base state const borderFilterStyles = { root: "_1h6dip4g" }; /* eslint-enable @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/design-system/no-nested-styles, @atlaskit/ui-styling-standard/no-important-styles */ /** * __AvatarTag__ * * AvatarTag is a specialized tag for representing people, teams/other entities, or agents with an avatar and name. * The visual appearance (round, square, or hexagonal) is determined by the `type` prop. */ const AvatarTagComponent = /*#__PURE__*/forwardRef(function AvatarTag({ text, type, avatar: AvatarComponent, href, linkComponent, isRemovable = true, removeButtonLabel, onBeforeRemoveAction, onAfterRemoveAction, testId, isVerified, // Shows verified icon for 'other' type tags maxWidth, hasMargin = true, onClick, ...other }, ref) { const isMotionEnabled = fg('platform-dst-motion-uplift-labels'); const { status, handleRemoveRequest, onKeyPress, removingTag, showingTag } = useTagRemoval(onBeforeRemoveAction); const onShrinkOutExitComplete = useCallback(() => { onAfterRemoveAction === null || onAfterRemoveAction === void 0 ? void 0 : onAfterRemoveAction(text); }, [onAfterRemoveAction, text]); const { isLink, LinkComponent } = useLink(href, linkComponent); const { isLinkHovered, isOverButton, isButtonFocused, isLinkFocused, buttonHandlers, linkHandlers } = useButtonInteraction(); // Determine styles based on type const isOtherType = type === 'other'; const isAgentType = type === 'agent'; const isUserType = type === 'user'; // isVerified is only available for 'other' type const showVerified = isOtherType && isVerified; // Determine avatar appearance based on type const avatarAppearance = isUserType ? 'circle' : isAgentType ? 'hexagon' : 'square'; // Determine remove button shape based on type const removeButtonShape = isUserType ? 'circle' : 'default'; const removeButton = useRemoveButton({ isRemovable, tagText: text, removeButtonLabel, testId, handleRemoveRequest, removingTag, showingTag, onKeyPress, shape: removeButtonShape, buttonHandlers }); // Render the avatar with controlled props, then clone so our props are applied const controlledProps = { size: 'xxsmall', appearance: avatarAppearance, borderColor: 'transparent' }; const AvatarComponentTyped = AvatarComponent; const rendered = /*#__PURE__*/React.createElement(AvatarComponentTyped, controlledProps); const avatarElement = // eslint-disable-next-line @repo/internal/react/no-clone-element /*#__PURE__*/isValidElement(rendered) ? /*#__PURE__*/cloneElement(rendered, controlledProps) : rendered; const renderTagContent = (tagRef, isEntering = false, isExiting = false, hasEllipsis = null) => /*#__PURE__*/React.createElement("span", _extends({}, other, { ref: tagRef, "data-testid": testId // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- maxWidth is a runtime consumer value , style: maxWidth !== undefined ? { maxWidth } : undefined, className: ax([styles.baseStyles, (isMotionEnabled || !hasMargin) && styles.noMarginStyles, isOtherType && styles.otherBaseStyles, isAgentType && styles.agentBaseStyles, borderColorStyles.root, borderFilterStyles.root, isLink && styles.interactiveBaseStyles, isLink && styles.focusRingStyles, isLink && isMotionEnabled && styles.interactiveMotionStyles, (isEntering || isExiting) && styles.activeMotionStyles, isLink && isLinkHovered && !isOverButton && styles.interactiveHoverStyles, isRemovable && !isUserType && styles.removableStyles, isRemovable && isUserType && styles.userRemovableStyles, isLinkFocused && !isButtonFocused && styles.childFocusRingStyles]) }), /*#__PURE__*/React.createElement(LinkWrapper, { isLink: isLink, href: href, LinkComponent: LinkComponent, testId: testId, linkHandlers: linkHandlers, onClick: onClick }, /*#__PURE__*/React.createElement("span", { className: ax([styles.avatarStyles, isOtherType && styles.otherAvatarStyles, isAgentType && styles.agentAvatarStyles]) }, avatarElement), /*#__PURE__*/React.createElement("span", { "data-tag-text": true, className: ax([styles.textStyles, hasEllipsis === false ? styles.textClip : styles.textEllipsis]) }, text)), showVerified && /*#__PURE__*/React.createElement("span", { className: ax([styles.verifiedIconStyles]) }, /*#__PURE__*/React.createElement(StatusVerifiedIcon, { label: "Verified", size: "small" })), removeButton && /*#__PURE__*/React.createElement("span", { className: ax([styles.afterStyles, isMotionEnabled && styles.afterMotionStyles]) }, !isExiting && removeButton)); if (isMotionEnabled) { return /*#__PURE__*/React.createElement(TagMotion, { forwardedRef: ref, hasMargin: hasMargin, onExitComplete: isRemovable ? onShrinkOutExitComplete : undefined, status: status }, ({ hasEllipsis, isEntering, isExiting, ref: motionRef }) => renderTagContent(motionRef, isEntering, isExiting, hasEllipsis)); } return /*#__PURE__*/React.createElement(RemovableWrapper, { isRemovable: isRemovable, status: status, onShrinkOutExitComplete: isRemovable ? onShrinkOutExitComplete : undefined }, renderTagContent(ref)); }); /** * __Avatar tag__ */ const AvatarTag = markAsTagMotionCapable( /*#__PURE__*/memo(AvatarTagComponent)); export default AvatarTag;