From fb22ba48b0474ab91ba44f712d5ba3b57de5c785 Mon Sep 17 00:00:00 2001 From: Benjamin Cabanes Date: Thu, 29 Apr 2021 12:00:21 -0400 Subject: [PATCH] feat(nxdev): Search component using Algolia (#5451) --- .circleci/config.yml | 14 +- jest.config.js | 1 + nx-dev/feature-search/.babelrc | 12 + nx-dev/feature-search/.eslintrc.json | 21 + nx-dev/feature-search/README.md | 7 + nx-dev/feature-search/jest.config.js | 9 + nx-dev/feature-search/src/index.ts | 1 + .../src/lib/algolia-search.global.css | 403 ++++++++++++++++++ .../feature-search/src/lib/algolia-search.tsx | 151 +++++++ nx-dev/feature-search/tsconfig.json | 19 + nx-dev/feature-search/tsconfig.lib.json | 14 + nx-dev/feature-search/tsconfig.spec.json | 15 + nx-dev/nx-dev/pages/_app.tsx | 3 +- nx-dev/nx-dev/pages/styles.css | 4 - nx-dev/nx-dev/styles/main.css | 13 + nx-dev/ui/common/src/lib/header.tsx | 35 +- nx.json | 3 +- package.json | 1 + tsconfig.base.json | 3 +- workspace.json | 21 + yarn.lock | 143 +++++++ 21 files changed, 845 insertions(+), 48 deletions(-) create mode 100644 nx-dev/feature-search/.babelrc create mode 100644 nx-dev/feature-search/.eslintrc.json create mode 100644 nx-dev/feature-search/README.md create mode 100644 nx-dev/feature-search/jest.config.js create mode 100644 nx-dev/feature-search/src/index.ts create mode 100644 nx-dev/feature-search/src/lib/algolia-search.global.css create mode 100644 nx-dev/feature-search/src/lib/algolia-search.tsx create mode 100644 nx-dev/feature-search/tsconfig.json create mode 100644 nx-dev/feature-search/tsconfig.lib.json create mode 100644 nx-dev/feature-search/tsconfig.spec.json delete mode 100644 nx-dev/nx-dev/pages/styles.css create mode 100644 nx-dev/nx-dev/styles/main.css diff --git a/.circleci/config.yml b/.circleci/config.yml index 10ca20f250..a1f94218df 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -25,7 +25,7 @@ commands: - checkout - when: condition: - equal: [ << parameters.os >>, windows ] + equal: [<< parameters.os >>, windows] steps: - run: nvm install 12.20 - run: nvm use 12.20 @@ -46,14 +46,14 @@ commands: - when: condition: - equal: [ << parameters.os >>, linux ] + equal: [<< parameters.os >>, linux] steps: - run: name: Install PNPM command: npm install --prefix=$HOME/.local -g pnpm@5.18.9 - when: condition: - equal: [ << parameters.os >>, windows ] + equal: [<< parameters.os >>, windows] steps: - run: name: Install PNPM @@ -100,7 +100,7 @@ jobs: default: pnpm executor: << parameters.os >> environment: - NX_CLOUD_DISTRIBUTED_EXECUTION: "true" + NX_CLOUD_DISTRIBUTED_EXECUTION: 'true' SELECTED_CLI: << parameters.cli >> NX_E2E_CI_CACHE_KEY: e2e-circleci-<< parameters.os >>-<< parameters.pm >> steps: @@ -120,7 +120,7 @@ jobs: command: yarn depcheck - run: name: Run Builds - command: npx nx affected --target=build + command: npx nx affected --target=build - run: name: Run Unit Tests command: npx nx affected --target=test @@ -147,7 +147,7 @@ jobs: default: pnpm executor: << parameters.os >> environment: - NX_CLOUD_DISTRIBUTED_EXECUTION: "true" + NX_CLOUD_DISTRIBUTED_EXECUTION: 'true' SELECTED_CLI: << parameters.cli >> NX_E2E_CI_CACHE_KEY: e2e-circleci-<< parameters.os >>-<< parameters.pm >> steps: @@ -191,4 +191,4 @@ workflows: - pr-main: filters: branches: - ignore: master \ No newline at end of file + ignore: master diff --git a/jest.config.js b/jest.config.js index a79e4eed44..52a5d31763 100644 --- a/jest.config.js +++ b/jest.config.js @@ -25,5 +25,6 @@ module.exports = { '/nx-dev/feature-doc-viewer', '/nx-dev/data-access-documents', '/nx-dev/data-access-menu', + '/nx-dev/feature-search', ], }; diff --git a/nx-dev/feature-search/.babelrc b/nx-dev/feature-search/.babelrc new file mode 100644 index 0000000000..ccae900be4 --- /dev/null +++ b/nx-dev/feature-search/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + [ + "@nrwl/react/babel", + { + "runtime": "automatic", + "useBuiltIns": "usage" + } + ] + ], + "plugins": [] +} diff --git a/nx-dev/feature-search/.eslintrc.json b/nx-dev/feature-search/.eslintrc.json new file mode 100644 index 0000000000..abfab9984c --- /dev/null +++ b/nx-dev/feature-search/.eslintrc.json @@ -0,0 +1,21 @@ +{ + "extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "parserOptions": { + "project": ["/nx-dev/feature-search/tsconfig.*?.json"] + }, + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/nx-dev/feature-search/README.md b/nx-dev/feature-search/README.md new file mode 100644 index 0000000000..4cc6aa1c66 --- /dev/null +++ b/nx-dev/feature-search/README.md @@ -0,0 +1,7 @@ +# nx-dev-feature-search + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test nx-dev-feature-search` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/nx-dev/feature-search/jest.config.js b/nx-dev/feature-search/jest.config.js new file mode 100644 index 0000000000..29c7aa2453 --- /dev/null +++ b/nx-dev/feature-search/jest.config.js @@ -0,0 +1,9 @@ +module.exports = { + displayName: 'nx-dev-feature-search', + preset: '../../jest.preset.js', + transform: { + '^.+\\.[tj]sx?$': 'babel-jest', + }, + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], + coverageDirectory: '../../coverage/nx-dev/feature-search', +}; diff --git a/nx-dev/feature-search/src/index.ts b/nx-dev/feature-search/src/index.ts new file mode 100644 index 0000000000..020b270945 --- /dev/null +++ b/nx-dev/feature-search/src/index.ts @@ -0,0 +1 @@ +export * from './lib/algolia-search'; diff --git a/nx-dev/feature-search/src/lib/algolia-search.global.css b/nx-dev/feature-search/src/lib/algolia-search.global.css new file mode 100644 index 0000000000..59dabfd686 --- /dev/null +++ b/nx-dev/feature-search/src/lib/algolia-search.global.css @@ -0,0 +1,403 @@ +.DocSearch--active { + overflow: hidden !important; +} + +.DocSearch-Container { + height: 100vh; + left: 0; + position: fixed; + top: 0; + width: 100vw; + z-index: 200; + display: flex; + flex-direction: column; + background: rgba(0, 0, 0, 0.25); + padding: 1rem; +} + +@screen sm { + .DocSearch-Container { + padding: 1.5rem; + } +} + +@screen md { + .DocSearch-Container { + padding: 10vh; + } +} + +@screen lg { + .DocSearch-Container { + padding: 12vh; + } +} + +.DocSearch-LoadingIndicator svg { + display: none; +} + +.DocSearch-LoadingIndicator { + display: none; + width: 1.5rem; + height: 1.5rem; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'%3E%3Ccircle cx='12' cy='12' r='9' stroke-width='2' stroke='%23cffafe' /%3E%3Cpath d='M3,12a9,9 0 1,0 18,0a9,9 0 1,0 -18,0' stroke-width='2' stroke='%232663eb' stroke-dasharray='56.5486677646' stroke-dashoffset='37.6991118431' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); + background-size: 100% 100%; +} + +.DocSearch-Container--Stalled .DocSearch-LoadingIndicator { + display: block; +} + +.DocSearch-Modal { + margin: 0 auto; + width: 100%; + max-width: 47.375rem; + display: flex; + flex-direction: column; + min-height: 0; + border-radius: 1rem; + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); + background: white; +} + +.DocSearch-SearchBar { + flex: none; + border-bottom: 1px solid theme('colors.gray.200'); + position: relative; + z-index: 1; + display: flex; + align-items: center; + margin: 0 1.5rem; +} + +.DocSearch-Form { + flex: auto; + display: flex; + align-items: center; + min-width: 0; +} + +.DocSearch-Dropdown { + flex: auto; + border-bottom-left-radius: 1rem; + border-bottom-right-radius: 1rem; + padding: 0 1.5rem 1.5rem; + overflow: auto; +} + +.DocSearch-MagnifierLabel { + flex: none; + width: 1.5rem; + height: 1.5rem; + background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21 21L15 15M17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10Z' stroke='%232663eb' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E%0A"); + background-size: 100%; +} + +.DocSearch-MagnifierLabel svg { + display: none; +} + +.DocSearch-Container--Stalled .DocSearch-MagnifierLabel { + display: none; +} + +.DocSearch-Input { + appearance: none; + background: transparent; + height: 4.5rem; + font-size: 1rem; + font-weight: 500; + color: black; + margin-left: 1rem; + margin-right: 1rem; + flex: auto; + min-width: 0; +} + +.DocSearch-Input:focus { + outline: 2px dotted transparent; +} + +.DocSearch-Input::-webkit-search-cancel-button, +.DocSearch-Input::-webkit-search-decoration, +.DocSearch-Input::-webkit-search-results-button, +.DocSearch-Input::-webkit-search-results-decoration { + display: none; +} + +.DocSearch-Reset { + display: none; +} + +.DocSearch-Reset::before { + content: 'esc'; +} + +.DocSearch-Cancel { + flex: none; + font-size: 0; + border-radius: 0.375rem; + background-color: theme('colors.gray.50'); + border: 1px solid theme('colors.gray.300'); + padding: 0.125rem 0.375rem; +} + +.DocSearch-Cancel::before { + content: 'esc'; + color: theme('colors.gray.400'); + font-size: 0.875rem; + line-height: 1.25rem; +} + +.DocSearch-Reset svg { + display: none; +} + +.DocSearch-Hit-source { + line-height: 1.5rem; + font-weight: bold; + color: theme('colors.gray.600'); + margin-top: 1.5rem; + margin-bottom: 1rem; +} + +.DocSearch-Hit-Container { + display: flex; + align-items: center; + height: 4rem; +} + +.DocSearch-Hit-Tree { + display: none; +} + +.DocSearch-Hit-icon { + flex: none; + margin-right: 0.875rem; +} + +.DocSearch-Hit-icon path { + stroke-width: 2px; + stroke: #71717a; +} + +.DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-icon path { + stroke: white; +} + +.DocSearch-Hit-content-wrapper { + flex: auto; + display: flex; + flex-direction: column-reverse; + min-width: 0; +} + +.DocSearch-Hit-path { + font-size: 0.75rem; + line-height: 1rem; + font-weight: 500; + color: theme('colors.gray.500'); +} + +.DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-path { + color: theme('colors.blue.200'); +} + +.DocSearch-Hit-title { + color: black; + line-height: 1.5rem; + font-weight: 600; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-title { + color: white; +} + +.DocSearch-Hit-title + .DocSearch-Hit-path { + margin-bottom: 0.125rem; +} + +.DocSearch-Hit-action { + flex: none; + margin-left: 0.875rem; +} + +.DocSearch-Hit-action-button { + display: flex; +} + +.DocSearch-Hit-action + .DocSearch-Hit-action { + margin-left: 0.5rem; +} + +.DocSearch-Hit-action path { + stroke-width: 2px; + stroke: #71717a; +} + +.DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-action path { + stroke: white; +} + +.DocSearch-Hit > a { + display: block; + background: theme('colors.gray.50'); + border-radius: 0.5rem; + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + padding: 0 1.25rem 0 1rem; +} + +.DocSearch-Hit[aria-selected='true'] > a { + background: theme('colors.blue.500'); +} + +.DocSearch-Hit + .DocSearch-Hit { + margin-top: 0.5rem; +} + +.DocSearch-Hit { + position: relative; +} + +.DocSearch-Hit--Child { + padding-left: 1.75rem; +} + +.DocSearch-Hit--Child::before, +.DocSearch-Hit--Child + .DocSearch-Hit:not(.DocSearch-Hit--Child)::before { + content: ''; + position: absolute; + top: -0.25rem; + bottom: -0.25rem; + left: 0.5rem; + width: 1.25rem; + background-image: url("data:image/svg+xml,%3Csvg width='12' height='200' viewBox='0 0 12 200' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M 1 0 V 200 M 1 100 H 12' stroke='%23a1a1aa' stroke-width='2'/%3E%3C/svg%3E%0A"); + background-repeat: no-repeat; + background-position: center left; +} + +.DocSearch-Hit--Child:last-child::before, +.DocSearch-Hit--Child + .DocSearch-Hit:not(.DocSearch-Hit--Child)::before { + background-image: url("data:image/svg+xml,%3Csvg width='12' height='200' viewBox='0 0 12 200' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M 1 0 V 89 Q 1 100 12 100' stroke='%23a1a1aa' stroke-width='2'/%3E%3C/svg%3E%0A"); +} + +.DocSearch-Hit:not(.DocSearch-Hit--Child) + .DocSearch-Hit--Child::after { + content: ''; + position: absolute; + top: -0.25rem; + left: 0; + width: 1.25rem; + height: 0.25rem; + background: #fff; +} + +.DocSearch-Hit--Child + .DocSearch-Hit:not(.DocSearch-Hit--Child)::before { + top: auto; + bottom: calc(100% + 0.25rem); + height: calc(100% + 0.25rem); + background-color: #fff; +} + +.DocSearch-Hits mark { + background: none; + color: theme('colors.blue.500'); +} + +.DocSearch-Hit[aria-selected='true'] mark { + color: inherit; + text-decoration: underline; +} + +.DocSearch-Footer { + flex: none; + display: flex; + justify-content: flex-end; + margin: 0 1.5rem; + border-top: 1px solid theme('colors.gray.200'); + padding: 1.25rem 0; +} + +.DocSearch-Commands { + display: none; +} + +.DocSearch-Logo a { + display: flex; + align-items: center; + color: #5d6494; + font-size: 0.75rem; + font-weight: 500; +} + +.DocSearch-Logo svg { + color: #5468ff; + margin-left: 0.5rem; +} + +.DocSearch-Hit--deleting, +.DocSearch-Hit--favoriting { + opacity: 0; + transition: all 250ms linear; +} + +.DocSearch-NoResults .DocSearch-Screen-Icon { + display: none; +} + +.DocSearch-Title { + font-size: theme('fontSize.lg'); + line-height: theme('lineHeight.6'); + margin-bottom: 2.5rem; +} + +.DocSearch-Title strong { + color: theme('colors.gray.900'); + font-weight: 500; +} + +.DocSearch-StartScreen, +.DocSearch-NoResults { + padding-top: 2.5rem; + padding-bottom: 1rem; +} + +.DocSearch-StartScreen .DocSearch-Help { + font-size: theme('fontSize.lg'); + line-height: theme('lineHeight.6'); +} + +.DocSearch-NoResults-Prefill-List .DocSearch-Help { + font-size: theme('fontSize.xs'); + line-height: theme('lineHeight.4'); + letter-spacing: theme('letterSpacing.wide'); + text-transform: uppercase; + font-weight: 600; + padding-bottom: 0.5rem; + border-bottom: 1px solid theme('colors.gray.200'); +} + +.DocSearch-NoResults-Prefill-List li { + padding: 0.5rem 0; + border-bottom: 1px solid theme('colors.gray.200'); +} + +.DocSearch-NoResults-Prefill-List button { + font-weight: 500; + color: theme('colors.blue.600'); +} + +.DocSearch-NoResults-Prefill-List + .DocSearch-Help { + font-size: theme('fontSize.sm'); + line-height: theme('lineHeight.5'); + margin-top: 1rem; +} + +.DocSearch-NoResults-Prefill-List + .DocSearch-Help a { + box-shadow: theme('boxShadow.sm'); + color: theme('colors.blue.700'); + font-weight: 500; +} diff --git a/nx-dev/feature-search/src/lib/algolia-search.tsx b/nx-dev/feature-search/src/lib/algolia-search.tsx new file mode 100644 index 0000000000..2c7678a233 --- /dev/null +++ b/nx-dev/feature-search/src/lib/algolia-search.tsx @@ -0,0 +1,151 @@ +import { useState, useCallback, useRef, useEffect } from 'react'; +import { createPortal } from 'react-dom'; +import Link from 'next/link'; +import Head from 'next/head'; +import { useRouter } from 'next/router'; +import { DocSearchModal, useDocSearchKeyboardEvents } from '@docsearch/react'; + +const ACTION_KEY_DEFAULT = ['Ctrl ', 'Control']; +const ACTION_KEY_APPLE = ['⌘', 'Command']; + +function Hit({ hit, children }) { + return ( + + {children} + + ); +} + +export function AlgoliaSearch() { + const frameworkFilter = `framework:react`; // TODO: @ben Tap into current framework selection + const versionFilter = `version:latest`; // TODO: @ben Tap into current version selection + + const router = useRouter(); + const [isOpen, setIsOpen] = useState(false); + const searchButtonRef = useRef(); + const [initialQuery, setInitialQuery] = useState(null); + const [browserDetected, setBrowserDetected] = useState(false); + const [actionKey, setActionKey] = useState(ACTION_KEY_DEFAULT); + + const handleOpen = useCallback(() => { + setIsOpen(true); + }, [setIsOpen]); + const handleClose = useCallback(() => { + setIsOpen(false); + }, [setIsOpen]); + + const handleInput = useCallback( + (e) => { + setIsOpen(true); + setInitialQuery(e.key); + }, + [setIsOpen, setInitialQuery] + ); + + useDocSearchKeyboardEvents({ + isOpen, + onOpen: handleOpen, + onClose: handleClose, + onInput: handleInput, + searchButtonRef, + }); + + useEffect(() => { + if (typeof navigator !== 'undefined') { + if (/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)) { + setActionKey(ACTION_KEY_APPLE); + } else { + setActionKey(ACTION_KEY_DEFAULT); + } + setBrowserDetected(true); + } + }, []); + + return ( + <> + + + + + {isOpen && + createPortal( + { + return items.map((item) => { + // We transform the absolute URL into a relative URL to + // leverage Next's preloading. + const a = document.createElement('a'); + a.href = item.url; + + const hash = a.hash === '#content-wrapper' ? '' : a.hash; + + return { + ...item, + url: `${a.pathname}${hash}`, + }; + }); + }} + />, + document.body + )} + + ); +} diff --git a/nx-dev/feature-search/tsconfig.json b/nx-dev/feature-search/tsconfig.json new file mode 100644 index 0000000000..37ab84bcdb --- /dev/null +++ b/nx-dev/feature-search/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "jsx": "react-jsx", + "allowJs": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/nx-dev/feature-search/tsconfig.lib.json b/nx-dev/feature-search/tsconfig.lib.json new file mode 100644 index 0000000000..29ad381b67 --- /dev/null +++ b/nx-dev/feature-search/tsconfig.lib.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": ["node"], + "lib": ["dom"] + }, + "files": [ + "../../node_modules/@nrwl/react/typings/cssmodule.d.ts", + "../../node_modules/@nrwl/react/typings/image.d.ts" + ], + "exclude": ["**/*.spec.ts", "**/*.spec.tsx"], + "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] +} diff --git a/nx-dev/feature-search/tsconfig.spec.json b/nx-dev/feature-search/tsconfig.spec.json new file mode 100644 index 0000000000..559410b96a --- /dev/null +++ b/nx-dev/feature-search/tsconfig.spec.json @@ -0,0 +1,15 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "**/*.spec.ts", + "**/*.spec.tsx", + "**/*.spec.js", + "**/*.spec.jsx", + "**/*.d.ts" + ] +} diff --git a/nx-dev/nx-dev/pages/_app.tsx b/nx-dev/nx-dev/pages/_app.tsx index 1caf6cd827..2ea88e8bc9 100644 --- a/nx-dev/nx-dev/pages/_app.tsx +++ b/nx-dev/nx-dev/pages/_app.tsx @@ -2,8 +2,7 @@ import React from 'react'; import { AppProps } from 'next/app'; import Head from 'next/head'; import { Header, Footer } from '@nrwl/nx-dev/ui/common'; -import 'tailwindcss/tailwind.css'; -import './styles.css'; +import '../styles/main.css'; export default function CustomApp({ Component, pageProps }: AppProps) { return ( diff --git a/nx-dev/nx-dev/pages/styles.css b/nx-dev/nx-dev/pages/styles.css deleted file mode 100644 index c1bf04bf4e..0000000000 --- a/nx-dev/nx-dev/pages/styles.css +++ /dev/null @@ -1,4 +0,0 @@ -svg { - shape-rendering: crispEdges; - text-rendering: optimizeLegibility; -} diff --git a/nx-dev/nx-dev/styles/main.css b/nx-dev/nx-dev/styles/main.css new file mode 100644 index 0000000000..3037970ce4 --- /dev/null +++ b/nx-dev/nx-dev/styles/main.css @@ -0,0 +1,13 @@ +@tailwind base; + +/*! purgecss start ignore */ +@import 'nx-dev/feature-search/src/lib/algolia-search.global.css'; +/*! purgecss end ignore */ + +@tailwind components; +@tailwind utilities; + +svg { + shape-rendering: crispEdges; + text-rendering: optimizeLegibility; +} diff --git a/nx-dev/ui/common/src/lib/header.tsx b/nx-dev/ui/common/src/lib/header.tsx index aa36e4d575..b2ff1f0b79 100644 --- a/nx-dev/ui/common/src/lib/header.tsx +++ b/nx-dev/ui/common/src/lib/header.tsx @@ -1,5 +1,6 @@ import React from 'react'; import Link from 'next/link'; +import { AlgoliaSearch } from '@nrwl/nx-dev/feature-search'; /* eslint-disable-next-line */ export interface headerProps {} @@ -46,39 +47,7 @@ export function Header(props: headerProps) { {/*SEARCH*/} - + {/*NAVIGATION*/}