@tramo-digital/types
v0.0.0
Published
tramo.digital - types
Readme
@tramo-digital/types
TypeScript type definitions for the Open Design System component-driven design system. This library provides type-safe component models, validation utilities, and Standard Schema integration for building scalable, data-driven UI components.
Installation
npm install @tramo-digital/types
# or
pnpm add @tramo-digital/types
# or
pnpm add @tramo-digital/typesOverview
This library provides a modern, data-driven approach to component typing with:
- Component Models - Data-centric component definitions with type safety
- Standard Schema Integration - Runtime validation with library-agnostic schema support
- Loader System - Async data loading with validation for server-side rendering
- Utility Types - String manipulation and type transformation helpers
- Framework Agnostic - Works with React, Vue, and vanilla JavaScript
Core Concepts
Component Models
Components are defined as data models with optional loaders, events, and validation:
import { HeroModel, BaseComponentModel } from '@tramo-digital/types';
// Pre-built component models
const hero: HeroModel = {
_type: 'hero',
data: {
title: 'Welcome to our platform',
subtitle: 'Build amazing experiences',
ctaText: 'Get Started',
ctaLink: '/signup'
},
events: {
onCtaClick: (event) => console.log('CTA clicked', event)
}
};
// Create custom component models
interface CustomModel extends BaseComponentModel<'custom', MyData, MyEvents> {}Standard Schema Integration
Leverage any Standard Schema compatible library (Zod, Valibot, ArkType) for validation:
import { z } from 'zod';
import { BaseComponentModelWithSchema, safeValidateWithSchema } from '@tramo-digital/types';
const UserSchema = z.object({
name: z.string(),
email: z.string().email(),
role: z.enum(['admin', 'user'])
});
interface UserComponent extends BaseComponentModelWithSchema<
'user',
typeof UserSchema,
UserEvents
> {}
const userComponent: UserComponent = {
_type: 'user',
_schema: UserSchema,
loader: async (context) => {
const userData = await fetchUser(context?.user?.id);
return await safeValidateWithSchema(UserSchema, userData);
}
};Async Data Loading
Components can load and validate data asynchronously:
import { ComponentLoader, LoaderContext } from '@tramo-digital/types';
const createHeroLoader: ComponentLoader<HeroData> = async (context) => {
try {
const data = await fetchHeroFromCMS(context?.request?.params?.id);
return { value: data }; // Success result
} catch (error) {
return { issues: [{ message: 'Failed to load hero data' }] }; // Error result
}
};📦 Available Components
Primitive Components
ButtonModel- Interactive button componentsIconModel- Icon display componentsImageModel- Image components with responsive featuresContentModel- Text content componentsAccordionItemModel- Individual accordion panelsCarouselItemModel- Carousel slide components
Pattern Components
HeroModel- Hero sections with CTACardModel- Content cardsAccordionModel- Expandable content sectionsCarouselModel- Image/content slidersBannerModel- Promotional bannersMarqueeModel- Scrolling text displaysCountdownTimerModel- Timer components
Layout Components
GridContainerModel- CSS Grid containersGridItemModel- Grid item positioningOneColModel- Single column layoutsTwoColModel- Two column layouts
Composition Components
HeroAccordionModel- Hero sections with integrated accordions
🛠 Utility Types
Transform and manipulate types with built-in utilities:
import { ToSnakeCase, ToPascalCase, ComponentType } from '@tramo-digital/types';
type Example1 = ToSnakeCase<'MyComponent'>; // 'my_component'
type Example2 = ToPascalCase<'my_component'>; // 'MyComponent'
type Example3 = ComponentType<'UserCard'>; // 'user_card'
// Filter components by type
type HeroComponents = FilterByType<AllComponents, 'hero'>;
// Make specific properties optional/required
type PartialHero = PartialBy<HeroModel, 'events' | 'loader'>;
type RequiredHero = RequiredBy<HeroModel, 'data'>;🔒 Runtime Validation
Validate data at runtime with Standard Schema compatible validators:
import {
validateWithSchema,
safeValidateWithSchema,
isStandardSchema,
ValidationError
} from '@tramo-digital/types';
// Throws on validation failure
const validData = await validateWithSchema(schema, data);
// Returns result object (safe, no throwing)
const result = await safeValidateWithSchema(schema, data);
if ('issues' in result) {
console.error('Validation failed:', result.issues);
} else {
console.log('Valid data:', result.value);
}
// Check if object is a valid schema
if (isStandardSchema(someSchema)) {
// Safe to use with validation functions
}🔧 Framework Integration
Works seamlessly with popular frameworks:
// React
import { HeroModel } from '@tramo-digital/types';
const HeroComponent: React.FC<{ model: HeroModel }> = ({ model }) => {
// Use model.data, model.events, etc.
};
// Vue
import { HeroModel } from '@tramo-digital/types';
defineComponent({
props: {
model: { type: Object as PropType<HeroModel>, required: true }
}
});
🎯 Best Practices
- Use Type-Safe Models: Always use the provided component models for consistency
- Validate External Data: Use schema validation for data from APIs or user input
- Leverage Loaders: Use component loaders for async data fetching with error handling
- Compose Components: Build complex UIs by composing simpler component models
- Framework Agnostic: Keep business logic in models, UI logic in framework components
📚 Advanced Usage
For detailed examples and advanced patterns, see:
- Standard Schema Integration Guide
- Component-specific documentation in
/src/models/
🤝 Contributing
This library uses:
- TypeScript 5.8+ for modern type features
- Standard Schema v1 for validation interfaces
- ESM modules for modern bundle compatibility
- Strict type checking for maximum safety
📄 License
Part of the Open Design System design system. See main repository for license details.
