Overview
A presentation component for building and reviewing conditional automation rules. Each rule is composed of one or more conditions (field / operator / value) and one or more actions (a target agent or service). Cinder renders the UI and reports every edit through a callback — it owns no rule execution, persistence, or validation semantics.
Ownership boundary
Cinder does not execute, validate, or persist rules. The consumer provides the complete rule model through the rules prop and handles every change emitted by onchange. Cinder is responsible only for rendering the controls with correct accessible names and emitting pure (non-mutating) change descriptors.
Usage
Data model
A rule fires when ALL of its conditions match (implicit AND). Boolean grouping, OR logic, and nested condition trees are out of scope for this component.
Modes
Pass readonly={true} to render a read-only summary instead of editable controls. Schema-driven usage is read-only because callbacks are not representable in JSON Schema. Runtime consumers can render editable controls by passing onchange and leaving readonly false.
Conditions-only mode
Pass mode="conditions" to render conditions without actions — for example, a saved-search or alert-filter builder that has nothing to invoke. In this mode:
- Action controls are hidden entirely. Rules never render or emit action descriptors (
add-action,remove-action,update-action), and any actions on incoming rules are stripped from emitted rules. In the TypeScript props,operatorOptions,actionOptions, andaddActionLabelare typedneverin conditions-only mode, so passing them is a compile-time error. (The schema-driven surface and the runtime are more lenient — they treat those props as optional and simply ignore them in conditions-only mode, which is why the generated props table below lists them as optional.) - The operator set is fixed to
eq(equals),gt(greater than),lt(less than),gte(greater than or equal), andlte(less than or equal). Cinder supplies these five with default labels. - The field control is a free-text combobox.
fieldOptionsremain typeahead suggestions and provide type metadata, but a user can press Enter or leave the field after typing a key that is not in the list. - The value control for each condition is inferred from the matching
fieldOptionsentry's optionaltype: a numeric text input for'number', a checkbox for'boolean', a<select>populated from that option'soptionsfor'enum', and a plain text input for'string'or an omittedtype.
A rule created in this mode still has an actions array on its data shape (so InvocationRule stays a single type across modes), but it is always empty and the UI provides no way to populate it.
Accessibility
Each condition's field selector, operator selector, value input, and remove button carry accessible labels that identify which condition and rule they belong to (e.g. "Field for condition 2 of Rule 1"). Each action's target selector and remove button are similarly labeled. Rule reorder buttons are labeled "Move Rule 1 up" and "Move Rule 1 down". Add buttons describe their destination rule. A live region announces add, remove, and move events to screen reader users.
In readonly mode all controls are replaced by visible text, so no interaction is possible and keyboard navigation follows the natural document order.
Focus management on remove: when a condition or action row is removed, focus moves to the preceding row's remove button, or to the "Add condition" / "Add action" button if the removed row was the last one.
The component uses semantic HTML: the root is a section with an aria-label, condition and action lists use role="list" with aria-labelledby pointing to the "Conditions" / "Actions" section heading, and each row uses role="listitem". In conditions-only modes, each field combobox keeps the per-condition accessible name (for example, "Field for condition 2 of Rule 1").
When to use
- Building a UI for configuring which agents or services run based on event conditions.
- You only need conditions (no actions) — pass mode="conditions" for a constrained operator set and typed value inputs.
- Your data is one flat implicit-AND conditions list — pass mode="flat-conditions" without rule-group metadata.
- You need to execute, validate, or persist rules — cinder owns none of that logic.
Examples
PR review routing rules
Configure which code review agents run based on pull request conditions such as changed paths, labels, and author membership.
Conditions-only mode
Build alert-filter conditions with typed value inputs and a fixed comparison-operator set — no action targets, for cases like saved searches or alert filters that have nothing to invoke.
Flat AND-only conditions
Edit one controlled conditions array directly, without rule names, ordering, actions, or a way to add another group.
Readonly rule summary
Display configured automation rules in a non-editable summary view, suitable for review or confirmation screens.
Props
| Name | Type | Default | Required | Bindable | Description |
|---|---|---|---|---|---|
rules | unknown | [] | |||
conditions | unknown | [] | |||
onchange | unknown | req | |||
fieldOptions | InvocationRuleOption[] | req | Options for the condition field selector. Consumer-provided list of fields that a condition can test, e.g. "path", "label", "author". | ||
operatorOptions | unknown | req | |||
actionOptions | unknown | req | |||
mode | unknown | 'full' | |||
readonly | unknown | false | |||
addRuleLabel | unknown | 'Add rule' | |||
addConditionLabel | text | 'Add condition' | Label for the "Add condition" button. Defaults to "Add condition". | ||
addActionLabel | unknown | 'Add action' | |||
label | text | Accessible label for the entire rule builder region. |