Skip to content

Commit

Permalink
Typescript generics in fluent-ui
Browse files Browse the repository at this point in the history
- Partially fixes rjsf-team#3072
  • Loading branch information
nickgros committed Jan 7, 2023
1 parent 08cb1b2 commit 89dd3ec
Show file tree
Hide file tree
Showing 31 changed files with 483 additions and 241 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -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)
Expand Down
35 changes: 22 additions & 13 deletions 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) => (
<CommandBarButton
style={{ height: "32px" }}
iconProps={addIcon}
text="Add item"
className={props.className}
onClick={props.onClick}
disabled={props.disabled}
/>
);

export default AddButton;
export default function AddButton<
T = any,
S extends StrictRJSFSchema = RJSFSchema,
F extends FormContextType = any
>(props: IconButtonProps<T, S, F>) {
return (
<CommandBarButton
style={{ height: "32px" }}
iconProps={addIcon}
text="Add item"
className={props.className}
onClick={props.onClick}
disabled={props.disabled}
/>
);
}
@@ -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<T, S, F>) {
const {
children,
disabled,
Expand Down Expand Up @@ -58,6 +67,4 @@ const ArrayFieldItemTemplate = (props: ArrayFieldTemplateItemType) => {
</div>
</div>
);
};

export default ArrayFieldItemTemplate;
}
46 changes: 27 additions & 19 deletions packages/fluent-ui/src/ArrayFieldTemplate/ArrayFieldTemplate.tsx
Expand Up @@ -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<T, S, F>) {
const {
canAdd,
disabled,
Expand All @@ -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<T, S, F>(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 },
Expand All @@ -63,9 +71,11 @@ const ArrayFieldTemplate = (props: ArrayFieldTemplateProps) => {
registry={registry}
/>
{items.length > 0 &&
items.map(({ key, ...itemProps }: ArrayFieldTemplateItemType) => (
<ArrayFieldItemTemplate key={key} {...itemProps} />
))}
items.map(
({ key, ...itemProps }: ArrayFieldTemplateItemType<T, S, F>) => (
<ArrayFieldItemTemplate key={key} {...itemProps} />
)
)}
{canAdd && (
<span style={rightJustify}>
<AddButton
Expand All @@ -79,6 +89,4 @@ const ArrayFieldTemplate = (props: ArrayFieldTemplateProps) => {
)}
</>
);
};

export default ArrayFieldTemplate;
}
22 changes: 15 additions & 7 deletions 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
Expand Down Expand Up @@ -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,
Expand All @@ -61,8 +71,8 @@ const BaseInputTemplate = ({
type,
rawErrors,
multiline,
}: WidgetProps) => {
const inputProps = getInputProps(schema, type, options);
}: WidgetProps<T, S, F>) {
const inputProps = getInputProps<T, S, F>(schema, type, options);
const _onChange = ({
target: { value },
}: React.ChangeEvent<HTMLInputElement>) =>
Expand Down Expand Up @@ -109,6 +119,4 @@ const BaseInputTemplate = ({
)}
</>
);
};

export default BaseInputTemplate;
}
17 changes: 12 additions & 5 deletions 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
Expand All @@ -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<T, S, F>) {
const {
id,
value,
Expand Down Expand Up @@ -75,6 +84,4 @@ const CheckboxWidget = (props: WidgetProps) => {
/>
</>
);
};

export default CheckboxWidget;
}
19 changes: 13 additions & 6 deletions 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";

Expand All @@ -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,
Expand All @@ -39,7 +48,7 @@ const CheckboxesWidget = ({
onBlur,
onFocus,
rawErrors = [],
}: WidgetProps) => {
}: WidgetProps<T, S, F>) {
const { enumOptions, enumDisabled } = options;

const _onChange =
Expand Down Expand Up @@ -95,6 +104,4 @@ const CheckboxesWidget = ({
<span style={styles_red}>{(rawErrors || []).join("\n")}</span>
</>
);
};

export default CheckboxesWidget;
}
23 changes: 12 additions & 11 deletions packages/fluent-ui/src/ColorWidget/ColorWidget.tsx
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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<T, S, F>) {
const updateColor = (_ev: any, colorObj: IColor) => {
onChange(colorObj.hex);
};
Expand All @@ -64,5 +66,4 @@ const ColorWidget = ({
/>
</>
);
};
export default ColorWidget;
}
22 changes: 16 additions & 6 deletions 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<T, S, F>) {
const { registry } = props;
const uiProps: any = props.options["props"] || {};
const options = {
Expand All @@ -12,7 +24,7 @@ const DateTimeWidget = (props: WidgetProps) => {
...uiProps,
},
};
const BaseInputTemplate = getTemplate<"BaseInputTemplate">(
const BaseInputTemplate = getTemplate<"BaseInputTemplate", T, S, F>(
"BaseInputTemplate",
registry,
options
Expand All @@ -31,6 +43,4 @@ const DateTimeWidget = (props: WidgetProps) => {
onChange={onChange}
/>
);
};

export default DateTimeWidget;
}

0 comments on commit 89dd3ec

Please sign in to comment.