| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Shared Web Components with theming for use across HOTOSM tools.
📖 Documentation:
https://ui.hotosm.org
🖥️ Source Code:
https://github.com/hotosm/ui
🎯 Roadmap / Tasks: https://github.com/orgs/hotosm/projects/37/views/3
Shared Web Components built with Lit and themed for HOTOSM tools using WebAwesome primitives.
Goals:
WebAwesome version: 3.11.0
pnpm install @hotosm/ui @awesome.me/webawesome@3.11.0Note
@awesome.me/webawesome is a peer dependency. Always pin it to the version shown above to avoid conflicts between HOT components and WebAwesome internals.
Use the single self-contained stylesheet (WebAwesome base styles + HOT theme inlined):
import "@hotosm/ui/dist/style.css";Or from CDN:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@hotosm/ui@3.0.0/dist/style.css" />style-core.css (HOT theme only, no WebAwesome) exists for pages that load the WebAwesome base stylesheets themselves - most apps don't need it.
Nothing to add. style.css and style-core.css include self-hosted @font-face rules for the HOT brand fonts: Archivo (--hot-font-sans), Barlow (--hot-font-sans-variant) and Barlow Condensed (--hot-font-sans-variant-condensed). The woff2 files ship in dist/assets/fonts as latin / latin-ext / vietnamese subsets with unicode-range, so browsers only download what a page renders. Remove any Google Fonts <link> for these families.
Scripts these fonts don't cover fall back to Helvetica (Apple) or Noto (Android / ChromeOS), then the system sans. Set lang on <html> and on any content in a different language from the page (e.g. user-created project names) - browsers use it to pick the right fallback, and it is what future per-language :lang() tweaks will hook onto.
See MADR 0014 and the font test page.
Add the required WebAwesome classes to your <html> element:
<!DOCTYPE html>
<html class="wa-theme-default wa-palette-hotosm">
<head>
...
</head>
<body>
...
</body>
</html>Important
These classes activate the HOT colour palette and light theme for every WebAwesome component on the page. Do not remove them.
brand, danger, warning and neutral follow the HOT palette with no extra classes. Since 3.0.0 brand follows HOT primary, which is grey (see hotosm/ui-design). success stays green rather than the HOT teal, which reads poorly against a red danger.
Any variant can take any hue via WebAwesome's variant classes, which override the theme - e.g. to opt in to the teal:
<html class="wa-theme-default wa-palette-hotosm wa-success-cyan"></html>Recommended: register all WebAwesome elements once, up front, so every custom element is defined before first render - this eliminates flash of undefined custom elements (FOUCE) without maintaining per-page import lists:
import "@hotosm/ui/dist/style.css";
import "@hotosm/ui/dist/webawesome-all.js"; // registers every wa-* element
import "@hotosm/ui/dist/components/header/header.js"; // hot-* components you use<hot-header title="My App"></hot-header>@hotosm/ui/vite provides build helpers for Vite 5, 7, and 8.
Add the circular chunk guard to catch chunk cycles that can cause a blank page at runtime:
// vite.config.ts
import { circularChunkGuard } from "@hotosm/ui/vite";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [circularChunkGuard()],
});Keep the guard enabled even if you do not split chunks manually. Dependency updates can also introduce cycles.
You can also place WebAwesome in its own chunk. This lets browsers keep it cached when the rest of your app changes:
For Vite 8:
// vite.config.ts
import { WEBAWESOME_CHUNK } from "@hotosm/ui/vite";
import { defineConfig } from "vite";
export default defineConfig({
build: {
rolldownOptions: {
output: {
codeSplitting: {
groups: [WEBAWESOME_CHUNK],
},
},
},
},
});For Vite 5-7:
// vite.config.ts
import { matchWebawesome } from "@hotosm/ui/vite";
import { defineConfig } from "vite";
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: (id) => matchWebawesome(id),
},
},
},
});This cache is per origin, so it is reused across deployments of the same app, not across different HOT tools.
Load the raw dist files, with an import map to resolve the bare @awesome.me/webawesome/... imports in webawesome-all.js. The map's WebAwesome pin must match the version this @hotosm/ui release was built against. Do not use jsDelivr's /+esm URLs - they duplicate element registrations and most wa-* elements never register.
<!DOCTYPE html>
<!-- wa-cloak: hides the page until all custom elements are defined (2s max) -->
<html class="wa-theme-default wa-palette-hotosm wa-cloak">
<head>
<!-- Fonts: see "Fonts" above -->
<!-- WebAwesome base styles + HOT theme, self-contained -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@hotosm/ui@3.0.0/dist/style.css" />
<script type="importmap">
{
"imports": {
"@awesome.me/webawesome/dist/components/": "https://cdn.jsdelivr.net/npm/@awesome.me/webawesome@3.11.0/dist-cdn/components/"
}
}
</script>
<!-- Register every wa-* element, then the hot-* components -->
<script
type="module"
src="https://cdn.jsdelivr.net/npm/@hotosm/ui@3.0.0/dist/webawesome-all.js"
></script>
<script
type="module"
src="https://cdn.jsdelivr.net/npm/@hotosm/ui@3.0.0/dist/hotosm-ui.js"
></script>
</head>
<body>
<hot-header id="hdr" title="My App" size="s" show-login></hot-header>
<script>
// Boolean props default to false.
// Include the attribute to make it true.
const hdr = document.getElementById("hdr");
hdr.drawer = true; // enable the hamburger drawer
</script>
</body>
</html>For multi-page (HTMX) apps, also inline a few critical theme tokens in <head> so first paint looks right before the CDN CSS arrives - see Loading Strategies.
Web Components work in React with a small caveat - use ref callbacks for custom events if React's synthetic event system doesn't forward them:
import "@hotosm/ui/dist/components/header/header.js";
function App() {
return (
<hot-header
title="My App"
ref={(el) => {
if (el) el.addEventListener("login", () => console.log("logged in"));
}}
/>
);
}The HOT theme exposes CSS custom properties you can reference in your own stylesheets:
.my-card {
background: var(--hot-color-primary-50);
color: var(--hot-color-neutral-900);
font-family: var(--hot-font-sans);
padding: var(--hot-spacing-medium);
border-radius: var(--hot-border-radius-large);
}See all available tokens in src/themes/hot.css.
git clone git@github.com:hotosm/ui.git
cd ui
pnpm install
pnpm run dev # starts Storybook on localhost:3001Styling files (under src/themes/):
| File | Purpose |
|---|---|
| hot.css | HOT design tokens (colours, typography, spacing) |
| hot-wa.css | WebAwesome variable overrides to apply the HOT palette |
HOT UI is free and open source software. You may use any HOT UI project under the terms of the GNU General Public License (GPL) Version 3.
| Back | FazBrowse Home | New Git URL |