From 36f5449508be8feada13725bafa0a176b4b47031 Mon Sep 17 00:00:00 2001 From: Tamas Kovacs Date: Wed, 17 Sep 2025 16:54:54 +0200 Subject: [PATCH] feat(ui-alerts): expand Alert's liveRegion to accept direct DOM element INSTUI-4454 --- .../src/Alert/__tests__/Alert.test.tsx | 18 ++++++++++++++++++ packages/ui-alerts/src/Alert/index.tsx | 10 +++++----- packages/ui-alerts/src/Alert/props.ts | 6 +++--- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/packages/ui-alerts/src/Alert/__tests__/Alert.test.tsx b/packages/ui-alerts/src/Alert/__tests__/Alert.test.tsx index a5874f6499..95129fab3e 100644 --- a/packages/ui-alerts/src/Alert/__tests__/Alert.test.tsx +++ b/packages/ui-alerts/src/Alert/__tests__/Alert.test.tsx @@ -148,6 +148,24 @@ describe('', () => { expect(liveRegion).toHaveAttribute('aria-live', 'polite') }) + it('should accept a direct DOM element as liveRegion', async () => { + const liveRegion = document.getElementById('_alertLiveRegion')! + render( + + Success: Sample alert text. + + ) + + expect(liveRegion).toHaveTextContent('Success: Sample alert text.') + expect(liveRegion).toHaveAttribute('aria-atomic', 'true') + }) + it('should render an icon when provided as the `renderIcon` prop', () => { const { container } = render(} />) const icon = container.querySelector('svg[class$="-svgIcon"]') diff --git a/packages/ui-alerts/src/Alert/index.tsx b/packages/ui-alerts/src/Alert/index.tsx index bd796545e3..5faa726313 100644 --- a/packages/ui-alerts/src/Alert/index.tsx +++ b/packages/ui-alerts/src/Alert/index.tsx @@ -136,15 +136,15 @@ class Alert extends Component { } // duck type for a dom node - isDOMNode(n: Element | null) { + isDOMNode(n: Element | null | undefined) { return n && typeof n === 'object' && n.nodeType === 1 } getLiveRegion() { - let lr = null - if (typeof this.props.liveRegion === 'function') { - lr = this.props.liveRegion() - } + const lr = + typeof this.props.liveRegion === 'function' + ? this.props.liveRegion() + : this.props.liveRegion return this.isDOMNode(lr) ? lr : null } diff --git a/packages/ui-alerts/src/Alert/props.ts b/packages/ui-alerts/src/Alert/props.ts index 2c3b759671..06c9b412ff 100644 --- a/packages/ui-alerts/src/Alert/props.ts +++ b/packages/ui-alerts/src/Alert/props.ts @@ -51,9 +51,9 @@ type AlertOwnProps = { */ variantScreenReaderLabel?: string /** - * Function that returns the DIV where screenreader alerts will be placed. + * A DOM element or function that returns an element where screenreader alerts will be placed. */ - liveRegion?: () => Element + liveRegion?: Element | null | (() => Element | null | undefined) /** * Choose the politeness level of screenreader alerts, sets the value of * `aria-live`. @@ -132,7 +132,7 @@ const propTypes: PropValidators = { children: PropTypes.node, variant: PropTypes.oneOf(['info', 'success', 'warning', 'error']), margin: PropTypes.string, - liveRegion: PropTypes.func, + liveRegion: PropTypes.oneOfType([PropTypes.func, PropTypes.element]), liveRegionPoliteness: PropTypes.oneOf(['polite', 'assertive']), isLiveRegionAtomic: PropTypes.bool, screenReaderOnly: PropTypes.bool,