Shared Web Components with theming for use across HOTOSM tools.
📖 Documentation: https://hotosm.github.io/ui/
🖥️ Source Code: https://github.com/hotosm/ui
🎯 Roadmap / Tasks: https://github.com/orgs/hotosm/projects/37/views/3
Shared UI components with theming for use across HOTOSM tools, to reduce code duplication.
The components are Web Components, currently written in Lit, using TypeScript.
The main goal of this project is not to re-invent the wheel, or add an extra burden of development and maintenance.
Primarily we want to have:
- Low level components exported from the excellent Shoelace web component library, simply re-exported with our default styling / CSS overrides.
- A few composite components (header, sidebar, etc):
- Consistent styling across most of our tools where it counts.
- Reduction in duplicated logic, such as user management, OAuth login, etc.
- Improved developer experience, reduced development time for new tools, while maintaining consistency in look and feel of applications.
There are two options for install:
- NPM: appropriate for applications that have installable dependencies.
- CDN: appropriate for HTML / Markdown / HTMX.
- This is the compiled JavaScript bundle generated from the TypeScript code.
- The components require no additional dependencies and are minified.
- Install package
@hotosm/ui
as a dependency in yourpackage.json
. - Import the components.
<script>
import '@hotosm/ui/dist/style.css';
import '@hotosm/ui/dist/components.js';
</script>
// Use the components in your templates
<hot-header @login="someFunction()"> </hot-header>
// Import the styles (or create your own)
<link
rel="stylesheet"
href="https://s3.amazonaws.com/hotosm-ui/latest/style.css"
/>
// Import the components
<script
type="module"
src="https://cdn.jsdelivr.net/npm/@hotosm/ui@latest/dist/components.js"
></script>
<hot-header @login="someFunction()> </hot-header>
The jsdelivr
CDN only includes package releases, with @latest
pointing to the
most recent tagged release.
There is also an S3-based CDN, where latest
tracks the main
branch of the repo:
https://s3.amazonaws.com/hotosm-ui/latest/dist/components.js
-
Using the TypeScript ES Modules allows for cherry-picking components, so 'tree-shaking' can remove the remaining ones you don't use.
-
If you are developing an application that uses
@hotosm/ui
components, including a bundler such as rollup/vite/webpack, this is probably the best approach. -
However, you must first add Shoelace as a
peerDependency
in yourpackage.json
:"peerDependencies": { "@shoelace-style/shoelace": "^2.15.1" }
Ideally the version of Shoelace installed should match the version used in hotosm/ui.
Example:
import '@hotosm/ui/components/header/header';
// Then in your template
<hot-header @login="${someFunction()}"></hot-header>
Versions of React below v19 require a specific 'wrapper' component to use the web components.
Use these instead of the standard @hotosm/ui/components/xxx
:
pnpm install @hotosm/ui
import { Button } from '@hotosm/ui/react/Header'
const HomePage = ({}) => {
return (
<div className="your-css-classes">
<div
...
>
<Header @onLogin="${someFunction()}" />
</div>
</div>
);
};
export default HomePage;
Note that while web components must always have a closing tag, this is not required for the React wrappers.
The UI library contains many composite components, such as headers, sidebars, tracking banners, etc, and does not re-invent the wheel for low-level components.
Shoelace is an excellent UI library that is exported directly from @hotosm/ui
.
To access the low-level components, such as buttons, dropdowns, modals, etc, simply import the component of the same name from the [Shoelace docs] (https://shoelace.style):
import '@hotosm/ui/components/button/button';
// Then in your template
<hot-button disabled variant="secondary">Can't Click Me</hot-button>
If you are using a bundler, you must bundle the (icon) assets yourself, described in the Shoelace docs.
- To include the Shoelace assets in your final bundle (dist), you could add
the following to your
package.json
:
"scripts": {
"clean-icons": "rm -rf public/assets/icons",
"get-icons": "cp -r node_modules/@shoelace-style/shoelace/dist/assets/icons public/",
"setup-dist": "pnpm run clean-icons && pnpm run get-icons",
}
- Now the Shoelace assets will be bundled with your dist, under
/shoelace
. - Following the example, also add
public/assets/icons
to your.gitignore
file.