@atlaskit/editor-plugin-mentions
Version:
Mentions plugin for @atlaskit/editor-core
232 lines (227 loc) • 9.24 kB
JavaScript
/* InviteItemWithEmailDomain.tsx generated by @compiled/babel-plugin v0.39.1 */
import _extends from "@babel/runtime/helpers/extends";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import "./InviteItemWithEmailDomain.compiled.css";
import { ax, ix } from "@compiled/react/runtime";
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { FormattedMessage, injectIntl } from 'react-intl';
import { mentionMessages as messages } from '@atlaskit/editor-common/messages';
import EmailIcon from '@atlaskit/icon/core/email';
import StatusErrorIcon from '@atlaskit/icon/core/status-error';
import Pressable from '@atlaskit/primitives/pressable';
import { isValidEmail } from '@atlaskit/user-picker';
var mentionItemStyle = null;
var mentionItemSelectedStyle = null;
var displayNameStyles = {
localPart: "_1i4q1hna",
domainPart: "_1e0c1o8l _p12f1osq _1i4q1hna"
};
var DisplayName = function DisplayName(_ref) {
var name = _ref.name;
var atIndex = name.indexOf('@');
if (atIndex === -1) {
return /*#__PURE__*/React.createElement("span", {
className: ax([displayNameStyles.localPart])
}, name);
}
var localPart = name.slice(0, atIndex);
var domainPart = name.slice(atIndex); // includes the @
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
className: ax([displayNameStyles.localPart])
}, localPart), /*#__PURE__*/React.createElement("span", {
className: ax([displayNameStyles.domainPart])
}, domainPart));
};
var style = {
byline: "_19pkv77o",
rowStyle: "_1reo15vq _18m915vq _4cvr1h6o _1e0c1txw _2lx2vrvc _1n261g80 _ca0q12x7 _n3td12x7 _19bvutpp _u5f3utpp _1bto1l2s _s7n4nkob",
avatar: "_16jlidpf _1o9zkb7n _i0dl1wug _1e0c1txw _4cvr1h6o _1bah1h6o _kqswh2mm _1bsb14no _4t3i14no",
nameSection: "_16jlkb7n _1o9zkb7n _i0dlf1ug _1ul9idpf _18u0utpp _2hwxu2gc _syazazsu",
capitalize: "_1p1d1dk0",
inviteButton: "_2rko12b0 _11c8fhey _1h6d1l7x _1dqonqa1 _189ee4h9 _1e0c116y _4cvr1h6o _1bah1h6o _ca0q12x7 _u5f3utpp _n3td12x7 _19bvutpp _syazazsu _k48p1wq8 _4t3iviql _bfhksm61 _cun9187o _irr31dpa"
};
var VALID_OPTION = 'VALID';
var POTENTIAL_OPTION = 'POTENTIAL';
// eslint-disable-next-line require-unicode-regexp
var COMPLETE_EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/i;
var ERROR_DELAY_MS = 750;
/**
* Truncates an email-like string to fit within a max length by inserting an
* ellipsis into the middle of the local part (before the @).
*
* Preserves the full `@domain` suffix so users can always see
* which domain the invite targets.
*/
export var truncateInviteOption = function truncateInviteOption(value) {
var maxLength = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 34;
if (value.length <= maxLength) {
return value;
}
var atIndex = value.lastIndexOf('@');
if (atIndex === -1) {
// No @ — truncate to maxLength and append ellipsis
var _ellipsis = "\u2026";
return "".concat(value.slice(0, maxLength - 1)).concat(_ellipsis);
}
var domain = value.slice(atIndex); // includes @
var local = value.slice(0, atIndex);
var ellipsis = "\u2026";
var available = maxLength - domain.length - ellipsis.length;
if (available <= 0) {
// Domain alone exceeds budget — show as much as we can
return "".concat(ellipsis).concat(domain.slice(-(maxLength - ellipsis.length)));
}
var leading = Math.ceil(available / 2);
var trailing = Math.floor(available / 2);
var truncatedLocal = trailing > 0 ? "".concat(local.slice(0, leading)).concat(ellipsis).concat(local.slice(local.length - trailing)) : "".concat(local.slice(0, leading)).concat(ellipsis);
return "".concat(truncatedLocal).concat(domain);
};
var getInviteOption = function getInviteOption(inputValue, suggestedEmailDomain) {
if (inputValue.includes(' ') && inputValue.includes('@')) {
return truncateInviteOption(inputValue);
}
var isEmail = inputValue && [VALID_OPTION, POTENTIAL_OPTION].includes(isValidEmail(inputValue));
if (isEmail || !suggestedEmailDomain) {
return truncateInviteOption(inputValue);
}
return truncateInviteOption("".concat(inputValue.toLocaleLowerCase(), "@").concat(suggestedEmailDomain));
};
var getIsEmailValid = function getIsEmailValid(inputValue) {
if (!inputValue || inputValue.length === 0) {
return false;
}
if (inputValue.includes(' ')) {
return false;
}
if (inputValue.includes('@') && !COMPLETE_EMAIL_REGEX.test(inputValue)) {
return false;
}
return true;
};
export var INVITE_ITEM_DESCRIPTION = {
id: 'invite-teammate'
};
var InviteItemWithEmailDomain = function InviteItemWithEmailDomain(_ref2) {
var productName = _ref2.productName,
onMount = _ref2.onMount,
onMouseEnter = _ref2.onMouseEnter,
onSelection = _ref2.onSelection,
selected = _ref2.selected,
userRole = _ref2.userRole,
_ref2$query = _ref2.query,
query = _ref2$query === void 0 ? '' : _ref2$query,
emailDomain = _ref2.emailDomain,
intl = _ref2.intl;
var _useState = useState(query.length !== 0 && !getIsEmailValid(query)),
_useState2 = _slicedToArray(_useState, 2),
showErrorIcon = _useState2[0],
setShowErrorIcon = _useState2[1];
var timeoutRef = useRef();
var possibleEmail = getInviteOption(query, emailDomain);
var isEmailValid = getIsEmailValid(query);
var getByline = function getByline() {
if (showErrorIcon) {
return intl.formatMessage(messages.inviteTeammateInvalidEmail);
}
if (userRole === 'admin') {
return /*#__PURE__*/React.createElement(FormattedMessage
// Ignored via go/ees005
// eslint-disable-next-line react/jsx-props-no-spreading
, _extends({}, messages.inviteItemTitle, {
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
values: {
userRole: userRole || 'basic',
productName: /*#__PURE__*/React.createElement("span", {
"data-testid": "capitalized-message",
className: ax([style.capitalize])
}, productName)
}
}));
}
return intl.formatMessage(messages.sendInvite);
};
var onInviteButtonClick = useCallback(
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function (event) {
if (onSelection) {
event.preventDefault();
onSelection(INVITE_ITEM_DESCRIPTION, event);
}
}, [onSelection]);
var onItemMouseEnter = useCallback(
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function (event) {
if (onMouseEnter) {
onMouseEnter(INVITE_ITEM_DESCRIPTION, event);
}
}, [onMouseEnter]);
var onItemFocus = useCallback(
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function (event) {
if (onMouseEnter) {
onMouseEnter(INVITE_ITEM_DESCRIPTION, event);
}
}, [onMouseEnter]);
useEffect(function () {
if (onMount) {
onMount();
}
}, [onMount]);
// Debounce error icon display: only show error after user stops typing invalid input
useEffect(function () {
// Clear existing timeout
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
timeoutRef.current = undefined;
}
// Reset error icon immediately if input becomes valid or empty
if (isEmailValid || query.length === 0) {
setShowErrorIcon(false);
} else {
// Debounce: only show error icon after delay if input remains invalid
timeoutRef.current = setTimeout(function () {
setShowErrorIcon(true);
}, ERROR_DELAY_MS);
}
// Cleanup timeout on unmount or when query changes
return function () {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
};
}, [query, isEmailValid]);
var displayName = query && emailDomain ? possibleEmail : undefined;
return displayName && /*#__PURE__*/React.createElement("div", {
onMouseEnter: onItemMouseEnter,
onFocus: onItemFocus,
"data-id": INVITE_ITEM_DESCRIPTION.id,
className: ax(["_1reo15vq _18m915vq _bfhk1j28 _1e0c1ule _2mzuglyw", selected && "_bfhk1dpa"])
}, /*#__PURE__*/React.createElement("div", {
className: ax([style.rowStyle])
}, /*#__PURE__*/React.createElement("span", {
className: ax([style.avatar])
}, showErrorIcon ? /*#__PURE__*/React.createElement(StatusErrorIcon, {
label: "Error",
color: "var(--ds-icon-danger, #C9372C)"
}) : /*#__PURE__*/React.createElement(EmailIcon, {
label: "Email",
color: "var(--ds-icon-subtle, #505258)"
})), /*#__PURE__*/React.createElement("div", {
"data-testid": "name-section",
className: ax([style.nameSection])
}, /*#__PURE__*/React.createElement(DisplayName, {
name: displayName
}), /*#__PURE__*/React.createElement("div", {
className: ax([style.byline])
}, getByline())), /*#__PURE__*/React.createElement(Pressable, {
onClick: onInviteButtonClick,
xcss: style.inviteButton,
isDisabled: showErrorIcon
}, intl.formatMessage(messages.inviteButton))));
};
// eslint-disable-next-line @typescript-eslint/ban-types
var _default_1 = injectIntl(InviteItemWithEmailDomain);
export default _default_1;