Skip to content

Commit

Permalink
Implement className as function for compatibility with react-router.
Browse files Browse the repository at this point in the history
  • Loading branch information
jhsware committed Oct 22, 2022
1 parent 8e89b76 commit ab86a0a
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 6 deletions.
74 changes: 74 additions & 0 deletions packages/inferno-router/__tests__/NavLink.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,80 @@ describe('NavLink', () => {
});
});

it("applies its className when provided as a function", () => {
render(
<MemoryRouter initialEntries={["/pizza"]}>
<NavLink
to="/pizza"
className={(isActive: boolean) => isActive ? "active-pizza" : "chill-pizza"}
>
Pizza!
</NavLink>
</MemoryRouter >,
node
);

const a = node.querySelector("a");
expect(a.className).toContain("active-pizza");
});

it("applies its style when provided as a function", () => {
const defaultStyle = { color: "black" };
const activeStyle = { color: "red" };

render(
<MemoryRouter initialEntries={["/pizza"]}>
<NavLink
to="/pizza"
style={isActive => (isActive ? activeStyle : defaultStyle)}
>
Pizza!
</NavLink>
</MemoryRouter>,
node
);

const a = node.querySelector("a");
expect(a.style.color).toBe(activeStyle.color);
});

it("applies its className when provided as a function", () => {
render(
<MemoryRouter initialEntries={["/pizza"]}>
<NavLink
to="/salad"
className={isActive => (isActive ? "active-salad" : "chill-salad")}
>
Salad?
</NavLink>
</MemoryRouter>,
node
);

const a = node.querySelector("a");
expect(a.className).toContain("chill-salad");
});

it("applies its style when provided as a function", () => {
const defaultStyle = { color: "black" };
const activeStyle = { color: "red" };

render(
<MemoryRouter initialEntries={["/pizza"]}>
<NavLink
to="/salad"
style={isActive => (isActive ? activeStyle : defaultStyle)}
>
Salad?
</NavLink>
</MemoryRouter>,
node
);

const a = node.querySelector("a");
expect(a.style.color).toBe(defaultStyle.color);
});

describe('exact', () => {
it('does not do exact matching by default', () => {
render(
Expand Down
21 changes: 15 additions & 6 deletions packages/inferno-router/src/NavLink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ function filter(i) {
return i;
}

interface NavLinkProps extends ILinkProps {
interface NavLinkProps extends Omit<ILinkProps, 'className'> {
to: string | Location;
exact?: boolean;
strict?: boolean;
location?: any;
activeClassName?: string;
className?: string | ((isActive: boolean) => string);
activeStyle?: any;
style?: any;
style?: object | ((isActive: boolean) => string);
isActive?: (match, location) => boolean;
ariaCurrent?: string;
}
Expand All @@ -32,22 +33,30 @@ export function NavLink({
onClick,
location: linkLocation,
activeClassName = 'active',
className,
className: classNameProp,
activeStyle,
style,
style: styleProp,
isActive: getIsActive,
ariaCurrent = 'true',
...rest
}: NavLinkProps & Inferno.LinkHTMLAttributes<HTMLLinkElement>): any {
}: NavLinkProps & Omit<Inferno.LinkHTMLAttributes<HTMLLinkElement>, 'className' | 'style'>): any {
function linkComponent({ location, match }): VNode {
const isActive = Boolean(getIsActive ? getIsActive(match, location) : match);

let className = typeof classNameProp === "function"
? classNameProp(isActive)
: classNameProp;

let style = typeof styleProp === "function"
? styleProp(isActive)
: styleProp;

return createComponentVNode(
VNodeFlags.ComponentFunction,
Link,
combineFrom(
{
'aria-current': isActive && ariaCurrent,
'aria-current': (isActive && ariaCurrent) || null,
className: isActive ? [className, activeClassName].filter(filter).join(' ') : className,
onClick,
style: isActive ? combineFrom(style, activeStyle) : style,
Expand Down

0 comments on commit ab86a0a

Please sign in to comment.