@rjsf/mui 6.4.1 → 6.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/README.md +25 -0
  2. package/dist/index.cjs +353 -214
  3. package/dist/index.cjs.map +4 -4
  4. package/dist/mui.esm.js +354 -185
  5. package/dist/mui.esm.js.map +4 -4
  6. package/dist/mui.umd.js +293 -165
  7. package/lib/AddButton/AddButton.js +12 -2
  8. package/lib/AddButton/AddButton.js.map +1 -1
  9. package/lib/ArrayFieldItemTemplate/ArrayFieldItemTemplate.d.ts +22 -1
  10. package/lib/ArrayFieldItemTemplate/ArrayFieldItemTemplate.js +3 -1
  11. package/lib/ArrayFieldItemTemplate/ArrayFieldItemTemplate.js.map +1 -1
  12. package/lib/ArrayFieldTemplate/ArrayFieldTemplate.d.ts +20 -1
  13. package/lib/ArrayFieldTemplate/ArrayFieldTemplate.js +3 -1
  14. package/lib/ArrayFieldTemplate/ArrayFieldTemplate.js.map +1 -1
  15. package/lib/BaseInputTemplate/BaseInputTemplate.d.ts +17 -1
  16. package/lib/BaseInputTemplate/BaseInputTemplate.js +9 -4
  17. package/lib/BaseInputTemplate/BaseInputTemplate.js.map +1 -1
  18. package/lib/CheckboxWidget/CheckboxWidget.d.ts +13 -1
  19. package/lib/CheckboxWidget/CheckboxWidget.js +3 -1
  20. package/lib/CheckboxWidget/CheckboxWidget.js.map +1 -1
  21. package/lib/CheckboxesWidget/CheckboxesWidget.d.ts +17 -2
  22. package/lib/CheckboxesWidget/CheckboxesWidget.js +12 -7
  23. package/lib/CheckboxesWidget/CheckboxesWidget.js.map +1 -1
  24. package/lib/DescriptionField/DescriptionField.d.ts +10 -1
  25. package/lib/DescriptionField/DescriptionField.js +6 -1
  26. package/lib/DescriptionField/DescriptionField.js.map +1 -1
  27. package/lib/ErrorList/ErrorList.d.ts +29 -2
  28. package/lib/ErrorList/ErrorList.js +7 -4
  29. package/lib/ErrorList/ErrorList.js.map +1 -1
  30. package/lib/FieldErrorTemplate/FieldErrorTemplate.d.ts +16 -1
  31. package/lib/FieldErrorTemplate/FieldErrorTemplate.js +8 -4
  32. package/lib/FieldErrorTemplate/FieldErrorTemplate.js.map +1 -1
  33. package/lib/FieldHelpTemplate/FieldHelpTemplate.d.ts +10 -1
  34. package/lib/FieldHelpTemplate/FieldHelpTemplate.js +6 -2
  35. package/lib/FieldHelpTemplate/FieldHelpTemplate.js.map +1 -1
  36. package/lib/FieldTemplate/FieldTemplate.d.ts +13 -1
  37. package/lib/FieldTemplate/FieldTemplate.js +3 -1
  38. package/lib/FieldTemplate/FieldTemplate.js.map +1 -1
  39. package/lib/IconButton/IconButton.js +12 -2
  40. package/lib/IconButton/IconButton.js.map +1 -1
  41. package/lib/MultiSchemaFieldTemplate/MultiSchemaFieldTemplate.d.ts +13 -1
  42. package/lib/MultiSchemaFieldTemplate/MultiSchemaFieldTemplate.js +6 -2
  43. package/lib/MultiSchemaFieldTemplate/MultiSchemaFieldTemplate.js.map +1 -1
  44. package/lib/ObjectFieldTemplate/ObjectFieldTemplate.d.ts +16 -1
  45. package/lib/ObjectFieldTemplate/ObjectFieldTemplate.js +4 -2
  46. package/lib/ObjectFieldTemplate/ObjectFieldTemplate.js.map +1 -1
  47. package/lib/OptionalDataControlsTemplate/OptionalDataControlsTemplate.js +3 -3
  48. package/lib/OptionalDataControlsTemplate/OptionalDataControlsTemplate.js.map +1 -1
  49. package/lib/RadioWidget/RadioWidget.d.ts +17 -2
  50. package/lib/RadioWidget/RadioWidget.js +13 -9
  51. package/lib/RadioWidget/RadioWidget.js.map +1 -1
  52. package/lib/RangeWidget/RangeWidget.d.ts +10 -1
  53. package/lib/RangeWidget/RangeWidget.js +3 -1
  54. package/lib/RangeWidget/RangeWidget.js.map +1 -1
  55. package/lib/SelectWidget/SelectWidget.d.ts +14 -3
  56. package/lib/SelectWidget/SelectWidget.js +26 -19
  57. package/lib/SelectWidget/SelectWidget.js.map +1 -1
  58. package/lib/SubmitButton/SubmitButton.d.ts +13 -1
  59. package/lib/SubmitButton/SubmitButton.js +5 -2
  60. package/lib/SubmitButton/SubmitButton.js.map +1 -1
  61. package/lib/TitleField/TitleField.d.ts +24 -2
  62. package/lib/TitleField/TitleField.js +9 -4
  63. package/lib/TitleField/TitleField.js.map +1 -1
  64. package/lib/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.d.ts +16 -1
  65. package/lib/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.js +7 -2
  66. package/lib/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.js.map +1 -1
  67. package/lib/tsconfig.tsbuildinfo +1 -1
  68. package/lib/util.d.ts +9 -0
  69. package/lib/util.js +24 -0
  70. package/lib/util.js.map +1 -0
  71. package/package.json +7 -7
  72. package/src/AddButton/AddButton.tsx +21 -3
  73. package/src/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx +39 -9
  74. package/src/ArrayFieldTemplate/ArrayFieldTemplate.tsx +30 -8
  75. package/src/BaseInputTemplate/BaseInputTemplate.tsx +29 -5
  76. package/src/CheckboxWidget/CheckboxWidget.tsx +20 -2
  77. package/src/CheckboxesWidget/CheckboxesWidget.tsx +51 -23
  78. package/src/DescriptionField/DescriptionField.tsx +25 -3
  79. package/src/ErrorList/ErrorList.tsx +52 -15
  80. package/src/FieldErrorTemplate/FieldErrorTemplate.tsx +34 -8
  81. package/src/FieldHelpTemplate/FieldHelpTemplate.tsx +30 -3
  82. package/src/FieldTemplate/FieldTemplate.tsx +26 -4
  83. package/src/IconButton/IconButton.tsx +21 -2
  84. package/src/MultiSchemaFieldTemplate/MultiSchemaFieldTemplate.tsx +28 -6
  85. package/src/ObjectFieldTemplate/ObjectFieldTemplate.tsx +25 -5
  86. package/src/OptionalDataControlsTemplate/OptionalDataControlsTemplate.tsx +3 -1
  87. package/src/RadioWidget/RadioWidget.tsx +43 -26
  88. package/src/RangeWidget/RangeWidget.tsx +16 -1
  89. package/src/SelectWidget/SelectWidget.tsx +71 -49
  90. package/src/SubmitButton/SubmitButton.tsx +36 -5
  91. package/src/TitleField/TitleField.tsx +54 -16
  92. package/src/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.tsx +39 -5
  93. package/src/util.ts +30 -0
package/lib/util.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ import { FormContextType, RJSFSchema, StrictRJSFSchema, UIOptionsType, GenericObjectType } from '@rjsf/utils';
2
+ /**
3
+ * Extract props meant for MUI components from the `options` field of the `uiSchema`.
4
+ * @param {UIOptionsType} options - The options from the uiSchema
5
+ * @param {string[]} [propsToFilter] - An optional allowlist of props to return (used by button/icon components)
6
+ * @param {boolean} [rjsfSlotPropsOnly] - If true, returns only `rjsfSlotProps`, preventing root-level prop bleeding
7
+ * @returns {P}
8
+ */
9
+ export declare function getMuiProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any, P extends GenericObjectType = GenericObjectType>(options: UIOptionsType<T, S, F>, propsToFilter?: string[], rjsfSlotPropsOnly?: boolean): P;
package/lib/util.js ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Extract props meant for MUI components from the `options` field of the `uiSchema`.
3
+ * @param {UIOptionsType} options - The options from the uiSchema
4
+ * @param {string[]} [propsToFilter] - An optional allowlist of props to return (used by button/icon components)
5
+ * @param {boolean} [rjsfSlotPropsOnly] - If true, returns only `rjsfSlotProps`, preventing root-level prop bleeding
6
+ * @returns {P}
7
+ */
8
+ export function getMuiProps(options, propsToFilter, rjsfSlotPropsOnly) {
9
+ const muiProps = (options === null || options === void 0 ? void 0 : options.mui) || {};
10
+ if (rjsfSlotPropsOnly) {
11
+ const { rjsfSlotProps } = muiProps;
12
+ return { rjsfSlotProps };
13
+ }
14
+ if (propsToFilter) {
15
+ return Object.keys(muiProps)
16
+ .filter((key) => propsToFilter.includes(key))
17
+ .reduce((obj, key) => {
18
+ obj[key] = muiProps[key];
19
+ return obj;
20
+ }, {});
21
+ }
22
+ return muiProps;
23
+ }
24
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAKzB,OAA+B,EAAE,aAAwB,EAAE,iBAA2B;IACtF,MAAM,QAAQ,GAAG,CAAC,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,GAAS,KAAK,EAAQ,CAAC;IAClD,IAAI,iBAAiB,EAAE,CAAC;QACtB,MAAM,EAAE,aAAa,EAAE,GAAG,QAAe,CAAC;QAC1C,OAAO,EAAE,aAAa,EAAkB,CAAC;IAC3C,CAAC;IACD,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;aACzB,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;aAC5C,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YACnB,GAAG,CAAC,GAAc,CAAC,GAAG,QAAQ,CAAC,GAAc,CAAC,CAAC;YAC/C,OAAO,GAAG,CAAC;QACb,CAAC,EAAE,EAAO,CAAC,CAAC;IAChB,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rjsf/mui",
3
- "version": "6.4.1",
3
+ "version": "6.5.0",
4
4
  "main": "./dist/index.cjs",
5
5
  "module": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",
@@ -72,12 +72,12 @@
72
72
  "@emotion/jest": "^11.14.2",
73
73
  "@emotion/react": "^11.14.0",
74
74
  "@emotion/styled": "^11.14.1",
75
- "@mui/icons-material": "^7.3.7",
76
- "@mui/material": "^7.3.7",
77
- "@rjsf/core": "6.4.1",
78
- "@rjsf/snapshot-tests": "6.4.1",
79
- "@rjsf/utils": "6.4.1",
80
- "@rjsf/validator-ajv8": "6.4.1",
75
+ "@mui/icons-material": "^7.3.9",
76
+ "@mui/material": "^7.3.9",
77
+ "@rjsf/core": "6.5.0",
78
+ "@rjsf/snapshot-tests": "6.5.0",
79
+ "@rjsf/utils": "6.5.0",
80
+ "@rjsf/validator-ajv8": "6.5.0",
81
81
  "eslint": "^8.57.1"
82
82
  },
83
83
  "publishConfig": {
@@ -1,6 +1,14 @@
1
1
  import AddIcon from '@mui/icons-material/Add';
2
- import IconButton from '@mui/material/IconButton';
3
- import { FormContextType, IconButtonProps, RJSFSchema, StrictRJSFSchema, TranslatableString } from '@rjsf/utils';
2
+ import IconButton, { IconButtonProps as MuiIconButtonProps } from '@mui/material/IconButton';
3
+ import {
4
+ FormContextType,
5
+ getUiOptions,
6
+ IconButtonProps,
7
+ RJSFSchema,
8
+ StrictRJSFSchema,
9
+ TranslatableString,
10
+ } from '@rjsf/utils';
11
+ import { getMuiProps } from '../util';
4
12
 
5
13
  /** The `AddButton` renders a button that represent the `Add` action on a form
6
14
  */
@@ -10,8 +18,18 @@ export default function AddButton<T = any, S extends StrictRJSFSchema = RJSFSche
10
18
  ...props
11
19
  }: IconButtonProps<T, S, F>) {
12
20
  const { translateString } = registry;
21
+ const uiOptions = getUiOptions<T, S, F>(uiSchema);
22
+ const muiProps = getMuiProps<T, S, F, MuiIconButtonProps>(uiOptions, [
23
+ 'color',
24
+ 'disableFocusRipple',
25
+ 'disableRipple',
26
+ 'edge',
27
+ 'size',
28
+ 'sx',
29
+ ]);
30
+
13
31
  return (
14
- <IconButton title={translateString(TranslatableString.AddItemButton)} {...props} color='primary'>
32
+ <IconButton title={translateString(TranslatableString.AddItemButton)} {...props} color='primary' {...muiProps}>
15
33
  <AddIcon />
16
34
  </IconButton>
17
35
  );
@@ -1,7 +1,7 @@
1
1
  import { CSSProperties } from 'react';
2
- import Box from '@mui/material/Box';
3
- import Grid from '@mui/material/Grid';
4
- import Paper from '@mui/material/Paper';
2
+ import Box, { BoxProps } from '@mui/material/Box';
3
+ import Grid, { GridProps } from '@mui/material/Grid';
4
+ import Paper, { PaperProps } from '@mui/material/Paper';
5
5
  import {
6
6
  ArrayFieldItemTemplateProps,
7
7
  FormContextType,
@@ -9,7 +9,28 @@ import {
9
9
  getTemplate,
10
10
  RJSFSchema,
11
11
  StrictRJSFSchema,
12
+ GenericObjectType,
12
13
  } from '@rjsf/utils';
14
+ import { getMuiProps } from '../util';
15
+
16
+ /** Properties available for the `rjsfSlotProps` target of the ArrayFieldItemTemplate. */
17
+ export interface ArrayFieldItemTemplateMuiProps extends GenericObjectType {
18
+ /** RJSF-specific slot props for targeting child elements of the ArrayFieldItemTemplate. */
19
+ rjsfSlotProps?: {
20
+ /** Props applied to the outermost `Grid` container. */
21
+ arrayItemGridContainer?: GridProps;
22
+ /** Props applied to the `Grid` item wrapping the item's content. */
23
+ arrayItemGridItem?: GridProps;
24
+ /** Props applied to the outer `Box` container. */
25
+ arrayItemOuterBox?: BoxProps;
26
+ /** Props applied to the `Paper` elevation component. */
27
+ arrayItemPaper?: PaperProps;
28
+ /** Props applied to the inner `Box` containing the actual children. */
29
+ arrayItemInnerBox?: BoxProps;
30
+ /** Props applied to the `Grid` containing the item's buttons. */
31
+ arrayItemToolbarGrid?: GridProps;
32
+ };
33
+ }
13
34
 
14
35
  /** The `ArrayFieldItemTemplate` component is the template used to render an items of an array.
15
36
  *
@@ -34,17 +55,26 @@ export default function ArrayFieldItemTemplate<
34
55
  fontWeight: 'bold',
35
56
  minWidth: 0,
36
57
  };
58
+
59
+ const { rjsfSlotProps: muiSlotProps } = getMuiProps<T, S, F, ArrayFieldItemTemplateMuiProps>(uiOptions);
60
+
37
61
  return (
38
- <Grid container={true} alignItems='center'>
39
- <Grid size={{ xs: 8, sm: 9, md: 10, lg: 11, xl: 11.25 }} style={{ overflow: 'auto' }}>
40
- <Box mb={2}>
41
- <Paper elevation={2}>
42
- <Box p={2}>{children}</Box>
62
+ <Grid container={true} alignItems='center' {...muiSlotProps?.arrayItemGridContainer}>
63
+ <Grid
64
+ size={{ xs: 8, sm: 9, md: 10, lg: 11, xl: 11.25 }}
65
+ style={{ overflow: 'auto' }}
66
+ {...muiSlotProps?.arrayItemGridItem}
67
+ >
68
+ <Box mb={2} {...muiSlotProps?.arrayItemOuterBox}>
69
+ <Paper elevation={2} {...muiSlotProps?.arrayItemPaper}>
70
+ <Box p={2} {...muiSlotProps?.arrayItemInnerBox}>
71
+ {children}
72
+ </Box>
43
73
  </Paper>
44
74
  </Box>
45
75
  </Grid>
46
76
  {hasToolbar && (
47
- <Grid sx={{ mt: hasDescription ? -5 : -1.5 }}>
77
+ <Grid sx={{ mt: hasDescription ? -5 : -1.5 }} {...muiSlotProps?.arrayItemToolbarGrid}>
48
78
  <ArrayFieldItemButtonsTemplate {...buttonsProps} style={btnStyle} />
49
79
  </Grid>
50
80
  )}
@@ -1,6 +1,6 @@
1
- import Box from '@mui/material/Box';
2
- import Grid from '@mui/material/Grid';
3
- import Paper from '@mui/material/Paper';
1
+ import Box, { BoxProps } from '@mui/material/Box';
2
+ import Grid, { GridProps } from '@mui/material/Grid';
3
+ import Paper, { PaperProps } from '@mui/material/Paper';
4
4
  import {
5
5
  getTemplate,
6
6
  getUiOptions,
@@ -9,7 +9,26 @@ import {
9
9
  RJSFSchema,
10
10
  StrictRJSFSchema,
11
11
  buttonId,
12
+ GenericObjectType,
12
13
  } from '@rjsf/utils';
14
+ import { getMuiProps } from '../util';
15
+
16
+ /** Properties available for the `rjsfSlotProps` target of the ArrayFieldTemplate. */
17
+ export interface ArrayFieldTemplateMuiProps extends GenericObjectType {
18
+ /** RJSF-specific slot props for targeting child elements of the ArrayFieldTemplate. */
19
+ rjsfSlotProps?: {
20
+ /** Props applied to the wrapper `Paper` material. */
21
+ arrayPaper?: PaperProps;
22
+ /** Props applied to the primary `Box` container. */
23
+ arrayBox?: BoxProps;
24
+ /** Props applied to the wrapper `Grid` container next to the Add Button. */
25
+ arrayAddButtonGridContainer?: GridProps;
26
+ /** Props applied to the `Grid` item containing the Add Button. */
27
+ arrayAddButtonGridItem?: GridProps;
28
+ /** Props applied to the `Box` containing the Add Button. */
29
+ arrayAddButtonBox?: BoxProps;
30
+ };
31
+ }
13
32
 
14
33
  /** The `ArrayFieldTemplate` component is the template used to render all items in an array.
15
34
  *
@@ -50,9 +69,12 @@ export default function ArrayFieldTemplate<
50
69
  const {
51
70
  ButtonTemplates: { AddButton },
52
71
  } = registry.templates;
72
+
73
+ const { rjsfSlotProps: muiSlotProps } = getMuiProps<T, S, F, ArrayFieldTemplateMuiProps>(uiOptions);
74
+
53
75
  return (
54
- <Paper elevation={2}>
55
- <Box p={2}>
76
+ <Paper elevation={2} {...muiSlotProps?.arrayPaper}>
77
+ <Box p={2} {...muiSlotProps?.arrayBox}>
56
78
  <ArrayFieldTitleTemplate
57
79
  fieldPathId={fieldPathId}
58
80
  title={uiOptions.title || title}
@@ -72,9 +94,9 @@ export default function ArrayFieldTemplate<
72
94
  {!showOptionalDataControlInTitle ? optionalDataControl : undefined}
73
95
  {items}
74
96
  {canAdd && (
75
- <Grid container justifyContent='flex-end'>
76
- <Grid>
77
- <Box mt={2}>
97
+ <Grid container justifyContent='flex-end' {...muiSlotProps?.arrayAddButtonGridContainer}>
98
+ <Grid {...muiSlotProps?.arrayAddButtonGridItem}>
99
+ <Box mt={2} {...muiSlotProps?.arrayAddButtonBox}>
78
100
  <AddButton
79
101
  id={buttonId(fieldPathId, 'add')}
80
102
  className='rjsf-array-item-add'
@@ -1,7 +1,8 @@
1
1
  import { ChangeEvent, FocusEvent, MouseEvent, useCallback } from 'react';
2
2
  import TextField, { TextFieldProps } from '@mui/material/TextField';
3
3
  import InputAdornment from '@mui/material/InputAdornment';
4
-
4
+ import { InputProps as MuiInputProps } from '@mui/material/Input';
5
+ import { InputLabelProps as MuiInputLabelProps } from '@mui/material/InputLabel';
5
6
  import {
6
7
  ariaDescribedByIds,
7
8
  BaseInputTemplateProps,
@@ -9,10 +10,27 @@ import {
9
10
  getInputProps,
10
11
  labelValue,
11
12
  FormContextType,
13
+ GenericObjectType,
12
14
  RJSFSchema,
13
15
  StrictRJSFSchema,
14
16
  } from '@rjsf/utils';
15
17
  import { SchemaExamples } from '@rjsf/core';
18
+ import { getMuiProps } from '../util';
19
+
20
+ /** Properties available for the MUI `ui:options` of the BaseInputTemplate.
21
+ * Unlike RJSF templates, `slotProps` here maps directly to MUI's native `TextField` `slotProps`,
22
+ * enabling type-safe customization of the underlying MUI sub-components. */
23
+ export interface BaseInputTemplateMuiProps extends GenericObjectType {
24
+ /** Native MUI `TextField` slotProps for targeting specific sub-components. */
25
+ slotProps?: {
26
+ /** Props applied to the base native HTML `<input>` or `<textarea>` element. */
27
+ htmlInput?: React.HTMLAttributes<HTMLInputElement | HTMLTextAreaElement>;
28
+ /** Props applied to the MUI `Input` element, useful for `endAdornment`/`startAdornment`. */
29
+ input?: MuiInputProps;
30
+ /** Props applied to the MUI `InputLabel` element. */
31
+ inputLabel?: MuiInputLabelProps;
32
+ };
33
+ }
16
34
 
17
35
  const TYPES_THAT_SHRINK_LABEL = ['date', 'datetime-local', 'file', 'time'];
18
36
 
@@ -59,8 +77,13 @@ export default function BaseInputTemplate<
59
77
  const { ClearButton } = registry.templates.ButtonTemplates;
60
78
  // Now we need to pull out the step, min, max into an inner `inputProps` for material-ui
61
79
  const { step, min, max, accept, ...rest } = getInputProps<T, S, F>(schema, type, options);
80
+
81
+ const muiProps = getMuiProps<T, S, F, BaseInputTemplateMuiProps>(options);
82
+ const { slotProps: muiSlotProps, ...otherMuiProps } = muiProps;
83
+
62
84
  const htmlInputProps = {
63
85
  ...slotProps?.htmlInput,
86
+ ...muiSlotProps?.htmlInput,
64
87
  step,
65
88
  min,
66
89
  max,
@@ -72,8 +95,8 @@ export default function BaseInputTemplate<
72
95
  const _onBlur = ({ target }: FocusEvent<HTMLInputElement>) => onBlur(id, target && target.value);
73
96
  const _onFocus = ({ target }: FocusEvent<HTMLInputElement>) => onFocus(id, target && target.value);
74
97
  const DisplayInputLabelProps = TYPES_THAT_SHRINK_LABEL.includes(type)
75
- ? { ...slotProps?.inputLabel, ...InputLabelProps, shrink: true }
76
- : { ...slotProps?.inputLabel, ...InputLabelProps };
98
+ ? { ...slotProps?.inputLabel, ...muiSlotProps?.inputLabel, ...InputLabelProps, shrink: true }
99
+ : { ...slotProps?.inputLabel, ...muiSlotProps?.inputLabel, ...InputLabelProps };
77
100
  const _onClear = useCallback(
78
101
  (e: MouseEvent) => {
79
102
  e.preventDefault();
@@ -82,7 +105,7 @@ export default function BaseInputTemplate<
82
105
  },
83
106
  [onChange, options.emptyValue],
84
107
  );
85
- const inputProps = { ...InputProps, ...slotProps?.input };
108
+ const inputProps = { ...InputProps, ...slotProps?.input, ...muiSlotProps?.input };
86
109
  if (options.allowClearTextInputs && value && !readonly && !disabled) {
87
110
  const clearAdornment = (
88
111
  <InputAdornment position='end'>
@@ -111,6 +134,7 @@ export default function BaseInputTemplate<
111
134
  disabled={disabled || readonly}
112
135
  slotProps={{
113
136
  ...slotProps,
137
+ ...muiSlotProps,
114
138
  input: inputProps,
115
139
  htmlInput: htmlInputProps,
116
140
  inputLabel: DisplayInputLabelProps,
@@ -121,7 +145,7 @@ export default function BaseInputTemplate<
121
145
  onChange={onChangeOverride || _onChange}
122
146
  onBlur={_onBlur}
123
147
  onFocus={_onFocus}
124
- {...(textFieldProps as TextFieldProps)}
148
+ {...({ ...otherMuiProps, ...textFieldProps } as TextFieldProps)}
125
149
  aria-describedby={ariaDescribedByIds(id, !!schema.examples)}
126
150
  />
127
151
  <SchemaExamples id={id} schema={schema} />
@@ -1,5 +1,5 @@
1
- import Checkbox from '@mui/material/Checkbox';
2
- import FormControlLabel from '@mui/material/FormControlLabel';
1
+ import Checkbox, { CheckboxProps } from '@mui/material/Checkbox';
2
+ import FormControlLabel, { FormControlLabelProps } from '@mui/material/FormControlLabel';
3
3
  import {
4
4
  ariaDescribedByIds,
5
5
  descriptionId,
@@ -7,10 +7,23 @@ import {
7
7
  labelValue,
8
8
  schemaRequiresTrueValue,
9
9
  FormContextType,
10
+ GenericObjectType,
10
11
  RJSFSchema,
11
12
  StrictRJSFSchema,
12
13
  WidgetProps,
13
14
  } from '@rjsf/utils';
15
+ import { getMuiProps } from '../util';
16
+
17
+ /** Properties available for the `rjsfSlotProps` target of the CheckboxWidget. */
18
+ export interface CheckboxWidgetMuiProps extends GenericObjectType {
19
+ /** RJSF-specific slot props for targeting child elements of the CheckboxWidget. */
20
+ rjsfSlotProps?: {
21
+ /** Props applied to the individual `Checkbox` component. */
22
+ checkbox?: CheckboxProps;
23
+ /** Props applied to the `FormControlLabel` component wrapping the checkbox. */
24
+ formControlLabel?: FormControlLabelProps;
25
+ };
26
+ }
14
27
 
15
28
  /** The `CheckBoxWidget` is a widget for rendering boolean properties.
16
29
  * It is typically used to represent a boolean.
@@ -54,6 +67,8 @@ export default function CheckboxWidget<
54
67
  const _onFocus: React.FocusEventHandler<HTMLButtonElement> = () => onFocus(id, value);
55
68
  const description = options.description ?? schema.description;
56
69
 
70
+ const { rjsfSlotProps: muiSlotProps, ...otherMuiProps } = getMuiProps<T, S, F, CheckboxWidgetMuiProps>(options);
71
+
57
72
  return (
58
73
  <>
59
74
  {!hideLabel && description && (
@@ -66,6 +81,8 @@ export default function CheckboxWidget<
66
81
  />
67
82
  )}
68
83
  <FormControlLabel
84
+ {...otherMuiProps}
85
+ {...muiSlotProps?.formControlLabel}
69
86
  control={
70
87
  <Checkbox
71
88
  id={id}
@@ -78,6 +95,7 @@ export default function CheckboxWidget<
78
95
  onBlur={_onBlur}
79
96
  onFocus={_onFocus}
80
97
  aria-describedby={ariaDescribedByIds(id)}
98
+ {...muiSlotProps?.checkbox}
81
99
  />
82
100
  }
83
101
  label={labelValue(label, hideLabel, false)}
@@ -1,21 +1,37 @@
1
1
  import { ChangeEvent, FocusEvent } from 'react';
2
- import Checkbox from '@mui/material/Checkbox';
3
- import FormControlLabel from '@mui/material/FormControlLabel';
4
- import FormGroup from '@mui/material/FormGroup';
2
+ import Checkbox, { CheckboxProps } from '@mui/material/Checkbox';
3
+ import FormControlLabel, { FormControlLabelProps } from '@mui/material/FormControlLabel';
4
+ import FormGroup, { FormGroupProps } from '@mui/material/FormGroup';
5
5
  import FormLabel from '@mui/material/FormLabel';
6
6
  import {
7
7
  ariaDescribedByIds,
8
+ enumOptionValueDecoder,
8
9
  enumOptionsDeselectValue,
9
10
  enumOptionsIsSelected,
10
11
  enumOptionsSelectValue,
11
- enumOptionsValueForIndex,
12
+ getOptionValueFormat,
12
13
  labelValue,
13
14
  optionId,
14
15
  FormContextType,
16
+ GenericObjectType,
15
17
  WidgetProps,
16
18
  RJSFSchema,
17
19
  StrictRJSFSchema,
18
20
  } from '@rjsf/utils';
21
+ import { getMuiProps } from '../util';
22
+
23
+ /** Properties available for the `rjsfSlotProps` target of the CheckboxesWidget. */
24
+ export interface CheckboxesWidgetMuiProps extends GenericObjectType {
25
+ /** RJSF-specific slot props for targeting child elements of the CheckboxesWidget. */
26
+ rjsfSlotProps?: {
27
+ /** Props applied to the `FormGroup` container. */
28
+ formGroup?: FormGroupProps;
29
+ /** Props applied to the individual `Checkbox` components. */
30
+ checkbox?: CheckboxProps;
31
+ /** Props applied to the `FormControlLabel` components wrapping each checkbox. */
32
+ formControlLabel?: FormControlLabelProps;
33
+ };
34
+ }
19
35
 
20
36
  /** The `CheckboxesWidget` is a widget for rendering checkbox groups.
21
37
  * It is typically used to represent an array of enums.
@@ -26,22 +42,24 @@ export default function CheckboxesWidget<
26
42
  T = any,
27
43
  S extends StrictRJSFSchema = RJSFSchema,
28
44
  F extends FormContextType = any,
29
- >({
30
- label,
31
- hideLabel,
32
- id,
33
- htmlName,
34
- disabled,
35
- options,
36
- value,
37
- autofocus,
38
- readonly,
39
- required,
40
- onChange,
41
- onBlur,
42
- onFocus,
43
- }: WidgetProps<T, S, F>) {
45
+ >(props: WidgetProps<T, S, F>) {
46
+ const {
47
+ label,
48
+ hideLabel,
49
+ id,
50
+ htmlName,
51
+ disabled,
52
+ options,
53
+ value,
54
+ autofocus,
55
+ readonly,
56
+ required,
57
+ onChange,
58
+ onBlur,
59
+ onFocus,
60
+ } = props;
44
61
  const { enumOptions, enumDisabled, inline, emptyValue } = options;
62
+ const optionValueFormat = getOptionValueFormat(options);
45
63
  const checkboxesValues = Array.isArray(value) ? value : [value];
46
64
 
47
65
  const _onChange =
@@ -55,9 +73,11 @@ export default function CheckboxesWidget<
55
73
  };
56
74
 
57
75
  const _onBlur = ({ target }: FocusEvent<HTMLButtonElement>) =>
58
- onBlur(id, enumOptionsValueForIndex<S>(target && target.value, enumOptions, emptyValue));
76
+ onBlur(id, enumOptionValueDecoder<S>(target && target.value, enumOptions, optionValueFormat, emptyValue));
59
77
  const _onFocus = ({ target }: FocusEvent<HTMLButtonElement>) =>
60
- onFocus(id, enumOptionsValueForIndex<S>(target && target.value, enumOptions, emptyValue));
78
+ onFocus(id, enumOptionValueDecoder<S>(target && target.value, enumOptions, optionValueFormat, emptyValue));
79
+
80
+ const { rjsfSlotProps: muiSlotProps, ...otherMuiProps } = getMuiProps<T, S, F, CheckboxesWidgetMuiProps>(options);
61
81
 
62
82
  return (
63
83
  <>
@@ -67,13 +87,14 @@ export default function CheckboxesWidget<
67
87
  </FormLabel>,
68
88
  hideLabel,
69
89
  )}
70
- <FormGroup id={id} row={!!inline}>
90
+ <FormGroup {...otherMuiProps} {...muiSlotProps?.formGroup} id={id} row={!!inline}>
71
91
  {Array.isArray(enumOptions) &&
72
92
  enumOptions.map((option, index: number) => {
73
93
  const checked = enumOptionsIsSelected<S>(option.value, checkboxesValues);
74
94
  const itemDisabled = Array.isArray(enumDisabled) && enumDisabled.indexOf(option.value) !== -1;
75
95
  const checkbox = (
76
96
  <Checkbox
97
+ {...muiSlotProps?.checkbox}
77
98
  id={optionId(id, index)}
78
99
  name={htmlName || id}
79
100
  checked={checked}
@@ -85,7 +106,14 @@ export default function CheckboxesWidget<
85
106
  aria-describedby={ariaDescribedByIds(id)}
86
107
  />
87
108
  );
88
- return <FormControlLabel control={checkbox} key={index} label={option.label} />;
109
+ return (
110
+ <FormControlLabel
111
+ {...muiSlotProps?.formControlLabel}
112
+ control={checkbox}
113
+ key={index}
114
+ label={option.label}
115
+ />
116
+ );
89
117
  })}
90
118
  </FormGroup>
91
119
  </>
@@ -1,6 +1,23 @@
1
- import Typography from '@mui/material/Typography';
2
- import { DescriptionFieldProps, FormContextType, RJSFSchema, StrictRJSFSchema } from '@rjsf/utils';
1
+ import Typography, { TypographyProps } from '@mui/material/Typography';
2
+ import {
3
+ DescriptionFieldProps,
4
+ FormContextType,
5
+ GenericObjectType,
6
+ RJSFSchema,
7
+ StrictRJSFSchema,
8
+ getUiOptions,
9
+ } from '@rjsf/utils';
3
10
  import { RichDescription } from '@rjsf/core';
11
+ import { getMuiProps } from '../util';
12
+
13
+ /** Properties available for the `rjsfSlotProps` target of the DescriptionField. */
14
+ export interface DescriptionFieldMuiProps extends GenericObjectType {
15
+ /** RJSF-specific slot props for targeting child elements of the DescriptionField. */
16
+ rjsfSlotProps?: {
17
+ /** Props applied to the `Typography` element used for the description. */
18
+ descTypography?: TypographyProps;
19
+ };
20
+ }
4
21
 
5
22
  /** The `DescriptionField` is the template to use to render the description of a field
6
23
  *
@@ -12,9 +29,14 @@ export default function DescriptionField<
12
29
  F extends FormContextType = any,
13
30
  >(props: DescriptionFieldProps<T, S, F>) {
14
31
  const { id, description, registry, uiSchema } = props;
32
+
33
+ const uiOptions = getUiOptions<T, S, F>(uiSchema);
34
+ const muiProps = getMuiProps<T, S, F, DescriptionFieldMuiProps>(uiOptions);
35
+ const { rjsfSlotProps: muiSlotProps } = muiProps;
36
+
15
37
  if (description) {
16
38
  return (
17
- <Typography id={id} variant='subtitle2' style={{ marginTop: '5px' }}>
39
+ <Typography id={id} variant='subtitle2' style={{ marginTop: '5px' }} {...muiSlotProps?.descTypography}>
18
40
  <RichDescription description={description} registry={registry} uiSchema={uiSchema} />
19
41
  </Typography>
20
42
  );
@@ -1,12 +1,42 @@
1
1
  import ErrorIcon from '@mui/icons-material/Error';
2
- import Box from '@mui/material/Box';
3
- import List from '@mui/material/List';
4
- import ListItem from '@mui/material/ListItem';
5
- import ListItemIcon from '@mui/material/ListItemIcon';
6
- import ListItemText from '@mui/material/ListItemText';
7
- import Paper from '@mui/material/Paper';
8
- import Typography from '@mui/material/Typography';
9
- import { ErrorListProps, FormContextType, RJSFSchema, StrictRJSFSchema, TranslatableString } from '@rjsf/utils';
2
+ import Box, { BoxProps } from '@mui/material/Box';
3
+ import List, { ListProps } from '@mui/material/List';
4
+ import ListItem, { ListItemProps } from '@mui/material/ListItem';
5
+ import ListItemIcon, { ListItemIconProps } from '@mui/material/ListItemIcon';
6
+ import ListItemText, { ListItemTextProps } from '@mui/material/ListItemText';
7
+ import Paper, { PaperProps } from '@mui/material/Paper';
8
+ import Typography, { TypographyProps } from '@mui/material/Typography';
9
+ import {
10
+ ErrorListProps,
11
+ FormContextType,
12
+ GenericObjectType,
13
+ RJSFSchema,
14
+ StrictRJSFSchema,
15
+ TranslatableString,
16
+ getUiOptions,
17
+ } from '@rjsf/utils';
18
+ import { getMuiProps } from '../util';
19
+
20
+ /** Properties available for the `rjsfSlotProps` target of the ErrorList. */
21
+ export interface ErrorListMuiProps extends GenericObjectType {
22
+ /** RJSF-specific slot props for targeting child elements of the ErrorList. */
23
+ rjsfSlotProps?: {
24
+ /** Props applied to the outermost `Paper` component. */
25
+ errorPaper?: PaperProps;
26
+ /** Props applied to the `Box` container. */
27
+ errorBox?: BoxProps;
28
+ /** Props applied to the `Typography` element for the title. */
29
+ errorTypography?: TypographyProps;
30
+ /** Props applied to the `List` container holding the errors. */
31
+ errorList?: ListProps;
32
+ /** Props applied to each `ListItem` representing an error. */
33
+ errorListItem?: ListItemProps;
34
+ /** Props applied to each `ListItemIcon` representing the error icon. */
35
+ errorListItemIcon?: ListItemIconProps;
36
+ /** Props applied to each `ListItemText` representing the error message. */
37
+ errorListItemText?: ListItemTextProps;
38
+ };
39
+ }
10
40
 
11
41
  /** The `ErrorList` component is the template that renders the all the errors associated with the fields in the `Form`
12
42
  *
@@ -15,20 +45,27 @@ import { ErrorListProps, FormContextType, RJSFSchema, StrictRJSFSchema, Translat
15
45
  export default function ErrorList<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>({
16
46
  errors,
17
47
  registry,
48
+ uiSchema,
18
49
  }: ErrorListProps<T, S, F>) {
19
50
  const { translateString } = registry;
51
+
52
+ const uiOptions = getUiOptions<T, S, F>(uiSchema);
53
+ const { rjsfSlotProps: muiSlotProps } = getMuiProps<T, S, F, ErrorListMuiProps>(uiOptions);
54
+
20
55
  return (
21
- <Paper elevation={2}>
22
- <Box mb={2} p={2}>
23
- <Typography variant='h6'>{translateString(TranslatableString.ErrorsLabel)}</Typography>
24
- <List dense={true}>
56
+ <Paper elevation={2} {...muiSlotProps?.errorPaper}>
57
+ <Box mb={2} p={2} {...muiSlotProps?.errorBox}>
58
+ <Typography variant='h6' {...muiSlotProps?.errorTypography}>
59
+ {translateString(TranslatableString.ErrorsLabel)}
60
+ </Typography>
61
+ <List dense={true} {...muiSlotProps?.errorList}>
25
62
  {errors.map((error, i: number) => {
26
63
  return (
27
- <ListItem key={i}>
28
- <ListItemIcon>
64
+ <ListItem key={i} {...muiSlotProps?.errorListItem}>
65
+ <ListItemIcon {...muiSlotProps?.errorListItemIcon}>
29
66
  <ErrorIcon color='error' />
30
67
  </ListItemIcon>
31
- <ListItemText primary={error.stack} />
68
+ <ListItemText primary={error.stack} {...muiSlotProps?.errorListItemText} />
32
69
  </ListItem>
33
70
  );
34
71
  })}