|
1 | 1 | import toConstant from './toConstant';
|
2 |
| -import { RJSFSchema, EnumOptionsType, StrictRJSFSchema } from './types'; |
| 2 | +import { RJSFSchema, EnumOptionsType, StrictRJSFSchema, FormContextType, UiSchema } from './types'; |
| 3 | +import getUiOptions from './getUiOptions'; |
3 | 4 |
|
4 |
| -/** Gets the list of options from the schema. If the schema has an enum list, then those enum values are returned. The |
| 5 | +/** Gets the list of options from the `schema`. If the schema has an enum list, then those enum values are returned. The |
5 | 6 | * labels for the options will be extracted from the non-standard, RJSF-deprecated `enumNames` if it exists, otherwise
|
6 | 7 | * the label will be the same as the `value`. If the schema has a `oneOf` or `anyOf`, then the value is the list of
|
7 |
| - * `const` values from the schema and the label is either the `schema.title` or the value. |
| 8 | + * `const` values from the schema and the label is either the `schema.title` or the value. If a `uiSchema` is provided |
| 9 | + * and it has the `ui:enumNames` matched with `enum` or it has an associated `oneOf` or `anyOf` with a list of objects |
| 10 | + * containing `ui:title` then the UI schema values will replace the values from the schema. |
8 | 11 | *
|
9 | 12 | * @param schema - The schema from which to extract the options list
|
| 13 | + * @param [uiSchema] - The optional uiSchema from which to get alternate labels for the options |
10 | 14 | * @returns - The list of options from the schema
|
11 | 15 | */
|
12 |
| -export default function optionsList<S extends StrictRJSFSchema = RJSFSchema>( |
13 |
| - schema: S |
| 16 | +export default function optionsList<S extends StrictRJSFSchema = RJSFSchema, T = any, F extends FormContextType = any>( |
| 17 | + schema: S, |
| 18 | + uiSchema?: UiSchema<T, S, F> |
14 | 19 | ): EnumOptionsType<S>[] | undefined {
|
15 |
| - // enumNames was deprecated in v5 and is intentionally omitted from the RJSFSchema type. |
16 |
| - // Cast the type to include enumNames so the feature still works. |
| 20 | + // TODO flip generics to move T first in v6 |
17 | 21 | const schemaWithEnumNames = schema as S & { enumNames?: string[] };
|
18 |
| - if (schemaWithEnumNames.enumNames && process.env.NODE_ENV !== 'production') { |
19 |
| - console.warn('The enumNames property is deprecated and may be removed in a future major release.'); |
20 |
| - } |
21 | 22 | if (schema.enum) {
|
| 23 | + let enumNames: string[] | undefined; |
| 24 | + if (uiSchema) { |
| 25 | + const { enumNames: uiEnumNames } = getUiOptions<T, S, F>(uiSchema); |
| 26 | + enumNames = uiEnumNames; |
| 27 | + } |
| 28 | + if (!enumNames && schemaWithEnumNames.enumNames) { |
| 29 | + // enumNames was deprecated in v5 and is intentionally omitted from the RJSFSchema type. |
| 30 | + // Cast the type to include enumNames so the feature still works. |
| 31 | + if (process.env.NODE_ENV !== 'production') { |
| 32 | + console.warn( |
| 33 | + 'The "enumNames" property in the schema is deprecated and will be removed in a future major release. Use the "ui:enumNames" property in the uiSchema instead.' |
| 34 | + ); |
| 35 | + } |
| 36 | + enumNames = schemaWithEnumNames.enumNames; |
| 37 | + } |
22 | 38 | return schema.enum.map((value, i) => {
|
23 |
| - const label = (schemaWithEnumNames.enumNames && schemaWithEnumNames.enumNames[i]) || String(value); |
| 39 | + const label = enumNames?.[i] || String(value); |
24 | 40 | return { label, value };
|
25 | 41 | });
|
26 | 42 | }
|
27 |
| - const altSchemas = schema.oneOf || schema.anyOf; |
| 43 | + let altSchemas: S['anyOf'] | S['oneOf'] = undefined; |
| 44 | + let altUiSchemas: UiSchema<T, S, F> | undefined = undefined; |
| 45 | + if (schema.anyOf) { |
| 46 | + altSchemas = schema.anyOf; |
| 47 | + altUiSchemas = uiSchema?.anyOf; |
| 48 | + } else if (schema.oneOf) { |
| 49 | + altSchemas = schema.oneOf; |
| 50 | + altUiSchemas = uiSchema?.oneOf; |
| 51 | + } |
28 | 52 | return (
|
29 | 53 | altSchemas &&
|
30 |
| - altSchemas.map((aSchemaDef) => { |
| 54 | + altSchemas.map((aSchemaDef, index) => { |
| 55 | + const { title } = getUiOptions<T, S, F>(altUiSchemas?.[index]); |
31 | 56 | const aSchema = aSchemaDef as S;
|
32 | 57 | const value = toConstant(aSchema);
|
33 |
| - const label = aSchema.title || String(value); |
| 58 | + const label = title || aSchema.title || String(value); |
34 | 59 | return {
|
35 | 60 | schema: aSchema,
|
36 | 61 | label,
|
|
0 commit comments