87 lines
2.9 KiB
JavaScript
87 lines
2.9 KiB
JavaScript
import { Component } from 'react';
|
|
import TextField from '@mui/material/TextField';
|
|
|
|
/**
|
|
* Centralized single-line text field with the same outlined look everywhere.
|
|
* Wraps MUI TextField; `value`/`onChange` follow the `(nextValue)` signature
|
|
* used across the app.
|
|
*
|
|
* @component SingleLineTextEdit
|
|
* @import dashgui/SingleLineTextEdit
|
|
* @defaultExport
|
|
*
|
|
* @prop {string} value - Controlled field value.
|
|
* @prop {(nextValue: string) => void} onChange - Called with the new string value (not an event). Not called while `readOnly`.
|
|
* @prop {React.Ref} [inputRef] - Ref forwarded to the inner input (used by EditablePanelTile to focus on edit).
|
|
* @prop {ReactNode} [label=Name] - Outlined field label.
|
|
* @prop {boolean} [readOnly=false] - When true, the input is read-only: non-editable, not tabbable, spellcheck off, and onChange is suppressed.
|
|
* @prop {boolean} [disabled=false] - Passed to TextField — disables the field.
|
|
* @prop {boolean} [required=false] - Passed to TextField — marks the field required.
|
|
* @prop {boolean} [fullWidth=true] - TextField fullWidth prop.
|
|
* @prop {boolean} [autoFocus=false] - TextField autoFocus prop.
|
|
* @prop {string} [autoComplete=off] - TextField autoComplete prop.
|
|
* @prop {'small' | 'medium'} [size] - TextField size prop.
|
|
* @prop {object} [slotProps] - MUI slotProps, merged (input/htmlInput are augmented for readOnly/spellCheck/tabIndex).
|
|
* @prop {object} [sx] - Extra styles passed to TextField.
|
|
* @prop {any} [otherProps] - Any remaining TextField props (helperText, etc.) are spread onto TextField.
|
|
*
|
|
* @behaviour Always renders `variant="outlined"` for a consistent look.
|
|
* @behaviour readOnly inputs get `spellCheck=false` and `tabIndex=-1`, so they are visually editable but not interactive.
|
|
* @behaviour Because it wraps TextField, styling is theme-consistent across the app.
|
|
*/
|
|
class SingleLineTextEdit extends Component {
|
|
render() {
|
|
const {
|
|
value,
|
|
onChange,
|
|
inputRef,
|
|
label,
|
|
disabled = false,
|
|
readOnly = false,
|
|
autoFocus = false,
|
|
autoComplete = 'off',
|
|
size,
|
|
fullWidth = true,
|
|
required = false,
|
|
sx,
|
|
slotProps,
|
|
...rest
|
|
} = this.props;
|
|
|
|
return (
|
|
<TextField
|
|
inputRef={inputRef}
|
|
fullWidth={fullWidth}
|
|
required={required}
|
|
size={size}
|
|
variant="outlined"
|
|
label={label}
|
|
value={value}
|
|
disabled={disabled}
|
|
onChange={(event) => {
|
|
if (!readOnly) onChange(event.target.value);
|
|
}}
|
|
autoFocus={autoFocus}
|
|
autoComplete={autoComplete}
|
|
slotProps={{
|
|
...slotProps,
|
|
input: {
|
|
readOnly,
|
|
...slotProps?.input,
|
|
},
|
|
htmlInput: {
|
|
spellCheck: false,
|
|
readOnly,
|
|
tabIndex: readOnly ? -1 : undefined,
|
|
...slotProps?.htmlInput,
|
|
},
|
|
}}
|
|
sx={sx}
|
|
{...rest}
|
|
/>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default SingleLineTextEdit;
|