DivDrop is a component-first CSS framework with a reactive JavaScript layer. All CSS classes use the dd- prefix. All CSS custom properties use --dd-. The JavaScript global is window.DD.
Enable dev warnings by setting window.DD_DEV = true before loading the script. Warnings appear in the browser console for invalid attributes or missing elements.
Getting Started
Installation
Add the CSS in <head> and the JS before </body>. No npm, no build step.
<!-- Optional: prevents theme flash on first load -->
<script>
(function(){
var t = localStorage.getItem('dd-theme');
if (t) document.documentElement.setAttribute('data-dd-theme', t);
})();
</script>
<!-- CSS in <head> -->
<link rel="stylesheet"
href="https://divdrop.io/CDN/CSS/Def/divdrop.css">
<!-- JS before </body> -->
<script src="https://divdrop.io/CDN/JS/divdrop.js"></script>
Foundation
Design Tokens CSS
Every visual property flows through CSS custom properties. Override any token in a <style> tag after the CDN link. The inline style tag wins because it loads later in the cascade.
<hr class="dd-divider"> <!-- full line -->
<div class="dd-divider">or</div> <!-- text in middle -->
<hr class="dd-divider dd-divider-line"> <!-- lighter line -->
<div class="dd-divider-v"></div> <!-- vertical -->
Add data-dd-validate to a <form>. Validation runs on submit and on blur. Errors have role="alert" so screen readers announce them. Fields are linked to errors via aria-describedby.
DivDrop JS auto-initialises on DOMContentLoaded. The global DD object is available immediately. window.DivDrop is an alias. Enable dev warnings: window.DD_DEV = true before the script.
DD.version // '1.0.0'
DD.themes // ['light','dark','midnight','forest','sand','rose','slate','carbon','paper']
DD.setTheme(name) // switch theme + save to localStorage
DD.store(initial) // create reactive store
DD.binder(store) // create DOM binder
DD.globalStore(i) // single-page store — auto-mounts binder
DD.action(name, fn) // register named action
DD.dispatch(name, d)// fire action
DD.on(event, fn) // event bus subscribe
DD.off(event, fn) // event bus unsubscribe
DD.emit(event, data)// event bus emit
DD.router(routes) // hash router
DD.navigate(path) // programmatic navigation
DD.toast(opts) // show toast notification
DD.setBellCount(n) // update nav bell badge
JavaScript
Reactive Store JS
const store = DD.store({ count: 0, name: 'DivDrop' });
store.get('count') // → 0
store.set('count', 5) // set value
store.update('count', n => n + 1) // update with function
store.patch({ count: 3, name: 'DD' }) // set multiple keys
store.subscribe('count', (val, prev) => console.log(val, prev))
store.watch(['count','name'], (key, val) => {})
store.derived('doubled', () => store.get('count') * 2)
store.snapshot() // plain object copy
store.reset() // back to initial values
For most single-page use cases use DD.globalStore() — it creates the store, auto-mounts the binder, and makes it available as DD._store.
// Programmatic
DD.setTheme('forest'); // validates, sets attr, saves to localStorage
DD.themes; // ['light','dark','midnight','forest',…]
// HTML attribute — set theme on click
<button data-dd-set-theme="midnight">Go Midnight</button>
// Toggle button — cycles light ↔ dark
<button data-dd-theme-toggle aria-label="Toggle dark mode">🌙</button>
// Listen to changes
DD.on('dd:theme-change', ({ theme }) => console.log(theme));
JavaScript
Toast API JS
// Simple
DD.toast('Message sent!');
// With options
DD.toast({
title: 'Success', // optional bold heading
message: 'File saved.', // body text (required)
type: 'success', // success | danger | warning | info
duration: 4000, // ms — default 3000
});
// Types: (default) | success | danger | warning | info
JavaScript
All data-dd-* Attributes HTML
Attribute
Effect
data-dd-theme
On <html> — sets active theme
data-dd-set-theme="name"
On any element — sets theme on click
data-dd-theme-toggle
Cycles light ↔ dark on click
data-dd-bind="key"
Two-way input ↔ store
data-dd-output="key"
Store → element textContent
data-dd-output-attr="attr:key"
Store → element attribute
data-dd-if="key"
Show/hide on truthy — supports == and !=
data-dd-show="key"
Show/hide via .is-visible class
data-dd-class="key:className"
Toggle class on truthy
data-dd-repeat="key"
List rendering from store array
data-dd-key="prop"
Inside repeat template — bind text
data-dd-key-attr="attr:prop"
Inside repeat template — bind attribute
data-dd-on-click="action.name"
Fire action on click
data-dd-on-change="action.name"
Fire action on change
data-dd-on-input="action.name"
Fire action on input
data-dd-on-submit="action.name"
Fire action on form submit
data-dd-payload='{}'
JSON payload sent with action
data-dd-route="/path"
Navigate to hash route on click
data-dd-modal-open="#id"
Open modal by id
data-dd-modal-close
Close nearest modal
data-dd-drawer-open="#id"
Open drawer by id
data-dd-drawer-close
Close nearest drawer
data-dd-dropdown-toggle
Toggle dropdown menu
data-dd-popover="#id"
Toggle popover by id
data-dd-accordion-single
On accordion parent — single open at a time
data-dd-toast="message"
Show toast on click
data-dd-toast-type="success"
Toast type: success | danger | warning | info
data-dd-processing="Label"
Button loading state on click
data-dd-duration="2000"
Processing duration in ms
data-dd-scroll-to="#id"
Smooth scroll to element
data-dd-clipboard="text"
Copy text to clipboard on click
data-dd-clipboard="#id"
Copy element text content
data-dd-confirm="Are you sure?"
Confirm dialog before proceeding
data-dd-confirm-type="danger"
Confirm dialog type
data-dd-validate
On <form> — enables built-in validation
data-dd-message="text"
Custom validation error message on field
data-dd-tooltip="text"
CSS tooltip (no JS)
data-dd-tooltip-pos="bottom"
Tooltip position: top | bottom | left | right
data-dd-sticky
Make element sticky on scroll
data-dd-sticky-offset="80"
Top offset in px for sticky
data-dd-lazy
Lazy-load image — use data-src instead of src
data-dd-nav-toggle
Hamburger — toggles nav panel open/closed
data-dd-bell
On nav bell element — opens notification panel
data-dd-bell-count="5"
Number shown in bell badge
JavaScript
Custom HTML Elements JS
dd-typewriter
<!-- Looping multi-phrase mode -->
<dd-typewriter
speed="150"
delete-speed="65"
pause="2400"
phrases='["Build fast.","Zero deps.","Ship today."]'>
</dd-typewriter>
<!-- Once mode — types once like an AI model, cursor blinks at end -->
<dd-typewriter once="true" speed="42">
Your full sentence types out once.
</dd-typewriter>
<!-- Attributes -->
<!-- speed="150" ms per character -->
<!-- delete-speed="65" ms per deletion -->
<!-- pause="2400" ms pause after each phrase -->
<!-- loop="false" type once (looping mode) -->
<!-- once="true" single-pass AI mode -->
<!-- caret="false" hide blinking cursor -->
dd-counter
<dd-counter to="4200" suffix="+" duration="1400">0</dd-counter>
<dd-counter to="99" suffix="%" duration="1000">0</dd-counter>
<dd-counter to="14.5" prefix="$" decimals="1">0</dd-counter>
<!-- Triggers on scroll into view -->