@rjsf/mui 6.0.0-beta.9 → 6.0.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 (82) hide show
  1. package/README.md +2 -2
  2. package/dist/{index.js → index.cjs} +165 -91
  3. package/dist/index.cjs.map +7 -0
  4. package/dist/mui.esm.js +164 -90
  5. package/dist/mui.esm.js.map +4 -4
  6. package/dist/mui.umd.js +107 -43
  7. package/lib/AddButton/AddButton.js +1 -1
  8. package/lib/ArrayFieldItemTemplate/ArrayFieldItemTemplate.d.ts +3 -3
  9. package/lib/ArrayFieldItemTemplate/ArrayFieldItemTemplate.js +4 -4
  10. package/lib/ArrayFieldItemTemplate/ArrayFieldItemTemplate.js.map +1 -1
  11. package/lib/ArrayFieldTemplate/ArrayFieldTemplate.d.ts +1 -1
  12. package/lib/ArrayFieldTemplate/ArrayFieldTemplate.js +7 -8
  13. package/lib/ArrayFieldTemplate/ArrayFieldTemplate.js.map +1 -1
  14. package/lib/BaseInputTemplate/BaseInputTemplate.js +3 -3
  15. package/lib/BaseInputTemplate/BaseInputTemplate.js.map +1 -1
  16. package/lib/CheckboxWidget/CheckboxWidget.js +6 -6
  17. package/lib/CheckboxWidget/CheckboxWidget.js.map +1 -1
  18. package/lib/CheckboxesWidget/CheckboxesWidget.d.ts +1 -1
  19. package/lib/CheckboxesWidget/CheckboxesWidget.js +6 -6
  20. package/lib/CheckboxesWidget/CheckboxesWidget.js.map +1 -1
  21. package/lib/DescriptionField/DescriptionField.js +1 -1
  22. package/lib/ErrorList/ErrorList.js +7 -7
  23. package/lib/FieldErrorTemplate/FieldErrorTemplate.js +5 -5
  24. package/lib/FieldErrorTemplate/FieldErrorTemplate.js.map +1 -1
  25. package/lib/FieldHelpTemplate/FieldHelpTemplate.js +3 -3
  26. package/lib/FieldHelpTemplate/FieldHelpTemplate.js.map +1 -1
  27. package/lib/FieldTemplate/FieldTemplate.js +4 -4
  28. package/lib/FieldTemplate/FieldTemplate.js.map +1 -1
  29. package/lib/GridTemplate/GridTemplate.js +1 -1
  30. package/lib/IconButton/IconButton.js +1 -1
  31. package/lib/MultiSchemaFieldTemplate/MultiSchemaFieldTemplate.d.ts +2 -0
  32. package/lib/MultiSchemaFieldTemplate/MultiSchemaFieldTemplate.js +8 -0
  33. package/lib/MultiSchemaFieldTemplate/MultiSchemaFieldTemplate.js.map +1 -0
  34. package/lib/MultiSchemaFieldTemplate/index.d.ts +2 -0
  35. package/lib/MultiSchemaFieldTemplate/index.js +3 -0
  36. package/lib/MultiSchemaFieldTemplate/index.js.map +1 -0
  37. package/lib/ObjectFieldTemplate/ObjectFieldTemplate.js +5 -4
  38. package/lib/ObjectFieldTemplate/ObjectFieldTemplate.js.map +1 -1
  39. package/lib/OptionalDataControlsTemplate/OptionalDataControlsTemplate.d.ts +10 -0
  40. package/lib/OptionalDataControlsTemplate/OptionalDataControlsTemplate.js +22 -0
  41. package/lib/OptionalDataControlsTemplate/OptionalDataControlsTemplate.js.map +1 -0
  42. package/lib/OptionalDataControlsTemplate/index.d.ts +2 -0
  43. package/lib/OptionalDataControlsTemplate/index.js +3 -0
  44. package/lib/OptionalDataControlsTemplate/index.js.map +1 -0
  45. package/lib/RadioWidget/RadioWidget.d.ts +1 -1
  46. package/lib/RadioWidget/RadioWidget.js +7 -7
  47. package/lib/RadioWidget/RadioWidget.js.map +1 -1
  48. package/lib/RangeWidget/RangeWidget.js +2 -2
  49. package/lib/RangeWidget/RangeWidget.js.map +1 -1
  50. package/lib/SelectWidget/SelectWidget.d.ts +1 -1
  51. package/lib/SelectWidget/SelectWidget.js +4 -4
  52. package/lib/SelectWidget/SelectWidget.js.map +1 -1
  53. package/lib/SubmitButton/SubmitButton.js +2 -2
  54. package/lib/Templates/Templates.js +4 -0
  55. package/lib/Templates/Templates.js.map +1 -1
  56. package/lib/TitleField/TitleField.d.ts +1 -1
  57. package/lib/TitleField/TitleField.js +10 -5
  58. package/lib/TitleField/TitleField.js.map +1 -1
  59. package/lib/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.js +4 -5
  60. package/lib/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.js.map +1 -1
  61. package/lib/tsconfig.tsbuildinfo +1 -1
  62. package/package.json +22 -23
  63. package/src/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx +3 -3
  64. package/src/ArrayFieldTemplate/ArrayFieldTemplate.tsx +22 -16
  65. package/src/BaseInputTemplate/BaseInputTemplate.tsx +5 -5
  66. package/src/CheckboxWidget/CheckboxWidget.tsx +6 -6
  67. package/src/CheckboxesWidget/CheckboxesWidget.tsx +3 -2
  68. package/src/FieldErrorTemplate/FieldErrorTemplate.tsx +2 -2
  69. package/src/FieldHelpTemplate/FieldHelpTemplate.tsx +2 -2
  70. package/src/FieldTemplate/FieldTemplate.tsx +6 -4
  71. package/src/MultiSchemaFieldTemplate/MultiSchemaFieldTemplate.tsx +20 -0
  72. package/src/MultiSchemaFieldTemplate/index.ts +2 -0
  73. package/src/ObjectFieldTemplate/ObjectFieldTemplate.tsx +10 -6
  74. package/src/OptionalDataControlsTemplate/OptionalDataControlsTemplate.tsx +43 -0
  75. package/src/OptionalDataControlsTemplate/index.ts +2 -0
  76. package/src/RadioWidget/RadioWidget.tsx +4 -3
  77. package/src/RangeWidget/RangeWidget.tsx +1 -1
  78. package/src/SelectWidget/SelectWidget.tsx +3 -3
  79. package/src/Templates/Templates.ts +4 -0
  80. package/src/TitleField/TitleField.tsx +12 -1
  81. package/src/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.tsx +6 -8
  82. package/dist/index.js.map +0 -7
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rjsf/mui",
3
- "version": "6.0.0-beta.9",
4
- "main": "./dist/index.js",
3
+ "version": "6.0.0",
4
+ "main": "./dist/index.cjs",
5
5
  "module": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",
7
7
  "type": "module",
@@ -9,27 +9,27 @@
9
9
  "exports": {
10
10
  ".": {
11
11
  "types": "./lib/index.d.ts",
12
- "require": "./dist/index.js",
12
+ "require": "./dist/index.cjs",
13
13
  "import": "./lib/index.js"
14
14
  },
15
15
  "./lib": {
16
16
  "types": "./lib/index.d.ts",
17
- "require": "./dist/index.js",
17
+ "require": "./dist/index.cjs",
18
18
  "import": "./lib/index.js"
19
19
  },
20
20
  "./lib/*.js": {
21
21
  "types": "./lib/*.d.ts",
22
- "require": "./dist/*.js",
22
+ "require": "./dist/*.cjs",
23
23
  "import": "./lib/*.js"
24
24
  },
25
25
  "./dist": {
26
26
  "types": "./lib/index.d.ts",
27
- "require": "./dist/index.js",
27
+ "require": "./dist/index.cjs",
28
28
  "import": "./lib/index.js"
29
29
  },
30
- "./dist/*.js": {
30
+ "./dist/*.cjs": {
31
31
  "types": "./lib/*.d.ts",
32
- "require": "./dist/*.js",
32
+ "require": "./dist/*.cjs",
33
33
  "import": "./lib/*.js"
34
34
  }
35
35
  },
@@ -39,9 +39,8 @@
39
39
  "src"
40
40
  ],
41
41
  "scripts": {
42
- "compileReplacer": "tsc -p tsconfig.replacer.json && move-file muiReplacer.js muiReplacer.cjs",
43
- "build:ts": "npm run compileReplacer && rimraf ./lib && tsc -b tsconfig.build.json && tsc-alias -p tsconfig.build.json",
44
- "build:cjs": "esbuild ./src/index.ts --bundle --outfile=dist/index.js --sourcemap --packages=external --format=cjs",
42
+ "build:ts": "rimraf ./lib && tsc -b tsconfig.build.json && tsc-alias -p tsconfig.build.json",
43
+ "build:cjs": "esbuild ./src/index.ts --bundle --outfile=dist/index.cjs --sourcemap --packages=external --format=cjs",
45
44
  "build:esm": "esbuild ./src/index.ts --bundle --outfile=dist/mui.esm.js --sourcemap --packages=external --format=esm",
46
45
  "build:umd": "rollup dist/mui.esm.js --format=umd --file=dist/mui.umd.js --name=@rjsf/mui",
47
46
  "build": "npm run build:ts && npm run build:cjs && npm run build:esm && npm run build:umd",
@@ -65,21 +64,21 @@
65
64
  "@emotion/styled": "^11.6.0",
66
65
  "@mui/icons-material": "^7.0.0",
67
66
  "@mui/material": "^7.0.0",
68
- "@rjsf/core": "^6.0.0-beta",
69
- "@rjsf/utils": "^6.0.0-beta",
67
+ "@rjsf/core": "^6.0.0-beta.23",
68
+ "@rjsf/utils": "^6.0.0-beta.23",
70
69
  "react": ">=18"
71
70
  },
72
71
  "devDependencies": {
73
- "@emotion/jest": "^11.11.0",
74
- "@emotion/react": "^11.11.3",
75
- "@emotion/styled": "^11.11.0",
76
- "@mui/icons-material": "^7.1.0",
77
- "@mui/material": "^7.1.0",
78
- "@rjsf/core": "^6.0.0-beta.9",
79
- "@rjsf/snapshot-tests": "^6.0.0-beta.9",
80
- "@rjsf/utils": "^6.0.0-beta.9",
81
- "@rjsf/validator-ajv8": "^6.0.0-beta.9",
82
- "eslint": "^8.56.0"
72
+ "@emotion/jest": "^11.13.0",
73
+ "@emotion/react": "^11.14.0",
74
+ "@emotion/styled": "^11.14.1",
75
+ "@mui/icons-material": "^7.3.4",
76
+ "@mui/material": "^7.3.4",
77
+ "@rjsf/core": "^6.0.0-beta.23",
78
+ "@rjsf/snapshot-tests": "^6.0.0-beta.23",
79
+ "@rjsf/utils": "^6.0.0-beta.23",
80
+ "@rjsf/validator-ajv8": "^6.0.0-beta.23",
81
+ "eslint": "^8.57.1"
83
82
  },
84
83
  "publishConfig": {
85
84
  "access": "public"
@@ -3,7 +3,7 @@ import Box from '@mui/material/Box';
3
3
  import Grid from '@mui/material/Grid';
4
4
  import Paper from '@mui/material/Paper';
5
5
  import {
6
- ArrayFieldItemTemplateType,
6
+ ArrayFieldItemTemplateProps,
7
7
  FormContextType,
8
8
  getUiOptions,
9
9
  getTemplate,
@@ -13,13 +13,13 @@ import {
13
13
 
14
14
  /** The `ArrayFieldItemTemplate` component is the template used to render an items of an array.
15
15
  *
16
- * @param props - The `ArrayFieldItemTemplateType` props for the component
16
+ * @param props - The `ArrayFieldItemTemplateProps` props for the component
17
17
  */
18
18
  export default function ArrayFieldItemTemplate<
19
19
  T = any,
20
20
  S extends StrictRJSFSchema = RJSFSchema,
21
21
  F extends FormContextType = any,
22
- >(props: ArrayFieldItemTemplateType<T, S, F>) {
22
+ >(props: ArrayFieldItemTemplateProps<T, S, F>) {
23
23
  const { children, buttonsProps, hasToolbar, uiSchema, registry } = props;
24
24
  const uiOptions = getUiOptions<T, S, F>(uiSchema);
25
25
  const ArrayFieldItemButtonsTemplate = getTemplate<'ArrayFieldItemButtonsTemplate', T, S, F>(
@@ -5,7 +5,6 @@ import {
5
5
  getTemplate,
6
6
  getUiOptions,
7
7
  ArrayFieldTemplateProps,
8
- ArrayFieldItemTemplateType,
9
8
  FormContextType,
10
9
  RJSFSchema,
11
10
  StrictRJSFSchema,
@@ -14,31 +13,39 @@ import {
14
13
 
15
14
  /** The `ArrayFieldTemplate` component is the template used to render all items in an array.
16
15
  *
17
- * @param props - The `ArrayFieldItemTemplateType` props for the component
16
+ * @param props - The `ArrayFieldTemplateProps` props for the component
18
17
  */
19
18
  export default function ArrayFieldTemplate<
20
19
  T = any,
21
20
  S extends StrictRJSFSchema = RJSFSchema,
22
21
  F extends FormContextType = any,
23
22
  >(props: ArrayFieldTemplateProps<T, S, F>) {
24
- const { canAdd, disabled, idSchema, uiSchema, items, onAddClick, readonly, registry, required, schema, title } =
25
- props;
23
+ const {
24
+ canAdd,
25
+ disabled,
26
+ fieldPathId,
27
+ uiSchema,
28
+ items,
29
+ optionalDataControl,
30
+ onAddClick,
31
+ readonly,
32
+ registry,
33
+ required,
34
+ schema,
35
+ title,
36
+ } = props;
26
37
  const uiOptions = getUiOptions<T, S, F>(uiSchema);
27
38
  const ArrayFieldDescriptionTemplate = getTemplate<'ArrayFieldDescriptionTemplate', T, S, F>(
28
39
  'ArrayFieldDescriptionTemplate',
29
40
  registry,
30
41
  uiOptions,
31
42
  );
32
- const ArrayFieldItemTemplate = getTemplate<'ArrayFieldItemTemplate', T, S, F>(
33
- 'ArrayFieldItemTemplate',
34
- registry,
35
- uiOptions,
36
- );
37
43
  const ArrayFieldTitleTemplate = getTemplate<'ArrayFieldTitleTemplate', T, S, F>(
38
44
  'ArrayFieldTitleTemplate',
39
45
  registry,
40
46
  uiOptions,
41
47
  );
48
+ const showOptionalDataControlInTitle = !readonly && !disabled;
42
49
  // Button templates are not overridden in the uiSchema
43
50
  const {
44
51
  ButtonTemplates: { AddButton },
@@ -47,30 +54,29 @@ export default function ArrayFieldTemplate<
47
54
  <Paper elevation={2}>
48
55
  <Box p={2}>
49
56
  <ArrayFieldTitleTemplate
50
- idSchema={idSchema}
57
+ fieldPathId={fieldPathId}
51
58
  title={uiOptions.title || title}
52
59
  schema={schema}
53
60
  uiSchema={uiSchema}
54
61
  required={required}
55
62
  registry={registry}
63
+ optionalDataControl={showOptionalDataControlInTitle ? optionalDataControl : undefined}
56
64
  />
57
65
  <ArrayFieldDescriptionTemplate
58
- idSchema={idSchema}
66
+ fieldPathId={fieldPathId}
59
67
  description={uiOptions.description || schema.description}
60
68
  schema={schema}
61
69
  uiSchema={uiSchema}
62
70
  registry={registry}
63
71
  />
64
- {items &&
65
- items.map(({ key, ...itemProps }: ArrayFieldItemTemplateType<T, S, F>) => (
66
- <ArrayFieldItemTemplate key={key} {...itemProps} />
67
- ))}
72
+ {!showOptionalDataControlInTitle ? optionalDataControl : undefined}
73
+ {items}
68
74
  {canAdd && (
69
75
  <Grid container justifyContent='flex-end'>
70
76
  <Grid>
71
77
  <Box mt={2}>
72
78
  <AddButton
73
- id={buttonId<T>(idSchema, 'add')}
79
+ id={buttonId(fieldPathId, 'add')}
74
80
  className='rjsf-array-item-add'
75
81
  onClick={onAddClick}
76
82
  disabled={disabled || readonly}
@@ -27,6 +27,7 @@ export default function BaseInputTemplate<
27
27
  const {
28
28
  id,
29
29
  name, // remove this from textFieldProps
30
+ htmlName,
30
31
  placeholder,
31
32
  required,
32
33
  readonly,
@@ -46,7 +47,6 @@ export default function BaseInputTemplate<
46
47
  uiSchema,
47
48
  rawErrors = [],
48
49
  errorSchema,
49
- formContext,
50
50
  registry,
51
51
  InputLabelProps,
52
52
  ...textFieldProps
@@ -54,7 +54,7 @@ export default function BaseInputTemplate<
54
54
  const inputProps = getInputProps<T, S, F>(schema, type, options);
55
55
  // Now we need to pull out the step, min, max into an inner `inputProps` for material-ui
56
56
  const { step, min, max, accept, ...rest } = inputProps;
57
- const htmlInputProps = { step, min, max, accept, ...(schema.examples ? { list: examplesId<T>(id) } : undefined) };
57
+ const htmlInputProps = { step, min, max, accept, ...(schema.examples ? { list: examplesId(id) } : undefined) };
58
58
  const _onChange = ({ target: { value } }: ChangeEvent<HTMLInputElement>) =>
59
59
  onChange(value === '' ? options.emptyValue : value);
60
60
  const _onBlur = ({ target }: FocusEvent<HTMLInputElement>) => onBlur(id, target && target.value);
@@ -70,7 +70,7 @@ export default function BaseInputTemplate<
70
70
  <>
71
71
  <TextField
72
72
  id={id}
73
- name={id}
73
+ name={htmlName || id}
74
74
  placeholder={placeholder}
75
75
  label={labelValue(label || undefined, hideLabel, undefined)}
76
76
  autoFocus={autofocus}
@@ -84,10 +84,10 @@ export default function BaseInputTemplate<
84
84
  onBlur={_onBlur}
85
85
  onFocus={_onFocus}
86
86
  {...(textFieldProps as TextFieldProps)}
87
- aria-describedby={ariaDescribedByIds<T>(id, !!schema.examples)}
87
+ aria-describedby={ariaDescribedByIds(id, !!schema.examples)}
88
88
  />
89
89
  {Array.isArray(schema.examples) && (
90
- <datalist id={examplesId<T>(id)}>
90
+ <datalist id={examplesId(id)}>
91
91
  {(schema.examples as string[])
92
92
  .concat(schema.default && !schema.examples.includes(schema.default) ? ([schema.default] as string[]) : [])
93
93
  .map((example: any) => {
@@ -1,4 +1,3 @@
1
- import { FocusEvent } from 'react';
2
1
  import Checkbox from '@mui/material/Checkbox';
3
2
  import FormControlLabel from '@mui/material/FormControlLabel';
4
3
  import {
@@ -26,6 +25,7 @@ export default function CheckboxWidget<
26
25
  const {
27
26
  schema,
28
27
  id,
28
+ htmlName,
29
29
  value,
30
30
  disabled,
31
31
  readonly,
@@ -50,15 +50,15 @@ export default function CheckboxWidget<
50
50
  const required = schemaRequiresTrueValue<S>(schema);
51
51
 
52
52
  const _onChange = (_: any, checked: boolean) => onChange(checked);
53
- const _onBlur = ({ target }: FocusEvent<HTMLButtonElement>) => onBlur(id, target && target.value);
54
- const _onFocus = ({ target }: FocusEvent<HTMLButtonElement>) => onFocus(id, target && target.value);
53
+ const _onBlur: React.FocusEventHandler<HTMLButtonElement> = () => onBlur(id, value);
54
+ const _onFocus: React.FocusEventHandler<HTMLButtonElement> = () => onFocus(id, value);
55
55
  const description = options.description ?? schema.description;
56
56
 
57
57
  return (
58
58
  <>
59
59
  {!hideLabel && description && (
60
60
  <DescriptionFieldTemplate
61
- id={descriptionId<T>(id)}
61
+ id={descriptionId(id)}
62
62
  description={description}
63
63
  schema={schema}
64
64
  uiSchema={uiSchema}
@@ -69,7 +69,7 @@ export default function CheckboxWidget<
69
69
  control={
70
70
  <Checkbox
71
71
  id={id}
72
- name={id}
72
+ name={htmlName || id}
73
73
  checked={typeof value === 'undefined' ? false : Boolean(value)}
74
74
  required={required}
75
75
  disabled={disabled || readonly}
@@ -77,7 +77,7 @@ export default function CheckboxWidget<
77
77
  onChange={_onChange}
78
78
  onBlur={_onBlur}
79
79
  onFocus={_onFocus}
80
- aria-describedby={ariaDescribedByIds<T>(id)}
80
+ aria-describedby={ariaDescribedByIds(id)}
81
81
  />
82
82
  }
83
83
  label={labelValue(label, hideLabel, false)}
@@ -30,6 +30,7 @@ export default function CheckboxesWidget<
30
30
  label,
31
31
  hideLabel,
32
32
  id,
33
+ htmlName,
33
34
  disabled,
34
35
  options,
35
36
  value,
@@ -74,14 +75,14 @@ export default function CheckboxesWidget<
74
75
  const checkbox = (
75
76
  <Checkbox
76
77
  id={optionId(id, index)}
77
- name={id}
78
+ name={htmlName || id}
78
79
  checked={checked}
79
80
  disabled={disabled || itemDisabled || readonly}
80
81
  autoFocus={autofocus && index === 0}
81
82
  onChange={_onChange(index)}
82
83
  onBlur={_onBlur}
83
84
  onFocus={_onFocus}
84
- aria-describedby={ariaDescribedByIds<T>(id)}
85
+ aria-describedby={ariaDescribedByIds(id)}
85
86
  />
86
87
  );
87
88
  return <FormControlLabel control={checkbox} key={index} label={option.label} />;
@@ -12,11 +12,11 @@ export default function FieldErrorTemplate<
12
12
  S extends StrictRJSFSchema = RJSFSchema,
13
13
  F extends FormContextType = any,
14
14
  >(props: FieldErrorProps<T, S, F>) {
15
- const { errors = [], idSchema } = props;
15
+ const { errors = [], fieldPathId } = props;
16
16
  if (errors.length === 0) {
17
17
  return null;
18
18
  }
19
- const id = errorId<T>(idSchema);
19
+ const id = errorId(fieldPathId);
20
20
 
21
21
  return (
22
22
  <List id={id} dense={true} disablePadding={true}>
@@ -10,11 +10,11 @@ export default function FieldHelpTemplate<
10
10
  S extends StrictRJSFSchema = RJSFSchema,
11
11
  F extends FormContextType = any,
12
12
  >(props: FieldHelpProps<T, S, F>) {
13
- const { idSchema, help } = props;
13
+ const { fieldPathId, help } = props;
14
14
  if (!help) {
15
15
  return null;
16
16
  }
17
- const id = helpId<T>(idSchema);
17
+ const id = helpId(fieldPathId);
18
18
  return (
19
19
  <FormHelperText component='div' id={id}>
20
20
  {help}
@@ -28,8 +28,9 @@ export default function FieldTemplate<
28
28
  displayLabel,
29
29
  hidden,
30
30
  label,
31
- onDropPropertyClick,
32
- onKeyChange,
31
+ onKeyRename,
32
+ onKeyRenameBlur,
33
+ onRemoveProperty,
33
34
  readonly,
34
35
  required,
35
36
  rawErrors = [],
@@ -58,8 +59,9 @@ export default function FieldTemplate<
58
59
  disabled={disabled}
59
60
  id={id}
60
61
  label={label}
61
- onDropPropertyClick={onDropPropertyClick}
62
- onKeyChange={onKeyChange}
62
+ onKeyRename={onKeyRename}
63
+ onKeyRenameBlur={onKeyRenameBlur}
64
+ onRemoveProperty={onRemoveProperty}
63
65
  readonly={readonly}
64
66
  required={required}
65
67
  schema={schema}
@@ -0,0 +1,20 @@
1
+ import Box from '@mui/material/Box';
2
+ import { FormContextType, MultiSchemaFieldTemplateProps, RJSFSchema, StrictRJSFSchema } from '@rjsf/utils';
3
+ import FormControl from '@mui/material/FormControl';
4
+
5
+ export default function MultiSchemaFieldTemplate<
6
+ T = any,
7
+ S extends StrictRJSFSchema = RJSFSchema,
8
+ F extends FormContextType = any,
9
+ >(props: MultiSchemaFieldTemplateProps<T, S, F>) {
10
+ const { optionSchemaField, selector } = props;
11
+
12
+ return (
13
+ <Box sx={{ mb: 2 }}>
14
+ <FormControl fullWidth sx={{ mb: 2 }}>
15
+ {selector}
16
+ </FormControl>
17
+ {optionSchemaField}
18
+ </Box>
19
+ );
20
+ }
@@ -0,0 +1,2 @@
1
+ export { default } from './MultiSchemaFieldTemplate';
2
+ export * from './MultiSchemaFieldTemplate';
@@ -31,10 +31,11 @@ export default function ObjectFieldTemplate<
31
31
  disabled,
32
32
  readonly,
33
33
  uiSchema,
34
- idSchema,
34
+ fieldPathId,
35
35
  schema,
36
36
  formData,
37
- onAddClick,
37
+ optionalDataControl,
38
+ onAddProperty,
38
39
  registry,
39
40
  } = props;
40
41
  const uiOptions = getUiOptions<T, S, F>(uiSchema);
@@ -44,6 +45,7 @@ export default function ObjectFieldTemplate<
44
45
  registry,
45
46
  uiOptions,
46
47
  );
48
+ const showOptionalDataControlInTitle = !readonly && !disabled;
47
49
  // Button templates are not overridden in the uiSchema
48
50
  const {
49
51
  ButtonTemplates: { AddButton },
@@ -52,17 +54,18 @@ export default function ObjectFieldTemplate<
52
54
  <>
53
55
  {title && (
54
56
  <TitleFieldTemplate
55
- id={titleId<T>(idSchema)}
57
+ id={titleId(fieldPathId)}
56
58
  title={title}
57
59
  required={required}
58
60
  schema={schema}
59
61
  uiSchema={uiSchema}
60
62
  registry={registry}
63
+ optionalDataControl={showOptionalDataControlInTitle ? optionalDataControl : undefined}
61
64
  />
62
65
  )}
63
66
  {description && (
64
67
  <DescriptionFieldTemplate
65
- id={descriptionId<T>(idSchema)}
68
+ id={descriptionId(fieldPathId)}
66
69
  description={description}
67
70
  schema={schema}
68
71
  uiSchema={uiSchema}
@@ -70,6 +73,7 @@ export default function ObjectFieldTemplate<
70
73
  />
71
74
  )}
72
75
  <Grid container={true} spacing={2} style={{ marginTop: '10px' }}>
76
+ {!showOptionalDataControlInTitle ? optionalDataControl : undefined}
73
77
  {properties.map((element, index) =>
74
78
  // Remove the <Grid> if the inner element is hidden as the <Grid>
75
79
  // itself would otherwise still take up space.
@@ -85,9 +89,9 @@ export default function ObjectFieldTemplate<
85
89
  <Grid container justifyContent='flex-end'>
86
90
  <Grid>
87
91
  <AddButton
88
- id={buttonId<T>(idSchema, 'add')}
92
+ id={buttonId(fieldPathId, 'add')}
89
93
  className='rjsf-object-property-expand'
90
- onClick={onAddClick(schema)}
94
+ onClick={onAddProperty}
91
95
  disabled={disabled || readonly}
92
96
  uiSchema={uiSchema}
93
97
  registry={registry}
@@ -0,0 +1,43 @@
1
+ import { FormContextType, OptionalDataControlsTemplateProps, RJSFSchema, StrictRJSFSchema } from '@rjsf/utils';
2
+
3
+ import IconButton, { RemoveButton } from '../IconButton';
4
+ import AddIcon from '@mui/icons-material/Add';
5
+
6
+ /** The OptionalDataControlsTemplate renders one of three different states. If
7
+ * there is an `onAddClick()` function, it renders the "Add" button. If there is
8
+ * an `onRemoveClick()` function, it renders the "Remove" button. Otherwise it
9
+ * renders the "No data found" section. All of them use the `label` as either
10
+ * the `title` of buttons or simply outputting it.
11
+ *
12
+ * @param props - The `OptionalDataControlsTemplateProps` for the template
13
+ */
14
+ export default function OptionalDataControlsTemplate<
15
+ T = any,
16
+ S extends StrictRJSFSchema = RJSFSchema,
17
+ F extends FormContextType = any,
18
+ >(props: OptionalDataControlsTemplateProps<T, S, F>) {
19
+ const { id, registry, label, onAddClick, onRemoveClick } = props;
20
+ if (onAddClick) {
21
+ return (
22
+ <IconButton
23
+ id={id}
24
+ registry={registry}
25
+ className='rjsf-add-optional-data'
26
+ onClick={onAddClick}
27
+ title={label}
28
+ icon={<AddIcon fontSize='small' />}
29
+ />
30
+ );
31
+ } else if (onRemoveClick) {
32
+ return (
33
+ <RemoveButton
34
+ id={id}
35
+ registry={registry}
36
+ className='rjsf-remove-optional-data'
37
+ onClick={onRemoveClick}
38
+ title={label}
39
+ />
40
+ );
41
+ }
42
+ return <em id={id}>{label}</em>;
43
+ }
@@ -0,0 +1,2 @@
1
+ export { default } from './OptionalDataControlsTemplate';
2
+ export * from './OptionalDataControlsTemplate';
@@ -22,6 +22,7 @@ import {
22
22
  */
23
23
  export default function RadioWidget<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>({
24
24
  id,
25
+ htmlName,
25
26
  options,
26
27
  value,
27
28
  required,
@@ -54,20 +55,20 @@ export default function RadioWidget<T = any, S extends StrictRJSFSchema = RJSFSc
54
55
  )}
55
56
  <RadioGroup
56
57
  id={id}
57
- name={id}
58
+ name={htmlName || id}
58
59
  value={selectedIndex}
59
60
  row={row as boolean}
60
61
  onChange={_onChange}
61
62
  onBlur={_onBlur}
62
63
  onFocus={_onFocus}
63
- aria-describedby={ariaDescribedByIds<T>(id)}
64
+ aria-describedby={ariaDescribedByIds(id)}
64
65
  >
65
66
  {Array.isArray(enumOptions) &&
66
67
  enumOptions.map((option, index) => {
67
68
  const itemDisabled = Array.isArray(enumDisabled) && enumDisabled.indexOf(option.value) !== -1;
68
69
  const radio = (
69
70
  <FormControlLabel
70
- control={<Radio name={id} id={optionId(id, index)} color='primary' />}
71
+ control={<Radio name={htmlName || id} id={optionId(id, index)} color='primary' />}
71
72
  label={option.label}
72
73
  value={String(index)}
73
74
  key={index}
@@ -44,7 +44,7 @@ export default function RangeWidget<T = any, S extends StrictRJSFSchema = RJSFSc
44
44
  onFocus={_onFocus}
45
45
  valueLabelDisplay='auto'
46
46
  {...sliderProps}
47
- aria-describedby={ariaDescribedByIds<T>(id)}
47
+ aria-describedby={ariaDescribedByIds(id)}
48
48
  />
49
49
  </>
50
50
  );
@@ -25,6 +25,7 @@ export default function SelectWidget<
25
25
  schema,
26
26
  id,
27
27
  name, // remove this from textFieldProps
28
+ htmlName,
28
29
  options,
29
30
  label,
30
31
  hideLabel,
@@ -43,7 +44,6 @@ export default function SelectWidget<
43
44
  registry,
44
45
  uiSchema,
45
46
  hideError,
46
- formContext,
47
47
  ...textFieldProps
48
48
  }: WidgetProps<T, S, F>) {
49
49
  const { enumOptions, enumDisabled, emptyValue: optEmptyVal } = options;
@@ -66,7 +66,7 @@ export default function SelectWidget<
66
66
  return (
67
67
  <TextField
68
68
  id={id}
69
- name={id}
69
+ name={htmlName || id}
70
70
  label={labelValue(label || undefined, hideLabel, undefined)}
71
71
  value={!isEmpty && typeof selectedIndexes !== 'undefined' ? selectedIndexes : emptyValue}
72
72
  required={required}
@@ -88,7 +88,7 @@ export default function SelectWidget<
88
88
  ...SelectProps,
89
89
  multiple,
90
90
  }}
91
- aria-describedby={ariaDescribedByIds<T>(id)}
91
+ aria-describedby={ariaDescribedByIds(id)}
92
92
  >
93
93
  {showPlaceholderOption && <MenuItem value=''>{placeholder}</MenuItem>}
94
94
  {Array.isArray(enumOptions) &&
@@ -11,7 +11,9 @@ import FieldErrorTemplate from '../FieldErrorTemplate';
11
11
  import FieldHelpTemplate from '../FieldHelpTemplate';
12
12
  import FieldTemplate from '../FieldTemplate';
13
13
  import GridTemplate from '../GridTemplate';
14
+ import MultiSchemaFieldTemplate from '../MultiSchemaFieldTemplate';
14
15
  import ObjectFieldTemplate from '../ObjectFieldTemplate';
16
+ import OptionalDataControlsTemplate from '../OptionalDataControlsTemplate';
15
17
  import SubmitButton from '../SubmitButton';
16
18
  import TitleField from '../TitleField';
17
19
  import WrapIfAdditionalTemplate from '../WrapIfAdditionalTemplate';
@@ -39,7 +41,9 @@ export function generateTemplates<
39
41
  FieldHelpTemplate,
40
42
  FieldTemplate,
41
43
  GridTemplate,
44
+ MultiSchemaFieldTemplate,
42
45
  ObjectFieldTemplate,
46
+ OptionalDataControlsTemplate,
43
47
  TitleFieldTemplate: TitleField,
44
48
  WrapIfAdditionalTemplate,
45
49
  };
@@ -1,5 +1,6 @@
1
1
  import Box from '@mui/material/Box';
2
2
  import Divider from '@mui/material/Divider';
3
+ import Grid from '@mui/material/Grid';
3
4
  import Typography from '@mui/material/Typography';
4
5
  import { FormContextType, TitleFieldProps, RJSFSchema, StrictRJSFSchema } from '@rjsf/utils';
5
6
 
@@ -10,10 +11,20 @@ import { FormContextType, TitleFieldProps, RJSFSchema, StrictRJSFSchema } from '
10
11
  export default function TitleField<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>({
11
12
  id,
12
13
  title,
14
+ optionalDataControl,
13
15
  }: TitleFieldProps<T, S, F>) {
16
+ let heading = <Typography variant='h5'>{title}</Typography>;
17
+ if (optionalDataControl) {
18
+ heading = (
19
+ <Grid container={true} spacing={0}>
20
+ <Grid size='grow'>{heading}</Grid>
21
+ <Grid justifyContent='flex-end'>{optionalDataControl}</Grid>
22
+ </Grid>
23
+ );
24
+ }
14
25
  return (
15
26
  <Box id={id} mb={1} mt={1}>
16
- <Typography variant='h5'>{title}</Typography>
27
+ {heading}
17
28
  <Divider />
18
29
  </Box>
19
30
  );