@reallygoodwork/coral-core
v1.6.1
Published
Core types, schemas, utilities, and CLI for the Coral UI specification format.
Readme
@reallygoodwork/coral-core
Core types, schemas, utilities, and CLI for the Coral UI specification format.
Installation
npm install @reallygoodwork/coral-core
# or
pnpm add @reallygoodwork/coral-core
# or
yarn add @reallygoodwork/coral-coreOverview
This package provides the foundational types, Zod schemas, utility functions, and CLI tools for working with the Coral UI specification format. It's the core of the Coral ecosystem, enabling:
- Component Variants System - CVA-style variant definitions at the component level
- Package System -
coral.config.jsonmanifest for organizing design systems - Component Composition - Embed components within components with prop/slot bindings
- Typed Props & Events - Full type definitions for component APIs
- Conditional Rendering - Expression-based conditional logic
- Reference Resolution - Token, prop, asset, and component references
CLI Commands
The package includes a CLI for managing Coral packages:
# Initialize a new package
coral init my-design-system
# Validate a package
coral validate ./path/to/package
# Build outputs (types, json)
coral build --target types
# Add a new component
coral add component Button --category ActionsQuick Start
Creating a Component with Variants
import type { CoralRootNode } from '@reallygoodwork/coral-core'
const button: CoralRootNode = {
name: 'Button',
elementType: 'button',
// Component metadata
$meta: {
name: 'Button',
version: '1.0.0',
status: 'stable',
category: 'Actions',
},
// Define variant axes
componentVariants: {
axes: [
{
name: 'intent',
values: ['primary', 'secondary', 'destructive'],
default: 'primary',
description: 'Visual style of the button',
},
{
name: 'size',
values: ['sm', 'md', 'lg'],
default: 'md',
},
],
},
// Base styles
styles: {
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
borderRadius: '6px',
fontWeight: '500',
},
// Per-node variant responses
variantStyles: {
intent: {
primary: { backgroundColor: '#007bff', color: '#ffffff' },
secondary: { backgroundColor: '#6c757d', color: '#ffffff' },
destructive: { backgroundColor: '#dc3545', color: '#ffffff' },
},
size: {
sm: { padding: '4px 8px', fontSize: '12px' },
md: { padding: '8px 16px', fontSize: '14px' },
lg: { padding: '12px 24px', fontSize: '16px' },
},
},
// State styles
stateStyles: {
hover: {
intent: {
primary: { backgroundColor: '#0056b3' },
secondary: { backgroundColor: '#5a6268' },
destructive: { backgroundColor: '#c82333' },
},
},
disabled: { opacity: '0.5', cursor: 'not-allowed' },
},
// Typed props
props: {
label: {
type: 'string',
required: true,
description: 'Button text',
},
disabled: {
type: 'boolean',
default: false,
},
},
// Events
events: {
onClick: {
description: 'Fired when button is clicked',
parameters: [
{ name: 'event', type: 'React.MouseEvent<HTMLButtonElement>' },
],
},
},
textContent: { $prop: 'label' },
}Package Manifest
Create a coral.config.json to organize your design system:
{
"$schema": "https://coral.design/config.schema.json",
"name": "@acme/design-system",
"version": "1.0.0",
"description": "ACME Design System",
"coral": { "specVersion": "1.0.0" },
"tokens": { "entry": "./tokens/index.json" },
"components": { "entry": "./components/index.json" },
"exports": {
"react": {
"outDir": "./dist/react",
"typescript": true,
"styling": "tailwind"
}
}
}API Reference
Core Functions
parseUISpec(spec)
Parses and validates a UI specification object against the Coral schema.
import { parseUISpec } from '@reallygoodwork/coral-core'
const validatedSpec = await parseUISpec({
name: 'Card',
elementType: 'div',
styles: { padding: '20px' },
})transformHTMLToSpec(html)
Transforms an HTML string into a Coral specification.
import { transformHTMLToSpec } from '@reallygoodwork/coral-core'
const spec = transformHTMLToSpec('<div class="card"><h1>Hello</h1></div>')Package System
loadPackage(configPath, options)
Load a Coral package from disk.
import { loadPackage } from '@reallygoodwork/coral-core'
import * as fs from 'fs/promises'
const pkg = await loadPackage('./coral.config.json', {
readFile: (path) => fs.readFile(path, 'utf-8'),
})
console.log(`Loaded ${pkg.components.size} components`)validatePackage(pkg)
Validate all references in a package.
import { validatePackage } from '@reallygoodwork/coral-core'
const result = validatePackage(pkg)
if (!result.valid) {
console.error('Errors:', result.errors)
}Variant Resolution
resolveNodeStyles(node, activeVariants)
Resolve styles for a node with active variants.
import { resolveNodeStyles } from '@reallygoodwork/coral-core'
const styles = resolveNodeStyles(buttonNode, {
intent: 'primary',
size: 'lg',
})
// Merges base styles with variant-specific overridesevaluateCondition(expression, props)
Evaluate a conditional expression.
import { evaluateCondition } from '@reallygoodwork/coral-core'
const isVisible = evaluateCondition(
{ $and: [{ $prop: 'enabled' }, { $not: { $prop: 'loading' } }] },
{ enabled: true, loading: false }
)
// trueType Generation
generatePropsInterface(component)
Generate TypeScript interface from component definition.
import { generatePropsInterface } from '@reallygoodwork/coral-core'
const typeCode = generatePropsInterface(buttonComponent)
// export interface ButtonProps {
// intent?: "primary" | "secondary" | "destructive";
// ...
// }Type Guards
Coral Core provides comprehensive type guards for safe type narrowing without type assertions:
import {
isTokenReference,
isPropReference,
isComponentReference,
isConditionalExpression,
isComponentInstance,
} from '@reallygoodwork/coral-core'
// Check if a value is a token reference
if (isTokenReference(value)) {
// value.$token is available - TypeScript knows this is TokenReference
}
// Check if a node is a component instance
if (isComponentInstance(node)) {
// node.$component is available - TypeScript knows this is ComponentInstance
}Type Safety: All type guards use proper type narrowing - no as assertions needed. The codebase is fully type-safe with zero any types.
Type System
Type Safety
Coral Core is fully type-safe with:
- Zero
anytypes - All types are properly defined or useunknownwith type guards - No type assertions - Type guards provide safe type narrowing
- Recursive types -
CoralStyleTypeis an interface supporting nested styles - Nullable types -
CoralTSTypesisz.nullable- returnsnullwhen type cannot be determined
References
type TokenReference = { $token: string; $fallback?: unknown }
type PropReference = { $prop: string }
type ComponentReference = {
$component: { ref: string; version?: string }
propBindings?: Record<string, unknown>
slotBindings?: Record<string, unknown>
}TypeScript Types
// CoralTSTypes is nullable - can be null when type cannot be determined
type CoralTSTypes =
| 'string'
| 'number'
| 'boolean'
| 'array'
| 'object'
| 'null'
| 'undefined'
| 'function'
| null
// CoralStyleType is an interface supporting recursive nested styles
interface CoralStyleType {
[key: string]:
| string
| number
| CoralColorType
| CoralGradientType
| Dimension
| CoralStyleType // Recursive for nested styles
}Variants
type VariantAxis = {
name: string
values: string[]
default: string
description?: string
}
type ComponentVariants = {
axes: VariantAxis[]
compounds: CompoundVariantCondition[]
}Props & Events
type ComponentPropDefinition = {
type: PropType
default?: unknown
required?: boolean
description?: string
editorControl?: 'text' | 'select' | 'boolean' | 'color' | 'slider'
constraints?: { min?: number; max?: number; pattern?: string }
}
type ComponentEventDefinition = {
description?: string
parameters: EventParameter[]
deprecated?: boolean | string
}Conditional Expressions
type ConditionalExpression =
| { $prop: string }
| { $not: ConditionalExpression }
| { $and: ConditionalExpression[] }
| { $or: ConditionalExpression[] }
| { $eq: [ConditionalExpression, unknown] }
| { $ne: [ConditionalExpression, unknown] }Extended CoralNode Fields
The CoralNode type now includes:
// Variant styles
variantStyles?: NodeVariantStyles
compoundVariantStyles?: CompoundVariantStyle[]
stateStyles?: StateStyles
// Conditional rendering
conditional?: ConditionalExpression
conditionalBehavior?: 'hide' | 'dim' | 'outline'
conditionalStyles?: ConditionalStyle[]
// Slots
slotTarget?: string
slotFallback?: CoralNode[]
// Component instances
$component?: ComponentInstanceRef
propBindings?: Record<string, PropBinding>
eventBindings?: Record<string, EventBinding>
slotBindings?: Record<string, SlotBinding>
variantOverrides?: Record<string, string>
// Element bindings
eventHandlers?: Record<string, EventBinding>
ariaAttributes?: Record<string, BindableValue>
dataAttributes?: Record<string, BindableValue>Related Packages
- @reallygoodwork/coral-tw2css - Convert Tailwind to CSS
- @reallygoodwork/react-to-coral - React to Coral
- @reallygoodwork/coral-to-react - Coral to React
- @reallygoodwork/coral-to-html - Coral to HTML
License
MIT © Really Good Work
