UNPKG

@primer/react

Version:

An implementation of GitHub's Primer Design System using React

613 lines (609 loc) • 18.4 kB
import { c } from 'react-compiler-runtime'; import { FocusKeys } from '@primer/behaviors'; import { isFocusable } from '@primer/behaviors/utils'; import React, { useRef, useState } from 'react'; import { isValidElementType } from 'react-is'; import { useRefObjectAsForwardedRef } from '../hooks/useRefObjectAsForwardedRef.js'; import { useFocusZone } from '../hooks/useFocusZone.js'; import Token from '../Token/Token.js'; import { TextInputWrapper } from '../internal/components/TextInputWrapper.js'; import UnstyledTextInput from '../internal/components/UnstyledTextInput.js'; import TextInputInnerVisualSlot from '../internal/components/TextInputInnerVisualSlot.js'; import styles from './TextInputWithTokens.module.css.js'; import { clsx } from 'clsx'; import { jsx, jsxs } from 'react/jsx-runtime'; import Text from '../Text/Text.js'; const overflowCountClassMap = { small: styles.OverflowCountSmall, medium: styles.OverflowCountMedium, large: styles.OverflowCountLarge, xlarge: styles.OverflowCountXLarge }; // using forwardRef is important so that other components (ex. Autocomplete) can use the ref function TextInputWithTokensInnerComponent(t0, forwardedRef) { const $ = c(135); let IconComponent; let LeadingVisual; let TrailingVisual; let block; let className; let contrast; let disabled; let loading; let maxHeight; let maxWidthProp; let minWidthProp; let onTokenRemove; let rest; let style; let t1; let t2; let t3; let t4; let t5; let tokens; let validationStatus; let variantProp; let visibleTokenCount; let widthProp; if ($[0] !== t0) { ({ icon: IconComponent, leadingVisual: LeadingVisual, trailingVisual: TrailingVisual, loading, loaderPosition: t1, contrast, className, block, disabled, tokens, onTokenRemove, tokenComponent: t2, preventTokenWrapping: t3, size: t4, hideTokenRemoveButtons: t5, maxHeight, width: widthProp, minWidth: minWidthProp, maxWidth: maxWidthProp, validationStatus, variant: variantProp, visibleTokenCount, style, ...rest } = t0); $[0] = t0; $[1] = IconComponent; $[2] = LeadingVisual; $[3] = TrailingVisual; $[4] = block; $[5] = className; $[6] = contrast; $[7] = disabled; $[8] = loading; $[9] = maxHeight; $[10] = maxWidthProp; $[11] = minWidthProp; $[12] = onTokenRemove; $[13] = rest; $[14] = style; $[15] = t1; $[16] = t2; $[17] = t3; $[18] = t4; $[19] = t5; $[20] = tokens; $[21] = validationStatus; $[22] = variantProp; $[23] = visibleTokenCount; $[24] = widthProp; } else { IconComponent = $[1]; LeadingVisual = $[2]; TrailingVisual = $[3]; block = $[4]; className = $[5]; contrast = $[6]; disabled = $[7]; loading = $[8]; maxHeight = $[9]; maxWidthProp = $[10]; minWidthProp = $[11]; onTokenRemove = $[12]; rest = $[13]; style = $[14]; t1 = $[15]; t2 = $[16]; t3 = $[17]; t4 = $[18]; t5 = $[19]; tokens = $[20]; validationStatus = $[21]; variantProp = $[22]; visibleTokenCount = $[23]; widthProp = $[24]; } const loaderPosition = t1 === undefined ? "auto" : t1; const TokenComponent = t2 === undefined ? Token : t2; const preventTokenWrapping = t3 === undefined ? false : t3; const size = t4 === undefined ? "xlarge" : t4; const hideTokenRemoveButtons = t5 === undefined ? false : t5; let inputPropsRest; let onBlur; let onFocus; let onKeyDown; if ($[25] !== rest) { ({ onBlur, onFocus, onKeyDown, ...inputPropsRest } = rest); $[25] = rest; $[26] = inputPropsRest; $[27] = onBlur; $[28] = onFocus; $[29] = onKeyDown; } else { inputPropsRest = $[26]; onBlur = $[27]; onFocus = $[28]; onKeyDown = $[29]; } const ref = useRef(null); useRefObjectAsForwardedRef(forwardedRef, ref); const [selectedTokenIndex, setSelectedTokenIndex] = useState(); const [tokensAreTruncated, setTokensAreTruncated] = useState(Boolean(visibleTokenCount)); let t6; if ($[30] !== selectedTokenIndex) { t6 = [selectedTokenIndex]; $[30] = selectedTokenIndex; $[31] = t6; } else { t6 = $[31]; } const { containerRef: t7 } = useFocusZone({ focusOutBehavior: "wrap", bindKeys: FocusKeys.ArrowHorizontal | FocusKeys.HomeAndEnd, focusableElementFilter: _temp, getNextFocusable: direction => { var _containerRef$current; if (!selectedTokenIndex && selectedTokenIndex !== 0) { return; } let nextIndex = selectedTokenIndex + 1; if (direction === "next") { nextIndex = nextIndex + 1; } if (direction === "previous") { nextIndex = nextIndex - 1; } if (nextIndex > tokens.length || nextIndex < 1) { return ref.current || undefined; } return (_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.children[nextIndex]; } }, t6); const containerRef = t7; let t8; if ($[32] !== containerRef || $[33] !== onTokenRemove || $[34] !== selectedTokenIndex) { t8 = tokenId => { onTokenRemove(tokenId); setTimeout(() => { var _containerRef$current2, _containerRef$current3; const nextElementToFocus = (_containerRef$current2 = containerRef.current) === null || _containerRef$current2 === void 0 ? void 0 : _containerRef$current2.children[selectedTokenIndex || 0]; const firstFocusable = nextElementToFocus && isFocusable(nextElementToFocus) ? nextElementToFocus : Array.from(((_containerRef$current3 = containerRef.current) === null || _containerRef$current3 === void 0 ? void 0 : _containerRef$current3.children) || []).find(_temp2); if (firstFocusable) { firstFocusable.focus(); } else { var _ref$current; (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.focus(); } }, 0); }; $[32] = containerRef; $[33] = onTokenRemove; $[34] = selectedTokenIndex; $[35] = t8; } else { t8 = $[35]; } const handleTokenRemove = t8; let t9; if ($[36] !== disabled) { t9 = tokenIndex => () => { if (!disabled) { setSelectedTokenIndex(tokenIndex); } }; $[36] = disabled; $[37] = t9; } else { t9 = $[37]; } const handleTokenFocus = t9; let t10; if ($[38] !== containerRef || $[39] !== visibleTokenCount) { t10 = () => { setSelectedTokenIndex(undefined); setTimeout(() => { var _containerRef$current4; if (!((_containerRef$current4 = containerRef.current) !== null && _containerRef$current4 !== void 0 && _containerRef$current4.contains(document.activeElement)) && visibleTokenCount) { setTokensAreTruncated(true); } }, 0); }; $[38] = containerRef; $[39] = visibleTokenCount; $[40] = t10; } else { t10 = $[40]; } const handleTokenBlur = t10; let t11; if ($[41] === Symbol.for("react.memo_cache_sentinel")) { t11 = event => { if (event.key === "Escape") { var _ref$current2; (_ref$current2 = ref.current) === null || _ref$current2 === void 0 ? void 0 : _ref$current2.focus(); } }; $[41] = t11; } else { t11 = $[41]; } const handleTokenKeyUp = t11; let t12; if ($[42] !== onFocus || $[43] !== visibleTokenCount) { t12 = event_0 => { onFocus && onFocus(event_0); setSelectedTokenIndex(undefined); visibleTokenCount && setTokensAreTruncated(false); }; $[42] = onFocus; $[43] = visibleTokenCount; $[44] = t12; } else { t12 = $[44]; } const handleInputFocus = t12; let t13; if ($[45] !== containerRef || $[46] !== onBlur || $[47] !== visibleTokenCount) { t13 = event_1 => { onBlur && onBlur(event_1); setTimeout(() => { var _containerRef$current5; if (!((_containerRef$current5 = containerRef.current) !== null && _containerRef$current5 !== void 0 && _containerRef$current5.contains(document.activeElement)) && visibleTokenCount) { setTokensAreTruncated(true); } }, 0); }; $[45] = containerRef; $[46] = onBlur; $[47] = visibleTokenCount; $[48] = t13; } else { t13 = $[48]; } const handleInputBlur = t13; let t14; if ($[49] !== handleTokenRemove || $[50] !== onKeyDown || $[51] !== tokens) { t14 = e => { var _ref$current3; if (onKeyDown) { onKeyDown(e); } if ((_ref$current3 = ref.current) !== null && _ref$current3 !== void 0 && _ref$current3.value) { return; } const lastToken = tokens[tokens.length - 1]; if (e.key === "Backspace" && lastToken) { handleTokenRemove(lastToken.id); if (ref.current) { ref.current.value = `${lastToken.text} `; } setTimeout(() => { var _ref$current4; (_ref$current4 = ref.current) === null || _ref$current4 === void 0 ? void 0 : _ref$current4.select(); }, 0); } }; $[49] = handleTokenRemove; $[50] = onKeyDown; $[51] = tokens; $[52] = t14; } else { t14 = $[52]; } const handleInputKeyDown = t14; let t15; if ($[53] === Symbol.for("react.memo_cache_sentinel")) { t15 = () => { var _ref$current5; (_ref$current5 = ref.current) === null || _ref$current5 === void 0 ? void 0 : _ref$current5.focus(); }; $[53] = t15; } else { t15 = $[53]; } const focusInput = t15; const preventTokenClickPropagation = _temp3; let t16; if ($[54] !== tokens || $[55] !== tokensAreTruncated || $[56] !== visibleTokenCount) { t16 = tokensAreTruncated ? tokens.slice(0, visibleTokenCount) : tokens; $[54] = tokens; $[55] = tokensAreTruncated; $[56] = visibleTokenCount; $[57] = t16; } else { t16 = $[57]; } const visibleTokens = t16; let t17; if ($[58] === Symbol.for("react.memo_cache_sentinel")) { t17 = { small: "small", medium: "small", large: "medium", xlarge: "medium" }; $[58] = t17; } else { t17 = $[58]; } const inputSizeMap = t17; const showLeadingLoadingIndicator = loading && (loaderPosition === "leading" || Boolean(LeadingVisual && loaderPosition !== "trailing")); const showTrailingLoadingIndicator = loading && (loaderPosition === "trailing" || loaderPosition === "auto" && !LeadingVisual); const t18 = Boolean(LeadingVisual || showLeadingLoadingIndicator); const t19 = Boolean(TrailingVisual || showTrailingLoadingIndicator); const t20 = inputSizeMap[size]; const t21 = Boolean(preventTokenWrapping || maxHeight) || undefined; let t22; if ($[59] !== className) { t22 = clsx(className, styles.TextInputWrapper); $[59] = className; $[60] = t22; } else { t22 = $[60]; } let t23; if ($[61] !== maxHeight || $[62] !== style) { t23 = maxHeight ? { maxHeight, ...style } : style; $[61] = maxHeight; $[62] = style; $[63] = t23; } else { t23 = $[63]; } let t24; if ($[64] !== IconComponent || $[65] !== LeadingVisual) { t24 = IconComponent && !LeadingVisual && /*#__PURE__*/jsx(IconComponent, { className: "TextInput-icon" }); $[64] = IconComponent; $[65] = LeadingVisual; $[66] = t24; } else { t24 = $[66]; } const t25 = typeof loading === "boolean"; let t26; if ($[67] !== LeadingVisual) { t26 = typeof LeadingVisual !== "string" && isValidElementType(LeadingVisual) ? /*#__PURE__*/jsx(LeadingVisual, {}) : LeadingVisual; $[67] = LeadingVisual; $[68] = t26; } else { t26 = $[68]; } let t27; if ($[69] !== showLeadingLoadingIndicator || $[70] !== t25 || $[71] !== t26) { t27 = /*#__PURE__*/jsx(TextInputInnerVisualSlot, { hasLoadingIndicator: t25, visualPosition: "leading", showLoadingIndicator: showLeadingLoadingIndicator, children: t26 }); $[69] = showLeadingLoadingIndicator; $[70] = t25; $[71] = t26; $[72] = t27; } else { t27 = $[72]; } const t28 = containerRef; const t29 = validationStatus === "error" ? "true" : "false"; let t30; if ($[73] !== disabled || $[74] !== handleInputBlur || $[75] !== handleInputFocus || $[76] !== handleInputKeyDown || $[77] !== inputPropsRest || $[78] !== t29) { t30 = /*#__PURE__*/jsx("div", { className: styles.InputWrapper, children: /*#__PURE__*/jsx(UnstyledTextInput, { ref: ref, disabled: disabled, onFocus: handleInputFocus, onBlur: handleInputBlur, onKeyDown: handleInputKeyDown, type: "text", className: styles.UnstyledTextInput, "aria-invalid": t29, ...inputPropsRest }) }); $[73] = disabled; $[74] = handleInputBlur; $[75] = handleInputFocus; $[76] = handleInputKeyDown; $[77] = inputPropsRest; $[78] = t29; $[79] = t30; } else { t30 = $[79]; } let t31; if ($[80] !== TokenComponent || $[81] !== disabled || $[82] !== handleTokenBlur || $[83] !== handleTokenFocus || $[84] !== handleTokenRemove || $[85] !== hideTokenRemoveButtons || $[86] !== selectedTokenIndex || $[87] !== size || $[88] !== visibleTokens) { let t32; if ($[90] !== TokenComponent || $[91] !== disabled || $[92] !== handleTokenBlur || $[93] !== handleTokenFocus || $[94] !== handleTokenRemove || $[95] !== hideTokenRemoveButtons || $[96] !== selectedTokenIndex || $[97] !== size) { t32 = (t33, i) => { const { id, ...tokenRest } = t33; return /*#__PURE__*/jsx(TokenComponent, { disabled: disabled, onFocus: handleTokenFocus(i), onBlur: handleTokenBlur, onKeyUp: handleTokenKeyUp, onClick: preventTokenClickPropagation, isSelected: selectedTokenIndex === i, onRemove: () => { handleTokenRemove(id); }, hideRemoveButton: disabled || hideTokenRemoveButtons, size: size, tabIndex: 0, ...tokenRest }, id); }; $[90] = TokenComponent; $[91] = disabled; $[92] = handleTokenBlur; $[93] = handleTokenFocus; $[94] = handleTokenRemove; $[95] = hideTokenRemoveButtons; $[96] = selectedTokenIndex; $[97] = size; $[98] = t32; } else { t32 = $[98]; } t31 = visibleTokens.map(t32); $[80] = TokenComponent; $[81] = disabled; $[82] = handleTokenBlur; $[83] = handleTokenFocus; $[84] = handleTokenRemove; $[85] = hideTokenRemoveButtons; $[86] = selectedTokenIndex; $[87] = size; $[88] = visibleTokens; $[89] = t31; } else { t31 = $[89]; } let t32; if ($[99] !== size || $[100] !== tokens || $[101] !== tokensAreTruncated || $[102] !== visibleTokens.length) { t32 = tokensAreTruncated && tokens.length - visibleTokens.length ? /*#__PURE__*/jsxs(Text, { className: overflowCountClassMap[size], children: ["+", tokens.length - visibleTokens.length] }) : null; $[99] = size; $[100] = tokens; $[101] = tokensAreTruncated; $[102] = visibleTokens.length; $[103] = t32; } else { t32 = $[103]; } let t33; if ($[104] !== preventTokenWrapping || $[105] !== t28 || $[106] !== t30 || $[107] !== t31 || $[108] !== t32) { t33 = /*#__PURE__*/jsxs("div", { ref: t28, className: styles.Container, "data-prevent-token-wrapping": preventTokenWrapping, children: [t30, t31, t32] }); $[104] = preventTokenWrapping; $[105] = t28; $[106] = t30; $[107] = t31; $[108] = t32; $[109] = t33; } else { t33 = $[109]; } const t34 = typeof loading === "boolean"; let t35; if ($[110] !== TrailingVisual) { t35 = typeof TrailingVisual !== "string" && isValidElementType(TrailingVisual) ? /*#__PURE__*/jsx(TrailingVisual, {}) : TrailingVisual; $[110] = TrailingVisual; $[111] = t35; } else { t35 = $[111]; } let t36; if ($[112] !== showTrailingLoadingIndicator || $[113] !== t34 || $[114] !== t35) { t36 = /*#__PURE__*/jsx(TextInputInnerVisualSlot, { hasLoadingIndicator: t34, visualPosition: "trailing", showLoadingIndicator: showTrailingLoadingIndicator, children: t35 }); $[112] = showTrailingLoadingIndicator; $[113] = t34; $[114] = t35; $[115] = t36; } else { t36 = $[115]; } let t37; if ($[116] !== block || $[117] !== contrast || $[118] !== disabled || $[119] !== maxWidthProp || $[120] !== minWidthProp || $[121] !== t18 || $[122] !== t19 || $[123] !== t20 || $[124] !== t21 || $[125] !== t22 || $[126] !== t23 || $[127] !== t24 || $[128] !== t27 || $[129] !== t33 || $[130] !== t36 || $[131] !== validationStatus || $[132] !== variantProp || $[133] !== widthProp) { t37 = /*#__PURE__*/jsxs(TextInputWrapper, { block: block, contrast: contrast, disabled: disabled, hasLeadingVisual: t18, hasTrailingVisual: t19, width: widthProp, minWidth: minWidthProp, maxWidth: maxWidthProp, size: t20, validationStatus: validationStatus, variant: variantProp, onClick: focusInput, "data-token-wrapping": t21, className: t22, style: t23, children: [t24, t27, t33, t36] }); $[116] = block; $[117] = contrast; $[118] = disabled; $[119] = maxWidthProp; $[120] = minWidthProp; $[121] = t18; $[122] = t19; $[123] = t20; $[124] = t21; $[125] = t22; $[126] = t23; $[127] = t24; $[128] = t27; $[129] = t33; $[130] = t36; $[131] = validationStatus; $[132] = variantProp; $[133] = widthProp; $[134] = t37; } else { t37 = $[134]; } return t37; } function _temp3(event_2) { event_2.stopPropagation(); } function _temp2(el) { return isFocusable(el); } function _temp(element) { return !element.getAttributeNames().includes("aria-hidden"); } const TextInputWithTokens = /*#__PURE__*/React.forwardRef(TextInputWithTokensInnerComponent); TextInputWithTokens.displayName = 'TextInputWithTokens'; TextInputWithTokens.__SLOT__ = Symbol('TextInputWithTokens'); export { TextInputWithTokens as default };