skip to content

Component Library

The coded library behind a design system: its public API, composition model, theme hooks, accessibility, tests, versioning and packaging. Asked because API mistakes ship to every consumer.

part ofDesign systems & UX foundationsoverview, primer and where to startread it →
on this pageshow

explore

questions

page 1 of 2

In a shared component library, how should an icon-only button component ensure every instance has an accessible name?

level: juniorimportance: must knowfreq 58%

answer

  1. make the wrong thing impossible
  2. no name, no button
  3. name the action, not the icon
  4. row context in the name
  5. Name, Role, Value at Level A

basics

~20 s

Make the label a required input the component cannot be created without, and feed it into the accessible name. It should name the action and its object, such as download invoice 1042, never the icon.

solid answer

~50 s

An icon-only button has no visible text, so nothing supplies its accessible name unless the author does — and WCAG 2.2 success criterion 4.1.2 Name, Role, Value (Level A) requires one. A library fixes this once for every consumer by making the label a **required input**: where the tooling can enforce it, the button cannot be created without one; where it cannot, the component fails loudly in development. The label becomes the accessible name, and can double as the hover hint. It should name the **action and its object** — `Download invoice 1042`, not `download icon` — because a list of twenty identical names in a table is useless. The library also refuses silent fallbacks such as the icon's file name. Where design allows, a visible text label is still better: visible text keeps the name maintained and helps people who never hear accessible names.

go deeper

for a junior

Recall that every icon-only button needs an accessible name naming its action, and that the library makes that name a required input.

for a middle

Explain how enforcement works at creation and in development, why fallbacks hide failures, and how a name distinguishes rows in a table.

for a senior

Show how you would find unnamed buttons across consuming apps, migrate them, and decide which icon-only actions should gain a visible label instead.

for a principal

Weigh strict enforcement that can break consumers' builds against softer warnings, and set the system rule that icon-only is an exception to justify.

## Why icon-only buttons are the classic gap Every interactive control needs an **accessible name** — the text assistive technology announces to identify it. A button with visible text usually gets its name from that text. An **icon-only button** has none, so unless its author supplies a name, a screen reader announces something like *button* and nothing more, and a voice-control user has nothing to say to activate it. This is not a nicety. Under WCAG 2.2, success criterion **4.1.2 Name, Role, Value** (Level A) requires that the name and role of every user interface component can be programmatically determined. A missing name on an icon button is one of the most common failures of it. ## Why the library is the right place to fix it In a small-business accounting product, the invoice table has three icon buttons per row — duplicate, download, archive — and the same icon buttons appear in bills, quotes and expense claims. If each product team must remember to name each instance, some will not. A library component that **cannot be used without a name** removes the decision from hundreds of call sites. | Approach | Where names come from | Typical outcome | |---|---|---| | Leave naming to consumers | each call site, if remembered | some buttons announce only *button* | | Optional label input | consumers who read the docs | better, still gaps | | Required label input | enforced at creation | every instance named | | Silent fallback to icon name | the icon's file name | named, but uselessly (*copy*, *arrow-down*) | ## How to make the label required 1. **Make it a required input.** Where the library's language or tooling can express required inputs, the button will not build without a label. 2. **Fail loudly in development** where it cannot: a clear warning naming the component and the fix, not a silent render. 3. **Feed the label into the accessible name** and, where the design wants it, into a hover or focus hint, so sighted and non-sighted users hear the same words. 4. **Refuse fallbacks.** No default name, no deriving it from the icon's file name; a wrong name is worse than an obvious gap because it passes a quick check. 5. **Apply the rule across the library.** Icon-only toggles, menu triggers and icon links carry the same requirement; one library-wide rule — *no interactive icon without a name* — beats fixing components one at a time. ## What a good name says The Authoring Practices naming guide asks for **brief, useful names** (Rule 5). For an icon button, that means: - **The action, not the picture.** *Duplicate invoice*, not *copy icon*. - **The object when there are many.** In a table, *Download invoice 1042* distinguishes rows; twenty buttons all called *Download* do not. - **No role words.** Assistive technology already announces *button*; *download button* says it twice. - **Consistency with any visible hint.** WCAG 2.2 success criterion **2.5.3 Label in Name** (Level A) requires that when a component has a visible text label, its accessible name contains that text, so a voice-control user can say what they see. - **Stable across states.** For a toggle such as *Mark as paid*, the Authoring Practices button pattern says the label must not change when the state changes; the library exposes the pressed state instead of swapping names. The library can help with the object part too: a row-action button can accept the row's identifying text and compose *Download invoice 1042* itself, so consumers pass data rather than hand-writing strings. ## When the right fix is a visible label The same naming guide's **Rule 2, Prefer Visible Text**, points out that names that exist only in code drift out of date when the design changes, and that visible labels help many people who never hear an accessible name. An icon that is not universally understood — *archive* versus *void* in accounting is a real ambiguity — is often better as an icon plus a word. The library should make that easy (a button with icon and text is the same component, not a new one) and treat icon-only as the exception it has to justify. ## The same rule on native mobile Native platforms have the same concept — every control exposes a label to the platform's screen reader and voice control — and the same failure. A cross-platform system states the rule once in the component spec (*icon-only buttons require a label naming the action*) and each platform's library enforces it in its own way.

  • A consumer passes the label 'Button' to satisfy the requirement. What can the library do?
    A required input guarantees presence, not quality. The library can warn in development on obviously useless values — the role word, the icon's own name, an empty or whitespace string — and its usage guidance should show good and bad names. Beyond that, review and manual testing catch the rest; no check can judge meaning.
  • Why is a silent fallback to the icon's name worse than no name at all?
    A missing name is an obvious defect that a quick automated check will flag. A fallback like 'arrow-down' produces a name, so the check passes, while the user still hears something meaningless. The failure moves from visible to hidden, which makes it last much longer.

saying these in an interview costs you the question

  • A screen reader can describe an icon by itself, so no name is needed.
  • The icon's file name is a reasonable default accessible name.
  • Every download button in a table can share the name 'Download'.
  • Adding the word 'button' to the name helps screen-reader users.
  • Naming is each product team's job, not the library's.
open as a page

In a component library, why should an element's visible text arrive as translatable inputs instead of being hardcoded inside the element?

level: juniorimportance: must knowfreq 45%

basics

~20 s

A library cannot know which languages its products ship in, so hardcoded text forces one language on every consumer. Elements should take complete, translatable messages from the app, which owns translation, and let every internal default string be overridden.

open as a page

In a shared component library, why should a component's styles reference semantic theme tokens instead of literal values such as a raw color code?

level: juniorimportance: must knowfreq 62%

basics

~20 s

A literal freezes one decision inside the component, so no theme, mode or consumer can change it. A semantic token names the role a value plays, such as selected surface, and lets the active theme supply the value.

open as a page

In a component library that follows semantic versioning, which version part should change for a new variant, a spacing bug fix, and a renamed property?

level: juniorimportance: must knowfreq 55%

basics

~10 s

A new variant is MINOR because it adds backward-compatible capability; a spacing fix back to the documented design is PATCH; a renamed property is MAJOR, because code still passing the old name stops working.

open as a page

In a shared component library, why do teams give a component one enum variant property instead of several boolean style flags?

level: middleimportance: must knowfreq 58%

basics

~20 s

Several boolean style flags let callers ask for combinations that make no sense, with the winner hidden in the implementation. One enum variant property makes the options mutually exclusive, exhaustively checkable and easy to extend; booleans stay for genuinely independent axes.

open as a page

In a component library, what is a compound component family, and why build an accordion that way rather than as one component fed an item array?

level: middleimportance: must knowfreq 48%

basics

~20 s

A compound component family is a root holding shared state plus named parts that read it implicitly. Consumers arrange the parts and write their contents, so new layouts need no new API; an item array turns every need into a field.

open as a page

In a design-system component library, what separates a headless component from a styled one, and when should a team choose headless?

level: middleimportance: must knowfreq 52%

basics

~20 s

A headless component supplies behaviour — state, keyboard handling, focus and accessibility semantics — and ships no styling; a styled component adds the system's look on top. Choose headless when a product's visuals differ beyond what theming can express.

open as a page

For a component library serving teams on three UI frameworks, how do thin wrappers over an agnostic core, custom elements and shared behaviour logic compare?

level: middleimportance: must knowfreq 50%

basics

~20 s

Thin wrappers put everything framework-free in a core and give each framework an idiomatic shell; custom elements ship one implementation any framework renders; shared behaviour logic writes interaction rules once while each framework renders its own markup.

open as a page

In a component library, what must the package do so a consuming app's bundler can drop unused components, and what goes wrong with a wrong side-effect declaration?

level: middleimportance: must knowfreq 55%

basics

~20 s

Ship a static import-and-export format with one module per component, keep modules free of import-time work, and declare which files have side effects. Declaring everything side-effect free drops imported style files; declaring nothing keeps every component.

open as a page

In a component library shared by many product teams, which test layers do you run, and what does each catch that the others miss?

level: middleimportance: must knowfreq 50%

basics

~20 s

Interaction tests catch broken behavior and keyboard contracts; visual diffs across variants and themes catch rendering regressions; automated accessibility scans catch rule-detectable defects; consumer-contract tests catch breaks in real usage; manual assistive-technology review covers the rest.

open as a page

In a component library shared by several product teams, which changes are breaking even when no property was removed or renamed, and why?

level: middleimportance: must knowfreq 50%

basics

~20 s

Changing a default, removing a documented styling hook or stable markup part, changing focus order or keyboard behavior, changing a role or accessible name, and changing when an event fires all break consumers without touching a property.

open as a page

In a design-system component library offering both primitives and prebuilt recipes, which should a product team reach for first, and why?

level: juniorimportance: should knowfreq 35%

basics

~20 s

Reach for the prebuilt recipe first: it encodes the approved layout, behaviour and edge cases for a common need and picks up fixes automatically. Drop to primitives only when no recipe fits, and compose them rather than restyling a recipe's internals.

open as a page

In a design system with web and native mobile apps, what do native apps share with the web component library, and what do they rebuild?

level: juniorimportance: should knowfreq 42%

basics

~20 s

Native apps share the design tokens, the component specs (anatomy, variants, states, behaviour, accessibility intent) and the naming, not the web code. Each platform rebuilds the components with its own UI toolkit, input model and accessibility services.

open as a page

In a component library built on a UI framework, why is that framework declared as a peer dependency rather than bundled as a regular dependency?

level: juniorimportance: should knowfreq 45%

basics

~20 s

An app must run a single copy of its UI framework; declaring it a peer makes the app supply that copy, avoiding duplicate instances that break shared state and double the download, while the range states which versions work.

open as a page

In a component library, why render each component in isolation in a component workshop instead of only reviewing it inside the running app?

level: juniorimportance: should knowfreq 50%

basics

~20 s

Isolation makes every state reachable on demand without the app's data, login or routes, lets teams build before pages exist, and exposes hidden dependencies. It cannot show real page layout or data, so it complements in-app review.

open as a page

In a component library's interaction tests, why should a test find controls by role and accessible name instead of internal class names or test IDs?

level: juniorimportance: should knowfreq 45%

basics

~10 s

Role and accessible name are what assistive-technology users and consuming teams rely on, so querying by them tests the public contract, fails when a control loses its name, and survives internal refactors.

open as a page

In a component library, why provide one shared live-region announcer instead of letting each component create its own live region?

level: middleimportance: should knowfreq 38%

basics

~10 s

Live regions created on the fly are often not announced, and many regions talk over each other. One announcer mounted up front queues, deduplicates and throttles status messages, so every component announces reliably.

open as a page

In a component library, what keyboard contract should a tabs component implement per the WAI-ARIA Authoring Practices, and when should activation be manual?

level: middleimportance: should knowfreq 45%

basics

~20 s

Tab enters the list on the active tab and leaves it for the panel; arrow keys move between tabs and wrap. Activation follows focus only when panels appear without noticeable latency; otherwise Space or Enter activates.

open as a page

In a shared component library, how should a stateful component let callers either own its state or leave it to the component?

level: middleimportance: should knowfreq 48%

basics

~20 s

Offer both modes through one convention: a value input makes the component controlled, a default-value input seeds internal state for uncontrolled use, and a change callback fires in either mode. The mode is fixed at first render.

open as a page

For a component library, what are the trade-offs between publishing one package for all components and publishing one package per component?

level: middleimportance: should knowfreq 40%

basics

~20 s

One package gives consumers a single coherent version and simple upgrades; per-component packages allow independent releases but let an app mix incompatible versions and duplicate shared internals. Many systems ship one package with per-component entry points.

open as a page

When a component library ships its styles, what are the trade-offs between runtime-injected styles, one prebuilt stylesheet, and per-component style files?

level: middleimportance: should knowfreq 35%

basics

~20 s

Runtime injection needs no consumer setup but costs runtime work and complicates server rendering; one prebuilt stylesheet is simplest but ships every component's styles; per-component style files ship only what is used but need build support.

open as a page

In a component workshop, how do you decide which examples a component needs, and why keep named examples rather than one playground with property controls?

level: middleimportance: should knowfreq 42%

basics

~10 s

Start from the component's specified variants and states, add extreme data and setup-dependent states, and skip redundant combinations. Named examples are reviewable, linkable and reusable; states reachable only through controls are rarely seen.

open as a page

In a component library, why should elements that display amounts and dates use locale-aware formatter hooks instead of formatting values themselves?

level: middleimportance: should knowfreq 38%

basics

~20 s

Formatting rules — separators, currency placement, date order, digits — differ by locale, and only the app knows the user's locale. Elements should take raw values and format them through a formatter the app supplies, so every element in a product agrees.

open as a page

When a component library's elements render in a right-to-left language, what should mirror, and which icons should not flip?

level: middleimportance: should knowfreq 40%

basics

~20 s

Everything that expresses reading direction mirrors: element order, start and end alignment, back and next arrows, chevrons, steppers and progress. Icons of real objects, clocks, logos and usually media controls stay unflipped, and numbers keep their left-to-right order.

open as a page

In a component library, how should elements handle text that grows after translation, and when is truncating it acceptable?

level: middleimportance: should knowfreq 45%

basics

~20 s

Elements should let text grow or wrap — no fixed widths or heights on text-bearing parts — because translations are often longer. Truncate only non-critical text in constrained spots, and keep the full text reachable; never truncate actions, amounts, dates or errors.

open as a page

In a component library where every component passes automated accessibility scans, why can apps built from it still fail WCAG, and who must catch what?

level: middleimportance: should knowfreq 40%

basics

~20 s

Scans check rule-detectable defects in isolated components; they cannot judge meaning, keyboard flow, or how components combine on a page. The library guarantees each part's semantics; the app owns label wording, page structure, focus order and overrides.

open as a page

In a component library, what is a component-scoped override token, and when is exposing one better than changing a semantic token?

level: middleimportance: should knowfreq 48%

basics

~20 s

A component-scoped override token is a named hook on one component whose default references a semantic token. Setting it changes only that component, so it beats editing the semantic token when the rest of the product must stay as it is.

open as a page

In a component library, how should a component map its visual variants to theme tokens, and why keep that mapping in one declared table?

level: middleimportance: should knowfreq 40%

basics

~20 s

Each variant should resolve, per anatomy part and state, to a semantic token name, never to a value. One declared table makes every combination visible and checkable, keeps values in the theme, and turns a new variant into one reviewed row.

open as a page

In a component library preparing a breaking major release, how should the team use semantic-versioning pre-releases to let consuming teams trial it?

level: middleimportance: should knowfreq 30%

basics

~10 s

Publish versions such as 5.0.0-beta.1 that consumers must opt into explicitly; they sort below 5.0.0, promise no stability, may change between betas, and let pilot apps prove the migration guide first.

open as a page

In an accounting product, a library date picker opened inside a record-payment dialog lets Tab escape to the page behind, and closing it loses focus. How should the library fix this?

level: seniorimportance: should knowfreq 42%

basics

~20 s

Replace per-component traps with one shared focus-layer stack: only the top layer contains focus, everything beneath is inert, Escape closes one layer, and closing returns focus to the opener, or a logical fallback if it is gone.

open as a page

showing 1–30 of 43