formtress-js 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,27 @@
1
+ name: Publish Package to npmjs
2
+ on:
3
+ release:
4
+ types: [created]
5
+
6
+ jobs:
7
+ build:
8
+ runs-on: ubuntu-latest
9
+ permissions:
10
+ contents: read
11
+ packages: write
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - uses: pnpm/action-setup@v4.1.0
15
+ name: Install pnpm
16
+ with:
17
+ version: 8.15.5
18
+ - uses: actions/setup-node@v4
19
+ with:
20
+ node-version: 20
21
+ registry-url: 'https://registry.npmjs.org'
22
+ cache: 'pnpm'
23
+ - run: pnpm install --frozen-lockfile
24
+ - run: pnpm run build
25
+ - run: npm publish
26
+ env:
27
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ import { default as o } from "./webflow.js";
2
+ export {
3
+ o as webflow
4
+ };
@@ -0,0 +1,32 @@
1
+ function d() {
2
+ document.querySelectorAll('form[data-ft^="https://formtress"]').forEach((r) => {
3
+ const n = r.dataset.ft;
4
+ if (!n) return;
5
+ const s = r.closest(".w-form");
6
+ if (!s) return;
7
+ const t = s.querySelector(".w-button"), l = s.querySelector(".w-form-done"), e = s.querySelector(".w-form-fail");
8
+ if (!t || !l || !e) return;
9
+ let a = e.querySelector("[data-ft-error]");
10
+ a || (a = e.firstChild), r.addEventListener("submit", async function(c) {
11
+ c.preventDefault(), e.style.display = "none";
12
+ const i = t.value;
13
+ t.value = t.dataset.wait || "Please wait...";
14
+ const f = new FormData(r);
15
+ try {
16
+ const o = await fetch(n, {
17
+ method: "POST",
18
+ body: f,
19
+ mode: "cors",
20
+ credentials: "same-origin"
21
+ }), u = await o.text();
22
+ t.value = i, o.ok ? (r.style.display = "none", l.style.display = "block") : (console.error("Form submission failed:", o.status, o.statusText), a.textContent = u, e.style.display = "block");
23
+ } catch (o) {
24
+ console.error("Error submitting form:", o), a.textContent = "An error occurred. Please try again later.", e.style.display = "block", t.value = i;
25
+ }
26
+ });
27
+ });
28
+ }
29
+ typeof window < "u" && d();
30
+ export {
31
+ d as default
32
+ };
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "formtress-js",
3
+ "description": "A tiny library for managing Formtress forms",
4
+ "private": false,
5
+ "license": "MIT",
6
+ "main": "dist/index.js",
7
+ "version": "0.1.2",
8
+ "type": "module",
9
+ "homepage": "https://formtress.com",
10
+ "author": "Christos Soulaki",
11
+ "packageManager": "pnpm@8.15.5",
12
+ "scripts": {
13
+ "dev": "vite",
14
+ "build": "tsc && vite build",
15
+ "preview": "vite preview"
16
+ },
17
+ "devDependencies": {
18
+ "@types/node": "^22.14.1",
19
+ "typescript": "~5.7.2",
20
+ "vite": "^6.3.1"
21
+ }
22
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { default as webflow } from './webflow'
@@ -0,0 +1,55 @@
1
+ export default function webflow() {
2
+ const forms = document.querySelectorAll('form[data-ft^="https://formtress"]') as NodeListOf<HTMLFormElement>
3
+
4
+ forms.forEach((form) => {
5
+ const action = form.dataset.ft as string
6
+ if (!action) return
7
+ const formWrapper = form.closest('.w-form')
8
+ if (!formWrapper) return
9
+ const submitBtn = formWrapper.querySelector('.w-button') as HTMLInputElement
10
+ const success = formWrapper.querySelector('.w-form-done') as HTMLElement
11
+ const fail = formWrapper.querySelector('.w-form-fail') as HTMLElement
12
+ if (!submitBtn || !success || !fail) return
13
+
14
+ let failText = fail.querySelector('[data-ft-error]') as HTMLElement | null
15
+ if (!failText) {
16
+ failText = fail.firstChild as HTMLElement
17
+ }
18
+
19
+ form.addEventListener('submit', async function (e: Event) {
20
+ e.preventDefault()
21
+ fail.style.display = 'none'
22
+ const initialButtonText = submitBtn.value
23
+ submitBtn.value = submitBtn.dataset.wait || 'Please wait...'
24
+ const formData = new FormData(form)
25
+ try {
26
+ const response = await fetch(action, {
27
+ method: 'POST',
28
+ body: formData,
29
+ mode: 'cors',
30
+ credentials: 'same-origin'
31
+ })
32
+ const message = await response.text()
33
+ submitBtn.value = initialButtonText
34
+
35
+ if (response.ok) {
36
+ form.style.display = 'none'
37
+ success.style.display = 'block'
38
+ } else {
39
+ console.error('Form submission failed:', response.status, response.statusText)
40
+
41
+ failText.textContent = message
42
+ fail.style.display = 'block'
43
+ }
44
+ } catch (error) {
45
+ console.error('Error submitting form:', error)
46
+ failText.textContent = 'An error occurred. Please try again later.'
47
+ fail.style.display = 'block'
48
+ submitBtn.value = initialButtonText
49
+ }
50
+ })
51
+ })
52
+ }
53
+
54
+ // Auto-initialize if this file is loaded directly via script tag
55
+ if (typeof window !== 'undefined') webflow()
package/tsconfig.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "module": "ESNext",
6
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
7
+ "skipLibCheck": true,
8
+
9
+ /* Bundler mode */
10
+ "moduleResolution": "bundler",
11
+ "allowImportingTsExtensions": true,
12
+ "isolatedModules": true,
13
+ "moduleDetection": "force",
14
+ "noEmit": true,
15
+
16
+ /* Linting */
17
+ "strict": true,
18
+ "noUnusedLocals": true,
19
+ "noUnusedParameters": true,
20
+ "noFallthroughCasesInSwitch": true,
21
+ "noUncheckedSideEffectImports": true
22
+ },
23
+ "include": ["src"]
24
+ }
package/vite.config.ts ADDED
@@ -0,0 +1,18 @@
1
+ import { resolve } from 'path'
2
+ import { defineConfig } from "vite"
3
+ import type { UserConfig } from "vite"
4
+
5
+ export default defineConfig({
6
+ base: "./",
7
+ build: {
8
+ lib: {
9
+ entry: {
10
+ webflow: resolve(__dirname, "src/webflow/index.ts"),
11
+ index: resolve(__dirname, "src/index.ts"),
12
+ },
13
+ name: "formtress",
14
+ formats: ["es"],
15
+ fileName: (format, entryName) => `${entryName}.js`,
16
+ },
17
+ },
18
+ } satisfies UserConfig)