@primer/react
Version:
An implementation of GitHub's Primer Design System using React
613 lines (609 loc) • 18.4 kB
JavaScript
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 };