diff --git a/src/app/content/components/Topbar/__snapshots__/index.spec.tsx.snap b/src/app/content/components/Topbar/__snapshots__/index.spec.tsx.snap index 3a52769aee..16ba148ea0 100644 --- a/src/app/content/components/Topbar/__snapshots__/index.spec.tsx.snap +++ b/src/app/content/components/Topbar/__snapshots__/index.spec.tsx.snap @@ -690,6 +690,7 @@ exports[`text resizer does not render if textSize is null 1`] = ` > { }; }); - const render = (options?: TestRendererOptions) => - renderer.create( - - - - - - - , - options - ); + const render = (options?: TestRendererOptions) => renderer.create( + + + + + + , options); - const dispatchSearchShortcut = (target: HTMLElement | undefined) => { - dispatchKeyDownEvent({ - code: searchKeyCombination.code, - altKey: searchKeyCombination.altKey, - target, - }); - }; +const dispatchSearchShortcut = (target: HTMLElement | undefined) => { + dispatchKeyDownEvent({code: searchKeyCombination.code, altKey: searchKeyCombination.altKey, target}); +}; it('opens and closes mobile interface', () => { const component = render(); @@ -101,10 +87,11 @@ describe('search', () => { }); expect(mobileSearch.props.mobileToolbarOpen).toBe(false); expect(event.preventDefault).toHaveBeenCalledTimes(2); + }); - it('goes to main when no search results', () => { - const { node } = renderToDom( + it('goes between main and search input when no search results', () => { + const {node} = renderToDom( @@ -116,12 +103,13 @@ describe('search', () => { ); const tb = node.querySelector('[class*="TopBar"]'); + expect(document?.activeElement?.tagName).toBe('INPUT'); act(() => dispatchSearchShortcut(tb!)); expect(document?.activeElement?.tagName).toBe('MAIN'); }); it('goes to search results when provided', () => { - const { node } = renderToDom( + const {node} = renderToDom( @@ -139,14 +127,12 @@ describe('search', () => { act(() => dispatchSearchShortcut(tb!)); expect(document?.activeElement?.tagName).toBe('INPUT'); act(() => dispatchSearchShortcut(tb!)); - expect( - document?.activeElement?.classList.contains('SearchResultsBar') - ).toBe(true); + expect(document?.activeElement?.classList.contains('SearchResultsBar')).toBe(true); }); it('aborts on mobile', () => { (useMatchMobileQuery as jest.Mock).mockReturnValue(true); - const { node } = renderToDom( + const {node} = renderToDom( @@ -204,20 +190,14 @@ describe('search', () => { }); const htmlelement = document.createElement('div'); - Object.defineProperty(document, 'activeElement', { - value: htmlelement, - writable: true, - }); + Object.defineProperty(document, 'activeElement', {value: htmlelement, writable: true}); const blur1 = jest.spyOn(htmlelement, 'blur'); renderer.act(() => findById('desktop-search').props.onSubmit(makeEvent())); expect(blur1).toHaveBeenCalled(); // test non HTMLElement branch - const svgelement = document.createElementNS( - 'http://www.w3.org/2000/svg', - 'path' - ); - Object.defineProperty(document, 'activeElement', { value: svgelement }); + const svgelement = document.createElementNS('http://www.w3.org/2000/svg', 'path'); + Object.defineProperty(document, 'activeElement', {value: svgelement}); const blur2 = jest.spyOn(svgelement, 'blur'); renderer.act(() => findById('desktop-search').props.onSubmit(makeEvent())); expect(blur2).not.toHaveBeenCalled(); @@ -360,10 +340,7 @@ describe('search', () => { jest.spyOn(searchSelectors, 'searchInSidebar').mockReturnValue(true); const component = render(); - expect( - component.root.findByProps({ 'data-testid': 'desktop-search' }).props - .searchInSidebar - ).toBe(true); + expect(component.root.findByProps({ 'data-testid': 'desktop-search' }).props.searchInSidebar).toBe(true); }); }); @@ -378,60 +355,37 @@ describe('search button', () => { jest.restoreAllMocks(); }); - const render = () => - renderer.create( - - - - ); + const render = () => renderer.create(); it('button has theme bg color applied', () => { - const color = searchSelectors.searchButtonColor.resultFunc( - 'bannerColorButton', - book, - 'blue' - ); + const color = searchSelectors.searchButtonColor.resultFunc('bannerColorButton', book, 'blue'); jest.spyOn(searchSelectors, 'searchButtonColor').mockReturnValue(color); jest.spyOn(searchSelectors, 'mobileToolbarOpen').mockReturnValue(true); const component = render(); - const [searchButton, searchButtonMobile] = component.root.findAllByType( - SearchButton - ); + const [searchButton, searchButtonMobile] = component.root.findAllByType(SearchButton); expect(searchButton.props.colorSchema).toEqual('blue'); expect(searchButtonMobile.props.colorSchema).toEqual('blue'); }); it('button has gray bg color applied', () => { - const color = searchSelectors.searchButtonColor.resultFunc( - 'grayButton', - book, - 'red' - ); + const color = searchSelectors.searchButtonColor.resultFunc('grayButton', book, 'red'); jest.spyOn(searchSelectors, 'searchButtonColor').mockReturnValue(color); const component = render(); - const [searchButton, searchButtonMobile] = component.root.findAllByType( - SearchButton - ); + const [searchButton, searchButtonMobile] = component.root.findAllByType(SearchButton); expect(searchButton.props.colorSchema).toEqual('gray'); expect(searchButtonMobile.props.colorSchema).toEqual('gray'); }); it('button has no bg color applied', () => { - const color = searchSelectors.searchButtonColor.resultFunc( - null, - book, - 'blue' - ); + const color = searchSelectors.searchButtonColor.resultFunc(null, book, 'blue'); jest.spyOn(searchSelectors, 'searchButtonColor').mockReturnValue(color); const component = render(); - const [searchButton, searchButtonMobile] = component.root.findAllByType( - SearchButton - ); + const [searchButton, searchButtonMobile] = component.root.findAllByType(SearchButton); expect(searchButton.props.colorSchema).toEqual(null); expect(searchButtonMobile.props.colorSchema).toEqual(null); @@ -444,8 +398,8 @@ describe('search button', () => { const findById = makeFindByTestId(component.root); const inputEvent = makeInputEvent('cool search'); - renderer.act(() => - findById('desktop-search-input').props.onChange(inputEvent) + renderer.act( + () => findById('desktop-search-input').props.onChange(inputEvent) ); const event = makeEvent(); @@ -467,16 +421,10 @@ describe('mobile menu button', () => { }); it('opens mobile menu', () => { - const component = renderer.create( - - - - ); + const component = renderer.create(); renderer.act(() => { - component.root - .findByType(MenuButton) - .props.onClick({ preventDefault: jest.fn() }); + component.root.findByType(MenuButton).props.onClick({preventDefault: jest.fn()}); }); expect(dispatch).toHaveBeenCalledWith(openMobileMenu()); @@ -495,28 +443,18 @@ describe('text resizer', () => { it('does not render if textSize is null', () => { store.dispatch((setTextSize as any)(null)); - const component = renderer.create( - - - - ); + const component = renderer.create(); expect(component.root.findAllByType(TextResizerMenu)).toEqual([]); expect(component).toMatchSnapshot(); }); it('opens menu when clicking menu button', () => { - const component = renderer.create( - - - - ); + const component = renderer.create(); expect(component.root.findAllByType(TextResizerMenu)).toEqual([]); renderer.act(() => { - component.root - .findByProps({ 'data-testid': 'text-resizer' }) - .findByProps({ isOpen: false }) - .props.onClick({ preventDefault: jest.fn() }); + component.root.findByProps({ 'data-testid': 'text-resizer' }) + .findByProps({ isOpen: false }).props.onClick({ preventDefault: jest.fn() }); }); expect(component.root.findByType(TextResizerMenu)).toBeDefined(); @@ -524,39 +462,27 @@ describe('text resizer', () => { }); it('changes the text size with buttons', () => { - const component = renderer.create( - - - - ); + const component = renderer.create(); renderer.act(() => { - component.root - .findByProps({ 'data-testid': 'text-resizer' }) - .findByProps({ isOpen: false }) - .props.onClick({ preventDefault: jest.fn() }); + component.root.findByProps({ 'data-testid': 'text-resizer' }) + .findByProps({ isOpen: false }).props.onClick({ preventDefault: jest.fn() }); }); renderer.act(() => { - component.root - .findByProps({ 'data-testid': 'decrease-text-size' }) - .props.onClick({ preventDefault: jest.fn() }); + component.root.findByProps({ 'data-testid': 'decrease-text-size' }).props.onClick({ preventDefault: jest.fn() }); }); expect(dispatch).toHaveBeenCalledWith(setTextSize(-1)); renderer.act(() => { - component.root - .findByProps({ 'data-testid': 'increase-text-size' }) - .props.onClick({ preventDefault: jest.fn() }); + component.root.findByProps({ 'data-testid': 'increase-text-size' }).props.onClick({ preventDefault: jest.fn() }); }); expect(dispatch).toHaveBeenCalledWith(setTextSize(0)); renderer.act(() => { - component.root - .findByProps({ 'data-testid': 'increase-text-size' }) - .props.onClick({ preventDefault: jest.fn() }); + component.root.findByProps({ 'data-testid': 'increase-text-size' }).props.onClick({ preventDefault: jest.fn() }); }); expect(dispatch).toHaveBeenCalledWith(setTextSize(1)); @@ -564,8 +490,7 @@ describe('text resizer', () => { dispatch.mockReset(); renderer.act(() => { - component.root - .findByProps({ 'data-testid': 'change-text-size' }) + component.root.findByProps({ 'data-testid': 'change-text-size' }) .props.onChange({ currentTarget: { value: '3' } }); }); @@ -575,38 +500,24 @@ describe('text resizer', () => { it('keeps values within bounds', () => { store.dispatch(setTextSize(textResizerMaxValue)); dispatch.mockClear(); - const component = renderer.create( - - - - ); + const component = renderer.create(); renderer.act(() => { - component.root - .findByProps({ 'data-testid': 'text-resizer' }) - .findByProps({ isOpen: false }) - .props.onClick({ preventDefault: jest.fn() }); + component.root.findByProps({ 'data-testid': 'text-resizer' }) + .findByProps({ isOpen: false }).props.onClick({ preventDefault: jest.fn() }); }); renderer.act(() => { - component.root - .findByProps({ 'data-testid': 'increase-text-size' }) - .props.onClick({ preventDefault: jest.fn() }); + component.root.findByProps({ 'data-testid': 'increase-text-size' }).props.onClick({ preventDefault: jest.fn() }); }); - expect(dispatch).not.toHaveBeenCalledWith( - setTextSize((textResizerMaxValue + 1) as any) - ); + expect(dispatch).not.toHaveBeenCalledWith(setTextSize((textResizerMaxValue + 1) as any)); renderer.act(() => { - component.root - .findByProps({ 'data-testid': 'decrease-text-size' }) - .props.onClick({ preventDefault: jest.fn() }); + component.root.findByProps({ 'data-testid': 'decrease-text-size' }).props.onClick({ preventDefault: jest.fn() }); }); - expect(dispatch).toHaveBeenCalledWith( - setTextSize((textResizerMaxValue - 1) as any) - ); + expect(dispatch).toHaveBeenCalledWith(setTextSize((textResizerMaxValue - 1 as any))); renderer.act(() => { store.dispatch(setTextSize(textResizerMinValue)); @@ -614,41 +525,31 @@ describe('text resizer', () => { }); renderer.act(() => { - component.root - .findByProps({ 'data-testid': 'decrease-text-size' }) - .props.onClick({ preventDefault: jest.fn() }); + component.root.findByProps({ 'data-testid': 'decrease-text-size' }).props.onClick({ preventDefault: jest.fn() }); }); - expect(dispatch).not.toHaveBeenCalledWith( - setTextSize((textResizerMinValue - 1) as any) - ); + expect(dispatch).not.toHaveBeenCalledWith(setTextSize((textResizerMinValue - 1 as any))); renderer.act(() => { - component.root - .findByProps({ 'data-testid': 'change-text-size' }) + component.root.findByProps({ 'data-testid': 'change-text-size' }) .props.onChange({ currentTarget: { value: textResizerMaxValue + 1 } }); }); - expect(dispatch).not.toHaveBeenCalledWith( - setTextSize((textResizerMaxValue + 1) as any) - ); + expect(dispatch).not.toHaveBeenCalledWith(setTextSize(textResizerMaxValue + 1 as any)); renderer.act(() => { - component.root - .findByProps({ 'data-testid': 'change-text-size' }) + component.root.findByProps({ 'data-testid': 'change-text-size' }) .props.onChange({ currentTarget: { value: textResizerMinValue - 1 } }); }); - expect(dispatch).not.toHaveBeenCalledWith( - setTextSize((textResizerMinValue - 1) as any) - ); + expect(dispatch).not.toHaveBeenCalledWith(setTextSize(textResizerMinValue - 1 as any)); renderer.act(() => { - component.root - .findByProps({ 'data-testid': 'change-text-size' }) + component.root.findByProps({ 'data-testid': 'change-text-size' }) .props.onChange({ currentTarget: { value: 'invalid' } }); }); expect(dispatch).not.toHaveBeenCalled(); }); + }); diff --git a/src/app/content/components/Topbar/index.tsx b/src/app/content/components/Topbar/index.tsx index 8b38589473..72c4f8605d 100644 --- a/src/app/content/components/Topbar/index.tsx +++ b/src/app/content/components/Topbar/index.tsx @@ -167,14 +167,9 @@ function MobileSearchInputWrapper({ colorSchema={searchButtonColor} searchInSidebar={searchInSidebar} > - + {!state.formSubmitted && !newButtonEnabled && } diff --git a/src/app/content/components/Topbar/styled.tsx b/src/app/content/components/Topbar/styled.tsx index c972e31498..4e0b56ef0a 100644 --- a/src/app/content/components/Topbar/styled.tsx +++ b/src/app/content/components/Topbar/styled.tsx @@ -10,7 +10,6 @@ import { decoratedLinkStyle, textRegularStyle, textStyle } from '../../../compon import theme from '../../../theme'; import { textResizerMaxValue, textResizerMinValue } from '../../constants'; import { BookWithOSWebData } from '../../types'; -import { HTMLInputElement } from '@openstax/types/lib.dom'; import { bookBannerDesktopMiniHeight, bookBannerMobileMiniHeight, @@ -227,44 +226,29 @@ export const SearchInputWrapper = styled.form` `; // tslint:disable-next-line:variable-name -export const SearchInput = styled(({ desktop, mobile, autoFocus, ...props }) => { - const ref = React.useRef(null); +export const SearchInput = styled(({ desktop, mobile, ...props }) => + )` + ${textStyle} + ${hideSearchChrome} + font-size: 1.6rem; + margin: 0 1rem 0 1rem; + height: ${toolbarSearchInputHeight}rem; + border: none; + outline: none; + width: 100%; + appearance: textfield; - React.useEffect( - () => { - if (autoFocus) { - ref.current?.focus(); + ::placeholder { + color: ${theme.color.text.label}; } - }, - [autoFocus] - ); - - return ( - - ); -})` - ${textStyle} - ${hideSearchChrome} - font-size: 1.6rem; - margin: 0 1rem 0 1rem; - height: ${toolbarSearchInputHeight}rem; - border: none; - outline: none; - width: 100%; - appearance: textfield; - - ::placeholder { - color: ${theme.color.text.label}; - } - ${(props) => props.desktop && theme.breakpoints.mobileMedium(css` - display: none; - `)} -`; + ${(props) => props.desktop && theme.breakpoints.mobileMedium(css` + display: none; + `)} + `; // tslint:disable-next-line:variable-name export const SearchPrintWrapper = isVerticalNavOpenConnector(styled.div`