Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

UI Kit Catalog

A small reusable UI kit built in vanilla JavaScript — Button, Card, Badge, Input Field, Modal, and Toast — each implemented as a self-contained, prop-driven function, mirroring how components work in React (createX(props) → DOM node).

Files

File Purpose
index.html Page structure / demo layout
style.css All styling (component styles, dark-mode tokens, catalog page styling)
script.js The 6 reusable component functions + the code that wires up the demo

Open index.html in a browser — no build step, no dependencies, no server required.

Requirements checklist

1. Four reusable UI elements as JS functions (plus 2 extra — see below)

  • createButton(props)script.js
  • createCard(props)script.js
  • createModal(props)script.js
  • showToast(props)script.js

2. Each accepts parameters instead of being hardcoded

createButton({ text, variant = 'primary', size = 'md', onClick, disabled = false, icon = null, loading = false })
createCard({ title, description = '', tag = '', variant = 'default', footerButtons = [] })
createModal({ title, body = '', actions = null })          // returns { open(), close() }
showToast({ message, type = 'info', duration = 4000 })

Every instance on the page is produced by calling these functions with different arguments — there is no duplicated/hand-written markup per variant.

3. Demo page uses each component multiple times with different props/variants

  • Buttons: all 4 variants, all 3 sizes, a disabled state, an icon button, and an async loading button.
  • Cards: 3 cards using the 3 variants, each with a different tag and footerButtons.
  • Modals: 3 separate modal instances (infoModal, confirmModal, stackedModal) triggered from 2 buttons.
  • Toasts: 4 buttons for each type, plus a button that fires 3 toasts in sequence.

4. Modal and Toast are fully functional

  • Modal open/close: .open() / .close() methods; also closes via the × button, a backdrop click, or the Escape key.
  • Modal stacking: click "Open info modal" → "Open a stacked modal" — a second dialog layers on top of the first with its own backdrop; Escape closes only the topmost modal (tracked via an openModals stack array).
  • Toast auto-dismiss: each toast is removed automatically after its duration (default 4000ms); a shrinking progress bar visualizes the countdown.
  • Toast stacking: toasts append to a fixed-position container and stack vertically; click "Fire 3 at once (stack)" to see several independent toasts, each with its own timer, coexist and dismiss separately. Every toast also has a manual × close button.

5. Reflection — how "thinking in components" changed the code

Earlier tasks started from a page and I wrote markup and logic wherever they were needed, so the same button or card ended up re-typed with small inconsistencies each time. Building this kit forced me to start from the element instead: decide what varies (text, variant, size) versus what stays fixed, and write one function that returns a DOM node for any combination of those props. That made the demo page itself much thinner — it's mostly just calls to createButton/createCard/createModal/showToast with different arguments, not hand-written HTML. It also pushed state and behavior (open/close, auto-dismiss timers, stacking order) inside each component's own function instead of scattering them across page-level event listeners, which helped me understand the separation between reusable component logic and the page that uses it — one of the core ideas behind React.

(This is also included directly on the page itself, in the "Build notes" section.)

Extra features added beyond the base requirements

Feature What it does Where
Badge component (BADGE-600) createBadge({ text, tone }) — small status pill in 5 tones script.js
Input Field component (INPUT-500) createInput({ label, type, placeholder, value, helper, error, onChange }) — labeled field with helper/error text script.js
Button loading state loading prop + setButtonLoading(btn, isLoading) helper — swaps in a spinner and disables the button; demoed on the "Save (async)" button, which simulates a 1.5s request script.js
Dark / light theme toggle Button in the header flips data-theme on <html>; every component restyles instantly because colors are driven by shared CSS custom properties, not hardcoded values style.css, script.js
Copy-usage snippets Every spec panel has a "Copy usage" button that copies the exact createX({...}) call to the clipboard, with a toast confirmation index.html, script.js

Component API reference

createButton(props)

Prop Type Default
text string required
variant primary | secondary | ghost | danger primary
size sm | md | lg md
onClick function
disabled boolean false
icon string null
loading boolean false

setButtonLoading(btnElement, isLoading, loadingText?) — toggles the spinner/disabled state on a button after it's already been created (for async actions).

createCard(props)

Prop Type Default
title string required
description string ""
tag string ""
variant default | outlined | elevated default
footerButtons array of button props []

createBadge(props)

Prop Type Default
text string required
tone neutral | info | success | warning | danger neutral

createInput(props)

Prop Type Default
label string ""
type string (any HTML input type) text
placeholder string ""
value string ""
helper string
error string (overrides helper, adds error styling)
onChange function(value, event)

createModal(props){ open(), close() }

Prop Type Default
title string required
body string ""
actions array of button props [{ text: 'Close', ... }]

showToast(props)

Prop Type Default
message string required
type info | success | warning | danger info
duration ms (0 = sticky, no auto-dismiss) 4000

About

Reusable UI Kit built with Vanilla JavaScript

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages