diff --git a/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-2-dark-chromium-1-chromium-linux.png b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-2-dark-chromium-1-chromium-linux.png index 3d7bce7..54f2ffd 100644 Binary files a/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-2-dark-chromium-1-chromium-linux.png and b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-2-dark-chromium-1-chromium-linux.png differ diff --git a/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-2-dark-webkit-1-webkit-linux.png b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-2-dark-webkit-1-webkit-linux.png index 7919db9..ea920a0 100644 Binary files a/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-2-dark-webkit-1-webkit-linux.png and b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-2-dark-webkit-1-webkit-linux.png differ diff --git a/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-2-light-chromium-1-chromium-linux.png b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-2-light-chromium-1-chromium-linux.png index 80e6379..af97c54 100644 Binary files a/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-2-light-chromium-1-chromium-linux.png and b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-2-light-chromium-1-chromium-linux.png differ diff --git a/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-2-light-webkit-1-webkit-linux.png b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-2-light-webkit-1-webkit-linux.png index 61938b7..ab70846 100644 Binary files a/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-2-light-webkit-1-webkit-linux.png and b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-2-light-webkit-1-webkit-linux.png differ diff --git a/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-dark-chromium-1-chromium-linux.png b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-dark-chromium-1-chromium-linux.png index a687be3..24506c1 100644 Binary files a/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-dark-chromium-1-chromium-linux.png and b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-dark-chromium-1-chromium-linux.png differ diff --git a/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-dark-webkit-1-webkit-linux.png b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-dark-webkit-1-webkit-linux.png index 80b6c1e..62449cf 100644 Binary files a/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-dark-webkit-1-webkit-linux.png and b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-dark-webkit-1-webkit-linux.png differ diff --git a/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-light-chromium-1-chromium-linux.png b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-light-chromium-1-chromium-linux.png index a415324..1bf1b1c 100644 Binary files a/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-light-chromium-1-chromium-linux.png and b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-light-chromium-1-chromium-linux.png differ diff --git a/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-light-webkit-1-webkit-linux.png b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-light-webkit-1-webkit-linux.png index d9d1df5..629f011 100644 Binary files a/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-light-webkit-1-webkit-linux.png and b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-case-insensitive-search-with-matches-light-webkit-1-webkit-linux.png differ diff --git a/src/ReactUnipika/__stories__/ReactUnipika.stories.tsx b/src/ReactUnipika/__stories__/ReactUnipika.stories.tsx index eba370a..9bd5f88 100644 --- a/src/ReactUnipika/__stories__/ReactUnipika.stories.tsx +++ b/src/ReactUnipika/__stories__/ReactUnipika.stories.tsx @@ -5,6 +5,7 @@ import {Meta, StoryObj} from '@storybook/react'; import {ReactUnipika, ReactUnipikaProps} from '../../index'; import data from './data.json'; +import {Button} from '@gravity-ui/uikit'; const meta: Meta = { title: 'ReactUnipika', @@ -25,10 +26,27 @@ export const Yson: StoryObj = { }, }; +function WithCaseInsensitiveSearchComponent() { + const [caseInsensitiveSearch, setCaseInsensitiveSearch] = React.useState(true); + return ( + <> + + + + ); +} + export const WithCaseInsensitiveSearch: StoryObj = { - args: { - value: data, - caseInsensitiveSearch: true, + render() { + return ; }, }; diff --git a/src/ReactUnipika/__tests__/ReactUnipika.visual.test.tsx b/src/ReactUnipika/__tests__/ReactUnipika.visual.test.tsx index 8d730c1..d1f8287 100644 --- a/src/ReactUnipika/__tests__/ReactUnipika.visual.test.tsx +++ b/src/ReactUnipika/__tests__/ReactUnipika.visual.test.tsx @@ -177,3 +177,78 @@ test('ReactUnipika: with error', async ({mount, expectScreenshot, page}) => { await expectScreenshot({component: page}); }); + +test('ReactUnipika: with case insensitive search with matches', async ({ + mount, + expectScreenshot, + page, +}) => { + await mount(, {width: 1280}); + + await page.getByTestId('qa:structuredyson:search').locator('input').fill('Attr'); + + await expectScreenshot({component: page}); +}); + +test('ReactUnipika: with case insensitive search with matches 2', async ({ + mount, + expectScreenshot, + page, +}) => { + await mount(, {width: 1280}); + + await page.getByTestId('qa:structuredyson:search').locator('input').fill('attr'); + + await expectScreenshot({component: page}); +}); + +test('ReactUnipika: with case insensitive search toggle', async ({mount, page}) => { + await mount(, {width: 1280}); + + await page.getByTestId('qa:structuredyson:search').locator('input').fill('Type_1'); + + const visibleHighlightedElements = await page + .locator('.g-ru-cell__filtered_highlighted:has-text("type_1")') + .filter({hasText: 'Type_1'}) + .count(); + if (visibleHighlightedElements !== 1) { + throw new Error( + `Expected 1 visible highlighted elements with "Type_1", but found ${visibleHighlightedElements}`, + ); + } + + await page.getByTestId('qa:case-sensitive-button').click(); + const newVisibleHighlightedElements = await page + .locator('.g-ru-cell__filtered_highlighted:has-text("type_1")') + .filter({hasText: 'Type_1'}) + .count(); + if (newVisibleHighlightedElements !== 0) { + throw new Error( + `Expected 0 visible highlighted elements with "Type_1", but found ${visibleHighlightedElements}`, + ); + } +}); + +test('ReactUnipika: with case sensitive search no matches', async ({ + mount, + expectScreenshot, + page, +}) => { + await mount(, {width: 1280}); + + await page.getByTestId('qa:structuredyson:search').locator('input').fill('Attr'); + + await expectScreenshot({component: page}); +}); + +test('ReactUnipika: with case sensitive search with matches', async ({ + mount, + expectScreenshot, + page, +}) => { + await mount(, {width: 1280}); + + await page.getByTestId('qa:structuredyson:search').locator('input').fill('attr'); + + await expectScreenshot({component: page}); +}); diff --git a/src/StructuredYson/StructuredYson.tsx b/src/StructuredYson/StructuredYson.tsx index a0ad2cb..cacc540 100644 --- a/src/StructuredYson/StructuredYson.tsx +++ b/src/StructuredYson/StructuredYson.tsx @@ -49,6 +49,7 @@ interface State { value: Props['value']; settings: Props['settings']; yson: boolean; + caseInsensitiveSearch?: boolean; collapsedState: CollapsedState; filter: string; matchIndex: number; @@ -116,14 +117,24 @@ function calculateState( export class StructuredYson extends React.PureComponent { static getDerivedStateFromProps(props: Props, state: State) { - const {value: prevValue, settings: prevSettings, yson: prevYson} = state; - const {value, settings} = props; + const { + value: prevValue, + settings: prevSettings, + yson: prevYson, + caseInsensitiveSearch: prevCaseInsensitiveSearch, + } = state; + const {value, settings, caseInsensitiveSearch} = props; const res: Partial = {}; const yson = settings.format === 'yson'; - if (prevSettings !== settings || yson !== prevYson) { + if ( + prevSettings !== settings || + yson !== prevYson || + caseInsensitiveSearch !== prevCaseInsensitiveSearch + ) { Object.assign, Partial>(res, { settings, yson, + caseInsensitiveSearch, }); } if (prevValue !== value || !isEmpty_(res)) { @@ -133,7 +144,7 @@ export class StructuredYson extends React.PureComponent { value, state.collapsedState, state.filter, - props.caseInsensitiveSearch, + caseInsensitiveSearch, settings, ), }); @@ -147,7 +158,7 @@ export class StructuredYson extends React.PureComponent { searchRef = React.createRef(); getInitialState(): State { - const {initiallyCollapsed, value, settings} = this.props; + const {initiallyCollapsed, value, settings, caseInsensitiveSearch} = this.props; const collapsedState = initiallyCollapsed ? this.getFullyCollapsedState(value, settings.format !== 'yson') : {}; @@ -163,6 +174,7 @@ export class StructuredYson extends React.PureComponent { matchIndex: -1, matchedRows: [], allMatchPaths: [], + caseInsensitiveSearch, }; } @@ -182,8 +194,7 @@ export class StructuredYson extends React.PureComponent { changedState: Partial>, cb?: () => void, ) { - const {value, settings} = this.state; - const {caseInsensitiveSearch} = this.props; + const {value, settings, caseInsensitiveSearch} = this.state; const { collapsedState = this.state.collapsedState, matchIndex = this.state.matchIndex,