From f74d0e51f8e5647e64040e9c68953c4da37d69ca Mon Sep 17 00:00:00 2001 From: Fondryext <160865254+Fondryext@users.noreply.github.com> Date: Wed, 18 Feb 2026 14:26:09 -0500 Subject: [PATCH 1/4] feat: allow users to turn analytics on and off (v2.1.0) (#632) * feat: allow users to turn analytics on and off (v2.1.0) This PR adds a new property to the SearchAnalyticsConfig, which can be used to start with analytics enabled or disabled by default. Three new methods are added to the analytics object- two to turn analytics on/off, and one to get the current enabled status. J=WAT-5404 TEST=auto, manual Ran test site locally with debugging and buttons to turn analytics on and off, saw expected behavior. * Update various names to be in-line with pages code * Automated update to repo's documentation from github action * Add enableYextAnalytics function to window * drop unneeded parens --------- Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> --- docs/search-ui-react.searchanalyticsconfig.md | 19 +++++++++++ ...eact.searchanalyticsconfig.requireoptin.md | 13 ++++++++ ...ticseventservice.isyextanalyticsenabled.md | 17 ++++++++++ ...ch-ui-react.searchanalyticseventservice.md | 33 +++++++++++++++++++ ...react.searchanalyticseventservice.optin.md | 17 ++++++++++ ...eact.searchanalyticseventservice.optout.md | 17 ++++++++++ etc/search-ui-react.api.md | 6 +++- src/components/AnalyticsProvider.tsx | 30 ++++++++++++++--- src/models/SearchAnalyticsEventService.ts | 8 ++++- src/models/SearchAnalyticsEventServiceImpl.ts | 18 ++++++++++ test-site/package-lock.json | 2 +- test-site/src/config.ts | 2 +- tests/components/SearchBar.test.tsx | 7 ++-- 13 files changed, 175 insertions(+), 14 deletions(-) create mode 100644 docs/search-ui-react.searchanalyticsconfig.requireoptin.md create mode 100644 docs/search-ui-react.searchanalyticseventservice.isyextanalyticsenabled.md create mode 100644 docs/search-ui-react.searchanalyticseventservice.optin.md create mode 100644 docs/search-ui-react.searchanalyticseventservice.optout.md diff --git a/docs/search-ui-react.searchanalyticsconfig.md b/docs/search-ui-react.searchanalyticsconfig.md index 7a29492df..2b7d09b50 100644 --- a/docs/search-ui-react.searchanalyticsconfig.md +++ b/docs/search-ui-react.searchanalyticsconfig.md @@ -91,6 +91,25 @@ Environment _(Optional)_ The Yext environment to send requests to. Defaults to 'PRODUCTION'. + + + +[requireOptIn?](./search-ui-react.searchanalyticsconfig.requireoptin.md) + + + + + + + +boolean + + + + +_(Optional)_ Whether a user must consent to analytics tracking before events are fired. Defaults to false. + + diff --git a/docs/search-ui-react.searchanalyticsconfig.requireoptin.md b/docs/search-ui-react.searchanalyticsconfig.requireoptin.md new file mode 100644 index 000000000..d4d1473c8 --- /dev/null +++ b/docs/search-ui-react.searchanalyticsconfig.requireoptin.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [@yext/search-ui-react](./search-ui-react.md) > [SearchAnalyticsConfig](./search-ui-react.searchanalyticsconfig.md) > [requireOptIn](./search-ui-react.searchanalyticsconfig.requireoptin.md) + +## SearchAnalyticsConfig.requireOptIn property + +Whether a user must consent to analytics tracking before events are fired. Defaults to false. + +**Signature:** + +```typescript +requireOptIn?: boolean; +``` diff --git a/docs/search-ui-react.searchanalyticseventservice.isyextanalyticsenabled.md b/docs/search-ui-react.searchanalyticseventservice.isyextanalyticsenabled.md new file mode 100644 index 000000000..0f2b71545 --- /dev/null +++ b/docs/search-ui-react.searchanalyticseventservice.isyextanalyticsenabled.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [@yext/search-ui-react](./search-ui-react.md) > [SearchAnalyticsEventService](./search-ui-react.searchanalyticseventservice.md) > [isYextAnalyticsEnabled](./search-ui-react.searchanalyticseventservice.isyextanalyticsenabled.md) + +## SearchAnalyticsEventService.isYextAnalyticsEnabled() method + +Returns whether analytics reporting is currently enabled + +**Signature:** + +```typescript +isYextAnalyticsEnabled(): boolean; +``` +**Returns:** + +boolean + diff --git a/docs/search-ui-react.searchanalyticseventservice.md b/docs/search-ui-react.searchanalyticseventservice.md index 477fce642..47de37fd3 100644 --- a/docs/search-ui-react.searchanalyticseventservice.md +++ b/docs/search-ui-react.searchanalyticseventservice.md @@ -27,6 +27,39 @@ Description +[isYextAnalyticsEnabled()](./search-ui-react.searchanalyticseventservice.isyextanalyticsenabled.md) + + + + +Returns whether analytics reporting is currently enabled + + + + + +[optIn()](./search-ui-react.searchanalyticseventservice.optin.md) + + + + +Enables analytics reporting + + + + + +[optOut()](./search-ui-react.searchanalyticseventservice.optout.md) + + + + +Disables analytics reporting + + + + + [report(payload)](./search-ui-react.searchanalyticseventservice.report.md) diff --git a/docs/search-ui-react.searchanalyticseventservice.optin.md b/docs/search-ui-react.searchanalyticseventservice.optin.md new file mode 100644 index 000000000..94aab7f9f --- /dev/null +++ b/docs/search-ui-react.searchanalyticseventservice.optin.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [@yext/search-ui-react](./search-ui-react.md) > [SearchAnalyticsEventService](./search-ui-react.searchanalyticseventservice.md) > [optIn](./search-ui-react.searchanalyticseventservice.optin.md) + +## SearchAnalyticsEventService.optIn() method + +Enables analytics reporting + +**Signature:** + +```typescript +optIn(): void; +``` +**Returns:** + +void + diff --git a/docs/search-ui-react.searchanalyticseventservice.optout.md b/docs/search-ui-react.searchanalyticseventservice.optout.md new file mode 100644 index 000000000..5279a42b5 --- /dev/null +++ b/docs/search-ui-react.searchanalyticseventservice.optout.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [@yext/search-ui-react](./search-ui-react.md) > [SearchAnalyticsEventService](./search-ui-react.searchanalyticseventservice.md) > [optOut](./search-ui-react.searchanalyticseventservice.optout.md) + +## SearchAnalyticsEventService.optOut() method + +Disables analytics reporting + +**Signature:** + +```typescript +optOut(): void; +``` +**Returns:** + +void + diff --git a/etc/search-ui-react.api.md b/etc/search-ui-react.api.md index f20150e16..dd840b2af 100644 --- a/etc/search-ui-react.api.md +++ b/etc/search-ui-react.api.md @@ -689,11 +689,15 @@ export interface SearchAnalyticsConfig { apiKey: string; cloudRegion?: CloudRegion; environment?: Environment; + requireOptIn?: boolean; sessionTrackingEnabled?: boolean; } // @public export interface SearchAnalyticsEventService { + isYextAnalyticsEnabled(): boolean; + optIn(): void; + optOut(): void; // Warning: (ae-forgotten-export) The symbol "SearchEventPayload" needs to be exported by the entry point index.d.ts report(payload: SearchEventPayload): Promise; } @@ -1039,7 +1043,7 @@ export interface VisualAutocompleteConfig { // Warnings were encountered during analysis: // -// dist/index.d.ts:1741:5 - (ae-forgotten-export) The symbol "translations" needs to be exported by the entry point index.d.ts +// dist/index.d.ts:1749:5 - (ae-forgotten-export) The symbol "translations" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/src/components/AnalyticsProvider.tsx b/src/components/AnalyticsProvider.tsx index 3a3ebf46f..10f07d6e8 100644 --- a/src/components/AnalyticsProvider.tsx +++ b/src/components/AnalyticsProvider.tsx @@ -1,7 +1,8 @@ -import React, { PropsWithChildren } from 'react'; +import React, { PropsWithChildren, useEffect, useRef } from 'react'; import { AnalyticsContext } from '../hooks/useAnalytics'; import { CloudRegion, Environment } from '@yext/search-core'; import { SearchAnalyticsEventServiceImpl } from '../models/SearchAnalyticsEventServiceImpl'; +import { SearchAnalyticsEventService } from '../models'; /** * A higher-order component which provides analytics for its children. @@ -13,11 +14,28 @@ import { SearchAnalyticsEventServiceImpl } from '../models/SearchAnalyticsEventS */ export function AnalyticsProvider(props: PropsWithChildren): React.JSX.Element { const { children, ...searchAnalyticsConfig } = props; - const analyticsReporter = - new SearchAnalyticsEventServiceImpl(searchAnalyticsConfig); + + const analyticsRef = useRef(null); + + if (analyticsRef.current === null) { + analyticsRef.current = new SearchAnalyticsEventServiceImpl(searchAnalyticsConfig); + } + + const analytics = analyticsRef.current; + + // Adds enableYextAnalytics to the window. Typically used during consent banner implementation. + useEffect(() => { + (window as any).enableYextAnalytics = () => { + analytics.optIn(); + }; + + return () => { + delete (window as any).enableYextAnalytics; + }; + }, [analytics]); return ( - + {children} ); @@ -36,5 +54,7 @@ export interface SearchAnalyticsConfig { /** The region to send requests to. Defaults to 'US'. */ cloudRegion?: CloudRegion, /** Whether to enable session tracking for analytics events. */ - sessionTrackingEnabled?: boolean + sessionTrackingEnabled?: boolean, + /** Whether a user must consent to analytics tracking before events are fired. Defaults to false. */ + requireOptIn?: boolean } diff --git a/src/models/SearchAnalyticsEventService.ts b/src/models/SearchAnalyticsEventService.ts index 0624538f8..e30282a0e 100644 --- a/src/models/SearchAnalyticsEventService.ts +++ b/src/models/SearchAnalyticsEventService.ts @@ -11,5 +11,11 @@ export interface SearchAnalyticsEventService { * * @param payload - desired values to be applied */ - report(payload: SearchEventPayload): Promise + report(payload: SearchEventPayload): Promise, + /** Enables analytics reporting */ + optIn(): void, + /** Disables analytics reporting */ + optOut(): void, + /** Returns whether analytics reporting is currently enabled */ + isYextAnalyticsEnabled(): boolean } diff --git a/src/models/SearchAnalyticsEventServiceImpl.ts b/src/models/SearchAnalyticsEventServiceImpl.ts index 72d4af57b..2c3de8b83 100644 --- a/src/models/SearchAnalyticsEventServiceImpl.ts +++ b/src/models/SearchAnalyticsEventServiceImpl.ts @@ -7,6 +7,7 @@ import { SearchAnalyticsEventService } from './SearchAnalyticsEventService'; /** An implementation of {@link SearchAnalyticsEventService} which makes calls to the Analytics Events API */ export class SearchAnalyticsEventServiceImpl implements SearchAnalyticsEventService { private internalService: AnalyticsEventService; + private analyticsEnabled: boolean; /** * @param searchAnalyticsConfig - configuration for analytics reporting. */ @@ -21,9 +22,26 @@ export class SearchAnalyticsEventServiceImpl implements SearchAnalyticsEventServ sessionTrackingEnabled: searchAnalyticsConfig.sessionTrackingEnabled }; this.internalService = analytics(analyticsConfig); + // if requireOptIn is undefined or set to false, analytics are enabled + this.analyticsEnabled = !searchAnalyticsConfig.requireOptIn; + } + + public optIn(): void { + this.analyticsEnabled = true; + } + + public optOut(): void { + this.analyticsEnabled = false; + } + + public isYextAnalyticsEnabled(): boolean { + return this.analyticsEnabled; } public async report(payload: SearchEventPayload): Promise { + if (!this.analyticsEnabled) { + return Promise.resolve(''); + } const eventPayload: EventPayload = { action: payload.action, destinationUrl: payload.destinationUrl, diff --git a/test-site/package-lock.json b/test-site/package-lock.json index dae59a0a4..4e7b1b3d3 100644 --- a/test-site/package-lock.json +++ b/test-site/package-lock.json @@ -34,7 +34,7 @@ }, "..": { "name": "@yext/search-ui-react", - "version": "2.0.4", + "version": "2.0.5", "license": "BSD-3-Clause", "dependencies": { "@restart/ui": "^1.0.1", diff --git a/test-site/src/config.ts b/test-site/src/config.ts index 826e4d1a7..4db37e315 100644 --- a/test-site/src/config.ts +++ b/test-site/src/config.ts @@ -1,5 +1,4 @@ import { CloudRegion, CloudChoice, Environment } from '@yext/search-headless-react'; -import {AnalyticsConfig} from "@yext/analytics"; import {SearchAnalyticsConfig} from "../../src"; export const config = { @@ -17,4 +16,5 @@ export const analyticsConfig: SearchAnalyticsConfig = { apiKey: process.env.REACT_APP_EVENTS_API_KEY || 'REPLACE_ME', environment: Environment.PROD, cloudRegion: CloudRegion.US, + requireOptIn: false, }; diff --git a/tests/components/SearchBar.test.tsx b/tests/components/SearchBar.test.tsx index 98c3d8733..ff7bd205e 100644 --- a/tests/components/SearchBar.test.tsx +++ b/tests/components/SearchBar.test.tsx @@ -6,14 +6,11 @@ import { State, SearchTypeEnum } from '@yext/search-headless-react'; import { render, RenderResult, screen } from '@testing-library/react'; -import { SearchBar, onSearchFunc } from '../../src/components/SearchBar'; -import { VerticalLink } from '../../src/models/verticalLink'; -import { SearchI18nextProvider } from '../../src/components/SearchI18nextProvider'; +import { SearchBar, onSearchFunc, VerticalLink, SearchI18nextProvider, SearchAnalyticsEventService } from '../../src'; import userEvent from '@testing-library/user-event'; import { generateMockedHeadless } from '../__fixtures__/search-headless'; import { RecursivePartial } from '../__utils__/mocks'; import * as Analytics from '../../src/hooks/useAnalytics'; -import { AnalyticsEventService } from '@yext/analytics'; import React from 'react'; const mockedState: Partial = { @@ -560,7 +557,7 @@ describe('SearchBar', () => { beforeEach(() => { jest.spyOn(Analytics, 'useAnalytics') - .mockImplementation(() => ({ report: mockedReport }) as unknown as AnalyticsEventService); + .mockImplementation(() => ({ report: mockedReport }) as unknown as SearchAnalyticsEventService); }); it('reports AUTO_COMPLETE_SELECTION feedback', async () => { From d71dc882a6008cf914b636e14f4de86f42257f37 Mon Sep 17 00:00:00 2001 From: Jacob Fondriest Date: Wed, 18 Feb 2026 14:29:17 -0500 Subject: [PATCH 2/4] release: v2.1.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 85444a4fd..c3212de58 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@yext/search-ui-react", - "version": "2.0.5", + "version": "2.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@yext/search-ui-react", - "version": "2.0.5", + "version": "2.1.0", "license": "BSD-3-Clause", "dependencies": { "@restart/ui": "^1.0.1", diff --git a/package.json b/package.json index 510aafff6..0b8d5c88f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@yext/search-ui-react", - "version": "2.0.5", + "version": "2.1.0", "description": "A library of React Components for powering Yext Search integrations", "author": "watson@yext.com", "license": "BSD-3-Clause", From 3a2168edeba709a3a2041c2c45dd426c9da46e01 Mon Sep 17 00:00:00 2001 From: anguyen-yext2 <143001514+anguyen-yext2@users.noreply.github.com> Date: Thu, 19 Feb 2026 17:06:37 -0500 Subject: [PATCH 3/4] More accessbilities fixes for autocomplete results (#635) * More accessbilities fixes for autocomplete results Associate the visible label with the input via `label` + `htmlFor`, and wire `DropdownInput` with `inputId` and `aria-labelledby`. Change the instructions container from `hidden` to `sr-only`, so `aria-describedby` references content that is actually exposed to screen readers. J=WAT-5357 TEST=manual tested with voice over enabled on test-site * Update snapshots --------- Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> --- .../filtersearch--dropdown-sectioned.png | Bin 13628 -> 13626 bytes .../filtersearch--dropdown-unsectioned.png | Bin 11083 -> 11081 bytes .../__snapshots__/filtersearch--primary.png | Bin 6776 -> 6773 bytes src/components/Dropdown/DropdownInput.tsx | 15 ++++++++++++--- src/components/FilterSearch.tsx | 11 ++++++++++- src/components/ScreenReader.tsx | 2 +- 6 files changed, 23 insertions(+), 5 deletions(-) diff --git a/.storybook/snapshots/__snapshots__/filtersearch--dropdown-sectioned.png b/.storybook/snapshots/__snapshots__/filtersearch--dropdown-sectioned.png index e02626969db17c44c2a202c25fff9a74cdd22f89..06a954e9d62eb9489bfc479b0bef20599e9c100f 100644 GIT binary patch literal 13626 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 E2DnjrxBvhE literal 13628 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 bub9XQGkcjZgvDi`M#T8K*{|5YIY0XkpmgF~ literal 11083 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 z%0A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 literal 6776 zcmeHLX;jnK5|8o(H^Aj7C|h4SEmf+hsDKFABBh9gieP{cqM$+&Rw0BCLZr1IP(h1| z0-~UTh$Nztgb;#?ND(1y0kaVnNq|6Nf+1vofBO0LeQdw*W$v80bI+am%{}v*bMt-z z`BGzbJ*1*j`~SFZ$?BX-ADfIu5Sen-CxPA{M3+#Gv07 zr%-RNuHJU$ha}^;Jg{~9zfvQ1UApA5Wp!8A%4Q4Rh)-N*c3#)4aj8J$tSrJYu{}*9 zf%LHGa18{9!vSG{2s0U5fMvrGkP#ri`&(qCZ{Gp3Hht*2IYHG4lWNU?030qw-&!%E z|A2-t!{yDCIIN(9q2w0?+Ib*D4VXecZQRZ?!&j!#v^q~-UxKmlZZv%rZRT?=1)q$> zv#eToikY7EdT&f*FtGb_&5UJYHgSd^{2&v#*y?{Hl05t4naveCj&I^3TPV=Y-mNaQ zWVuH5dyzhbk8o%UvZm*r`yQSNj&3s{l`BY&2g$bEc{F`C>TCQWEti4gvj}^uW%OzD z`uJVI4fpC&MPG)pL;~$yOdOuOtG6CSP~Si?8g*4{c$l^%CL}&yDhT#zeNu>_GA4M7 z6TPG@EgpMjz9K}4r;RZv2_7k8;!xCS)zKS@ww@;t25@!iFVUu>-b~P4nI@Dkk2HTW zJG|Jg5fU=rxVtN_xP8>iEkK})34I~b6`rNDgQ6cOAOSjZtT*1i4 z8cD1q6@*dC_&N4OGK2#xCc3#|ZS}ZH6>azv!UEqe*YHIi`o6%Db0u9}!jiLN>h$ z9!|fY7{WK!T)DlFS7%5}%V4T+%!_tqj8D$(YVWKmYC1dgzEd=G%6f8p;r>lPGMk|g zrJ>EMeEuZHvyy0WIVO|&Bz870DAG2lJe3g06os$uoU-P^R$oPk} z24~{kk)NPQb^9|DJH4LA5x4G19Cr!+3_o{#2QT(n63TBf7P&W_5_xDs}v2PV_8-BHU z_noG!?rwibOUA3-v0r|GA5?r=^A?urBj^r*!x`s0R&6%1;{+vh-rRP6TQvJXmz28;VZ%u;u1$D| z)&no}dojo7>CT)$?O-c>kB-$XKIKK3$-Chwr6Ul!kFAEc@B6lNTSfAl@QS%%5B<;> z+P=)c{Zo`^X0pIGl8#geVYwEup7FS@G6(BDRcCswiaXp7)~og*W>vofA=5mG9lA8Q;WhTrsb(rbK`@ z^|hLIi&=V8;VyI&>a#$sgrdEjs@hT~;%CjvA2K5j(i)=Yull!YC&OYCSj|*F%~zDA zyH;#CFPyz?pJQel+#ty&jmRVVPW24CWRT_E9Vkb4hOI7)TU?;58dr*NU8_o5PJPzB zWC<9_uSYSnNUofSa((wBP;qb^Uu`>@&ylC15ODw6K~loUdr{n(8pIfNog-WhPJmtI_7^D9dq24mMk+DdeY8&r_{!>$r-Bg z+!8}tpxX|nbtvbBu>C?1IUXk;v*T&H@V+bv9fit=ZNNDjH?o4L?duR zrkqM}Pu;BGVgO1_I-EN9WoTQ+6=XR1b7d|(>!JM`&3ZS&c!+?W`I>E0a6;jR<21tS zpnDR>l%DPccx@mW&+pBtjdm=^zgFz!h7%KbxCxQydOjltT)r18`o+mc_4!8I*I8pj z`KtM?eC$ME_&X5^K^3ak_&^?6?;qnpHQMx%Djb9Mq-n5@oG?1NG1@EnffcdH6KI~; zwgPd1O=55gcBf{t(Y?owCrac34DnKy6aVd6`UbG8W7iQSc$<^>aKZiyN z#o`VH(KR&8g_CL}kcw2|)VZ&g1}Yk4`eim=1I0*q1J7faCv(?-dq`?&M4h^oJkoL> zi&04d77GO&k6?B()i-NSo2;LLL;0<)Ujy6>m_HdVH<$ds4F4+gW&1J$%LptZ@DCvH zB&d)J0 void, onFocus?: (value: string) => void, onChange?: (value: string) => void, @@ -19,7 +22,10 @@ export function DropdownInput(props: { const { className, placeholder, + inputId, ariaLabel, + ariaLabelledBy, + ariaDescribedBy, onSubmit, onFocus, onChange, @@ -36,6 +42,8 @@ export function DropdownInput(props: { updateFocusedItem } = useFocusContext(); const [isTyping, setIsTyping] = useState(true); + const describedBy = [screenReaderUUID, ariaDescribedBy].filter(Boolean).join(' ') || undefined; + const resolvedAriaLabel = ariaLabelledBy ? undefined : ariaLabel; const handleChange = useCallback((e: ChangeEvent) => { setIsTyping(true); @@ -86,13 +94,14 @@ export function DropdownInput(props: { onChange={handleChange} onKeyDown={handleKeyDown} onFocus={handleFocus} - id={generateDropdownId(screenReaderUUID, -1)} + id={inputId ?? generateDropdownId(screenReaderUUID, -1)} autoComplete='off' - aria-describedby={screenReaderUUID} + aria-describedby={describedBy} aria-activedescendant={ !isTyping ? generateDropdownId(screenReaderUUID, focusedIndex) : undefined } - aria-label={ariaLabel} + aria-label={resolvedAriaLabel} + aria-labelledby={ariaLabelledBy} aria-autocomplete="list" role="combobox" aria-controls={dropdownListUUID} diff --git a/src/components/FilterSearch.tsx b/src/components/FilterSearch.tsx index 2318f613b..5766f2c19 100644 --- a/src/components/FilterSearch.tsx +++ b/src/components/FilterSearch.tsx @@ -6,6 +6,7 @@ import { useSynchronizedRequest } from '../hooks/useSynchronizedRequest'; import { useDebouncedFunction } from '../hooks/useDebouncedFunction'; import { executeSearch } from '../utils'; import { isDuplicateStaticFilter } from '../utils/filterutils'; +import { useId } from '../hooks/useId'; import { Dropdown } from './Dropdown/Dropdown'; import { DropdownInput } from './Dropdown/DropdownInput'; import { DropdownItem } from './Dropdown/DropdownItem'; @@ -156,6 +157,8 @@ export function FilterSearch({ }: FilterSearchProps): React.JSX.Element { const { t } = useTranslation(); const searchActions = useSearchActions(); + const inputId = useId('filter-search-input'); + const labelId = useId('filter-search-label'); const searchParamFields = searchFields.map((searchField) => { return { ...searchField, fetchEntities: false }; }); @@ -356,7 +359,9 @@ export function FilterSearch({ onChange={handleInputChange} onFocus={handleInputFocus} submitCriteria={meetsSubmitCritera} + inputId={inputId} ariaLabel={ariaLabel} + ariaLabelledBy={label ? labelId : undefined} /> ); @@ -372,7 +377,11 @@ export function FilterSearch({ return (
- {label &&

{label}

} + {label && ( + + )}
{instructions}
From f96e0cfcd4b13bc89b1712150182369d7dfff019 Mon Sep 17 00:00:00 2001 From: anguyen-yext2 Date: Thu, 19 Feb 2026 17:17:28 -0500 Subject: [PATCH 4/4] release: v2.1.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index c3212de58..f38c1bc4b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@yext/search-ui-react", - "version": "2.1.0", + "version": "2.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@yext/search-ui-react", - "version": "2.1.0", + "version": "2.1.1", "license": "BSD-3-Clause", "dependencies": { "@restart/ui": "^1.0.1", diff --git a/package.json b/package.json index 0b8d5c88f..9418feb58 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@yext/search-ui-react", - "version": "2.1.0", + "version": "2.1.1", "description": "A library of React Components for powering Yext Search integrations", "author": "watson@yext.com", "license": "BSD-3-Clause",