feat: Add Docs MCP action, update DSxAlgolia logo
This commit is contained in:
parent
01b9533632
commit
95177b1c4e
23 changed files with 492 additions and 146 deletions
24
AGENTS.md
24
AGENTS.md
|
|
@ -78,27 +78,6 @@ bun run pw:run:webkit
|
|||
|
||||
## Code Style Guidelines
|
||||
|
||||
### Imports
|
||||
|
||||
Imported modules must be ordered alphabetically with newlines between groups:
|
||||
|
||||
1. Built-in modules
|
||||
2. External dependencies
|
||||
3. Parent directory imports
|
||||
4. Sibling imports
|
||||
5. Index imports
|
||||
|
||||
Internal `@/**/*` paths go before parent imports.
|
||||
|
||||
```typescript
|
||||
// Correct order
|
||||
import type { AutocompleteOptions } from '@algolia/autocomplete-core';
|
||||
import React, { type JSX } from 'react';
|
||||
|
||||
import { DocSearchButton } from './DocSearchButton';
|
||||
import type { DocSearchHit } from './types';
|
||||
```
|
||||
|
||||
### TypeScript
|
||||
|
||||
- Use `type` imports for type-only imports: `import type { Foo } from './types'`
|
||||
|
|
@ -137,9 +116,8 @@ function createStorage<TItem>(key: string): StorageInterface<TItem> {
|
|||
|
||||
### React Component Structure
|
||||
|
||||
- `src/components/ui/` contains reusable rendering components.
|
||||
- `src/components/ui/` contains small, composable, building block components that are used to construct larger components (Button, Popover, Menu, etc...).
|
||||
- Prefer domain-light primitives in `src/components/ui/` when possible.
|
||||
- Feature-scoped UI components may live in `src/components/ui/` when their feature scope is explicit in the filename, such as `RecentConversationsResults.tsx`.
|
||||
- `src/components/` contains scoped composition components that own feature flow, branching, and state orchestration.
|
||||
- Keep AI-specific behavior out of generic UI primitives. If a UI component is AI-specific, make that scope clear in its name.
|
||||
|
||||
|
|
|
|||
|
|
@ -87,6 +87,20 @@ describe('validateThemeConfig', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('accepts hideMCPCallout', () => {
|
||||
const docsearch: DocSearchInput = {
|
||||
...minimalDocSearchConfig,
|
||||
hideMCPCallout: true,
|
||||
};
|
||||
|
||||
expect(testValidateThemeConfig(docsearch)).toEqual({
|
||||
docsearch: {
|
||||
...DEFAULT_CONFIG,
|
||||
...docsearch,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('rejects missing docsearch config', () => {
|
||||
expectThrowMessage(
|
||||
() => testValidateThemeConfig(undefined),
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ declare module '@docsearch/docusaurus-adapter' {
|
|||
| 'recentSearchesWithFavoritesLimit'
|
||||
| 'resultBadgeKey'
|
||||
| 'translations'
|
||||
| 'hideMCPCallout'
|
||||
> & {
|
||||
indices: NonNullable<DocSearchProps['indices']>;
|
||||
askAi?: AskAiConfig;
|
||||
|
|
|
|||
|
|
@ -371,6 +371,13 @@ function DocSearch({
|
|||
const panelOptions = getSidePanelPanelOptions(
|
||||
typeof sidePanel === 'object' ? sidePanel : undefined
|
||||
);
|
||||
const sidepanelTranslations = {
|
||||
...panelOptions.translations,
|
||||
byAlgoliaAriaLabel:
|
||||
panelOptions.translations?.byAlgoliaAriaLabel ??
|
||||
props.translations?.modal?.footer?.byAlgoliaAriaLabel ??
|
||||
translations.modal?.footer?.byAlgoliaAriaLabel ?? 'DocSearch by Algolia',
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
@ -420,6 +427,7 @@ function DocSearch({
|
|||
DocSearchSidepanel && (
|
||||
<DocSearchSidepanel
|
||||
{...panelOptions}
|
||||
translations={sidepanelTranslations}
|
||||
variant={panelOptions.variant ?? 'inline'}
|
||||
pushSelector={panelOptions.pushSelector ?? '#__docusaurus'}
|
||||
assistantId={sidePanelAskAi.assistantId}
|
||||
|
|
|
|||
|
|
@ -63,9 +63,9 @@ const translations: DocSearchTranslations & {
|
|||
};
|
||||
footer: {
|
||||
submitQuestionText: string;
|
||||
poweredByText: string;
|
||||
backToSearchText: string;
|
||||
searchByText: string;
|
||||
addDocsMCPText: string;
|
||||
byAlgoliaAriaLabel: string;
|
||||
};
|
||||
};
|
||||
} = {
|
||||
|
|
@ -393,21 +393,21 @@ const translations: DocSearchTranslations & {
|
|||
message: 'Escape key',
|
||||
description: 'The ARIA label for close key in footer',
|
||||
}),
|
||||
poweredByText: translate({
|
||||
id: 'theme.SearchModal.footer.searchByText',
|
||||
message: 'Powered by',
|
||||
description: "The 'Powered by' text for footer",
|
||||
}),
|
||||
searchByText: translate({
|
||||
id: 'theme.SearchModal.footer.searchByText',
|
||||
message: 'Powered by',
|
||||
description: "The 'Powered by' text for footer",
|
||||
}),
|
||||
backToSearchText: translate({
|
||||
id: 'theme.SearchModal.footer.backToSearchText',
|
||||
message: 'Back to search',
|
||||
description: 'The back to search text for footer',
|
||||
}),
|
||||
addDocsMCPText: translate({
|
||||
id: 'theme.SearchModal.footer.addDocsMCPText',
|
||||
message: 'Add Docs MCP',
|
||||
description: 'The callout text for linking to Docs MCP',
|
||||
}),
|
||||
byAlgoliaAriaLabel: translate({
|
||||
id: 'theme.SearchModal.footer.byAlgoliaAriaLabel',
|
||||
message: 'DocSearch by Algolia',
|
||||
description: 'The ARIA label text for the DocSearch by Algolia lockup',
|
||||
}),
|
||||
},
|
||||
noResultsScreen: {
|
||||
noResultsText: translate({
|
||||
|
|
|
|||
|
|
@ -205,6 +205,7 @@ const DocSearchSchema = Joi.object<ThemeConfigDocSearch>({
|
|||
searchPage: SearchPageSchema,
|
||||
askAi: AskAiSchema.optional(),
|
||||
sidePanel: Joi.alternatives().try(Joi.boolean(), SidePanelSchema).optional(),
|
||||
hideMCPCallout: Joi.boolean().optional(),
|
||||
})
|
||||
.label('themeConfig.docsearch')
|
||||
.unknown(false);
|
||||
|
|
|
|||
|
|
@ -664,13 +664,74 @@
|
|||
font-weight: 500;
|
||||
}
|
||||
|
||||
.DocSearch-Logo a {
|
||||
display: flex;
|
||||
.DocSearch-ByAlgolia {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
min-width: 131px;
|
||||
color: var(--docsearch-text-color);
|
||||
}
|
||||
|
||||
.DocSearch-Logo svg {
|
||||
.DocSearch-ByAlgolia-mark {
|
||||
color: var(--docsearch-logo-color);
|
||||
margin-inline-start: 8px;
|
||||
height: 1.5rem;
|
||||
width: auto;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.DocSearch-ByAlgolia-Lockup {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.DocSearch-ByAlgolia-Lockup-title {
|
||||
font-size: 0.9375em;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.DocSearch-ByAlgolia-Lockup-by {
|
||||
margin-block-start: 0.125rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
font-size: 0.625em;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.025em;
|
||||
color: oklch(64% 0.008 75deg);
|
||||
|
||||
svg {
|
||||
height: 0.75rem;
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.DocSearch-DocsMCPAction {
|
||||
a {
|
||||
font-size: 0.875em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
color: var(--docsearch-text-color);
|
||||
padding-inline: 0.5rem;
|
||||
padding-block: 0.25rem;
|
||||
border-radius: var(--docsearch-border-radius);
|
||||
background-color: var(--docsearch-hit-focus-background);
|
||||
min-block-size: 1.5rem;
|
||||
|
||||
&:hover,
|
||||
&:focus-visible {
|
||||
outline: 2px solid var(--docsearch-highlight-color);
|
||||
}
|
||||
}
|
||||
|
||||
svg {
|
||||
height: 1rem;
|
||||
width: 1rem;
|
||||
color: var(--docsearch-highlight-color);
|
||||
}
|
||||
}
|
||||
|
||||
/* Hit */
|
||||
|
|
@ -1039,15 +1100,30 @@
|
|||
border-block-start: 1px solid var(--docsearch-subtle-color);
|
||||
border-radius: 0 0 var(--docsearch-modal-radius) var(--docsearch-modal-radius);
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
flex-shrink: 0;
|
||||
height: var(--docsearch-footer-height);
|
||||
justify-content: space-between;
|
||||
padding: 0 var(--docsearch-spacing);
|
||||
position: relative;
|
||||
user-select: none;
|
||||
width: 100%;
|
||||
z-index: 300;
|
||||
|
||||
@media screen and (width >= 768px) {
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
.DocSearch-Footer-Actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1em;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
|
||||
@media screen and (width >= 768px) {
|
||||
justify-content: unset;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.DocSearch-Commands {
|
||||
|
|
|
|||
|
|
@ -552,10 +552,6 @@
|
|||
padding: 0.75rem 1rem 1rem;
|
||||
}
|
||||
|
||||
.DocSearch-Sidepanel--powered-by {
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.DocSearch-Sidepanel-Screen--title {
|
||||
font-size: 1.625rem;
|
||||
font-weight: 600;
|
||||
|
|
@ -743,6 +739,53 @@
|
|||
right: -4rem;
|
||||
}
|
||||
|
||||
.DocSearch-Sidepanel .DocSearch-ByAlgolia {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
min-width: 131px;
|
||||
color: var(--docsearch-text-color);
|
||||
|
||||
.DocSearch-ByAlgolia-mark {
|
||||
color: var(--docsearch-logo-color);
|
||||
height: 1rem;
|
||||
width: auto;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.DocSearch-ByAlgolia-Lockup {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.DocSearch-ByAlgolia-Lockup-title {
|
||||
font-size: 0.9em;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.DocSearch-ByAlgolia-Lockup-by {
|
||||
margin-block-start: 0.125rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
font-size: 0.75em;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.025em;
|
||||
color: oklch(64% 0.008 75deg);
|
||||
border-inline-start: 2px solid var(--docsearch-subtle-color);
|
||||
padding-inline-start: 0.25rem;
|
||||
|
||||
svg {
|
||||
height: 0.85rem;
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sr-only {
|
||||
clip-path: inset(50%);
|
||||
white-space: nowrap;
|
||||
|
|
|
|||
|
|
@ -1,81 +0,0 @@
|
|||
import React, { type JSX } from 'react';
|
||||
|
||||
export type AlgoliaLogoTranslations = Partial<{
|
||||
poweredByText: string;
|
||||
}>;
|
||||
|
||||
type AlgoliaLogoProps = {
|
||||
translations?: AlgoliaLogoTranslations;
|
||||
};
|
||||
|
||||
export function AlgoliaLogo({
|
||||
translations = {},
|
||||
}: AlgoliaLogoProps): JSX.Element {
|
||||
const { poweredByText = 'Powered by' } = translations;
|
||||
|
||||
return (
|
||||
<a
|
||||
href={`https://www.algolia.com/ref/docsearch/?utm_source=${window.location.hostname}&utm_medium=referral&utm_content=powered_by&utm_campaign=docsearch`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<span className="DocSearch-Label">{poweredByText}</span>
|
||||
<svg
|
||||
width="80"
|
||||
height="24"
|
||||
aria-label="Algolia"
|
||||
role="img"
|
||||
id="Layer_1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 2196.2 500"
|
||||
>
|
||||
<defs>
|
||||
<style>
|
||||
{'.cls-1,.cls-2{fill:#003dff;}.cls-2{fill-rule:evenodd;}'}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
className="cls-2"
|
||||
d="M1070.38,275.3V5.91c0-3.63-3.24-6.39-6.82-5.83l-50.46,7.94c-2.87,.45-4.99,2.93-4.99,5.84l.17,273.22c0,12.92,0,92.7,95.97,95.49,3.33,.1,6.09-2.58,6.09-5.91v-40.78c0-2.96-2.19-5.51-5.12-5.84-34.85-4.01-34.85-47.57-34.85-54.72Z"
|
||||
/>
|
||||
<rect
|
||||
className="cls-1"
|
||||
x="1845.88"
|
||||
y="104.73"
|
||||
width="62.58"
|
||||
height="277.9"
|
||||
rx="5.9"
|
||||
ry="5.9"
|
||||
/>
|
||||
<path
|
||||
className="cls-2"
|
||||
d="M1851.78,71.38h50.77c3.26,0,5.9-2.64,5.9-5.9V5.9c0-3.62-3.24-6.39-6.82-5.83l-50.77,7.95c-2.87,.45-4.99,2.92-4.99,5.83v51.62c0,3.26,2.64,5.9,5.9,5.9Z"
|
||||
/>
|
||||
<path
|
||||
className="cls-2"
|
||||
d="M1764.03,275.3V5.91c0-3.63-3.24-6.39-6.82-5.83l-50.46,7.94c-2.87,.45-4.99,2.93-4.99,5.84l.17,273.22c0,12.92,0,92.7,95.97,95.49,3.33,.1,6.09-2.58,6.09-5.91v-40.78c0-2.96-2.19-5.51-5.12-5.84-34.85-4.01-34.85-47.57-34.85-54.72Z"
|
||||
/>
|
||||
<path
|
||||
className="cls-2"
|
||||
d="M1631.95,142.72c-11.14-12.25-24.83-21.65-40.78-28.31-15.92-6.53-33.26-9.85-52.07-9.85-18.78,0-36.15,3.17-51.92,9.85-15.59,6.66-29.29,16.05-40.76,28.31-11.47,12.23-20.38,26.87-26.76,44.03-6.38,17.17-9.24,37.37-9.24,58.36,0,20.99,3.19,36.87,9.55,54.21,6.38,17.32,15.14,32.11,26.45,44.36,11.29,12.23,24.83,21.62,40.6,28.46,15.77,6.83,40.12,10.33,52.4,10.48,12.25,0,36.78-3.82,52.7-10.48,15.92-6.68,29.46-16.23,40.78-28.46,11.29-12.25,20.05-27.04,26.25-44.36,6.22-17.34,9.24-33.22,9.24-54.21,0-20.99-3.34-41.19-10.03-58.36-6.38-17.17-15.14-31.8-26.43-44.03Zm-44.43,163.75c-11.47,15.75-27.56,23.7-48.09,23.7-20.55,0-36.63-7.8-48.1-23.7-11.47-15.75-17.21-34.01-17.21-61.2,0-26.89,5.59-49.14,17.06-64.87,11.45-15.75,27.54-23.52,48.07-23.52,20.55,0,36.63,7.78,48.09,23.52,11.47,15.57,17.36,37.98,17.36,64.87,0,27.19-5.72,45.3-17.19,61.2Z"
|
||||
/>
|
||||
<path
|
||||
className="cls-2"
|
||||
d="M894.42,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-14.52,22.58-22.99,49.63-22.99,78.73,0,44.89,20.13,84.92,51.59,111.1,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47,1.23,0,2.46-.03,3.68-.09,.36-.02,.71-.05,1.07-.07,.87-.05,1.75-.11,2.62-.2,.34-.03,.68-.08,1.02-.12,.91-.1,1.82-.21,2.73-.34,.21-.03,.42-.07,.63-.1,32.89-5.07,61.56-30.82,70.9-62.81v57.83c0,3.26,2.64,5.9,5.9,5.9h50.42c3.26,0,5.9-2.64,5.9-5.9V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,206.92c-12.2,10.16-27.97,13.98-44.84,15.12-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-42.24,0-77.12-35.89-77.12-79.37,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33v142.83Z"
|
||||
/>
|
||||
<path
|
||||
className="cls-2"
|
||||
d="M2133.97,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-14.52,22.58-22.99,49.63-22.99,78.73,0,44.89,20.13,84.92,51.59,111.1,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47,1.23,0,2.46-.03,3.68-.09,.36-.02,.71-.05,1.07-.07,.87-.05,1.75-.11,2.62-.2,.34-.03,.68-.08,1.02-.12,.91-.1,1.82-.21,2.73-.34,.21-.03,.42-.07,.63-.1,32.89-5.07,61.56-30.82,70.9-62.81v57.83c0,3.26,2.64,5.9,5.9,5.9h50.42c3.26,0,5.9-2.64,5.9-5.9V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,206.92c-12.2,10.16-27.97,13.98-44.84,15.12-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-42.24,0-77.12-35.89-77.12-79.37,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33v142.83Z"
|
||||
/>
|
||||
<path
|
||||
className="cls-2"
|
||||
d="M1314.05,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-11.79,18.34-19.6,39.64-22.11,62.59-.58,5.3-.88,10.68-.88,16.14s.31,11.15,.93,16.59c4.28,38.09,23.14,71.61,50.66,94.52,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47h0c17.99,0,34.61-5.93,48.16-15.97,16.29-11.58,28.88-28.54,34.48-47.75v50.26h-.11v11.08c0,21.84-5.71,38.27-17.34,49.36-11.61,11.08-31.04,16.63-58.25,16.63-11.12,0-28.79-.59-46.6-2.41-2.83-.29-5.46,1.5-6.27,4.22l-12.78,43.11c-1.02,3.46,1.27,7.02,4.83,7.53,21.52,3.08,42.52,4.68,54.65,4.68,48.91,0,85.16-10.75,108.89-32.21,21.48-19.41,33.15-48.89,35.2-88.52V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,64.1s.65,139.13,0,143.36c-12.08,9.77-27.11,13.59-43.49,14.7-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-1.32,0-2.63-.03-3.94-.1-40.41-2.11-74.52-37.26-74.52-79.38,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33Z"
|
||||
/>
|
||||
<path
|
||||
className="cls-1"
|
||||
d="M249.83,0C113.3,0,2,110.09,.03,246.16c-2,138.19,110.12,252.7,248.33,253.5,42.68,.25,83.79-10.19,120.3-30.03,3.56-1.93,4.11-6.83,1.08-9.51l-23.38-20.72c-4.75-4.21-11.51-5.4-17.36-2.92-25.48,10.84-53.17,16.38-81.71,16.03-111.68-1.37-201.91-94.29-200.13-205.96,1.76-110.26,92-199.41,202.67-199.41h202.69V407.41l-115-102.18c-3.72-3.31-9.42-2.66-12.42,1.31-18.46,24.44-48.53,39.64-81.93,37.34-46.33-3.2-83.87-40.5-87.34-86.81-4.15-55.24,39.63-101.52,94-101.52,49.18,0,89.68,37.85,93.91,85.95,.38,4.28,2.31,8.27,5.52,11.12l29.95,26.55c3.4,3.01,8.79,1.17,9.63-3.3,2.16-11.55,2.92-23.58,2.07-35.92-4.82-70.34-61.8-126.93-132.17-131.26-80.68-4.97-148.13,58.14-150.27,137.25-2.09,77.1,61.08,143.56,138.19,145.26,32.19,.71,62.03-9.41,86.14-26.95l150.26,133.2c6.44,5.71,16.61,1.14,16.61-7.47V9.48C499.66,4.25,495.42,0,490.18,0H249.83Z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
|
@ -154,6 +154,12 @@ export interface DocSearchProps {
|
|||
* @default undefined
|
||||
*/
|
||||
resultBadgeKey?: string;
|
||||
/**
|
||||
* Hides the Docs MCP callout in the Footer.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
hideMCPCallout?: boolean;
|
||||
}
|
||||
|
||||
function DocSearchComponent(
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ export function DocSearchAskAiModal({
|
|||
indices,
|
||||
facets,
|
||||
isHybridModeSupported = false,
|
||||
hideMCPCallout,
|
||||
...props
|
||||
}: DocSearchAskAiModalProps): JSX.Element {
|
||||
const {
|
||||
|
|
@ -653,6 +654,7 @@ export function DocSearchAskAiModal({
|
|||
<Footer
|
||||
translations={footerTranslations}
|
||||
isAskAiActive={isAskAiActive}
|
||||
hideMCPCallout={hideMCPCallout}
|
||||
/>
|
||||
}
|
||||
onClose={onClose}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ export function DocSearchModal({
|
|||
recentSearchesWithFavoritesLimit = 4,
|
||||
indices,
|
||||
facets,
|
||||
hideMCPCallout,
|
||||
...props
|
||||
}: DocSearchModalProps): JSX.Element {
|
||||
const {
|
||||
|
|
@ -303,7 +304,12 @@ export function DocSearchModal({
|
|||
}}
|
||||
/>
|
||||
}
|
||||
footer={<Footer translations={footerTranslations} />}
|
||||
footer={
|
||||
<Footer
|
||||
translations={footerTranslations}
|
||||
hideMCPCallout={hideMCPCallout}
|
||||
/>
|
||||
}
|
||||
onClose={onClose}
|
||||
/>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React, { type JSX } from 'react';
|
||||
|
||||
import { AlgoliaLogo } from './AlgoliaLogo';
|
||||
import { DocSearchByAlgolia } from './components/DocSearchByAlgolia';
|
||||
import { DocsMCPAction } from './components/DocsMCPAction';
|
||||
|
||||
export type FooterTranslations = Partial<{
|
||||
selectText: string;
|
||||
|
|
@ -12,12 +13,24 @@ export type FooterTranslations = Partial<{
|
|||
closeText: string;
|
||||
backToSearchText: string;
|
||||
closeKeyAriaLabel: string;
|
||||
poweredByText: string;
|
||||
/**
|
||||
* Text displayed for the add Docs MCP CTA.
|
||||
*
|
||||
* @default 'Add Docs MCP'
|
||||
*/
|
||||
addDocsMCPText: string;
|
||||
/**
|
||||
* Aria label for the DocSearch by Algolia lockup.
|
||||
*
|
||||
* @default 'DocSearch by Algolia'
|
||||
*/
|
||||
byAlgoliaAriaLabel: string;
|
||||
}>;
|
||||
|
||||
type FooterProps = Partial<{
|
||||
translations: FooterTranslations;
|
||||
isAskAiActive: boolean;
|
||||
hideMCPCallout: boolean;
|
||||
}>;
|
||||
|
||||
interface CommandIconProps {
|
||||
|
|
@ -50,6 +63,7 @@ function CommandIcon(props: CommandIconProps): JSX.Element {
|
|||
export function Footer({
|
||||
translations = {},
|
||||
isAskAiActive = false,
|
||||
hideMCPCallout = false,
|
||||
}: FooterProps): JSX.Element {
|
||||
const {
|
||||
selectText = 'Select',
|
||||
|
|
@ -61,14 +75,12 @@ export function Footer({
|
|||
closeText = 'Close',
|
||||
backToSearchText = 'Back to search',
|
||||
closeKeyAriaLabel = 'Escape key',
|
||||
poweredByText = 'Powered by',
|
||||
addDocsMCPText = 'Add Docs MCP',
|
||||
byAlgoliaAriaLabel = 'DocSearch by Algolia',
|
||||
} = translations;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="DocSearch-Logo">
|
||||
<AlgoliaLogo translations={{ poweredByText }} />
|
||||
</div>
|
||||
<ul className="DocSearch-Commands">
|
||||
<li>
|
||||
<kbd className="DocSearch-Commands-Key">
|
||||
|
|
@ -105,6 +117,14 @@ export function Footer({
|
|||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div className="DocSearch-Footer-Actions">
|
||||
{!hideMCPCallout && (
|
||||
<div className="DocSearch-DocsMCPAction">
|
||||
<DocsMCPAction addDocsMCPText={addDocsMCPText} />
|
||||
</div>
|
||||
)}
|
||||
<DocSearchByAlgolia byAlgoliaAriaLabel={byAlgoliaAriaLabel} />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import type { SidepanelShortcuts, InitialAskAiMessage } from '@docsearch/core';
|
|||
import React, { useCallback } from 'react';
|
||||
import type { JSX } from 'react';
|
||||
|
||||
import { AlgoliaLogo, type AlgoliaLogoTranslations } from '../AlgoliaLogo';
|
||||
import { DocSearchByAlgolia } from '../components/DocSearchByAlgolia';
|
||||
import type {
|
||||
DocSearchSidepanelProps,
|
||||
SidepanelSearchParameters,
|
||||
|
|
@ -52,8 +52,12 @@ export type SidepanelTranslations = Partial<{
|
|||
conversationScreen: ConversationScreenTranslations;
|
||||
/** Translation texts for the new conversation/starting screen. */
|
||||
newConversationScreen: NewConversationScreenTranslations;
|
||||
/** Translation text for the Algolia logo. */
|
||||
logo: AlgoliaLogoTranslations;
|
||||
/**
|
||||
* Aria label for the DocSearch by Algolia lockup.
|
||||
*
|
||||
* @default 'DocSearch by Algolia'
|
||||
*/
|
||||
byAlgoliaAriaLabel: string;
|
||||
}>;
|
||||
|
||||
export type SidepanelProps = Pick<
|
||||
|
|
@ -161,6 +165,7 @@ function SidepanelInner(
|
|||
const sidepanelContainerRef = React.useRef<HTMLDivElement>(null);
|
||||
const promptInputRef = React.useRef<HTMLTextAreaElement>(null);
|
||||
const isMobile = useIsMobile();
|
||||
const { byAlgoliaAriaLabel = 'DocSearch by Algolia' } = translations;
|
||||
|
||||
const expectedWidth = useSidepanelWidth({
|
||||
isExpanded,
|
||||
|
|
@ -438,9 +443,7 @@ function SidepanelInner(
|
|||
onStopStreaming={handleStopStreaming}
|
||||
/>
|
||||
<footer className="DocSearch-Sidepanel-Footer">
|
||||
<span className="DocSearch-Logo DocSearch-Sidepanel--powered-by">
|
||||
<AlgoliaLogo translations={translations.logo} />
|
||||
</span>
|
||||
<DocSearchByAlgolia byAlgoliaAriaLabel={byAlgoliaAriaLabel} />
|
||||
</footer>
|
||||
</aside>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ describe('api', () => {
|
|||
navigateText: 'Pour naviguer',
|
||||
navigateUpKeyAriaLabel: 'Flèche vers le haut',
|
||||
navigateDownKeyAriaLabel: 'Flèche vers le bas',
|
||||
poweredByText: 'Propulsé par',
|
||||
byAlgoliaAriaLabel: 'Propulsé par',
|
||||
selectText: 'Pour sélectionner',
|
||||
selectKeyAriaLabel: "Touche d'entrée",
|
||||
},
|
||||
|
|
@ -253,7 +253,7 @@ describe('api', () => {
|
|||
fireEvent.click(await screen.findByText('Search'));
|
||||
});
|
||||
|
||||
await screen.findByText('Propulsé par');
|
||||
expect(await screen.findByLabelText('Propulsé par')).toBeInTheDocument();
|
||||
await screen.findByText('Pour fermer');
|
||||
await screen.findByText('Pour naviguer');
|
||||
await screen.findByText('Pour sélectionner');
|
||||
|
|
@ -342,6 +342,85 @@ describe('api', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('footer callout', () => {
|
||||
it('renders the Docs MCP callout by default', async () => {
|
||||
render(<DocSearch />);
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(await screen.findByText('Search'));
|
||||
});
|
||||
|
||||
const mcpLink = await screen.findByRole('link', {
|
||||
name: 'Add Docs MCP',
|
||||
});
|
||||
|
||||
expect(mcpLink).toHaveAttribute(
|
||||
'href',
|
||||
expect.stringContaining('https://docsearch.algolia.com/mcp/install')
|
||||
);
|
||||
expect(mcpLink).toHaveAttribute('target', '_blank');
|
||||
expect(mcpLink).toHaveAttribute('rel', 'noopener noreferrer');
|
||||
});
|
||||
|
||||
it('overrides the Docs MCP callout text', async () => {
|
||||
render(
|
||||
<DocSearch
|
||||
translations={{
|
||||
modal: {
|
||||
footer: {
|
||||
addDocsMCPText: 'Ajouter Docs MCP',
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(await screen.findByText('Search'));
|
||||
});
|
||||
|
||||
expect(
|
||||
await screen.findByRole('link', { name: 'Ajouter Docs MCP' })
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('disables the Docs MCP callout', async () => {
|
||||
render(<DocSearch hideMCPCallout={true} />);
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(await screen.findByText('Search'));
|
||||
});
|
||||
|
||||
expect(
|
||||
screen.queryByRole('link', { name: 'Add Docs MCP' })
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders the Docs MCP callout in the Ask AI modal', async () => {
|
||||
render(<DocSearchAI />);
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(await screen.findByText('Search'));
|
||||
});
|
||||
|
||||
expect(
|
||||
await screen.findByRole('link', { name: 'Add Docs MCP' })
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('disables the Docs MCP callout in the Ask AI modal', async () => {
|
||||
render(<DocSearchAI hideMCPCallout={true} />);
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(await screen.findByText('Search'));
|
||||
});
|
||||
|
||||
expect(
|
||||
screen.queryByRole('link', { name: 'Add Docs MCP' })
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('ask AI integration', () => {
|
||||
it('updates placeholder when ask AI is available', async () => {
|
||||
render(<DocSearchAI />);
|
||||
|
|
|
|||
63
packages/docsearch-react/src/components/AlgoliaWordMark.tsx
Normal file
63
packages/docsearch-react/src/components/AlgoliaWordMark.tsx
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
import React from 'react';
|
||||
import type { JSX } from 'react';
|
||||
|
||||
export function AlgoliaWordMark(): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
width="80"
|
||||
height="24"
|
||||
id="Layer_1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 2196.2 500"
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
>
|
||||
<defs>
|
||||
<style>
|
||||
{'.cls-1,.cls-2{fill:#003dff;}.cls-2{fill-rule:evenodd;}'}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
className="cls-2"
|
||||
d="M1070.38,275.3V5.91c0-3.63-3.24-6.39-6.82-5.83l-50.46,7.94c-2.87,.45-4.99,2.93-4.99,5.84l.17,273.22c0,12.92,0,92.7,95.97,95.49,3.33,.1,6.09-2.58,6.09-5.91v-40.78c0-2.96-2.19-5.51-5.12-5.84-34.85-4.01-34.85-47.57-34.85-54.72Z"
|
||||
/>
|
||||
<rect
|
||||
className="cls-1"
|
||||
x="1845.88"
|
||||
y="104.73"
|
||||
width="62.58"
|
||||
height="277.9"
|
||||
rx="5.9"
|
||||
ry="5.9"
|
||||
/>
|
||||
<path
|
||||
className="cls-2"
|
||||
d="M1851.78,71.38h50.77c3.26,0,5.9-2.64,5.9-5.9V5.9c0-3.62-3.24-6.39-6.82-5.83l-50.77,7.95c-2.87,.45-4.99,2.92-4.99,5.83v51.62c0,3.26,2.64,5.9,5.9,5.9Z"
|
||||
/>
|
||||
<path
|
||||
className="cls-2"
|
||||
d="M1764.03,275.3V5.91c0-3.63-3.24-6.39-6.82-5.83l-50.46,7.94c-2.87,.45-4.99,2.93-4.99,5.84l.17,273.22c0,12.92,0,92.7,95.97,95.49,3.33,.1,6.09-2.58,6.09-5.91v-40.78c0-2.96-2.19-5.51-5.12-5.84-34.85-4.01-34.85-47.57-34.85-54.72Z"
|
||||
/>
|
||||
<path
|
||||
className="cls-2"
|
||||
d="M1631.95,142.72c-11.14-12.25-24.83-21.65-40.78-28.31-15.92-6.53-33.26-9.85-52.07-9.85-18.78,0-36.15,3.17-51.92,9.85-15.59,6.66-29.29,16.05-40.76,28.31-11.47,12.23-20.38,26.87-26.76,44.03-6.38,17.17-9.24,37.37-9.24,58.36,0,20.99,3.19,36.87,9.55,54.21,6.38,17.32,15.14,32.11,26.45,44.36,11.29,12.23,24.83,21.62,40.6,28.46,15.77,6.83,40.12,10.33,52.4,10.48,12.25,0,36.78-3.82,52.7-10.48,15.92-6.68,29.46-16.23,40.78-28.46,11.29-12.25,20.05-27.04,26.25-44.36,6.22-17.34,9.24-33.22,9.24-54.21,0-20.99-3.34-41.19-10.03-58.36-6.38-17.17-15.14-31.8-26.43-44.03Zm-44.43,163.75c-11.47,15.75-27.56,23.7-48.09,23.7-20.55,0-36.63-7.8-48.1-23.7-11.47-15.75-17.21-34.01-17.21-61.2,0-26.89,5.59-49.14,17.06-64.87,11.45-15.75,27.54-23.52,48.07-23.52,20.55,0,36.63,7.78,48.09,23.52,11.47,15.57,17.36,37.98,17.36,64.87,0,27.19-5.72,45.3-17.19,61.2Z"
|
||||
/>
|
||||
<path
|
||||
className="cls-2"
|
||||
d="M894.42,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-14.52,22.58-22.99,49.63-22.99,78.73,0,44.89,20.13,84.92,51.59,111.1,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47,1.23,0,2.46-.03,3.68-.09,.36-.02,.71-.05,1.07-.07,.87-.05,1.75-.11,2.62-.2,.34-.03,.68-.08,1.02-.12,.91-.1,1.82-.21,2.73-.34,.21-.03,.42-.07,.63-.1,32.89-5.07,61.56-30.82,70.9-62.81v57.83c0,3.26,2.64,5.9,5.9,5.9h50.42c3.26,0,5.9-2.64,5.9-5.9V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,206.92c-12.2,10.16-27.97,13.98-44.84,15.12-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-42.24,0-77.12-35.89-77.12-79.37,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33v142.83Z"
|
||||
/>
|
||||
<path
|
||||
className="cls-2"
|
||||
d="M2133.97,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-14.52,22.58-22.99,49.63-22.99,78.73,0,44.89,20.13,84.92,51.59,111.1,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47,1.23,0,2.46-.03,3.68-.09,.36-.02,.71-.05,1.07-.07,.87-.05,1.75-.11,2.62-.2,.34-.03,.68-.08,1.02-.12,.91-.1,1.82-.21,2.73-.34,.21-.03,.42-.07,.63-.1,32.89-5.07,61.56-30.82,70.9-62.81v57.83c0,3.26,2.64,5.9,5.9,5.9h50.42c3.26,0,5.9-2.64,5.9-5.9V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,206.92c-12.2,10.16-27.97,13.98-44.84,15.12-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-42.24,0-77.12-35.89-77.12-79.37,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33v142.83Z"
|
||||
/>
|
||||
<path
|
||||
className="cls-2"
|
||||
d="M1314.05,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-11.79,18.34-19.6,39.64-22.11,62.59-.58,5.3-.88,10.68-.88,16.14s.31,11.15,.93,16.59c4.28,38.09,23.14,71.61,50.66,94.52,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47h0c17.99,0,34.61-5.93,48.16-15.97,16.29-11.58,28.88-28.54,34.48-47.75v50.26h-.11v11.08c0,21.84-5.71,38.27-17.34,49.36-11.61,11.08-31.04,16.63-58.25,16.63-11.12,0-28.79-.59-46.6-2.41-2.83-.29-5.46,1.5-6.27,4.22l-12.78,43.11c-1.02,3.46,1.27,7.02,4.83,7.53,21.52,3.08,42.52,4.68,54.65,4.68,48.91,0,85.16-10.75,108.89-32.21,21.48-19.41,33.15-48.89,35.2-88.52V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,64.1s.65,139.13,0,143.36c-12.08,9.77-27.11,13.59-43.49,14.7-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-1.32,0-2.63-.03-3.94-.1-40.41-2.11-74.52-37.26-74.52-79.38,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33Z"
|
||||
/>
|
||||
<path
|
||||
className="cls-1"
|
||||
d="M249.83,0C113.3,0,2,110.09,.03,246.16c-2,138.19,110.12,252.7,248.33,253.5,42.68,.25,83.79-10.19,120.3-30.03,3.56-1.93,4.11-6.83,1.08-9.51l-23.38-20.72c-4.75-4.21-11.51-5.4-17.36-2.92-25.48,10.84-53.17,16.38-81.71,16.03-111.68-1.37-201.91-94.29-200.13-205.96,1.76-110.26,92-199.41,202.67-199.41h202.69V407.41l-115-102.18c-3.72-3.31-9.42-2.66-12.42,1.31-18.46,24.44-48.53,39.64-81.93,37.34-46.33-3.2-83.87-40.5-87.34-86.81-4.15-55.24,39.63-101.52,94-101.52,49.18,0,89.68,37.85,93.91,85.95,.38,4.28,2.31,8.27,5.52,11.12l29.95,26.55c3.4,3.01,8.79,1.17,9.63-3.3,2.16-11.55,2.92-23.58,2.07-35.92-4.82-70.34-61.8-126.93-132.17-131.26-80.68-4.97-148.13,58.14-150.27,137.25-2.09,77.1,61.08,143.56,138.19,145.26,32.19,.71,62.03-9.41,86.14-26.95l150.26,133.2c6.44,5.71,16.61,1.14,16.61-7.47V9.48C499.66,4.25,495.42,0,490.18,0H249.83Z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
import React from 'react';
|
||||
import type { JSX } from 'react';
|
||||
|
||||
import { DocSearchMarkIcon } from '../icons';
|
||||
|
||||
import { AlgoliaWordMark } from './AlgoliaWordMark';
|
||||
|
||||
interface DocSearchByAlgoliaProps {
|
||||
byAlgoliaAriaLabel: string;
|
||||
}
|
||||
|
||||
export function DocSearchByAlgolia({
|
||||
byAlgoliaAriaLabel,
|
||||
}: DocSearchByAlgoliaProps): JSX.Element {
|
||||
return (
|
||||
<a
|
||||
href={`https://www.algolia.com/ref/docsearch/?utm_source=${window.location.hostname}&utm_medium=referral&utm_content=powered_by&utm_campaign=docsearch`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label={byAlgoliaAriaLabel}
|
||||
className="DocSearch-ByAlgolia"
|
||||
>
|
||||
<DocSearchMarkIcon className="DocSearch-ByAlgolia-mark" />
|
||||
<span className="DocSearch-ByAlgolia-Lockup">
|
||||
<span className="DocSearch-ByAlgolia-Lockup-title">DOCSEARCH</span>
|
||||
<span className="DocSearch-ByAlgolia-Lockup-by">
|
||||
by <AlgoliaWordMark />
|
||||
</span>
|
||||
</span>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
23
packages/docsearch-react/src/components/DocsMCPAction.tsx
Normal file
23
packages/docsearch-react/src/components/DocsMCPAction.tsx
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import React from 'react';
|
||||
import type { JSX } from 'react';
|
||||
|
||||
import { PlusIcon } from '../icons';
|
||||
|
||||
interface DocsMCPActionProps {
|
||||
addDocsMCPText: string;
|
||||
}
|
||||
|
||||
export function DocsMCPAction({
|
||||
addDocsMCPText,
|
||||
}: DocsMCPActionProps): JSX.Element {
|
||||
return (
|
||||
<a
|
||||
href={`https://docsearch.algolia.com/mcp/install?utm_source=${window.location.hostname}&utm_medium=referral&utm_content=add_docs_mcp&utm_campaign=docsearch`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<PlusIcon />
|
||||
{addDocsMCPText}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import { render, screen } from '@testing-library/react';
|
||||
import '@testing-library/jest-dom/vitest';
|
||||
import React from 'react';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { DocSearchByAlgolia } from '../DocSearchByAlgolia';
|
||||
|
||||
describe('DocSearchByAlgolia', () => {
|
||||
it('uses the default Sidepanel accessible label', () => {
|
||||
render(<DocSearchByAlgolia byAlgoliaAriaLabel="DocSearch by Algolia" />);
|
||||
|
||||
expect(
|
||||
screen.getByRole('link', { name: 'DocSearch by Algolia' })
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('uses a localized accessible label', () => {
|
||||
render(<DocSearchByAlgolia byAlgoliaAriaLabel="DocSearch par Algolia" />);
|
||||
|
||||
expect(
|
||||
screen.getByRole('link', { name: 'DocSearch par Algolia' })
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
29
packages/docsearch-react/src/icons/DocSearchMarkIcon.tsx
Normal file
29
packages/docsearch-react/src/icons/DocSearchMarkIcon.tsx
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import React from 'react';
|
||||
import type { JSX } from 'react';
|
||||
|
||||
interface DocSearchMarkIconProps {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function DocSearchMarkIcon({
|
||||
className = '',
|
||||
}: DocSearchMarkIconProps): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
viewBox="0 0 76 78"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fillRule="nonzero"
|
||||
className={className}
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
d="M36.493 77.289H3.074C1.376 77.289 0 75.919 0 74.228h36.523c12.769.062 24.6-6.663 31.038-17.642 6.438-10.979 6.504-24.543.174-35.584C61.404 9.962 49.639 3.122 36.87 3.061H0C0 1.37 1.376 0 3.074 0h33.796c10.31.01 20.193 4.1 27.473 11.369 7.279 7.268 11.36 17.12 11.341 27.384-.06 21.366-17.741 38.536-39.19 38.536z"
|
||||
fill="currentcolor"
|
||||
/>
|
||||
<path
|
||||
d="M0 69.045h23.711c2.931.01 5.761-1.071 7.933-3.031H0v3.031zM0 60.8h36.374c.734-.987 1.418-1.975 2.053-3.07H0v3.07zM0 52.546h41.025c.407-.987.774-1.975 1.091-3.06H0v3.06zM0 44.302h43.306c.149-.987.268-2.034.337-3.061H0v3.061zM0 36.058h43.633a29.95 29.95 0 0 1-.337-3.071H0v3.071zM0 27.804h42.116c-.317-1.037-.684-2.064-1.09-3.061H0v3.061zM0 19.559h38.427a32.68 32.68 0 0 1-2.053-3.06H0v3.06zM0 8.244v3.071h31.674A19.04 19.04 0 0 0 23.74 8.284L0 8.244z"
|
||||
fill="currentcolor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
22
packages/docsearch-react/src/icons/PlusIcon.tsx
Normal file
22
packages/docsearch-react/src/icons/PlusIcon.tsx
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import React from 'react';
|
||||
import type { JSX } from 'react';
|
||||
|
||||
export function PlusIcon(): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<line x1="12" y1="5" x2="12" y2="19" />
|
||||
<line x1="5" y1="12" x2="19" y2="12" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
export * from './DocSearchMarkIcon';
|
||||
export * from './GoToExternalIcon';
|
||||
export * from './LoadingIcon';
|
||||
export * from './SparklesIcon';
|
||||
|
|
@ -22,6 +23,7 @@ export * from './ToolIcon';
|
|||
export * from './MemoryIcon';
|
||||
export * from './MessageIcon';
|
||||
export * from './PinIcon';
|
||||
export * from './PlusIcon';
|
||||
export * from './BackIcon';
|
||||
export * from './ChevronIcon';
|
||||
export * from './CheckIcon';
|
||||
|
|
|
|||
|
|
@ -86,11 +86,6 @@ export default {
|
|||
button: {
|
||||
buttonText: 'Go on, give it a search...',
|
||||
},
|
||||
modal: {
|
||||
footer: {
|
||||
poweredByText: 'Powered by',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
metadata: [
|
||||
|
|
|
|||
Loading…
Reference in a new issue