@redocly/theme 0.11.4 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/I18n/LanguagePicker.d.ts +4 -0
- package/lib/I18n/LanguagePicker.js +111 -0
- package/lib/I18n/index.d.ts +1 -0
- package/lib/I18n/index.js +6 -0
- package/lib/components/Cards/Card.js +3 -1
- package/lib/components/Catalog/Catalog.js +14 -9
- package/lib/components/Catalog/CatalogCard.js +6 -1
- package/lib/components/Catalog/useCatalog.js +4 -1
- package/lib/components/CodeSample/CodeSample.js +11 -3
- package/lib/components/Feedback/Comment.js +12 -4
- package/lib/components/Feedback/Rating.js +8 -2
- package/lib/components/Feedback/Reasons.js +11 -4
- package/lib/components/Feedback/Sentiment.js +12 -4
- package/lib/components/Feedback/Thumbs.js +31 -18
- package/lib/components/Feedback/useReportDialog.js +8 -2
- package/lib/components/Filter/Filter.js +15 -8
- package/lib/components/Footer/FooterColumn.js +4 -2
- package/lib/components/Footer/FooterCopyright.d.ts +1 -2
- package/lib/components/Footer/FooterCopyright.js +6 -1
- package/lib/components/LastUpdated/LastUpdated.js +8 -4
- package/lib/components/Markdown/MarkdownLayout.js +6 -1
- package/lib/components/Markdown/MarkdownWrapper.js +4 -0
- package/lib/components/Menu/MenuGroup.js +3 -1
- package/lib/components/Menu/MenuItem.js +3 -1
- package/lib/components/Navbar/MobileNavbarItem.js +6 -2
- package/lib/components/Navbar/Navbar.d.ts +1 -0
- package/lib/components/Navbar/Navbar.js +6 -1
- package/lib/components/Navbar/NavbarDropdown.js +3 -1
- package/lib/components/Navbar/NavbarItem.js +9 -4
- package/lib/components/PageNavigation/NextButton.js +7 -2
- package/lib/components/PageNavigation/PreviousButton.js +10 -2
- package/lib/components/Profile/LoginLink.js +6 -1
- package/lib/components/Profile/UserProfileMenu.js +10 -4
- package/lib/components/Search/Autocomplete.d.ts +3 -3
- package/lib/components/Search/Autocomplete.js +21 -11
- package/lib/components/Search/ClearIcon.js +1 -1
- package/lib/components/Search/Search.js +6 -4
- package/lib/components/Separator/Separator.js +3 -1
- package/lib/components/Sidebar/DrilldownMenu.js +6 -1
- package/lib/components/Sidebar/DrilldownMenuItem.js +4 -2
- package/lib/components/Sidebar/types.d.ts +2 -0
- package/lib/components/TableOfContent/TableOfContent.js +6 -1
- package/lib/globalStyle.js +7 -0
- package/lib/icons/SpinnerIcon/SpinnerIcon.d.ts +8 -0
- package/lib/icons/SpinnerIcon/SpinnerIcon.js +32 -0
- package/lib/icons/SpinnerIcon/index.d.ts +1 -0
- package/lib/icons/SpinnerIcon/index.js +6 -0
- package/lib/icons/index.d.ts +1 -0
- package/lib/icons/index.js +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/layouts/Forbidden.js +8 -2
- package/lib/layouts/NotFound.js +8 -2
- package/lib/mocks/hooks/index.d.ts +15 -1
- package/lib/mocks/hooks/index.js +19 -1
- package/lib/mocks/search.d.ts +1 -0
- package/lib/mocks/search.js +1 -0
- package/lib/mocks/utils.d.ts +5 -0
- package/lib/mocks/utils.js +9 -1
- package/lib/types/portal/index.d.ts +1 -0
- package/lib/types/portal/index.js +1 -0
- package/lib/types/portal/src/shared/types/catalog.d.ts +4 -0
- package/lib/types/portal/src/shared/types/nav.d.ts +7 -0
- package/package.json +1 -1
- package/src/I18n/LanguagePicker.tsx +113 -0
- package/src/I18n/index.ts +1 -0
- package/src/components/Cards/Card.tsx +5 -1
- package/src/components/Catalog/Catalog.tsx +23 -6
- package/src/components/Catalog/CatalogCard.tsx +8 -1
- package/src/components/Catalog/useCatalog.ts +4 -2
- package/src/components/CodeSample/CodeSample.tsx +22 -4
- package/src/components/Feedback/Comment.tsx +25 -4
- package/src/components/Feedback/Rating.tsx +15 -2
- package/src/components/Feedback/Reasons.tsx +23 -5
- package/src/components/Feedback/Sentiment.tsx +25 -4
- package/src/components/Feedback/Thumbs.tsx +61 -46
- package/src/components/Feedback/useReportDialog.ts +11 -2
- package/src/components/Filter/Filter.tsx +17 -9
- package/src/components/Footer/CustomFooter.tsx +1 -1
- package/src/components/Footer/FooterColumn.tsx +5 -3
- package/src/components/Footer/FooterCopyright.tsx +12 -3
- package/src/components/LastUpdated/LastUpdated.tsx +10 -2
- package/src/components/Markdown/MarkdownLayout.tsx +11 -1
- package/src/components/Markdown/MarkdownWrapper.tsx +4 -0
- package/src/components/Menu/MenuGroup.tsx +4 -1
- package/src/components/Menu/MenuItem.tsx +3 -1
- package/src/components/Navbar/MobileNavbarItem.tsx +7 -1
- package/src/components/Navbar/Navbar.tsx +8 -0
- package/src/components/Navbar/NavbarDropdown.tsx +3 -1
- package/src/components/Navbar/NavbarItem.tsx +9 -3
- package/src/components/PageNavigation/NextButton.tsx +8 -2
- package/src/components/PageNavigation/PreviousButton.tsx +11 -2
- package/src/components/Profile/LoginLink.tsx +11 -1
- package/src/components/Profile/UserProfileMenu.tsx +13 -3
- package/src/components/Search/Autocomplete.tsx +31 -17
- package/src/components/Search/ClearIcon.tsx +1 -1
- package/src/components/Search/Search.tsx +8 -7
- package/src/components/Separator/Separator.tsx +4 -1
- package/src/components/Sidebar/DrilldownMenu.tsx +8 -1
- package/src/components/Sidebar/DrilldownMenuItem.tsx +7 -2
- package/src/components/Sidebar/types.ts +2 -0
- package/src/components/TableOfContent/TableOfContent.tsx +11 -1
- package/src/globalStyle.ts +7 -0
- package/src/icons/SpinnerIcon/SpinnerIcon.tsx +42 -0
- package/src/icons/SpinnerIcon/index.ts +1 -0
- package/src/icons/index.ts +1 -0
- package/src/index.ts +1 -0
- package/src/layouts/Forbidden.tsx +18 -3
- package/src/layouts/NotFound.tsx +17 -3
- package/src/mocks/hooks/index.ts +20 -1
- package/src/mocks/search.ts +2 -0
- package/src/mocks/utils.ts +13 -0
- package/src/types/portal/index.ts +1 -0
- package/src/types/portal/src/shared/types/catalog.ts +4 -0
- package/src/types/portal/src/shared/types/i18n.d.ts +3 -0
- package/src/types/portal/src/shared/types/nav.ts +7 -0
|
@@ -3,6 +3,7 @@ import styled from 'styled-components';
|
|
|
3
3
|
|
|
4
4
|
import type { RatingProps, ReasonsProps } from '@theme/components/Feedback';
|
|
5
5
|
import { Comment, Reasons } from '@theme/components/Feedback';
|
|
6
|
+
import { useTranslate } from '@portal/hooks';
|
|
6
7
|
|
|
7
8
|
type StarsProps = {
|
|
8
9
|
onSubmit: (value: number) => void;
|
|
@@ -20,6 +21,11 @@ export const Rating = ({ settings, onSubmit }: RatingProps): JSX.Element => {
|
|
|
20
21
|
const [score, setScore] = React.useState(0);
|
|
21
22
|
const [comment, setComment] = React.useState('');
|
|
22
23
|
const [reasons, setReasons] = React.useState([] as ReasonsProps['settings']['items']);
|
|
24
|
+
const { translate } = useTranslate();
|
|
25
|
+
const translationKeys = {
|
|
26
|
+
submitText: 'theme.feedback.settings.submitText',
|
|
27
|
+
label: 'theme.feedback.settings.label',
|
|
28
|
+
};
|
|
23
29
|
|
|
24
30
|
if (score && reasonsSettings?.enable && !reasons.length) {
|
|
25
31
|
const { label: reasonsLabel, items, multi } = reasonsSettings;
|
|
@@ -49,14 +55,21 @@ export const Rating = ({ settings, onSubmit }: RatingProps): JSX.Element => {
|
|
|
49
55
|
});
|
|
50
56
|
return (
|
|
51
57
|
<Wrapper>
|
|
52
|
-
<Label
|
|
58
|
+
<Label data-translation-key={translationKeys.submitText}>
|
|
59
|
+
{translate(
|
|
60
|
+
translationKeys.submitText,
|
|
61
|
+
submitText || 'Thank you for helping improve our documentation!',
|
|
62
|
+
)}
|
|
63
|
+
</Label>
|
|
53
64
|
</Wrapper>
|
|
54
65
|
);
|
|
55
66
|
}
|
|
56
67
|
|
|
57
68
|
return (
|
|
58
69
|
<Wrapper data-component-name="Feedback/Rating">
|
|
59
|
-
<Label
|
|
70
|
+
<Label data-translation-key={translationKeys.label}>
|
|
71
|
+
{translate(translationKeys.label, label || 'How helpful was this page?')}
|
|
72
|
+
</Label>
|
|
60
73
|
<Stars max={max || 5} onSubmit={setScore} />
|
|
61
74
|
</Wrapper>
|
|
62
75
|
);
|
|
@@ -3,10 +3,17 @@ import styled from 'styled-components';
|
|
|
3
3
|
|
|
4
4
|
import { Button } from '@theme/components/Button/Button';
|
|
5
5
|
import type { ReasonsProps } from '@theme/components/Feedback';
|
|
6
|
+
import { useTranslate } from '@portal/hooks';
|
|
6
7
|
|
|
7
8
|
export const Reasons = ({ settings, onSubmit }: ReasonsProps): JSX.Element => {
|
|
8
9
|
const { label, multi, buttonText, items = [] } = settings;
|
|
9
10
|
const [checkedState, setCheckedState] = React.useState(new Array(items.length).fill(false));
|
|
11
|
+
const { translate } = useTranslate();
|
|
12
|
+
const translationKeys = {
|
|
13
|
+
label: 'theme.feedback.settings.reasons.label',
|
|
14
|
+
items: 'theme.feedback.settings.reasons.items',
|
|
15
|
+
send: 'theme.feedback.settings.reasons.send',
|
|
16
|
+
};
|
|
10
17
|
|
|
11
18
|
if (!items.length) {
|
|
12
19
|
return <></>;
|
|
@@ -27,8 +34,13 @@ export const Reasons = ({ settings, onSubmit }: ReasonsProps): JSX.Element => {
|
|
|
27
34
|
};
|
|
28
35
|
|
|
29
36
|
return (
|
|
30
|
-
<Wrapper data-component-name="Feedback/Reasons">
|
|
31
|
-
<Label>
|
|
37
|
+
<Wrapper data-component-name="Feedback/Reasons" data-translation-key={translationKeys.label}>
|
|
38
|
+
<Label>
|
|
39
|
+
{translate(
|
|
40
|
+
translationKeys.label,
|
|
41
|
+
label || 'Which statement describes your thoughts about this page?',
|
|
42
|
+
)}
|
|
43
|
+
</Label>
|
|
32
44
|
{items.map((reason, idx) => (
|
|
33
45
|
<OptionWrapper key={reason}>
|
|
34
46
|
<input
|
|
@@ -38,12 +50,18 @@ export const Reasons = ({ settings, onSubmit }: ReasonsProps): JSX.Element => {
|
|
|
38
50
|
name="reasons"
|
|
39
51
|
onChange={() => handleOptionChange(idx)}
|
|
40
52
|
/>
|
|
41
|
-
<label
|
|
42
|
-
{
|
|
53
|
+
<label
|
|
54
|
+
data-translation-key={`${translationKeys.items}.${idx + 1}`}
|
|
55
|
+
id={reason}
|
|
56
|
+
onClick={() => handleOptionChange(idx)}
|
|
57
|
+
>
|
|
58
|
+
{translate(`${translationKeys.items}.${idx + 1}`, reason)}
|
|
43
59
|
</label>
|
|
44
60
|
</OptionWrapper>
|
|
45
61
|
))}
|
|
46
|
-
<SendButton onClick={submitForm}>
|
|
62
|
+
<SendButton data-translation-key={translationKeys.send} onClick={submitForm}>
|
|
63
|
+
{translate(translationKeys.send, buttonText || 'Send')}
|
|
64
|
+
</SendButton>
|
|
47
65
|
</Wrapper>
|
|
48
66
|
);
|
|
49
67
|
};
|
|
@@ -4,12 +4,20 @@ import styled from 'styled-components';
|
|
|
4
4
|
import type { SentimentProps, ReasonsProps } from '@theme/components/Feedback';
|
|
5
5
|
import { Comment, Reasons } from '@theme/components/Feedback';
|
|
6
6
|
import { ThumbUp, ThumbDown } from '@theme/components/Feedback/Thumbs';
|
|
7
|
+
import { useTranslate } from '@portal/hooks';
|
|
7
8
|
|
|
8
9
|
export const Sentiment = ({ settings, onSubmit }: SentimentProps): JSX.Element => {
|
|
9
10
|
const { label, submitText, comment: commentSettings, reasons: reasonsSettings } = settings || {};
|
|
10
11
|
const [score, setScore] = React.useState(0);
|
|
11
12
|
const [comment, setComment] = React.useState('');
|
|
12
13
|
const [reasons, setReasons] = React.useState([] as ReasonsProps['settings']['items']);
|
|
14
|
+
const { translate } = useTranslate();
|
|
15
|
+
const translationKeys = {
|
|
16
|
+
submitText: 'theme.feedback.settings.submitText',
|
|
17
|
+
label: 'theme.feedback.settings.label',
|
|
18
|
+
likeLabel: 'theme.feedback.settings.comment.likeLabel',
|
|
19
|
+
dislikeLabel: 'theme.feedback.settings.comment.dislikeLabel',
|
|
20
|
+
};
|
|
13
21
|
|
|
14
22
|
if (score && reasonsSettings?.enable && !reasons.length) {
|
|
15
23
|
const { label: reasonsLabel, items, multi } = reasonsSettings;
|
|
@@ -25,8 +33,14 @@ export const Sentiment = ({ settings, onSubmit }: SentimentProps): JSX.Element =
|
|
|
25
33
|
if (score && commentSettings?.enable && !comment) {
|
|
26
34
|
const commentLabel =
|
|
27
35
|
score === 1
|
|
28
|
-
?
|
|
29
|
-
|
|
36
|
+
? translate(
|
|
37
|
+
translationKeys.likeLabel,
|
|
38
|
+
commentSettings.likeLabel || 'What was most helpful?',
|
|
39
|
+
)
|
|
40
|
+
: translate(
|
|
41
|
+
translationKeys.dislikeLabel,
|
|
42
|
+
commentSettings.dislikeLabel || 'What can we improve?',
|
|
43
|
+
);
|
|
30
44
|
return (
|
|
31
45
|
<Comment onSubmit={({ comment }) => setComment(comment)} settings={{ label: commentLabel }} />
|
|
32
46
|
);
|
|
@@ -40,14 +54,21 @@ export const Sentiment = ({ settings, onSubmit }: SentimentProps): JSX.Element =
|
|
|
40
54
|
});
|
|
41
55
|
return (
|
|
42
56
|
<Wrapper>
|
|
43
|
-
<Label
|
|
57
|
+
<Label data-translation-key={translationKeys.submitText}>
|
|
58
|
+
{translate(
|
|
59
|
+
translationKeys.submitText,
|
|
60
|
+
submitText || 'Thank you for helping improve our documentation!',
|
|
61
|
+
)}
|
|
62
|
+
</Label>
|
|
44
63
|
</Wrapper>
|
|
45
64
|
);
|
|
46
65
|
}
|
|
47
66
|
|
|
48
67
|
return (
|
|
49
68
|
<Wrapper data-component-name="Feedback/Sentiment">
|
|
50
|
-
<Label
|
|
69
|
+
<Label data-translation-key={translationKeys.label}>
|
|
70
|
+
{translate(translationKeys.label, label || 'Was this page helpful?')}
|
|
71
|
+
</Label>
|
|
51
72
|
<Vote onClick={() => setScore(1)}>
|
|
52
73
|
<ThumbUp text="Yes" />
|
|
53
74
|
</Vote>
|
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
import { useTranslate } from '@portal/hooks';
|
|
5
|
+
|
|
6
|
+
export const ThumbUp = ({ text }: { text?: string }) => {
|
|
7
|
+
const { translate } = useTranslate();
|
|
8
|
+
const translationKeys = {
|
|
9
|
+
thumbUp: 'theme.feedback.sentiment.thumbUp',
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<Wrapper style={{ alignItems: 'normal' }}>
|
|
14
|
+
<Icon>
|
|
15
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 512 512">
|
|
9
16
|
<g>
|
|
10
17
|
<g>
|
|
11
|
-
<
|
|
12
|
-
|
|
18
|
+
<g>
|
|
19
|
+
<path
|
|
20
|
+
d="M495.736,290.773C509.397,282.317,512,269.397,512,260.796c0-22.4-18.253-47.462-42.667-47.462H349.918
|
|
13
21
|
c-4.284-0.051-25.651-1.51-25.651-25.6c0-4.71-3.814-8.533-8.533-8.533s-8.533,3.823-8.533,8.533
|
|
14
22
|
c0,33.749,27.913,42.667,42.667,42.667h119.467c14.182,0,25.6,16.631,25.6,30.396c0,4.437,0,17.946-26.53,20.855
|
|
15
23
|
c-4.506,0.495-7.834,4.42-7.586,8.951c0.239,4.523,3.985,8.064,8.516,8.064c14.114,0,25.6,11.486,25.6,25.6
|
|
@@ -20,45 +28,51 @@ export const ThumbUp = ({ text }: { text?: string }) => (
|
|
|
20
28
|
c15.497,8.542,31.505,17.374,71.526,17.374h128c17.869,0,34.133-16.273,34.133-34.133c0-6.229-1.775-12.134-4.83-17.229
|
|
21
29
|
c21.794-1.877,38.963-20.224,38.963-42.505c0-10.829-4.062-20.736-10.735-28.271C500.42,358.212,512,342.571,512,324.267
|
|
22
30
|
C512,310.699,505.634,298.59,495.736,290.773z"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
31
|
+
/>
|
|
32
|
+
<path
|
|
33
|
+
d="M76.8,443.733c9.412,0,17.067-7.654,17.067-17.067S86.212,409.6,76.8,409.6c-9.412,0-17.067,7.654-17.067,17.067
|
|
26
34
|
S67.388,443.733,76.8,443.733z"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
35
|
+
/>
|
|
36
|
+
<path
|
|
37
|
+
d="M179.2,247.467c25.353,0,57.429-28.297,74.3-45.167c36.634-36.634,36.634-82.167,36.634-151.1
|
|
30
38
|
c0-5.342,3.191-8.533,8.533-8.533c29.508,0,42.667,13.158,42.667,42.667v102.4c0,4.71,3.814,8.533,8.533,8.533
|
|
31
39
|
s8.533-3.823,8.533-8.533v-102.4c0-39.083-20.659-59.733-59.733-59.733c-14.831,0-25.6,10.769-25.6,25.6
|
|
32
40
|
c0,66.978,0,107.401-31.633,139.034C216.661,215.006,192.811,230.4,179.2,230.4c-4.719,0-8.533,3.823-8.533,8.533
|
|
33
41
|
S174.481,247.467,179.2,247.467z"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
/>
|
|
43
|
+
<path
|
|
44
|
+
d="M145.067,213.333H8.533c-4.719,0-8.533,3.823-8.533,8.533v256c0,4.71,3.814,8.533,8.533,8.533h136.533
|
|
37
45
|
c4.719,0,8.533-3.823,8.533-8.533v-256C153.6,217.156,149.786,213.333,145.067,213.333z M136.533,469.333H17.067V230.4h119.467
|
|
38
46
|
V469.333z"
|
|
39
|
-
|
|
47
|
+
/>
|
|
48
|
+
</g>
|
|
40
49
|
</g>
|
|
41
50
|
</g>
|
|
42
|
-
</
|
|
43
|
-
</
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
51
|
+
</svg>
|
|
52
|
+
</Icon>
|
|
53
|
+
<span>{translate(translationKeys.thumbUp, text || 'Yes')}</span>
|
|
54
|
+
</Wrapper>
|
|
55
|
+
);
|
|
56
|
+
};
|
|
48
57
|
|
|
49
|
-
export const ThumbDown = ({ text }: { text?: string }) =>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
58
|
+
export const ThumbDown = ({ text }: { text?: string }) => {
|
|
59
|
+
const { translate } = useTranslate();
|
|
60
|
+
const translationKeys = {
|
|
61
|
+
thumbDown: 'theme.feedback.sentiment.thumbDown',
|
|
62
|
+
};
|
|
63
|
+
return (
|
|
64
|
+
<Wrapper style={{ alignItems: 'end' }}>
|
|
65
|
+
<Icon>
|
|
66
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 512 512">
|
|
54
67
|
<g>
|
|
55
68
|
<g>
|
|
56
|
-
<
|
|
57
|
-
|
|
69
|
+
<g>
|
|
70
|
+
<path
|
|
71
|
+
d="M76.8,247.467c9.412,0,17.067-7.654,17.067-17.067c0-9.412-7.654-17.067-17.067-17.067
|
|
58
72
|
c-9.412,0-17.067,7.654-17.067,17.067C59.733,239.812,67.388,247.467,76.8,247.467z"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
73
|
+
/>
|
|
74
|
+
<path
|
|
75
|
+
d="M495.736,221.227C505.634,213.41,512,201.301,512,187.733c0-18.295-11.58-33.946-27.802-39.996
|
|
62
76
|
c6.673-7.535,10.735-17.434,10.735-28.271c0-22.281-17.169-40.627-38.963-42.505c3.055-5.094,4.83-10.999,4.83-17.229
|
|
63
77
|
c0-17.86-16.265-34.133-34.133-34.133h-128c-40.021,0-56.03,8.832-71.526,17.374c-11.827,6.519-24.047,13.261-49.152,16.845
|
|
64
78
|
c-4.668,0.666-7.902,4.992-7.236,9.66c0.666,4.659,4.949,7.885,9.66,7.236c28.177-4.028,42.411-11.87,54.963-18.79
|
|
@@ -69,26 +83,27 @@ export const ThumbDown = ({ text }: { text?: string }) => (
|
|
|
69
83
|
c26.53,2.91,26.53,16.418,26.53,20.847c0,13.773-11.418,30.404-25.6,30.404H349.867c-14.763,0-42.667,8.917-42.667,42.667
|
|
70
84
|
c0,4.71,3.814,8.533,8.533,8.533s8.533-3.823,8.533-8.533c0-24.09,21.367-25.549,25.6-25.6h119.467
|
|
71
85
|
c24.414,0,42.667-25.054,42.667-47.471C512,242.603,509.397,229.683,495.736,221.227z"
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
86
|
+
/>
|
|
87
|
+
<path
|
|
88
|
+
d="M349.867,315.733c-4.719,0-8.533,3.823-8.533,8.533v102.4c0,29.508-13.158,42.667-42.667,42.667
|
|
75
89
|
c-5.342,0-8.533-3.192-8.533-8.533c0-68.932,0-114.466-36.634-151.1c-16.87-16.87-48.947-45.167-74.3-45.167
|
|
76
90
|
c-4.719,0-8.533,3.823-8.533,8.533s3.814,8.533,8.533,8.533c13.611,0,37.461,15.394,62.234,40.166
|
|
77
91
|
c31.633,31.633,31.633,72.055,31.633,139.034c0,14.831,10.769,25.6,25.6,25.6c39.074,0,59.733-20.651,59.733-59.733v-102.4
|
|
78
92
|
C358.4,319.556,354.586,315.733,349.867,315.733z"
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
93
|
+
/>
|
|
94
|
+
<path
|
|
95
|
+
d="M145.067,25.6H8.533C3.814,25.6,0,29.423,0,34.133v256c0,4.71,3.814,8.533,8.533,8.533h136.533
|
|
82
96
|
c4.719,0,8.533-3.823,8.533-8.533v-256C153.6,29.423,149.786,25.6,145.067,25.6z M136.533,281.6H17.067V42.667h119.467V281.6z"
|
|
83
|
-
|
|
97
|
+
/>
|
|
98
|
+
</g>
|
|
84
99
|
</g>
|
|
85
100
|
</g>
|
|
86
|
-
</
|
|
87
|
-
</
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
101
|
+
</svg>
|
|
102
|
+
</Icon>
|
|
103
|
+
<span>{translate(translationKeys.thumbDown, text || 'No')}</span>
|
|
104
|
+
</Wrapper>
|
|
105
|
+
);
|
|
106
|
+
};
|
|
92
107
|
|
|
93
108
|
const Wrapper = styled.div`
|
|
94
109
|
font-family: var(--font-family-base);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
2
|
|
|
3
3
|
import type { ReportDialogProps } from '@theme/components/Feedback/types';
|
|
4
|
+
import { useTranslate } from '@portal/hooks';
|
|
4
5
|
|
|
5
6
|
type ReportSettings = {
|
|
6
7
|
hide?: boolean;
|
|
@@ -11,6 +12,11 @@ type ReportSettings = {
|
|
|
11
12
|
export function useReportDialog(reportSettings: ReportSettings): Record<string, any> {
|
|
12
13
|
const [isReportDialogShown, setIsReportDialogShown] = useState(false);
|
|
13
14
|
const isReportButtonShown = reportSettings.hide === false; // TODO: report temporary disabled by default
|
|
15
|
+
const { translate } = useTranslate();
|
|
16
|
+
const translationKeys = {
|
|
17
|
+
tooltipText: 'theme.codeSnippet.report.tooltipText',
|
|
18
|
+
label: 'theme.codeSnippet.report.label',
|
|
19
|
+
};
|
|
14
20
|
|
|
15
21
|
const showReportDialog = () => {
|
|
16
22
|
setIsReportDialogShown(true);
|
|
@@ -20,11 +26,14 @@ export function useReportDialog(reportSettings: ReportSettings): Record<string,
|
|
|
20
26
|
};
|
|
21
27
|
const reportButtonProps = {
|
|
22
28
|
onClick: showReportDialog,
|
|
23
|
-
title: reportSettings.tooltipText || 'Report a problem',
|
|
29
|
+
title: translate(translationKeys.tooltipText, reportSettings.tooltipText || 'Report a problem'),
|
|
24
30
|
};
|
|
25
31
|
const reportDialogProps: Partial<ReportDialogProps> = {
|
|
26
32
|
settings: {
|
|
27
|
-
label:
|
|
33
|
+
label: translate(
|
|
34
|
+
translationKeys.label,
|
|
35
|
+
reportSettings.label || 'What is wrong with this code?',
|
|
36
|
+
),
|
|
28
37
|
},
|
|
29
38
|
onSubmit: hideReportDialog,
|
|
30
39
|
onCancel: hideReportDialog,
|
|
@@ -3,25 +3,33 @@ import styled from 'styled-components';
|
|
|
3
3
|
|
|
4
4
|
import type { ResolvedFilter } from '@theme/types/portal/src/shared/types/catalog';
|
|
5
5
|
import { Checkbox } from '@theme/ui/Checkbox';
|
|
6
|
+
import { useTranslate } from '@portal/hooks';
|
|
6
7
|
|
|
7
8
|
export function Filter({ filter }: { filter: ResolvedFilter }) {
|
|
9
|
+
const { translate } = useTranslate();
|
|
10
|
+
const translationKeys = {
|
|
11
|
+
selectAll: 'theme.catalog.filters.select.all',
|
|
12
|
+
};
|
|
13
|
+
|
|
8
14
|
if (!filter.parentUsed) return null;
|
|
9
15
|
return (
|
|
10
16
|
<FilterGroup key={filter.property + filter.title}>
|
|
11
|
-
<FilterTitle>{filter.title}</FilterTitle>
|
|
17
|
+
<FilterTitle>{translate(filter.titleTranslationKey, filter.title)}</FilterTitle>
|
|
12
18
|
{filter.type === 'select' ? (
|
|
13
19
|
<StyledSelect
|
|
14
20
|
onChange={(e) => filter.selectOption(e.target.value)}
|
|
15
21
|
value={filter.selectedOptions.values().next()?.value || ''}
|
|
16
22
|
>
|
|
17
|
-
<option key="none" value="">
|
|
18
|
-
All
|
|
23
|
+
<option key="none" value="" data-translation-key={translationKeys.selectAll}>
|
|
24
|
+
{translate(translationKeys.selectAll, 'All')}
|
|
19
25
|
</option>
|
|
20
|
-
{filter.filteredOptions.map((value: any) =>
|
|
21
|
-
|
|
22
|
-
{value.value}
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
{filter.filteredOptions.map((value: any) => {
|
|
27
|
+
return (
|
|
28
|
+
<option key={value.value} value={value.value}>
|
|
29
|
+
{translate(value.value)} ({value.count})
|
|
30
|
+
</option>
|
|
31
|
+
);
|
|
32
|
+
})}
|
|
25
33
|
</StyledSelect>
|
|
26
34
|
) : (
|
|
27
35
|
filter.filteredOptions.map((value: any) => {
|
|
@@ -35,7 +43,7 @@ export function Filter({ filter }: { filter: ResolvedFilter }) {
|
|
|
35
43
|
onChange={() => filter.toggleOption(value.value)}
|
|
36
44
|
/>
|
|
37
45
|
<label htmlFor={id}>
|
|
38
|
-
{value.value} ({value.count})
|
|
46
|
+
{translate(value.value)} ({value.count})
|
|
39
47
|
</label>
|
|
40
48
|
</FilterValue>
|
|
41
49
|
);
|
|
@@ -3,15 +3,17 @@ import styled from 'styled-components';
|
|
|
3
3
|
|
|
4
4
|
import { Link } from '@portal/Link';
|
|
5
5
|
import type { ResolvedNavItem } from '@theme/types/portal';
|
|
6
|
+
import { useTranslate } from '@portal/hooks';
|
|
6
7
|
|
|
7
8
|
interface FooterColumnProps {
|
|
8
9
|
column: ResolvedNavItem;
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
export function FooterColumn({ column }: FooterColumnProps): JSX.Element {
|
|
13
|
+
const { translate } = useTranslate();
|
|
12
14
|
return (
|
|
13
15
|
<FooterColumnContainer data-component-name="Footer/FooterColumn">
|
|
14
|
-
<FooterColumnTitle>{column.label}</FooterColumnTitle>
|
|
16
|
+
<FooterColumnTitle>{translate(column.labelTranslationKey, column.label)}</FooterColumnTitle>
|
|
15
17
|
{column?.items?.map((columnItem, columnItemIndex) => {
|
|
16
18
|
if (columnItem.type === 'error') {
|
|
17
19
|
return null;
|
|
@@ -19,7 +21,7 @@ export function FooterColumn({ column }: FooterColumnProps): JSX.Element {
|
|
|
19
21
|
|
|
20
22
|
return columnItem.type === 'separator' ? (
|
|
21
23
|
<FooterSeparator key={columnItem.label + '_' + columnItemIndex}>
|
|
22
|
-
{columnItem.label}
|
|
24
|
+
{translate(columnItem.labelTranslationKey, columnItem.label)}
|
|
23
25
|
</FooterSeparator>
|
|
24
26
|
) : (
|
|
25
27
|
<FooterLink
|
|
@@ -29,7 +31,7 @@ export function FooterColumn({ column }: FooterColumnProps): JSX.Element {
|
|
|
29
31
|
target={columnItem.target}
|
|
30
32
|
data-cy={columnItem.label}
|
|
31
33
|
>
|
|
32
|
-
{columnItem.label}
|
|
34
|
+
{translate(columnItem.labelTranslationKey, columnItem.label)}
|
|
33
35
|
</FooterLink>
|
|
34
36
|
);
|
|
35
37
|
})}
|
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
|
-
import
|
|
4
|
+
import { useTranslate } from '@portal/hooks';
|
|
5
5
|
|
|
6
6
|
interface FooterCopyrightProps {
|
|
7
|
-
copyrightText:
|
|
7
|
+
copyrightText: string;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export function FooterCopyright({ copyrightText = '' }: FooterCopyrightProps): JSX.Element | null {
|
|
11
|
+
const { translate } = useTranslate();
|
|
12
|
+
const translationKeys = {
|
|
13
|
+
copyrightText: 'theme.footer.copyrightText',
|
|
14
|
+
};
|
|
11
15
|
return copyrightText ? (
|
|
12
|
-
<Wrapper
|
|
16
|
+
<Wrapper
|
|
17
|
+
data-component-name="Footer/FooterCopyright"
|
|
18
|
+
data-translation-key={translationKeys.copyrightText}
|
|
19
|
+
>
|
|
20
|
+
{translate(translationKeys.copyrightText, copyrightText)}
|
|
21
|
+
</Wrapper>
|
|
13
22
|
) : null;
|
|
14
23
|
}
|
|
15
24
|
|
|
@@ -3,6 +3,7 @@ import styled from 'styled-components';
|
|
|
3
3
|
import { format } from 'timeago.js';
|
|
4
4
|
|
|
5
5
|
import { useThemeConfig } from '@theme/hooks/useThemeConfig';
|
|
6
|
+
import { useTranslate } from '@portal/hooks';
|
|
6
7
|
|
|
7
8
|
const FORMATS = {
|
|
8
9
|
timeago: (date: Date, locale: string) => format(date, locale),
|
|
@@ -21,6 +22,7 @@ export interface LastUpdatedProps {
|
|
|
21
22
|
|
|
22
23
|
export function LastUpdated(props: LastUpdatedProps): JSX.Element | null {
|
|
23
24
|
const { markdown: { lastUpdatedBlock = {} } = {} } = useThemeConfig();
|
|
25
|
+
const { translate } = useTranslate();
|
|
24
26
|
|
|
25
27
|
if (lastUpdatedBlock?.hide) {
|
|
26
28
|
return null;
|
|
@@ -32,16 +34,22 @@ export function LastUpdated(props: LastUpdatedProps): JSX.Element | null {
|
|
|
32
34
|
const isoDate = lastModified.toISOString().split('T')[0];
|
|
33
35
|
|
|
34
36
|
const lastUpdatedString = FORMATS[format as keyof typeof FORMATS](lastModified, locale);
|
|
37
|
+
const translationKey =
|
|
38
|
+
format === 'timeago' ? 'theme.page.lastUpdated.timeago' : 'theme.page.lastUpdated.on';
|
|
35
39
|
|
|
36
|
-
const
|
|
40
|
+
const text =
|
|
41
|
+
format === 'timeago'
|
|
42
|
+
? translate(translationKey, 'Last updated ')
|
|
43
|
+
: translate(translationKey, 'Last updated on');
|
|
37
44
|
|
|
38
45
|
return (
|
|
39
46
|
<Wrapper
|
|
40
47
|
data-component-name="LastUpdated/LastUpdated"
|
|
41
48
|
rawOnPrint={format === 'timeago'}
|
|
42
49
|
data-print-datetime={isoDate}
|
|
50
|
+
data-translation-key={translationKey}
|
|
43
51
|
>
|
|
44
|
-
|
|
52
|
+
{text}
|
|
45
53
|
{/* TODO: fix issue with snapshot tests - they should not depend on current date */}
|
|
46
54
|
<time dateTime={isoDate}>{lastUpdatedString}</time>
|
|
47
55
|
</Wrapper>
|
|
@@ -8,6 +8,7 @@ import { EditPageButton } from '@theme/components/EditPageButton';
|
|
|
8
8
|
import { LastUpdated } from '@theme/components/LastUpdated/LastUpdated';
|
|
9
9
|
import { useThemeConfig } from '@theme/hooks';
|
|
10
10
|
import type { ResolvedNavItemWithLink } from '@theme/types/portal';
|
|
11
|
+
import { useTranslate } from '@portal/hooks';
|
|
11
12
|
|
|
12
13
|
type MarkdownLayoutProps = {
|
|
13
14
|
tableOfContent: React.ReactNode;
|
|
@@ -34,6 +35,10 @@ export function MarkdownLayout({
|
|
|
34
35
|
prevPage,
|
|
35
36
|
}: MarkdownLayoutProps): JSX.Element {
|
|
36
37
|
const { markdown } = useThemeConfig();
|
|
38
|
+
const { translate } = useTranslate();
|
|
39
|
+
const translationKeys = {
|
|
40
|
+
text: 'theme.markdown.editPage.text',
|
|
41
|
+
};
|
|
37
42
|
const { editPage: themeEditPage } = markdown || {};
|
|
38
43
|
|
|
39
44
|
const mergedConf = editPage ? { ...themeEditPage, ...editPage } : undefined;
|
|
@@ -44,7 +49,12 @@ export function MarkdownLayout({
|
|
|
44
49
|
<LayoutTop>
|
|
45
50
|
{lastModified && <LastUpdated lastModified={new Date(lastModified)} />}
|
|
46
51
|
{mergedConf && (
|
|
47
|
-
<EditPageButton
|
|
52
|
+
<EditPageButton
|
|
53
|
+
text={translate(translationKeys.text, mergedConf.text)}
|
|
54
|
+
to={mergedConf.to}
|
|
55
|
+
icon={mergedConf.icon}
|
|
56
|
+
data-translation-key={translationKeys.text}
|
|
57
|
+
/>
|
|
48
58
|
)}
|
|
49
59
|
</LayoutTop>
|
|
50
60
|
{markdownWrapper}
|
|
@@ -352,6 +352,10 @@ export const MarkdownWrapper = styled.main.attrs(() => ({
|
|
|
352
352
|
list-style: var(--md-list-item-style);
|
|
353
353
|
}
|
|
354
354
|
|
|
355
|
+
ul > li:has(input[type='checkbox']) {
|
|
356
|
+
list-style: var(--md-checkbox-list-item-style);
|
|
357
|
+
}
|
|
358
|
+
|
|
355
359
|
ol > li {
|
|
356
360
|
list-style: var(--md-numbered-list-item-style);
|
|
357
361
|
}
|
|
@@ -6,6 +6,7 @@ import { MenuLinkItem } from '@theme/components/Menu/MenuLinkItem';
|
|
|
6
6
|
import { MenuItemLabel } from '@theme/components/Menu/MenuItemLabel';
|
|
7
7
|
import { SeparatorLine } from '@theme/components/Separator/SeparatorLine';
|
|
8
8
|
import type { ItemState } from '@theme/components/Sidebar/types';
|
|
9
|
+
import { useTranslate } from '@portal/hooks';
|
|
9
10
|
|
|
10
11
|
interface MenuGroupProps {
|
|
11
12
|
item: ItemState;
|
|
@@ -21,6 +22,8 @@ export function MenuGroup({
|
|
|
21
22
|
}: React.PropsWithChildren<MenuGroupProps>): JSX.Element {
|
|
22
23
|
const [showChildren, setShowChildren] = useState<boolean>(isExpanded);
|
|
23
24
|
const timer = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
25
|
+
const { translate } = useTranslate();
|
|
26
|
+
|
|
24
27
|
useEffect(() => {
|
|
25
28
|
timer.current && clearTimeout(timer.current);
|
|
26
29
|
if (isExpanded) {
|
|
@@ -47,7 +50,7 @@ export function MenuGroup({
|
|
|
47
50
|
visibility={item.items.length ? 'visible' : 'hidden'}
|
|
48
51
|
direction={isExpanded ? 'down' : 'right'}
|
|
49
52
|
/>
|
|
50
|
-
{item.label}
|
|
53
|
+
{translate(item.labelTranslationKey, item.label)}
|
|
51
54
|
</MenuGroupLabel>
|
|
52
55
|
</MenuLinkItem>
|
|
53
56
|
|
|
@@ -6,13 +6,15 @@ import { ExternalIcon } from '@theme/icons/ExternalIcon';
|
|
|
6
6
|
import { MenuItemLabel } from '@theme/components/Menu/MenuItemLabel';
|
|
7
7
|
import { SeparatorLine } from '@theme/components/Separator/SeparatorLine';
|
|
8
8
|
import type { MenuItemProps } from '@theme/components/Sidebar/types';
|
|
9
|
+
import { useTranslate } from '@portal/hooks';
|
|
9
10
|
|
|
10
11
|
export function MenuItem({ item }: MenuItemProps): JSX.Element {
|
|
12
|
+
const { translate } = useTranslate();
|
|
11
13
|
return (
|
|
12
14
|
<Wrapper data-component-name="Sidebar/MenuItem">
|
|
13
15
|
<MenuLinkItem item={item}>
|
|
14
16
|
<MenuItemLabel active={item.active}>
|
|
15
|
-
{item.label}
|
|
17
|
+
{translate(item.labelTranslationKey, item.label)}
|
|
16
18
|
{item.external ? <ExternalIcon dataComponentName="Sidebar/ExternalIcon" /> : null}
|
|
17
19
|
</MenuItemLabel>
|
|
18
20
|
</MenuLinkItem>
|
|
@@ -3,6 +3,8 @@ import styled from 'styled-components';
|
|
|
3
3
|
import { useLocation } from 'react-router-dom';
|
|
4
4
|
|
|
5
5
|
import { Link } from '@portal/Link';
|
|
6
|
+
import { useI18nConfig } from '@portal/hooks';
|
|
7
|
+
import { getPathnameForLocale } from '@portal/utils';
|
|
6
8
|
import type {
|
|
7
9
|
ResolvedNavItem,
|
|
8
10
|
ResolvedNavLinkItem,
|
|
@@ -21,10 +23,14 @@ export function MobileNavbarItem({ navItem, className }: NavbarItemProps): JSX.E
|
|
|
21
23
|
const { pathname } = useLocation();
|
|
22
24
|
const [expandedDropdown, setExpandedDropdown] = useState(false);
|
|
23
25
|
const toggleDropdown = () => setExpandedDropdown(!expandedDropdown);
|
|
26
|
+
const { defaultLocale, currentLocale, locales } = useI18nConfig();
|
|
24
27
|
|
|
25
28
|
if ((navItem as ResolvedNavLinkItem).link) {
|
|
26
29
|
const item = navItem as ResolvedNavLinkItem;
|
|
27
|
-
const isActive =
|
|
30
|
+
const isActive =
|
|
31
|
+
pathname ===
|
|
32
|
+
withPathPrefix(getPathnameForLocale(item.link, defaultLocale, currentLocale, locales));
|
|
33
|
+
|
|
28
34
|
return (
|
|
29
35
|
<NavMenuItem
|
|
30
36
|
active={isActive}
|