@primer/react
Version:
An implementation of GitHub's Primer Design System using React
297 lines (294 loc) • 8.58 kB
JavaScript
import { c } from 'react-compiler-runtime';
import React, { useRef, useId, useEffect } from 'react';
import { TextInputBaseWrapper } from '../internal/components/TextInputWrapper.js';
import classes from './TextArea.module.css.js';
import { AlertFillIcon } from '@primer/octicons-react';
import { CharacterCounter } from '../utils/character-counter.js';
import VisuallyHidden from '../_VisuallyHidden.js';
import { clsx } from 'clsx';
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import Text from '../Text/Text.js';
const DEFAULT_TEXTAREA_ROWS = 7;
const DEFAULT_TEXTAREA_COLS = 30;
const DEFAULT_TEXTAREA_RESIZE = 'both';
/**
* An accessible, native textarea component that supports validation states.
* This component accepts all native HTML <textarea> attributes as props.
*/
const Textarea = /*#__PURE__*/React.forwardRef((t0, ref) => {
const $ = c(68);
let block;
let characterLimit;
let className;
let contrast;
let defaultValue;
let disabled;
let maxHeight;
let minHeight;
let onChange;
let required;
let rest;
let style;
let t1;
let t2;
let t3;
let validationStatus;
let value;
if ($[0] !== t0) {
({
value,
disabled,
required,
validationStatus,
rows: t1,
cols: t2,
resize: t3,
block,
contrast,
className,
minHeight,
maxHeight,
style,
characterLimit,
onChange,
defaultValue,
...rest
} = t0);
$[0] = t0;
$[1] = block;
$[2] = characterLimit;
$[3] = className;
$[4] = contrast;
$[5] = defaultValue;
$[6] = disabled;
$[7] = maxHeight;
$[8] = minHeight;
$[9] = onChange;
$[10] = required;
$[11] = rest;
$[12] = style;
$[13] = t1;
$[14] = t2;
$[15] = t3;
$[16] = validationStatus;
$[17] = value;
} else {
block = $[1];
characterLimit = $[2];
className = $[3];
contrast = $[4];
defaultValue = $[5];
disabled = $[6];
maxHeight = $[7];
minHeight = $[8];
onChange = $[9];
required = $[10];
rest = $[11];
style = $[12];
t1 = $[13];
t2 = $[14];
t3 = $[15];
validationStatus = $[16];
value = $[17];
}
const rows = t1 === undefined ? DEFAULT_TEXTAREA_ROWS : t1;
const cols = t2 === undefined ? DEFAULT_TEXTAREA_COLS : t2;
const resize = t3 === undefined ? DEFAULT_TEXTAREA_RESIZE : t3;
const [characterCount, setCharacterCount] = React.useState("");
const [isOverLimit, setIsOverLimit] = React.useState(false);
const [screenReaderMessage, setScreenReaderMessage] = React.useState("");
const characterCounterRef = useRef(null);
const characterCountId = useId();
const characterCountStaticMessageId = useId();
let t4;
let t5;
if ($[18] !== characterLimit) {
t4 = () => {
if (characterLimit) {
characterCounterRef.current = new CharacterCounter({
onCountUpdate: (count, overLimit, message) => {
setCharacterCount(message);
setIsOverLimit(overLimit);
},
onScreenReaderAnnounce: message_0 => {
setScreenReaderMessage(message_0);
}
});
return () => {
var _characterCounterRef$;
(_characterCounterRef$ = characterCounterRef.current) === null || _characterCounterRef$ === void 0 ? void 0 : _characterCounterRef$.cleanup();
};
}
};
t5 = [characterLimit];
$[18] = characterLimit;
$[19] = t4;
$[20] = t5;
} else {
t4 = $[19];
t5 = $[20];
}
useEffect(t4, t5);
let t6;
let t7;
if ($[21] !== characterLimit || $[22] !== defaultValue || $[23] !== value) {
t6 = () => {
if (characterLimit && characterCounterRef.current) {
const currentValue = value !== undefined ? String(value) : defaultValue !== undefined ? String(defaultValue) : "";
characterCounterRef.current.updateCharacterCount(currentValue.length, characterLimit);
}
};
t7 = [value, defaultValue, characterLimit];
$[21] = characterLimit;
$[22] = defaultValue;
$[23] = value;
$[24] = t6;
$[25] = t7;
} else {
t6 = $[24];
t7 = $[25];
}
useEffect(t6, t7);
let t8;
if ($[26] !== characterLimit || $[27] !== onChange) {
t8 = e => {
var _onChange;
if (characterLimit && characterCounterRef.current) {
characterCounterRef.current.updateCharacterCount(e.target.value.length, characterLimit);
}
(_onChange = onChange) === null || _onChange === void 0 ? void 0 : _onChange(e);
};
$[26] = characterLimit;
$[27] = onChange;
$[28] = t8;
} else {
t8 = $[28];
}
const handleTextareaChange = t8;
const isValid = isOverLimit ? "error" : validationStatus;
const t9 = isValid === "error" ? "true" : "false";
let t10;
if ($[29] !== maxHeight || $[30] !== minHeight || $[31] !== style) {
t10 = {
minHeight,
maxHeight,
...style
};
$[29] = maxHeight;
$[30] = minHeight;
$[31] = style;
$[32] = t10;
} else {
t10 = $[32];
}
let t11;
if ($[33] !== characterCountStaticMessageId || $[34] !== characterLimit || $[35] !== rest) {
t11 = characterLimit ? [characterCountStaticMessageId, rest["aria-describedby"]].filter(Boolean).join(" ") || undefined : rest["aria-describedby"];
$[33] = characterCountStaticMessageId;
$[34] = characterLimit;
$[35] = rest;
$[36] = t11;
} else {
t11 = $[36];
}
let t12;
if ($[37] !== cols || $[38] !== defaultValue || $[39] !== disabled || $[40] !== handleTextareaChange || $[41] !== ref || $[42] !== required || $[43] !== resize || $[44] !== rest || $[45] !== rows || $[46] !== t10 || $[47] !== t11 || $[48] !== t9 || $[49] !== value) {
t12 = /*#__PURE__*/jsx("textarea", {
value: value,
defaultValue: defaultValue,
"data-resize": resize,
"aria-required": required,
"aria-invalid": t9,
ref: ref,
disabled: disabled,
rows: rows,
cols: cols,
className: classes.TextArea,
onChange: handleTextareaChange,
style: t10,
...rest,
"aria-describedby": t11
});
$[37] = cols;
$[38] = defaultValue;
$[39] = disabled;
$[40] = handleTextareaChange;
$[41] = ref;
$[42] = required;
$[43] = resize;
$[44] = rest;
$[45] = rows;
$[46] = t10;
$[47] = t11;
$[48] = t9;
$[49] = value;
$[50] = t12;
} else {
t12 = $[50];
}
let t13;
if ($[51] !== block || $[52] !== className || $[53] !== contrast || $[54] !== disabled || $[55] !== isValid || $[56] !== t12) {
t13 = /*#__PURE__*/jsx(TextInputBaseWrapper, {
validationStatus: isValid,
disabled: disabled,
block: block,
contrast: contrast,
className: className,
children: t12
});
$[51] = block;
$[52] = className;
$[53] = contrast;
$[54] = disabled;
$[55] = isValid;
$[56] = t12;
$[57] = t13;
} else {
t13 = $[57];
}
let t14;
if ($[58] !== characterCount || $[59] !== characterCountId || $[60] !== characterCountStaticMessageId || $[61] !== characterLimit || $[62] !== isOverLimit || $[63] !== screenReaderMessage) {
t14 = characterLimit && /*#__PURE__*/jsxs(Fragment, {
children: [/*#__PURE__*/jsx(VisuallyHidden, {
"aria-live": "polite",
role: "status",
children: screenReaderMessage
}), /*#__PURE__*/jsxs(VisuallyHidden, {
id: characterCountStaticMessageId,
children: ["You can enter up to ", characterLimit, " ", characterLimit === 1 ? "character" : "characters"]
}), /*#__PURE__*/jsxs(Text, {
"aria-hidden": "true",
id: characterCountId,
size: "small",
className: clsx(classes.CharacterCounter, isOverLimit && classes["CharacterCounter--error"]),
children: [isOverLimit && /*#__PURE__*/jsx(AlertFillIcon, {
size: 16
}), characterCount]
})]
});
$[58] = characterCount;
$[59] = characterCountId;
$[60] = characterCountStaticMessageId;
$[61] = characterLimit;
$[62] = isOverLimit;
$[63] = screenReaderMessage;
$[64] = t14;
} else {
t14 = $[64];
}
let t15;
if ($[65] !== t13 || $[66] !== t14) {
t15 = /*#__PURE__*/jsxs(Fragment, {
children: [t13, t14]
});
$[65] = t13;
$[66] = t14;
$[67] = t15;
} else {
t15 = $[67];
}
return t15;
});
Textarea.displayName = 'Textarea';
Textarea.__SLOT__ = Symbol('Textarea');
export { DEFAULT_TEXTAREA_COLS, DEFAULT_TEXTAREA_RESIZE, DEFAULT_TEXTAREA_ROWS, Textarea as default };