@jamesbattye-dev/ez-component
v0.0.2
Published
A tiny developer toolkit for Webflow projects. Helps you consistently manage components by scoping DOM selection, structured logging, and grabbing data attributes.
Maintainers
Readme
Webflow Component Helper
A tiny developer toolkit for Webflow projects. Helps you consistently manage "components" by scoping DOM selection, structured logging, and grabbing data attributes.
Package size: ~0.5 kB gzipped (GSAP is ~26.6 kB, making this helper ~53× smaller).
With vs Without Component Helper
Custom tabs without the helper (vanilla JS)
// Tiny log helper to avoid spamming production
function wfLog(label, ...args) {
const host = window.location.hostname;
const isWebflowDomain = host.endsWith('.webflow.io') || host === 'webflow.io';
if (isWebflowDomain) {
console.log('[Tabs]', label, ...args);
}
}
// Manually loop all tabs
document.querySelectorAll('.tabs').forEach((wrap, index) => {
const buttons = wrap.querySelectorAll('button');
const panes = wrap.querySelectorAll('.tab-pane');
// Grab data-* attributes manually
const attrs = { ...wrap.dataset };
buttons.forEach((btn, i) => {
btn.addEventListener('click', () => {
panes.forEach((p) => (p.hidden = true));
panes[i].hidden = false;
// Use our custom log each time
wfLog('Switched tab', { index, attrs, active: i });
});
});
});Custom tabs with the helper
new wfComponent('.tabs', function () {
const buttons = this.select('button'); // auto-scoped
const panes = this.select('.tab-pane'); // auto-scoped
buttons.forEach((btn, i) => {
btn.addEventListener('click', () => {
panes.forEach((p) => (p.hidden = true));
panes[i].hidden = false;
this.log('Switched tab', i, this.attributes); // logs only on *.webflow.io
});
});
});Examples
Animate a button with GSAP
import { wfComponent } from 'webflow-component-helper';
import gsap from 'gsap';
new wfComponent('.button', function () {
gsap.from(this.wrap, {
y: 100,
});
});Tabs Component
new wfComponent('.tabs', function () {
const buttons = this.select('button');
const panes = this.select('.tab-pane');
buttons.forEach((btn, i) => {
btn.addEventListener('click', () => {
panes.forEach((p) => (p.hidden = true));
panes[i].hidden = false;
this.log('Switched to tab', i);
});
});
});Benefits:
- Logging is built in — no need for a custom helper.
- Attributes already exposed as
this.attributes. - Scoped queries are automatic.
- Instances are tracked (
wfComponent.list(),wfComponent.count()).
Features
- 🔍 Scoped selection:
this.select()always scoped to the component root. - 🪵 Domain‑aware logging: logs only appear on
*.webflow.ioby default. - ⚡ Attributes helper: access
data-*attributes attached to the component root withthis.attributes. - 📊 Instance tracking: inspect all active components with
wfComponent.list().
Installation
Via NPM (local dev in VS Code)
npm i @jamesbattye-dev/ez-componentThen import into your project:
import { wfComponent } from '@jamesbattye-dev/ez-component';Via CDN (inside Webflow project settings > Custom Code)
Add this to the Before embed:
<script src="https://cdn.jsdelivr.net/npm/@jamesbattye-dev/[email protected]/dist/index.js"></script>API (How to use)
new wfComponent(selector, callbackFunction)
Loops all elements matching selector and runs your callbackFunction for each instance.
Inside the callback, this is a component object with:
this.wrap→ the root element (the selector you passed).this.index→ index of the instance (0-based).this.select(selector?)→ scoped query. If no selector, returns[this.wrap].this.log(...args)→ logs only on*.webflow.io.this.attributes→ object of alldata-*attributes on the root.this.selector→ the CSS selector used to create this instance.
Static helpers
wfComponent.list()→ get all instances created so far.wfComponent.count()→ number of active instances.wfComponent.clear()→ clear the tracked list.
Notes on this
When you use wfComponent, the callback is bound so that this refers to the component instance.
That means you must use a function() {} expression, not an arrow function:
// ✅ Correct
new wfComponent('.card', function () {
this.log(this.select('button'));
});
// ❌ Incorrect (arrow functions do not bind their own `this`)
new wfComponent('.card', () => {
this.log(this.select('button')); // 'this' is not the component here
});If you prefer arrows, you can instead access the component via the first argument:
new wfComponent('.card', (comp) => {
comp.log(comp.select('button'));
});Debugging
Logs only appear automatically on *.webflow.io preview domains.
When your site is on a custom domain, logs stay quiet (keeping production clean).
License
MIT
