unit-collection-item-marker
"A collection edited as one unit must not render data-slot-item row markers."
Venue: check — A collection edited as one unit must not render data-slot-item row markers.
A list edited as one unit must render no data-slot-item markers. check renders
every fixture and reads the markers that reached the DOM; this is reported when a list
whose editing granularity is "unit" emits an item marker on any row, in any fixture.
The granularity comes from the declared ITEM, and nothing declares it. A record
item — list.of({ … }, { … }) — is edited per row. Every single-slot item is
edited as one card, so its rows are not individually selectable and a row marker on
one is a contradiction between the schema and the markup.
Reason
Section titled “Reason”The editor trusts the item. A unit-edited list gets one sidebar card and no per-row selection: nothing ever reads its item markers, so a marker there is not extra coverage — it is a claim the editor will never honor. A user clicks the marked row, nothing selects, and the row looks broken; an author reads the markup, sees row markers, and reasonably expects per-row editing the item never asked for.
Before this check, that mismatch was invisible: the marker was simply ignored. Making it an error keeps the schema and the markup telling the same story, whichever one is wrong — either the item should be a record, or its rows should stop claiming identity.
Decide which side is right. If the rows really are individually editable, they have per-row content — declare the item as the record it is:
import { defineSchema, list, text } from "@homepages/template-kit";
export const schema = defineSchema({ label: "Amenities", slots: { features: list.of( { label: text.short({ label: "Name" }), detail: text.medium({ label: "Detail" }), }, { label: "Features", title: "label" }, ), },});If the list really is one editing unit, render its rows as plain elements — the container keeps the list’s own marker, the rows carry none:
Before
Section titled “Before”import { bindItems, bindSlots, Section, Slot } from "@homepages/template-kit";
import { schema } from "./schema.js";import type { Props } from "./schema.js";
export function Renderer({ slots }: Props) { const slot = bindSlots(schema, slots); return ( <Section> <Slot.List slot={slot.features} as="ul"> {bindItems(slot.features).map((feature) => ( // template-kit/unit-collection-item-marker: a row marker on a unit-edited list <Slot.Group slot={feature} as="li" key={feature.index}> {feature.value} </Slot.Group> ))} </Slot.List> </Section> );}import { bindItems, bindSlots, defineSchema, list, Section, Slot, text } from "@homepages/template-kit";import type { SectionProps } from "@homepages/template-kit";
const schema = defineSchema({ label: "Amenities", slots: { features: list.of(text.short({ label: "Text" }), { label: "Features" }), },});
type Props = SectionProps<typeof schema>;
export function Renderer({ slots }: Props) { const slot = bindSlots(schema, slots); return ( <Section> <Slot.List slot={slot.features} as="ul"> {bindItems(slot.features).map((feature) => ( <li key={feature.index}>{feature.value}</li> ))} </Slot.List> </Section> );}See also
Section titled “See also”missing-slot-marker— the opposite direction: a record-item list must mark every row, in every rendered copy.- Schema reference — the list grammar the granularity is read from.
- Slot primitives —
Slot.List,Slot.Group, and which marker each emits.