expose TRouter generic in custom link wrappers?
#7061
Replies: 2 comments
|
For your React Aria case: import { createLink, type LinkComponent } from '@tanstack/react-router'
import { Link as AriaLink } from 'react-aria-components'
const BaseLinkInner = React.forwardRef<HTMLAnchorElement, React.ComponentPropsWithoutRef<typeof AriaLink> & { disabled?: boolean }>(
(props, ref) => <AriaLink {...props} ref={ref} isDisabled={props.disabled} />
)
export const BaseLink: LinkComponent<typeof BaseLinkInner> = createLink(BaseLinkInner)On For Storybook/testing, wrapping stories in a One friction point to watch with React Aria: TSR's preload-on-intent behavior works through |
|
My bias here would be:
For the reusable case, A nice compromise is to keep the styling/accessibility primitive router-agnostic, then create the typed router binding in the app layer: export const AppLink = createLink(BaseLinkInner)That way:
So I probably wouldn’t ask for exposing |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Background
We're building a design system on top of TanStack Router. Our
BaseLinkcomponent wrapsRouterLinkwith ReactAria's
Linkfor accessibility (focus management, keyboardnavigation,
aria-disabled, etc.).We deliberately avoided
createLink()because it introduces extra component nesting (our component already hasmultiple internal layers), and we noticed that
createLink()internally uses_asChildanyway — so we use itdirectly:
A styled consumer wraps it:
Question 1 — Should
TRouterbe exposed?TanStack Router's own
Linkcomponent exposesTRouterwith a default:Our current implementation hardcodes
RegisteredRouterinValidateLinkOptions<RegisteredRouter, TOptions>.The proposed change would mirror TanStack's own pattern:
Our assumption: Exposing
TRouterlets consumers pass a non-globally-registered router, which is useful for:The question: Is this the recommended pattern for application-level custom link components, or is hardcoding
RegisteredRouteracceptable/preferred?Question 2 — Is
_asChilda stable/intentional public API?We rely on the
_asChildprop to swap the rendered element:We noticed this is how
createLink()works internally, but_asChilddoes not appear in the public documentation.Our concern:
extra nesting that
createLink()introduces?We added a comment in our code acknowledging this risk:
Is this a safe long-term approach, or should we use
createLink()despite the nesting overhead?Versions
@tanstack/react-router1.16.xreact-aria-componentsAll reactions