Dynamic CSS from class names — no build step, no config.
/* property-value | hover:p-v | mobile:p-v | spaces->underscores */
<span class="padding-12px color-blue fontSize-16px">Hello</span>
<span class="hover:color-red">Hover me</span>
ECStyleSheet.process("paddingTop-16px");
let btn = new ECButton("Save");
btn.setTheme(ECTheme.Green);
let custom = new ECTheme({ primary:"#6a1b9a" });
let btn = new ECButton("Click Me");
btn.onClick(() => alert("Hi!"));
let outline = new ECButton("Outline", { variant:"outline" });
Starts closed — no flash on load.
let modal = new ECModal("My Modal");
modal.setContent("<p>Hello!</p>");
modal.addFooterButton("Close", () => modal.close(), "outline");
modal.open();
new ECToast("Saved!", { type:"success", duration:3000 }).show();
Starts closed — no flicker on load.
let topbar = new ECTopbar("My App");
topbar.addAction(menuBtn);
document.body.appendChild(topbar.element);
let badge = new ECBadge("Active", "success");
badge.setType("danger");
btn.setTheme(ECTheme.Dark).enableDarkMode();
Vertically collapsing FAQ list. One open at a time by default.
let acc = new ECAccordion({ allowMultiple:true, items:[
{ title:"Q", content:"A", open:true },
]});
acc.addItem("New Q", "New A");
let list = new ECList({ variant:"bordered" });
list.addItem("Item", () => alert("clicked"));
new ECList({ direction:"horizontal", variant:"hoverable" });
let crumbs = new ECBreadcrumbs([
{ label:"Home", href:"/" },
{ label:"Settings", href:"/settings" },
{ label:"Profile" },
]);
let stepper = new ECStepper(["Account","Details","Payment","Confirm"], 0);
stepper.next(); stepper.prev(); stepper.setStep(2);
new ECDivider();
new ECDivider({ label:"or" });
new ECDivider({ dashed:true, thick:true });
let bar = new ECProgressBar({ label:"Upload", value:65 });
bar.setValue(90); bar.setHeight(12); bar.setTheme(ECTheme.Green);
let s = new ECSpinner({ size:"lg" });
s.setTheme(ECTheme.Red);
Hover the buttons below.
let tip = new ECTooltip(myBtn, "Saves your work");
document.body.appendChild(tip.element);
Floating panel anchored to a trigger. Click outside to dismiss.
let popup = new ECPopup(triggerBtn);
popup.setContent("<p>Menu item</p>");
popup.setWidth(200);
Sortable columns, live search filter, and built-in pagination.
let table = new ECDataTable({
columns:[
{ key:"name", label:"Name" },
{ key:"status", label:"Status", render:(v) => `<b>${v}</b>` },
],
data:[{ name:"Alice", status:"Active" }],
pageSize:5,
});
table.setData(newRows); table.setPageSize(10);
let slider = new ECSlider({
label:"Volume", min:0, max:100, value:60, suffix:"%",
ticks:["0%","50%","100%"],
});
slider.onChange(v => console.log(v));
slider.setValue(80); slider.getValue();
Click to open. Navigate months with the arrow buttons. Click a date to select.
let picker = new ECDatePicker({ label:"Start date" });
picker.onChange(iso => console.log(iso)); // "YYYY-MM-DD"
picker.setValue("2025-12-25");
picker.getValue();
Drag files onto the zone or click Browse. Each file appears in the list with a remove button.
let up = new ECFileUpload({
accept:".pdf,.png", multiple:true, maxSize:5*1024*1024,
});
up.onChange(files => console.log(files));
up.getFiles(); up.clear();
Click to rate. Click the same star again to clear the rating.
let r = new ECRating({ value:3, max:5 });
r.onChange(val => console.log(val));
new ECRating({ value:4, readonly:true }); // display-only
new ECRating({ max:10 }); // custom max
Flexible post-style card with header, optional image, body, and footer actions.
let card = new ECMediaCard({
author:"Jane Doe", timestamp:"2 hours ago",
imageSrc:"photo.jpg", imageHeight:"160px",
content:"<p>Card body.</p>",
actions:[{ icon:"👍", label:"Like", onClick:() => {} }],
});
card.setWidth(300); card.addContent("More text");
Large jumbotron for landing pages. Supports eyebrow, title, subtitle, actions, and background.
let hero = new ECHero({
eyebrow:"Zero dependencies · Pure JS",
title:"Build UIs without the overhead",
subtitle:"Drop in two script tags and go.",
background:"linear-gradient(135deg,#e8f0fe 0%,#fce4ec 100%)",
actions:[
{ label:"Get Started" },
{ label:"Docs", variant:"outline" },
],
});
Nested hierarchical list for displaying folders, files, or tree structures.
let tree = new ECTreeView([
{ label: "Documents", expanded: true, children: [
{ label: "Projects", children: [{ label: "ECElements" }] },
{ label: "Invoices" }
]}
]);
Avatars with image fallback to initials. Indicators represent notification dots or online status.
let av = new ECAvatar({ initials: "JD", size: "48px" });
let indicator = new ECIndicator(av, { type: "online" });
Click the thumbnail to open the image viewer overlay.
let lb = new ECLightbox();
lb.open("image.jpg", "Beautiful Landscape");
Touch and click-friendly slider for images or cards.
let car = new ECCarousel([
"<img src='1.jpg' />",
cardComponent,
"<img src='3.jpg' />"
]);
Standard dismissible banners and looping marquee banners.
let banner = new ECBanner("Server maintenance at 2 AM.");
let marquee = new ECBanner("50% OFF SALE!", { loop: true });
Counts down to a specific target date (e.g., event launch).
let timer = new ECCountdown(new Date("2027-01-01"));
document.body.appendChild(timer.element);
Generates responsive CSS Grid layouts automatically.
let grid = new ECGrid({ columns: 3, gap: "16px" });
grid.addItem(card1);
grid.addItem(card2);
A bottom-sliding variation of the Sidebar component.
let drawer = new ECDrawer("Settings");
drawer.setContent("<p>Drawer content goes here.</p>");
drawer.open();