Imported from wieslawsoltes/CssUno (
AGENTS.md). Install upstream withnpx skills add wieslawsoltes/CssUno. Copyright stays with the author.
AGENTS.md
Guidance for agents working in this repository.
Project Goal
CssUno is a CSS-to-Uno Platform compiler and runtime bridge. It parses CSS at build time, uses Roslyn source generators to emit C# style registration code, and applies generated Uno/WinUI styles through application resources plus runtime selector matching where CSS semantics require it.
The long-term direction is broad CSS compatibility while keeping the output idiomatic for Uno, WinUI, XAML, and C#:
- Translate CSS into generated Uno/WinUI styles and dependency-property setters.
- Support global CSS, linked CSS, inline stylesheet blocks, and CSS-like inline
Styleattributes. - Support prefixless XAML authoring through
XmlnsDefinitionand the build-time XAML rewrite. - Provide HTML-style XAML helpers such as
<div>, semantic HTML element wrappers, input/control wrappers,class, andid. - Provide native Tailwind-style utility generation by scanning static XAML class tokens and expanding supported utilities into normal CssUno CSS before translation.
- Provide a converter library that transforms HTML/CSS into Uno XAML and C# object construction code.
- Provide CSS-to-Uno style export that emits idiomatic
ResourceDictionary,Style, andSetterXAML where CSS rules can be represented without runtime selector semantics. - Keep generated output deterministic, inspectable, and enabled in the sample app.
Repository Shape
src/CssUno.Stylesheets: framework-neutral CSS parser model, selector parsing, media-query model, and diagnostics.src/CssUno.Uno.Compiler: Uno/WinUI declaration translation and CSS-to-XAML style export.src/CssUno.Core: compatibility package with type forwarders referencingCssUno.StylesheetsandCssUno.Uno.Compiler.src/CssUno.Tailwind: standalone Tailwind-style utility compiler and XAML class-token extractor.src/CssUno.SourceGenerators: Roslyn incremental source generator and generated C# emitter.src/CssUno: Uno runtime bridge, attached properties,CssStyleRegistry,CssStyleRule,CssStylesheet,Div, HTML-style elements, XAML namespace metadata, and MSBuild integration.src/CssUno.Html: HTML/CSS converter, element mappings, selector rewriting, XAML/C# object writers, built-in playground samples.samples/CssUno.Sample: Uno catalog sample and converter playground.tests/CssUno.Tests: parser, translator, source generator, and converter tests.
Current Feature Surface
Maintain and extend the existing support for:
- CSS selectors: type, class, id, combined selectors, selector lists, descendant/child/sibling combinators, common attribute selectors, runtime state pseudo-classes, structural pseudo-classes, and form-oriented pseudo-classes backed by Uno state or
Css.Attributes. - Runtime media queries: width, height, orientation, ranges,
screen,all,only, comma alternatives. - Tailwind utilities: responsive variants, state/structural/form variants, group/peer state and attribute variants, spacing, structural
space-*child selectors, sizing, logical positioning, colors, typography, flex/layout, grid helpers, borders and structuraldivide-*child selectors, effects, transforms, transitions, opacity, overflow, object-fit, z-index, and arbitrary bracket or parenthesized variable values where CssUno translators can map or preserve them. - Box model: width/height/min/max, margin, padding, opacity.
- Colors and borders: color/background, background-image/size/position/repeat metadata, border color/width/radius, border shorthand, and outline metadata.
- Typography: font size/family/weight/style, font shorthand, text alignment, line height, decoration, transform, letter spacing, white-space, text-overflow, word-break, overflow-wrap, hyphens, and user-select.
- Layout:
Divblock/flex layout, Grid templates and placement, grid longhands and auto-track metadata, gaps, alignment, object-fit/object-position, overflow, Canvas top/left/z-index. - Style export: type-only CSS to implicit Uno styles, simple selector rules to keyed styles, diagnostics for media/descendant/runtime-only behavior.
- HTML object model and converter mappings:
divand structural containers toCssUnoDiv derivatives, grid divs toGrid, lists toUl/Ol/Li, text tags to CssUno text wrappers, forms to CssUno input/control wrappers, images toImg. - Sample catalog pages covering every supported feature group.
Implementation Principles
Use SOLID principles when adding or changing features:
- Single Responsibility: keep parsing, translation, generation, runtime application, and sample UI concerns separate.
- Open/Closed: prefer adding focused translators/helpers over editing unrelated behavior or hard-coding one-off cases.
- Liskov Substitution: generated styles and runtime matching must work with derived Uno controls where
TargetType.IsAssignableFromapplies. - Interface Segregation: keep public APIs small and task-specific; do not force consumers to depend on converter APIs when they only need runtime styling.
- Dependency Inversion: keep low-level parser/runtime details behind simple models where practical, especially in converter and generator code.
Favor idiomatic Uno/WinUI behavior over emulating a browser engine. Add attached properties only when a CSS concept has no good direct WinUI style property.
Uno/WinUI Style Integration
Generated and transformed output must preserve native Uno/WinUI styling behavior whenever possible:
- Prefer built-in Uno/WinUI controls, dependency properties, default templates, and theme resources over custom runtime abstractions.
- Generated runtime styles should be based on the element's existing explicit, implicit, or theme style when the platform API allows it.
- Do not replace a control style in a way that drops its default template, visual states, focus behavior, accessibility behavior, or theme resources.
- Preserve user-authored explicit
Stylevalues when applying runtime CSS. CSS-generated styles should layer on top of the existing style, not discard it. - Use generated setters for CSS declarations, but let Uno/WinUI own control templates and standard visual behavior.
- Prefer emitting normal XAML
ResourceDictionary/Style/Setteroutput when a CSS rule can be represented as idiomatic Uno/WinUI styles without runtime matching. - The XAML transformer should not rewrite non-CSS
Stylevalues such as{StaticResource ...},{ThemeResource ...}, or bindings. - Prefer idiomatic WinUI style inheritance or resource lookups before introducing CssUno-specific replacement mechanisms.
Performance Requirements
Performance matters in parser, generator, converter, selector matching, and layout code.
When implementing features:
- Using the fastest appropriate .NET language and framework features is mandatory for hot paths. Prefer modern runtime APIs, span-based parsing, pooled temporary storage, allocation-free enumeration, and source-generated or strongly typed access over slower convenience APIs whenever correctness and maintainability can be preserved.
- Performance-sensitive changes must be validated with BenchmarkDotNet when they affect parser, Tailwind compiler, generator, selector matching, converter, or runtime style application throughput. Keep benchmarks focused, repeatable, and checked into the repository when they cover reusable infrastructure.
- Choose the best practical Big O complexity. Prefer linear or near-linear algorithms; avoid accidental O(n²) behavior in selector matching, tree walks, string rewriting, and generated-code emission.
- Use dictionaries, hash sets, pre-indexed lookups, and stable ordering where they reduce repeated scans.
- Use high-performance .NET APIs where appropriate:
ReadOnlySpan<char>/Span<T>for hot-path tokenization and parsing.Memory<T>/ReadOnlyMemory<T>when data must outlive a stack frame.ArrayPool<T>or pooled builders for large temporary buffers.StringBuilderfor generated source and repeated string composition.- Cached or compiled
Regexonly when regex is justified; prefer explicit parsers for hot paths. StringComparer.Ordinal/OrdinalIgnoreCasefor deterministic identifiers and selectors.CultureInfo.InvariantCulturefor generated code, CSS numeric values, and serialized output.
- Avoid LINQ in hot loops when allocations or repeated enumeration are material.
- Avoid unnecessary allocations in source generators; keep incremental generator inputs stable and deterministic.
- Respect cancellation tokens in generator pipelines where Roslyn provides them.
- Do not add reflection-heavy or dynamic behavior to runtime style application unless there is a clear measured reason.
For layout and runtime style application, consider visual-tree size. Any new matching algorithm should scale predictably on large UI trees.
Algorithm and Design Expectations
Use state-of-the-art, proven approaches for the domain:
- Prefer mature permissively licensed parsing libraries for CSS/HTML rather than hand-rolling full parsers.
- Keep source generation incremental, deterministic, and side-effect free.
- Use structured models for CSS rules, selectors, declarations, diagnostics, and object trees.
- Preserve unsupported CSS as diagnostics instead of silently ignoring it, unless it is an expected expansion artifact from a supported shorthand.
- Add new CSS support in a way that can evolve toward the full spec rather than blocking future selectors, cascade, custom properties, pseudo states, or at-rules.
- Keep generated code readable enough to inspect in
Generated/SourceGenerators.
When a feature has incomplete CSS semantics, implement the best Uno-compatible subset and document the limitation.
Adding CSS Support
For each new CSS property or feature:
- Add parser/model support in
src/CssUno.Stylesheetsand Uno/WinUI translator support insrc/CssUno.Uno.Compiler. - Map directly to Uno/WinUI dependency properties whenever possible.
- Use attached properties in
src/CssUnoonly for CSS concepts without native Uno equivalents. - Update
UnoStyleSheetConverterwhen the property can be represented as XAMLStyle/Setteroutput. - Emit warnings for unsupported targets or values.
- Add focused tests in
tests/CssUno.Tests. - Add or update sample catalog pages and CSS in
samples/CssUno.Sample. - Update
README.mdsupported feature tables.
Generated setters must use fully qualified global type names where generator output requires them.
Adding Tailwind Utility Support
For each new Tailwind utility or variant:
- Add utility expansion in
src/CssUno.Tailwind/TailwindUtilityCompiler.cs. - Prefer emitting plain CSS declarations that the existing
UnoCssTranslatoralready maps. - Preserve variant semantics by emitting media queries and pseudo-class selectors instead of flattening them into unconditional styles.
- Add a translator/runtime feature only when the emitted CSS property or selector cannot currently be represented.
- Avoid warnings for arbitrary unknown class names; XAML often contains project-specific classes that are not Tailwind utilities.
- Add unit tests that validate generated CSS and downstream CssUno translation.
- Add or update a sample page using HTML-style objects.
- Update
README.mdsupported utility coverage and limitations.
Adding HTML/CSS Converter Support
For each new HTML element or attribute mapping:
- Update
HtmlElementMapwith the semantic Uno target. - Update selector rewriting so web selectors still apply after conversion.
- Preserve internal
_html_*tag classes. - Emit valid XAML and valid C# object construction code.
- Add built-in playground samples that cover the new mapping.
- Add converter tests that assert XAML, C#, and rewritten CSS output.
The converter is not a browser engine. It should create maintainable Uno object models that are useful for migration and tooling.
Sample App Requirements
The sample app should remain a control-catalog style app:
- Every supported feature group should have a visible page.
- Add pages for newly supported CSS or HTML object-model features.
- Keep pages dense, practical, and inspectable.
- Keep generated source output enabled so users can inspect source-generator output.
- Avoid decorative-only UI work that does not demonstrate CssUno behavior.
Testing and Verification
Run these before considering feature work complete:
dotnet test CssUno.slnx --no-restore
dotnet build CssUno.slnx --no-restore
dotnet pack src/CssUno/CssUno.csproj --no-restore
dotnet pack src/CssUno.Html/CssUno.Html.csproj --no-restore
Use targeted tests while iterating, but finish with the full verification pass unless the change is documentation-only.
Code Quality
- Keep APIs small and explicit.
- Keep diagnostics actionable.
- Prefer deterministic ordering in generated code and tests.
- Keep comments brief and only where they explain non-obvious behavior.
- Do not introduce unrelated refactors while adding a feature.
- Do not regress existing XAML rewrite behavior, global styles, inline CSS extraction, generated source output, or catalog samples.
