// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
syntax = "proto3";
package webui;
// Root protocol containing all fragment records.
// Per-component metadata keyed by tag name.
message ComponentData {
// Client-side template string for hydration.
// Populated by the active parser plugin at build time.
// Used by servers to send templates to the client during navigation.
string template = 1;
// Component CSS content for the Module strategy.
// Contains the full CSS content when CssStrategy::Module is active.
// Empty for Link and Style strategies (CSS is handled via <link> tags
// or inline <style> tags baked into raw fragments by the parser).
string css = 2;
// External stylesheet href for the Link CSS strategy.
// Set to e.g. "/my-card.css" when CssStrategy::Link is active and the
// component has a CSS file. Empty for Style/Module strategies and for
// components without CSS. The handler emits a <link> tag only when
// this field is non-empty.
string css_href = 3;
}
message WebUIProtocol {
map<string, FragmentList> fragments = 1;
// Sorted, deduplicated CSS custom property names used across all components
// and entry page styles (e.g., "colorBrandBackground", "spacingMedium").
// Only usage via var(--name) is included; local definitions are excluded.
repeated string tokens = 2;
// Per-component data keyed by tag name (f-template + CSS).
map<string, ComponentData> components = 3;
}
// A list of fragments (needed because protobuf maps cannot have repeated values directly).
message FragmentList {
repeated WebUIFragment fragments = 1;
}
// A single fragment — one of several types.
message WebUIFragment {
oneof fragment {
WebUIFragmentRaw raw = 1;
WebUIFragmentComponent component = 2;
WebUIFragmentFor for_loop = 3;
WebUIFragmentSignal signal = 4;
WebUIFragmentIf if_cond = 5;
WebUIFragmentAttribute attribute = 6;
WebUIFragmentPlugin plugin = 7;
WebUIFragmentRoute route = 8;
WebUIFragmentOutlet outlet = 9;
}
}
// Declarative route definition linking a URL path template to a component.
// Nested routes are expressed via repeated children.
message WebUIFragmentRoute {
string path = 1;
string fragment_id = 2;
bool exact = 3;
// Nested child routes rendered at the component's <outlet />.
repeated WebUIFragmentRoute children = 4;
}
// Outlet placeholder — marks where matched child route content renders.
// Components use this to indicate where nested route children are rendered.
message WebUIFragmentOutlet {}
// Opaque plugin-specific data passed from parser plugin to handler plugin.
// WebUI framework does not interpret this data — it is a pass-through conduit.
// Each parser/handler plugin pair defines its own binary contract for the data field.
message WebUIFragmentPlugin {
bytes data = 1;
}
// Static text or HTML content.
message WebUIFragmentRaw {
string value = 1;
}
// Reference to a reusable component fragment.
message WebUIFragmentComponent {
string fragment_id = 1;
}
// Loop directive iterating over a collection.
message WebUIFragmentFor {
string item = 1;
string collection = 2;
string fragment_id = 3;
}
// Dynamic data binding via signal.
message WebUIFragmentSignal {
string value = 1;
bool raw = 2;
}
// Conditional rendering fragment.
message WebUIFragmentIf {
ConditionExpr condition = 1;
string fragment_id = 2;
}
// Dynamic attribute binding.
message WebUIFragmentAttribute {
string name = 1;
// For simple dynamic attrs, the signal name.
string value = 2;
// For mixed (template) attrs, the sub-stream ID.
string template = 3;
// True for :-prefixed complex attributes.
bool complex = 4;
// True for the first dynamic attribute on a component element.
bool attr_start = 5;
// True for skipped attributes (class, style, role, data-*, aria-*).
bool attr_skip = 6;
// True for static attribute values on components.
bool raw_value = 7;
// For ?-prefixed boolean attributes, the condition tree.
ConditionExpr condition_tree = 8;
}
// A condition expression tree.
message ConditionExpr {
oneof expr {
Predicate predicate = 1;
NotCondition not = 2;
CompoundCondition compound = 3;
IdentifierCondition identifier = 4;
}
}
// Simple comparison predicate.
message Predicate {
string left = 1;
ComparisonOperator operator = 2;
string right = 3;
}
// Negation wrapper.
message NotCondition {
ConditionExpr condition = 1;
}
// Two conditions joined by a logical operator.
message CompoundCondition {
ConditionExpr left = 1;
LogicalOperator op = 2;
ConditionExpr right = 3;
}
// Single identifier (variable name).
message IdentifierCondition {
string value = 1;
}
enum LogicalOperator {
LOGICAL_OPERATOR_UNSPECIFIED = 0;
AND = 1;
OR = 2;
}
enum ComparisonOperator {
COMPARISON_OPERATOR_UNSPECIFIED = 0;
GREATER_THAN = 1;
LESS_THAN = 2;
EQUAL = 3;
NOT_EQUAL = 4;
GREATER_THAN_OR_EQUAL = 5;
LESS_THAN_OR_EQUAL = 6;
}