diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0c4f19f344..865916d4ad 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -45,6 +45,7 @@ should change the heading of the (upcoming) version to include a major version b
## @rjsf/fluent-ui
- Updated the usage of the `ButtonTemplates` to pass the new required `registry` prop, filtering it out in the actual implementations before spreading props, fixing - [#3314](https://github.com/rjsf-team/react-jsonschema-form/issues/3314)
- Updated the test for the `CheckboxWidget` validating that the `schema.title` is passed as the label, fixing [#3302](https://github.com/rjsf-team/react-jsonschema-form/issues/3302)
+- Updated the theme to accept generic types, exporting `generateXXX` functions for `Form`, `Theme`, `Templates` and `Widgets` to support using the theme with user-specified type generics, partially fixing [#3072](https://github.com/rjsf-team/react-jsonschema-form/issues/3072)
## @rjsf/material-ui
- Updated the usage of the `ButtonTemplates` to pass the new required `registry` prop, filtering it out in the actual implementations before spreading props, fixing - [#3314](https://github.com/rjsf-team/react-jsonschema-form/issues/3314)
diff --git a/packages/fluent-ui/src/AddButton/AddButton.tsx b/packages/fluent-ui/src/AddButton/AddButton.tsx
index 9768974763..66b3e21f7d 100644
--- a/packages/fluent-ui/src/AddButton/AddButton.tsx
+++ b/packages/fluent-ui/src/AddButton/AddButton.tsx
@@ -1,18 +1,27 @@
import React from "react";
-import { IconButtonProps } from "@rjsf/utils";
+import {
+ FormContextType,
+ IconButtonProps,
+ RJSFSchema,
+ StrictRJSFSchema,
+} from "@rjsf/utils";
import { IIconProps, CommandBarButton } from "@fluentui/react";
const addIcon: IIconProps = { iconName: "Add" };
-const AddButton = (props: IconButtonProps) => (
-
-);
-
-export default AddButton;
+export default function AddButton<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>(props: IconButtonProps) {
+ return (
+
+ );
+}
diff --git a/packages/fluent-ui/src/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx b/packages/fluent-ui/src/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx
index 021def7afa..425d907b21 100644
--- a/packages/fluent-ui/src/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx
+++ b/packages/fluent-ui/src/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx
@@ -1,7 +1,16 @@
import React from "react";
-import { ArrayFieldTemplateItemType } from "@rjsf/utils";
+import {
+ ArrayFieldTemplateItemType,
+ FormContextType,
+ RJSFSchema,
+ StrictRJSFSchema,
+} from "@rjsf/utils";
-const ArrayFieldItemTemplate = (props: ArrayFieldTemplateItemType) => {
+export default function ArrayFieldItemTemplate<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>(props: ArrayFieldTemplateItemType) {
const {
children,
disabled,
@@ -58,6 +67,4 @@ const ArrayFieldItemTemplate = (props: ArrayFieldTemplateItemType) => {
);
-};
-
-export default ArrayFieldItemTemplate;
+}
diff --git a/packages/fluent-ui/src/ArrayFieldTemplate/ArrayFieldTemplate.tsx b/packages/fluent-ui/src/ArrayFieldTemplate/ArrayFieldTemplate.tsx
index a88d0adc88..7f3f25a5eb 100644
--- a/packages/fluent-ui/src/ArrayFieldTemplate/ArrayFieldTemplate.tsx
+++ b/packages/fluent-ui/src/ArrayFieldTemplate/ArrayFieldTemplate.tsx
@@ -4,13 +4,20 @@ import {
getUiOptions,
ArrayFieldTemplateItemType,
ArrayFieldTemplateProps,
+ StrictRJSFSchema,
+ RJSFSchema,
+ FormContextType,
} from "@rjsf/utils";
const rightJustify = {
float: "right",
} as React.CSSProperties;
-const ArrayFieldTemplate = (props: ArrayFieldTemplateProps) => {
+export default function ArrayFieldTemplate<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>(props: ArrayFieldTemplateProps) {
const {
canAdd,
disabled,
@@ -24,23 +31,24 @@ const ArrayFieldTemplate = (props: ArrayFieldTemplateProps) => {
schema,
title,
} = props;
- const uiOptions = getUiOptions(uiSchema);
- const ArrayFieldDescriptionTemplate =
- getTemplate<"ArrayFieldDescriptionTemplate">(
- "ArrayFieldDescriptionTemplate",
- registry,
- uiOptions
- );
- const ArrayFieldItemTemplate = getTemplate<"ArrayFieldItemTemplate">(
+ const uiOptions = getUiOptions(uiSchema);
+ const ArrayFieldDescriptionTemplate = getTemplate<
+ "ArrayFieldDescriptionTemplate",
+ T,
+ S,
+ F
+ >("ArrayFieldDescriptionTemplate", registry, uiOptions);
+ const ArrayFieldItemTemplate = getTemplate<"ArrayFieldItemTemplate", T, S, F>(
"ArrayFieldItemTemplate",
registry,
uiOptions
);
- const ArrayFieldTitleTemplate = getTemplate<"ArrayFieldTitleTemplate">(
+ const ArrayFieldTitleTemplate = getTemplate<
"ArrayFieldTitleTemplate",
- registry,
- uiOptions
- );
+ T,
+ S,
+ F
+ >("ArrayFieldTitleTemplate", registry, uiOptions);
// Button templates are not overridden in the uiSchema
const {
ButtonTemplates: { AddButton },
@@ -63,9 +71,11 @@ const ArrayFieldTemplate = (props: ArrayFieldTemplateProps) => {
registry={registry}
/>
{items.length > 0 &&
- items.map(({ key, ...itemProps }: ArrayFieldTemplateItemType) => (
-
- ))}
+ items.map(
+ ({ key, ...itemProps }: ArrayFieldTemplateItemType) => (
+
+ )
+ )}
{canAdd && (
{
)}
>
);
-};
-
-export default ArrayFieldTemplate;
+}
diff --git a/packages/fluent-ui/src/BaseInputTemplate/BaseInputTemplate.tsx b/packages/fluent-ui/src/BaseInputTemplate/BaseInputTemplate.tsx
index c71f93566e..2cc9e233d8 100644
--- a/packages/fluent-ui/src/BaseInputTemplate/BaseInputTemplate.tsx
+++ b/packages/fluent-ui/src/BaseInputTemplate/BaseInputTemplate.tsx
@@ -1,6 +1,12 @@
import React from "react";
import { TextField } from "@fluentui/react";
-import { getInputProps, WidgetProps } from "@rjsf/utils";
+import {
+ FormContextType,
+ getInputProps,
+ RJSFSchema,
+ StrictRJSFSchema,
+ WidgetProps,
+} from "@rjsf/utils";
import _pick from "lodash/pick";
// Keys of ITextFieldProps from @fluentui/react
@@ -44,7 +50,11 @@ const allowedProps = [
"list",
];
-const BaseInputTemplate = ({
+export default function BaseInputTemplate<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>({
id,
placeholder,
required,
@@ -61,8 +71,8 @@ const BaseInputTemplate = ({
type,
rawErrors,
multiline,
-}: WidgetProps) => {
- const inputProps = getInputProps(schema, type, options);
+}: WidgetProps) {
+ const inputProps = getInputProps(schema, type, options);
const _onChange = ({
target: { value },
}: React.ChangeEvent) =>
@@ -109,6 +119,4 @@ const BaseInputTemplate = ({
)}
>
);
-};
-
-export default BaseInputTemplate;
+}
diff --git a/packages/fluent-ui/src/CheckboxWidget/CheckboxWidget.tsx b/packages/fluent-ui/src/CheckboxWidget/CheckboxWidget.tsx
index f8d86c7ef8..94dd6fe0f3 100644
--- a/packages/fluent-ui/src/CheckboxWidget/CheckboxWidget.tsx
+++ b/packages/fluent-ui/src/CheckboxWidget/CheckboxWidget.tsx
@@ -1,6 +1,11 @@
import React from "react";
import { Checkbox } from "@fluentui/react";
-import { WidgetProps } from "@rjsf/utils";
+import {
+ FormContextType,
+ RJSFSchema,
+ StrictRJSFSchema,
+ WidgetProps,
+} from "@rjsf/utils";
import _pick from "lodash/pick";
// Keys of ICheckboxProps from @fluentui/react
@@ -27,7 +32,11 @@ export const allowedProps = [
"theme",
];
-const CheckboxWidget = (props: WidgetProps) => {
+export default function CheckboxWidget<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>(props: WidgetProps) {
const {
id,
value,
@@ -75,6 +84,4 @@ const CheckboxWidget = (props: WidgetProps) => {
/>
>
);
-};
-
-export default CheckboxWidget;
+}
diff --git a/packages/fluent-ui/src/CheckboxesWidget/CheckboxesWidget.tsx b/packages/fluent-ui/src/CheckboxesWidget/CheckboxesWidget.tsx
index 8f74121537..57d2cd507f 100644
--- a/packages/fluent-ui/src/CheckboxesWidget/CheckboxesWidget.tsx
+++ b/packages/fluent-ui/src/CheckboxesWidget/CheckboxesWidget.tsx
@@ -1,6 +1,11 @@
import React from "react";
import { Checkbox, Label } from "@fluentui/react";
-import { WidgetProps } from "@rjsf/utils";
+import {
+ FormContextType,
+ RJSFSchema,
+ StrictRJSFSchema,
+ WidgetProps,
+} from "@rjsf/utils";
import { allowedProps } from "../CheckboxWidget";
import _pick from "lodash/pick";
@@ -25,7 +30,11 @@ const deselectValue = (value: any, selected: any) => {
return selected.filter((v: any) => v !== value);
};
-const CheckboxesWidget = ({
+export default function CheckboxesWidget<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>({
schema,
label,
id,
@@ -39,7 +48,7 @@ const CheckboxesWidget = ({
onBlur,
onFocus,
rawErrors = [],
-}: WidgetProps) => {
+}: WidgetProps) {
const { enumOptions, enumDisabled } = options;
const _onChange =
@@ -95,6 +104,4 @@ const CheckboxesWidget = ({
{(rawErrors || []).join("\n")}
>
);
-};
-
-export default CheckboxesWidget;
+}
diff --git a/packages/fluent-ui/src/ColorWidget/ColorWidget.tsx b/packages/fluent-ui/src/ColorWidget/ColorWidget.tsx
index 3ae6686ff4..08380b78a9 100644
--- a/packages/fluent-ui/src/ColorWidget/ColorWidget.tsx
+++ b/packages/fluent-ui/src/ColorWidget/ColorWidget.tsx
@@ -6,7 +6,12 @@ import {
getColorFromString,
Label,
} from "@fluentui/react";
-import { WidgetProps } from "@rjsf/utils";
+import {
+ FormContextType,
+ RJSFSchema,
+ StrictRJSFSchema,
+ WidgetProps,
+} from "@rjsf/utils";
import _pick from "lodash/pick";
const styles_red = {
@@ -35,14 +40,11 @@ const allowedProps: (keyof IColorPickerProps)[] = [
"showPreview",
];
-const ColorWidget = ({
- schema,
- options,
- value,
- required,
- label,
- onChange,
-}: WidgetProps) => {
+export default function ColorWidget<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>({ schema, options, value, required, label, onChange }: WidgetProps) {
const updateColor = (_ev: any, colorObj: IColor) => {
onChange(colorObj.hex);
};
@@ -64,5 +66,4 @@ const ColorWidget = ({
/>
>
);
-};
-export default ColorWidget;
+}
diff --git a/packages/fluent-ui/src/DateTimeWidget/DateTimeWidget.tsx b/packages/fluent-ui/src/DateTimeWidget/DateTimeWidget.tsx
index bf6ef42da9..b92f9fc2b2 100644
--- a/packages/fluent-ui/src/DateTimeWidget/DateTimeWidget.tsx
+++ b/packages/fluent-ui/src/DateTimeWidget/DateTimeWidget.tsx
@@ -1,8 +1,20 @@
import React from "react";
-import { WidgetProps, getTemplate, localToUTC, utcToLocal } from "@rjsf/utils";
+import {
+ WidgetProps,
+ getTemplate,
+ localToUTC,
+ utcToLocal,
+ StrictRJSFSchema,
+ RJSFSchema,
+ FormContextType,
+} from "@rjsf/utils";
-const DateTimeWidget = (props: WidgetProps) => {
+export default function DateTimeWidget<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>(props: WidgetProps) {
const { registry } = props;
const uiProps: any = props.options["props"] || {};
const options = {
@@ -12,7 +24,7 @@ const DateTimeWidget = (props: WidgetProps) => {
...uiProps,
},
};
- const BaseInputTemplate = getTemplate<"BaseInputTemplate">(
+ const BaseInputTemplate = getTemplate<"BaseInputTemplate", T, S, F>(
"BaseInputTemplate",
registry,
options
@@ -31,6 +43,4 @@ const DateTimeWidget = (props: WidgetProps) => {
onChange={onChange}
/>
);
-};
-
-export default DateTimeWidget;
+}
diff --git a/packages/fluent-ui/src/DateWidget/DateWidget.tsx b/packages/fluent-ui/src/DateWidget/DateWidget.tsx
index 3a6fd01fd4..2295b5e07b 100644
--- a/packages/fluent-ui/src/DateWidget/DateWidget.tsx
+++ b/packages/fluent-ui/src/DateWidget/DateWidget.tsx
@@ -1,5 +1,11 @@
import React from "react";
-import { WidgetProps, pad } from "@rjsf/utils";
+import {
+ WidgetProps,
+ pad,
+ StrictRJSFSchema,
+ RJSFSchema,
+ FormContextType,
+} from "@rjsf/utils";
import { DatePicker, DayOfWeek, mergeStyleSets } from "@fluentui/react";
import _pick from "lodash/pick";
@@ -75,7 +81,11 @@ const parseDate = (dateStr?: string) => {
return dt;
};
-const DateWidget = ({
+export default function DateWidget<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>({
id,
required,
label,
@@ -85,7 +95,7 @@ const DateWidget = ({
onFocus,
options,
placeholder,
-}: WidgetProps) => {
+}: WidgetProps) {
const _onSelectDate = (date: Date | null | undefined) => {
if (date) {
const formatted = formatDate(date);
@@ -115,6 +125,4 @@ const DateWidget = ({
{...uiProps}
/>
);
-};
-
-export default DateWidget;
+}
diff --git a/packages/fluent-ui/src/DescriptionField/DescriptionField.tsx b/packages/fluent-ui/src/DescriptionField/DescriptionField.tsx
index 71190d0bfb..c7f8eab79b 100644
--- a/packages/fluent-ui/src/DescriptionField/DescriptionField.tsx
+++ b/packages/fluent-ui/src/DescriptionField/DescriptionField.tsx
@@ -1,13 +1,20 @@
import React from "react";
-import { DescriptionFieldProps } from "@rjsf/utils";
+import {
+ DescriptionFieldProps,
+ FormContextType,
+ RJSFSchema,
+ StrictRJSFSchema,
+} from "@rjsf/utils";
import { Text } from "@fluentui/react";
-const DescriptionField = ({ description, id }: DescriptionFieldProps) => {
+export default function DescriptionField<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>({ description, id }: DescriptionFieldProps) {
if (description) {
return {description};
}
return null;
-};
-
-export default DescriptionField;
+}
diff --git a/packages/fluent-ui/src/ErrorList/ErrorList.tsx b/packages/fluent-ui/src/ErrorList/ErrorList.tsx
index 94b9d345ea..43edfc49cb 100644
--- a/packages/fluent-ui/src/ErrorList/ErrorList.tsx
+++ b/packages/fluent-ui/src/ErrorList/ErrorList.tsx
@@ -1,22 +1,31 @@
import React from "react";
import { MessageBar, MessageBarType } from "@fluentui/react";
-import { ErrorListProps } from "@rjsf/utils";
+import {
+ ErrorListProps,
+ FormContextType,
+ RJSFSchema,
+ StrictRJSFSchema,
+} from "@rjsf/utils";
-const ErrorList = ({ errors }: ErrorListProps) => (
- <>
- {errors.map((error, i) => {
- return (
-
- {error.stack}
-
- );
- })}
- >
-);
-
-export default ErrorList;
+export default function ErrorList<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>({ errors }: ErrorListProps) {
+ return (
+ <>
+ {errors.map((error, i) => {
+ return (
+
+ {error.stack}
+
+ );
+ })}
+ >
+ );
+}
diff --git a/packages/fluent-ui/src/FieldErrorTemplate/FieldErrorTemplate.tsx b/packages/fluent-ui/src/FieldErrorTemplate/FieldErrorTemplate.tsx
index f59e0896ec..c3c6a842f4 100644
--- a/packages/fluent-ui/src/FieldErrorTemplate/FieldErrorTemplate.tsx
+++ b/packages/fluent-ui/src/FieldErrorTemplate/FieldErrorTemplate.tsx
@@ -1,12 +1,21 @@
import React from "react";
-import { FieldErrorProps } from "@rjsf/utils";
+import {
+ FieldErrorProps,
+ FormContextType,
+ RJSFSchema,
+ StrictRJSFSchema,
+} from "@rjsf/utils";
import { List } from "@fluentui/react";
/** The `FieldErrorTemplate` component renders the errors local to the particular field
*
* @param props - The `FieldErrorProps` for the errors being rendered
*/
-export default function FieldErrorTemplate(props: FieldErrorProps) {
+export default function FieldErrorTemplate<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>(props: FieldErrorProps) {
const { errors = [], idSchema } = props;
if (errors.length === 0) {
return null;
diff --git a/packages/fluent-ui/src/FieldHelpTemplate/FieldHelpTemplate.tsx b/packages/fluent-ui/src/FieldHelpTemplate/FieldHelpTemplate.tsx
index 13980e2e47..244e51fad9 100644
--- a/packages/fluent-ui/src/FieldHelpTemplate/FieldHelpTemplate.tsx
+++ b/packages/fluent-ui/src/FieldHelpTemplate/FieldHelpTemplate.tsx
@@ -1,12 +1,21 @@
import React from "react";
-import { FieldHelpProps } from "@rjsf/utils";
+import {
+ FieldHelpProps,
+ FormContextType,
+ RJSFSchema,
+ StrictRJSFSchema,
+} from "@rjsf/utils";
import { Text } from "@fluentui/react";
/** The `FieldHelpTemplate` component renders any help desired for a field
*
* @param props - The `FieldHelpProps` to be rendered
*/
-export default function FieldHelpTemplate(props: FieldHelpProps) {
+export default function FieldHelpTemplate<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>(props: FieldHelpProps) {
const { idSchema, help } = props;
if (!help) {
return null;
diff --git a/packages/fluent-ui/src/FieldTemplate/FieldTemplate.tsx b/packages/fluent-ui/src/FieldTemplate/FieldTemplate.tsx
index 83a302e9c7..a6dde0890a 100644
--- a/packages/fluent-ui/src/FieldTemplate/FieldTemplate.tsx
+++ b/packages/fluent-ui/src/FieldTemplate/FieldTemplate.tsx
@@ -1,8 +1,19 @@
import React from "react";
-import { FieldTemplateProps, getTemplate, getUiOptions } from "@rjsf/utils";
+import {
+ FieldTemplateProps,
+ FormContextType,
+ getTemplate,
+ getUiOptions,
+ RJSFSchema,
+ StrictRJSFSchema,
+} from "@rjsf/utils";
import { Text } from "@fluentui/react";
-const FieldTemplate = (props: FieldTemplateProps) => {
+export default function FieldTemplate<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>(props: FieldTemplateProps) {
const {
id,
children,
@@ -13,12 +24,13 @@ const FieldTemplate = (props: FieldTemplateProps) => {
uiSchema,
registry,
} = props;
- const uiOptions = getUiOptions(uiSchema);
- const WrapIfAdditionalTemplate = getTemplate<"WrapIfAdditionalTemplate">(
+ const uiOptions = getUiOptions(uiSchema);
+ const WrapIfAdditionalTemplate = getTemplate<
"WrapIfAdditionalTemplate",
- registry,
- uiOptions
- );
+ T,
+ S,
+ F
+ >("WrapIfAdditionalTemplate", registry, uiOptions);
// TODO: do this better by not returning the form-group class from master.
let { classNames = "" } = props;
classNames = "ms-Grid-col ms-sm12 " + classNames.replace("form-group", "");
@@ -36,6 +48,4 @@ const FieldTemplate = (props: FieldTemplateProps) => {
);
-};
-
-export default FieldTemplate;
+}
diff --git a/packages/fluent-ui/src/FuiForm/FuiForm.ts b/packages/fluent-ui/src/FuiForm/FuiForm.ts
new file mode 100644
index 0000000000..8db1a897f5
--- /dev/null
+++ b/packages/fluent-ui/src/FuiForm/FuiForm.ts
@@ -0,0 +1,15 @@
+import { ComponentType } from "react";
+import { FormProps, withTheme } from "@rjsf/core";
+
+import { generateTheme } from "../Theme";
+import { FormContextType, RJSFSchema, StrictRJSFSchema } from "@rjsf/utils";
+
+export function generateForm<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>(): ComponentType> {
+ return withTheme(generateTheme());
+}
+
+export default generateForm();
diff --git a/packages/fluent-ui/src/FuiForm/FuiForm.tsx b/packages/fluent-ui/src/FuiForm/FuiForm.tsx
deleted file mode 100644
index 3c85392e75..0000000000
--- a/packages/fluent-ui/src/FuiForm/FuiForm.tsx
+++ /dev/null
@@ -1,8 +0,0 @@
-import { ComponentType } from "react";
-import { withTheme, FormProps } from "@rjsf/core";
-
-import Theme from "../Theme";
-
-const FuiForm: ComponentType = withTheme(Theme);
-
-export default FuiForm;
diff --git a/packages/fluent-ui/src/IconButton/IconButton.tsx b/packages/fluent-ui/src/IconButton/IconButton.tsx
index ac114550d1..ff1565f463 100644
--- a/packages/fluent-ui/src/IconButton/IconButton.tsx
+++ b/packages/fluent-ui/src/IconButton/IconButton.tsx
@@ -1,8 +1,17 @@
import React from "react";
import { IconButton, IIconProps } from "@fluentui/react";
-import { IconButtonProps } from "@rjsf/utils";
+import {
+ FormContextType,
+ IconButtonProps,
+ RJSFSchema,
+ StrictRJSFSchema,
+} from "@rjsf/utils";
-export default function FluentIconButton(props: IconButtonProps) {
+export default function FluentIconButton<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>(props: IconButtonProps) {
const iconProps: IIconProps = {
iconName: props.icon as string,
};
@@ -17,14 +26,26 @@ export default function FluentIconButton(props: IconButtonProps) {
);
}
-export function MoveDownButton(props: IconButtonProps) {
- return ;
+export function MoveDownButton<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>(props: IconButtonProps) {
+ return title="Move down" {...props} icon="Down" />;
}
-export function MoveUpButton(props: IconButtonProps) {
- return ;
+export function MoveUpButton<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>(props: IconButtonProps) {
+ return title="Move up" {...props} icon="Up" />;
}
-export function RemoveButton(props: IconButtonProps) {
- return ;
+export function RemoveButton<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>(props: IconButtonProps) {
+ return title="Remove" {...props} icon="Delete" />;
}
diff --git a/packages/fluent-ui/src/ObjectFieldTemplate/ObjectFieldTemplate.tsx b/packages/fluent-ui/src/ObjectFieldTemplate/ObjectFieldTemplate.tsx
index 2dc176cd21..25f25b5bab 100644
--- a/packages/fluent-ui/src/ObjectFieldTemplate/ObjectFieldTemplate.tsx
+++ b/packages/fluent-ui/src/ObjectFieldTemplate/ObjectFieldTemplate.tsx
@@ -1,11 +1,18 @@
import React from "react";
import {
+ FormContextType,
getTemplate,
getUiOptions,
ObjectFieldTemplateProps,
+ RJSFSchema,
+ StrictRJSFSchema,
} from "@rjsf/utils";
-const ObjectFieldTemplate = ({
+export default function ObjectFieldTemplate<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>({
description,
title,
properties,
@@ -14,18 +21,19 @@ const ObjectFieldTemplate = ({
uiSchema,
idSchema,
registry,
-}: ObjectFieldTemplateProps) => {
- const uiOptions = getUiOptions(uiSchema);
- const TitleFieldTemplate = getTemplate<"TitleFieldTemplate">(
+}: ObjectFieldTemplateProps) {
+ const uiOptions = getUiOptions(uiSchema);
+ const TitleFieldTemplate = getTemplate<"TitleFieldTemplate", T, S, F>(
"TitleFieldTemplate",
registry,
uiOptions
);
- const DescriptionFieldTemplate = getTemplate<"DescriptionFieldTemplate">(
+ const DescriptionFieldTemplate = getTemplate<
"DescriptionFieldTemplate",
- registry,
- uiOptions
- );
+ T,
+ S,
+ F
+ >("DescriptionFieldTemplate", registry, uiOptions);
return (
<>
{(uiOptions.title || title) && (
@@ -54,6 +62,4 @@ const ObjectFieldTemplate = ({
>
);
-};
-
-export default ObjectFieldTemplate;
+}
diff --git a/packages/fluent-ui/src/RadioWidget/RadioWidget.tsx b/packages/fluent-ui/src/RadioWidget/RadioWidget.tsx
index bd22a2d096..21b8cf7ef4 100644
--- a/packages/fluent-ui/src/RadioWidget/RadioWidget.tsx
+++ b/packages/fluent-ui/src/RadioWidget/RadioWidget.tsx
@@ -4,7 +4,12 @@ import {
IChoiceGroupOption,
IChoiceGroupProps,
} from "@fluentui/react";
-import { WidgetProps } from "@rjsf/utils";
+import {
+ FormContextType,
+ RJSFSchema,
+ StrictRJSFSchema,
+ WidgetProps,
+} from "@rjsf/utils";
import _pick from "lodash/pick";
const allowedProps: (keyof IChoiceGroupProps)[] = [
@@ -20,7 +25,11 @@ const allowedProps: (keyof IChoiceGroupProps)[] = [
"ariaLabelledBy",
];
-const RadioWidget = ({
+export default function RadioWidget<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>({
id,
schema,
options,
@@ -32,7 +41,7 @@ const RadioWidget = ({
onFocus,
disabled,
readonly,
-}: WidgetProps) => {
+}: WidgetProps) {
const { enumOptions, enumDisabled } = options;
function _onChange(
@@ -78,6 +87,4 @@ const RadioWidget = ({
{...uiProps}
/>
);
-};
-
-export default RadioWidget;
+}
diff --git a/packages/fluent-ui/src/RangeWidget/RangeWidget.tsx b/packages/fluent-ui/src/RangeWidget/RangeWidget.tsx
index b09a3905d8..986e744fe2 100644
--- a/packages/fluent-ui/src/RangeWidget/RangeWidget.tsx
+++ b/packages/fluent-ui/src/RangeWidget/RangeWidget.tsx
@@ -1,7 +1,13 @@
import React from "react";
import { Slider, Label } from "@fluentui/react";
-import { rangeSpec, WidgetProps } from "@rjsf/utils";
+import {
+ FormContextType,
+ rangeSpec,
+ RJSFSchema,
+ StrictRJSFSchema,
+ WidgetProps,
+} from "@rjsf/utils";
import _pick from "lodash/pick";
const styles_red = {
@@ -36,21 +42,22 @@ const allowedProps = [
"originFromZero",
];
-const RangeWidget = ({
+export default function RangeWidget<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>({
value,
readonly,
disabled,
options,
schema,
- //formContext,
- //registry,
- //rawErrors,
onChange,
required,
label,
id,
-}: WidgetProps) => {
- const sliderProps = { value, label, id, ...rangeSpec(schema) };
+}: WidgetProps) {
+ const sliderProps = { value, label, id, ...rangeSpec(schema) };
const _onChange = (value: number) => onChange(value);
@@ -72,6 +79,4 @@ const RangeWidget = ({
/>
>
);
-};
-
-export default RangeWidget;
+}
diff --git a/packages/fluent-ui/src/SelectWidget/SelectWidget.tsx b/packages/fluent-ui/src/SelectWidget/SelectWidget.tsx
index 794f225694..07f7908123 100644
--- a/packages/fluent-ui/src/SelectWidget/SelectWidget.tsx
+++ b/packages/fluent-ui/src/SelectWidget/SelectWidget.tsx
@@ -1,6 +1,12 @@
import React from "react";
import { Label, Dropdown, IDropdownOption } from "@fluentui/react";
-import { WidgetProps, processSelectValue } from "@rjsf/utils";
+import {
+ WidgetProps,
+ processSelectValue,
+ StrictRJSFSchema,
+ RJSFSchema,
+ FormContextType,
+} from "@rjsf/utils";
import _pick from "lodash/pick";
// Keys of IDropdownProps from @fluentui/react
@@ -49,7 +55,11 @@ const allowedProps = [
"openOnKeyboardFocus",
];
-const SelectWidget = ({
+export default function SelectWidget<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>({
schema,
id,
options,
@@ -62,7 +72,7 @@ const SelectWidget = ({
onChange,
onBlur,
onFocus,
-}: WidgetProps) => {
+}: WidgetProps) {
const { enumOptions, enumDisabled } = options;
const _onChange = (
@@ -80,14 +90,14 @@ const SelectWidget = ({
onChange(valueOrDefault.filter((key: any) => key !== item.key));
}
} else {
- onChange(processSelectValue(schema, item.key, options));
+ onChange(processSelectValue(schema, item.key, options));
}
};
const _onBlur = (e: any) =>
- onBlur(id, processSelectValue(schema, e.target.value, options));
+ onBlur(id, processSelectValue(schema, e.target.value, options));
const _onFocus = (e: any) =>
- onFocus(id, processSelectValue(schema, e.target.value, options));
+ onFocus(id, processSelectValue(schema, e.target.value, options));
const newOptions = (enumOptions as { value: any; label: any }[]).map(
(option) => ({
@@ -116,6 +126,4 @@ const SelectWidget = ({
/>
>
);
-};
-
-export default SelectWidget;
+}
diff --git a/packages/fluent-ui/src/SubmitButton/SubmitButton.tsx b/packages/fluent-ui/src/SubmitButton/SubmitButton.tsx
index 793773d953..72899cab36 100644
--- a/packages/fluent-ui/src/SubmitButton/SubmitButton.tsx
+++ b/packages/fluent-ui/src/SubmitButton/SubmitButton.tsx
@@ -1,8 +1,18 @@
import React from "react";
-import { getSubmitButtonOptions, SubmitButtonProps } from "@rjsf/utils";
+import {
+ FormContextType,
+ getSubmitButtonOptions,
+ RJSFSchema,
+ StrictRJSFSchema,
+ SubmitButtonProps,
+} from "@rjsf/utils";
import { PrimaryButton } from "@fluentui/react";
-export default ({ uiSchema }: SubmitButtonProps) => {
+export default function SubmitButton<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>({ uiSchema }: SubmitButtonProps) {
const {
submitText,
norender,
@@ -19,4 +29,4 @@ export default ({ uiSchema }: SubmitButtonProps) => {
);
-};
+}
diff --git a/packages/fluent-ui/src/Templates/Templates.ts b/packages/fluent-ui/src/Templates/Templates.ts
index 2c373e17d8..b4b5648b07 100644
--- a/packages/fluent-ui/src/Templates/Templates.ts
+++ b/packages/fluent-ui/src/Templates/Templates.ts
@@ -12,24 +12,38 @@ import ObjectFieldTemplate from "../ObjectFieldTemplate";
import SubmitButton from "../SubmitButton";
import TitleField from "../TitleField";
import WrapIfAdditionalTemplate from "../WrapIfAdditionalTemplate";
+import {
+ FormContextType,
+ RJSFSchema,
+ StrictRJSFSchema,
+ TemplatesType,
+} from "@rjsf/utils";
-export default {
- ArrayFieldItemTemplate,
- ArrayFieldTemplate,
- BaseInputTemplate,
- ButtonTemplates: {
- AddButton,
- MoveDownButton,
- MoveUpButton,
- RemoveButton,
- SubmitButton,
- },
- DescriptionFieldTemplate: DescriptionField,
- ErrorListTemplate: ErrorList,
- FieldErrorTemplate,
- FieldHelpTemplate,
- FieldTemplate,
- ObjectFieldTemplate,
- TitleFieldTemplate: TitleField,
- WrapIfAdditionalTemplate,
-};
+export function generateTemplates<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>(): Partial> {
+ return {
+ ArrayFieldItemTemplate,
+ ArrayFieldTemplate,
+ BaseInputTemplate,
+ ButtonTemplates: {
+ AddButton,
+ MoveDownButton,
+ MoveUpButton,
+ RemoveButton,
+ SubmitButton,
+ },
+ DescriptionFieldTemplate: DescriptionField,
+ ErrorListTemplate: ErrorList,
+ FieldErrorTemplate,
+ FieldHelpTemplate,
+ FieldTemplate,
+ ObjectFieldTemplate,
+ TitleFieldTemplate: TitleField,
+ WrapIfAdditionalTemplate,
+ };
+}
+
+export default generateTemplates();
diff --git a/packages/fluent-ui/src/TextareaWidget/TextareaWidget.tsx b/packages/fluent-ui/src/TextareaWidget/TextareaWidget.tsx
index 120129de28..fdb2916320 100644
--- a/packages/fluent-ui/src/TextareaWidget/TextareaWidget.tsx
+++ b/packages/fluent-ui/src/TextareaWidget/TextareaWidget.tsx
@@ -1,16 +1,25 @@
import React from "react";
-import { getTemplate, getUiOptions, WidgetProps } from "@rjsf/utils";
+import {
+ FormContextType,
+ getTemplate,
+ getUiOptions,
+ RJSFSchema,
+ StrictRJSFSchema,
+ WidgetProps,
+} from "@rjsf/utils";
-const TextareaWidget = (props: WidgetProps) => {
+export default function TextareaWidget<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>(props: WidgetProps) {
const { uiSchema, registry } = props;
- const options = getUiOptions(uiSchema);
- const BaseInputTemplate = getTemplate<"BaseInputTemplate">(
+ const options = getUiOptions(uiSchema);
+ const BaseInputTemplate = getTemplate<"BaseInputTemplate", T, S, F>(
"BaseInputTemplate",
registry,
options
);
// TODO: rows and columns.
return ;
-};
-
-export default TextareaWidget;
+}
diff --git a/packages/fluent-ui/src/Theme/Theme.ts b/packages/fluent-ui/src/Theme/Theme.ts
index ecfcdd5720..ec9d319569 100644
--- a/packages/fluent-ui/src/Theme/Theme.ts
+++ b/packages/fluent-ui/src/Theme/Theme.ts
@@ -1,11 +1,18 @@
import { ThemeProps } from "@rjsf/core";
-import Templates from "../Templates";
-import Widgets from "../Widgets";
+import { generateTemplates } from "../Templates";
+import { generateWidgets } from "../Widgets";
+import { FormContextType, RJSFSchema, StrictRJSFSchema } from "@rjsf/utils";
-const Theme: ThemeProps = {
- templates: Templates,
- widgets: Widgets,
-};
+export function generateTheme<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>(): ThemeProps {
+ return {
+ templates: generateTemplates(),
+ widgets: generateWidgets(),
+ };
+}
-export default Theme;
+export default generateTheme();
diff --git a/packages/fluent-ui/src/TitleField/TitleField.tsx b/packages/fluent-ui/src/TitleField/TitleField.tsx
index 1985f2f7e7..6e68e01408 100644
--- a/packages/fluent-ui/src/TitleField/TitleField.tsx
+++ b/packages/fluent-ui/src/TitleField/TitleField.tsx
@@ -1,5 +1,10 @@
import React from "react";
-import { TitleFieldProps } from "@rjsf/utils";
+import {
+ FormContextType,
+ RJSFSchema,
+ StrictRJSFSchema,
+ TitleFieldProps,
+} from "@rjsf/utils";
import { Label } from "@fluentui/react";
const styles = {
@@ -12,10 +17,14 @@ const styles = {
],
};
-const TitleField = ({ id, title }: TitleFieldProps) => (
-
-);
-
-export default TitleField;
+export default function TitleField<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>({ id, title }: TitleFieldProps) {
+ return (
+
+ );
+}
diff --git a/packages/fluent-ui/src/UpDownWidget/UpDownWidget.tsx b/packages/fluent-ui/src/UpDownWidget/UpDownWidget.tsx
index 4bf580d7a2..14bc6a85c4 100644
--- a/packages/fluent-ui/src/UpDownWidget/UpDownWidget.tsx
+++ b/packages/fluent-ui/src/UpDownWidget/UpDownWidget.tsx
@@ -1,7 +1,12 @@
import React from "react";
-import { Label } from "@fluentui/react";
-import { SpinButton } from "@fluentui/react";
-import { WidgetProps, rangeSpec } from "@rjsf/utils";
+import { Label, SpinButton } from "@fluentui/react";
+import {
+ FormContextType,
+ rangeSpec,
+ RJSFSchema,
+ StrictRJSFSchema,
+ WidgetProps,
+} from "@rjsf/utils";
import _pick from "lodash/pick";
// Keys of ISpinButtonProps from @fluentui/react
@@ -44,7 +49,11 @@ const allowedProps = [
"value",
];
-const UpDownWidget = ({
+export default function UpDownWidget<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>({
id,
required,
readonly,
@@ -57,7 +66,7 @@ const UpDownWidget = ({
options,
schema,
}: // autofocus,
-WidgetProps) => {
+WidgetProps) {
const _onChange = ({
target: { value },
}: React.ChangeEvent) => onChange(Number(value));
@@ -117,6 +126,4 @@ WidgetProps) => {
/>
>
);
-};
-
-export default UpDownWidget;
+}
diff --git a/packages/fluent-ui/src/Widgets/Widgets.ts b/packages/fluent-ui/src/Widgets/Widgets.ts
index 106aa60235..b9939a891b 100644
--- a/packages/fluent-ui/src/Widgets/Widgets.ts
+++ b/packages/fluent-ui/src/Widgets/Widgets.ts
@@ -8,15 +8,30 @@ import RangeWidget from "../RangeWidget/RangeWidget";
import SelectWidget from "../SelectWidget/SelectWidget";
import TextareaWidget from "../TextareaWidget/TextareaWidget";
import UpDownWidget from "../UpDownWidget/UpDownWidget";
-export default {
- CheckboxWidget,
- CheckboxesWidget,
- ColorWidget,
- DateWidget,
- DateTimeWidget,
- RadioWidget,
- RangeWidget,
- SelectWidget,
- TextareaWidget,
- UpDownWidget,
-};
+import {
+ FormContextType,
+ RegistryWidgetsType,
+ RJSFSchema,
+ StrictRJSFSchema,
+} from "@rjsf/utils";
+
+export function generateWidgets<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>(): RegistryWidgetsType {
+ return {
+ CheckboxWidget,
+ CheckboxesWidget,
+ ColorWidget,
+ DateWidget,
+ DateTimeWidget,
+ RadioWidget,
+ RangeWidget,
+ SelectWidget,
+ TextareaWidget,
+ UpDownWidget,
+ };
+}
+
+export default generateWidgets();
diff --git a/packages/fluent-ui/src/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.tsx b/packages/fluent-ui/src/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.tsx
index b7b516a46e..1468feb73a 100644
--- a/packages/fluent-ui/src/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.tsx
+++ b/packages/fluent-ui/src/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.tsx
@@ -1,9 +1,16 @@
import React from "react";
-import { WrapIfAdditionalTemplateProps } from "@rjsf/utils";
+import {
+ FormContextType,
+ RJSFSchema,
+ StrictRJSFSchema,
+ WrapIfAdditionalTemplateProps,
+} from "@rjsf/utils";
-export default function WrapIfAdditionalTemplate(
- props: WrapIfAdditionalTemplateProps
-) {
+export default function WrapIfAdditionalTemplate<
+ T = any,
+ S extends StrictRJSFSchema = RJSFSchema,
+ F extends FormContextType = any
+>(props: WrapIfAdditionalTemplateProps) {
const { children } = props;
// TODO Implement WrapIfAdditionalTemplate features in FluentUI (#2777)
return <>{children}>;
diff --git a/packages/fluent-ui/src/index.ts b/packages/fluent-ui/src/index.ts
index 4b96d43dfa..692cd22bfd 100644
--- a/packages/fluent-ui/src/index.ts
+++ b/packages/fluent-ui/src/index.ts
@@ -1,10 +1,10 @@
import { initializeIcons } from "@fluentui/react";
import FuiForm from "./FuiForm/";
-export { default as Form } from "./FuiForm";
-export { default as Templates } from "./Templates";
-export { default as Theme } from "./Theme";
-export { default as Widgets } from "./Widgets";
+export { default as Form, generateForm } from "./FuiForm";
+export { default as Templates, generateTemplates } from "./Templates";
+export { default as Theme, generateTheme } from "./Theme";
+export { default as Widgets, generateWidgets } from "./Widgets";
initializeIcons();