From c595843590315ea176b814f73a5a5857495ad9b9 Mon Sep 17 00:00:00 2001 From: ido Date: Wed, 22 Nov 2023 13:20:27 +0200 Subject: [PATCH] BREAKING CHANGE: Change components names --- README.md | 13 +- examples/simple-form/astro.config.mjs | 6 +- examples/simple-form/package.json | 5 + examples/simple-form/src/pages/index.astro | 14 +- examples/simple-form/tsconfig.json | 6 +- package-lock.json | 300 ++++++++++++++++++ packages/formidable/src/ExtendedFormData.ts | 14 +- packages/formidable/src/index.ts | 6 +- packages/forms/.idea/.gitignore | 5 + packages/forms/.idea/forms.iml | 12 + packages/forms/.idea/modules.xml | 8 + packages/forms/.idea/vcs.xml | 6 + packages/forms/README.md | 40 +-- packages/forms/components/form/BButton.astro | 31 ++ packages/forms/components/form/BInput.astro | 38 +++ packages/forms/components/form/BOption.astro | 27 ++ packages/forms/components/form/BSelect.astro | 38 +++ .../forms/components/form/BTextarea.astro | 30 ++ packages/forms/components/form/BindForm.astro | 2 +- packages/forms/components/form/Button.astro | 28 -- packages/forms/components/form/Input.astro | 34 -- packages/forms/components/form/Option.astro | 23 -- packages/forms/components/form/Select.astro | 35 -- packages/forms/components/form/Textarea.astro | 27 -- packages/forms/forms.ts | 31 +- packages/forms/package.json | 1 + packages/forms/src/form-tools/post.ts | 4 +- packages/forms/src/index.ts | 8 +- packages/forms/src/settings.ts | 11 +- packages/forms/src/utils.ts | 3 +- 30 files changed, 582 insertions(+), 224 deletions(-) create mode 100644 packages/forms/.idea/.gitignore create mode 100644 packages/forms/.idea/forms.iml create mode 100644 packages/forms/.idea/modules.xml create mode 100644 packages/forms/.idea/vcs.xml create mode 100644 packages/forms/components/form/BButton.astro create mode 100644 packages/forms/components/form/BInput.astro create mode 100644 packages/forms/components/form/BOption.astro create mode 100644 packages/forms/components/form/BSelect.astro create mode 100644 packages/forms/components/form/BTextarea.astro delete mode 100644 packages/forms/components/form/Button.astro delete mode 100644 packages/forms/components/form/Input.astro delete mode 100644 packages/forms/components/form/Option.astro delete mode 100644 packages/forms/components/form/Select.astro delete mode 100644 packages/forms/components/form/Textarea.astro 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 // ───┐