tawt
v0.0.7
Published
A lightweight library for building web user interfaces with a fluent, object-oriented API.
Readme
TAWT (TypeScript Abstract Window Toolkit)
A modern, lightweight, Swing-inspired library for building web UIs with a fluent, object-oriented API.
TAWT brings the structure and elegance of component-based development to the DOM, wrapped in TypeScript's type safety. Build interfaces with classes instead of templates and methods instead of CSS files.
[!WARNING] This project is currently under active development.
If you'd like to contribute or learn more, contact us at [email protected].
✨ Features
- Object-Oriented: Build UIs with classes (
TawtButton,TawtPanel,TawtLabel) - Fluent API: Chain methods continuously (
.width(100).height(50).onClick(...)) - Type-Safe CSS: Fully typed properties with enums (no string typos!)
- Reusable Styles: Define
TawtCSSClassonce, apply everywhere - Compile-Time CSS: Styles are injected into the DOM automatically when classes are instantiated
- Zero Dependencies: Lightweight and native (jQuery removed)
📦 Installation
npm install tawt� Running the Example
This repository includes a complete example application in the example/ folder demonstrating all TAWT features.
To run it:
- Clone this repository
- Open
index.htmlin your browser, or - Run the dev server:
npm run dev
The example showcases:
- Login forms with validation
- Dynamic tables and grids
- Image galleries
- Reusable CSS classes
- Flexbox layouts
�🏗️ Core Concepts
TawtApplication
The entry point for your application. Manages the root container and mounts to the DOM.
import { TawtApplication, TawtPanel } from 'tawt';
const app = new TawtApplication();
const mainPanel = new TawtPanel();
app.add(mainPanel);
app.mount(); // Attaches to document.bodyTawtElement
Base class for all components. Provides fluent methods for styling, events, and DOM manipulation.
import { TawtLabel, CssColors } from 'tawt';
const label = new TawtLabel('Hello World')
.setColor(CssColors.BLUE)
.setFontSize(24)
.setFontWeight('bold')
.setPadding(10);🧩 Components
TawtPanel
A container <div> with built-in flexbox helpers.
import { TawtPanel, CssFlexDirection, CssJustify, CssAlign } from 'tawt';
const card = new TawtPanel()
.setFlex(CssFlexDirection.COLUMN, CssJustify.CENTER, CssAlign.CENTER)
.setGap(20)
.setPadding(30)
.setBackground('#f5f5f5')
.setBorderRadius(8);TawtButton
An interactive button with click handlers.
import { TawtButton, CssColors, CssCursor } from 'tawt';
const btn = new TawtButton('Click Me', () => alert('Clicked!'))
.setPadding(12)
.setBackground(CssColors.BLUE)
.setColor(CssColors.WHITE)
.setBorderRadius(4)
.setCursor(CssCursor.POINTER);TawtLabel
A text label (<span> by default).
import { TawtLabel, CssFontWeight } from 'tawt';
const title = new TawtLabel('Welcome')
.setFontSize(32)
.setFontWeight(CssFontWeight.BOLD)
.setColor('#333');TawtTextField
An input field (<input type="text">).
import { TawtTextField } from 'tawt';
const emailInput = new TawtTextField()
.setPlaceholder('Enter your email')
.setAttribute('type', 'email')
.setPadding(10)
.setBorder('1px solid #ccc')
.setBorderRadius(4);
// Get value
const email = emailInput.getValue();TawtForm
A semantic <form> with submit handling.
import { TawtForm, TawtFormLabel, TawtTextField, TawtButton } from 'tawt';
const form = new TawtForm();
const usernameLabel = new TawtFormLabel('Username:').setFor('username-input');
const usernameField = new TawtTextField(undefined, undefined, 'username-input');
const submitBtn = new TawtButton('Submit');
form.addComponent(usernameLabel)
.addField(usernameField)
.addComponent(submitBtn)
.onSubmit(() => {
console.log('Username:', usernameField.getValue());
});TawtList
Ordered (<ol>) or unordered (<ul>) lists.
import { TawtList, TawtLabel } from 'tawt';
// Unordered list
const ul = new TawtList(false); // false = <ul>
ul.push('Item 1');
ul.push('Item 2');
ul.push(new TawtLabel('Rich Item').setColor('blue'));
// Ordered list
const ol = new TawtList(true); // true = <ol>
ol.push('Step 1');
ol.push('Step 2');TawtImage
An <img> element with fluent sizing.
import { TawtImage } from 'tawt';
const logo = new TawtImage('https://example.com/logo.png')
.setWidth(200)
.setHeight(100)
.setBorderRadius(8);TawtImageFolder
Manage multiple images from a base URL.
import { TawtImageFolder } from 'tawt';
const icons = new TawtImageFolder('https://img.icons8.com/ios/50', [
'000000/typescript.png',
'000000/javascript.png',
]);
const tsIcon = icons.get('000000/typescript.png');
tsIcon.setWidth(40).setHeight(40);
// Or use index access (Proxy-based)
// @ts-ignore
const jsIcon = icons[1];TawtGrid & TawtTable
Grid and table layouts (see src/components/grid and src/components/table for details).
import { TawtGrid } from 'tawt';
const grid = new TawtGrid();
const row = grid.addRow();
row.addColumn().setWeight(2).setBackground('#FF6B6B'); // 2/3 width
row.addColumn().setWeight(1).setBackground('#4ECDC4'); // 1/3 width🌐 HTTP Client
TAWT includes a built-in HTTP client with a fluent API, using native fetch for maximum performance and zero dependencies.
Quick Start
import { TawtHttp } from 'tawt';
// Simple GET request
const response = await TawtHttp.get<User>('https://api.example.com/users/1');
console.log(response.data);
// POST request
const newUser = await TawtHttp.post<User>('https://api.example.com/users', {
name: 'John Doe',
email: '[email protected]',
});Fluent Configuration
import { TawtHttp } from 'tawt';
const api = new TawtHttp()
.baseUrl('https://api.example.com')
.bearer('your-token-here')
.header('X-Custom-Header', 'value')
.timeout(5000); // 5 seconds
// All requests use the configured base URL and headers
const users = await api.get<User[]>('/users');
const user = await api.post<User>('/users', { name: 'Jane' });HTTP Methods
// GET
const data = await api.get<T>('/endpoint');
// POST
const created = await api.post<T>('/endpoint', { data });
// PUT
const updated = await api.put<T>('/endpoint/1', { data });
// PATCH
const patched = await api.patch<T>('/endpoint/1', { partial });
// DELETE
const deleted = await api.delete<T>('/endpoint/1');Authentication
// Bearer token
api.bearer('your-jwt-token');
// Basic auth
api.basic('username', 'password');
// Custom headers
api.header('Authorization', 'Custom scheme');Error Handling
import { TawtHttp, TawtHttpError } from 'tawt';
try {
const data = await TawtHttp.get('/api/users/1');
} catch (error) {
if (error instanceof TawtHttpError) {
console.log(error.status); // 404
console.log(error.statusText); // "Not Found"
console.log(error.url); // Full URL
console.log(error.response); // Response body
// Helper methods
if (error.isClientError()) {
/* 4xx */
}
if (error.isServerError()) {
/* 5xx */
}
if (error.isNetworkError()) {
/* Network failure */
}
}
}Response Object
const response = await api.get<User>('/users/1');
response.data; // Typed response data
response.status; // 200
response.statusText; // "OK"
response.ok; // true
response.headers; // Headers object
// Helper methods
response.isSuccess(); // true for 2xx
response.isError(); // true for 4xx/5xx
response.getHeader('Content-Type');
response.hasHeader('X-Custom');🎨 CSS Styling
Compile-Time CSS Loading
TAWT automatically injects CSS into the DOM when you instantiate TawtCSSClass or TawtCSSId. You don't need to manually manage stylesheets.
import { TawtCSSClass, CssColors } from 'tawt';
// This creates a .card class and injects it into <style> tag
const cardStyle = new TawtCSSClass('card');
cardStyle
.backgroundColor(CssColors.WHITE)
.padding(20)
.borderRadius(12)
.boxShadow('0 2px 10px rgba(0,0,0,0.1)');
// Apply to components
const panel = new TawtPanel();
panel.applyCSSClass(cardStyle);Fluent CSS API
All CSS properties are available as fluent methods on TawtCSSClass, TawtCSSId, and TawtElement.
Single Property
import { TawtCSSClass, CssMeasure } from 'tawt';
const style = new TawtCSSClass('example');
style.width(100, CssMeasure.PERCENT);
style.height(50, CssMeasure.VH);
style.margin(10, 20, 10, 20); // top, right, bottom, left (defaults to px)Method Chaining
const btnStyle = new TawtCSSClass('primary-btn')
.backgroundColor('#007bff')
.color('white')
.padding(12, 24, 12, 24)
.borderRadius(6)
.cursor('pointer')
.fontWeight('bold')
.fontSize(16);Flexbox Shorthand
import { TawtCSSClass, CssFlexDirection, CssJustify, CssAlign } from 'tawt';
const containerStyle = new TawtCSSClass('flex-container');
containerStyle.flex(
CssFlexDirection.ROW,
CssJustify.SPACE_BETWEEN,
CssAlign.CENTER
);TawtCSSClass vs TawtCSSId
TawtCSSClass: Reusable style (compiles to.classname)TawtCSSId: Unique style (compiles to#idname)
import { TawtCSSClass, TawtCSSId } from 'tawt';
// Reusable class
const buttonClass = new TawtCSSClass('btn');
buttonClass.padding(10).borderRadius(4);
// Unique ID
const headerId = new TawtCSSId('main-header');
headerId.fontSize(32).fontWeight('bold');
// Apply
const btn1 = new TawtButton('Button 1');
btn1.applyCSSClass(buttonClass);
const header = new TawtLabel('Header');
header.applyCSSId(headerId);Inline Styles vs Classes
You can mix inline styles (via TawtElement methods) with classes:
const panel = new TawtPanel();
panel.applyCSSClass(cardStyle); // Apply class
panel.setBackground('red'); // Override with inline styleNote: Inline styles have higher specificity than classes.
🚀 Complete Example
import {
TawtApplication,
TawtPanel,
TawtLabel,
TawtButton,
TawtTextField,
TawtForm,
TawtFormLabel,
TawtCSSClass,
CssColors,
CssFlexDirection,
CssJustify,
CssAlign,
CssCursor,
CssFontWeight,
CssMeasure,
} from 'tawt';
// 1. Create Application
const app = new TawtApplication();
// 2. Define Reusable Styles
const cardStyle = new TawtCSSClass('card')
.backgroundColor(CssColors.WHITE)
.padding(20)
.borderRadius(12)
.boxShadow('0 2px 10px rgba(0,0,0,0.05)');
const inputStyle = new TawtCSSClass('input')
.padding(10)
.border('1px solid #ddd')
.borderRadius(6)
.width(100, CssMeasure.PERCENT);
// 3. Build UI
const container = new TawtPanel()
.setFlex(CssFlexDirection.COLUMN, CssJustify.CENTER, CssAlign.CENTER)
.setGap(30)
.setPadding(40)
.setBackground('#f0f2f5')
.setWidth(100, CssMeasure.VW)
.setMinHeight(100, CssMeasure.VH);
const title = new TawtLabel('Login Form')
.setFontSize(24)
.setFontWeight(CssFontWeight.BOLD)
.setColor('#333');
const form = new TawtForm().applyCSSClass(cardStyle).setWidth('350px');
const emailLabel = new TawtFormLabel('Email:').setFor('email-input');
const emailField = new TawtTextField(
undefined,
inputStyle,
'email-input'
).setPlaceholder('[email protected]');
const passwordLabel = new TawtFormLabel('Password:').setFor('password-input');
const passwordField = new TawtTextField(undefined, inputStyle, 'password-input')
.setAttribute('type', 'password')
.setPlaceholder('••••••••');
const submitBtn = new TawtButton('Login')
.setPadding(12)
.setBackground(CssColors.BLUE)
.setColor(CssColors.WHITE)
.setBorderRadius(6)
.setCursor(CssCursor.POINTER);
form.addComponent(emailLabel)
.addField(emailField)
.addComponent(passwordLabel)
.addField(passwordField)
.addComponent(submitBtn)
.onSubmit(() => {
alert(`Email: ${emailField.getValue()}`);
});
container.add(title).add(form);
app.add(container);
// 4. Mount
app.mount();📚 API Reference
Core
TawtApplication- Application entry pointTawtElement- Base class for all components
Components
TawtPanel- Container with flexboxTawtButton- Interactive buttonTawtLabel- Text labelTawtTextField- Input fieldTawtForm- Form with submit handlingTawtFormLabel- Label for form fieldsTawtList- Ordered/unordered listsTawtImage- Image elementTawtImageFolder- Image collection managerTawtGrid- Grid layout systemTawtTable- Table layout
CSS
TawtCSSClass- Reusable CSS classTawtCSSId- Unique CSS IDCssProperties- CSS property constantsCssColors- Color constantsCssMeasure- Unit constants (PX, EM, REM, PERCENT, VW, VH, etc.)- Enums:
CssDisplay,CssPosition,CssFlexDirection,CssJustify,CssAlign,CssCursor, etc.
🤝 Contributing
Contributions are welcome! Please submit a Pull Request.
📄 License
MIT
