-
Notifications
You must be signed in to change notification settings - Fork 325
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce react hook form macaw bindings (#469)
* Add components and update the configuration * Export components to be used in apps
- Loading branch information
1 parent
ce8d9de
commit 8a339fc
Showing
20 changed files
with
7,082 additions
and
2,213 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@saleor/react-hook-form-macaw": patch | ||
--- | ||
|
||
Introduction of the library integrating Macaw with the React Hook Forms. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"root": true, | ||
"extends": ["saleor"], | ||
"overrides": [ | ||
{ | ||
"files": ["*stories.tsx"], | ||
"rules": { | ||
// Stories require default export for storybook | ||
"import/no-default-export": "off", | ||
// Story wrapper is an exception to the rule | ||
"react-hooks/rules-of-hooks": "off" | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Ignore storybook build artifacts | ||
storybook-static |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { mergeConfig } from "vite"; | ||
|
||
export default { | ||
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"], | ||
addons: [ | ||
"@storybook/addon-links", | ||
"@storybook/addon-essentials", | ||
"@storybook/addon-interactions", | ||
], | ||
framework: { | ||
name: "@storybook/react-vite", | ||
options: {}, | ||
}, | ||
staticDirs: [ | ||
{ | ||
from: "../public", | ||
to: "/assets", | ||
}, | ||
"./public", | ||
], | ||
features: { | ||
storyStoreV7: true, | ||
}, | ||
async viteFinal(config) { | ||
return mergeConfig(config, { | ||
plugins: [require("@vanilla-extract/vite-plugin").vanillaExtractPlugin()], | ||
}); | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import "@saleor/macaw-ui/next/style"; | ||
import "./styles.css"; | ||
|
||
import React from "react"; | ||
import { Preview } from "@storybook/react"; | ||
import { Box, DefaultTheme, ThemeProvider, useTheme } from "@saleor/macaw-ui/next"; | ||
|
||
const ThemeSwitcher = ({ children, theme }) => { | ||
const { setTheme } = useTheme(); | ||
React.useEffect(() => { | ||
setTheme(theme); | ||
}, [theme]); | ||
|
||
return ( | ||
<Box display="flex" justifyContent="center" __backgroundColor="white"> | ||
{children} | ||
</Box> | ||
); | ||
}; | ||
|
||
const themes: DefaultTheme[] = ["defaultLight", "defaultDark"]; | ||
|
||
const preview: Preview = { | ||
globalTypes: { | ||
theme: { | ||
name: "Theme", | ||
description: "Global theme for components", | ||
defaultValue: themes[0], | ||
toolbar: { | ||
icon: "mirror", | ||
items: themes, | ||
dynamicTitle: true, | ||
}, | ||
}, | ||
}, | ||
decorators: [ | ||
(Story, context) => ( | ||
<ThemeProvider defaultTheme={context.globals.theme}> | ||
<ThemeSwitcher theme={context.globals.theme}> | ||
<Story /> | ||
</ThemeSwitcher> | ||
</ThemeProvider> | ||
), | ||
], | ||
}; | ||
|
||
export default preview; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
.sbdocs-wrapper { | ||
width: 100%; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# @saleor/react-hook-form-macaw |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# react-hook-form-macaw |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from "./src/components/Input"; | ||
export * from "./src/components/Combobox"; | ||
export * from "./src/components/Multiselect"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/// <reference types="next" /> | ||
/// <reference types="next/image-types/global" /> | ||
|
||
// NOTE: This file should not be edited | ||
// see https://nextjs.org/docs/basic-features/typescript for more information. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
{ | ||
"name": "@saleor/react-hook-form-macaw", | ||
"version": "0.0.1", | ||
"devDependencies": { | ||
"@babel/core": "^7.21.8", | ||
"@saleor/macaw-ui": "0.8.0-pre.84", | ||
"@storybook/addon-actions": "^7.0.12", | ||
"@storybook/addon-essentials": "^7.0.12", | ||
"@storybook/addon-interactions": "^7.0.12", | ||
"@storybook/addon-links": "^7.0.12", | ||
"@storybook/blocks": "^7.0.12", | ||
"@storybook/react": "^7.0.12", | ||
"@storybook/react-vite": "^7.0.12", | ||
"@storybook/testing-library": "^0.0.14-next.2", | ||
"@types/react": "^18.0.27", | ||
"@types/react-dom": "^18.0.10", | ||
"@vanilla-extract/vite-plugin": "^3.8.1", | ||
"eslint-config-saleor": "workspace:*", | ||
"react": "^18.2.0", | ||
"react-dom": "^18.2.0", | ||
"react-hook-form": "^7.43.9", | ||
"storybook": "^7.0.12", | ||
"typescript": "^5.0.4", | ||
"vite": "^4.3.6", | ||
"webpack": "^5.82.1" | ||
}, | ||
"peerDependencies": { | ||
"react": "^18.2.0", | ||
"react-dom": "^18.2.0" | ||
}, | ||
"scripts": { | ||
"lint:fix": "eslint --fix .", | ||
"storybook": "storybook dev -p 6006", | ||
"build-storybook": "storybook build", | ||
"start-storybook-build": "pnpm dlx http-server ./storybook-static" | ||
}, | ||
"main": "index.ts" | ||
} |
70 changes: 70 additions & 0 deletions
70
packages/react-hook-form-macaw/src/components/Combobox.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import { useEffect } from "react"; | ||
import { Meta, StoryObj } from "@storybook/react"; | ||
import { Combobox } from "./Combobox"; | ||
import { useForm } from "react-hook-form"; | ||
import { action } from "@storybook/addon-actions"; | ||
|
||
const meta: Meta<typeof Combobox> = { | ||
title: "Components / Combobox", | ||
component: Combobox, | ||
}; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof Combobox>; | ||
|
||
const ComboboxTemplate: Story = { | ||
render: (args) => { | ||
const { control, watch, setError } = useForm(); | ||
const name = "comboboxField"; | ||
|
||
if (args.error) { | ||
setError(name, { message: "Error message" }); | ||
} | ||
|
||
useEffect(() => { | ||
const subscription = watch((value) => action("[React Hooks Form] Form value changed")(value)); | ||
|
||
return () => subscription.unsubscribe(); | ||
}, [watch]); | ||
|
||
return ( | ||
<Combobox | ||
{...args} | ||
control={control} | ||
label="Combobox field" | ||
name={name} | ||
options={[ | ||
{ value: "1", label: "One" }, | ||
{ value: "2", label: "Two" }, | ||
{ value: "3", label: "Three" }, | ||
]} | ||
/> | ||
); | ||
}, | ||
}; | ||
|
||
export const Default: Story = { | ||
...ComboboxTemplate, | ||
}; | ||
|
||
export const Errored: Story = { | ||
...ComboboxTemplate, | ||
args: { | ||
error: true, | ||
}, | ||
}; | ||
|
||
export const Disabled: Story = { | ||
...ComboboxTemplate, | ||
args: { | ||
disabled: true, | ||
}, | ||
}; | ||
|
||
export const WithHelpText: Story = { | ||
...ComboboxTemplate, | ||
args: { | ||
helperText: "Helper text", | ||
}, | ||
}; |
36 changes: 36 additions & 0 deletions
36
packages/react-hook-form-macaw/src/components/Combobox.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { Combobox as $Combobox, type ComboboxProps as $ComboboxProps } from "@saleor/macaw-ui/next"; | ||
import { Control, Controller, FieldPath, FieldValues } from "react-hook-form"; | ||
|
||
export type ComboboxProps<T extends FieldValues = FieldValues> = Omit<$ComboboxProps, "name"> & { | ||
name: FieldPath<T>; | ||
control: Control<T>; | ||
}; | ||
|
||
export function Combobox<TFieldValues extends FieldValues = FieldValues>({ | ||
type, | ||
required, | ||
name, | ||
control, | ||
options, | ||
...rest | ||
}: ComboboxProps<TFieldValues>): JSX.Element { | ||
return ( | ||
<Controller | ||
name={name} | ||
control={control} | ||
render={({ field: { value, ...field }, fieldState: { error } }) => ( | ||
<$Combobox | ||
{...rest} | ||
{...field} | ||
options={options} | ||
value={value || ""} | ||
name={name} | ||
required={required} | ||
type={type} | ||
error={!!error} | ||
helperText={rest.helperText} | ||
/> | ||
)} | ||
/> | ||
); | ||
} |
58 changes: 58 additions & 0 deletions
58
packages/react-hook-form-macaw/src/components/Input.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { useEffect } from "react"; | ||
import { Meta, StoryObj } from "@storybook/react"; | ||
import { Input } from "./Input"; | ||
import { useForm } from "react-hook-form"; | ||
import { action } from "@storybook/addon-actions"; | ||
|
||
const meta: Meta<typeof Input> = { | ||
title: "Components / Input", | ||
component: Input, | ||
}; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof Input>; | ||
|
||
const InputTemplate: Story = { | ||
render: (args) => { | ||
const { control, watch, setError } = useForm(); | ||
const name = "inputField"; | ||
|
||
if (args.error) { | ||
setError(name, { message: "Error message" }); | ||
} | ||
|
||
useEffect(() => { | ||
const subscription = watch((value) => action("[React Hooks Form] Form value changed")(value)); | ||
|
||
return () => subscription.unsubscribe(); | ||
}, [watch]); | ||
|
||
return <Input {...args} control={control} label="Input field" name={name} />; | ||
}, | ||
}; | ||
|
||
export const Default: Story = { | ||
...InputTemplate, | ||
}; | ||
|
||
export const Errored: Story = { | ||
...InputTemplate, | ||
args: { | ||
error: true, | ||
}, | ||
}; | ||
|
||
export const Disabled: Story = { | ||
...InputTemplate, | ||
args: { | ||
disabled: true, | ||
}, | ||
}; | ||
|
||
export const WithHelpText: Story = { | ||
...InputTemplate, | ||
args: { | ||
helperText: "Helper text", | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { Input as $Input, type InputProps as $InputProps } from "@saleor/macaw-ui/next"; | ||
import { Control, Controller, FieldPath, FieldValues } from "react-hook-form"; | ||
|
||
export type TextFieldElementProps<T extends FieldValues = FieldValues> = Omit< | ||
$InputProps, | ||
"name" | ||
> & { | ||
name: FieldPath<T>; | ||
control: Control<T>; | ||
}; | ||
|
||
export function Input<TFieldValues extends FieldValues = FieldValues>({ | ||
type, | ||
required, | ||
name, | ||
control, | ||
...rest | ||
}: TextFieldElementProps<TFieldValues>): JSX.Element { | ||
return ( | ||
<Controller | ||
name={name} | ||
control={control} | ||
render={({ field, fieldState: { error } }) => ( | ||
<$Input | ||
{...rest} | ||
{...field} | ||
name={name} | ||
required={required} | ||
type={type} | ||
error={!!error} | ||
helperText={rest.helperText} | ||
/> | ||
)} | ||
/> | ||
); | ||
} |
Oops, something went wrong.