-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
♻️ [refactor]: Add playground app for local development, add abstract…
…ed hooks
- Loading branch information
Showing
35 changed files
with
724 additions
and
61 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
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
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
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 |
---|---|---|
@@ -1,10 +1,5 @@ | ||
import React from "react"; | ||
import ReactDOM from "react-dom/client"; | ||
import "tdv-core/dist/polyfill.d.ts"; | ||
import App from "./App.tsx"; | ||
|
||
ReactDOM.createRoot(document.getElementById("root")!).render( | ||
<React.StrictMode> | ||
<App /> | ||
</React.StrictMode> | ||
); | ||
ReactDOM.createRoot(document.getElementById("root")!).render(<App />); |
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,18 @@ | ||
module.exports = { | ||
root: true, | ||
env: { browser: true, es2020: true }, | ||
extends: [ | ||
'eslint:recommended', | ||
'plugin:@typescript-eslint/recommended', | ||
'plugin:react-hooks/recommended', | ||
], | ||
ignorePatterns: ['dist', '.eslintrc.cjs'], | ||
parser: '@typescript-eslint/parser', | ||
plugins: ['react-refresh'], | ||
rules: { | ||
'react-refresh/only-export-components': [ | ||
'warn', | ||
{ allowConstantExport: true }, | ||
], | ||
}, | ||
} |
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,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? |
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,27 @@ | ||
# 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 | ||
parserOptions: { | ||
ecmaVersion: 'latest', | ||
sourceType: 'module', | ||
project: ['./tsconfig.json', './tsconfig.node.json'], | ||
tsconfigRootDir: __dirname, | ||
}, | ||
``` | ||
|
||
- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked` | ||
- Optionally add `plugin:@typescript-eslint/stylistic-type-checked` | ||
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list |
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,39 @@ | ||
import { exec } from "child_process"; | ||
import { watch } from "chokidar"; | ||
|
||
// Specify the directories you want to watch for changes | ||
const directoriesToWatch = ["./../../../core/src", "./../../src"]; // Adjust as needed | ||
|
||
// Define the command to restart your Vite development server | ||
const restartCommand = "npm run dev"; | ||
|
||
// Create a chokidar watcher | ||
const watcher = watch(directoriesToWatch, { | ||
ignoreInitial: true, // Ignore initial scan to avoid unnecessary restarts | ||
}); | ||
|
||
// Start the Vite development server | ||
exec(restartCommand, (error, stdout, stderr) => { | ||
if (error) { | ||
console.error(`Error starting the server: ${error}`); | ||
return; | ||
} | ||
console.log(`Server started successfully.`); | ||
}); | ||
|
||
// When a change is detected, execute the restart command | ||
watcher.on("change", (path) => { | ||
console.log(`Change detected in ${path}. Restarting server...`); | ||
exec(restartCommand, (error, stdout, stderr) => { | ||
if (error) { | ||
console.error(`Error during server restart: ${error}`); | ||
return; | ||
} | ||
console.log(`Server restarted successfully.`); | ||
}); | ||
}); | ||
|
||
// Handle errors | ||
watcher.on("error", (error) => { | ||
console.error(`Watcher error: ${error}`); | ||
}); |
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,12 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>tdv-react example</title> | ||
</head> | ||
<body> | ||
<div id="root"></div> | ||
<script type="module" src="/src/main.tsx"></script> | ||
</body> | ||
</html> |
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,33 @@ | ||
{ | ||
"name": "basic-example-form", | ||
"private": true, | ||
"version": "0.0.0", | ||
"type": "module", | ||
"scripts": { | ||
"start": "npm run dev", | ||
"dev:watch": "node dev-watch.js", | ||
"dev": "npm i --silent && npm run build:noTest --prefix=../../../core && npm run build:noTest --prefix=../.. && vite", | ||
"build": "tsc && vite build", | ||
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", | ||
"preview": "vite preview" | ||
}, | ||
"dependencies": { | ||
"react": "^18.2.0", | ||
"react-dom": "^18.2.0", | ||
"tdv-core": "file:../../../core/dist", | ||
"tdv-react": "file:../../dist" | ||
}, | ||
"devDependencies": { | ||
"@types/react": "^18.2.15", | ||
"@types/react-dom": "^18.2.7", | ||
"@typescript-eslint/eslint-plugin": "^6.0.0", | ||
"@typescript-eslint/parser": "^6.0.0", | ||
"@vitejs/plugin-react": "^4.0.3", | ||
"chokidar-cli": "^3.0.0", | ||
"eslint": "^8.45.0", | ||
"eslint-plugin-react-hooks": "^4.6.0", | ||
"eslint-plugin-react-refresh": "^0.4.3", | ||
"typescript": "^5.2.2", | ||
"vite": "^4.4.5" | ||
} | ||
} |
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,11 @@ | ||
import UserFormControls from "./components/controls/UserFormControls"; | ||
|
||
function App() { | ||
return ( | ||
<div style={{ padding: "1rem" }}> | ||
<UserFormControls /> | ||
</div> | ||
); | ||
} | ||
|
||
export default App; |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
102 changes: 102 additions & 0 deletions
102
packages/react/examples/playground/src/components/controls/UserFormControls.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,102 @@ | ||
import { useState } from "react"; | ||
import { FormProvider, useForm } from "tdv-react"; | ||
import UserForm from "../../models/UserForm"; | ||
import Input from "../shared/Input"; | ||
|
||
const SUBMIT_BUTTON_TRIGGERS_VALIDATION = true; | ||
const VALIDATION_GROUPS_FACTORY: "native" | "custom" | "both" = "both"; | ||
const GROUPS = | ||
VALIDATION_GROUPS_FACTORY === "both" | ||
? ["custom", "native"] | ||
: VALIDATION_GROUPS_FACTORY === "custom" | ||
? ["custom"] | ||
: ["native"]; | ||
|
||
function onSubmitValidationFail(e: any) { | ||
alert( | ||
"Form has invalid data. Please correct them\n" + JSON.stringify(e, null, 2) | ||
); | ||
} | ||
|
||
export default function UserFormInput() { | ||
const [numberOfStateChanges, setNumberOfStateChanges] = useState(0); | ||
const [ | ||
form, | ||
_setForm, | ||
{ providerProps, errors, isSubmitted, isValid, onSubmit, reset, mutations }, | ||
] = useForm<UserForm>(UserForm, { | ||
validationGroups: GROUPS, | ||
onSubmit: () => alert("Congrats, you don't have any validation errors!"), | ||
whenChanged: () => setNumberOfStateChanges((p) => ++p), | ||
defaultValue: undefined, | ||
standalone: true, | ||
validateImmediately: !SUBMIT_BUTTON_TRIGGERS_VALIDATION, | ||
onSubmitValidationFail, | ||
}); | ||
|
||
console.count("UserFormControls"); | ||
|
||
const dateOfBirthValue = form!.dateOfBirth | ||
? form.dateOfBirth.toISOString().substring(0, 10) | ||
: ""; | ||
|
||
return ( | ||
<> | ||
<FormProvider {...providerProps}> | ||
<div | ||
style={{ display: "flex", flexDirection: "column", gap: "0.25rem" }} | ||
> | ||
<Input | ||
value={form.testEmail} | ||
onChange={mutations.testEmail} | ||
errors={errors.testEmail} | ||
label="Test email" | ||
/> | ||
<Input | ||
value={form.age} | ||
onChange={mutations.age} | ||
errors={errors.age} | ||
label="Age" | ||
/> | ||
<Input | ||
value={form.password} | ||
onChange={mutations.password} | ||
errors={errors.password} | ||
type="password" | ||
label="Password" | ||
/> | ||
<Input | ||
value={form.confirmPassword} | ||
onChange={mutations.confirmPassword} | ||
errors={errors.confirmPassword} | ||
type="password" | ||
label="Confirm password" | ||
/> | ||
<Input | ||
value={dateOfBirthValue} | ||
onChange={(v) => mutations.dateOfBirth!(v ? new Date(v) : null!)} | ||
errors={errors.dateOfBirth} | ||
type="date" | ||
label="Date of birth" | ||
/> | ||
{SUBMIT_BUTTON_TRIGGERS_VALIDATION && ( | ||
<button | ||
style={{ padding: "0.5rem", fontSize: 18, marginTop: 8 }} | ||
onClick={onSubmit} | ||
disabled={isSubmitted && !isValid} | ||
> | ||
<strong>Submit</strong> | ||
</button> | ||
)} | ||
<p>Form changed state count: {numberOfStateChanges}</p> | ||
<button | ||
style={{ padding: "0.5rem", fontSize: 18, marginTop: 8 }} | ||
onClick={() => reset("testEmail")} | ||
> | ||
<strong>Reset form</strong> | ||
</button> | ||
</div> | ||
</FormProvider> | ||
</> | ||
); | ||
} |
Oops, something went wrong.