Polymorphic Components
Reuse one visual component while it still renders the element the browser needs.
What it adds
A mechanism for letting a shared component keep its appearance while the caller chooses the underlying element it renders as.
What your agent is told to do
5
What your agent is told to do
5-
1
Find the components that already fake their element — a button styled as a link, a card wrapped in an anchor, a heading rendered at the wrong level to get the right size — and make the element an explicit choice rather than a workaround.
-
2
Let the caller pass through the native attributes that belong to the chosen element, and merge them with the component's own rather than letting either side silently win. Class names, event handlers, and identifiers all need a defined merge order.
-
3
Constrain the choice. A component that can render as anything will eventually render as something meaningless; allow the small set of elements that make sense for that component and reject the rest.
-
4
Keep the reference to the real underlying node reachable by the caller, so focus management, measurement, and scroll-into-view still work once the element changes.
-
5
Do not style on the element name. Appearance belongs to the variant chosen through props — the rules named in Component Prop Guardrails — and the element belongs to semantics; if the two are coupled, changing one silently changes the other.
Edge cases it handles
7
Edge cases it handles
7- Native attributes passed by the caller must merge rather than clobber. Two class lists concatenate, two click handlers both run in a defined order, and an identifier supplied by the caller wins over a generated one.
- Anything that navigates must be an anchor with a destination, and anything that acts must be a button with a type. A clickable division with a click handler is not keyboard-operable and must be refused, not worked around with a tab index.
- The reference to the underlying node must survive the element switch, and the shapes of the events the component emits must match the element actually rendered, so a form event is not typed or documented as a pointer event.
- Styling must not depend on which element was chosen. A rule that only matches when the component renders as an anchor breaks the moment a caller renders it as a button, and the breakage shows up in an unrelated screen.
- A disabled state has to be expressed differently on an anchor than on a button — anchors cannot be disabled — so the component must either refuse the combination or render an inert non-navigating state.
- Nesting must be checked: an interactive element inside another interactive element is invalid and produces unpredictable activation, so a card rendered as an anchor cannot also contain buttons.
- Any accessible name, role, or state the component supplies must be recomputed for the chosen element, not hardcoded for the default one.
Definition of done
8
Definition of done
8- Each polymorphic component accepts only a documented set of elements and rejects the others.
- Caller-supplied attributes, class names, and handlers merge with the component's own under a stated precedence.
- The underlying element node remains reachable by callers for focus and measurement.
- No visual rule in the codebase keys off which element a polymorphic component rendered as.
- Navigating instances render anchors with destinations and acting instances render buttons with an explicit type.
- Disabled and inert states are correct for every permitted element, not only the default.
- The feature matches the existing design system.
- No existing functionality is broken.
Related features
Screen Reader Only Utility
Screen Reader Only Utility
One tested way to add text for assistive technology without it appearing on screen.
What it does
A single visually hidden utility used for labels, instructions, and context that assistive technology needs and sighted users do not.
How it works
- 1 Find every place the app currently hides text from sight — off-screen positioning, zero dimensions, transparent colour, tiny font sizes, aria-label strings duplicating nearby copy — and consolidate them onto one utility.
- 2 Build it by clipping the element to nothing while keeping it rendered and in the accessibility tree: it must occupy no visual space and contribute nothing to layout, yet still be read in document order.
- 3 Provide a second variant that becomes visible when it receives focus, and use it for skip links and any other hidden content that is itself focusable.
Copy the prompt
No account needed
Add this feature to my app:
https://addthisfeature.com/x/screen-reader-only-utility
Avatar Group
Avatar Group
Show who is involved in a compact space without a pile of broken images.
What it does
A stacked set of member avatars with deterministic ordering, an overflow count, and access to the full list.
How it works
- 1 Find the places that show several people at once — assignees, collaborators, workspace members, comment participants — and render them through one grouped component.
- 2 Order the stack deterministically by a stable rule such as role then name, so the same group renders in the same order on every load and every device.
- 3 Cap the number shown and collapse the remainder into a single count that is announced meaningfully, not as a bare number sitting after a row of pictures.
Copy the prompt
No account needed
Add this feature to my app:
https://addthisfeature.com/x/avatar-group
Progress Indicator System
Progress Indicator System
Tell people how far along the work is, in the same way every time.
What it does
A consistent set of bars, rings, step trackers, and accompanying text for work that takes measurable time.
How it works
- 1 Identify every operation in the app that takes long enough to need feedback — uploads, imports, exports, batch actions, multi-step flows — and decide for each whether its progress is genuinely measurable.
- 2 Use a determinate form only when a real proportion is known. Where the total is unknown, use an indeterminate form and say what is happening in words rather than inventing a percentage.
- 3 Pair every indicator with text that names the operation and its current position, so the information survives for someone who cannot see the graphic.
Copy the prompt
No account needed
Add this feature to my app:
https://addthisfeature.com/x/progress-indicator-system
How it works
-
1
Copy the link
Grab the Markdown instruction URL for this feature.
-
2
Give it to your AI
Paste it into Claude Code, Cursor, v0, Lovable — whatever you build with.
-
3
It inspects, then implements
Your agent reads your existing app first, then adds the feature to fit it.
Works with your stack
These instructions are written to adapt. They tell the agent to detect your framework, match your existing design system, and reuse what you already have — rather than assuming a particular stack.
Need it tighter than that? Customize the feature and tell it exactly what you're running.