diff --git a/README.md b/README.md
index ecc885a..babf7c6 100644
--- a/README.md
+++ b/README.md
@@ -54,8 +54,7 @@ import {WebForms} from '@astro-utils/forms/forms.js';
### Simple example
```astro
---
-import { Bind } from "@astro-utils/forms";
-import { BindForm, Button, Input } from "@astro-utils/forms/forms.js";
+import { Bind, BindForm, BButton, BInput } from "@astro-utils/forms/forms.js";
import Layout from "../layouts/Layout.astro";
const form = Bind();
@@ -68,14 +67,14 @@ function formSubmit(){
{showSubmitText}
-
+
What you name*
-
+
Enter age*
-
+
-
+ Submit
```
@@ -89,7 +88,7 @@ import { defineConfig } from 'astro/config';
import astroFormsDebug from "@astro-utils/forms/dist/integration.js";
export default defineConfig({
- output: 'server',
+ output: 'server',
integrations: [astroFormsDebug]
});
```
diff --git a/examples/simple-form/astro.config.mjs b/examples/simple-form/astro.config.mjs
index cd059f2..0d57f21 100644
--- a/examples/simple-form/astro.config.mjs
+++ b/examples/simple-form/astro.config.mjs
@@ -1,6 +1,8 @@
-import { defineConfig } from 'astro/config';
+import {defineConfig} from 'astro/config';
+import react from '@astrojs/react';
// https://astro.build/config
export default defineConfig({
- output: "server"
+ output: "server",
+ integrations: [react()]
});
diff --git a/examples/simple-form/package.json b/examples/simple-form/package.json
index 4015119..9002038 100644
--- a/examples/simple-form/package.json
+++ b/examples/simple-form/package.json
@@ -13,7 +13,12 @@
"dependencies": {
"@astro-utils/express-endpoints": "^0.0.1",
"@astro-utils/forms": "^0.0.1",
+ "@astrojs/react": "^3.0.6",
"astro": "^3.5.5",
+ "bootstrap": "^5.3.2",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "reactstrap": "^9.2.1",
"zod": "^3.22.4"
}
}
diff --git a/examples/simple-form/src/pages/index.astro b/examples/simple-form/src/pages/index.astro
index a31f0a4..75d8ec0 100644
--- a/examples/simple-form/src/pages/index.astro
+++ b/examples/simple-form/src/pages/index.astro
@@ -1,8 +1,9 @@
---
import Layout from '../layouts/Layout.astro';
-import { Bind } from "@astro-utils/forms";
-import { BindForm, Button, Input } from "@astro-utils/forms/forms.js";
-import Layout from "../layouts/Layout.astro";
+import {BButton, Bind, BindForm, BInput} from '@astro-utils/forms/forms.js';
+import {Button} from 'reactstrap';
+import 'bootstrap/dist/css/bootstrap.css';
+
const form = Bind({age: 0, name: ''});
let showSubmitText: string;
@@ -11,17 +12,16 @@ function formSubmit(){
showSubmitText = `You name is ${form.name}, you are ${form.age} years old. `;
}
---
-
{showSubmitText}
What you name*
-
+
Enter age*
-
+
-
+ Submit
diff --git a/examples/simple-form/tsconfig.json b/examples/simple-form/tsconfig.json
index 1a46b47..7fb90fa 100644
--- a/examples/simple-form/tsconfig.json
+++ b/examples/simple-form/tsconfig.json
@@ -1,3 +1,7 @@
{
- "extends": "astro/tsconfigs/base"
+ "extends": "astro/tsconfigs/base",
+ "compilerOptions": {
+ "jsx": "react-jsx",
+ "jsxImportSource": "react"
+ }
}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index b311919..9f94329 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,7 +18,12 @@
"dependencies": {
"@astro-utils/express-endpoints": "^0.0.1",
"@astro-utils/forms": "^0.0.1",
+ "@astrojs/react": "^3.0.6",
"astro": "^3.5.5",
+ "bootstrap": "^5.3.2",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "reactstrap": "^9.2.1",
"zod": "^3.22.4"
}
},
@@ -150,6 +155,24 @@
"node": ">=18.14.1"
}
},
+ "node_modules/@astrojs/react": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/@astrojs/react/-/react-3.0.6.tgz",
+ "integrity": "sha512-hjC02q8cPeyzw+LWe6V2dPTYf8OgfuZwxmH32tkhn3JC/VTz1AdO5rM7dgvbilLnUoL7qMGapODEkSl2mmW+oA==",
+ "dependencies": {
+ "@vitejs/plugin-react": "^4.0.4",
+ "ultrahtml": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=18.14.1"
+ },
+ "peerDependencies": {
+ "@types/react": "^17.0.50 || ^18.0.21",
+ "@types/react-dom": "^17.0.17 || ^18.0.6",
+ "react": "^17.0.2 || ^18.0.0",
+ "react-dom": "^17.0.2 || ^18.0.0"
+ }
+ },
"node_modules/@astrojs/telemetry": {
"version": "3.0.4",
"license": "MIT",
@@ -430,6 +453,45 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz",
+ "integrity": "sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-source": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.23.3.tgz",
+ "integrity": "sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.23.4",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.4.tgz",
+ "integrity": "sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg==",
+ "dependencies": {
+ "regenerator-runtime": "^0.14.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@babel/template": {
"version": "7.22.15",
"license": "MIT",
@@ -737,6 +799,15 @@
"node": ">=12"
}
},
+ "node_modules/@popperjs/core": {
+ "version": "2.11.8",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
+ "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/popperjs"
+ }
+ },
"node_modules/@semantic-release/changelog": {
"version": "6.0.3",
"dev": true,
@@ -1590,6 +1661,12 @@
"version": "6.0.3",
"license": "MIT"
},
+ "node_modules/@types/prop-types": {
+ "version": "15.7.11",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz",
+ "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==",
+ "peer": true
+ },
"node_modules/@types/qs": {
"version": "6.9.10",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz",
@@ -1602,6 +1679,32 @@
"integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
"peer": true
},
+ "node_modules/@types/react": {
+ "version": "18.2.38",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.38.tgz",
+ "integrity": "sha512-cBBXHzuPtQK6wNthuVMV6IjHAFkdl/FOPFIlkd81/Cd1+IqkHu/A+w4g43kaQQoYHik/ruaQBDL72HyCy1vuMw==",
+ "peer": true,
+ "dependencies": {
+ "@types/prop-types": "*",
+ "@types/scheduler": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "18.2.17",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.17.tgz",
+ "integrity": "sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg==",
+ "peer": true,
+ "dependencies": {
+ "@types/react": "*"
+ }
+ },
+ "node_modules/@types/scheduler": {
+ "version": "0.16.8",
+ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz",
+ "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==",
+ "peer": true
+ },
"node_modules/@types/send": {
"version": "0.17.4",
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
@@ -1648,6 +1751,24 @@
"version": "1.2.0",
"license": "ISC"
},
+ "node_modules/@vitejs/plugin-react": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.2.0.tgz",
+ "integrity": "sha512-+MHTH/e6H12kRp5HUkzOGqPMksezRMmW+TNzlh/QXfI8rRf6l2Z2yH/v12no1UvTwhZgEDMuQ7g7rrfMseU6FQ==",
+ "dependencies": {
+ "@babel/core": "^7.23.3",
+ "@babel/plugin-transform-react-jsx-self": "^7.23.3",
+ "@babel/plugin-transform-react-jsx-source": "^7.23.3",
+ "@types/babel__core": "^7.20.4",
+ "react-refresh": "^0.14.0"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^4.2.0 || ^5.0.0"
+ }
+ },
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@@ -2071,6 +2192,24 @@
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"peer": true
},
+ "node_modules/bootstrap": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.2.tgz",
+ "integrity": "sha512-D32nmNWiQHo94BKHLmOrdjlL05q1c8oxbtBphQFb9Z5to6eGRDCm0QgeaZ4zFBHzfg2++rqa2JkqCcxDy0sH0g==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/twbs"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/bootstrap"
+ }
+ ],
+ "peerDependencies": {
+ "@popperjs/core": "^2.11.8"
+ }
+ },
"node_modules/bottleneck": {
"version": "2.19.5",
"dev": true,
@@ -2357,6 +2496,11 @@
"node": ">=8"
}
},
+ "node_modules/classnames": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
+ "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
+ },
"node_modules/clean-stack": {
"version": "5.2.0",
"dev": true,
@@ -2863,6 +3007,11 @@
"node": ">= 0.8"
}
},
+ "node_modules/csstype": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
+ "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
+ },
"node_modules/debug": {
"version": "4.3.4",
"license": "MIT",
@@ -3024,6 +3173,15 @@
"version": "1.1.3",
"license": "MIT"
},
+ "node_modules/dom-helpers": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
+ "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
+ "dependencies": {
+ "@babel/runtime": "^7.8.7",
+ "csstype": "^3.0.2"
+ }
+ },
"node_modules/dot-prop": {
"version": "5.3.0",
"dev": true,
@@ -4636,6 +4794,17 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
"node_modules/lru-cache": {
"version": "5.1.1",
"license": "ISC",
@@ -8720,6 +8889,14 @@
"inBundle": true,
"license": "ISC"
},
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/object-inspect": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
@@ -9300,6 +9477,16 @@
"node": ">=6"
}
},
+ "node_modules/prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "dependencies": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ }
+ },
"node_modules/property-information": {
"version": "6.4.0",
"license": "MIT",
@@ -9418,6 +9605,93 @@
"rc": "cli.js"
}
},
+ "node_modules/react": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
+ "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
+ "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.0"
+ },
+ "peerDependencies": {
+ "react": "^18.2.0"
+ }
+ },
+ "node_modules/react-fast-compare": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
+ "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="
+ },
+ "node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ },
+ "node_modules/react-popper": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz",
+ "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==",
+ "dependencies": {
+ "react-fast-compare": "^3.0.1",
+ "warning": "^4.0.2"
+ },
+ "peerDependencies": {
+ "@popperjs/core": "^2.0.0",
+ "react": "^16.8.0 || ^17 || ^18",
+ "react-dom": "^16.8.0 || ^17 || ^18"
+ }
+ },
+ "node_modules/react-refresh": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz",
+ "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-transition-group": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
+ "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
+ "dependencies": {
+ "@babel/runtime": "^7.5.5",
+ "dom-helpers": "^5.0.1",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2"
+ },
+ "peerDependencies": {
+ "react": ">=16.6.0",
+ "react-dom": ">=16.6.0"
+ }
+ },
+ "node_modules/reactstrap": {
+ "version": "9.2.1",
+ "resolved": "https://registry.npmjs.org/reactstrap/-/reactstrap-9.2.1.tgz",
+ "integrity": "sha512-3d+jo7EEw1GxobrSeTjs+Vq1SNrMnRTcwKp3/t1ufrceTLFHS6LpAck4eLKlzvgQgTpSJpLeJtVQKSqkxbHTiQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.12.5",
+ "@popperjs/core": "^2.6.0",
+ "classnames": "^2.2.3",
+ "prop-types": "^15.5.8",
+ "react-popper": "^2.2.4",
+ "react-transition-group": "^4.4.2"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
+ }
+ },
"node_modules/readable-stream": {
"version": "3.6.2",
"license": "MIT",
@@ -9448,6 +9722,11 @@
"esprima": "~4.0.0"
}
},
+ "node_modules/regenerator-runtime": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
+ "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
+ },
"node_modules/registry-auth-token": {
"version": "5.0.2",
"dev": true,
@@ -9769,6 +10048,14 @@
"version": "1.3.0",
"license": "ISC"
},
+ "node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
"node_modules/section-matter": {
"version": "1.0.0",
"license": "MIT",
@@ -11135,6 +11422,11 @@
"node": ">= 0.8"
}
},
+ "node_modules/ultrahtml": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.5.2.tgz",
+ "integrity": "sha512-qh4mBffhlkiXwDAOxvSGxhL0QEQsTbnP9BozOK3OYPEGvPvdWzvAUaXNtUSMdNsKDtuyjEbyVUPFZ52SSLhLqw=="
+ },
"node_modules/undici-types": {
"version": "5.26.5",
"license": "MIT"
@@ -11564,6 +11856,14 @@
}
}
},
+ "node_modules/warning": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
+ "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
+ "dependencies": {
+ "loose-envify": "^1.0.0"
+ }
+ },
"node_modules/web-namespaces": {
"version": "2.0.1",
"license": "MIT",
diff --git a/packages/formidable/src/ExtendedFormData.ts b/packages/formidable/src/ExtendedFormData.ts
index c741cb0..7ed336c 100644
--- a/packages/formidable/src/ExtendedFormData.ts
+++ b/packages/formidable/src/ExtendedFormData.ts
@@ -1,12 +1,12 @@
-import {File as FormidableFile} from 'formidable';
+import {VolatileFile} from 'formidable';
-export type FormDataValue = string | FormidableFile;
+export type FormDataValue = string | typeof VolatileFile;
export default class ExtendedFormData {
#data = new Map();
#validateFileType(value: FormDataValue) {
- if (typeof value != 'string' && !(value instanceof FormidableFile)) {
+ if (typeof value != 'string' && !(value instanceof VolatileFile)) {
return String(value);
}
return value;
@@ -43,13 +43,13 @@ export default class ExtendedFormData {
return this.getAll(name).filter(value => typeof value == 'string') as string[];
}
- getFile(name: string): FormidableFile | null {
+ getFile(name: string): typeof VolatileFile | null {
const value = this.get(name);
- return value instanceof FormidableFile ? value as FormidableFile : null;
+ return value instanceof VolatileFile ? value as typeof VolatileFile : null;
}
- getAllFiles(name: string): FormidableFile[] {
- return this.getAll(name).filter(value => value instanceof File) as FormidableFile[];
+ getAllFiles(name: string): (typeof VolatileFile)[] {
+ return this.getAll(name).filter(value => value instanceof File) as (typeof VolatileFile)[];
}
has(name: string): boolean {
diff --git a/packages/formidable/src/index.ts b/packages/formidable/src/index.ts
index 6ea0887..d0ff0f2 100644
--- a/packages/formidable/src/index.ts
+++ b/packages/formidable/src/index.ts
@@ -1,4 +1,4 @@
-import formidable, {PersistentFile} from 'formidable';
+import formidable, {VolatileFile} from 'formidable';
import {EventEmitter} from 'node:events';
import ExtendedFormData, {FormDataValue} from './ExtendedFormData.js';
@@ -63,8 +63,8 @@ export default async function parseAstroForm(request: Request, options?: formida
}
export function isFormidableFile(object: any) {
- return object instanceof PersistentFile;
+ return object instanceof VolatileFile;
}
-export {PersistentFile, FormDataValue, ExtendedFormData};
+export {VolatileFile, FormDataValue, ExtendedFormData};
diff --git a/packages/forms/.idea/.gitignore b/packages/forms/.idea/.gitignore
new file mode 100644
index 0000000..b58b603
--- /dev/null
+++ b/packages/forms/.idea/.gitignore
@@ -0,0 +1,5 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/packages/forms/.idea/forms.iml b/packages/forms/.idea/forms.iml
new file mode 100644
index 0000000..24643cc
--- /dev/null
+++ b/packages/forms/.idea/forms.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/forms/.idea/modules.xml b/packages/forms/.idea/modules.xml
new file mode 100644
index 0000000..ce2b651
--- /dev/null
+++ b/packages/forms/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/forms/.idea/vcs.xml b/packages/forms/.idea/vcs.xml
new file mode 100644
index 0000000..b2bdec2
--- /dev/null
+++ b/packages/forms/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/forms/README.md b/packages/forms/README.md
index 6c79231..6e19064 100644
--- a/packages/forms/README.md
+++ b/packages/forms/README.md
@@ -48,8 +48,7 @@ import {WebForms} from '@astro-utils/forms/forms.js';
### Simple example
```astro
---
-import { Bind } from "@astro-utils/forms";
-import { BindForm, Button, Input } from "@astro-utils/forms/forms.js";
+import { Bind, BindForm, BButton, BInput } from "@astro-utils/forms/forms.js";
import Layout from "../layouts/Layout.astro";
const form = Bind();
@@ -64,12 +63,12 @@ function formSubmit(){
{showSubmitText}
What you name*
-
+
Enter age*
-
+
-
+ Submit
```
@@ -79,8 +78,7 @@ function formSubmit(){
`pages/index.astro`
```astro
---
-import { BindForm, Button, FormErrors, Input, Option, Select, Textarea } from "@astro-utils/forms/forms.js";
-import { Bind } from "@astro-utils/forms";
+import { Bind, BindForm, FormErrors, BButton, BInput, BOption, BSelect, BTextarea } from "@astro-utils/forms/forms.js";
import Layout from "../layouts/Layout.astro";
type formType = {
@@ -110,23 +108,23 @@ function formSubmit(){
What you name*
-
+
Enter age*
-
+
Tell about yourself
-
+
What you favorite food?
-
+
+ Idk
+ Pizaa
+ Salad
+ Lasagna
+
-
+ Submit
{showSubmitText && <>
You submitted the form:
@@ -142,8 +140,10 @@ You can also use this as a simple on click hook
```astro
---
-import { Button } from "@astro-utils/forms/forms.js";
-const { session } = Astro.locals
+import { BButton } from "@astro-utils/forms/forms.js";
+import { Button } from 'reactstrap';
+
+const { session } = Astro.locals;
function increaseCounter() {
session.counter ??= 0
@@ -151,7 +151,7 @@ function increaseCounter() {
}
---
-
+ ++
{session.counter}
```
diff --git a/packages/forms/components/form/BButton.astro b/packages/forms/components/form/BButton.astro
new file mode 100644
index 0000000..8ba4ecb
--- /dev/null
+++ b/packages/forms/components/form/BButton.astro
@@ -0,0 +1,31 @@
+---
+import getContext from '@astro-utils/context';
+import {createUniqueContinuanceName} from '../../dist/form-tools/connectId.js';
+import {isPost, validateAction} from '../../dist/form-tools/post.js';
+
+export interface Props> extends astroHTML.JSX.ButtonHTMLAttributes {
+ onClick: Function;
+ connectId?: string;
+ whenFormOK?: boolean;
+ as?: T;
+ props?: React.ComponentProps;
+}
+
+const {as: asComponent = 'button', props: componentProps, onClick, whenFormOK, connectId = createUniqueContinuanceName(onClick), ...props} = Astro.props;
+const {bind, executeAfter} = getContext(Astro, '@astro-utils/forms');
+
+const checkFormValidation = whenFormOK && !bind?.errors.length || !whenFormOK;
+
+if (isPost(Astro) && await validateAction(Astro, 'button-callback', connectId) && checkFormValidation) {
+ if (executeAfter) {
+ executeAfter.push(onClick);
+ } else {
+ await onClick();
+ }
+}
+
+const Component = asComponent as any;
+---
+
+
+
diff --git a/packages/forms/components/form/BInput.astro b/packages/forms/components/form/BInput.astro
new file mode 100644
index 0000000..b805206
--- /dev/null
+++ b/packages/forms/components/form/BInput.astro
@@ -0,0 +1,38 @@
+---
+import getContext from '@astro-utils/context';
+import {caseTypes, inputReturnValueAttr, validateFormInput} from '../../dist/components/input-parse.js';
+import {validatePostRequest} from '../../dist/form-tools/post.js';
+import {ModifyDeep} from '../../dist/utils.js';
+
+type inputTypes = astroHTML.JSX.InputHTMLAttributes['type'] | 'int';
+
+interface ModifyInputProps {
+ type?: inputTypes;
+ pattern?: RegExp;
+ minlength?: number;
+ maxlength?: number;
+}
+
+export interface Props> extends Partial> {
+ name: string;
+ errorMessage?: string;
+ validate?: Function;
+ as?: T;
+ props?: React.ComponentProps;
+};
+
+const {bind, method, webFormsSettings} = getContext(Astro, '@astro-utils/forms');
+if (!Astro.props.disabled && method === 'POST' && await validatePostRequest(Astro as any)) {
+ await validateFormInput(Astro, bind);
+}
+
+const {as: asComponent = 'input', props: componentProps, type = 'text', pattern, ...props} = Astro.props;
+const castProps = caseTypes(type);
+const inputValue = inputReturnValueAttr(Astro, bind);
+
+const allProps = {...inputValue, ...props, ...componentProps, pattern: pattern?.toString(), ...castProps};
+webFormsSettings.haveFileUpload ||= allProps.type === 'file';
+
+const Component = asComponent as any;
+---
+
diff --git a/packages/forms/components/form/BOption.astro b/packages/forms/components/form/BOption.astro
new file mode 100644
index 0000000..949816d
--- /dev/null
+++ b/packages/forms/components/form/BOption.astro
@@ -0,0 +1,27 @@
+---
+import getContext from '@astro-utils/context';
+import {validatePostRequest} from '../../dist/form-tools/post.js';
+import {validateSelectOption} from '../../dist/components/select.js';
+
+export interface Props> extends astroHTML.JSX.OptionHTMLAttributes {
+ as?: T;
+ props?: React.ComponentProps;
+};
+
+const {bind, name, value: selectValue, allowSelected, method} = getContext(Astro, '@astro-utils/forms');
+
+const htmlSolt = await Astro.slots.render('default');
+if (!Astro.props.disabled && method === 'POST' && await validatePostRequest(Astro as any)) {
+ validateSelectOption(Astro, bind, name, htmlSolt);
+}
+
+const optionValue = Astro.props.value ?? htmlSolt;
+const {as: asComponent = 'option', props: componentProps, selected, ...props} = Astro.props;
+
+const isSelectedByDefault = allowSelected && selectValue.length == 0;
+
+const Component = asComponent as any;
+---
+
+
+
diff --git a/packages/forms/components/form/BSelect.astro b/packages/forms/components/form/BSelect.astro
new file mode 100644
index 0000000..03917dd
--- /dev/null
+++ b/packages/forms/components/form/BSelect.astro
@@ -0,0 +1,38 @@
+---
+import {validatePostRequest} from '../../dist/form-tools/post.js';
+import {validateSelect} from '../../dist/components/select.js';
+import {getSelectValue} from '../../dist/components/select.js';
+import getContext from '@astro-utils/context';
+import Context from '@astro-utils/context/Context.astro';
+
+export interface Props> extends astroHTML.JSX.SelectHTMLAttributes {
+ name: string
+ errorMessage?: string
+ type?: 'string' | 'number' | 'date',
+ as?: T;
+ props?: React.ComponentProps;
+};
+
+const {bind, method} = getContext(Astro, '@astro-utils/forms');
+
+const {as: asComponent = 'select', props: componentProps, value: defaultValue, ...props} = Astro.props;
+let value = bind[Astro.props.name] ?? defaultValue;
+
+if (!Astro.props.disabled && method === 'POST' && await validatePostRequest(Astro as any)) {
+ await validateSelect(Astro, bind);
+ value = await getSelectValue(Astro);
+}
+
+
+const isValueNotArray = !Array.isArray(value);
+if (isValueNotArray) {
+ value = value != null ? [value] : [];
+}
+
+const Component = asComponent as any;
+---
+
+
+
+
+
diff --git a/packages/forms/components/form/BTextarea.astro b/packages/forms/components/form/BTextarea.astro
new file mode 100644
index 0000000..182f92e
--- /dev/null
+++ b/packages/forms/components/form/BTextarea.astro
@@ -0,0 +1,30 @@
+---
+import getContext from '@astro-utils/context';
+import {validateFormInput} from '../../dist/components/input-parse.js';
+import {validatePostRequest} from '../../dist/form-tools/post.js';
+import {ModifyDeep} from '../../dist/utils.js';
+
+interface ModifyInputProps {
+ minlength?: number;
+ maxlength?: number;
+}
+
+export interface Props> extends Partial> {
+ name: string;
+ errorMessage?: string;
+ validate?: Function;
+ as?: T;
+ props?: React.ComponentProps;
+};
+
+const {bind, method} = getContext(Astro, '@astro-utils/forms');
+if (!Astro.props.disabled && method === 'POST' && await validatePostRequest(Astro as any)) {
+ await validateFormInput(Astro, bind);
+}
+
+const {as: asComponent = 'textarea', props: componentProps, value: defaultValue, ...props} = Astro.props;
+const value = bind[Astro.props.name] ?? await Astro.slots.render('default') ?? defaultValue;
+
+const Component = asComponent as any;
+---
+{value}
diff --git a/packages/forms/components/form/BindForm.astro b/packages/forms/components/form/BindForm.astro
index 22d879f..43d8c6f 100644
--- a/packages/forms/components/form/BindForm.astro
+++ b/packages/forms/components/form/BindForm.astro
@@ -11,7 +11,7 @@ const context = {executeAfter: [], method: Astro.request.method, bind};
let htmlSolt = await asyncContext(() => Astro.slots.render('default'), Astro, {name: "@astro-utils/forms", context});
bind?.finishFormValidation();
for(const func of context.executeAfter){
- await func();
+ await (func as any)();
}
diff --git a/packages/forms/components/form/Button.astro b/packages/forms/components/form/Button.astro
deleted file mode 100644
index 03809fd..0000000
--- a/packages/forms/components/form/Button.astro
+++ /dev/null
@@ -1,28 +0,0 @@
----
-import getContext from "@astro-utils/context";
-import { createUniqueContinuanceName } from "../../dist/form-tools/connectId.js";
-import { isPost, validateAction } from "../../dist/form-tools/post.js";
-
-export interface Props extends astroHTML.JSX.ButtonHTMLAttributes {
- onClick: Function;
- connectId?: string
- whenFormOK?: boolean
-}
-
-const {onClick, whenFormOK, connectId = createUniqueContinuanceName(onClick), ...props} = Astro.props;
-const {bind, executeAfter} = getContext(Astro, "@astro-utils/forms");
-
-const checkFormValidation = whenFormOK && !bind?.errors.length || !whenFormOK;
-
-if (isPost(Astro) && await validateAction(Astro, 'button-callback', connectId) && checkFormValidation) {
- if (executeAfter) {
- executeAfter.push(onClick);
- } else {
- await onClick();
- }
-}
-
----
-
diff --git a/packages/forms/components/form/Input.astro b/packages/forms/components/form/Input.astro
deleted file mode 100644
index 21e40a7..0000000
--- a/packages/forms/components/form/Input.astro
+++ /dev/null
@@ -1,34 +0,0 @@
----
-import getContext from "@astro-utils/context";
-import { caseTypes, inputReturnValueAttr, validateFormInput } from "../../dist/components/input-parse.js";
-import { validatePostRequest } from "../../dist/form-tools/post.js";
-import { ModifyDeep } from "../../dist/utils.js";
-
-type inputTypes = astroHTML.JSX.InputHTMLAttributes['type'] | "int";
-
-interface ModifyInputProps {
- type?: inputTypes
- pattern?: RegExp
- minlength?: number
- maxlength?: number
-}
-
-export interface Props extends Partial> {
- name: string
- errorMessage?: string
- validate?: Function
-};
-
-const {bind, method, webFormsSettings} = getContext(Astro, "@astro-utils/forms");
-if(!Astro.props.disabled && method === "POST" && await validatePostRequest(Astro as any)){
- await validateFormInput(Astro, bind);
-}
-
-const {type = "text", pattern, ...props} = Astro.props;
-const castProps = caseTypes(type);
-const inputValue = inputReturnValueAttr(Astro, bind);
-
-const allProps = {...inputValue, ...props, pattern: pattern?.toString(), ...castProps};
-webFormsSettings.haveFileUpload ||= allProps.type === 'file';
----
-
diff --git a/packages/forms/components/form/Option.astro b/packages/forms/components/form/Option.astro
deleted file mode 100644
index 9ae1a60..0000000
--- a/packages/forms/components/form/Option.astro
+++ /dev/null
@@ -1,23 +0,0 @@
----
-import getContext from "@astro-utils/context";
-import { validatePostRequest } from "../../dist/form-tools/post.js";
-import { validateSelectOption } from "../../dist/components/select.js";
-
-export interface Props extends astroHTML.JSX.OptionHTMLAttributes {
-};
-
-const {bind, name, value: selectValue, allowSelected, method} = getContext(Astro, "@astro-utils/forms");
-
-const htmlSolt = await Astro.slots.render('default');
-if(!Astro.props.disabled && method === "POST" && await validatePostRequest(Astro as any)){
- validateSelectOption(Astro, bind, name, htmlSolt);
-}
-
-const optionValue = Astro.props.value ?? htmlSolt;
-const {selected, ...props} = Astro.props;
-
-const isSelectedByDefault = allowSelected && selectValue.length == 0;
----
-
diff --git a/packages/forms/components/form/Select.astro b/packages/forms/components/form/Select.astro
deleted file mode 100644
index e560e08..0000000
--- a/packages/forms/components/form/Select.astro
+++ /dev/null
@@ -1,35 +0,0 @@
----
-import { validatePostRequest } from '../../dist/form-tools/post.js';
-import { validateSelect } from '../../dist/components/select.js';
-import { getSelectValue } from '../../dist/components/select.js';
-import getContext from '@astro-utils/context';
-import Context from '@astro-utils/context/Context.astro';
-
-export interface Props extends astroHTML.JSX.SelectHTMLAttributes {
- name: string
- errorMessage?: string
- type?: 'string' | 'number' | 'date'
-};
-
-const {bind, method} = getContext(Astro, "@astro-utils/forms");
-
-const {value: defaultValue, ...props} = Astro.props;
-let value = bind[Astro.props.name] ?? defaultValue;
-
-if(!Astro.props.disabled && method === "POST" && await validatePostRequest(Astro as any)){
- await validateSelect(Astro, bind);
- value = await getSelectValue(Astro);
-}
-
-
-const isValueNotArray = !Array.isArray(value);
-if(isValueNotArray){
- value = value != null ? [value]: [];
-}
-
----
-
-
-
diff --git a/packages/forms/components/form/Textarea.astro b/packages/forms/components/form/Textarea.astro
deleted file mode 100644
index 2896a59..0000000
--- a/packages/forms/components/form/Textarea.astro
+++ /dev/null
@@ -1,27 +0,0 @@
----
-import getContext from "@astro-utils/context";
-import { validateFormInput } from "../../dist/components/input-parse.js";
-import { validatePostRequest } from "../../dist/form-tools/post.js";
-import { ModifyDeep } from "../../dist/utils.js";
-
-interface ModifyInputProps {
- minlength?: number
- maxlength?: number
-}
-
-export interface Props extends Partial> {
- name: string
- errorMessage?: string
- validate?: Function
-};
-
-const {bind, method} = getContext(Astro, "@astro-utils/forms");
-if(!Astro.props.disabled && method === "POST" && await validatePostRequest(Astro as any)){
- await validateFormInput(Astro, bind);
-}
-
-const {value: defaultValue, ...props} = Astro.props;
-const value = bind[Astro.props.name] ?? await Astro.slots.render('default') ?? defaultValue;
-
----
-
diff --git a/packages/forms/forms.ts b/packages/forms/forms.ts
index a1d6be7..5c64387 100644
--- a/packages/forms/forms.ts
+++ b/packages/forms/forms.ts
@@ -1,20 +1,21 @@
-//@ts-nocheck
-import BindForm from "./components/form/BindForm.astro";
-import Button from "./components/form/Button.astro";
-import FormErrors from "./components/form/FormErrors.astro";
-import Input from "./components/form/Input.astro";
-import Textarea from "./components/form/Textarea.astro";
-import Option from "./components/form/Option.astro";
-import Select from "./components/form/Select.astro";
-import WebForms from "./components/WebForms.astro";
+import BindForm from './components/form/BindForm.astro';
+import BButton from './components/form/BButton.astro';
+import FormErrors from './components/form/FormErrors.astro';
+import BInput from './components/form/BInput.astro';
+import BTextarea from './components/form/BTextarea.astro';
+import BOption from './components/form/BOption.astro';
+import BSelect from './components/form/BSelect.astro';
+import WebForms from './components/WebForms.astro';
+import Bind from './dist/components/form-utils/bind-form.js';
export {
+ Bind,
BindForm,
- Button,
+ BButton,
FormErrors,
- Input,
- Textarea,
- Option,
- Select,
+ BInput,
+ BTextarea,
+ BOption,
+ BSelect,
WebForms
-}
\ No newline at end of file
+}
diff --git a/packages/forms/package.json b/packages/forms/package.json
index 12f0dbd..48aab02 100644
--- a/packages/forms/package.json
+++ b/packages/forms/package.json
@@ -15,6 +15,7 @@
"react",
"hooks"
],
+ "funding": "https://github.com/sponsors/ido-pluto",
"homepage": "https://withastro-utils.github.io/docs/",
"author": "Ido S.",
"license": "MIT",
diff --git a/packages/forms/src/form-tools/post.ts b/packages/forms/src/form-tools/post.ts
index 3410c76..2e46c25 100644
--- a/packages/forms/src/form-tools/post.ts
+++ b/packages/forms/src/form-tools/post.ts
@@ -1,4 +1,4 @@
-import parseAstroForm, {ExtendedFormData, FormDataValue, PersistentFile} from '@astro-utils/formidable';
+import parseAstroForm, {ExtendedFormData, FormDataValue, VolatileFile} from '@astro-utils/formidable';
import {FORM_OPTIONS} from '../settings.js';
import {AstroLinkHTTP} from '../utils.js';
import {validateFrom} from './csrf.js';
@@ -10,7 +10,7 @@ export function isPost(astro: {request: Request}){
function extractDeleteMethods(formData: ExtendedFormData | FormData){
return [...formData].map(([_, value]) => {
- if (value instanceof PersistentFile) {
+ if (value instanceof VolatileFile) {
return value.destroy.bind(value);
}
}).filter(Boolean);
diff --git a/packages/forms/src/index.ts b/packages/forms/src/index.ts
index 2dc405d..d57362e 100644
--- a/packages/forms/src/index.ts
+++ b/packages/forms/src/index.ts
@@ -1,10 +1,8 @@
-import type {File as PersistentFile} from "formidable";
-import Bind from "./components/form-utils/bind-form.js";
-import astroMiddleware from "./middleware.js";
+import type {File as PersistentFile} from 'formidable';
+import astroMiddleware from './middleware.js';
export {
PersistentFile,
- astroMiddleware as default,
- Bind
+ astroMiddleware as default
};
diff --git a/packages/forms/src/settings.ts b/packages/forms/src/settings.ts
index 3b9ccb9..9abf84d 100644
--- a/packages/forms/src/settings.ts
+++ b/packages/forms/src/settings.ts
@@ -16,13 +16,12 @@ export type FormsSettings = {
secret?: string
}
-declare global {
- export namespace App {
- export interface Locals {
- session: any;
- [key: string]: any
- }
+///
+declare namespace App {
+ export interface Locals {
+ session: { [key: string]: any };
}
}
+
export const FORM_OPTIONS: FormsSettings = {} as any;
diff --git a/packages/forms/src/utils.ts b/packages/forms/src/utils.ts
index d2ce905..5c48896 100644
--- a/packages/forms/src/utils.ts
+++ b/packages/forms/src/utils.ts
@@ -3,9 +3,10 @@ import {AstroGlobal} from 'astro';
export interface AstroLinkHTTP {
request: AstroGlobal['request']
cookies: AstroGlobal['cookies']
- locals: AstroGlobal['locals'] & { session: { [key: string]: any } };
+ locals: AstroGlobal['locals'];
}
+
export type ModifyDeep> = {
[K in keyof A | keyof B]: // For all keys in A and B:
K extends keyof A // ───┐