Usage
Vanilla HTML (CDN)
Section titled “Vanilla HTML (CDN)”No build step needed. Add a script tag and start using components:
<script type="module" src="https://unpkg.com/@tessera-ui/core/dist/tessera-ui/tessera-ui.esm.js"></script>
<ts-button variant="primary">Submit</ts-button><ts-input label="Email" type="email" placeholder="you@example.com"></ts-input>
<script> document.querySelector('ts-button').addEventListener('tsClick', () => { console.log('Button clicked!'); });
document.querySelector('ts-input').addEventListener('tsInput', (e) => { console.log('Value:', e.detail.value); });</script>Vanilla (Bundler — Vite, Webpack, etc.)
Section titled “Vanilla (Bundler — Vite, Webpack, etc.)”npm install @tessera-ui/coreimport '@tessera-ui/core';<ts-button variant="primary">Submit</ts-button><ts-input label="Email" type="email" placeholder="you@example.com"></ts-input>npm install @tessera-ui/reactimport { useState } from 'react';import { TsButton, TsInput } from '@tessera-ui/react';
function App() { const [name, setName] = useState('');
return ( <> <TsInput label="Name" placeholder="Enter your name" value={name} onTsInput={(e) => setName(e.detail.value)} /> <TsButton variant="primary" onTsClick={() => alert(`Hello, ${name}!`)}> Submit </TsButton> </> );}npm install @tessera-ui/vueAdd isCustomElement to your Vite config:
import vue from '@vitejs/plugin-vue';
export default { plugins: [ vue({ template: { compilerOptions: { isCustomElement: (tag) => tag.startsWith('ts-'), }, }, }), ],};<template> <TsInput label="Name" placeholder="Enter your name" :value="name" @tsInput="name = $event.detail.value" /> <TsButton variant="primary" @tsClick="alert(`Hello, ${name}!`)"> Submit </TsButton></template>
<script setup>import { ref } from 'vue';import { TsButton, TsInput } from '@tessera-ui/vue';
const name = ref('');</script>Angular
Section titled “Angular”npm install @tessera-ui/angularimport { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';import { DIRECTIVES } from '@tessera-ui/angular';
@Component({ selector: 'app-root', standalone: true, imports: [DIRECTIVES], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: ` <ts-input label="Name" placeholder="Enter your name" (tsInput)="onInput($event)" ></ts-input> <ts-button variant="primary" (tsClick)="onSubmit()"> Submit </ts-button> `,})export class AppComponent { name = '';
onInput(e: Event) { this.name = (e as CustomEvent).detail.value; }
onSubmit() { alert(`Hello, ${this.name}!`); }}Common Patterns
Section titled “Common Patterns”These patterns work the same way across all frameworks.
Theming
Section titled “Theming”Override design tokens with CSS custom properties:
:root { --ts-color-interactive-primary: #7c3aed; --ts-button-radius: 9999px; --ts-font-family-base: 'Nunito', sans-serif;}Dark Mode
Section titled “Dark Mode”<html data-theme="dark">// Toggle dynamicallydocument.documentElement.setAttribute('data-theme', 'dark');Density
Section titled “Density”<html data-density="compact"> <!-- tighter spacing --><html data-density="spacious"> <!-- more breathing room --><ts-card> <h3 slot="header">Title</h3> <p>Body content</p> <div slot="footer"> <ts-button size="sm">Action</ts-button> </div></ts-card>CSS Parts
Section titled “CSS Parts”ts-button::part(base) { text-transform: uppercase;}<html dir="rtl">All components use CSS logical properties and adapt automatically.