Skip to content

Commit

Permalink
feat: custom matchers support new renderLink option for increased cus…
Browse files Browse the repository at this point in the history
…tomization
  • Loading branch information
joshswan committed Oct 7, 2023
1 parent fe8f0d9 commit af9cae1
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 2 deletions.
8 changes: 6 additions & 2 deletions src/Autolink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ export const Autolink = React.memo(
const uid = useRef(Math.floor(Math.random() * 0x10000000000).toString(16));
const [generateToken, tokenRegexp] = makeTokenGenerator(uid.current);

const matches: { [token: string]: Match } = {};
const matches: { [token: string]: Match | CustomMatch } = {};
let linkedText: string;

try {
Expand Down Expand Up @@ -242,7 +242,11 @@ export const Autolink = React.memo(

// Check if rendering link or text node
if (match?.getType()) {
return (renderLinkProp || renderLink)(match.getAnchorText(), match, index);
return ((match as any).getRenderFn?.() || renderLinkProp || renderLink)(
match.getAnchorText(),
match,
index,
);
}

return renderText ? (
Expand Down
7 changes: 7 additions & 0 deletions src/CustomMatch.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Match, MatchConfig } from 'autolinker/dist/es2015';
import React from 'react';
import { StyleProp, TextStyle } from 'react-native';

// The variadic arguments of a regex replacer function, wrapped in an array.
Expand All @@ -20,6 +21,8 @@ export interface CustomMatcher {
getLinkText?: (replacerArgs: ReplacerArgs) => string;
/* Custom function for extracting link URL using regex replacer args */
getLinkUrl?: (replacerArgs: ReplacerArgs) => string;
/* Custom function for rendering link - remember to attach press handlers! */
renderLink?: (text: string, match: CustomMatch, index: number) => React.ReactNode;
}

export interface CustomMatchConfig extends MatchConfig {
Expand Down Expand Up @@ -57,4 +60,8 @@ export class CustomMatch extends Match {
getReplacerArgs(): ReplacerArgs {
return this.replacerArgs;
}

getRenderFn(): CustomMatcher['renderLink'] {
return this.matcher.renderLink;
}
}
21 changes: 21 additions & 0 deletions src/__tests__/Autolink.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -342,5 +342,26 @@ describe('<Autolink />', () => {
expect(onPress.mock.calls[0][0]).toBe('__LINK_URL__');
expect(onPress.mock.calls[0][1]).toBeInstanceOf(CustomMatch);
});

test('uses renderLink when rendering link', () => {
const onPress = jest.fn();
const renderLink = jest
.fn()
.mockImplementation((text: string) => <Text onPress={onPress}>{text}</Text>);
const tree = renderer.create(
<Autolink
text="+14085550123"
onPress={onPress}
matchers={[{ ...IntlPhoneMatcher, renderLink }]}
/>,
);
expect(renderLink.mock.calls.length).toBe(1);
expect(renderLink.mock.calls[0][0]).toBe('+14085550123');
expect(renderLink.mock.calls[0][1]).toBeInstanceOf(CustomMatch);
expect(renderLink.mock.calls[0][2]).toBe(0);
expect(tree).toMatchSnapshot();
tree.root.findAllByType(Text)[1].props.onPress();
expect(onPress.mock.calls.length).toBe(1);
});
});
});
10 changes: 10 additions & 0 deletions src/__tests__/__snapshots__/Autolink.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,16 @@ exports[`<Autolink /> matchers uses getLinkText when rendering link 1`] = `
</Text>
`;

exports[`<Autolink /> matchers uses renderLink when rendering link 1`] = `
<Text>
<Text
onPress={[MockFunction]}
>
+14085550123
</Text>
</Text>
`;

exports[`<Autolink /> matchers wraps text based on supplied custom matchers 1`] = `
<Text>
<Text
Expand Down

0 comments on commit af9cae1

Please sign in to comment.