Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions src/components/dialogs/field-hook.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const useTextValue = ({
setHasChanged(true);
}, []);

const { input: slotPropsInput, formHelperText: slotPropsFormHelperText, ...slotProps } = formProps?.slotProps ?? {};
const { slotProps, ...otherFormProps } = formProps;

const field = useMemo(
() => (
Expand All @@ -54,21 +54,19 @@ export const useTextValue = ({
value={value}
style={{ width: '100%' }}
onChange={handleChangeValue}
{...formProps}
{...otherFormProps}
slotProps={{
formHelperText: {
sx: styles.helperText,
},
...slotProps,
input: {
...slotPropsInput,
endAdornment: adornment,
},
Comment on lines 62 to 65

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "Callers with component-level input slot props:"
rg -n -P -U -C 5 \
  'slotProps\s*:\s*\{(?s:.*?)\binput\s*:' \
  --glob '*.ts' --glob '*.tsx' . || true

echo "useTextValue callers and tests:"
rg -n -C 5 '\buseTextValue\s*\(' \
  --glob '*.ts' --glob '*.tsx' . || true

Repository: gridsuite/gridexplore-app

Length of output: 981


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "=== field-hook outline ==="
if command -v ast-grep >/dev/null 2>&1; then
  ast-grep outline src/components/dialogs/field-hook.tsx || true
fi

echo "=== field-hook relevant source ==="
sed -n '1,230p' src/components/dialogs/field-hook.tsx

echo "=== package metadata ==="
for f in package.json pnpm-lock.yaml yarn.lock package-lock.json; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    rg -n -C 2 '"`@mui/material`"|"`@mui/base`"|"`@mui/system`"|mui|vitest|jest|testing-library' "$f" || true
  fi
done

echo "=== declarations, slotProps, tests ==="
rg -n -C 4 \
  'UseTextValueProps|TextFieldProps|slotProps|field-hook' \
  --glob '*.ts' --glob '*.tsx' --glob '*.d.ts' --glob '*test*' --glob '*spec*' . || true

Repository: gridsuite/gridexplore-app

Length of output: 50381


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "=== test files near dialogs ==="
fd -t f -i 'test|spec' src | head -80

echo "=== relevant test configuration ==="
for f in jest.config.* babel.config.* tsconfig.json; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    sed -n '1,180p' "$f"
  fi
done

echo "=== focused slotProps references ==="
rg -n -C 3 \
  'slotProps|renderInput|TextField' \
  src --glob '*.test.ts' --glob '*.test.tsx' --glob '*.spec.ts' --glob '*.spec.tsx' \
  --glob '!**/node_modules/**' | head -240

echo "=== lockfile package entries ==="
python3 - <<'PY'
import json
with open("package-lock.json") as f:
    data = json.load(f)
for name in ("node_modules/@mui/material", "node_modules/@mui/base", "node_modules/@mui/types"):
    entry = data.get("packages", {}).get(name)
    print(name, entry.get("version") if entry else "absent")
PY

Repository: gridsuite/gridexplore-app

Length of output: 2603


🌐 Web query:

MUI Material UI v7 TextField API slotProps input function ownerState type

💡 Result:

In Material UI v7, the TextField component exposes a slotProps prop that allows you to pass custom props to its internal slots [1][2]. Each key in the slotProps object (e.g., input, htmlInput, inputLabel) can accept either a static object or a callback function [3][4]. When using a callback function for a slot, it receives the component's ownerState as its argument and must return the props to be applied to that slot [3][4]. For the TextField component, the ownerState is typed as TextFieldOwnerState, which is equivalent to BaseTextFieldProps [5][6][7]. The callback signature for a slot is generally: (ownerState: TextFieldOwnerState) => SlotProps Where SlotProps corresponds to the props accepted by the component rendered in that specific slot (e.g., Input, InputLabel, or a native HTML input element) [5][6]. For example, to conditionally pass props to the htmlInput slot based on the TextField's state: <TextField slotProps={{ htmlInput: (ownerState) => ({ 'data-error': ownerState.error, //...other props }), }} /> While this callback pattern is supported via the slotProps prop for component configuration [3][4], note that using callback functions to access ownerState within the theme's styleOverrides (for global component styling) has been deprecated in favor of using variants [8]. Top results: [1][3][5][6][2]

Citations:


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT

curl -fsSL https://unpkg.com/@mui/material@7.3.11/TextField/TextField.d.ts \
  -o "$tmpdir/TextField.d.ts"
curl -fsSL https://unpkg.com/@mui/material@7.3.11/TextField/TextField.js \
  -o "$tmpdir/TextField.js"
curl -fsSL https://unpkg.com/@mui/material@7.3.11/Input/Input.d.ts \
  -o "$tmpdir/Input.d.ts"
curl -fsSL https://unpkg.com/@mui/material@7.3.11/InputBase/InputBase.d.ts \
  -o "$tmpdir/InputBase.d.ts"

echo "=== TextField slotProps declarations ==="
rg -n -C 8 'slotProps|TextFieldOwnerState|SlotProps' "$tmpdir/TextField.d.ts"

echo "=== Input and InputBase slot-prop types ==="
rg -n -C 5 'endAdornment|SlotProps|ownerState' \
  "$tmpdir/Input.d.ts" "$tmpdir/InputBase.d.ts"

echo "=== TextField runtime slot resolution ==="
rg -n -C 8 'slotProps|useSlot|input:' "$tmpdir/TextField.js"

echo "=== deterministic merge model ==="
python3 - <<'PY'
def compose(slot_props, adornment, owner_state):
    input_props = slot_props.get("input") if slot_props else None
    existing = input_props(owner_state) if callable(input_props) else input_props
    return {**(existing or {}), "endAdornment": adornment}

owner_state = {"error": True}
cases = [
    ({"input": {"inputRef": "ref", "aria-label": "name"}}, "busy"),
    ({"input": lambda state: {"inputRef": "callback-ref", "data-error": state["error"]}}, "done"),
    ({}, None),
]
for slot_props, adornment in cases:
    print(compose(slot_props, adornment, owner_state))
PY

Repository: gridsuite/gridexplore-app

Length of output: 22606


Preserve caller-provided slotProps.input.

UseTextValueProps inherits TextFieldProps, and MUI v7 supports object and callback values for slotProps.input. The current input object replaces either value and removes caller-provided props. Merge the existing value, invoking it with ownerState when it is a function, before setting endAdornment. Add regression tests for both forms.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/dialogs/field-hook.tsx` around lines 62 - 65, Update the
slotProps construction in the field hook to preserve caller-provided
slotProps.input: resolve callback values with the available ownerState, merge
object values with the generated input props, and then set endAdornment without
overwriting existing properties. Add regression coverage for both object and
callback slotProps.input forms.

formHelperText: {
sx: styles.helperText,
...slotPropsFormHelperText,
},
}}
/>
),
[id, label, value, handleChangeValue, formProps, slotProps, slotPropsInput, adornment, slotPropsFormHelperText]
[id, label, value, handleChangeValue, otherFormProps, slotProps, adornment]
);

useEffect(() => setValue(defaultValue), [defaultValue]);
Expand Down
Loading