diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx
index df58d971fb..78aef3428f 100644
--- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx
+++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx
@@ -549,6 +549,66 @@ describe('Stepper', () => {
});
});
+ it('should allow overrides to the uiSchema and formContext correctly', async () => {
+ const manifest: TemplateParameterSchema = {
+ title: 'Custom Fields',
+ steps: [
+ {
+ title: 'Test',
+ schema: {
+ properties: {
+ name: {
+ type: 'string',
+ 'ui:placeholder': 'Enter your name',
+ },
+ age: {
+ type: 'number',
+ 'ui:placeholder': 'Enter your age',
+ },
+ },
+ },
+ },
+ ],
+ };
+
+ const uiSchema = {
+ name: {
+ 'ui:readonly': true,
+ 'ui:placeholder': 'Should be overwritten',
+ },
+ };
+
+ const formContext = {
+ readOnlyAsDisabled: true,
+ };
+
+ const { getByRole } = await renderInTestApp(
+
+
+ ,
+ );
+
+ expect(getByRole('textbox', { name: 'name' })).toHaveValue('Some Name');
+ expect(getByRole('textbox', { name: 'name' })).toBeDisabled();
+ expect(getByRole('textbox', { name: 'name' })).toHaveAttribute(
+ 'placeholder',
+ 'Enter your name',
+ );
+
+ expect(getByRole('spinbutton', { name: 'age' })).toHaveValue(40);
+ expect(getByRole('spinbutton', { name: 'age' })).toBeEnabled();
+ expect(getByRole('spinbutton', { name: 'age' })).toHaveAttribute(
+ 'placeholder',
+ 'Enter your age',
+ );
+ });
+
describe('Scaffolder Layouts', () => {
it('should render the step in the scaffolder layout', async () => {
const ScaffolderLayout: LayoutTemplate = ({ properties }) => (
diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx
index 788c7cd715..3a8858144b 100644
--- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx
+++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx
@@ -51,6 +51,7 @@ import { ErrorListTemplate } from './ErrorListTemplate';
import { makeStyles } from '@material-ui/core/styles';
import { PasswordWidget } from '../PasswordWidget/PasswordWidget';
import ajvErrors from 'ajv-errors';
+import { merge } from 'lodash';
const validator = customizeValidator();
ajvErrors(validator.ajv);
@@ -193,6 +194,14 @@ export const Stepper = (stepperProps: StepperProps) => {
setFormState(current => ({ ...current, ...formData }));
};
+ const {
+ formContext: propFormContext,
+ uiSchema: propUiSchema,
+ ...restFormProps
+ } = props.formProps ?? {};
+
+ const mergedUiSchema = merge({}, propUiSchema, currentStep?.uiSchema);
+
return (
<>
{isValidating && }
@@ -229,9 +238,9 @@ export const Stepper = (stepperProps: StepperProps) => {
validator={validator}
extraErrors={errors as unknown as ErrorSchema}
formData={formState}
- formContext={{ formData: formState }}
+ formContext={{ ...propFormContext, formData: formState }}
schema={currentStep.schema}
- uiSchema={currentStep.uiSchema}
+ uiSchema={mergedUiSchema}
onSubmit={handleNext}
fields={fields}
showErrorList="top"
@@ -241,7 +250,7 @@ export const Stepper = (stepperProps: StepperProps) => {
experimental_defaultFormStateBehavior={{
allOf: 'populateDefaults',
}}
- {...(props.formProps ?? {})}
+ {...restFormProps}
>