What is happening
Two components have grown an icon slot in the last few releases, each for the same reason and each defensible on its own:
Both were added because a product could not reach its existing appearance otherwise: parts style an element, they cannot replace its children. So the request is legitimate every time it arrives, and the answer is cheap every time. That is exactly how an API grows in the wrong direction one reasonable step at a time.
The components still waiting to ask are easy to name: Dropdown's indicator and clear, ComboBox's trigger, DatePickerInput's previous/next/clear, Breadcrumbs' separator (a prop already, for the same reason), NumberInput's steppers, DataTable's sort direction. If each grows its own prop, a product that wants its icon set throughout passes a dozen props spread across a dozen call sites, and gets no help at all for the ones it forgets.
Worth deciding instead
Whether the library wants one icon strategy rather than a per-component slot:
<CratisComponentsProvider icons={{ close: <XIcon />, remove: <XIcon />, chevronDown: … }}>
resolved by each component with its current glyph as the fallback, and the per-component prop kept as the override for a single call site. That is the shape messages already has on the provider, so it is an existing convention rather than a new one — a product registers its icon set once and every component, including ones added later, picks it up.
The cost is a decision about which icon names are public contract. The alternative is not free either: it is a dozen props and a product that can never be fully consistent.
No change proposed here, and nothing is broken today: closeIcon and removeIcon both work. This is a question about which direction the next five of these should go, before there are five.
What is happening
Two components have grown an icon slot in the last few releases, each for the same reason and each defensible on its own:
Dialog.closeIcon(4.7.0, Dialog: add start/end placement for side sheets #280) — so a product's header close button carries its own glyph instead of×.TagGroup.removeIcon(4.10.0, TagGroup hard-codes its remove glyph, so a product cannot keep its own close icon #293) — the same thing for a tag's remove button.Both were added because a product could not reach its existing appearance otherwise: parts style an element, they cannot replace its children. So the request is legitimate every time it arrives, and the answer is cheap every time. That is exactly how an API grows in the wrong direction one reasonable step at a time.
The components still waiting to ask are easy to name:
Dropdown's indicator and clear,ComboBox's trigger,DatePickerInput's previous/next/clear,Breadcrumbs' separator (a prop already, for the same reason),NumberInput's steppers,DataTable's sort direction. If each grows its own prop, a product that wants its icon set throughout passes a dozen props spread across a dozen call sites, and gets no help at all for the ones it forgets.Worth deciding instead
Whether the library wants one icon strategy rather than a per-component slot:
resolved by each component with its current glyph as the fallback, and the per-component prop kept as the override for a single call site. That is the shape
messagesalready has on the provider, so it is an existing convention rather than a new one — a product registers its icon set once and every component, including ones added later, picks it up.The cost is a decision about which icon names are public contract. The alternative is not free either: it is a dozen props and a product that can never be fully consistent.
No change proposed here, and nothing is broken today:
closeIconandremoveIconboth work. This is a question about which direction the next five of these should go, before there are five.