appify-domain-spic-lang-components
v0.0.2
Published
> **Reusable Angular component library for rendering DSL-based mobile applications**
Downloads
5
Readme
@appify/dsl-components
Reusable Angular component library for rendering DSL-based mobile applications
Angular 20 component library for the Appify project that provides recursive, constraint-based component rendering for building mobile apps visually.
📦 Installation
# Build the library
cd lib
npm run build
# Use in Appify_FE (already configured)
# Import from: 'appify-domain-spic-lang-components'🎯 Overview
This library provides:
- 18 Pre-built Components across 6 categories
- Recursive Component Trees with nested children support
- Constraint System for parent-child validation
- Event System for actions and triggers
- i18n Support built into all components
- Data Binding through ComponentContext
- Two Specialized Renderers (builder vs runtime)
🧩 Component Categories
Basic Components (4)
- Text - Display text with i18n and interpolation
- Button - Interactive buttons with actions
- Image - Images with loading states
- Icon - Ionic icon display
Layout Components (4)
- Container - Generic layout container
- Grid - Responsive grid layout
- Card - Card-based layouts
- Tabs - Tabbed content sections
Input Components (6)
- Input - Single-line text input
- Textarea - Multi-line text input
- Select - Dropdown selection
- Checkbox - Boolean checkbox
- Radio - Radio button group
- Searchbar - Search input with debounce
Data Components (2)
- List - Scrollable list with data binding
- Repeater - Repeat components from array
Media Components (2)
- Video - Video player
- Avatar - User avatar display
🏗️ Architecture
Component Model
interface DslComponent {
id: string;
type: string;
props: Record<string, any>;
children?: DslComponent[]; // Recursive nesting
events?: DslComponentEvents;
style?: Record<string, any>;
cssClass?: string;
}Constraint System
Components define what children they can accept:
{
type: 'Form',
acceptsChildren: true,
allowedChildren: ['Input', 'Textarea', 'Select', 'Button'],
minChildren: 1,
maxChildren: 20
}Validation:
canAcceptChild(parent, child)- Validates if child can be addedgetAllowedChildTypes(parent)- Gets list of valid child typesvalidateMinChildren(component)- Checks minimum requirements
Component Context
Runtime data passed to all components:
interface ComponentContext {
user?: any; // Current user
data?: any; // Component data
apis?: Record<string, any>; // API responses
i18n?: (key: string) => string; // Translation function
navigateTo?: (pageId: string) => void; // Navigation
executeAction?: (action: any) => void; // Action handler
}🎨 Two Renderers
1. DslRendererComponent (Production)
For final built apps - pure runtime rendering.
<app-dsl-renderer
[dslTree]="rootComponent"
[context]="runtimeContext"
(actionTriggered)="handleAction($event)">
</app-dsl-renderer>Features:
- Minimal overhead
- Performance optimized
- No editor UI
- Pure component rendering
2. BuilderRendererComponent (Editor)
For builder environment with editing controls.
<app-builder-renderer
[components]="pageComponents"
[selectedComponent]="selected"
[context]="editorContext"
(componentSelected)="onSelect($event)"
(componentDeleted)="onDelete($event)">
</app-builder-renderer>Features:
- Visual component hierarchy
- Selection highlighting
- Quick action buttons (move, delete)
- Drag & drop reordering
- Component icons and previews
🔌 Usage Examples
Creating a Component
const button: DslComponent = {
id: 'btn_1',
type: 'Button',
props: {
labelI18nKey: 'common.submit', // i18n support
color: 'primary',
expand: 'block',
action: 'navigate:home' // Action trigger
}
};Nested Components
const form: DslComponent = {
id: 'form_1',
type: 'Form',
props: { submitLabel: 'Submit' },
children: [
{
id: 'input_1',
type: 'Input',
props: {
label: 'Email',
type: 'email',
binding: 'data.user.email' // Data binding
}
},
{
id: 'btn_1',
type: 'Button',
props: { label: 'Submit', action: 'submit' }
}
]
};Using Context
const context: ComponentContext = {
user: { name: 'John', email: '[email protected]' },
data: { user: { email: '' } },
i18n: (key: string) => translations[key],
navigateTo: (pageId: string) => router.navigate([pageId]),
executeAction: (action) => console.log('Action:', action)
};🔧 Development
Building
# From lib/ directory
npm run build
# Output: lib/dist/appify-domain-spic-lang-components/
# Build time: ~6 secondsUsing in Angular Project
// Import components
import {
DslRendererComponent,
BuilderRendererComponent,
DslComponent,
ComponentContext
} from 'appify-domain-spic-lang-components';
// Import in standalone component
@Component({
selector: 'app-my-component',
standalone: true,
imports: [DslRendererComponent],
template: `<app-dsl-renderer [dslTree]="root" />`
})Component Registry
Access component definitions:
import { ComponentRegistryProvider } from 'appify-domain-spic-lang-components';
const registry = ComponentRegistryProvider.getRegistry();
const buttonDef = registry.getComponent('Button');
const allComponents = registry.getAllComponents();
const layoutComponents = registry.getComponentsByCategory('layout');📋 Component Props Reference
Common Props (All Components)
| Prop | Type | Description |
|------|------|-------------|
| style | Object | Inline CSS styles |
| cssClass | string | CSS class names |
| i18nKey | string | Translation key for text |
Button Props
| Prop | Type | Description |
|------|------|-------------|
| label | string | Button text |
| labelI18nKey | string | Translation key |
| action | string | Action to trigger |
| color | string | Ionic color |
| expand | string | 'block' | 'full' |
| fill | string | 'solid' | 'outline' | 'clear' |
| disabled | boolean | Disable button |
| icon | string | Icon name |
| iconPosition | string | 'start' | 'end' |
Input Props
| Prop | Type | Description |
|------|------|-------------|
| label | string | Input label |
| placeholder | string | Placeholder text |
| type | string | Input type |
| binding | string | Data binding path |
| required | boolean | Required validation |
| minLength | number | Min length |
| maxLength | number | Max length |
| pattern | string | Regex pattern |
| helperText | string | Helper text |
Container Props
| Prop | Type | Description |
|------|------|-------------|
| layout | string | 'vertical' | 'horizontal' |
| padding | number | Padding in pixels |
| gap | number | Gap between children |
| backgroundColor | string | Background color |
✅ Features
- [x] Recursive component rendering
- [x] Constraint-based validation
- [x] Event system with action triggers
- [x] i18n support
- [x] Data binding preparation
- [x] Two specialized renderers
- [x] 18 production-ready components
- [x] OnPush change detection
- [x] Standalone components (Angular 20)
- [x] TypeScript strict mode
- [x] Full type safety
🔜 Roadmap
- [ ] Add more components (Switch, Slider, Date Picker)
- [ ] Component animation support
- [ ] Advanced validation rules
- [ ] Custom component registration
- [ ] Component templates
- [ ] Accessibility improvements
- [ ] Unit tests
- [ ] Storybook documentation
📚 Documentation
See the main project documentation:
🛠️ Technical Details
- Angular: 20.3.0
- Ionic: 8.x
- TypeScript: 5.x (Strict mode)
- Change Detection: OnPush
- Component Type: Standalone
- Build Output: ES2022 modules
📝 License
Internal project library for Appify MVP.
