diff --git a/packages/render-html/src/__tests__/component.render-html-a11y.test.tsx b/packages/render-html/src/__tests__/component.render-html-a11y.test.tsx
index 9f98032b9..2a77e6979 100644
--- a/packages/render-html/src/__tests__/component.render-html-a11y.test.tsx
+++ b/packages/render-html/src/__tests__/component.render-html-a11y.test.tsx
@@ -1,7 +1,13 @@
+import {
+ defaultHTMLElementModels,
+ HTMLContentModel,
+ TBlock
+} from '@native-html/transient-render-engine';
import { render } from '@testing-library/react-native';
import React from 'react';
import AccessibilityEngine from 'react-native-accessibility-engine';
import RenderHTML from '../RenderHTML';
+import { CustomRendererProps } from '../shared-types';
describe('RenderHTML a11y', () => {
describe('regarding anchors', () => {
@@ -82,4 +88,62 @@ describe('RenderHTML a11y', () => {
expect(() => AccessibilityEngine.check(element)).not.toThrow();
});
});
+ describe('regarding pressable custom renderers', () => {
+ it('should add a button role if onPress is defined for custom renderers with a block content model', () => {
+ const element = (
+ '
+ }}
+ customHTMLElementModels={{
+ ...defaultHTMLElementModels,
+ button: defaultHTMLElementModels.button.extend({
+ contentModel: HTMLContentModel.block
+ })
+ }}
+ renderers={{
+ button: ({
+ TDefaultRenderer,
+ ...props
+ }: CustomRendererProps) => (
+ {}} {...props} />
+ )
+ }}
+ debug={false}
+ contentWidth={200}
+ />
+ );
+ const { getByA11yRole } = render(element);
+ const buttonProps = getByA11yRole('button').props;
+ expect(buttonProps.accessibilityRole).toBe('button');
+ expect(() => AccessibilityEngine.check(element)).not.toThrow();
+ });
+ it('should add a button role if onPress is defined for custom renderers with a textual content model', () => {
+ const element = (
+ '
+ }}
+ customHTMLElementModels={{
+ ...defaultHTMLElementModels,
+ customlink: defaultHTMLElementModels.span
+ }}
+ renderers={{
+ customlink: ({
+ TDefaultRenderer,
+ ...props
+ }: CustomRendererProps) => (
+ {}} {...props} />
+ )
+ }}
+ debug={false}
+ contentWidth={200}
+ />
+ );
+ const { getByA11yRole } = render(element);
+ const buttonProps = getByA11yRole('link').props;
+ expect(buttonProps.accessibilityRole).toBe('link');
+ expect(() => AccessibilityEngine.check(element)).not.toThrow();
+ });
+ });
});
diff --git a/packages/render-html/src/helpers/getNativePropsForTNode.ts b/packages/render-html/src/helpers/getNativePropsForTNode.ts
index e99370b7e..c39008034 100644
--- a/packages/render-html/src/helpers/getNativePropsForTNode.ts
+++ b/packages/render-html/src/helpers/getNativePropsForTNode.ts
@@ -1,4 +1,5 @@
import { TBlock, TPhrasing, TText } from '@native-html/transient-render-engine';
+import { TextProps, ViewProps } from 'react-native';
import { TDefaultRendererProps } from '../shared-types';
/**
@@ -8,10 +9,13 @@ import { TDefaultRendererProps } from '../shared-types';
*/
export default function getNativePropsForTNode(
props: TDefaultRendererProps
-) {
+): TextProps | ViewProps {
const { tnode, style, type, nativeProps, onPress } = props;
const switchProp = type === 'block' ? props.viewProps : props.textProps;
return {
+ ...(typeof onPress === 'function'
+ ? ({ accessibilityRole: type === 'block' ? 'button' : 'link' } as const)
+ : null),
...tnode.getReactNativeProps()?.[type === 'block' ? 'view' : 'text'],
...nativeProps,
...switchProp,