Compare commits

..

3 Commits

Author SHA1 Message Date
seb
266f5212aa u 2026-10-11 03:00:44 +02:00
seb
023a8889cd u 2026-10-10 22:58:48 +02:00
seb
ed290c127b u 2026-10-10 22:44:10 +02:00
2 changed files with 39 additions and 3 deletions

View File

@@ -211,6 +211,7 @@ class FillSpace extends Component {
_handleWheel = (event) => { _handleWheel = (event) => {
const { items } = this.props; const { items } = this.props;
if (!Array.isArray(items)) return; if (!Array.isArray(items)) return;
if (this.ref && event.target && !this.ref.contains(event.target)) return;
const { pageSize, currentPage } = this.state; const { pageSize, currentPage } = this.state;
const pageCount = Math.max(1, Math.ceil(items.length / Math.max(1, pageSize))); const pageCount = Math.max(1, Math.ceil(items.length / Math.max(1, pageSize)));
const delta = event.deltaY || 0; const delta = event.deltaY || 0;

View File

@@ -1,5 +1,9 @@
import { Component } from 'react'; import { Component } from 'react';
import TextField from '@mui/material/TextField'; import TextField from '@mui/material/TextField';
import InputAdornment from '@mui/material/InputAdornment';
import IconButton from '@mui/material/IconButton';
import SearchIcon from '@mui/icons-material/Search';
import ClearIcon from '@mui/icons-material/Clear';
/** /**
* Centralized single-line text field with the same outlined look everywhere. * Centralized single-line text field with the same outlined look everywhere.
@@ -13,7 +17,7 @@ import TextField from '@mui/material/TextField';
* @prop {string} value - Controlled field value. * @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 {(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 {React.Ref} [inputRef] - Ref forwarded to the inner input (used by EditablePanelTile to focus on edit).
* @prop {ReactNode} [label=Name] - Outlined field label. * @prop {ReactNode} [label] - 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} [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} [disabled=false] - Passed to TextField — disables the field.
* @prop {boolean} [required=false] - Passed to TextField — marks the field required. * @prop {boolean} [required=false] - Passed to TextField — marks the field required.
@@ -21,6 +25,8 @@ import TextField from '@mui/material/TextField';
* @prop {boolean} [autoFocus=false] - TextField autoFocus prop. * @prop {boolean} [autoFocus=false] - TextField autoFocus prop.
* @prop {string} [autoComplete=off] - TextField autoComplete prop. * @prop {string} [autoComplete=off] - TextField autoComplete prop.
* @prop {'small' | 'medium'} [size] - TextField size prop. * @prop {'small' | 'medium'} [size] - TextField size prop.
* @prop {boolean} [search=false] - When true, displays a search icon start adornment.
* @prop {boolean} [clear=false] - When true and value is non-empty, displays a clear button end adornment.
* @prop {object} [slotProps] - MUI slotProps, merged (input/htmlInput are augmented for readOnly/spellCheck/tabIndex). * @prop {object} [slotProps] - MUI slotProps, merged (input/htmlInput are augmented for readOnly/spellCheck/tabIndex).
* @prop {object} [sx] - Extra styles passed to TextField. * @prop {object} [sx] - Extra styles passed to TextField.
* @prop {any} [otherProps] - Any remaining TextField props (helperText, etc.) are spread onto TextField. * @prop {any} [otherProps] - Any remaining TextField props (helperText, etc.) are spread onto TextField.
@@ -35,7 +41,7 @@ class SingleLineTextEdit extends Component {
value, value,
onChange, onChange,
inputRef, inputRef,
label = 'Name', label,
disabled = false, disabled = false,
readOnly = false, readOnly = false,
autoFocus = false, autoFocus = false,
@@ -43,11 +49,38 @@ class SingleLineTextEdit extends Component {
size, size,
fullWidth = true, fullWidth = true,
required = false, required = false,
search = false,
clear = false,
sx, sx,
slotProps, slotProps,
...rest ...rest
} = this.props; } = this.props;
let startAdornment = slotProps?.input?.startAdornment;
if (search && startAdornment === undefined) {
startAdornment = (
<InputAdornment position="start">
<SearchIcon color="action" />
</InputAdornment>
);
}
let endAdornment = slotProps?.input?.endAdornment;
if (clear && endAdornment === undefined) {
endAdornment = (value && !readOnly && !disabled) ? (
<InputAdornment position="end">
<IconButton
size="small"
onClick={() => onChange?.('')}
onMouseDown={(e) => e.preventDefault()}
aria-label="Eingabe Löschen"
>
<ClearIcon fontSize="small" />
</IconButton>
</InputAdornment>
) : null;
}
return ( return (
<TextField <TextField
inputRef={inputRef} inputRef={inputRef}
@@ -59,7 +92,7 @@ class SingleLineTextEdit extends Component {
value={value} value={value}
disabled={disabled} disabled={disabled}
onChange={(event) => { onChange={(event) => {
if (!readOnly) onChange(event.target.value); if (!readOnly) onChange?.(event.target.value);
}} }}
autoFocus={autoFocus} autoFocus={autoFocus}
autoComplete={autoComplete} autoComplete={autoComplete}
@@ -67,6 +100,8 @@ class SingleLineTextEdit extends Component {
...slotProps, ...slotProps,
input: { input: {
readOnly, readOnly,
...(startAdornment !== undefined ? { startAdornment } : {}),
...(endAdornment !== undefined ? { endAdornment } : {}),
...slotProps?.input, ...slotProps?.input,
}, },
htmlInput: { htmlInput: {