feat: started to promote the bare minmum

Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
blam
2023-09-26 14:39:19 +02:00
committed by Patrik Oldsberg
parent 2425e79b19
commit 95415da622
14 changed files with 460 additions and 139 deletions
+2
View File
@@ -16,3 +16,5 @@
export * from './next';
export type { FormProps } from './next';
export * from './legacy';
@@ -14,23 +14,16 @@
* limitations under the License.
*/
import React from 'react';
import {
CustomFieldExtensionSchema,
CustomFieldValidator,
FieldExtensionOptions,
FieldExtensionComponentProps,
FieldExtensionUiSchema,
} from './types';
import { Extension, attachComponentData } from '@backstage/core-plugin-api';
import { UIOptionsType } from '@rjsf/utils';
import { FIELD_EXTENSION_KEY, FIELD_EXTENSION_WRAPPER_KEY } from './keys';
/**
* The type used to wrap up the Layout and embed the input props
*
* @public
*/
export type FieldExtensionComponent<_TReturnValue, _TInputProps> = () => null;
/**
* Method for creating field extensions that can be used in the scaffolder
* frontend form.
@@ -38,7 +31,7 @@ export type FieldExtensionComponent<_TReturnValue, _TInputProps> = () => null;
*/
export function createScaffolderFieldExtension<
TReturnValue = unknown,
TInputProps = unknown,
TInputProps extends UIOptionsType = {},
>(
options: FieldExtensionOptions<TReturnValue, TInputProps>,
): Extension<FieldExtensionComponent<TReturnValue, TInputProps>> {
@@ -72,9 +65,16 @@ attachComponentData(
true,
);
/**
* The type used to wrap up the Layout and embed the input props
*
* @public
*/
export type FieldExtensionComponent<_TReturnValue, _TInputProps> = () => null;
export type {
CustomFieldExtensionSchema,
CustomFieldValidator,
FieldExtensionOptions,
FieldExtensionComponentProps,
FieldExtensionUiSchema,
};
@@ -0,0 +1,292 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ComponentType, ElementType, FormEvent, ReactNode, Ref } from 'react';
import {
ErrorSchema,
FormContextType,
GenericObjectType,
IdSchema,
Registry,
RJSFSchema,
StrictRJSFSchema,
UiSchema,
ValidatorType,
TemplatesType,
RegistryWidgetsType,
RJSFValidationError,
CustomValidator,
Experimental_DefaultFormStateBehavior,
ErrorTransformer,
} from '@rjsf/utils';
import { HTMLAttributes } from 'react';
import Form, { IChangeEvent } from '@rjsf/core-v5';
/**
* The props for the `Field` components
* @public
*/
export interface ScaffolderRJSFFieldProps<
T = any,
S extends StrictRJSFSchema = RJSFSchema,
F extends FormContextType = any,
> extends GenericObjectType,
Pick<
HTMLAttributes<HTMLElement>,
Exclude<
keyof HTMLAttributes<HTMLElement>,
'onBlur' | 'onFocus' | 'onChange'
>
> {
/** The JSON subschema object for this field */
schema: S;
/** The uiSchema for this field */
uiSchema: UiSchema<T, S, F>;
/** The tree of unique ids for every child field */
idSchema: IdSchema<T>;
/** The data for this field */
formData: T;
/** The tree of errors for this field and its children */
errorSchema?: ErrorSchema<T>;
/** The field change event handler; called with the updated form data and an optional `ErrorSchema` */
onChange: (
newFormData: T | undefined,
es?: ErrorSchema<T>,
id?: string,
) => any;
/** The input blur event handler; call it with the field id and value */
onBlur: (id: string, value: any) => void;
/** The input focus event handler; call it with the field id and value */
onFocus: (id: string, value: any) => void;
/** The `formContext` object that you passed to `Form` */
formContext?: F;
/** A boolean value stating if the field should autofocus */
autofocus?: boolean;
/** A boolean value stating if the field is disabled */
disabled: boolean;
/** A boolean value stating if the field is hiding its errors */
hideError?: boolean;
/** A boolean value stating if the field is read-only */
readonly: boolean;
/** The required status of this field */
required?: boolean;
/** The unique name of the field, usually derived from the name of the property in the JSONSchema */
name: string;
/** To avoid collisions with existing ids in the DOM, it is possible to change the prefix used for ids;
* Default is `root`
*/
idPrefix?: string;
/** To avoid using a path separator that is present in field names, it is possible to change the separator used for
* ids (Default is `_`)
*/
idSeparator?: string;
/** An array of strings listing all generated error messages from encountered errors for this field */
rawErrors: string[];
/** The `registry` object */
registry: Registry<T, S, F>;
}
/**
* The properties that are passed to the `Form`
* @public
*/
export interface ScaffolderRJSFFormProps<
T = any,
S extends StrictRJSFSchema = RJSFSchema,
F extends FormContextType = any,
> {
/** The JSON schema object for the form */
schema: S;
/** An implementation of the `ValidatorType` interface that is needed for form validation to work */
validator: ValidatorType<T, S, F>;
/** The optional children for the form, if provided, it will replace the default `SubmitButton` */
children?: ReactNode;
/** The uiSchema for the form */
uiSchema?: UiSchema<T, S, F>;
/** The data for the form, used to prefill a form with existing data */
formData?: T;
/** You can provide a `formContext` object to the form, which is passed down to all fields and widgets. Useful for
* implementing context aware fields and widgets.
*
* NOTE: Setting `{readonlyAsDisabled: false}` on the formContext will make the antd theme treat readOnly fields as
* disabled.
*/
formContext?: F;
/** To avoid collisions with existing ids in the DOM, it is possible to change the prefix used for ids;
* Default is `root`
*/
idPrefix?: string;
/** To avoid using a path separator that is present in field names, it is possible to change the separator used for
* ids (Default is `_`)
*/
idSeparator?: string;
/** It's possible to disable the whole form by setting the `disabled` prop. The `disabled` prop is then forwarded down
* to each field of the form. If you just want to disable some fields, see the `ui:disabled` parameter in `uiSchema`
*/
disabled?: boolean;
/** It's possible to make the whole form read-only by setting the `readonly` prop. The `readonly` prop is then
* forwarded down to each field of the form. If you just want to make some fields read-only, see the `ui:readonly`
* parameter in `uiSchema`
*/
readonly?: boolean;
/** The dictionary of registered fields in the form */
fields?: ScaffolderRJSFRegistryFieldsType<T, S, F>;
/** The dictionary of registered templates in the form; Partial allows a subset to be provided beyond the defaults */
templates?: Partial<Omit<TemplatesType<T, S, F>, 'ButtonTemplates'>> & {
ButtonTemplates?: Partial<TemplatesType<T, S, F>['ButtonTemplates']>;
};
/** The dictionary of registered widgets in the form */
widgets?: RegistryWidgetsType<T, S, F>;
/** If you plan on being notified every time the form data are updated, you can pass an `onChange` handler, which will
* receive the same args as `onSubmit` any time a value is updated in the form. Can also return the `id` of the field
* that caused the change
*/
onChange?: (data: IChangeEvent<T, S, F>, id?: string) => void;
/** To react when submitted form data are invalid, pass an `onError` handler. It will be passed the list of
* encountered errors
*/
onError?: (errors: RJSFValidationError[]) => void;
/** You can pass a function as the `onSubmit` prop of your `Form` component to listen to when the form is submitted
* and its data are valid. It will be passed a result object having a `formData` attribute, which is the valid form
* data you're usually after. The original event will also be passed as a second parameter
*/
onSubmit?: (data: IChangeEvent<T, S, F>, event: FormEvent<any>) => void;
/** Sometimes you may want to trigger events or modify external state when a field has been touched, so you can pass
* an `onBlur` handler, which will receive the id of the input that was blurred and the field value
*/
onBlur?: (id: string, data: any) => void;
/** Sometimes you may want to trigger events or modify external state when a field has been focused, so you can pass
* an `onFocus` handler, which will receive the id of the input that is focused and the field value
*/
onFocus?: (id: string, data: any) => void;
/** The value of this prop will be passed to the `accept-charset` HTML attribute on the form */
acceptcharset?: string;
/** The value of this prop will be passed to the `action` HTML attribute on the form
*
* NOTE: this just renders the `action` attribute in the HTML markup. There is no real network request being sent to
* this `action` on submit. Instead, react-jsonschema-form catches the submit event with `event.preventDefault()`
* and then calls the `onSubmit` function, where you could send a request programmatically with `fetch` or similar.
*/
action?: string;
/** The value of this prop will be passed to the `autocomplete` HTML attribute on the form */
autoComplete?: string;
/** The value of this prop will be passed to the `class` HTML attribute on the form */
className?: string;
/** The value of this prop will be passed to the `enctype` HTML attribute on the form */
enctype?: string;
/** The value of this prop will be passed to the `id` HTML attribute on the form */
id?: string;
/** The value of this prop will be passed to the `name` HTML attribute on the form */
name?: string;
/** The value of this prop will be passed to the `method` HTML attribute on the form */
method?: string;
/** It's possible to change the default `form` tag name to a different HTML tag, which can be helpful if you are
* nesting forms. However, native browser form behaviour, such as submitting when the `Enter` key is pressed, may no
* longer work
*/
tagName?: ElementType;
/** The value of this prop will be passed to the `target` HTML attribute on the form */
target?: string;
/** Formerly the `validate` prop; Takes a function that specifies custom validation rules for the form */
customValidate?: CustomValidator<T, S, F>;
/** This prop allows passing in custom errors that are augmented with the existing JSON Schema errors on the form; it
* can be used to implement asynchronous validation
*/
extraErrors?: ErrorSchema<T>;
/** If set to true, turns off HTML5 validation on the form; Set to `false` by default */
noHtml5Validate?: boolean;
/** If set to true, turns off all validation. Set to `false` by default
*
* @deprecated - In a future release, this switch may be replaced by making `validator` prop optional
*/
noValidate?: boolean;
/** If set to true, the form will perform validation and show any validation errors whenever the form data is changed,
* rather than just on submit
*/
liveValidate?: boolean;
/** If `omitExtraData` and `liveOmit` are both set to true, then extra form data values that are not in any form field
* will be removed whenever `onChange` is called. Set to `false` by default
*/
liveOmit?: boolean;
/** If set to true, then extra form data values that are not in any form field will be removed whenever `onSubmit` is
* called. Set to `false` by default.
*/
omitExtraData?: boolean;
/** When this prop is set to `top` or 'bottom', a list of errors (or the custom error list defined in the `ErrorList`) will also
* show. When set to false, only inline input validation errors will be shown. Set to `top` by default
*/
showErrorList?: false | 'top' | 'bottom';
/** A function can be passed to this prop in order to make modifications to the default errors resulting from JSON
* Schema validation
*/
transformErrors?: ErrorTransformer<T, S, F>;
/** If set to true, then the first field with an error will receive the focus when the form is submitted with errors
*/
focusOnFirstError?: boolean | ((error: RJSFValidationError) => void);
/** Optional string translation function, if provided, allows users to change the translation of the RJSF internal
* strings. Some strings contain replaceable parameter values as indicated by `%1`, `%2`, etc. The number after the
* `%` indicates the order of the parameter. The ordering of parameters is important because some languages may choose
* to put the second parameter before the first in its translation.
*/
translateString?: Registry['translateString'];
/** Optional configuration object with flags, if provided, allows users to override default form state behavior
* Currently only affecting minItems on array fields and handling of setting defaults based on the value of
* `emptyObjectFields`
*/
experimental_defaultFormStateBehavior?: Experimental_DefaultFormStateBehavior;
/**
* _internalFormWrapper is currently used by the semantic-ui theme to provide a custom wrapper around `<Form />`
* that supports the proper rendering of those themes. To use this prop, one must pass a component that takes two
* props: `children` and `as`. That component, at minimum, should render the `children` inside of a <form /> tag
* unless `as` is provided, in which case, use the `as` prop in place of `<form />`.
* i.e.:
* ```
* export default function InternalForm({ children, as }) {
* const FormTag = as || 'form';
* return <FormTag>{children}</FormTag>;
* }
* ```
*
* Use at your own risk as this prop is private and may change at any time without notice.
*/
_internalFormWrapper?: ElementType;
/** Support receiving a React ref to the Form
*/
ref?: Ref<Form<T, S, F>>;
}
/**
* The set of `Fields` stored in the `Registry`
* @public
*/
export type ScaffolderRJSFRegistryFieldsType<
T = any,
S extends StrictRJSFSchema = RJSFSchema,
F extends FormContextType = any,
> = {
/** A `Field` indexed by `name` */
[name: string]: ScaffolderRJSFField<T, S, F>;
};
/**
* The `Field` type for Field Extensions
* @public
*/
export type ScaffolderRJSFField<
T = any,
S extends StrictRJSFSchema = RJSFSchema,
F extends FormContextType = any,
> = ComponentType<ScaffolderRJSFFieldProps<T, S, F>>;
@@ -14,19 +14,23 @@
* limitations under the License.
*/
import { ApiHolder } from '@backstage/core-plugin-api';
import { FieldValidation, FieldProps } from '@rjsf/core';
import { PropsWithChildren } from 'react';
import { JsonObject } from '@backstage/types';
import { JSONSchema7 } from 'json-schema';
import { UiSchema, UIOptionsType, FieldValidation } from '@rjsf/utils';
import { ScaffolderRJSFFieldProps } from './rjsf';
/**
* Field validation type for Custom Field Extensions.
* Type for Field Extension Props for RJSF v5
*
* @public
*/
export type CustomFieldValidator<TFieldReturnValue> = (
data: TFieldReturnValue,
field: FieldValidation,
context: { apiHolder: ApiHolder },
) => void | Promise<void>;
export interface FieldExtensionComponentProps<
TFieldReturnValue,
TUiOptions = {},
> extends PropsWithChildren<ScaffolderRJSFFieldProps<TFieldReturnValue>> {
uiSchema: FieldExtensionUiSchema<TFieldReturnValue, TUiOptions>;
}
/**
* Type for the Custom Field Extension schema.
@@ -38,6 +42,32 @@ export type CustomFieldExtensionSchema = {
uiOptions?: JSONSchema7;
};
/**
* Type for Field Extension UiSchema
*
* @public
*/
export interface FieldExtensionUiSchema<TFieldReturnValue, TUiOptions>
extends UiSchema<TFieldReturnValue> {
'ui:options'?: TUiOptions & UIOptionsType<TFieldReturnValue>;
}
/**
* Field validation type for Custom Field Extensions.
*
* @public
*/
export type CustomFieldValidator<TFieldReturnValue, TUiOptions = unknown> = (
data: TFieldReturnValue,
field: FieldValidation,
context: {
apiHolder: ApiHolder;
formData: JsonObject;
schema: JsonObject;
uiSchema?: FieldExtensionUiSchema<TFieldReturnValue, TUiOptions>;
},
) => void | Promise<void>;
/**
* Type for the Custom Field Extension with the
* name and components and validation function.
@@ -46,27 +76,12 @@ export type CustomFieldExtensionSchema = {
*/
export type FieldExtensionOptions<
TFieldReturnValue = unknown,
TInputProps = unknown,
TUiOptions = unknown,
> = {
name: string;
component: (
props: FieldExtensionComponentProps<TFieldReturnValue, TInputProps>,
props: FieldExtensionComponentProps<TFieldReturnValue, TUiOptions>,
) => JSX.Element | null;
validation?: CustomFieldValidator<TFieldReturnValue>;
validation?: CustomFieldValidator<TFieldReturnValue, TUiOptions>;
schema?: CustomFieldExtensionSchema;
};
/**
* Type for field extensions and being able to type
* incoming props easier.
*
* @public
*/
export interface FieldExtensionComponentProps<
TFieldReturnValue,
TUiOptions = unknown,
> extends FieldProps<TFieldReturnValue> {
uiSchema: FieldProps['uiSchema'] & {
'ui:options'?: TUiOptions;
};
}
@@ -15,26 +15,24 @@
*/
import {
NextCustomFieldValidator,
NextFieldExtensionOptions,
NextFieldExtensionComponentProps,
NextFieldExtensionUiSchema,
CustomFieldValidator,
FieldExtensionOptions,
FieldExtensionComponentProps,
} from './types';
import { Extension, attachComponentData } from '@backstage/core-plugin-api';
import { UIOptionsType } from '@rjsf/utils';
import { FIELD_EXTENSION_KEY } from '../../extensions/keys';
import { FieldExtensionComponent } from '@backstage/plugin-scaffolder-react';
import { FieldExtensionComponent } from '../../extensions';
/**
* Method for creating field extensions that can be used in the scaffolder
* frontend form.
* @alpha
*/
export function createNextScaffolderFieldExtension<
export function createLegacyScaffolderFieldExtension<
TReturnValue = unknown,
TInputProps extends UIOptionsType = {},
TInputProps = unknown,
>(
options: NextFieldExtensionOptions<TReturnValue, TInputProps>,
options: FieldExtensionOptions<TReturnValue, TInputProps>,
): Extension<FieldExtensionComponent<TReturnValue, TInputProps>> {
return {
expose() {
@@ -52,8 +50,7 @@ export function createNextScaffolderFieldExtension<
}
export type {
NextCustomFieldValidator,
NextFieldExtensionOptions,
NextFieldExtensionComponentProps,
NextFieldExtensionUiSchema,
CustomFieldValidator,
FieldExtensionOptions,
FieldExtensionComponentProps,
};
@@ -0,0 +1,62 @@
/*
* Copyright 2021 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ApiHolder } from '@backstage/core-plugin-api';
import { FieldValidation, FieldProps } from '@rjsf/core';
import { CustomFieldExtensionSchema } from '../../extensions/types';
/**
* Field validation type for Custom Field Extensions.
*
* @alpha
*/
export type CustomFieldValidator<TFieldReturnValue> = (
data: TFieldReturnValue,
field: FieldValidation,
context: { apiHolder: ApiHolder },
) => void | Promise<void>;
/**
* Type for the Custom Field Extension with the
* name and components and validation function.
*
* @alpha
*/
export type FieldExtensionOptions<
TFieldReturnValue = unknown,
TInputProps = unknown,
> = {
name: string;
component: (
props: FieldExtensionComponentProps<TFieldReturnValue, TInputProps>,
) => JSX.Element | null;
validation?: CustomFieldValidator<TFieldReturnValue>;
schema?: CustomFieldExtensionSchema;
};
/**
* Type for field extensions and being able to type
* incoming props easier.
*
* @alpha
*/
export interface FieldExtensionComponentProps<
TFieldReturnValue,
TUiOptions = unknown,
> extends FieldProps<TFieldReturnValue> {
uiSchema: FieldProps['uiSchema'] & {
'ui:options'?: TUiOptions;
};
}
@@ -0,0 +1,16 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export * from './extensions';
@@ -19,6 +19,7 @@ import React from 'react';
import { PropsWithChildren } from 'react';
import { FieldTemplate } from './FieldTemplate';
import { DescriptionFieldTemplate } from './DescriptionFieldTemplate';
import { FieldProps } from '@rjsf/utils';
// TODO(blam): We require here, as the types in this package depend on @rjsf/core explicitly
// which is what we're using here as the default types, it needs to depend on @rjsf/core-v5 because
@@ -30,10 +31,31 @@ const WrappedForm = withTheme(require('@rjsf/material-ui-v5').Theme);
* @alpha
*/
export const Form = (props: PropsWithChildren<FormProps>) => {
// This is where we unbreak the changes from RJSF, and make it work with our custom fields so we don't pass on this
// breaking change to our users. We will look more into a better API for this in scaffolderv2.
const wrappedFields = Object.fromEntries(
Object.entries(props.fields ?? {}).map(([key, Component]) => [
key,
(wrapperProps: FieldProps) => {
return (
<Component
{...wrapperProps}
uiSchema={wrapperProps.uiSchema ?? {}}
formData={wrapperProps.formData ?? {}}
rawErrors={wrapperProps.rawErrors ?? []}
/>
);
},
]),
);
const templates = {
FieldTemplate,
DescriptionFieldTemplate,
...props.templates,
};
return <WrappedForm {...props} templates={templates} />;
return (
<WrappedForm {...props} templates={templates} fields={wrappedFields} />
);
};
@@ -20,7 +20,7 @@ import { renderInTestApp } from '@backstage/test-utils';
import { act, fireEvent } from '@testing-library/react';
import type { RJSFValidationError } from '@rjsf/utils';
import { JsonValue } from '@backstage/types';
import { NextFieldExtensionComponentProps } from '../../extensions';
import { NextFieldExtensionComponentProps } from '../../../extensions';
import { LayoutTemplate } from '../../../layouts';
describe('Stepper', () => {
@@ -26,7 +26,7 @@ import {
import { type IChangeEvent } from '@rjsf/core-v5';
import { ErrorSchema } from '@rjsf/utils';
import React, { useCallback, useMemo, useState, type ReactNode } from 'react';
import { NextFieldExtensionOptions } from '../../extensions';
import { NextFieldExtensionOptions } from '../../../extensions';
import {
createAsyncValidators,
type FormValidation,
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { JsonObject } from '@backstage/types';
import { NextCustomFieldValidator } from '../../extensions';
import { NextCustomFieldValidator } from '../../../extensions';
import { createAsyncValidators } from './createAsyncValidators';
describe('createAsyncValidators', () => {
@@ -19,7 +19,7 @@ import type { JsonObject, JsonValue } from '@backstage/types';
import { ApiHolder } from '@backstage/core-plugin-api';
import { Draft07 as JSONSchema } from 'json-schema-library';
import { createFieldValidation, extractSchemaFromStep } from '../../lib';
import { NextCustomFieldValidator } from '../../extensions';
import { NextCustomFieldValidator } from '../../../extensions';
import { isObject } from './utils';
import { NextFieldExtensionUiSchema } from '../../extensions/types';
@@ -1,84 +0,0 @@
/*
* Copyright 2021 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ApiHolder } from '@backstage/core-plugin-api';
import {
UIOptionsType,
FieldProps as FieldPropsV5,
UiSchema as UiSchemaV5,
FieldValidation as FieldValidationV5,
} from '@rjsf/utils';
import { PropsWithChildren } from 'react';
import { JsonObject } from '@backstage/types';
import { CustomFieldExtensionSchema } from '@backstage/plugin-scaffolder-react';
/**
* Type for Field Extension Props for RJSF v5
*
* @alpha
*/
export interface NextFieldExtensionComponentProps<
TFieldReturnValue,
TUiOptions = {},
> extends PropsWithChildren<FieldPropsV5<TFieldReturnValue>> {
uiSchema?: NextFieldExtensionUiSchema<TFieldReturnValue, TUiOptions>;
}
/**
* Type for Field Extension UiSchema
*
* @alpha
*/
export interface NextFieldExtensionUiSchema<TFieldReturnValue, TUiOptions>
extends UiSchemaV5<TFieldReturnValue> {
'ui:options'?: TUiOptions & UIOptionsType;
}
/**
* Field validation type for Custom Field Extensions.
*
* @alpha
*/
export type NextCustomFieldValidator<
TFieldReturnValue,
TUiOptions = unknown,
> = (
data: TFieldReturnValue,
field: FieldValidationV5,
context: {
apiHolder: ApiHolder;
formData: JsonObject;
schema: JsonObject;
uiSchema?: NextFieldExtensionUiSchema<TFieldReturnValue, TUiOptions>;
},
) => void | Promise<void>;
/**
* Type for the Custom Field Extension with the
* name and components and validation function.
*
* @alpha
*/
export type NextFieldExtensionOptions<
TFieldReturnValue = unknown,
TUiOptions = unknown,
> = {
name: string;
component: (
props: NextFieldExtensionComponentProps<TFieldReturnValue, TUiOptions>,
) => JSX.Element | null;
validation?: NextCustomFieldValidator<TFieldReturnValue, TUiOptions>;
schema?: CustomFieldExtensionSchema;
};
@@ -14,7 +14,6 @@
* limitations under the License.
*/
export * from './components';
export * from './extensions';
export * from './types';
export * from './lib';
export * from './hooks';