Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make fields with const pre-fiiled and readonly #3843

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ should change the heading of the (upcoming) version to include a major version b
## @rjsf/core

- Updated `MultiSchemaField` to merge all top level fields except properties for anyOf/oneOf options, fixing [#3808](https://github.com/rjsf-team/react-jsonschema-form/issues/3808) and [#3787](https://github.com/rjsf-team/react-jsonschema-form/issues/3787)
- Updated `SchemaField` to make fields readonly when they have `const` defined, fixing [#2600](https://github.com/rjsf-team/react-jsonschema-form/issues/2600)

## @rjsf/antd

Expand All @@ -32,6 +33,11 @@ should change the heading of the (upcoming) version to include a major version b
## @rjsf/utils

- Updated `retrieveSchemaInternal` allOf logic for precompiled schemas to resolve top level properties fixing [#3817](https://github.com/rjsf-team/react-jsonschema-form/issues/3817)
- Updated `getDefaultFormState` to extract default value when fields have `const` definition, fixing [#2600](https://github.com/rjsf-team/react-jsonschema-form/issues/2600)

## Dev / docs / playground

- Updated the `playground` to add sample for `const` use cases

# 5.12.0

Expand Down
9 changes: 8 additions & 1 deletion packages/core/src/components/fields/SchemaField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,14 @@ function SchemaFieldRender<T = any, S extends StrictRJSFSchema = RJSFSchema, F e

const FieldComponent = getFieldComponent<T, S, F>(schema, uiOptions, idSchema, registry);
const disabled = Boolean(props.disabled || uiOptions.disabled);
const readonly = Boolean(props.readonly || uiOptions.readonly || props.schema.readOnly || schema.readOnly);
const readonly = Boolean(
props.readonly ||
uiOptions.readonly ||
props.schema.readOnly ||
schema.readOnly ||
props.schema.const ||
schema.const
);
const uiSchemaHideError = uiOptions.hideError;
// Set hideError to the value provided in the uiSchema, otherwise stick with the prop to propagate to children
const hideError = uiSchemaHideError === undefined ? props.hideError : Boolean(uiSchemaHideError);
Expand Down
53 changes: 53 additions & 0 deletions packages/playground/src/samples/constField.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
export default {
schema: {
type: 'object',
properties: {
name: {
type: 'string',
const: 'John',
},
address: {
type: 'object',
properties: {
city: {
type: 'string',
},
detail: {
type: 'object',
properties: {
street: {
type: 'string',
},
zip: {
type: 'integer',
},
},
},
},
const: {
city: 'New York',
detail: {
street: 'First Street',
zip: 12345,
},
},
},
tags: {
type: 'array',
items: {
type: 'string',
},
const: ['red', 'green', 'blue'],
},
isVerified: {
type: 'boolean',
const: true,
},
age: {
type: 'number',
const: 30,
},
},
},
formData: {},
};
2 changes: 2 additions & 0 deletions packages/playground/src/samples/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import defaults from './defaults';
import options from './options';
import ifThenElse from './ifThenElse';
import customField from './customField';
import constField from './constField';

export const samples = Object.freeze({
Blank: { schema: {}, uiSchema: {}, formData: {} },
Expand Down Expand Up @@ -67,6 +68,7 @@ export const samples = Object.freeze({
ErrorSchema: errorSchema,
Defaults: defaults,
'Custom Field': customField,
'Const Field': constField,
} as const);

export type Sample = keyof typeof samples;
12 changes: 11 additions & 1 deletion packages/utils/src/schema/getDefaultFormState.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import get from 'lodash/get';
import isEmpty from 'lodash/isEmpty';

import { ANY_OF_KEY, DEFAULT_KEY, DEPENDENCIES_KEY, PROPERTIES_KEY, ONE_OF_KEY, REF_KEY } from '../constants';
import {
ANY_OF_KEY,
CONST_KEY,
DEFAULT_KEY,
DEPENDENCIES_KEY,
PROPERTIES_KEY,
ONE_OF_KEY,
REF_KEY,
} from '../constants';
import findSchemaDefinition from '../findSchemaDefinition';
import getClosestMatchingOption from './getClosestMatchingOption';
import getDiscriminatorFieldFromSchema from '../getDiscriminatorFieldFromSchema';
Expand Down Expand Up @@ -177,6 +185,8 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
defaults = mergeObjects(defaults!, schema.default as GenericObjectType) as T;
} else if (DEFAULT_KEY in schema) {
defaults = schema.default as unknown as T;
} else if (CONST_KEY in schema) {
defaults = schema.const as unknown as T;
Copy link
Member

@heath-freenome heath-freenome Aug 29, 2023

Choose a reason for hiding this comment

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

Const are different than defaults in that they should ALWAYS be set regardless of those values of the experimental_defaultFormStateBehavior.emptyObjectFields that restrict how defaults are set. I'm not entirely sure the best approach to updating maybeAddDefaultToObject() to understand the difference. I'm curious to see what you come up with. Maybe passing parentConsts along side of parentDefaults?

} else if (REF_KEY in schema) {
const refName = schema[REF_KEY];
// Use referenced schema defaults for this node.
Expand Down
33 changes: 33 additions & 0 deletions packages/utils/test/schema/getDefaultFormStateTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,39 @@ export default function getDefaultFormStateTest(testValidator: TestValidatorType
const schema: RJSFSchema = { type: 'string' };
expect(computeDefaults(testValidator, schema)).toBe(undefined);
});
it('test const value will populate as field defaults', () => {
const schema: RJSFSchema = {
type: 'object',
properties: {
foo: {
type: 'string',
const: 'bar',
},
foo2: {
type: 'object',
properties: {
attr1: {
type: 'number',
},
attr2: {
type: 'boolean',
},
},
const: {
attr1: 1,
attr2: true,
},
},
},
};
expect(computeDefaults(testValidator, schema, { rootSchema: schema })).toEqual({
foo: 'bar',
foo2: {
attr1: 1,
attr2: true,
},
});
});
});
describe('default form state behavior: ignore min items unless required', () => {
it('should return empty data for an optional array property with minItems', () => {
Expand Down