A reactive component library built on compile-time template transformations. Provides typed, tree-shakeable UI components with integrated SCSS theming.
npm install @esportsplus/uiA reactive component library built on compile-time template transformations. Provides typed, tree-shakeable UI components with integrated SCSS theming.
``bash`
pnpm add @esportsplus/ui
- @esportsplus/frontend - Tagged template literals with compile-time transforms and reactive state management@esportsplus/action
- - Response/error handling@esportsplus/utilities
- - Core utilities
`typescript
import { button, form, input, select } from '@esportsplus/ui';
import { html } from '@esportsplus/frontend';
// Simple component
html${button({}, 'Click Me')};
// Form with validation
html
${form.action({
action: async ({ input: data }) => {
const result = await api.submit(data);
return result.ok ? { errors: [] } : { errors: result.errors };
}
}, html)}
${input({ name: 'email', type: 'email' })}
${button({}, 'Submit')}
;
// Select with reactive state
html
${select({
options: { a: 'Option A', b: 'Option B' },
selected: 'a'
}, (state) => htmlSelected: ${state.selected})};`
| Text input with validation state | - |
| textarea | Multi-line text input | - |
| checkbox | Checkbox with label | - |
| radio | Radio button group | - |
| range | Range slider | - |
| select | Dropdown with custom options | - |
| switch | Toggle switch | - |
| form | Form wrapper | form.action, form.input |$3
| Component | Description | Variants |
|-----------|-------------|----------|
| button | Standard button | button.hold |
| tooltip | Popup content | tooltip.menu, tooltip.onclick, tooltip.onhover |
| accordion | Collapsible sections | - |
| clipboard | Copy to clipboard | clipboard.onclick, clipboard.write |
| alert | Notifications | error, info, success types |$3
| Component | Description |
|-----------|-------------|
| counter | Animated number with currency formatting |
| loader | Loading spinner |
| loading | Border loading indicator |
| typewriter | Animated typing effect |
| highlight | Viewport intersection highlight |
| ellipsis | Animated dots |
| icon | SVG sprite wrapper |
| number | Number formatting |
| truncate | Text truncation |
| json | JSON display |$3
| Component | Description |
|-----------|-------------|
| scrollbar | Custom scrollbar container |
| frame | Scrollable frame |
| sidebar | Side navigation |
| site | Site wrapper |
| overlay | Modal/overlay container |$3
| Component | Description |
|-----------|-------------|
| back | Back navigation link |
| root | Global event coordination (root.onclick) |
| template | Template factory helper |Component Patterns
$3
Components use
template.factory() supporting flexible call signatures:`typescript
// No arguments
component()// Attributes only
component({ class: 'custom' })
// Content only
component(html
Content)// Both
component({ class: 'custom' }, html
Content)
`$3
Components can accept and return reactive state:
`typescript
import { reactive } from '@esportsplus/frontend';let state = reactive({ active: false });
accordion({ state }, html
);
`$3
`typescript
form.action({
action: async ({ input, response }) => {
// input: parsed FormData with dot-notation support
// response: error handling utilities
return { errors: [] };
}
}, content);// Input with error state
form.input(element, { error: 'Required field' });
`Styling
$3
Styles are organized into layers for proper cascade:
`
@layer normalize
@layer components
@layer themes
@layer css-utilities
`$3
`scss
// All component styles
@use '@esportsplus/ui/*.scss';// Specific component
@use '@esportsplus/ui/button.scss';
// CSS utilities
@use '@esportsplus/ui/css-utilities.scss';
// Design tokens
@use '@esportsplus/ui/tokens.scss';
// Theme
@use '@esportsplus/ui/themes/dark/*.scss';
`$3
Located in
tokens.scss:- Colors:
--color-{name}-{300|400|500} (black, white, red, green, blue, purple, yellow, grey)
- Sizing: --size-{300-800} (12px-80px)
- Spacing: --spacing-{0-600}
- Border: --border-radius-{100-900}, --border-width-{100-700}
- Typography: --font-size-, --font-weight-, --line-height-*$3
`html
`$3
Each component exposes CSS custom properties:
`scss
.ui-button {
--background: var(--color-blue-400);
--color: var(--color-white);
--border-radius: var(--border-radius-300);
--padding-horizontal: 16px;
--padding-vertical: 8px;
}
`Theming
`typescript
// JavaScript
import '@esportsplus/ui/themes/dark';// SCSS
@use '@esportsplus/ui/themes/dark/*.scss';
`Themes override component variables. Create custom themes by overriding CSS custom properties.
Build
`bash
pnpm build # Full build (SCSS + TypeScript)
pnpm build:vite # SCSS compilation only
pnpm build:ts # TypeScript compilation only
`$3
`
build/
├── components/
│ ├── {component}/
│ │ ├── index.js
│ │ ├── index.d.ts
│ │ └── scss/index.scss
│ └── index.js
├── css-utilities/
├── themes/
│ ├── dark/
│ └── light/
└── fonts/
`TypeScript
Full type safety with zero
any types:`typescript
import type { Attributes } from '@esportsplus/frontend';// Components are generic
template.factory(fn);
// State types are explicit
type State = {
active: boolean;
error: string;
};
``Performance
- Compile-time transforms: Template expressions optimized at build
- Tree-shakeable: Import only what you use
- WeakMap caching: Memoized formatters and icons
- Object pooling: Reused queue structures
- RAF batching: Coalesced DOM updates
- CSS layers: Efficient cascade resolution
License
MIT