Skip to content
eustasyPublic

About

Open, accessible, customizable web components written as vanilla as possible.

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

1 watching

Forks

Repository files navigation

Open, accessible, themable web components — vanilla HTML, CSS, and minimal JavaScript.

Philosophy

  • Vanilla first. HTML, CSS, absolutely minimal JavaScript. No frameworks.
  • Themable. Every color, font, spacing value, border radius, and shadow is a CSS custom property. Swap the theme file to restyle everything.
  • Accessible. WCAG 2.2 AA as baseline. Keyboard navigation, focus-visible rings, screen-reader support, prefers-reduced-motion, and prefers-color-scheme are built in.
  • Drop-in. Each component works independently. Copy the HTML, link the CSS, done.

Quick Start

<!-- Option A: Link the built single-file (recommended) -->
<link rel="stylesheet" href="dist/ui.min.css" />

<!-- Option B: Link the source entry (uses @import, fine for dev) -->
<link rel="stylesheet" href="base/main.css" />

For dark/light mode toggling, add the script and a toggle button:

<script src="js/theme-ext-toggle.js"></script>
<button data-theme-toggle aria-label="Toggle dark mode">🌓</button>

Building

Lightning CSS bundles and minifies CSS; esbuild bundles and minifies JS.

npm install
npm run build    # → dist/ui.min.css + dist/*.min.js (bundled + minified)
npm run dev      # → CSS watch mode

Structure

themes/
  flexoki.css                 ← Flexoki 2.0 palette + semantic tokens + light/dark
base/
  main.css                    ← CSS source entry point (imports everything)
  reset.css                   ← modern CSS reset
  typography.css              ← headings, prose, lists, code, links
  forms.css                   ← shared form styles, validation states
  media.css                   ← images, details, progress, dialog
  grid.css                    ← reusable grid utilities (.cols-2/3/4, .grid-auto)
components/
  alert.css                   ← info, success, warning, danger, dismissible
  avatar.css                  ← image and initials variants
  badge.css                   ← color variants for all accent colors
  button.css                  ← primary, secondary, outline, ghost, danger, sizes
  card.css                    ← header/body/footer, image variant, compact
  checkbox.css                ← styled checkbox with indeterminate state
  contents.css                ← sticky sidebar table of contents
  combobox.css                ← searchable select extending listbox
  description-list.css        ← horizontal and vertical term/definition pairs
  dialog.css                  ← modal and non-modal dialog
  divider.css                 ← horizontal and vertical separators
  dropdown.css                ← trigger + floating menu
  fieldset.css                ← grouped form controls with legend
  heading.css                 ← display and section headings
  input.css                   ← text, number, date, and other input types
  listbox.css                 ← inline/dropdown listbox with icons, avatars, flags
  navbar.css                  ← responsive nav with logo, icons, indicators, dropdowns, vertical mode
  pagination.css              ← page navigation controls
  radio.css                   ← radio button group
  select.css                  ← native and custom select
  switch.css                  ← toggle switch (checkbox variant)
  table.css                   ← base styles, responsive wrapper, striped/grid/condensed/wide variants
  text.css                    ← inline text elements
  textarea.css                ← auto-resizing textarea
  user-menu.css               ← avatar dropdown for user account actions
js/
  alert-ext-dismiss.js        ← dismiss .alert on .alert-dismiss click
  checkbox-ext-select-all.js  ← select-all with indeterminate state
  contents-ext-bookmark.js    ← scroll-spy, h3 injection, and section collapse for contents
  dialog.js                   ← open/close native <dialog> via data attributes
  dropdown.js                 ← toggle .dropdown menus; click-outside + Escape
  input-ext-search.js         ← expand-on-focus search with / shortcut
  listbox.js                  ← panel and dropdown listbox; keyboard nav, multi-select, live region
  listbox-ext-combobox.js     ← filterable combobox extending listbox.js
  textarea-ext-count.js       ← character count for .textarea-field[maxlength]
  navbar-ext-indicator.js     ← animated sliding tab indicator, one active per navbar
  navbar.js                   ← toggle, overlay, and Escape for .navbar-toggle
  theme-ext-toggle.js         ← dark/light toggle with localStorage persistence
  user-menu.js                ← user menu open/close behaviour
layouts/
  auth.html / auth.css        ← centred authentication layout
  sidebar.html / sidebar.css  ← sidebar + main content layout (uses navbar classes)
  stacked.html / stacked.css  ← stacked (app shell) layout (uses navbar classes)
tests/
  elements.html               ← living reference of all styled HTML elements
  components.html             ← preview of all components
dist/
  ui.min.css                  ← built CSS output (gitignored)
  *.min.js                    ← built JS output (gitignored)

Theming

The theme system has three layers:

  1. Raw palette (--flexoki-red-600, etc.) — Flexoki 2.0's full extended palette.
  2. Design tokens (--space-4, --radius-md, --font-size-base) — spacing, typography, borders.
  3. Semantic tokens (--color-danger, --color-action, --color-surface) — what components actually use.

Light/dark mode is automatic via prefers-color-scheme. Override with .theme-light or .theme-dark on <html>.

To create a new theme, define the same semantic token variables in a new CSS file and swap the import.

Accessibility

  • Focus rings via :focus-visible (keyboard only, not mouse clicks)
  • aria-invalid, aria-required, aria-describedby patterns on forms
  • role="alert" and aria-live for dynamic messages
  • prefers-reduced-motion disables all animation/transitions
  • color-scheme declaration for native form control theming
  • Semantic HTML throughout: <nav>, <main>, <article>, <dialog>, <details>

Credits

Color palette: Flexoki by Steph Ango (MIT License).

About

Open, accessible, customizable web components written as vanilla as possible.

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages