+
Skip to content

Add @inato-form/react-hook-form and @inato-form/mantine packages #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 32 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
2ccca96
domain -> fields
jrmdayn Dec 24, 2024
df269ef
cli -> react-hook-form
jrmdayn Dec 24, 2024
604c2ae
make ReactHookForm package
jrmdayn Dec 25, 2024
3d093ce
TextInput field using Mantine
jrmdayn Dec 25, 2024
40a2350
add apps/example
jrmdayn Dec 25, 2024
e949d20
make it work
jrmdayn Dec 25, 2024
f108e89
rename example -> nextjs
jrmdayn Jan 13, 2025
7becbb6
add vite app
jrmdayn Jan 13, 2025
181c165
add simple form
jrmdayn Jan 13, 2025
ca52298
fix vite app
jrmdayn Jan 13, 2025
1955c3f
remove nextjs app
jrmdayn Jan 13, 2025
3c4a59f
fix reset button
jrmdayn Jan 13, 2025
59aed1d
make Button a tag
jrmdayn Jan 13, 2025
c096b46
revisit layer
jrmdayn Jan 13, 2025
35c0104
handle error
jrmdayn Jan 13, 2025
130514a
add react-hook-form package
jrmdayn Jan 14, 2025
07f86c0
simplify
jrmdayn Jan 14, 2025
f2dfd22
better type
jrmdayn Jan 14, 2025
1515b8c
improve Simple example
jrmdayn Jan 14, 2025
721da4a
add more fields
jrmdayn Jan 14, 2025
1668620
add Select field
jrmdayn Jan 14, 2025
451ab00
MultiSelect
jrmdayn Jan 14, 2025
69b8ca4
add radio group
jrmdayn Jan 14, 2025
b744e42
add Checkbox and CheckboxGroup
jrmdayn Jan 14, 2025
3c9cd8f
add react router and mantine layout
jrmdayn Jan 15, 2025
62ad7aa
start @inato-form/mantine package
jrmdayn Jan 15, 2025
da588b6
export mantine layer and use it
jrmdayn Jan 15, 2025
61a3609
small changes
jrmdayn Jan 15, 2025
5e6cc78
use react.forwardedRef for Controlled component
jrmdayn Jan 15, 2025
5325b5b
fix Simple example
jrmdayn Jan 16, 2025
888e51c
changeset
jrmdayn Jan 16, 2025
4b07ac6
fix ci
jrmdayn Jan 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/little-rice-shave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@inato-form/react-hook-form": minor
"@inato-form/mantine": minor
"@inato-form/fields": minor
"@inato-form/core": minor
---

Add @inato-form/react-hook-form and @inato-form/mantine packages
24 changes: 24 additions & 0 deletions apps/vite/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
50 changes: 50 additions & 0 deletions apps/vite/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

## Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:

- Configure the top-level `parserOptions` property like this:

```js
export default tseslint.config({
languageOptions: {
// other options...
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
},
})
```

- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked`
- Optionally add `...tseslint.configs.stylisticTypeChecked`
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config:

```js
// eslint.config.js
import react from 'eslint-plugin-react'

export default tseslint.config({
// Set the react version
settings: { react: { version: '18.3' } },
plugins: {
// Add the react plugin
react,
},
rules: {
// other rules...
// Enable its recommended rules
...react.configs.recommended.rules,
...react.configs['jsx-runtime'].rules,
},
})
```
28 changes: 28 additions & 0 deletions apps/vite/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'

export default tseslint.config(
{ ignores: ['dist'] },
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ['**/*.{ts,tsx}'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
},
)
13 changes: 13 additions & 0 deletions apps/vite/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
41 changes: 41 additions & 0 deletions apps/vite/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "vite",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"@inato-form/core": "workspace:^",
"@inato-form/fields": "workspace:^",
"@inato-form/mantine": "workspace:^",
"@inato-form/react-hook-form": "workspace:^",
"@mantine/core": "^7.15.2",
"@mantine/hooks": "^7.15.2",
"effect": "^3.11.6",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-hook-form": "7.53.2",
"react-router-dom": "^7.1.1"
},
"devDependencies": {
"@eslint/js": "^9.17.0",
"@types/react": "^18.3.18",
"@types/react-dom": "^18.3.5",
"@vitejs/plugin-react": "^4.3.4",
"eslint": "^9.17.0",
"eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-react-refresh": "^0.4.16",
"globals": "^15.14.0",
"postcss": "^8.4.49",
"postcss-preset-mantine": "^1.17.0",
"postcss-simple-vars": "^7.0.1",
"typescript": "~5.6.2",
"typescript-eslint": "^8.18.2",
"vite": "^6.0.5"
}
}
14 changes: 14 additions & 0 deletions apps/vite/postcss.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = {
plugins: {
'postcss-preset-mantine': {},
'postcss-simple-vars': {
variables: {
'mantine-breakpoint-xs': '36em',
'mantine-breakpoint-sm': '48em',
'mantine-breakpoint-md': '62em',
'mantine-breakpoint-lg': '75em',
'mantine-breakpoint-xl': '88em',
},
},
},
};
1 change: 1 addition & 0 deletions apps/vite/public/vite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions apps/vite/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import "@mantine/core/styles.css";
import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom";

import forms from "./forms";
import { MantineProvider } from "@mantine/core";
import { Layout } from "./Layout";

export default function App() {
return (
<MantineProvider>
<BrowserRouter>
<Routes>
<Route element={<Layout />}>
{forms.map((Form) => (
<Route key={Form.route} path={Form.route} element={<Form />} />
))}
<Route path="*" element={<Navigate to="/simple" />} />
</Route>
</Routes>
</BrowserRouter>
</MantineProvider>
);
}
31 changes: 31 additions & 0 deletions apps/vite/src/Layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { AppShell, Burger, Group, Title, NavLink } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { Outlet } from "react-router-dom";
import forms from "./forms";

export function Layout() {
const [opened, { toggle }] = useDisclosure();

return (
<AppShell
header={{ height: 60 }}
navbar={{ width: 300, breakpoint: "sm", collapsed: { mobile: !opened } }}
padding="md"
>
<AppShell.Header>
<Group h="100%" px="md">
<Burger opened={opened} onClick={toggle} hiddenFrom="sm" size="sm" />
<Title>Inato forms</Title>
</Group>
</AppShell.Header>
<AppShell.Navbar p="md">
{forms.map(({ route, title }) => (
<NavLink key={route} href={route} label={title} />
))}
</AppShell.Navbar>
<AppShell.Main>
<Outlet />
</AppShell.Main>
</AppShell>
);
}
72 changes: 72 additions & 0 deletions apps/vite/src/forms/Simple.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { FormBody, FormDisplay } from "@inato-form/core";
import {
Checkbox,
CheckboxGroup,
MultiSelect,
NumberInput,
RadioGroup,
Select,
TextArea,
TextInput,
} from "@inato-form/fields";
import { Effect, pipe } from "effect";
import * as Mantine from "@mantine/core";
import { reportError, simulateSubmit } from "./utils";
import { MantineReactHookFormLive } from "./layer";

const body = FormBody.struct({
text: TextInput.Required,
textarea: TextArea.Required,
number: NumberInput.Optional,
select: Select.OptionalWithLiterals("react", "svelte", "ng", "vue"),
multiselect: MultiSelect.Default("react", "svelte", "ng", "vue"),
radiogroup: RadioGroup.Optional("react", "svelte", "ng", "vue"),
checkbox: Checkbox.Default,
checkboxgroup: CheckboxGroup.Default("react", "svelte", "ng", "vue"),
});

const Display = pipe(
FormDisplay.make(body),
Effect.provide(MantineReactHookFormLive),
Effect.runSync
);

const options = [
{ label: "React", value: "react" },
{ label: "Svelte", value: "svelte" },
{ label: "Angular", value: "ng" },
{ label: "Vue", value: "vue" },
] as const;

export default function Simple() {
return (
<Display.Form
onSubmit={({ encoded }) => simulateSubmit(encoded)}
onError={reportError}
validationMode="onSubmit"
>
<Mantine.Stack>
<Display.text label="text" placeholder="type something here..." />
<Display.textarea label="textarea" />
<Display.number label="number" />
<Display.checkbox label="checkbox" />
<Display.select
label="select"
placeholder="select one option"
options={options}
/>
<Display.multiselect
label="multiselect"
placeholder="select one or more option"
options={options}
/>
<Display.radiogroup label="radiogroup" options={options} />
<Display.checkboxgroup label="checkboxgroup" options={options} />
<Mantine.Group justify="end">
<Display.Clear>clear</Display.Clear>
<Display.Submit>submit</Display.Submit>
</Mantine.Group>
</Mantine.Stack>
</Display.Form>
);
}
9 changes: 9 additions & 0 deletions apps/vite/src/forms/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Simple from "./Simple"
import type { FormExample } from "./utils"
import { makeFormExample } from "./utils"

const all: ReadonlyArray<FormExample> = [
makeFormExample(Simple, { route: "/simple", title: "Simple form" })
]

export default all
9 changes: 9 additions & 0 deletions apps/vite/src/forms/layer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { MantineFields } from "@inato-form/mantine"
import { ReactHookForm } from "@inato-form/react-hook-form"
import * as Mantine from "@mantine/core"
import { Layer, pipe } from "effect"

export const MantineReactHookFormLive = pipe(
MantineFields.layer,
Layer.provideMerge(ReactHookForm.layer(Mantine.Button))
)
35 changes: 35 additions & 0 deletions apps/vite/src/forms/utils.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Container, Title } from "@mantine/core";
import { pipe, Effect, Logger } from "effect";

export interface FormExample extends React.FC {
title: string;
route: string;
}

export const makeFormExample = (
Form: React.FC,
{ route, title }: { title: string; route: string }
): FormExample => {
const FormExample = () => (
<Container mt="lg" maw={500}>
<Title>{title}</Title>
<Form />
</Container>
);
return Object.assign(FormExample, { title, route });
};

export const simulateSubmit = (values: unknown) =>
pipe(
Effect.log("submitting", { values }),
Effect.andThen(Effect.sleep(1000)),
Effect.provide(Logger.pretty),
Effect.runPromise
);

export const reportError = (error: unknown) =>
pipe(
Effect.log("failed to submit", { error }),
Effect.provide(Logger.pretty),
Effect.runPromise
);
9 changes: 9 additions & 0 deletions apps/vite/src/main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App.tsx";

createRoot(document.getElementById("root")!).render(
<StrictMode>
<App />
</StrictMode>
);
1 change: 1 addition & 0 deletions apps/vite/src/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="vite/client" />
Loading
Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载