Skip to content

Commit 0acfa0f

Browse files
committed
Start refactoring to use trussworks/react-uswds for form fields
1 parent ed729d2 commit 0acfa0f

File tree

9 files changed

+131
-112
lines changed

9 files changed

+131
-112
lines changed

CHANGELOG_v6.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@ should change the heading of the (upcoming) version to include a major version b
7575

7676
- Added new theme!
7777

78+
## @rjsf/uswds
79+
80+
- BREAKING: Initial release of the USWDS theme package (`@rjsf/uswds`).
81+
- BREAKING: Uses components from `@trussworks/react-uswds` library for core form elements, templates, and buttons.
82+
- feat: Implemented `GridTemplate` using `@trussworks/react-uswds` Grid components.
83+
- fix: Extensible for custom props `@rjsf/uswds` *if needed but defaults to `@trussworks/react-uswds` components (`FormGroup`, `Label`, `TextInput`, `Grid`).
84+
- fix: Refactored all Widgets to use components from `@trussworks/react-uswds`.
85+
- fix: Refactored all Templates (Field, ErrorList, Buttons, etc.) to use components from `@trussworks/react-uswds`.
86+
- test: Uses standard `@rjsf/snapshot-tests` tests for `@rjsf/uswds`.
87+
7888
## @rjsf/utils
7989

8090
- BREAKING CHANGE: Refactored the `ArrayFieldItemTemplateType` to extract out all the button related props to `ArrayFieldItemButtonsTemplateType`, adding `buttonsProps: ArrayFieldItemButtonsTemplateType` as a new prop

packages/docs/docs/usage/themes.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@ meaning that you must load the Bootstrap stylesheet on the page to view the form
55

66
## Supported themes
77

8-
| Theme Name | Status | Package Name / Link |
9-
| --------------------- | --------- | ------------------- |
10-
| antd | Published | `@rjsf/antd` |
11-
| Bootstrap 3 (default) | Published | `@rjsf/core` |
12-
| Bootstrap 4 | Published | `@rjsf/bootstrap-4` |
13-
| Chakra UI | Published | `@rjsf/chakra-ui` |
14-
| fluent-ui | Published | `@rjsf/fluent-ui` |
15-
| fluentui-rc | Published | `@rjsf/fluentui-rc` |
16-
| material-ui 4 | Published | `@rjsf/material-ui` |
17-
| material-ui 5 | Published | `@rjsf/mui` |
18-
| Semantic UI | Published | `@rjsf/semantic-ui` |
19-
| USWDS | Published | `@rjsf/uswds` |
8+
| Theme Name | Status | Package Name / Link |
9+
| -------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------- |
10+
| antd | Published | [`@rjsf/antd`](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/antd#readme) |
11+
| Chakra UI | Published | [`@rjsf/chakra-ui`](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/chakra-ui#readme) |
12+
| Core (default) | Published | [`@rjsf/core`](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/core#readme) |
13+
| DaisyUI | Published | [`@rjsf/daisyui`](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/daisyui#readme) |
14+
| Fluent UI React Components | Published | [`@rjsf/fluentui-rc`](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/fluentui-rc#readme) |
15+
| MUI | Published | [`@rjsf/mui`](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/mui#readme) |
16+
| React Bootstrap | Published | [`@rjsf/react-bootstrap`](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/react-bootstrap#readme) |
17+
| Semantic UI | Published | [`@rjsf/semantic-ui`](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/semantic-ui#readme) |
18+
| Shadcn | Published | [`@rjsf/shadcn`](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/shadcn#readme) |
19+
| USWDS | Published | [`@rjsf/uswds`](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/uswds#readme) |
2020

2121
## Using themes
2222

packages/playground/src/app.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ const themes: PlaygroundProps['themes'] = {
162162
theme: ShadcnTheme,
163163
},
164164
uswds: {
165-
stylesheet: '//cdn.jsdelivr.net/npm/uswds/dist/css/uswds.min.css',
165+
stylesheet: '//cdn.jsdelivr.net/npm/uswds@2.14.0/dist/css/uswds.min.css',
166166
theme: UswdsTheme,
167167
},
168168
};

packages/uswds/README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ USWDS theme, fields and widgets for [`react-jsonschema-form`](https://github.com
1212
```bash
1313
npm install @rjsf/core @rjsf/uswds @uswds/uswds react react-dom
1414
```
15+
## Usage
1516

1617
## Prerequisites: USWDS CSS
1718

@@ -32,8 +33,6 @@ npm install @rjsf/core @rjsf/uswds @uswds/uswds react react-dom
3233
<link rel="stylesheet" href="/path/to/node_modules/@uswds/uswds/dist/css/uswds.min.css" />
3334
```
3435

35-
## Usage
36-
3736
### Option 1: Use the themed Form component
3837

3938
This is the simplest way to use the theme.

packages/uswds/package.json

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,42 @@
77
"types": "dist/index.d.ts",
88
"scripts": {
99
"build": "tsc",
10-
"cs-check": "prettier -c --ignore-path ../../.prettierignore \"src/**/*.{js,jsx,ts,tsx,json}\"",
11-
"cs-format": "prettier -w --ignore-path ../../.prettierignore \"src/**/*.{js,jsx,ts,tsx,json}\"",
10+
"cs-check": "prettier -l \"{src,test}/**/*.ts?(x)\"",
11+
"cs-format": "prettier \"{src,test}/**/*.ts?(x)\" --write",
1212
"lint": "eslint src test",
1313
"test": "jest",
1414
"test:update": "jest --u"
1515
},
16-
"dependencies": {
17-
"@rjsf/utils": "^5.19.2"
18-
},
16+
"dependencies": {},
1917
"devDependencies": {
2018
"@babel/core": "^7.22.8",
2119
"@babel/preset-env": "^7.22.7",
2220
"@babel/preset-react": "^7.22.5",
2321
"@babel/preset-typescript": "^7.22.5",
24-
"@rjsf/snapshot-tests": "^5.19.2",
25-
"@rjsf/validator-ajv8": "^5.19.2",
22+
"@rjsf/snapshot-tests": "^6.0.0-alpha.0",
23+
"@rjsf/utils": "^6.0.0-alpha.0",
24+
"@rjsf/validator-ajv8": "^6.0.0-alpha.0",
25+
"@testing-library/dom": "^10.4.0",
26+
"@testing-library/jest-dom": "^6.4.2",
27+
"@testing-library/react": "^14.2.1",
28+
"@testing-library/user-event": "^14.5.2",
2629
"@types/jest": "^29.5.3",
2730
"@types/react": "^18.2.14",
2831
"@types/react-dom": "^18.2.6",
2932
"eslint": "^8.44.0",
30-
"jest": "^29.6.1",
33+
"jest": "^29.7.0",
3134
"jest-environment-jsdom": "^29.6.1",
3235
"prettier": "^3.0.0",
3336
"react": "^18.2.0",
3437
"react-dom": "^18.2.0",
3538
"react-test-renderer": "^18.2.0",
36-
"typescript": "^5.1.6"
39+
"typescript": "^5.1.6",
40+
"@trussworks/react-uswds": "^6.1.0"
3741
},
3842
"peerDependencies": {
39-
"@rjsf/core": "^5.19.2",
40-
"@uswds/uswds": "^3.0.0",
43+
"@rjsf/core": "^6",
44+
"@rjsf/utils": "^6",
45+
"@trussworks/react-uswds": "^5.0.0 || ^6.0.0",
4146
"react": "^16.14.0 || ^17.0.0 || ^18.0.0",
4247
"react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0"
4348
},

packages/uswds/src/Templates/ArrayFieldItemTemplate.tsx

Lines changed: 38 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,49 @@
11
import React from "react";
2-
import {
3-
ArrayFieldTemplateItemType,
4-
FormContextType,
5-
RJSFSchema,
6-
StrictRJSFSchema,
7-
} from "@rjsf/utils";
2+
import { ArrayFieldTemplateItemType, FormContextType, RJSFSchema, StrictRJSFSchema } from "@rjsf/utils";
3+
import { Grid } from "@trussworks/react-uswds"; // Updated import
84

5+
/** The `ArrayFieldItemTemplate` component is the template used to render an items of an array.
6+
*
7+
* @param props - The `ArrayFieldTemplateItemType` props for the component
8+
*/
99
const ArrayFieldItemTemplate = <
1010
T = any,
1111
S extends StrictRJSFSchema = RJSFSchema,
1212
F extends FormContextType = any,
13-
>(
14-
props: ArrayFieldTemplateItemType<T, S, F>,
15-
) => {
16-
const {
17-
children,
18-
disabled,
19-
hasToolbar,
20-
hasMoveDown,
21-
hasMoveUp,
22-
hasRemove,
23-
hasCopy, // Added for completeness, though icon not requested
24-
index,
25-
onCopyIndexClick, // Added for completeness
26-
onDropIndexClick,
27-
onReorderClick,
28-
readonly,
29-
registry,
30-
uiSchema,
31-
} = props;
32-
33-
const { CopyButton, MoveDownButton, MoveUpButton, RemoveButton } =
34-
registry.templates.ButtonTemplates;
13+
>({
14+
children,
15+
className,
16+
disabled,
17+
hasToolbar,
18+
hasCopy,
19+
hasMoveDown,
20+
hasMoveUp,
21+
hasRemove,
22+
index,
23+
onCopyIndexClick,
24+
onDropIndexClick,
25+
onReorderClick,
26+
readonly,
27+
registry,
28+
required,
29+
schema,
30+
uiSchema,
31+
buttonsProps, // Added buttonsProps
32+
}: ArrayFieldTemplateItemType<T, S, F>) => {
33+
const { ArrayFieldItemButtonsTemplate } = registry.templates; // Get ArrayFieldItemButtonsTemplate
3534

3635
return (
37-
<div className="rjsf-uswds-array-item">
38-
<div className="grid-row grid-gap">
39-
<div className={hasToolbar ? "grid-col-9" : "grid-col-12"}>
40-
{children}
41-
</div>
42-
43-
{hasToolbar && (
44-
<div className="grid-col-3 rjsf-uswds-array-item-toolbox">
45-
<div
46-
className="usa-button-group usa-button-group--segmented display-flex flex-justify-end grid-gap-1" // Use utility classes
47-
>
48-
{(hasMoveUp || hasMoveDown) && (
49-
<MoveUpButton
50-
className="array-item-move-up"
51-
disabled={disabled || readonly || !hasMoveUp}
52-
onClick={onReorderClick(index, index - 1)}
53-
uiSchema={uiSchema}
54-
registry={registry}
55-
/>
56-
)}
57-
58-
{(hasMoveUp || hasMoveDown) && (
59-
<MoveDownButton
60-
className="array-item-move-down"
61-
disabled={disabled || readonly || !hasMoveDown}
62-
onClick={onReorderClick(index, index + 1)}
63-
uiSchema={uiSchema}
64-
registry={registry}
65-
/>
66-
)}
67-
68-
{hasCopy && (
69-
<CopyButton
70-
className="array-item-copy"
71-
disabled={disabled || readonly}
72-
onClick={onCopyIndexClick(index)}
73-
uiSchema={uiSchema}
74-
registry={registry}
75-
/>
76-
)}
77-
78-
{hasRemove && (
79-
<RemoveButton
80-
className="array-item-remove"
81-
disabled={disabled || readonly}
82-
onClick={onDropIndexClick(index)}
83-
uiSchema={uiSchema}
84-
registry={registry}
85-
/>
86-
)}
87-
</div>
88-
</div>
89-
)}
90-
</div>
91-
</div>
36+
<Grid row gap className={className}>
37+
<Grid col={true} className="rjsf-uswds-array-item-content">
38+
{children}
39+
</Grid>
40+
{hasToolbar && (
41+
<Grid col="auto" className="rjsf-uswds-array-item-toolbox">
42+
{/* Render the buttons template */}
43+
<ArrayFieldItemButtonsTemplate {...buttonsProps} />
44+
</Grid>
45+
)}
46+
</Grid>
9247
);
9348
};
9449

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import React from "react";
2+
import { GridTemplateProps, FormContextType, RJSFSchema, StrictRJSFSchema } from "@rjsf/utils";
3+
import { Grid } from "@trussworks/react-uswds"; // Import Grid from @trussworks/react-uswds
4+
5+
/** The `GridTemplate` component is used by the `SchemaField` to render a field grid.
6+
*
7+
* @param props - The `GridTemplateProps` for the component
8+
*/
9+
const GridTemplate = <
10+
T = any,
11+
S extends StrictRJSFSchema = RJSFSchema,
12+
F extends FormContextType = any,
13+
>({
14+
children,
15+
// className, // className is not directly used on Grid but could be passed if needed
16+
// style, // style is not directly used on Grid but could be passed if needed
17+
// disabled, // disabled is handled by child elements
18+
// id, // id is handled by child elements
19+
// label, // label is handled by child elements
20+
// onAddClick, // onAddClick is handled by ArrayFieldTemplate
21+
// onDropIndexClick, // onDropIndexClick is handled by ArrayFieldTemplate
22+
// onReorderClick, // onReorderClick is handled by ArrayFieldTemplate
23+
// readonly, // readonly is handled by child elements
24+
// required, // required is handled by child elements
25+
// schema, // schema is used by child elements
26+
// uiSchema, // uiSchema is used by child elements
27+
// registry, // registry is used by child elements
28+
}: GridTemplateProps<T, S, F>) => {
29+
// The Grid component from react-uswds acts as a grid item (column).
30+
// RJSF's GridTemplate concept maps more closely to a row containing these items.
31+
// We'll render each child directly within a Grid component.
32+
// The parent component (likely FieldTemplate or ArrayFieldItemTemplate) should manage the Grid row structure.
33+
// This implementation assumes each child represents a grid cell's content.
34+
// Adjust column props (e.g., desktop={{ col: 6 }}) as needed, potentially based on uiSchema.
35+
return (
36+
<Grid col={12} tablet={{ col: 6 }} desktop={{ col: 4 }}> {/* Example column sizing */}
37+
{children}
38+
</Grid>
39+
);
40+
};
41+
42+
export default GridTemplate;

packages/uswds/src/Theme.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import {
55
StrictRJSFSchema,
66
} from "@rjsf/utils";
77

8-
import { generateTemplates } from "./Templates"; // Import the generator function
9-
import { generateWidgets } from "./Widgets"; // Import the generator function
8+
import { generateTemplates } from "./Templates";
9+
import { generateWidgets } from "./Widgets";
1010

1111
/** The `generateTheme` function generates the theme object for the USWDS theme.
1212
* It is used to merge the generated templates and widgets into a single theme object.
@@ -18,12 +18,14 @@ export function generateTheme<
1818
S extends StrictRJSFSchema = RJSFSchema,
1919
F extends FormContextType = any,
2020
>(): ThemeProps<T, S, F> {
21+
// Always use the generated templates and widgets (which now use @trussworks/react-uswds)
2122
return {
2223
templates: generateTemplates<T, S, F>(),
2324
widgets: generateWidgets<T, S, F>(),
2425
};
2526
}
2627

27-
const Theme = generateTheme(); // Generate the theme for the default export
28+
// Generate the default theme
29+
const Theme = generateTheme();
2830

2931
export default Theme;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { gridTests } from "@rjsf/snapshot-tests";
2+
3+
import Theme from "../src";
4+
5+
// Run the snapshot tests for the GridTemplate using the theme and directory context
6+
gridTests(Theme, __dirname);

0 commit comments

Comments
 (0)