Grouped workflow content with explicit loading and empty states. Busy takes precedence over empty. Content stays usable and focus remains with its native owner. Compose with cem-card.
Full examples and variation matrix · Property playground · Automated stories
{slice @name=label | Workspace}{cem-field @label="label" @value="{$datadom.slices.label}" @slice=label @slice-event=input @slice-value="$target.value"}
{slice @name=class | }{cem-field @label="class" @value="{$datadom.slices.class}" @slice=class @slice-event=input @slice-value="$target.value"}
{slice @name=tone | default}{fieldset @role=group @aria-label="tone" @slice=tone @slice-event=change @slice-value="$target.value" | {legend | tone}{cem-radio @name="property-tone" @value="default" @label="default" @checked={if datadom.slices.tone == "default" {true} else {null}}}{cem-radio @name="property-tone" @value="calm" @label="calm" @checked={if datadom.slices.tone == "calm" {true} else {null}}}{cem-radio @name="property-tone" @value="trust" @label="trust" @checked={if datadom.slices.tone == "trust" {true} else {null}}}{cem-radio @name="property-tone" @value="enthusiasm" @label="enthusiasm" @checked={if datadom.slices.tone == "enthusiasm" {true} else {null}}}{cem-radio @name="property-tone" @value="creativity" @label="creativity" @checked={if datadom.slices.tone == "creativity" {true} else {null}}}{cem-radio @name="property-tone" @value="danger" @label="danger" @checked={if datadom.slices.tone == "danger" {true} else {null}}}{cem-radio @name="property-tone" @value="conservative" @label="conservative" @checked={if datadom.slices.tone == "conservative" {true} else {null}}}}
{slice @name=dir | ltr}{fieldset @role=group @aria-label="dir" @slice=dir @slice-event=change @slice-value="$target.value" | {legend | dir}{cem-radio @name="property-dir" @value="ltr" @label="ltr" @checked={if datadom.slices.dir == "ltr" {true} else {null}}}{cem-radio @name="property-dir" @value="rtl" @label="rtl" @checked={if datadom.slices.dir == "rtl" {true} else {null}}}}
{slice @name=busy | absent}{fieldset @role=group @aria-label="busy" @slice=busy @slice-event=change @slice-value="$target.value" | {legend | busy}{cem-radio @name="property-busy" @value="absent" @label="absent" @checked={if datadom.slices.busy == "absent" {true} else {null}}}{cem-radio @name="property-busy" @value="present" @label="present" @checked={if datadom.slices.busy == "present" {true} else {null}}}}
{slice @name=empty | absent}{fieldset @role=group @aria-label="empty" @slice=empty @slice-event=change @slice-value="$target.value" | {legend | empty}{cem-radio @name="property-empty" @value="absent" @label="absent" @checked={if datadom.slices.empty == "absent" {true} else {null}}}{cem-radio @name="property-empty" @value="present" @label="present" @checked={if datadom.slices.empty == "present" {true} else {null}}}}
{slice @name=hidden | absent}{fieldset @role=group @aria-label="hidden" @slice=hidden @slice-event=change @slice-value="$target.value" | {legend | hidden}{cem-radio @name="property-hidden" @value="absent" @label="absent" @checked={if datadom.slices.hidden == "absent" {true} else {null}}}{cem-radio @name="property-hidden" @value="present" @label="present" @checked={if datadom.slices.hidden == "present" {true} else {null}}}}
{cem-surface @label="{$datadom.slices.label}" @tone="{$datadom.slices.tone}" @class="{$datadom.slices.class}" @dir="{$datadom.slices.dir}" @busy={if datadom.slices.busy == "present" {true} else {null}} @empty={if datadom.slices.empty == "present" {true} else {null}} @hidden={if datadom.slices.hidden == "present" {true} else {null}} | {h2 | Assets}{p | Content remains available during refresh.}{label | Filter {input @value=Images}}}{cem-module-url @slice=sourceUrl @src="@epa-wg/cem-components/components/cem-surface/cem-surface.xhtml"}{cem:if @test="datadom.slices.sourceUrl" | {p | {a @href="{$datadom.slices.sourceUrl}" | Open canonical XHTML}}{cem-demo-element @legend="Canonical source" @src="{$datadom.slices.sourceUrl}" @type=xml @demo=false}}