Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
canonrs-core
Single Source of Truth for the CanonRS design system. All metadata, constraints, and API contracts are generated from
*_ui.rsheaders.
Architecture
*_ui.rs (@canon-* headers + Leptos props)
↓
build.rs (orchestrates all generators)
↓
src/generated/
├── catalog.rs — CatalogEntry with kind, parts, regions, accept rules
├── component_meta.rs — ComponentMeta with intent, capabilities, required parts
├── block_meta.rs — BlockMeta for all blocks and layouts
├── block_definitions.rs — BlockDefinition with regions, props, presets, AcceptRule
├── layout_definitions.rs — LayoutDefinition with slots and descriptions
├── component_definitions.rs — ComponentDefinition unifying meta + catalog
├── llm_components.md — LLM context for UI components
├── llm_blocks.md — LLM context for blocks
└── llm_layouts.md — LLM context for layouts
SSOT Pipeline
The single source of truth flows in one direction only:
NEVER edit generated files manually
ALWAYS edit *_ui.rs headers or Leptos props
Component headers (*_ui.rs)
Every UI component declares its contract via @canon-* doc comments:
//! @canon-id: button
//! @canon-label: Button
//! @canon-family: interactive
//! @canon-category: Action
//! @canon-intent: Trigger an action or event
//! @canon-description: Action button with variant and size
//! @canon-composable: false
//! @canon-capabilities: Disabled
//! @canon-required-parts:
//! @canon-optional-parts:
//! @canon-tags: button, action, submit, click, cta
Block/Layout headers
Blocks and layouts extend the schema with structural metadata:
//! @canon-id: card
//! @canon-type: block
//! @canon-category: layout
//! @canon-variant: structure
//! @canon-container: true
//! @canon-regions: header, content, footer
//! @canon-label: Card
//! @canon-description: Container with header/content/footer regions
//! @canon-tags: card, container, box, content
//! @canon-slot-accepts: header=Any,content=Any,footer=Action
Generated Artifacts
catalog.rs
Unified registry of all components, blocks, and layouts with:
CatalogKind—Component | Block | LayoutCatalogAcceptRule— declarative accept rules per entryCatalogRegionRule— per-region accept rules derived from@canon-slot-accepts
CatalogEntry
component_meta.rs
Runtime statics for AI/RAG/Decision Engine:
pub static ACCORDION_META: ComponentMeta = ComponentMeta ;
block_definitions.rs
Full structural definitions for blocks with semantic AcceptRule per region:
BlockDefinition
api.rs (per component)
Generated in canonrs-server/src/ui/*/api.rs:
pub const BUTTON_API: ComponentApi = ComponentApi ;
Constraint Engine
src/infra/constraint_engine.rs — validates composition at runtime:
// Can a block be inserted into a region?
can_insert
// → ValidationResult::Valid
// Does a component have all required parts?
validate_parts
// → ValidationResult::Invalid([MissingParts { missing: ["AccordionContent"] }])
// What can go into a region?
valid_children_for
// → ["button", "input", "badge", ...]
// Can a catalog entry nest inside another?
catalog_can_nest_in_region
// → true (header accepts Navigation category)
Running tests
Build Generators
Located in build/generators/:
| Generator | Output | Source |
|---|---|---|
gen_catalog.rs |
catalog.rs |
@canon-* headers |
gen_meta.rs |
component_meta.rs, block_meta.rs |
@canon-* headers |
gen_definitions.rs |
block_definitions.rs, layout_definitions.rs |
@canon-* headers + props |
gen_api/ |
*/api.rs |
Leptos #[component] props |
gen_component_definitions.rs |
component_definitions.rs |
@canon-* headers |
gen_llm.rs |
llm_*.md |
All of the above |
Adding a New Component
- Create
canonrs-server/src/ui/<name>/<name>_ui.rswith@canon-*headers - Implement the Leptos
#[component] - Run
cargo build— all generated files update automatically
Adding a New Block
- Create
canonrs-server/src/blocks/<name>/<name>_block.rswith@canon-*headers - Add
@canon-slot-acceptsfor region rules - Run
cargo build
LLM Context
Three markdown files are generated for LLM consumption:
llm_components.md— intent, capabilities, relationships, usage contextllm_blocks.md— regions, props, presets, region rules, typical childrenllm_layouts.md— slots, slot rules, use when context
These files are the recommended input for AI page generation tasks.
Crate Structure
canonrs-core/
├── build/
│ ├── types.rs — shared build types
│ ├── utils.rs — helpers (pascal_to_kebab, to_const_name)
│ ├── parsers.rs — parse @canon-* headers, props, presets
│ └── generators/ — all code generators
├── src/
│ ├── infra/
│ │ ├── constraint_engine.rs — runtime validation engine
│ │ ├── state_engine.rs — aria-* / data-rs-state
│ │ └── dom_contract.rs — required parts validation
│ ├── primitives/ — 82 pure HTML primitives
│ ├── generated/ — auto-generated (do not edit)
│ ├── catalog_types.rs — CatalogEntry, CatalogAcceptRule, PropType
│ ├── block_types.rs — BlockDefinition, AcceptRule, BlockRegion
│ ├── meta_types.rs — ComponentMeta, Capability, ComponentFamily
│ └── lib.rs
└── build.rs — orchestrates all generators