@lovince/ui
v4.1.1
Published
Cross-framework UI components built with Web Components
Maintainers
Readme
@lovince/ui
Lit-based Web Component library with typed exports, theme tokens, and 73 reusable components.
Full usage guide: docs/PACKAGE_USAGE.md
What this package provides
- Framework-agnostic custom elements (tag names start with
lovince-) - TypeScript types for variants and component models
defineX()functions per componentdefineAllComponents()to register everything at once- Foundation tokens and a
lovince-theme-provider
Installation
If you consume this as a package:
npm install @lovince/ui litIf you are working in this repository:
npm install
npx tsc --noEmit
npx tsupQuick start
Option 1: Global Registration (Simple - Not Recommended for Production)
import { defineAllComponents } from '@lovince/ui/register';
defineAllComponents(); // Registers 250+ components globallyOption 2: Scoped Registration (Recommended for Production)
import { createScopedRegistry } from '@lovince/ui/foundations';
import { defineScopedModal, defineScopedButton } from '@lovince/ui';
const registry = createScopedRegistry();
defineScopedModal(registry);
defineScopedButton(registry);
// Clean up when done (important for SSR/memory)
registry.destroy();⚠️ Global registration (defineAllComponents) can cause memory leaks and SSR issues. Use scoped registration for production applications.
📖 See docs/SCOPED_COMPONENTS.md for detailed migration guide.
2. Use in HTML
<lovince-button variant="primary">Save</lovince-button>
<lovince-input variant="outlined" placeholder="Email"></lovince-input>Theming and tokens
Use lovince-theme-provider or set data-theme on document.documentElement.
<lovince-theme-provider theme="dark">
<lovince-card variant="default">Dark themed card</lovince-card>
</lovince-theme-provider>Key token families:
- Colors:
--ui-color-* - Spacing:
--ui-space-* - Radius:
--ui-radius-* - Shadow:
--ui-shadow-* - Z-index:
--ui-z-* - Breakpoints:
--ui-breakpoint-* - Motion:
--ui-motion-*
Source: src/foundations/*
Public API
Top-level exports from src/index.ts:
- Primitives:
export * from './primitives' - Forms:
export * from './forms' - Layout:
export * from './layout' - Overlays:
export * from './overlays' - Registration entry:
@lovince/ui/register(global pattern - deprecated for production) - Scoped registration entry:
@lovince/ui/foundations(recommended for production) - Advanced runtime entry:
@lovince/ui/internal/overlays(unstable/internal) - Foundations:
export * from './foundations' - Events:
export * from './events'
Component catalog (247)
This section is auto-generated from src/components by npm run readme:components.
| # | Component | Tag |
|---|---|---|
| 1 | accordion | <lovince-accordion> |
| 2 | accordion-group | <lovince-accordion-group> |
| 3 | activity-feed | <lovince-activity-feed> |
| 4 | activity-indicator | <lovince-activity-indicator> |
| 5 | activity-item | <lovince-activity-item> |
| 6 | alert | <lovince-alert> |
| 7 | alert-dialog | <lovince-alert-dialog> |
| 8 | analytics-card | <lovince-analytics-card> |
| 9 | anchor | <lovince-anchor> |
| 10 | announcement-bar | <lovince-announcement-bar> |
| 11 | app-bar | <lovince-app-bar> |
| 12 | aria-announcer | <lovince-aria-announcer> |
| 13 | aria-live-region | <lovince-aria-live-region> |
| 14 | aspect-ratio | <lovince-aspect-ratio> |
| 15 | audio-player | <lovince-audio-player> |
| 16 | auto-layout | <lovince-auto-layout> |
| 17 | autocomplete | <lovince-autocomplete> |
| 18 | avatar | <lovince-avatar> |
| 19 | avatar-group | <lovince-avatar-group> |
| 20 | background-video | <lovince-background-video> |
| 21 | badge | <lovince-badge> |
| 22 | badge-group | <lovince-badge-group> |
| 23 | banner | <lovince-banner> |
| 24 | bar-chart | <lovince-bar-chart> |
| 25 | bottom-navigation | <lovince-bottom-navigation> |
| 26 | box | <lovince-box> |
| 27 | breadcrumb | <lovince-breadcrumb> |
| 28 | breadcrumb-item | <lovince-breadcrumb-item> |
| 29 | breakpoint-provider | <lovince-breakpoint-provider> |
| 30 | button | <lovince-button> |
| 31 | button-base | <lovince-button-base> |
| 32 | calendar | <lovince-calendar> |
| 33 | calendar-range | <lovince-calendar-range> |
| 34 | caption | <lovince-caption> |
| 35 | card | <lovince-card> |
| 36 | carousel | <lovince-carousel> |
| 37 | carousel-item | <lovince-carousel-item> |
| 38 | chart | <lovince-chart> |
| 39 | checkbox | <lovince-checkbox> |
| 40 | checkbox-base | <lovince-checkbox-base> |
| 41 | chip | <lovince-chip> |
| 42 | chips-input | <lovince-chips-input> |
| 43 | coachmark | <lovince-coachmark> |
| 44 | collapse | <lovince-collapse> |
| 45 | collection | <lovince-collection> |
| 46 | color-picker | <lovince-color-picker> |
| 47 | combobox | <lovince-combobox> |
| 48 | command-bar | <lovince-command-bar> |
| 49 | command-group | <lovince-command-group> |
| 50 | command-item | <lovince-command-item> |
| 51 | command-palette | <lovince-command-palette> |
| 52 | comment | <lovince-comment> |
| 53 | comment-thread | <lovince-comment-thread> |
| 54 | confirm-dialog | <lovince-confirm-dialog> |
| 55 | container | <lovince-container> |
| 56 | context-menu | <lovince-context-menu> |
| 57 | context-provider | <lovince-context-provider> |
| 58 | cover-image | <lovince-cover-image> |
| 59 | currency-input | <lovince-currency-input> |
| 60 | data-grid | <lovince-data-grid> |
| 61 | date-picker | <lovince-date-picker> |
| 62 | date-range-picker | <lovince-date-range-picker> |
| 63 | datetime-picker | <lovince-datetime-picker> |
| 64 | dismissable-layer | <lovince-dismissable-layer> |
| 65 | divider | <lovince-divider> |
| 66 | dock | <lovince-dock> |
| 67 | drag-drop-zone | <lovince-drag-drop-zone> |
| 68 | drag-handle | <lovince-drag-handle> |
| 69 | drawer | <lovince-drawer> |
| 70 | dropdown | <lovince-dropdown> |
| 71 | dropdown-group | <lovince-dropdown-group> |
| 72 | dropdown-item | <lovince-dropdown-item> |
| 73 | emoji-picker | <lovince-emoji-picker> |
| 74 | empty-state | <lovince-empty-state> |
| 75 | error-boundary | <lovince-error-boundary> |
| 76 | fade | <lovince-fade> |
| 77 | faq | <lovince-faq> |
| 78 | faq-item | <lovince-faq-item> |
| 79 | feature-card | <lovince-feature-card> |
| 80 | feedback-message | <lovince-feedback-message> |
| 81 | field | <lovince-field> |
| 82 | figure | <lovince-figure> |
| 83 | file-dropzone | <lovince-file-dropzone> |
| 84 | file-upload | <lovince-file-upload> |
| 85 | flex | <lovince-flex> |
| 86 | floating-container | <lovince-floating-container> |
| 87 | floating-panel | <lovince-floating-panel> |
| 88 | focus-manager | <lovince-focus-manager> |
| 89 | focus-ring | <lovince-focus-ring> |
| 90 | focus-scope | <lovince-focus-scope> |
| 91 | focus-trap | <lovince-focus-trap> |
| 92 | focus-visible | <lovince-focus-visible> |
| 93 | focusable | <lovince-focusable> |
| 94 | form-control | <lovince-form-control> |
| 95 | form-field | <lovince-form-field> |
| 96 | gesture-area | <lovince-gesture-area> |
| 97 | grid | <lovince-grid> |
| 98 | grid-auto | <lovince-grid-auto> |
| 99 | guided-tour | <lovince-guided-tour> |
| 100 | heading | <lovince-heading> |
| 101 | heatmap | <lovince-heatmap> |
| 102 | hero | <lovince-hero> |
| 103 | hover-card | <lovince-hover-card> |
| 104 | hover-intent | <lovince-hover-intent> |
| 105 | hydration-boundary | <lovince-hydration-boundary> |
| 106 | id-provider | <lovince-id-provider> |
| 107 | image | <lovince-image> |
| 108 | image-gallery | <lovince-image-gallery> |
| 109 | image-lightbox | <lovince-image-lightbox> |
| 110 | indeterminate-progress | <lovince-indeterminate-progress> |
| 111 | infinite-scroll | <lovince-infinite-scroll> |
| 112 | input | <lovince-input> |
| 113 | input-base | <lovince-input-base> |
| 114 | intersection-observer | <lovince-intersection-observer> |
| 115 | item | <lovince-item> |
| 116 | keyboard-navigator | <lovince-keyboard-navigator> |
| 117 | label | <lovince-label> |
| 118 | lazy-loader | <lovince-lazy-loader> |
| 119 | line-chart | <lovince-line-chart> |
| 120 | link | <lovince-link> |
| 121 | link-base | <lovince-link-base> |
| 122 | list | <lovince-list> |
| 123 | listbox | <lovince-listbox> |
| 124 | loading-overlay | <lovince-loading-overlay> |
| 125 | long-press | <lovince-long-press> |
| 126 | markdown-editor | <lovince-markdown-editor> |
| 127 | masonry | <lovince-masonry> |
| 128 | media-object | <lovince-media-object> |
| 129 | mega-menu | <lovince-mega-menu> |
| 130 | mention-input | <lovince-mention-input> |
| 131 | menu | <lovince-menu> |
| 132 | menu-bar | <lovince-menu-bar> |
| 133 | menu-item-checkbox | <lovince-menu-item-checkbox> |
| 134 | menu-item-radio | <lovince-menu-item-radio> |
| 135 | metric-card | <lovince-metric-card> |
| 136 | modal | <lovince-modal> |
| 137 | multi-select | <lovince-multi-select> |
| 138 | mutation-observer | <lovince-mutation-observer> |
| 139 | navbar | <lovince-navbar> |
| 140 | navigation-group | <lovince-navigation-group> |
| 141 | navigation-rail | <lovince-navigation-rail> |
| 142 | newsletter-form | <lovince-newsletter-form> |
| 143 | notification | <lovince-notification> |
| 144 | number-stepper | <lovince-number-stepper> |
| 145 | option | <lovince-option> |
| 146 | otp-input | <lovince-otp-input> |
| 147 | overlay | <lovince-overlay> |
| 148 | page-footer | <lovince-page-footer> |
| 149 | page-header | <lovince-page-header> |
| 150 | pagination | <lovince-pagination> |
| 151 | parallax | <lovince-parallax> |
| 152 | password-field | <lovince-password-field> |
| 153 | pie-chart | <lovince-pie-chart> |
| 154 | pill | <lovince-pill> |
| 155 | pin-input | <lovince-pin-input> |
| 156 | polymorphic | <lovince-polymorphic> |
| 157 | popover | <lovince-popover> |
| 158 | portal | <lovince-portal> |
| 159 | portal-root | <lovince-portal-root> |
| 160 | positioner | <lovince-positioner> |
| 161 | prefetch-link | <lovince-prefetch-link> |
| 162 | presence | <lovince-presence> |
| 163 | pressable | <lovince-pressable> |
| 164 | pricing-table | <lovince-pricing-table> |
| 165 | profile-card | <lovince-profile-card> |
| 166 | progress | <lovince-progress> |
| 167 | progress-ring | <lovince-progress-ring> |
| 168 | quick-actions | <lovince-quick-actions> |
| 169 | radio | <lovince-radio> |
| 170 | radio-base | <lovince-radio-base> |
| 171 | range-slider | <lovince-range-slider> |
| 172 | rating | <lovince-rating> |
| 173 | rating-summary | <lovince-rating-summary> |
| 174 | reorder-group | <lovince-reorder-group> |
| 175 | resizable-group | <lovince-resizable-group> |
| 176 | resizable-panel | <lovince-resizable-panel> |
| 177 | resize-observer | <lovince-resize-observer> |
| 178 | retry-boundary | <lovince-retry-boundary> |
| 179 | review-card | <lovince-review-card> |
| 180 | rich-text-editor | <lovince-rich-text-editor> |
| 181 | roving-focus-group | <lovince-roving-focus-group> |
| 182 | safe-area | <lovince-safe-area> |
| 183 | scroll-area | <lovince-scroll-area> |
| 184 | scroll-snap | <lovince-scroll-snap> |
| 185 | search-autocomplete | <lovince-search-autocomplete> |
| 186 | search-field | <lovince-search-field> |
| 187 | select | <lovince-select> |
| 188 | selection-group | <lovince-selection-group> |
| 189 | selection-item | <lovince-selection-item> |
| 190 | separator | <lovince-separator> |
| 191 | shortcut-handler | <lovince-shortcut-handler> |
| 192 | sidebar | <lovince-sidebar> |
| 193 | signature-pad | <lovince-signature-pad> |
| 194 | skeleton | <lovince-skeleton> |
| 195 | slider-base | <lovince-slider-base> |
| 196 | slot | <lovince-slot> |
| 197 | snackbar | <lovince-snackbar> |
| 198 | sortable-list | <lovince-sortable-list> |
| 199 | spacer | <lovince-spacer> |
| 200 | sparkline | <lovince-sparkline> |
| 201 | spinner | <lovince-spinner> |
| 202 | split-view | <lovince-split-view> |
| 203 | spotlight-search | <lovince-spotlight-search> |
| 204 | stack | <lovince-stack> |
| 205 | stat | <lovince-stat> |
| 206 | stat-card | <lovince-stat-card> |
| 207 | status-indicator | <lovince-status-indicator> |
| 208 | step | <lovince-step> |
| 209 | stepper | <lovince-stepper> |
| 210 | sticky-container | <lovince-sticky-container> |
| 211 | suspense-boundary | <lovince-suspense-boundary> |
| 212 | switch | <lovince-switch> |
| 213 | switch-base | <lovince-switch-base> |
| 214 | tab-indicator | <lovince-tab-indicator> |
| 215 | tab-list | <lovince-tab-list> |
| 216 | tab-panel | <lovince-tab-panel> |
| 217 | table | <lovince-table> |
| 218 | table-cell | <lovince-table-cell> |
| 219 | table-header | <lovince-table-header> |
| 220 | table-pagination | <lovince-table-pagination> |
| 221 | table-row | <lovince-table-row> |
| 222 | table-sort | <lovince-table-sort> |
| 223 | tabs | <lovince-tabs> |
| 224 | tag | <lovince-tag> |
| 225 | tag-input | <lovince-tag-input> |
| 226 | testimonial | <lovince-testimonial> |
| 227 | text | <lovince-text> |
| 228 | textarea | <lovince-textarea> |
| 229 | time-picker | <lovince-time-picker> |
| 230 | timeline | <lovince-timeline> |
| 231 | timeline-item | <lovince-timeline-item> |
| 232 | toast | <lovince-toast> |
| 233 | toast-container | <lovince-toast-container> |
| 234 | tooltip | <lovince-tooltip> |
| 235 | tour-overlay | <lovince-tour-overlay> |
| 236 | transition | <lovince-transition> |
| 237 | tree-node | <lovince-tree-node> |
| 238 | tree-view | <lovince-tree-view> |
| 239 | user-card | <lovince-user-card> |
| 240 | video-player | <lovince-video-player> |
| 241 | viewport | <lovince-viewport> |
| 242 | virtual-list | <lovince-virtual-list> |
| 243 | virtual-table | <lovince-virtual-table> |
| 244 | visibility-sensor | <lovince-visibility-sensor> |
| 245 | visually-hidden | <lovince-visually-hidden> |
| 246 | wizard | <lovince-wizard> |
| 247 | wizard-step | <lovince-wizard-step> |
Custom events
These components dispatch custom events:
| Component | Event | Detail |
|---|---|---|
| interactive inputs/navigation | ui-change | { value } (normalized contract) |
| accordion | accordion-change | { activeIndex } |
| alert | alert-close | none |
| checkbox | checkbox-change | { checked } |
| input | input-change | { value } |
| modal | modal-open | none |
| modal | modal-close | { reason: 'escape' \| 'backdrop' \| 'programmatic' } |
| menu | menu-select | selected menu item |
| overlay | overlay-open | none |
| overlay | overlay-close | { reason: 'backdrop' \| 'programmatic' } |
| pagination | page-change | { page } |
| radio | radio-change | { checked, value } |
| search-field | search-change | { value } |
| search-field | search-submit | { value } |
| select | select-change | { value } |
| switch | switch-change | { checked } |
| tabs | tab-change | { id } |
| textarea | textarea-change | { value } |
Example:
document.querySelector('lovince-input')?.addEventListener('ui-change', (event: Event) => {
const detail = (event as CustomEvent<{ value: string }>).detail;
console.log(detail.value);
});Common usage patterns
Forms
<lovince-form-field label="Email" helper="Use your work email" variant="default">
<lovince-input type="email" variant="outlined"></lovince-input>
</lovince-form-field>Feedback
<lovince-alert variant="warning" dismissible>Check your entries.</lovince-alert>
<lovince-progress variant="success" value="55" max="100" show-label></lovince-progress>Navigation
<lovince-breadcrumb></lovince-breadcrumb>
<lovince-tabs></lovince-tabs>
<lovince-pagination page="1" page-size="10" total="120"></lovince-pagination>Typed imports
import type {
ButtonVariant,
InputVariant,
SelectVariant,
TabsVariant,
TooltipVariant,
} from '@lovince/ui';API docs with TypeDoc
Better Alternative #2 is to use proper TSDoc comments and generate API docs from source.
TypeDoc reads TSDoc-style comments, for example:
/**
* Primary button component used for triggering actions.
*
* @example
* ```html
* <lovince-button variant="primary">Save</lovince-button>
* ```
*
* @slot - Button label content.
*/
export class Button extends LitElement {}Action plan:
- Install docs generator:
npm install -D typedoc- Keep
typedoc.jsonconfigured with:
{
"entryPoints": ["src/index.ts"],
"out": "docs/api",
"tsconfig": "tsconfig.json"
}- Add TSDoc comments to components, public types, and define helpers.
- Generate docs:
npm run docs- Publish
docs/apithrough GitHub Pages or another static host.
A robust documentation system combines:
- API docs (TypeDoc)
- Component demos (Storybook or equivalent)
- Usage examples (README + package usage guide)
Notes
- ⚠️ Global registration (
defineAllComponents) is deprecated for production use due to memory leaks and SSR issues - ✅ Use scoped registration from
@lovince/ui/foundationsfor new projects - Components are not auto-registered by default. You must call registration functions before using custom elements.
- This README reflects the current
src/implementation in this repository.
Versioning and changelog
This repo uses Changesets for semantic versioning and changelog generation.
npm run changeset
npm run versionnpm run changeset: add a release note entry (patch/minor/major)npm run version: applies version bumps and updatesCHANGELOG.mdnpm run release: builds, typechecks, and publishesnpm run lint:layers: enforces cross-layer import boundariesnpm run test:treeshake: smoke test for single-component tree-shaking
System roadmap
Current focus areas to move from a component kit to a production design system:
Feedback and Notification Systems toast, toast-container, snackbar, notification, alert-dialog, confirm-dialog, loading-overlay, progress-ring, indeterminate-progress, status-indicator, activity-indicator, banner, announcement-bar, feedback-message, error-boundary, retry-boundary
Overlay and Floating Interface Patterns dropdown, dropdown-item, dropdown-group, popover, hover-card, context-menu, menu-bar, menu-item-checkbox, menu-item-radio, command-palette, command-item, command-group, floating-panel, spotlight-search, quick-actions, tour-overlay, guided-tour, coachmark
Advanced Form and Input Components combobox, autocomplete, multi-select, tag-input, chips-input, otp-input, pin-input, date-picker, date-range-picker, time-picker, datetime-picker, calendar, calendar-range, color-picker, file-upload, file-dropzone, signature-pad, rating, range-slider, currency-input, number-stepper, password-field, search-autocomplete, emoji-picker, mention-input, markdown-editor, rich-text-editor
Navigation and Application Layout Components navbar, app-bar, sidebar, drawer, bottom-navigation, navigation-rail, mega-menu, breadcrumb-item, stepper, step, wizard, wizard-step, tab-panel, tab-list, tab-indicator, tree-view, tree-node, accordion-group, navigation-group, command-bar, page-header, page-footer
Data Display Components table, table-header, table-row, table-cell, table-sort, table-pagination, data-grid, virtual-table, timeline, timeline-item, activity-feed, activity-item, stat, metric-card, analytics-card, chart, bar-chart, line-chart, pie-chart, sparkline, heatmap, tag, chip, pill, badge-group, avatar-group, user-card, profile-card, comment, comment-thread, review-card, rating-summary
Media and Content Components image, image-gallery, image-lightbox, carousel, carousel-item, video-player, audio-player, media-object, figure, caption, cover-image, background-video, parallax, hero, feature-card, testimonial, pricing-table, faq, faq-item, newsletter-form
Layout Utilities and Advanced Containers masonry, grid-auto, auto-layout, split-view, resizable-panel, resizable-group, sticky-container, scroll-snap, infinite-scroll, virtual-list, viewport, anchor, dock, portal-root, floating-container, safe-area, breakpoint-provider, theme-provider
Accessibility and Interaction Primitives focus-manager, focus-visible, aria-live-region, keyboard-navigator, shortcut-handler, gesture-area, drag-handle, drag-drop-zone, sortable-list, reorder-group, selection-group, selection-item, hover-intent, long-press
Performance and Observation Utilities intersection-observer, resize-observer, mutation-observer, visibility-sensor, lazy-loader, prefetch-link, suspense-boundary, hydration-boundary
