diff --git a/packages/lucide-react/src/Icon.ts b/packages/lucide-react/src/Icon.ts index c623c0e3e..5f243b129 100644 --- a/packages/lucide-react/src/Icon.ts +++ b/packages/lucide-react/src/Icon.ts @@ -1,7 +1,7 @@ import { createElement, forwardRef } from 'react'; import defaultAttributes from './defaultAttributes'; import { IconNode, LucideProps } from './types'; -import { mergeClasses } from '@lucide/shared'; +import { mergeClasses, hasA11yProp } from '@lucide/shared'; interface IconComponentProps extends LucideProps { iconNode: IconNode; @@ -46,6 +46,7 @@ const Icon = forwardRef( stroke: color, strokeWidth: absoluteStrokeWidth ? (Number(strokeWidth) * 24) / Number(size) : strokeWidth, className: mergeClasses('lucide', className), + ...(!children && !hasA11yProp(rest) && { 'aria-hidden': 'true' }), ...rest, }, [ diff --git a/packages/lucide-react/tests/Icon.spec.tsx b/packages/lucide-react/tests/Icon.spec.tsx index 906f0c311..22f0837b4 100644 --- a/packages/lucide-react/tests/Icon.spec.tsx +++ b/packages/lucide-react/tests/Icon.spec.tsx @@ -31,3 +31,63 @@ describe('Using Icon Component', () => { expect(container.firstChild).toMatchSnapshot(); }); }); + +describe('Icon Component Accessibility', () => { + it('should not have aria-hidden prop when aria prop is present', async () => { + const { container } = render( + , + ); + + expect(container.firstChild).not.toHaveAttribute('aria-hidden'); + }); + + it('should not have aria-hidden prop when title prop is present', async () => { + const { container } = render( + , + ); + + expect(container.firstChild).not.toHaveAttribute('aria-hidden'); + }); + + it('should not have aria-hidden prop when there are children that could be a element', async () => { + const { container } = render( + <Icon + iconNode={airVent} + size={48} + stroke="red" + absoluteStrokeWidth + > + <title>Some title + , + ); + + expect(container.firstChild).not.toHaveAttribute('aria-hidden'); + }); + + it('should never override aria-hidden prop', async () => { + const { container } = render( + , + ); + + expect(container.firstChild).toHaveAttribute('aria-hidden', 'false'); + }); +}); diff --git a/packages/lucide-react/tests/__snapshots__/Icon.spec.tsx.snap b/packages/lucide-react/tests/__snapshots__/Icon.spec.tsx.snap index 635ca428a..956aa8168 100644 --- a/packages/lucide-react/tests/__snapshots__/Icon.spec.tsx.snap +++ b/packages/lucide-react/tests/__snapshots__/Icon.spec.tsx.snap @@ -2,6 +2,7 @@ exports[`Using Icon Component > should render icon and match snapshot 1`] = `