nudge-components-library
Version:
A library of nudge UI components
82 lines (79 loc) • 4.1 kB
JavaScript
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import { useContext, useState, useRef, useEffect } from 'react';
import { ThemeContext } from '../../theme/ThemeContext.js';
import '../../styles/tokens.css.js';
import '../../styles/globals.css.js';
import styles from './TextBox.module.css.js';
function TextBox({ textBoxLabel, placeholder, value, defaultValue, onChange, disabled = false, nudgeText, id, ariaLabel, onFocus, onBlur, onCommit, nudgeVisible = true, nudgePosition = "bottom", renderNudge, }) {
const theme = useContext(ThemeContext);
const [text, setText] = useState(value !== undefined ? value : defaultValue);
const inputRef = useRef(null);
const containerRef = useRef(null);
useEffect(() => {
if (value !== undefined) {
setText(value);
}
}, [value]);
const handleFocus = (e) => {
e.target.select();
onFocus?.(e);
};
const handleTouchStart = (e) => {
if (onFocus) {
onFocus(e);
}
};
const handleClick = (e) => {
if (inputRef.current) {
inputRef.current.select();
}
};
const handleChange = (event) => {
const newValue = event.target.value;
setText(newValue);
onChange?.(newValue);
};
useEffect(() => {
const handleTouchOutside = (event) => {
if (containerRef.current &&
!containerRef.current.contains(event.target)) {
if (onBlur) {
const dummyEvent = {
target: { value: text },
};
onBlur(dummyEvent);
}
onCommit?.(text);
}
};
document.addEventListener("touchstart", handleTouchOutside);
return () => {
document.removeEventListener("touchstart", handleTouchOutside);
};
}, [onBlur, onCommit, text]);
const nudgeId = id ? `${id}-nudge` : undefined;
const nudgeElement = renderNudge && nudgeVisible ? (jsx("div", { id: nudgeId, style: theme.textBox.nudgeText, children: renderNudge(text) })) : nudgeVisible && nudgeText ? (jsx("div", { id: nudgeId, style: theme.textBox.nudgeText, children: nudgeText })) : null;
const inputElement = (jsx("input", { type: "text", id: id, ref: inputRef, value: text, onChange: handleChange, onFocus: handleFocus, onTouchStart: handleTouchStart, onClick: handleClick, onBlur: (e) => {
onBlur?.(e);
onCommit?.(e.target.value);
}, placeholder: placeholder, "aria-label": ariaLabel ?? textBoxLabel, style: {
...theme.textBox.input,
"--base-border": theme.textBox.input.baseBorder,
"--hover-border": theme.textBox.hover.hoverBorder,
"--placeholder-color": theme.textBox.input.placeholderColor,
"--placeholder-font-size": theme.textBox.input.placeholderFontSize,
}, disabled: disabled, className: styles.inputTextBox }));
let content;
if (nudgeVisible && (nudgePosition === "left" || nudgePosition === "right")) {
content = (jsxs("div", { style: { display: "flex", alignItems: "center" }, children: [nudgePosition === "left" && (jsx("div", { style: theme.textBox.nudgeLeft, children: nudgeElement })), inputElement, nudgePosition === "right" && (jsx("div", { style: theme.textBox.nudgeRight, children: nudgeElement }))] }));
}
else {
content = (jsxs(Fragment, { children: [nudgeVisible && nudgePosition === "top" && (jsx("div", { style: theme.textBox.nudgeTop, children: nudgeElement })), inputElement, nudgeVisible && nudgePosition === "bottom" && (jsx("div", { style: theme.textBox.nudgeBottom, children: nudgeElement }))] }));
}
return (jsxs("div", { style: {
...theme.textBox.wrapper,
...(disabled ? theme.textBox.disabled : {}),
}, ref: containerRef, children: [jsx("div", { style: theme.slider.sliderLabel, children: jsx("label", { htmlFor: id, children: textBoxLabel }) }), content] }));
}
export { TextBox };
//# sourceMappingURL=TextBox.js.map