hanap-labs
hanap-labs
Shared UI toolkit package for components, helpers, and composables.
Build
npm install
npm run build
Documentation Site
The repository also includes the Vue-powered documentation site with live component examples:
npm run dev
npm run build:site
npm run preview
Public Entrypoints
- Root entrypoint:
hanap-labs - Components entrypoint:
hanap-labs/components - Helpers entrypoint:
hanap-labs/helpers - Composables entrypoint:
hanap-labs/composables - Auto-import helper entrypoint:
hanap-labs/auto-import
Consumption Modes
1) Manual Named Imports (Default)
Use named imports when you want explicit dependencies per file.
import { HLButton, objectToQueryParams, usePopup } from "hanap-labs";
You can also import by module group:
import { HLButton } from "hanap-labs/components";
import type { HLButtonProps } from "hanap-labs/components";
import { objectToQueryParams } from "hanap-labs/helpers";
import { usePopup } from "hanap-labs/composables";
2) Optional Auto-Import Integration
If a consumer app uses unplugin-vue-components and unplugin-auto-import, the toolkit exposes helper factories to wire components and composables in one place.
Install plugins in the consumer app:
npm install -D unplugin-vue-components unplugin-auto-import
Update the consumer app vite.config.ts:
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import Components from "unplugin-vue-components/vite";
import AutoImport from "unplugin-auto-import/vite";
import { createToolkitAutoImportOptions } from "hanap-labs/auto-import";
const toolkitAutoImport = createToolkitAutoImportOptions();
export default defineConfig({
plugins: [
vue(),
Components({
resolvers: toolkitAutoImport.components.resolvers,
}),
AutoImport({
imports: toolkitAutoImport.composables.imports,
}),
],
});
To scope auto-imports, pass selected names:
createToolkitAutoImportOptions({
componentNames: ["HLButton"],
composableNames: ["usePopup"],
});
Consumer Setup Checklist
Apply these steps in each consuming website:
- Install
hanap-labs. - Import toolkit styles once in your app entry:
import "hanap-labs/styles.css";- In Nuxt, add
"hanap-labs/styles.css"tonuxt.config.tsundercss.
- Choose a mode:
- Keep manual named imports (default).
- Enable optional auto-import using the Vite plugin setup above.
- Run the app build and confirm toolkit components/composables resolve correctly.
Global Overlay Setup (popup and notify)
The toolkit includes app-level overlay plugins:
createPopupPlugin()for popup host mountingcreateNotifyPlugin()for toast/notify host mounting
Auto-mount (recommended)
Use auto-mount when you want the toolkit to create and mount hosts to document.body:
import { createApp } from "vue";
import App from "./App.vue";
import { createNotifyPlugin, createPopupPlugin } from "hanap-labs";
createApp(App).use(createPopupPlugin()).use(createNotifyPlugin()).mount("#app");
Manual mount target
Use manual targets when your app needs explicit host element control:
<div id="app"></div>
<div id="popup-root"></div>
<div id="notify-root"></div>
import { createApp } from "vue";
import App from "./App.vue";
import { createNotifyPlugin, createPopupPlugin } from "hanap-labs";
createApp(App)
.use(createPopupPlugin({ mountId: "popup-root", autoMount: true }))
.use(createNotifyPlugin({ mountId: "notify-root", autoMount: true }))
.mount("#app");
Theming
The toolkit supports host-driven theming through CSS variables, plus .light / .dark mode.
Toolkit theme tokens are scoped to the .hanap-labs-theme (and .hanap-labs-font) class, so importing hanap-labs/styles.css does not overwrite your app :root styles.
- Add
hanap-labs-theme(and optionallyhanap-labs-font) to a wrapper element in your app (oftenbody,#app, or a layout root). - (Optional) Define host tokens in your app
:root(and override them in.dark). - Toggle
.darkon a parent element (usuallyhtmlorbody) to enable dark mode.
Example wrapper:
<body class="hanap-labs-theme hanap-labs-font">
<div id="app"></div>
</body>
Example:
:root {
--primary: #15803d;
--secondary: #9fcb98;
--danger: #dc2626;
}
.dark {
--primary: #85bb65;
--secondary: #3e5f4a;
--danger: #f87171;
}
Global Theme CSS Custom Properties
All global theme tokens are available as CSS custom properties prefixed with --hanap-labs-.
Color Tokens
| Property | Description | Light Mode Default | Dark Mode Default |
|---|---|---|---|
--hanap-labs-primary |
Primary brand color | #15803d |
#85bb65 |
--hanap-labs-secondary |
Secondary brand color | #9fcb98 |
#3e5f4a |
--hanap-labs-tertiary |
Tertiary brand color | #79ae6f |
#2f4a39 |
--hanap-labs-success |
Success state color | #059669 |
#34d399 |
--hanap-labs-danger |
Danger/error state color | #dc2626 |
#f87171 |
--hanap-labs-warning |
Warning state color | #f59e0b |
#fbbf24 |
--hanap-labs-info |
Info state color | #38bdf8 |
#60a5fa |
--hanap-labs-light |
Light neutral color | #ede9e6 |
#1f2937 |
--hanap-labs-dark |
Dark neutral color | #030712 |
#030712 |
--hanap-labs-muted |
Muted neutral color | #6b8274 |
#9ca3af |
Surface Tokens
| Property | Description | Light Mode Default | Dark Mode Default |
|---|---|---|---|
--hanap-labs-surface |
Primary surface background | #ffffff |
#0f172a |
--hanap-labs-surface-subtle |
Subtle surface background | #f8fafc |
#111827 |
--hanap-labs-surface-muted |
Muted surface background | #f1f5f9 |
#1f2937 |
--hanap-labs-overlay |
Overlay/backdrop color | rgba(15, 23, 42, 0.55) |
rgba(2, 6, 23, 0.72) |
Border Tokens
| Property | Description | Light Mode Default | Dark Mode Default |
|---|---|---|---|
--hanap-labs-border-default |
Default border color | #e5e7eb |
#334155 |
--hanap-labs-border-strong |
Strong border color | #cbd5e1 |
#475569 |
Text Tokens
| Property | Description | Light Mode Default | Dark Mode Default |
|---|---|---|---|
--hanap-labs-text-default |
Default text color | #0f172a |
#f8fafc |
--hanap-labs-text-muted |
Muted text color | #64748b |
#94a3b8 |
--hanap-labs-text-subtle |
Subtle text color | #475569 |
#cbd5e1 |
--hanap-labs-text-light |
Light text color (for dark backgrounds) | #ffffff |
#030712 |
--hanap-labs-text-primary |
Primary text color | #15803d |
#85bb65 |
--hanap-labs-text-theme |
Theme text color | #0f172a |
#f8fafc |
Typography Tokens
| Property | Description | Default |
|---|---|---|
--hanap-labs-font-family |
Font family | "Work Sans", sans-serif |
TanStack Vue Query Setup (useQuery)
The useQuery and useMutation composables require TanStack Vue Query (optional peer dependency) to be installed, then registered once.
npm install @tanstack/vue-query
In your app entry (e.g., main.ts):
import { createApp } from "vue";
import App from "./App.vue";
import { createQueryPlugin } from "hanap-labs";
createApp(App)
.use(
createQueryPlugin({
queries: {
staleTime: 1000 * 60 * 5,
},
}),
)
.mount("#app");
Without this setup, useQuery and useMutation will throw a runtime error in fresh consumer apps.
Related Packages
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 11.8.1 | ^3.5.0 | MIT | |
| 11.8.0 | ^3.5.0 | MIT | |
| 11.7.0 | ^3.5.0 | MIT | |
| 11.6.1 | ^3.5.0 | MIT | |
| 11.6.0 | ^3.5.0 | MIT | |
| 11.5.0 | ^3.5.0 | MIT | |
| 11.4.0 | ^3.5.0 | MIT | |
| 11.3.1 | ^3.5.0 | MIT | |
| 11.3.0 | ^3.5.0 | MIT | |
| 11.2.1 | ^3.5.0 | MIT | |
| 11.2.0 | ^3.5.0 | MIT | |
| 11.1.2 | ^3.5.0 | MIT | |
| 11.1.1 | ^3.5.0 | MIT | |
| 11.1.0 | ^3.5.0 | MIT | |
| 11.0.0 | ^3.5.0 | MIT | |
| 10.9.2 | ^3.5.0 | MIT | |
| 10.9.1 | ^3.5.0 | MIT | |
| 10.9.0 | ^3.5.0 | MIT | |
| 10.8.0 | ^3.5.0 | MIT | |
| 10.7.0 | ^3.5.0 | MIT | |
| 10.5.3 | ^3.5.0 | MIT | |
| 10.5.2 | ^3.5.0 | MIT | |
| 10.5.1 | ^3.5.0 | MIT | |
| 10.5.0 | ^3.5.0 | MIT | |
| 10.4.0 | ^3.5.0 | MIT | |
| 10.3.3 | ^3.5.0 | MIT | |
| 10.3.2 | ^3.5.0 | MIT | |
| 10.3.1 | ^3.5.0 | MIT | |
| 10.3.0 | ^3.5.0 | MIT | |
| 10.2.2 | ^3.5.0 | MIT |
Showing the latest 30 of 158. See every release on npm