Rask UI is plain C#: you compose components from a small set of primitives, a generated tag
factory for every HTML (and SVG) element, a uniform set of universal props on every tag, and the
[...] children indexer to nest them. This guide is the reference for that surface, with a live demo of
each piece.
- Primitives —
Text,Raw,Doctype, sibling fragments via[...], and children from strings - Tag factories — every HTML element, strongly typed
- Universal props —
Id/Class/Style/Data/Ariaon every tag - SVG — typed SVG components, no
Raw() - HTML elements — the full element catalog, by category
Three primitives sit beneath every Rask page: Text, Raw, and Doctype. Everything else is
built out of them — plus the [...] collection expression, which groups siblings with no wrapping tag.
Text HTML-encodes its value — < and & render as literal characters, never parsed as markup:
Raw is the escape hatch: verbatim, un-encoded HTML. Use it when you control the source (Markdown
output, sanitised snippets) — never on user input.
Security:
Rawskips all HTML encoding. Never feed it untrusted strings — sanitize, or useText.
A bare [...] collection expression returns multiple siblings with no surrounding tag — a Component
in its own right, so it's what Render() returns when a component has more than one root. Handy for
siblings at the root, especially [Doctype(), Html(...)] as the page entry point:
Doctype() emits exactly <!DOCTYPE html> — special-cased, with no attributes, children, or wrapper:
A bare string is a valid child, so text flows into the [...] indexer alongside elements (it's
encoded exactly like Text):
Every standard HTML element has a generator-emitted factory in Rask.Core.Components.Generated.
Tag-specific attributes come first; the universal Id/Class/Style/Data trail at the end.
Text & semantic elements:
Form elements:
Tables:
Media:
Void elements (Br, Hr, Img, Meta, Link, Input, …) have SelfClosing => true and never
accept children:
Every tag accepts Id, Class, Style, Data, and the accessibility props Role, TabIndex, and
Aria. They render in that exact order, ahead of any tag-specific attributes.
Id, Class, Style:
Data — a dictionary expands to data-* attributes; a null value renders as a bare attribute (e.g.
data-new), the same way boolean attributes like disabled work:
Aria, Role, TabIndex — Aria is the data-* model applied to ARIA (each entry expands to
aria-{key}, value HTML-encoded, null → bare attribute); Role and TabIndex are typed because they
aren't aria-* attributes. See the accessibility guide and the RASK023 img-alt
analyzer.
Attribute order is fixed: base props first (id, class, style, title, data-*, role,
tabindex, aria-*), then tag-specific. Tests enforce it, so the output is predictable for diffing and
DOM tooling:
Title is the global title attribute — the browser's hover tooltip. Reach for it where a cell shows an
abbreviated value and the exact one belongs behind it (a relative timestamp over the precise instant, a
truncated string over its full text). It is not a label: title is invisible to touch users,
unreliable with screen readers, and unfocusable, so it may carry supplementary detail but never the only
copy of something the reader needs — use Aria for an accessible name.
SVG elements are first-class core components. svg, g, path, the shapes, text, gradients and
filters all have typed factories that flow through scoped CSS, keyed lists, and event handlers — no
Raw() required.
Shapes inside an <svg> — presentation attributes (Fill, Stroke, StrokeWidth, StrokeLinecap, …)
live on the shared SvgElement base, so every shape exposes them as optional factory parameters:
Gradients via <defs> and <linearGradient> (the Rask brand mark itself is built this way); a nested
SvgTitle gives the graphic its accessible name:
Clickable shapes — OnClick works on any element; the selection re-renders live over the same transport
as the rest of the page:
Text with <text> and <tspan> — SvgText is the <text> tag (renamed to avoid colliding with the
Text primitive); Tspan styles a run inside it:
Every standard element is a generated factory, composed through the [...] children indexer. The
catalog below groups them the way the HTML spec does.
a, abbr, b, bdi, bdo, br, cite, code, data, dfn, del, em, i, ins, kbd,
mark, q, ruby/rp/rt, s, samp, small, span, strong, sub, sup, time, u, wbr:
p, hr, pre, blockquote, ol/ul/li, dl/dt/dd, figure/figcaption, div:
h1–h6, header, footer, main, section, article, aside, nav, address, hgroup:
form, label, input, button, select/option/optgroup, textarea, fieldset/legend,
datalist, output, progress, meter:
table, caption, colgroup/col, thead/tbody/tfoot, tr, th/td:
img, picture/source, audio, video/track, iframe, embed, object, canvas, map/area:
details/summary, dialog, menu:
html, head, body, title, base, link, meta, style, script, noscript:
See also: Getting started for building your first component, and Best practices for production patterns.