A keyboard-navigable hierarchy whose expansion and selection remain distinct. Use cem-list for a flat collection or cem-nav for navigation links.
Full examples and variation matrix · Property playground · Automated stories · Shared project navigation declaration
Up/Down, Home/End and typeahead move focus. Right/Left open, close or traverse parent/child relationships. Enter/Space toggles a branch or emits leaf activation; application selection remains unchanged. Set activate-branches to also emit activation when a folder is clicked.
{slice @name=label | Workspace resources}
{cem-field @label="label" @value="{$datadom.slices.label}" @slice=label @slice-event=input @slice-value="$target.value"}
{slice @name=separate-toggle | absent}{fieldset @role=group @aria-label="separate-toggle" @slice=separate-toggle @slice-event=change @slice-value="$target.value" | {legend | separate-toggle}{cem-radio @name=property-separate-toggle @value=absent @label=absent @checked={if datadom.slices.separate-toggle == "absent" {true} else {null}}}{cem-radio @name=property-separate-toggle @value=present @label=present @checked={if datadom.slices.separate-toggle == "present" {true} else {null}}}}
{slice @name=data-cem-density | normal}{fieldset @role=group @aria-label="data-cem-density" @slice=data-cem-density @slice-event=change @slice-value="$target.value" | {legend | data-cem-density}{cem-radio @name=property-data-cem-density @value=normal @label=normal @checked={if datadom.slices.data-cem-density == "normal" {true} else {null}}}{cem-radio @name=property-data-cem-density @value=super-compact @label=super-compact @checked={if datadom.slices.data-cem-density == "super-compact" {true} else {null}}}}
{slice @name=icon | ◇}{cem-field @label=icon @value={datadom.slices.icon} @slice=icon @slice-event=input @slice-value="$target.value"}
{slice @name=kind | project}{fieldset @role=group @aria-label="kind" @slice=kind @slice-event=change @slice-value="$target.value" | {legend | kind}{cem-radio @name=property-kind @value=project @label=project @checked={if datadom.slices.kind == "project" {true} else {null}}}{cem-radio @name=property-kind @value=resource @label=resource @checked={if datadom.slices.kind == "resource" {true} else {null}}}{cem-radio @name=property-kind @value=output @label=output @checked={if datadom.slices.kind == "output" {true} else {null}}}{cem-radio @name=property-kind @value=folder @label=folder @checked={if datadom.slices.kind == "folder" {true} else {null}}}}
{slice @name=activate-branches | absent}
{fieldset @role=group @aria-label="activate-branches" @slice=activate-branches @slice-event=change @slice-value="$target.value" | {legend | activate-branches}{cem-radio @name=property-activate-branches @value=absent @label=absent @checked={if datadom.slices.activate-branches == "absent" {true} else {null}}}{cem-radio @name=property-activate-branches @value=present @label=present @checked={if datadom.slices.activate-branches == "present" {true} else {null}}}}
{slice @name=expanded-values | files}
{cem-field @label="expanded-values" @value="{$datadom.slices.expanded-values}" @slice=expanded-values @slice-event=input @slice-value="$target.value"}
{slice @name=selected-values | readme}
{cem-field @label="selected-values" @value="{$datadom.slices.selected-values}" @slice=selected-values @slice-event=input @slice-value="$target.value"}
{slice @name=loading-label | Loading}
{cem-field @label="loading-label" @value="{$datadom.slices.loading-label}" @slice=loading-label @slice-event=input @slice-value="$target.value"}
{slice @name=aria-label | }
{cem-field @label="aria-label" @value="{$datadom.slices.aria-label}" @slice=aria-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=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=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}}}}
{slice @name=disabled | absent}
{fieldset @role=group @aria-label="disabled" @slice=disabled @slice-event=change @slice-value="$target.value" | {legend | disabled}{cem-radio @name="property-disabled" @value="absent" @label="absent" @checked={if datadom.slices.disabled == "absent" {true} else {null}}}{cem-radio @name="property-disabled" @value="present" @label="present" @checked={if datadom.slices.disabled == "present" {true} else {null}}}}
{slice @name=loading | absent}
{fieldset @role=group @aria-label="loading" @slice=loading @slice-event=change @slice-value="$target.value" | {legend | loading}{cem-radio @name="property-loading" @value="absent" @label="absent" @checked={if datadom.slices.loading == "absent" {true} else {null}}}{cem-radio @name="property-loading" @value="present" @label="present" @checked={if datadom.slices.loading == "present" {true} else {null}}}}
{slice @name=expandable | absent}
{fieldset @role=group @aria-label="expandable" @slice=expandable @slice-event=change @slice-value="$target.value" | {legend | expandable}{cem-radio @name="property-expandable" @value="absent" @label="absent" @checked={if datadom.slices.expandable == "absent" {true} else {null}}}{cem-radio @name="property-expandable" @value="present" @label="present" @checked={if datadom.slices.expandable == "present" {true} else {null}}}}
{slice @name=item-disabled | absent}
{fieldset @role=group @aria-label="item-disabled" @slice=item-disabled @slice-event=change @slice-value="$target.value" | {legend | item-disabled}{cem-radio @name="property-item-disabled" @value="absent" @label="absent" @checked={if datadom.slices.item-disabled == "absent" {true} else {null}}}{cem-radio @name="property-item-disabled" @value="present" @label="present" @checked={if datadom.slices.item-disabled == "present" {true} else {null}}}}
{slice @name=selection | none}
{fieldset @role=group @aria-label="selection" @slice=selection @slice-event=change @slice-value="$target.value" | {legend | selection}{cem-radio @name="property-selection" @value="none" @label="none" @checked={if datadom.slices.selection == "none" {true} else {null}}}{cem-radio @name="property-selection" @value="single" @label="single" @checked={if datadom.slices.selection == "single" {true} else {null}}}{cem-radio @name="property-selection" @value="multiple" @label="multiple" @checked={if datadom.slices.selection == "multiple" {true} else {null}}}}
{cem-tree @separate-toggle={if datadom.slices.separate-toggle == "present" {true} else {null}} @data-cem-density={datadom.slices.data-cem-density} @activate-branches={if datadom.slices.activate-branches == "present" {true} else {null}} @label="{$datadom.slices.label}" @expanded-values="{$datadom.slices.expanded-values}" @selected-values="{$datadom.slices.selected-values}" @loading-label="{$datadom.slices.loading-label}" @selection="{$datadom.slices.selection}" @class="{$datadom.slices.class}" @dir="{$datadom.slices.dir}" @aria-label={if datadom.slices.aria-label {datadom.slices.aria-label} else {null}} @disabled={if datadom.slices.disabled == "present" {true} else {null}} @hidden={if datadom.slices.hidden == "present" {true} else {null}} | {cem-tree-item @value=files @label=Files @icon={datadom.slices.icon} @kind={datadom.slices.kind} | {cem-tree-item @value=readme @label=README}{cem-tree-item @value=locked @label=Locked @disabled={if datadom.slices.item-disabled == "present" {true} else {null}}}}{cem-tree-item @value=remote @label=Remote @expandable={if datadom.slices.expandable == "present" {true} else {null}} @loading={if datadom.slices.loading == "present" {true} else {null}}}{cem-tree-item @value=settings @label=Settings}}{cem-module-url @slice=sourceUrl @src="@epa-wg/cem-components/components/cem-tree/cem-tree.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}}