Skip to content

Commit

Permalink
feat(translations): expose Button and Modal translations (#1183)
Browse files Browse the repository at this point in the history
shortcuts authored Nov 22, 2021

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 4b0eec0 commit ef13dea
Showing 21 changed files with 669 additions and 123 deletions.
3 changes: 1 addition & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -157,8 +157,7 @@ workflows:
requires:
- build
- test_types
# TODO: Enable once the test env setup is ready.
# - test_unit
- test_unit
# TODO: Enable again once Cypress is installed on the repo.
# - test_cypress
- release:
4 changes: 2 additions & 2 deletions bundlesize.config.json
Original file line number Diff line number Diff line change
@@ -6,11 +6,11 @@
},
{
"path": "packages/docsearch-react/dist/umd/index.js",
"maxSize": "19.30 kB"
"maxSize": "20 kB"
},
{
"path": "packages/docsearch-js/dist/umd/index.js",
"maxSize": "27.25 kB"
"maxSize": "27.75 kB"
}
]
}
5 changes: 3 additions & 2 deletions cypress/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"extends": "../../tsconfig",
"extends": "../tsconfig.json",
"compilerOptions": {
"types": ["cypress"]
}
},
"exclude": []
}
16 changes: 10 additions & 6 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
module.exports = {
rootDir: process.cwd(),
setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],
testPathIgnorePatterns: ['node_modules/', 'dist/', 'cypress/'],
watchPlugins: [
'jest-watch-typeahead/filename',
'jest-watch-typeahead/testname',
preset: 'ts-jest',
testMatch: ['<rootDir>/packages/docsearch-*/src/__tests__/*.test.(ts|tsx)'],
transformIgnorePatterns: [
'<rootDir>/node_modules/',
'<rootDir>/packages/docsearch-*/node_modules/',
],
transform: {
'^.+\\.(tsx|ts|js)$': 'babel-jest',
},
setupFilesAfterEnv: ['<rootDir>/scripts/jest/setupTests.ts'],
testEnvironment: 'jsdom',
globals: {
__DEV__: true,
},
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -47,9 +47,10 @@
"@rollup/plugin-json": "4.1.0",
"@rollup/plugin-node-resolve": "7.1.1",
"@rollup/plugin-replace": "2.3.3",
"@testing-library/dom": "7.23.0",
"@testing-library/dom": "8.11.0",
"@testing-library/jest-dom": "5.15.0",
"@testing-library/user-event": "12.1.3",
"@testing-library/react": "12.1.2",
"@testing-library/user-event": "13.5.0",
"@types/jest": "^27.0.0",
"@types/jest-diff": "^24.3.0",
"@types/react": "^17.0.0",
@@ -102,6 +103,7 @@
"stylelint-no-unsupported-browser-features": "5.0.2",
"stylelint-order": "5.0.0",
"stylelint-prettier": "2.0.0",
"ts-jest": "27.0.7",
"typescript": "4.5.2",
"watch": "1.0.2",
"webpack": "4.44.1"
15 changes: 12 additions & 3 deletions packages/docsearch-react/src/AlgoliaLogo.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
import React from 'react';

export const AlgoliaLogo: React.FC = () => {
type AlgoliaLogoTranslations = Partial<{
searchByText: string;
}>;

type AlgoliaLogoProps = {
translations?: AlgoliaLogoTranslations;
};

export function AlgoliaLogo({ translations = {} }: AlgoliaLogoProps) {
const { searchByText = 'Search by' } = translations;
return (
<a
href="https://www.algolia.com/docsearch"
target="_blank"
rel="noopener noreferrer"
>
<span className="DocSearch-Label">Search by</span>
<span className="DocSearch-Label">{searchByText}</span>
<svg width="77" height="19">
<path
d="M2.5067 0h14.0245c1.384.001 2.5058 1.1205 2.5068 2.5017V16.5c-.0014 1.3808-1.1232 2.4995-2.5068 2.5H2.5067C1.1232 18.9995.0014 17.8808 0 16.5V2.4958A2.495 2.495 0 01.735.7294 2.505 2.505 0 012.5068 0zM37.95 15.0695c-3.7068.0168-3.7068-2.986-3.7068-3.4634L34.2372.3576 36.498 0v11.1794c0 .2715 0 1.9889 1.452 1.994v1.8961zm-9.1666-1.8388c.694 0 1.2086-.0397 1.5678-.1088v-2.2934a5.3639 5.3639 0 00-1.3303-.1679 4.8283 4.8283 0 00-.758.0582 2.2845 2.2845 0 00-.688.2024c-.2029.0979-.371.2362-.4919.4142-.1268.1788-.185.2826-.185.5533 0 .5297.185.8359.5205 1.0375.3355.2016.7928.3053 1.365.3053v-.0008zm-.1969-8.1817c.7463 0 1.3768.092 1.8856.2767.5088.1838.9195.4428 1.2204.7717.3068.334.5147.7777.6423 1.251.1327.4723.196.991.196 1.5603v5.798c-.5235.1036-1.05.192-1.5787.2649-.7048.1037-1.4976.156-2.3774.156-.5832 0-1.1215-.0582-1.6016-.167a3.385 3.385 0 01-1.2432-.5364 2.6034 2.6034 0 01-.8037-.9565c-.191-.3922-.29-.9447-.29-1.5208 0-.5533.11-.905.3246-1.2863a2.7351 2.7351 0 01.8849-.9329c.376-.242.8029-.415 1.2948-.5187a7.4517 7.4517 0 011.5381-.156 7.1162 7.1162 0 011.6667.2024V8.886c0-.259-.0296-.5061-.093-.7372a1.5847 1.5847 0 00-.3245-.6158 1.5079 1.5079 0 00-.6119-.4158 2.6788 2.6788 0 00-.966-.173c-.5206 0-.9948.0634-1.4283.1384a6.5481 6.5481 0 00-1.065.259l-.2712-1.849c.2831-.0986.7048-.1964 1.2491-.2943a9.2979 9.2979 0 011.752-.1501v.0008zm44.6597 8.1193c.6947 0 1.2086-.0405 1.567-.1097v-2.2942a5.3743 5.3743 0 00-1.3303-.1679c-.2485 0-.503.0177-.7573.0582a2.2853 2.2853 0 00-.688.2024 1.2333 1.2333 0 00-.4918.4142c-.1268.1788-.1843.2826-.1843.5533 0 .5297.1843.8359.5198 1.0375.3414.2066.7927.3053 1.365.3053v.0009zm-.191-8.1767c.7463 0 1.3768.0912 1.8856.2759.5087.1847.9195.4436 1.2204.7717.3.329.5147.7786.6414 1.251a5.7248 5.7248 0 01.197 1.562v5.7972c-.3466.0742-.874.1602-1.5788.2648-.7049.1038-1.4976.1552-2.3774.1552-.5832 0-1.1215-.0573-1.6016-.167a3.385 3.385 0 01-1.2432-.5356 2.6034 2.6034 0 01-.8038-.9565c-.191-.3922-.2898-.9447-.2898-1.5216 0-.5533.1098-.905.3245-1.2854a2.7373 2.7373 0 01.8849-.9338c.376-.2412.8029-.4141 1.2947-.5178a7.4545 7.4545 0 012.325-.1097c.2781.0287.5672.081.879.156v-.3686a2.7781 2.7781 0 00-.092-.738 1.5788 1.5788 0 00-.3246-.6166 1.5079 1.5079 0 00-.612-.415 2.6797 2.6797 0 00-.966-.1729c-.5205 0-.9947.0633-1.4282.1384a6.5608 6.5608 0 00-1.065.259l-.2712-1.8498c.283-.0979.7048-.1957 1.2491-.2935a9.8597 9.8597 0 011.752-.1494zm-6.79-1.072c-.7576.001-1.373-.6103-1.3759-1.3664 0-.755.6128-1.3664 1.376-1.3664.764 0 1.3775.6115 1.3775 1.3664s-.6195 1.3664-1.3776 1.3664zm1.1393 11.1507h-2.2726V5.3409l2.2734-.3568v10.0845l-.0008.0017zm-3.984 0c-3.707.0168-3.707-2.986-3.707-3.4642L59.7069.3576 61.9685 0v11.1794c0 .2715 0 1.9889 1.452 1.994V15.0703zm-7.3512-4.979c0-.975-.2138-1.7873-.6305-2.3516-.4167-.571-.9998-.852-1.747-.852-.7454 0-1.3302.281-1.7452.852-.4166.5702-.6195 1.3765-.6195 2.3516 0 .9851.208 1.6473.6254 2.2183.4158.576.9998.8587 1.7461.8587.7454 0 1.3303-.2885 1.747-.8595.4158-.5761.6237-1.2315.6237-2.2184v.0009zm2.3132-.006c0 .7609-.1099 1.3361-.3356 1.9654a4.654 4.654 0 01-.9533 1.6076A4.214 4.214 0 0155.613 14.69c-.579.2412-1.4697.3795-1.9143.3795-.4462-.005-1.3303-.1324-1.9033-.3795a4.307 4.307 0 01-1.474-1.0316c-.4115-.4445-.7293-.9801-.9609-1.6076a5.3423 5.3423 0 01-.3465-1.9653c0-.7608.104-1.493.3356-2.1155a4.683 4.683 0 01.9719-1.5958 4.3383 4.3383 0 011.479-1.0257c.5739-.242 1.2043-.3567 1.8864-.3567.6829 0 1.3125.1197 1.8906.3567a4.1245 4.1245 0 011.4816 1.0257 4.7587 4.7587 0 01.9592 1.5958c.2426.6225.3643 1.3547.3643 2.1155zm-17.0198 0c0 .9448.208 1.9932.6238 2.431.4166.4386.955.6579 1.6142.6579.3584 0 .6998-.0523 1.0176-.1502.3186-.0978.5721-.2134.775-.3517V7.0784a8.8706 8.8706 0 00-1.4926-.1906c-.8206-.0236-1.4452.312-1.8847.8468-.4335.5365-.6533 1.476-.6533 2.3516v-.0008zm6.2863 4.4485c0 1.5385-.3938 2.662-1.1866 3.3773-.791.7136-2.0005 1.0712-3.6308 1.0712-.5958 0-1.834-.1156-2.8228-.334l.3643-1.7865c.8282.173 1.9202.2193 2.4932.2193.9077 0 1.555-.1847 1.943-.5533.388-.3686.578-.916.578-1.643v-.3687a6.8289 6.8289 0 01-.8848.3349c-.3634.1096-.786.167-1.261.167-.6246 0-1.1917-.0979-1.7055-.2944a3.5554 3.5554 0 01-1.3244-.8645c-.3642-.3796-.6541-.8579-.8561-1.4289-.2028-.571-.3068-1.59-.3068-2.339 0-.7034.1099-1.5856.3245-2.1735.2198-.5871.5316-1.0949.9542-1.515.4167-.42.9255-.743 1.5213-.98a5.5923 5.5923 0 012.052-.3855c.7353 0 1.4114.092 2.0707.2024.6592.1088 1.2204.2236 1.6776.35v8.945-.0008zM11.5026 4.2418v-.6511c-.0005-.4553-.3704-.8241-.8266-.8241H8.749c-.4561 0-.826.3688-.8265.824v.669c0 .0742.0693.1264.1445.1096a6.0346 6.0346 0 011.6768-.2362 6.125 6.125 0 011.6202.2185.1116.1116 0 00.1386-.1097zm-5.2806.852l-.3296-.3282a.8266.8266 0 00-1.168 0l-.393.3922a.8199.8199 0 000 1.164l.3237.323c.0524.0515.1268.0397.1733-.0117.191-.259.3989-.507.6305-.7372.2374-.2362.48-.4437.7462-.6335.0575-.0354.0634-.1155.017-.1687zm3.5159 2.069v2.818c0 .081.0879.1392.1622.0987l2.5102-1.2964c.0574-.0287.0752-.0987.0464-.1552a3.1237 3.1237 0 00-2.603-1.574c-.0575 0-.115.0456-.115.1097l-.0008-.0009zm.0008 6.789c-2.0933.0005-3.7915-1.6912-3.7947-3.7804C5.9468 8.0821 7.6452 6.39 9.7387 6.391c2.0932-.0005 3.7911 1.6914 3.794 3.7804a3.7783 3.7783 0 01-1.1124 2.675 3.7936 3.7936 0 01-2.6824 1.1054h.0008zM9.738 4.8002c-1.9218 0-3.6975 1.0232-4.6584 2.6841a5.359 5.359 0 000 5.3683c.9609 1.661 2.7366 2.6841 4.6584 2.6841a5.3891 5.3891 0 003.8073-1.5725 5.3675 5.3675 0 001.578-3.7987 5.3574 5.3574 0 00-1.5771-3.797A5.379 5.379 0 009.7387 4.801l-.0008-.0008z"
@@ -17,4 +26,4 @@ export const AlgoliaLogo: React.FC = () => {
</svg>
</a>
);
};
}
15 changes: 14 additions & 1 deletion packages/docsearch-react/src/DocSearch.tsx
Original file line number Diff line number Diff line change
@@ -15,6 +15,13 @@ import type {
} from './types';
import { useDocSearchKeyboardEvents } from './useDocSearchKeyboardEvents';

import type { ButtonTranslations, ModalTranslations } from '.';

export type DocSearchTranslations = Partial<{
button: ButtonTranslations;
modal: ModalTranslations;
}>;

export interface DocSearchProps {
appId?: string;
apiKey: string;
@@ -33,6 +40,7 @@ export interface DocSearchProps {
disableUserPersonalization?: boolean;
initialQuery?: string;
navigator?: AutocompleteOptions<InternalDocSearchHit>['navigator'];
translations?: DocSearchTranslations;
}

export function DocSearch(props: DocSearchProps) {
@@ -68,14 +76,19 @@ export function DocSearch(props: DocSearchProps) {

return (
<>
<DocSearchButton ref={searchButtonRef} onClick={onOpen} />
<DocSearchButton
ref={searchButtonRef}
translations={props?.translations?.button}
onClick={onOpen}
/>

{isOpen &&
createPortal(
<DocSearchModal
{...props}
initialScrollY={window.scrollY}
initialQuery={initialQuery}
translations={props?.translations?.modal}
onClose={onClose}
/>,
document.body
4 changes: 2 additions & 2 deletions packages/docsearch-react/src/DocSearchButton.tsx
Original file line number Diff line number Diff line change
@@ -3,13 +3,13 @@ import React, { useMemo } from 'react';
import { ControlKeyIcon } from './icons/ControlKeyIcon';
import { SearchIcon } from './icons/SearchIcon';

type Translations = Partial<{
export type ButtonTranslations = Partial<{
buttonText: string;
buttonAriaLabel: string;
}>;

export type DocSearchButtonProps = React.ComponentProps<'button'> & {
translations?: Translations;
translations?: ButtonTranslations;
};

const ACTION_KEY_DEFAULT = 'Ctrl' as const;
25 changes: 21 additions & 4 deletions packages/docsearch-react/src/DocSearchModal.tsx
Original file line number Diff line number Diff line change
@@ -4,9 +4,12 @@ import React from 'react';

import { MAX_QUERY_SIZE } from './constants';
import type { DocSearchProps } from './DocSearch';
import type { FooterTranslations } from './Footer';
import { Footer } from './Footer';
import { Hit } from './Hit';
import type { ScreenStateTranslations } from './ScreenState';
import { ScreenState } from './ScreenState';
import type { SearchBoxTranslations } from './SearchBox';
import { SearchBox } from './SearchBox';
import { createStoredSearches } from './stored-searches';
import type {
@@ -19,10 +22,17 @@ import { useTouchEvents } from './useTouchEvents';
import { useTrapFocus } from './useTrapFocus';
import { groupBy, identity, noop, removeHighlightTags } from './utils';

export interface DocSearchModalProps extends DocSearchProps {
export type ModalTranslations = Partial<{
searchBox: SearchBoxTranslations;
footer: FooterTranslations;
}> &
ScreenStateTranslations;

export type DocSearchModalProps = DocSearchProps & {
initialScrollY: number;
onClose?: () => void;
}
translations?: ModalTranslations;
};

export function DocSearchModal({
appId = 'BH4D9OD16A',
@@ -39,7 +49,13 @@ export function DocSearchModal({
transformSearchClient = identity,
disableUserPersonalization = false,
initialQuery: initialQueryFromProp = '',
translations = {},
}: DocSearchModalProps) {
const {
footer: footerTranslations,
searchBox: searchBoxTranslations,
...screenStateTranslations
} = translations;
const [state, setState] = React.useState<
AutocompleteState<InternalDocSearchHit>
>({
@@ -127,7 +143,6 @@ export function DocSearchModal({
onStateChange(props) {
setState(props.state);
},

getSources({ query, state: sourcesState, setContext, setStatus }) {
if (!query) {
if (disableUserPersonalization) {
@@ -397,6 +412,7 @@ export function DocSearchModal({
Boolean(initialQuery) &&
initialQuery === initialQueryFromSelection
}
translations={searchBoxTranslations}
onClose={onClose}
/>
</header>
@@ -412,6 +428,7 @@ export function DocSearchModal({
recentSearches={recentSearches}
favoriteSearches={favoriteSearches}
inputRef={inputRef}
translations={screenStateTranslations}
onItemClick={(item) => {
saveRecentSearch(item);
onClose();
@@ -420,7 +437,7 @@ export function DocSearchModal({
</div>

<footer className="DocSearch-Footer">
<Footer />
<Footer translations={footerTranslations} />
</footer>
</div>
</div>
21 changes: 16 additions & 5 deletions packages/docsearch-react/src/ErrorScreen.tsx
Original file line number Diff line number Diff line change
@@ -2,16 +2,27 @@ import React from 'react';

import { ErrorIcon } from './icons';

export function ErrorScreen() {
export type ErrorScreenTranslations = Partial<{
titleText: string;
helpText: string;
}>;

type ErrorScreenProps = {
translations?: ErrorScreenTranslations;
};

export function ErrorScreen({ translations = {} }: ErrorScreenProps) {
const {
titleText = 'Unable to fetch results',
helpText = 'You might want to check your network connection.',
} = translations;
return (
<div className="DocSearch-ErrorScreen">
<div className="DocSearch-Screen-Icon">
<ErrorIcon />
</div>
<p className="DocSearch-Title">Unable to fetch results</p>
<p className="DocSearch-Help">
You might want to check your network connection.
</p>
<p className="DocSearch-Title">{titleText}</p>
<p className="DocSearch-Help">{helpText}</p>
</div>
);
}
68 changes: 43 additions & 25 deletions packages/docsearch-react/src/Footer.tsx
Original file line number Diff line number Diff line change
@@ -2,11 +2,49 @@ import React from 'react';

import { AlgoliaLogo } from './AlgoliaLogo';

export function Footer() {
export type FooterTranslations = Partial<{
selectText: string;
navigateText: string;
closeText: string;
searchByText: string;
}>;

type FooterProps = Partial<{
translations: FooterTranslations;
}>;

interface CommandIconProps {
children: React.ReactNode;
}

function CommandIcon(props: CommandIconProps) {
return (
<svg width="15" height="15">
<g
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="1.2"
>
{props.children}
</g>
</svg>
);
}

export function Footer({ translations = {} }: FooterProps) {
const {
selectText = 'to select',
navigateText = 'to navigate',
closeText = 'to close',
searchByText = 'Search by',
} = translations;

return (
<>
<div className="DocSearch-Logo">
<AlgoliaLogo />
<AlgoliaLogo translations={{ searchByText }} />
</div>
<ul className="DocSearch-Commands">
<li>
@@ -15,7 +53,7 @@ export function Footer() {
<path d="M12 3.53088v3c0 1-1 2-2 2H4M7 11.53088l-3-3 3-3" />
</CommandIcon>
</span>
<span className="DocSearch-Label">to select</span>
<span className="DocSearch-Label">{selectText}</span>
</li>
<li>
<span className="DocSearch-Commands-Key">
@@ -28,37 +66,17 @@ export function Footer() {
<path d="M7.5 11.5v-8M10.5 6.5l-3-3-3 3" />
</CommandIcon>
</span>
<span className="DocSearch-Label">to navigate</span>
<span className="DocSearch-Label">{navigateText}</span>
</li>
<li>
<span className="DocSearch-Commands-Key">
<CommandIcon>
<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>
</span>
<span className="DocSearch-Label">to close</span>
<span className="DocSearch-Label">{closeText}</span>
</li>
</ul>
</>
);
}

interface CommandIconProps {
children: React.ReactNode;
}

function CommandIcon(props: CommandIconProps) {
return (
<svg width="15" height="15">
<g
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="1.2"
>
{props.children}
</g>
</svg>
);
}
Loading

0 comments on commit ef13dea

Please sign in to comment.