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.
- package/.github/workflows/publish.yml +27 -0
- package/dist/index.js +4 -0
- package/dist/webflow.js +32 -0
- package/package.json +22 -0
- package/src/index.ts +1 -0
- package/src/webflow/index.ts +55 -0
- package/tsconfig.json +24 -0
- package/vite.config.ts +18 -0
|
@@ -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
package/dist/webflow.js
ADDED
|
@@ -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)
|