Headless Component Wrapper
Put the app's own styling and API in front of behaviour-only primitives.
What it adds
A wrapping layer that gives unstyled third-party primitives the app's visual language and its own stable interface.
What your agent is told to do
5
What your agent is told to do
5-
1
Identify the behaviour-heavy primitives already in use — menus, dialogs, comboboxes, date pickers, tooltips — and give each one wrapper that the rest of the app imports instead of the primitive directly.
-
2
Define the wrapper's interface from the app's own vocabulary of sizes, tones, and states, and translate to whatever the primitive expects inside. The call site should not need to know which primitive is underneath.
-
3
Preserve every accessibility behaviour the primitive provides — focus trapping, roving focus, labelling, keyboard handling, dismissal — and verify it survives the wrapping rather than assuming it does.
-
4
Keep the wrapper thin enough to be replaced. Confine the primitive's concepts to that one file so swapping it later is a rewrite of the wrapper, not an audit of every screen.
-
5
Do not let some screens import the wrapper and others reach past it to the primitive. A bypass route means the styling, defaults, and accessibility fixes live in two places, and the second one drifts.
Edge cases it handles
7
Edge cases it handles
7- Vendor props must not leak through the wrapper's interface. Spreading unknown props straight onto the primitive means every call site can quietly depend on vendor internals, and the wrapper stops being replaceable the moment one does.
- The primitive's accessibility work is the reason it was chosen, and it is easy to undo by overriding a role, replacing an internal element, stripping a generated identifier, or intercepting a keyboard handler. Every wrapper needs its keyboard and screen reader behaviour checked after wrapping.
- There must be a defined exit path from the vendor. If the primitive is abandoned or diverges, the work should be confined to the wrapper, which means no vendor type, prop name, or concept may appear in application code.
- A parallel component that bypasses the wrapper defeats the whole arrangement. Remove the direct import route, or make it obvious in review, so a second unstyled dialog does not appear next to the styled one.
- The primitive's own defaults may not match the app's conventions — dismissal on outside click, initial focus, portal target, animation timing — so the wrapper must set them explicitly rather than inheriting whatever the vendor decided.
- Version upgrades of the primitive can change behaviour without changing the wrapper's interface, so the wrapper's behaviour needs verifying on upgrade rather than trusting the type check to pass.
- Where a wrapped primitive exposes several coordinated parts, its composition should follow the same conventions as Compound Component Pattern rather than inventing a second way to compose the same shapes.
Definition of done
8
Definition of done
8- Every behaviour-only primitive in use is reached through an application wrapper.
- Application code contains no vendor prop names, types, or concepts.
- Keyboard navigation, focus management, labelling, and dismissal behave identically before and after wrapping.
- The wrapper sets the app's own defaults rather than inheriting the primitive's.
- There is no route by which a screen can use the primitive directly.
- Replacing a primitive requires changing only its wrapper.
- The feature matches the existing design system.
- No existing functionality is broken.
Related features
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
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
Landmark Shell
Landmark Shell
Give every page the same navigable regions so people can jump straight to the content.
What it does
A reusable application shell providing labelled banner, navigation, main, complementary, and contentinfo regions on every route.
How it works
- 1 Find the layouts the app already renders and identify what each region actually is — the top bar, the primary navigation, the page body, any inspector or sidebar, the footer — then express them as landmarks once in the shell rather than per page.
- 2 Give the shell exactly one main region per rendered page, and make it the target of a skip link that is the first focusable thing in the document.
- 3 Label every landmark that appears more than once so they can be told apart — primary navigation, breadcrumb, pagination — using a short distinct name rather than the word navigation repeated.
Copy the prompt
No account needed
Add this feature to my app:
https://addthisfeature.com/x/landmark-shell
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.