feat(v4): add new UI (#2555)
* feat: add new footer ui * feat: add new search box ui * feat: add searchbox actions * feat: add start screen * feat: add no results screen * feat: add new card ui * feat: add new icons * feat: add new key press class * fix: cypress tests * fix: circleci * fix: circleci * fix: close aria label * fix: circleci * fix: remove unused classes * fix: circleci * feat: update version * feat: add new dark mode ui * fix: colors * fix: design review * fix: hit title length * fix: improve accessibility * fix: ci * chore: increase bundle size threshold * fix: css
This commit is contained in:
parent
ec351710b1
commit
6a160aecf6
24 changed files with 434 additions and 302 deletions
|
|
@ -2,7 +2,7 @@
|
|||
"files": [
|
||||
{
|
||||
"path": "packages/docsearch-css/dist/style.css",
|
||||
"maxSize": "3.25 kB"
|
||||
"maxSize": "3.50 kB"
|
||||
},
|
||||
{
|
||||
"path": "packages/docsearch-react/dist/umd/index.js",
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ describe('Start', () => {
|
|||
|
||||
// check that the scrollbar offset is compensated
|
||||
cy.get('body').should('have.css', 'overflow', 'hidden');
|
||||
cy.get('body').should('have.css', 'margin-right', '15px');
|
||||
cy.get('.DocSearch-Modal').should('be.visible');
|
||||
});
|
||||
|
||||
it('Open modal with key shortcut on Windows/Linux', () => {
|
||||
|
|
@ -53,7 +53,7 @@ describe('End', () => {
|
|||
});
|
||||
|
||||
it('Close modal by clicking outside its container', () => {
|
||||
cy.get('.DocSearch-Container').click();
|
||||
cy.get('body').click(0, 0);
|
||||
cy.modalIsNotVisible();
|
||||
});
|
||||
|
||||
|
|
@ -81,7 +81,7 @@ describe('Search', () => {
|
|||
|
||||
it('Query can be cleared', () => {
|
||||
cy.typeQueryMatching();
|
||||
cy.get('.DocSearch-Reset').click();
|
||||
cy.get('.DocSearch-Clear').click();
|
||||
cy.get('.DocSearch-Hits').should('not.exist');
|
||||
cy.contains('No recent searches').should('be.visible');
|
||||
});
|
||||
|
|
@ -101,7 +101,9 @@ describe('Search', () => {
|
|||
const currentURL = cy.url();
|
||||
|
||||
cy.typeQueryMatching();
|
||||
cy.get('.DocSearch-Hits #docsearch-hits0-item-1 > a').click({ force: true });
|
||||
cy.get('.DocSearch-Hits #docsearch-hits0-item-1 > a').click({
|
||||
force: true,
|
||||
});
|
||||
cy.on('url:changed', (newUrl) => {
|
||||
expect(newUrl).not.equal(currentURL);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,16 +1,14 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>DocSearch v4 - React</title>
|
||||
</head>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>DocSearch v3 - React</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import '@docsearch/css/dist/style.css';
|
|||
function App(): React.JSX.Element {
|
||||
return (
|
||||
<div>
|
||||
<h1>DocSearch v3 - React - 18</h1>
|
||||
<h1>DocSearch v4 - React - 18</h1>
|
||||
<DocSearch indexName="vuejs" appId="ML0LEBN7FQ" apiKey="21cf9df0734770a2448a9da64a700c22" insights={true} />
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,16 +1,14 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>DocSearch v4 - React</title>
|
||||
</head>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>DocSearch v3 - React</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import '@docsearch/css/dist/style.css';
|
|||
function App(): JSX.Element {
|
||||
return (
|
||||
<div>
|
||||
<h1>DocSearch v3 - React</h1>
|
||||
<h1>DocSearch v4 - React</h1>
|
||||
<DocSearch indexName="vuejs" appId="ML0LEBN7FQ" apiKey="21cf9df0734770a2448a9da64a700c22" insights={true} />
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,17 +1,23 @@
|
|||
/* Variables */
|
||||
|
||||
:root {
|
||||
--docsearch-primary-color: rgb(84, 104, 255);
|
||||
--docsearch-text-color: rgb(28, 30, 33);
|
||||
--docsearch-primary-color: rgb(0, 61, 255);
|
||||
--docsearch-subtle-color: rgb(214, 214, 231);
|
||||
--docsearch-text-color: rgba(35, 38, 59, 1);
|
||||
--docsearch-secondary-text-color: rgba(90, 94, 154, 1);
|
||||
--docsearch-background-color: rgb(245, 245, 250);
|
||||
--docsearch-spacing: 12px;
|
||||
--docsearch-icon-stroke-width: 1.4;
|
||||
--docsearch-highlight-color: var(--docsearch-primary-color);
|
||||
--docsearch-muted-color: rgb(150, 159, 175);
|
||||
--docsearch-focus-color: rgb(0, 95, 204);
|
||||
--docsearch-highlight-color: rgb(0, 61, 255);
|
||||
--docsearch-muted-color: rgba(150, 152, 195, 1);
|
||||
--docsearch-muted-color-darker: rgba(120, 122, 165, 0.25);
|
||||
--docsearch-icon-color: rgba(90, 94, 154, 1);
|
||||
--docsearch-container-background: rgba(101, 108, 133, 0.8);
|
||||
--docsearch-logo-color: rgba(84, 104, 255);
|
||||
--docsearch-logo-color: rgba(0, 61, 255, 1);
|
||||
|
||||
/* modal */
|
||||
--docsearch-modal-width: 560px;
|
||||
--docsearch-modal-width: 800px;
|
||||
--docsearch-modal-height: 600px;
|
||||
--docsearch-modal-background: rgb(245, 246, 247);
|
||||
--docsearch-modal-shadow: inset 1px 1px 0 0 rgba(255, 255, 255, 0.5),
|
||||
|
|
@ -19,30 +25,24 @@
|
|||
|
||||
/* searchbox */
|
||||
--docsearch-searchbox-height: 56px;
|
||||
--docsearch-searchbox-background: rgb(235, 237, 240);
|
||||
--docsearch-searchbox-background: #fff;
|
||||
--docsearch-searchbox-focus-background: #fff;
|
||||
--docsearch-searchbox-shadow: inset 0 0 0 2px var(--docsearch-primary-color);
|
||||
--docsearch-actions-width: 99px;
|
||||
--docsearch-actions-height: 44px;
|
||||
|
||||
/* hit */
|
||||
--docsearch-hit-height: 56px;
|
||||
--docsearch-hit-color: rgb(68, 73, 80);
|
||||
--docsearch-hit-active-color: #fff;
|
||||
--docsearch-hit-highlight-color: rgba(0, 61, 255, 0.1);
|
||||
--docsearch-hit-background: #fff;
|
||||
--docsearch-hit-shadow: 0 1px 3px 0 rgb(212, 217, 225);
|
||||
|
||||
/* key */
|
||||
--docsearch-key-gradient: linear-gradient(
|
||||
-225deg,
|
||||
rgb(213, 219, 228) 0%,
|
||||
rgb(248, 248, 248) 100%
|
||||
);
|
||||
--docsearch-key-shadow: inset 0 -2px 0 0 rgb(205, 205, 230),
|
||||
inset 0 0 1px 1px #fff, 0 1px 2px 1px rgba(30, 35, 90, 0.4);
|
||||
--docsearch-key-pressed-shadow: inset 0 -2px 0 0 #cdcde6,
|
||||
inset 0 0 1px 1px #fff, 0 1px 1px 0 rgba(30, 35, 90, 0.4);
|
||||
--docsearch-key-background: rgb(245, 245, 250);
|
||||
--docsearch-key-color: rgba(90, 94, 154, 1);
|
||||
--docsearch-key-pressed-shadow: inset 0 2px 4px rgba(120, 122, 165, 0.25);
|
||||
|
||||
/* footer */
|
||||
--docsearch-footer-height: 44px;
|
||||
--docsearch-footer-height: 52px;
|
||||
--docsearch-footer-background: #fff;
|
||||
--docsearch-footer-shadow: 0 -1px 0 0 rgb(224, 227, 232),
|
||||
0 -3px 6px 0 rgba(69, 98, 155, 0.12);
|
||||
|
|
@ -51,7 +51,13 @@
|
|||
/* Darkmode */
|
||||
|
||||
html[data-theme='dark'] {
|
||||
--docsearch-text-color: rgb(245, 246, 247);
|
||||
--docsearch-text-color: rgba(196, 199, 220, 1);
|
||||
--docsearch-secondary-text-color: rgba(182, 183, 213, 1);
|
||||
--docsearch-subtle-color: rgba(33, 33, 57, 1);
|
||||
--docsearch-highlight-color: rgba(69, 122, 255, 1);
|
||||
--docsearch-focus-color: rgb(154, 200, 255);
|
||||
--docsearch-background-color: rgba(54, 57, 90, 1);
|
||||
--docsearch-icon-color: rgba(182, 183, 213, 1);
|
||||
--docsearch-container-background: rgba(9, 10, 17, 0.8);
|
||||
--docsearch-modal-background: rgb(21, 23, 42);
|
||||
--docsearch-modal-shadow: inset 1px 1px 0 0 rgb(44, 46, 64),
|
||||
|
|
@ -61,16 +67,10 @@ html[data-theme='dark'] {
|
|||
--docsearch-hit-color: rgb(190, 195, 201);
|
||||
--docsearch-hit-shadow: none;
|
||||
--docsearch-hit-background: rgb(9, 10, 17);
|
||||
--docsearch-key-gradient: linear-gradient(
|
||||
-26.5deg,
|
||||
rgb(86, 88, 114) 0%,
|
||||
rgb(49, 53, 91) 100%
|
||||
);
|
||||
--docsearch-key-shadow: inset 0 -2px 0 0 rgb(40, 45, 85),
|
||||
inset 0 0 1px 1px rgb(81, 87, 125), 0 2px 2px 0 rgba(3, 4, 9, 0.3);
|
||||
--docsearch-key-pressed-shadow: inset 0 -2px 0 0 #282d55,
|
||||
inset 0 0 1px 1px #51577d, 0 1px 1px 0 #0304094d;
|
||||
--docsearch-footer-background: rgb(30, 33, 54);
|
||||
--docsearch-key-background: rgba(54, 57, 90, 1);
|
||||
--docsearch-key-color: rgba(182, 183, 213, 1);
|
||||
--docsearch-key-pressed-shadow: inset 0 2px 4px rgba(12, 13, 20, 0.4);
|
||||
--docsearch-footer-background: rgba(13, 13, 13, 1);
|
||||
--docsearch-footer-shadow: inset 0 1px 0 0 rgba(73, 76, 106, 0.5),
|
||||
0 -4px 8px 0 rgba(0, 0, 0, 0.2);
|
||||
--docsearch-logo-color: rgb(255, 255, 255);
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
.DocSearch-Button {
|
||||
align-items: center;
|
||||
background: var(--docsearch-searchbox-background);
|
||||
border: 0;
|
||||
border-radius: 40px;
|
||||
border: 1px solid var(--docsearch-subtle-color);
|
||||
border-radius: 4px;
|
||||
background-color: var(--docsearch-searchbox-background);
|
||||
color: var(--docsearch-muted-color);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
font-weight: 500;
|
||||
font-weight: 300;
|
||||
width: 286px;
|
||||
height: 36px;
|
||||
justify-content: space-between;
|
||||
margin: 0 0 0 16px;
|
||||
|
|
@ -14,31 +15,27 @@
|
|||
user-select: none;
|
||||
}
|
||||
|
||||
.DocSearch-Button:hover,
|
||||
.DocSearch-Button:active,
|
||||
.DocSearch-Button:focus {
|
||||
background: var(--docsearch-searchbox-focus-background);
|
||||
box-shadow: var(--docsearch-searchbox-shadow);
|
||||
color: var(--docsearch-text-color);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.DocSearch-Button-Container {
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.DocSearch-Button-Container svg {
|
||||
color: var(--docsearch-highlight-color);
|
||||
}
|
||||
|
||||
.DocSearch-Search-Icon {
|
||||
color: var(--docsearch-highlight-color);
|
||||
stroke-width: 1.6;
|
||||
}
|
||||
|
||||
.DocSearch-Button .DocSearch-Search-Icon {
|
||||
color: var(--docsearch-text-color);
|
||||
}
|
||||
|
||||
.DocSearch-Button-Placeholder {
|
||||
font-size: 1rem;
|
||||
padding: 0 12px 0 6px;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 300;
|
||||
padding: 0 12px 0 8px;
|
||||
display: inline-block;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.DocSearch-Button-Keys {
|
||||
|
|
@ -48,36 +45,42 @@
|
|||
|
||||
.DocSearch-Button-Key {
|
||||
align-items: center;
|
||||
background: var(--docsearch-key-gradient);
|
||||
border-radius: 3px;
|
||||
box-shadow: var(--docsearch-key-shadow);
|
||||
color: var(--docsearch-muted-color);
|
||||
background: var(--docsearch-key-background);
|
||||
border-radius: 2px;
|
||||
color: var(--docsearch-key-color);
|
||||
box-shadow: none !important;
|
||||
display: flex;
|
||||
height: 18px;
|
||||
height: 24px;
|
||||
font-size: 20px;
|
||||
justify-content: center;
|
||||
margin-right: 0.4em;
|
||||
position: relative;
|
||||
padding: 0 0 2px;
|
||||
border: 0;
|
||||
top: -1px;
|
||||
width: 20px;
|
||||
width: 24px;
|
||||
transition-property: all;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-duration: 100ms;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion) {
|
||||
.DocSearch-Button-Key:first-child {
|
||||
margin-right: 0.4em;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion) {
|
||||
.DocSearch-Button-Key {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
.DocSearch-Button-Key--pressed {
|
||||
transform: translate3d(0, 1px, 0);
|
||||
box-shadow: var(--docsearch-key-pressed-shadow);
|
||||
transform: translateY(1px);
|
||||
box-shadow: var(--docsearch-key-pressed-shadow) !important;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.DocSearch-Button {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.DocSearch-Button-Keys,
|
||||
.DocSearch-Button-Placeholder {
|
||||
display: none;
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
.DocSearch-Modal {
|
||||
background: var(--docsearch-modal-background);
|
||||
border-radius: 6px;
|
||||
border-radius: 4px;
|
||||
box-shadow: var(--docsearch-modal-shadow);
|
||||
flex-direction: column;
|
||||
margin: 60px auto auto;
|
||||
|
|
@ -54,18 +54,21 @@
|
|||
|
||||
.DocSearch-SearchBar {
|
||||
display: flex;
|
||||
padding: var(--docsearch-spacing) var(--docsearch-spacing) 0;
|
||||
}
|
||||
|
||||
.DocSearch-SearchBar-Magnifier {
|
||||
color: var(--docsearch-highlight-color);
|
||||
}
|
||||
|
||||
.DocSearch-Form {
|
||||
align-items: center;
|
||||
background: var(--docsearch-searchbox-focus-background);
|
||||
border-radius: 4px;
|
||||
box-shadow: var(--docsearch-searchbox-shadow);
|
||||
border-bottom: 1px solid var(--docsearch-subtle-color);
|
||||
border-radius: 4px 4px 0 0;
|
||||
display: flex;
|
||||
height: var(--docsearch-searchbox-height);
|
||||
margin: 0;
|
||||
padding: 0 var(--docsearch-spacing);
|
||||
padding: var(--docsearch-spacing) 16px;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
|
@ -78,6 +81,7 @@
|
|||
flex: 1;
|
||||
font: inherit;
|
||||
font-size: 1.2em;
|
||||
font-weight: 300;
|
||||
height: 100%;
|
||||
outline: none;
|
||||
padding: 0 0 0 8px;
|
||||
|
|
@ -96,17 +100,32 @@
|
|||
display: none;
|
||||
}
|
||||
|
||||
.DocSearch-Actions {
|
||||
width: var(--docsearch-actions-width);
|
||||
height: var(--docsearch-actions-height);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding: 0 2px;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.DocSearch-Divider {
|
||||
height: 24px;
|
||||
border-left: 1px solid var(--docsearch-subtle-color);
|
||||
}
|
||||
|
||||
.DocSearch-LoadingIndicator,
|
||||
.DocSearch-MagnifierLabel,
|
||||
.DocSearch-Reset {
|
||||
.DocSearch-Close {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.DocSearch-MagnifierLabel,
|
||||
.DocSearch-Reset {
|
||||
.DocSearch-Close {
|
||||
align-items: center;
|
||||
color: var(--docsearch-highlight-color);
|
||||
color: var(--docsearch-highlight-color) !important;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
|
@ -127,7 +146,7 @@
|
|||
}
|
||||
|
||||
@media screen and (prefers-reduced-motion: reduce) {
|
||||
.DocSearch-Reset {
|
||||
.DocSearch-Close {
|
||||
animation: none;
|
||||
appearance: none;
|
||||
background: none;
|
||||
|
|
@ -140,7 +159,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.DocSearch-Reset {
|
||||
.DocSearch-Close {
|
||||
animation: fade-in 0.1s ease-in forwards;
|
||||
appearance: none;
|
||||
background: none;
|
||||
|
|
@ -153,28 +172,51 @@
|
|||
stroke-width: var(--docsearch-icon-stroke-width);
|
||||
}
|
||||
|
||||
.DocSearch-Reset[hidden] {
|
||||
.DocSearch-Close[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.DocSearch-Reset:hover {
|
||||
.DocSearch-Close:hover {
|
||||
color: var(--docsearch-highlight-color);
|
||||
}
|
||||
|
||||
.DocSearch-LoadingIndicator svg,
|
||||
.DocSearch-MagnifierLabel svg {
|
||||
color: var(--docsearch-highlight-color) !important;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
.DocSearch-Cancel {
|
||||
display: none;
|
||||
.DocSearch-Clear {
|
||||
appearance: none;
|
||||
background: none;
|
||||
border: 0;
|
||||
color: var(--docsearch-highlight-color);
|
||||
cursor: pointer;
|
||||
flex: none;
|
||||
font: inherit;
|
||||
font-size: 0.9em;
|
||||
font-weight: 300;
|
||||
height: 28px;
|
||||
margin-left: var(--docsearch-spacing);
|
||||
outline: none;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
user-select: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.DocSearch-Close:focus-visible,
|
||||
.DocSearch-Clear:focus-visible {
|
||||
outline: 2px solid var(--docsearch-focus-color);
|
||||
outline-offset: 1px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* Modal Dropdown */
|
||||
|
||||
.DocSearch-Dropdown {
|
||||
max-height: calc(
|
||||
height: calc(
|
||||
var(--docsearch-modal-height) - var(--docsearch-searchbox-height) -
|
||||
var(--docsearch-spacing) - var(--docsearch-footer-height)
|
||||
);
|
||||
|
|
@ -208,20 +250,40 @@
|
|||
}
|
||||
|
||||
.DocSearch-Label {
|
||||
color: var(--docsearch-muted-color);
|
||||
font-size: 0.75em;
|
||||
color: var(--docsearch-secondary-text-color);
|
||||
font-size: 0.875em;
|
||||
line-height: 1.6em;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.DocSearch-NoResults-Help {
|
||||
color: var(--docsearch-secondary-text-color);
|
||||
font-size: 0.8em;
|
||||
margin: 0;
|
||||
user-select: none;
|
||||
line-height: 1.5em;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.DocSearch-Help {
|
||||
color: var(--docsearch-muted-color);
|
||||
font-size: 0.9em;
|
||||
color: var(--docsearch-secondary-text-color);
|
||||
font-size: 0.8em;
|
||||
margin: 0;
|
||||
user-select: none;
|
||||
line-height: 1.5em;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.DocSearch-Title {
|
||||
font-size: 1.2em;
|
||||
color: var(--docsearch-text-color);
|
||||
vertical-align: middle;
|
||||
font-size: 1.1em;
|
||||
line-height: 0.5em;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.DocSearch-Title strong {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.DocSearch-Logo a {
|
||||
|
|
@ -293,7 +355,6 @@
|
|||
.DocSearch-Hit a {
|
||||
background: var(--docsearch-hit-background);
|
||||
border-radius: 4px;
|
||||
box-shadow: var(--docsearch-hit-shadow);
|
||||
display: block;
|
||||
padding-left: var(--docsearch-spacing);
|
||||
width: 100%;
|
||||
|
|
@ -301,12 +362,12 @@
|
|||
|
||||
.DocSearch-Hit-source {
|
||||
background: var(--docsearch-modal-background);
|
||||
color: var(--docsearch-highlight-color);
|
||||
font-size: 0.85em;
|
||||
color: var(--docsearch-text-color);
|
||||
font-size: 0.9em;
|
||||
font-weight: 600;
|
||||
line-height: 32px;
|
||||
margin: 0 -4px;
|
||||
padding: 8px 4px 0;
|
||||
padding: 8px 4px 4px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
|
|
@ -321,16 +382,17 @@
|
|||
}
|
||||
|
||||
.DocSearch-Hit[aria-selected='true'] a {
|
||||
background-color: var(--docsearch-highlight-color);
|
||||
background-color: var(--docsearch-hit-highlight-color) !important;
|
||||
}
|
||||
|
||||
.DocSearch-Hit[aria-selected='true'] mark {
|
||||
.DocSearch-Hit mark {
|
||||
color: var(--docsearch-highlight-color);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.DocSearch-Hit-Container {
|
||||
align-items: center;
|
||||
color: var(--docsearch-hit-color);
|
||||
color: var(--docsearch-text-color);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: var(--docsearch-hit-height);
|
||||
|
|
@ -338,7 +400,7 @@
|
|||
}
|
||||
|
||||
.DocSearch-Hit-icon {
|
||||
color: var(--docsearch-muted-color);
|
||||
color: var(--docsearch-secondary-text-color);
|
||||
height: 20px;
|
||||
stroke-width: var(--docsearch-icon-stroke-width);
|
||||
width: 20px;
|
||||
|
|
@ -395,13 +457,6 @@ svg.DocSearch-Hit-Select-Icon {
|
|||
transition: background-color 0.1s ease-in;
|
||||
}
|
||||
|
||||
@media screen and (prefers-reduced-motion: reduce) {
|
||||
.DocSearch-Hit-action-button:hover,
|
||||
.DocSearch-Hit-action-button:focus {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
.DocSearch-Hit-action-button:hover path,
|
||||
.DocSearch-Hit-action-button:focus path {
|
||||
fill: #fff;
|
||||
|
|
@ -420,6 +475,7 @@ svg.DocSearch-Hit-Select-Icon {
|
|||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: 80%;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.DocSearch-Hit-title {
|
||||
|
|
@ -427,18 +483,20 @@ svg.DocSearch-Hit-Select-Icon {
|
|||
}
|
||||
|
||||
.DocSearch-Hit-path {
|
||||
color: var(--docsearch-muted-color);
|
||||
color: var(--docsearch-secondary-text-color);
|
||||
font-size: 0.75em;
|
||||
}
|
||||
|
||||
.DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-title,
|
||||
.DocSearch-Hit[aria-selected='true'] mark,
|
||||
.DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-text,
|
||||
.DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-path,
|
||||
.DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-icon,
|
||||
.DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-action,
|
||||
.DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-Tree {
|
||||
color: var(--docsearch-hit-active-color) !important;
|
||||
color: var(--docsearch-text-color) !important;
|
||||
}
|
||||
|
||||
.DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-action,
|
||||
.DocSearch-Hit[aria-selected='true'] mark,
|
||||
.DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-icon {
|
||||
color: var(--docsearch-highlight-color) !important;
|
||||
}
|
||||
|
||||
@media screen and (prefers-reduced-motion: reduce) {
|
||||
|
|
@ -454,32 +512,64 @@ svg.DocSearch-Hit-Select-Icon {
|
|||
.DocSearch-NoResults,
|
||||
.DocSearch-StartScreen,
|
||||
.DocSearch-ErrorScreen {
|
||||
font-size: 0.9em;
|
||||
font-size: 1.25em;
|
||||
font-weight: 400;
|
||||
margin: 0 auto;
|
||||
padding: 36px 0;
|
||||
color: var(--docsearch-secondary-text-color);
|
||||
text-align: center;
|
||||
width: 80%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.DocSearch-NoResults,
|
||||
.DocSearch-ErrorScreen {
|
||||
height: 80%;
|
||||
}
|
||||
|
||||
.DocSearch-StartScreen {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.DocSearch-NoResults {
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.DocSearch-StartScreen,
|
||||
.DocSearch-ErrorScreen {
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.DocSearch-StartScreen-Icon {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
stroke: var(--docsearch-icon-color);
|
||||
}
|
||||
|
||||
.DocSearch-Screen-Icon {
|
||||
color: var(--docsearch-muted-color);
|
||||
padding-bottom: 12px;
|
||||
color: var(--docsearch-icon-color);
|
||||
}
|
||||
|
||||
.DocSearch-NoResults-Prefill-List {
|
||||
display: inline-block;
|
||||
padding-bottom: 24px;
|
||||
text-align: left;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.DocSearch-NoResults-Prefill-List ul {
|
||||
display: inline-block;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
height: 40px;
|
||||
padding: 8px 0 0;
|
||||
}
|
||||
|
||||
.DocSearch-NoResults-Prefill-List li {
|
||||
list-style-position: inside;
|
||||
list-style-type: '» ';
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.DocSearch-Prefill {
|
||||
|
|
@ -489,10 +579,13 @@ svg.DocSearch-Hit-Select-Icon {
|
|||
border-radius: 1em;
|
||||
color: var(--docsearch-highlight-color);
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-size: 1em;
|
||||
font-weight: 700;
|
||||
padding: 0;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
height: 40px;
|
||||
font-size: 0.8em;
|
||||
font-weight: 300;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.DocSearch-Prefill:hover,
|
||||
|
|
@ -506,8 +599,8 @@ svg.DocSearch-Hit-Select-Icon {
|
|||
.DocSearch-Footer {
|
||||
align-items: center;
|
||||
background: var(--docsearch-footer-background);
|
||||
border-radius: 0 0 8px 8px;
|
||||
box-shadow: var(--docsearch-footer-shadow);
|
||||
border-top: 1px solid var(--docsearch-subtle-color);
|
||||
border-radius: 0 0 4px 4px;
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
flex-shrink: 0;
|
||||
|
|
@ -526,6 +619,7 @@ svg.DocSearch-Hit-Select-Icon {
|
|||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.DocSearch-Commands li {
|
||||
|
|
@ -533,23 +627,31 @@ svg.DocSearch-Hit-Select-Icon {
|
|||
display: flex;
|
||||
}
|
||||
|
||||
.DocSearch-Commands li:not(:last-of-type) {
|
||||
margin-right: 0.8em;
|
||||
}
|
||||
|
||||
.DocSearch-Commands-Key {
|
||||
align-items: center;
|
||||
background: var(--docsearch-key-gradient);
|
||||
border-radius: 2px;
|
||||
box-shadow: var(--docsearch-key-shadow);
|
||||
background-color: var(--docsearch-background-color);
|
||||
display: flex;
|
||||
height: 18px;
|
||||
height: 24px;
|
||||
justify-content: center;
|
||||
margin-right: 0.4em;
|
||||
padding: 0 0 1px;
|
||||
color: var(--docsearch-muted-color);
|
||||
margin-right: 4px;
|
||||
color: var(--docsearch-icon-color);
|
||||
border: 0;
|
||||
width: 20px;
|
||||
width: 24px;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.DocSearch-Commands-Key:last-of-type {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.DocSearch-Escape-Key {
|
||||
font-weight: 300;
|
||||
font-size: 10px;
|
||||
line-height: 16px;
|
||||
letter-spacing: normal;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* Hide element accessibly, so that it is still accessible to
|
||||
|
|
@ -568,7 +670,7 @@ assistive tech users */
|
|||
@media (max-width: 768px) {
|
||||
:root {
|
||||
--docsearch-spacing: 10px;
|
||||
--docsearch-footer-height: 40px;
|
||||
--docsearch-footer-height: 48px;
|
||||
}
|
||||
|
||||
.DocSearch-Dropdown {
|
||||
|
|
@ -612,25 +714,6 @@ assistive tech users */
|
|||
);
|
||||
}
|
||||
|
||||
.DocSearch-Cancel {
|
||||
appearance: none;
|
||||
background: none;
|
||||
border: 0;
|
||||
color: var(--docsearch-highlight-color);
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
flex: none;
|
||||
font: inherit;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
margin-left: var(--docsearch-spacing);
|
||||
outline: none;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
user-select: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.DocSearch-Commands {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import React, { type JSX } from 'react';
|
||||
|
||||
type AlgoliaLogoTranslations = Partial<{
|
||||
searchByText: string;
|
||||
poweredByText: string;
|
||||
}>;
|
||||
|
||||
type AlgoliaLogoProps = {
|
||||
|
|
@ -9,7 +9,7 @@ type AlgoliaLogoProps = {
|
|||
};
|
||||
|
||||
export function AlgoliaLogo({ translations = {} }: AlgoliaLogoProps): JSX.Element {
|
||||
const { searchByText = 'Search by' } = translations;
|
||||
const { poweredByText = 'Powered by' } = translations;
|
||||
|
||||
return (
|
||||
<a
|
||||
|
|
@ -17,10 +17,10 @@ export function AlgoliaLogo({ translations = {} }: AlgoliaLogoProps): JSX.Elemen
|
|||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<span className="DocSearch-Label">{searchByText}</span>
|
||||
<span className="DocSearch-Label">{poweredByText}</span>
|
||||
<svg
|
||||
width="77"
|
||||
height="19"
|
||||
height="24"
|
||||
aria-label="Algolia"
|
||||
role="img"
|
||||
id="Layer_1"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React, { type JSX, useEffect, useState } from 'react';
|
||||
|
||||
import { ControlKeyIcon } from './icons/ControlKeyIcon';
|
||||
import { MetaKeyIcon } from './icons/MetaKeyIcon';
|
||||
import { SearchIcon } from './icons/SearchIcon';
|
||||
|
||||
export type ButtonTranslations = Partial<{
|
||||
|
|
@ -35,7 +36,8 @@ export const DocSearchButton = React.forwardRef<HTMLButtonElement, DocSearchButt
|
|||
key === ACTION_KEY_DEFAULT
|
||||
? // eslint-disable-next-line react/jsx-key -- false flag
|
||||
([ACTION_KEY_DEFAULT, 'Ctrl', <ControlKeyIcon />] as const)
|
||||
: (['Meta', 'Command', key] as const);
|
||||
: // eslint-disable-next-line react/jsx-key
|
||||
(['Meta', 'Command', <MetaKeyIcon />] as const);
|
||||
|
||||
return (
|
||||
<button
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ export function DocSearchModal({
|
|||
const formElementRef = React.useRef<HTMLDivElement | null>(null);
|
||||
const dropdownRef = React.useRef<HTMLDivElement | null>(null);
|
||||
const inputRef = React.useRef<HTMLInputElement | null>(null);
|
||||
const snippetLength = React.useRef<number>(10);
|
||||
const snippetLength = React.useRef<number>(15);
|
||||
const initialQueryFromSelection = React.useRef(
|
||||
typeof window !== 'undefined' ? window.getSelection()!.toString().slice(0, MAX_QUERY_SIZE) : '',
|
||||
).current;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ export type FooterTranslations = Partial<{
|
|||
navigateDownKeyAriaLabel: string;
|
||||
closeText: string;
|
||||
closeKeyAriaLabel: string;
|
||||
searchByText: string;
|
||||
poweredByText: string;
|
||||
}>;
|
||||
|
||||
type FooterProps = Partial<{
|
||||
|
|
@ -24,8 +24,8 @@ interface CommandIconProps {
|
|||
|
||||
function CommandIcon(props: CommandIconProps): JSX.Element {
|
||||
return (
|
||||
<svg width="15" height="15" aria-label={props.ariaLabel} role="img">
|
||||
<g fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.2">
|
||||
<svg width="20" height="20" aria-label={props.ariaLabel} viewBox="0 0 24 24" role="img">
|
||||
<g fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.4">
|
||||
{props.children}
|
||||
</g>
|
||||
</svg>
|
||||
|
|
@ -34,50 +34,53 @@ function CommandIcon(props: CommandIconProps): JSX.Element {
|
|||
|
||||
export function Footer({ translations = {} }: FooterProps): JSX.Element {
|
||||
const {
|
||||
selectText = 'to select',
|
||||
selectText = 'Select',
|
||||
selectKeyAriaLabel = 'Enter key',
|
||||
navigateText = 'to navigate',
|
||||
navigateText = 'Navigate',
|
||||
navigateUpKeyAriaLabel = 'Arrow up',
|
||||
navigateDownKeyAriaLabel = 'Arrow down',
|
||||
closeText = 'to close',
|
||||
closeText = 'Close',
|
||||
closeKeyAriaLabel = 'Escape key',
|
||||
searchByText = 'Search by',
|
||||
poweredByText = 'Powered by',
|
||||
} = translations;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="DocSearch-Logo">
|
||||
<AlgoliaLogo translations={{ searchByText }} />
|
||||
<AlgoliaLogo translations={{ poweredByText }} />
|
||||
</div>
|
||||
<ul className="DocSearch-Commands">
|
||||
<li>
|
||||
<kbd className="DocSearch-Commands-Key">
|
||||
<CommandIcon ariaLabel={selectKeyAriaLabel}>
|
||||
<path d="M12 3.53088v3c0 1-1 2-2 2H4M7 11.53088l-3-3 3-3" />
|
||||
</CommandIcon>
|
||||
</kbd>
|
||||
<span className="DocSearch-Label">{selectText}</span>
|
||||
</li>
|
||||
<li>
|
||||
<kbd className="DocSearch-Commands-Key">
|
||||
<CommandIcon ariaLabel={navigateDownKeyAriaLabel}>
|
||||
<path d="M7.5 3.5v8M10.5 8.5l-3 3-3-3" />
|
||||
<path d="M12 5v14" />
|
||||
<path d="m19 12-7 7-7-7" />
|
||||
</CommandIcon>
|
||||
</kbd>
|
||||
<kbd className="DocSearch-Commands-Key">
|
||||
<CommandIcon ariaLabel={navigateUpKeyAriaLabel}>
|
||||
<path d="M7.5 11.5v-8M10.5 6.5l-3-3-3 3" />
|
||||
<path d="m5 12 7-7 7 7" />
|
||||
<path d="M12 19V5" />
|
||||
</CommandIcon>
|
||||
</kbd>
|
||||
<span className="DocSearch-Label">{navigateText}</span>
|
||||
</li>
|
||||
<li>
|
||||
<kbd className="DocSearch-Commands-Key">
|
||||
<CommandIcon ariaLabel={closeKeyAriaLabel}>
|
||||
<path d="M13.6167 8.936c-.1065.3583-.6883.962-1.4875.962-.7993 0-1.653-.9165-1.653-2.1258v-.5678c0-1.2548.7896-2.1016 1.653-2.1016.8634 0 1.3601.4778 1.4875 1.0724M9 6c-.1352-.4735-.7506-.9219-1.46-.8972-.7092.0246-1.344.57-1.344 1.2166s.4198.8812 1.3445.9805C8.465 7.3992 8.968 7.9337 9 8.5c.032.5663-.454 1.398-1.4595 1.398C6.6593 9.898 6 9 5.963 8.4851m-1.4748.5368c-.2635.5941-.8099.876-1.5443.876s-1.7073-.6248-1.7073-2.204v-.4603c0-1.0416.721-2.131 1.7073-2.131.9864 0 1.6425 1.031 1.5443 2.2492h-2.956" />
|
||||
<CommandIcon ariaLabel={selectKeyAriaLabel}>
|
||||
<polyline points="9 10 4 15 9 20" />
|
||||
<path d="M20 4v7a4 4 0 0 1-4 4H4" />
|
||||
</CommandIcon>
|
||||
</kbd>
|
||||
<span className="DocSearch-Label">{closeText}</span>
|
||||
<span className="DocSearch-Label">{selectText}</span>
|
||||
</li>
|
||||
<li>
|
||||
<kbd className="DocSearch-Commands-Key">
|
||||
<span className="DocSearch-Escape-Key">ESC</span>
|
||||
</kbd>
|
||||
<span className="DocSearch-Label" aria-label={closeKeyAriaLabel}>
|
||||
{closeText}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React, { type JSX } from 'react';
|
||||
|
||||
import { NoResultsIcon } from './icons';
|
||||
import { NoResultsIcon, SearchIcon } from './icons';
|
||||
import type { ScreenStateProps } from './ScreenState';
|
||||
import type { InternalDocSearchHit } from './types';
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ type NoResultsScreenProps = Omit<ScreenStateProps<InternalDocSearchHit>, 'transl
|
|||
|
||||
export function NoResultsScreen({ translations = {}, ...props }: NoResultsScreenProps): JSX.Element {
|
||||
const {
|
||||
noResultsText = 'No results for',
|
||||
noResultsText = 'No results found for',
|
||||
suggestedQueryText = 'Try searching for',
|
||||
reportMissingResultsText = 'Believe this query should return results?',
|
||||
reportMissingResultsLinkText = 'Let us know.',
|
||||
|
|
@ -41,6 +41,7 @@ export function NoResultsScreen({ translations = {}, ...props }: NoResultsScreen
|
|||
(acc, search) => [
|
||||
...acc,
|
||||
<li key={search}>
|
||||
<SearchIcon size={16} />
|
||||
<button
|
||||
className="DocSearch-Prefill"
|
||||
key={search}
|
||||
|
|
|
|||
|
|
@ -2,16 +2,14 @@ import type { AutocompleteApi, AutocompleteState } from '@algolia/autocomplete-c
|
|||
import React, { type JSX, type RefObject } from 'react';
|
||||
|
||||
import { MAX_QUERY_SIZE } from './constants';
|
||||
import { LoadingIcon } from './icons/LoadingIcon';
|
||||
import { ResetIcon } from './icons/ResetIcon';
|
||||
import { SearchIcon } from './icons/SearchIcon';
|
||||
import { LoadingIcon, CloseIcon, SearchIcon } from './icons';
|
||||
import type { InternalDocSearchHit } from './types';
|
||||
|
||||
export type SearchBoxTranslations = Partial<{
|
||||
resetButtonTitle: string;
|
||||
resetButtonAriaLabel: string;
|
||||
cancelButtonText: string;
|
||||
cancelButtonAriaLabel: string;
|
||||
clearButtonTitle: string;
|
||||
clearButtonAriaLabel: string;
|
||||
closeButtonText: string;
|
||||
closeButtonAriaLabel: string;
|
||||
searchInputLabel: string;
|
||||
}>;
|
||||
|
||||
|
|
@ -27,10 +25,10 @@ interface SearchBoxProps
|
|||
|
||||
export function SearchBox({ translations = {}, ...props }: SearchBoxProps): JSX.Element {
|
||||
const {
|
||||
resetButtonTitle = 'Clear the query',
|
||||
resetButtonAriaLabel = 'Clear the query',
|
||||
cancelButtonText = 'Cancel',
|
||||
cancelButtonAriaLabel = 'Cancel',
|
||||
clearButtonTitle = 'Clear',
|
||||
clearButtonAriaLabel = 'Clear the query',
|
||||
closeButtonText = 'Close',
|
||||
closeButtonAriaLabel = 'Close',
|
||||
searchInputLabel = 'Search',
|
||||
} = translations;
|
||||
const { onReset } = props.getFormProps({
|
||||
|
|
@ -77,20 +75,31 @@ export function SearchBox({ translations = {}, ...props }: SearchBoxProps): JSX.
|
|||
})}
|
||||
/>
|
||||
|
||||
<button
|
||||
type="reset"
|
||||
title={resetButtonTitle}
|
||||
className="DocSearch-Reset"
|
||||
aria-label={resetButtonAriaLabel}
|
||||
hidden={!props.state.query}
|
||||
>
|
||||
<ResetIcon />
|
||||
</button>
|
||||
</form>
|
||||
<div className="DocSearch-Actions">
|
||||
<button
|
||||
className="DocSearch-Clear"
|
||||
type="reset"
|
||||
aria-label={clearButtonAriaLabel}
|
||||
hidden={!props.state.query}
|
||||
tabIndex={props.state.query ? 0 : -1}
|
||||
aria-hidden={!props.state.query ? 'true' : 'false'}
|
||||
>
|
||||
{clearButtonTitle}
|
||||
</button>
|
||||
|
||||
<button className="DocSearch-Cancel" type="reset" aria-label={cancelButtonAriaLabel} onClick={props.onClose}>
|
||||
{cancelButtonText}
|
||||
</button>
|
||||
<div className="DocSearch-Divider" />
|
||||
|
||||
<button
|
||||
type="button"
|
||||
title={closeButtonText}
|
||||
className="DocSearch-Close"
|
||||
aria-label={closeButtonAriaLabel}
|
||||
onClick={props.onClose}
|
||||
>
|
||||
<CloseIcon />
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React, { type JSX } from 'react';
|
||||
|
||||
import { RecentIcon, ResetIcon, StarIcon } from './icons';
|
||||
import { RecentIcon, CloseIcon, StarIcon, SearchIcon } from './icons';
|
||||
import { Results } from './Results';
|
||||
import type { ScreenStateProps } from './ScreenState';
|
||||
import type { InternalDocSearchHit } from './types';
|
||||
|
|
@ -22,7 +22,7 @@ type StartScreenProps = Omit<ScreenStateProps<InternalDocSearchHit>, 'translatio
|
|||
export function StartScreen({ translations = {}, ...props }: StartScreenProps): JSX.Element | null {
|
||||
const {
|
||||
recentSearchesTitle = 'Recent',
|
||||
noRecentSearchesText = 'No recent searches',
|
||||
noRecentSearchesText = 'Make a search to see results',
|
||||
saveRecentSearchButtonTitle = 'Save this search',
|
||||
removeRecentSearchButtonTitle = 'Remove this search from history',
|
||||
favoriteSearchesTitle = 'Favorite',
|
||||
|
|
@ -35,6 +35,9 @@ export function StartScreen({ translations = {}, ...props }: StartScreenProps):
|
|||
|
||||
return (
|
||||
<div className="DocSearch-StartScreen">
|
||||
<div className="DocSearch-StartScreen-Icon">
|
||||
<SearchIcon size={64} color="#5a5e9a" />
|
||||
</div>
|
||||
<p className="DocSearch-Help">{noRecentSearchesText}</p>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -89,7 +92,7 @@ export function StartScreen({ translations = {}, ...props }: StartScreenProps):
|
|||
});
|
||||
}}
|
||||
>
|
||||
<ResetIcon />
|
||||
<CloseIcon />
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
|
|
@ -120,7 +123,7 @@ export function StartScreen({ translations = {}, ...props }: StartScreenProps):
|
|||
});
|
||||
}}
|
||||
>
|
||||
<ResetIcon />
|
||||
<CloseIcon />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -134,10 +134,10 @@ describe('api', () => {
|
|||
translations={{
|
||||
modal: {
|
||||
searchBox: {
|
||||
resetButtonTitle: 'Effacer',
|
||||
resetButtonAriaLabel: 'Effacer',
|
||||
cancelButtonText: 'Annuler',
|
||||
cancelButtonAriaLabel: 'Annuler',
|
||||
clearButtonTitle: 'Effacer',
|
||||
clearButtonAriaLabel: 'Effacer',
|
||||
closeButtonText: 'Fermer',
|
||||
closeButtonAriaLabel: 'Fermer',
|
||||
searchInputLabel: 'Recherche',
|
||||
},
|
||||
},
|
||||
|
|
@ -153,10 +153,10 @@ describe('api', () => {
|
|||
|
||||
expect(document.querySelector(docSearchSelector)).toBeInTheDocument();
|
||||
|
||||
expect(document.querySelector('.DocSearch-Cancel')?.innerHTML).toBe('Annuler');
|
||||
expect(document.querySelector('.DocSearch-Cancel')?.getAttribute('aria-label')).toBe('Annuler');
|
||||
expect(document.querySelector('.DocSearch-Reset')?.getAttribute('title')).toBe('Effacer');
|
||||
expect(document.querySelector('.DocSearch-Reset')?.getAttribute('aria-label')).toBe('Effacer');
|
||||
expect(document.querySelector('.DocSearch-Clear')?.innerHTML).toBe('Effacer');
|
||||
expect(document.querySelector('.DocSearch-Clear')?.getAttribute('aria-label')).toBe('Effacer');
|
||||
expect(document.querySelector('.DocSearch-Close')?.getAttribute('title')).toBe('Fermer');
|
||||
expect(document.querySelector('.DocSearch-Close')?.getAttribute('aria-label')).toBe('Fermer');
|
||||
expect(searchInputLabel?.textContent).toBe('Recherche');
|
||||
});
|
||||
|
||||
|
|
@ -170,9 +170,9 @@ describe('api', () => {
|
|||
closeKeyAriaLabel: "Touche d'échappement",
|
||||
navigateText: 'Pour naviguer',
|
||||
navigateUpKeyAriaLabel: 'Flèche vers le haut',
|
||||
navigateDownKeyAriaLabel: 'Flèche le bas',
|
||||
searchByText: 'Recherche par',
|
||||
selectText: 'Pour selectionner',
|
||||
navigateDownKeyAriaLabel: 'Flèche vers le bas',
|
||||
poweredByText: 'Propulsé par',
|
||||
selectText: 'Pour sélectionner',
|
||||
selectKeyAriaLabel: "Touche d'entrée",
|
||||
},
|
||||
},
|
||||
|
|
@ -186,17 +186,18 @@ describe('api', () => {
|
|||
fireEvent.click(await screen.findByText('Search'));
|
||||
});
|
||||
|
||||
expect(screen.getByText('Recherche par')).toBeInTheDocument();
|
||||
expect(screen.getByText('Pour fermer')).toBeInTheDocument();
|
||||
expect(screen.getByText('Pour naviguer')).toBeInTheDocument();
|
||||
expect(screen.getByText('Pour selectionner')).toBeInTheDocument();
|
||||
expect(
|
||||
document.querySelector('.DocSearch-Commands-Key > svg[aria-label="Touche d\'échappement"]'),
|
||||
).toBeInTheDocument();
|
||||
await screen.findByText('Propulsé par');
|
||||
await screen.findByText('Pour fermer');
|
||||
await screen.findByText('Pour naviguer');
|
||||
await screen.findByText('Pour sélectionner');
|
||||
|
||||
expect(screen.getByLabelText("Touche d'échappement")).toBeInTheDocument();
|
||||
expect(
|
||||
document.querySelector('.DocSearch-Commands-Key > svg[aria-label="Flèche vers le haut"]'),
|
||||
).toBeInTheDocument();
|
||||
expect(document.querySelector('.DocSearch-Commands-Key > svg[aria-label="Flèche le bas"]')).toBeInTheDocument();
|
||||
expect(
|
||||
document.querySelector('.DocSearch-Commands-Key > svg[aria-label="Flèche vers le bas"]'),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
document.querySelector('.DocSearch-Commands-Key > svg[aria-label="Touche d\'entrée"]'),
|
||||
).toBeInTheDocument();
|
||||
|
|
@ -228,7 +229,7 @@ describe('api', () => {
|
|||
});
|
||||
});
|
||||
|
||||
expect(screen.getByText(/No results for/)).toBeInTheDocument();
|
||||
expect(screen.getByText(/No results found for/)).toBeInTheDocument();
|
||||
expect(document.querySelector('.DocSearch-Help a')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
|
@ -255,7 +256,7 @@ describe('api', () => {
|
|||
});
|
||||
});
|
||||
|
||||
expect(screen.getByText(/No results for/)).toBeInTheDocument();
|
||||
expect(screen.getByText(/No results found for/)).toBeInTheDocument();
|
||||
const link = document.querySelector('.DocSearch-Help a');
|
||||
expect(link).toBeInTheDocument();
|
||||
expect(link?.getAttribute('href')).toBe('https://github.com/algolia/docsearch/issues/new?title=q');
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React, { type JSX } from 'react';
|
||||
|
||||
export function ResetIcon(): JSX.Element {
|
||||
export function CloseIcon(): JSX.Element {
|
||||
return (
|
||||
<svg width="20" height="20" viewBox="0 0 20 20">
|
||||
<path
|
||||
16
packages/docsearch-react/src/icons/MetaKeyIcon.tsx
Normal file
16
packages/docsearch-react/src/icons/MetaKeyIcon.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import React, { type JSX } from 'react';
|
||||
|
||||
export function MetaKeyIcon(): JSX.Element {
|
||||
return (
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" className="DocSearch-Meta-Key-Icon">
|
||||
<path
|
||||
d="M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
|
@ -3,16 +3,20 @@ import React, { type JSX } from 'react';
|
|||
export function NoResultsIcon(): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
width="40"
|
||||
height="40"
|
||||
viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="64"
|
||||
height="64"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
fillRule="evenodd"
|
||||
stroke="currentColor"
|
||||
stroke="#5a5e9a"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M15.5 4.8c2 3 1.7 7-1 9.7h0l4.3 4.3-4.3-4.3a7.8 7.8 0 01-9.8 1m-2.2-2.2A7.8 7.8 0 0113.2 2.4M2 18L18 2"></path>
|
||||
<path d="m13.5 8.5-5 5" />
|
||||
<path d="m8.5 8.5 5 5" />
|
||||
<circle cx="11" cy="11" r="8" />
|
||||
<path d="m21 21-4.3-4.3" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,15 @@
|
|||
import React, { type JSX } from 'react';
|
||||
|
||||
export function SearchIcon(): JSX.Element {
|
||||
interface SearchIconProps {
|
||||
size?: number;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
export function SearchIcon({ size = 20, color = 'currentColor' }: SearchIconProps): JSX.Element {
|
||||
return (
|
||||
<svg width="20" height="20" className="DocSearch-Search-Icon" viewBox="0 0 20 20" aria-hidden="true">
|
||||
<path
|
||||
d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z"
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
fillRule="evenodd"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<svg width={size} height={size} className="DocSearch-Search-Icon" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<circle cx="11" cy="11" r="8" stroke={color} fill="none" strokeWidth="1.4" />
|
||||
<path d="m21 21-4.3-4.3" stroke={color} fill="none" strokeLinecap="round" strokeLinejoin="round" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,14 +2,22 @@ import React, { type JSX } from 'react';
|
|||
|
||||
const LvlIcon: React.FC = () => {
|
||||
return (
|
||||
<svg width="20" height="20" viewBox="0 0 20 20">
|
||||
<path
|
||||
d="M17 6v12c0 .52-.2 1-1 1H4c-.7 0-1-.33-1-1V2c0-.55.42-1 1-1h8l5 5zM14 8h-3.13c-.51 0-.87-.34-.87-.87V4"
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
fillRule="evenodd"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" />
|
||||
<path d="M14 2v4a2 2 0 0 0 2 2h4" />
|
||||
<path d="M10 9H8" />
|
||||
<path d="M16 13H8" />
|
||||
<path d="M16 17H8" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
|
@ -27,15 +35,20 @@ export function SourceIcon(props: { type: string }): JSX.Element {
|
|||
|
||||
function AnchorIcon(): JSX.Element {
|
||||
return (
|
||||
<svg width="20" height="20" viewBox="0 0 20 20">
|
||||
<path
|
||||
d="M13 13h4-4V8H7v5h6v4-4H7V8H3h4V3v5h6V3v5h4-4v5zm-6 0v4-4H3h4z"
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
fillRule="evenodd"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<line x1="4" x2="20" y1="9" y2="9" />
|
||||
<line x1="4" x2="20" y1="15" y2="15" />
|
||||
<line x1="10" x2="8" y1="3" y2="21" />
|
||||
<line x1="16" x2="14" y1="3" y2="21" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
export * from './GoToExternalIcon';
|
||||
export * from './LoadingIcon';
|
||||
export * from './RecentIcon';
|
||||
export * from './ResetIcon';
|
||||
export * from './CloseIcon';
|
||||
export * from './SearchIcon';
|
||||
export * from './SelectIcon';
|
||||
export * from './SourceIcon';
|
||||
|
|
|
|||
|
|
@ -187,14 +187,14 @@ const translations: DocSearchTranslations = {
|
|||
helpText: 'You might want to check your network connection.',
|
||||
},
|
||||
footer: {
|
||||
selectText: 'to select',
|
||||
selectText: 'Select',
|
||||
selectKeyAriaLabel: 'Enter key',
|
||||
navigateText: 'to navigate',
|
||||
navigateText: 'Navigate',
|
||||
navigateUpKeyAriaLabel: 'Arrow up',
|
||||
navigateDownKeyAriaLabel: 'Arrow down',
|
||||
closeText: 'to close',
|
||||
closeText: 'Close',
|
||||
closeKeyAriaLabel: 'Escape key',
|
||||
searchByText: 'Search by',
|
||||
poweredByText: 'Powered by',
|
||||
},
|
||||
noResultsScreen: {
|
||||
noResultsText: 'No results for',
|
||||
|
|
@ -253,10 +253,7 @@ docsearch({
|
|||
When provided, an informative message wrapped with your link will be displayed on no results searches. The default text can be changed using the [translations](#translations) property.
|
||||
|
||||
<div className="uil-ta-center">
|
||||
<img
|
||||
src={useBaseUrl('img/assets/noResultsScreen.png')}
|
||||
alt="No results screen with informative message"
|
||||
/>
|
||||
<img src={useBaseUrl('img/assets/noResultsScreen.png')} alt="No results screen with informative message" />
|
||||
</div>
|
||||
|
||||
## `resultsFooterComponent`
|
||||
|
|
|
|||
Loading…
Reference in a new issue