grundlage v0.0.1
Grundlage - a web component base rendering function
Overview
The Template System provides a declarative way to handle dynamic content, conditional rendering, lists, and asynchronous operations using native HTML <template>
elements. It uses slots for state management while maintaining compatibility with regular Web Component slots.
Core Concepts
Template Boundaries
Each template creates its own boundary for state management and error handling. Content and errors are scoped to their immediate parent template, creating clean separation between different template blocks.
State Management Slots
Templates use slots to manage different states (content, fallback, error, etc.). The default slot is used for the primary content, while other states are handled through named slots.
Basic Usage
Conditional Rendering
<template when="${condition}">
<!-- Default slot (content) -->
<div>Main content shown when condition is true</div>
<!-- Fallback state -->
<template slot="fallback">
<div>Shown when condition is false</div>
</template>
<!-- Error state -->
<template slot="error">
<div>${error => error.message}</div>
</template>
</template>
Async Operations
<template suspense="${fetchData}">
<!-- Default slot for success state -->
<div>${data => data.result}</div>
<!-- Loading state -->
<template slot="fallback" when="${() => status() === 'loading'}">
<div>Loading...</div>
</template>
<!-- Error state -->
<template slot="error">
<div>${error => error.message}</div>
</template>
</template>
List Rendering
<template each="${items}">
<!-- Item template -->
<template slot="item" key="${item => item.id}">
<div>${item => item.name}</div>
</template>
<!-- Empty state -->
<template slot="empty">
<div>No items available</div>
</template>
</template>
Slot Rules
- The default (unnamed) slot is used for primary content
Special state slots:
fallback
: Alternative contenterror
: Error handlingempty
: Empty state for listsitem
: List item template
Multiple elements can use the same slot:
<template when="${condition}">
<!-- Both fallbacks exist, visibility controlled by conditions -->
<template slot="fallback" when="${loading}">
<div>Loading...</div>
</template>
<template slot="fallback" when="${timeout}">
<div>Timeout...</div>
</template>
</template>
Template Boundaries and Nesting
Scope Rules
- Everything can be slotted, only templates have render functionality
- Templates create strict boundaries
- Slots belong to their immediate parent template
- Errors are caught by the nearest parent template
<template when="${outerCondition}">
<div>Outer content</div>
<!-- This template is self-contained -->
<template when="${innerCondition}">
<div>Inner content</div>
<!-- This fallback belongs to inner template -->
<template slot="fallback">
<div>Inner fallback</div>
</template>
</template>
<!-- This fallback belongs to outer template -->
<template slot="fallback">
<div>Outer fallback</div>
</template>
</template>
Component Integration
Templates inside component slots are self-contained:
<my-component>
<!-- This template manages its own states -->
<template when="${condition}" slot="footer">
<div>Footer content</div>
<!-- Fallback belongs to when template, not component -->
<template slot="fallback">
<div>Footer fallback</div>
</template>
</template>
</my-component>
Special Considerations
State management attributes (
when
,each
,suspense
) can only be used on<template>
elementsDynamic slot names are not supported
Template order doesn't affect slot rendering, but content within slots is rendered in document order
Error Handling
Errors are caught by the nearest parent template with an error slot:
<template when="${condition}">
<template suspense="${fetchData}">
<div>${data => data.result}</div>
<!-- Fetch errors are caught here -->
<template slot="error">
<div>Fetch error: ${error => error.message}</div>
</template>
</template>
<!-- Other errors in the when template are caught here -->
<template slot="error">
<div>General error: ${error => error.message}</div>
</template>
</template>
5 months ago