@redocly/theme 0.7.4 → 0.7.5
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/Catalog/Catalog.d.ts +8 -0
- package/lib/Catalog/Catalog.js +167 -0
- package/lib/Catalog/CatalogCard.d.ts +5 -0
- package/lib/Catalog/CatalogCard.js +113 -0
- package/lib/Catalog/Filter.d.ts +5 -0
- package/lib/Catalog/Filter.js +88 -0
- package/lib/Catalog/Tags.d.ts +4 -0
- package/lib/Catalog/Tags.js +32 -0
- package/lib/Feedback/ReportDialog.d.ts +3 -0
- package/lib/Feedback/ReportDialog.js +66 -0
- package/lib/Feedback/index.d.ts +2 -0
- package/lib/Feedback/index.js +5 -1
- package/lib/Feedback/types.d.ts +5 -3
- package/lib/Feedback/useReportDialog.d.ts +7 -0
- package/lib/Feedback/useReportDialog.js +28 -0
- package/lib/Markdown/CodeSample/CodeSample.js +5 -38
- package/lib/Sidebar/ArrowBack.js +2 -2
- package/lib/Sidebar/SidebarLayout.d.ts +5 -1
- package/lib/Sidebar/SidebarLayout.js +26 -1
- package/lib/config.js +2 -2
- package/lib/globalStyle.js +12 -10
- package/lib/mocks/hooks/index.d.ts +4 -0
- package/lib/mocks/hooks/index.js +9 -1
- package/lib/ui/Checkbox.d.ts +1 -0
- package/lib/ui/Checkbox.js +70 -0
- package/lib/ui/Highlight.d.ts +5 -0
- package/lib/ui/Highlight.js +63 -0
- package/lib/ui/darkColors.js +4 -2
- package/package.json +4 -2
- package/src/Catalog/Catalog.tsx +198 -0
- package/src/Catalog/CatalogCard.tsx +95 -0
- package/src/Catalog/Filter.tsx +103 -0
- package/src/Catalog/Tags.tsx +36 -0
- package/src/Feedback/ReportDialog.tsx +51 -0
- package/src/Feedback/index.ts +2 -0
- package/src/Feedback/types.ts +5 -3
- package/src/Feedback/useReportDialog.ts +34 -0
- package/src/Markdown/CodeSample/CodeSample.tsx +7 -50
- package/src/Sidebar/ArrowBack.tsx +2 -2
- package/src/Sidebar/SidebarLayout.tsx +38 -1
- package/src/config.ts +2 -2
- package/src/globalStyle.ts +12 -10
- package/src/mocks/hooks/index.ts +10 -1
- package/src/types/portal/src/shared/types/catalog.d.ts +55 -0
- package/src/ui/Checkbox.tsx +64 -0
- package/src/ui/Highlight.tsx +48 -0
- package/src/ui/darkColors.tsx +4 -2
- package/lib/hooks/useReportDialog.d.ts +0 -1
- package/lib/hooks/useReportDialog.js +0 -16
- package/src/hooks/useReportDialog.ts +0 -14
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
|
|
4
|
+
import type { ResolvedFilter } from '@theme/types/portal/src/shared/types/catalog';
|
|
5
|
+
import { Checkbox } from '@theme/ui/Checkbox';
|
|
6
|
+
|
|
7
|
+
export function Filter({ filter }: { filter: ResolvedFilter }) {
|
|
8
|
+
if (!filter.parentUsed) return null;
|
|
9
|
+
return (
|
|
10
|
+
<FilterGroup key={filter.property + filter.title}>
|
|
11
|
+
<FilterTitle>{filter.title} filter</FilterTitle>
|
|
12
|
+
{filter.type === 'select' ? (
|
|
13
|
+
<StyledSelect
|
|
14
|
+
onChange={(e) => filter.selectOption(e.target.value)}
|
|
15
|
+
value={filter.selectedOptions.values().next()?.value || ''}
|
|
16
|
+
>
|
|
17
|
+
<option key="none" value="">
|
|
18
|
+
All
|
|
19
|
+
</option>
|
|
20
|
+
{filter.filteredOptions.map((value: any) => (
|
|
21
|
+
<option key={value.value} value={value.value}>
|
|
22
|
+
{value.value} ({value.count})
|
|
23
|
+
</option>
|
|
24
|
+
))}
|
|
25
|
+
</StyledSelect>
|
|
26
|
+
) : (
|
|
27
|
+
filter.filteredOptions.map((value: any) => {
|
|
28
|
+
const id = 'filter--' + filter.property + '--' + slug(value.value);
|
|
29
|
+
return (
|
|
30
|
+
<FilterValue key={id}>
|
|
31
|
+
<Checkbox
|
|
32
|
+
type="checkbox"
|
|
33
|
+
id={id}
|
|
34
|
+
checked={filter.selectedOptions.has(value.value)}
|
|
35
|
+
onChange={() => filter.toggleOption(value.value)}
|
|
36
|
+
/>
|
|
37
|
+
<label htmlFor={id}>
|
|
38
|
+
{value.value} ({value.count})
|
|
39
|
+
</label>
|
|
40
|
+
</FilterValue>
|
|
41
|
+
);
|
|
42
|
+
})
|
|
43
|
+
)}
|
|
44
|
+
</FilterGroup>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const FilterGroup = styled.div`
|
|
49
|
+
padding: 16px 0;
|
|
50
|
+
border-bottom: 1px solid var(--border-color);
|
|
51
|
+
|
|
52
|
+
&:last-of-type {
|
|
53
|
+
border-bottom: none;
|
|
54
|
+
}
|
|
55
|
+
`;
|
|
56
|
+
|
|
57
|
+
const FilterTitle = styled.h4`
|
|
58
|
+
font-size: 18px;
|
|
59
|
+
font-weight: var(--font-weight-bold);
|
|
60
|
+
margin: 0;
|
|
61
|
+
margin-bottom: 16px;
|
|
62
|
+
`;
|
|
63
|
+
|
|
64
|
+
const FilterValue = styled.label`
|
|
65
|
+
display: block;
|
|
66
|
+
cursor: pointer;
|
|
67
|
+
font-size: 16px;
|
|
68
|
+
margin: 8px 0;
|
|
69
|
+
|
|
70
|
+
input {
|
|
71
|
+
cursor: pointer;
|
|
72
|
+
}
|
|
73
|
+
`;
|
|
74
|
+
|
|
75
|
+
const StyledSelect = styled.select`
|
|
76
|
+
border: 1px solid rgba(0, 0, 0, 0.23);
|
|
77
|
+
|
|
78
|
+
padding: var(--input-padding);
|
|
79
|
+
border-radius: var(--input-border-radius);
|
|
80
|
+
background-color: var(--input-background-color);
|
|
81
|
+
color: var(--text-color);
|
|
82
|
+
font-family: var(--input-font-family);
|
|
83
|
+
font-size: var(--input-font-size);
|
|
84
|
+
line-height: var(--input-line-height);
|
|
85
|
+
|
|
86
|
+
min-width: 200px;
|
|
87
|
+
outline-color: var(--color-primary-500);
|
|
88
|
+
transition: outline 0.25s ease;
|
|
89
|
+
display: inline-block;
|
|
90
|
+
text-align: left;
|
|
91
|
+
appearance: none;
|
|
92
|
+
|
|
93
|
+
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
|
|
94
|
+
background-repeat: no-repeat;
|
|
95
|
+
background-position: right 10px center;
|
|
96
|
+
background-size: 1em;
|
|
97
|
+
width: 100%;
|
|
98
|
+
`;
|
|
99
|
+
|
|
100
|
+
// TODO: import from portal
|
|
101
|
+
function slug(str: string): string {
|
|
102
|
+
return str.replace(/\s/g, '-').toLowerCase();
|
|
103
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
|
|
4
|
+
import { Highlight } from '@theme/ui/Highlight';
|
|
5
|
+
|
|
6
|
+
export function Tags({ tags }: { tags: string[] }) {
|
|
7
|
+
return (
|
|
8
|
+
<TagsWrapper>
|
|
9
|
+
{tags.map((tag) => (
|
|
10
|
+
<Tag key={tag} className={'tag-' + slug(tag)}>
|
|
11
|
+
<Highlight>{tag}</Highlight>
|
|
12
|
+
</Tag>
|
|
13
|
+
))}
|
|
14
|
+
</TagsWrapper>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const TagsWrapper = styled.div`
|
|
19
|
+
margin-top: 16px;
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
const Tag = styled.div`
|
|
23
|
+
display: inline-block;
|
|
24
|
+
background-color: #d3f4ef;
|
|
25
|
+
color: #000;
|
|
26
|
+
padding: 2px 5px;
|
|
27
|
+
border-radius: var(--border-radius);
|
|
28
|
+
margin-right: 5px;
|
|
29
|
+
margin-bottom: 5px;
|
|
30
|
+
font-size: 0.8em;
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
// TODO: import from portal
|
|
34
|
+
function slug(str: string): string {
|
|
35
|
+
return str.replace(/\s/g, '-').toLowerCase();
|
|
36
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
|
|
4
|
+
import { Comment } from '@theme/Feedback/Comment';
|
|
5
|
+
import type { ReportDialogProps } from '@theme/Feedback';
|
|
6
|
+
import { useSubmitFeedback } from '@portal/Feedback/useSubmitFeedback';
|
|
7
|
+
|
|
8
|
+
export const ReportDialog = ({
|
|
9
|
+
location,
|
|
10
|
+
settings,
|
|
11
|
+
onSubmit,
|
|
12
|
+
onCancel,
|
|
13
|
+
}: ReportDialogProps): JSX.Element => {
|
|
14
|
+
const { label } = settings;
|
|
15
|
+
const { submitFeedback } = useSubmitFeedback();
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<Wrapper className="modal">
|
|
19
|
+
<Comment
|
|
20
|
+
settings={{ label, onCancel }}
|
|
21
|
+
onSubmit={(value) => {
|
|
22
|
+
submitFeedback('problem', { ...value, location });
|
|
23
|
+
onSubmit();
|
|
24
|
+
}}
|
|
25
|
+
/>
|
|
26
|
+
</Wrapper>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const Wrapper = styled.div`
|
|
31
|
+
font-family: var(--font-family-base);
|
|
32
|
+
position: fixed;
|
|
33
|
+
top: 0;
|
|
34
|
+
left: 0;
|
|
35
|
+
width: 100vw;
|
|
36
|
+
height: 100vh;
|
|
37
|
+
background: var(--modal-overlay-background-color);
|
|
38
|
+
z-index: 10000;
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
justify-content: center;
|
|
42
|
+
|
|
43
|
+
& > * {
|
|
44
|
+
background: var(--modal-background-color);
|
|
45
|
+
box-shadow: var(--modal-box-shadow);
|
|
46
|
+
padding: 15px;
|
|
47
|
+
margin: 15px;
|
|
48
|
+
max-width: 500px;
|
|
49
|
+
max-height: 300px;
|
|
50
|
+
}
|
|
51
|
+
`;
|
package/src/Feedback/index.ts
CHANGED
|
@@ -2,4 +2,6 @@ export { Rating } from '@theme/Feedback/Rating';
|
|
|
2
2
|
export { Sentiment } from '@theme/Feedback/Sentiment';
|
|
3
3
|
export { Comment } from '@theme/Feedback/Comment';
|
|
4
4
|
export { Reasons } from '@theme/Feedback/Reasons';
|
|
5
|
+
export { ReportDialog } from '@theme/Feedback/ReportDialog';
|
|
6
|
+
export { useReportDialog } from '@theme/Feedback/useReportDialog';
|
|
5
7
|
export * from './types';
|
package/src/Feedback/types.ts
CHANGED
|
@@ -56,9 +56,11 @@ export type ReasonsProps = {
|
|
|
56
56
|
};
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
-
export type
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
export type ReportDialogProps = {
|
|
60
|
+
location: string;
|
|
61
|
+
onSubmit: () => void;
|
|
62
|
+
onCancel: () => void;
|
|
63
|
+
settings: {
|
|
62
64
|
label?: string;
|
|
63
65
|
};
|
|
64
66
|
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import type { ReportDialogProps } from '@theme/Feedback/types';
|
|
4
|
+
|
|
5
|
+
type ReportSettings = {
|
|
6
|
+
hide?: boolean;
|
|
7
|
+
label?: string;
|
|
8
|
+
tooltipText?: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export function useReportDialog(reportSettings: ReportSettings): Record<string, any> {
|
|
12
|
+
const [isReportDialogShown, setIsReportDialogShown] = useState(false);
|
|
13
|
+
const isReportButtonShown = reportSettings.hide === false; // TODO: report temporary disabled by default
|
|
14
|
+
|
|
15
|
+
const showReportDialog = () => {
|
|
16
|
+
setIsReportDialogShown(true);
|
|
17
|
+
};
|
|
18
|
+
const hideReportDialog = () => {
|
|
19
|
+
setIsReportDialogShown(false);
|
|
20
|
+
};
|
|
21
|
+
const reportButtonProps = {
|
|
22
|
+
onClick: showReportDialog,
|
|
23
|
+
title: reportSettings.tooltipText || 'Report a problem',
|
|
24
|
+
};
|
|
25
|
+
const reportDialogProps: Partial<ReportDialogProps> = {
|
|
26
|
+
settings: {
|
|
27
|
+
label: reportSettings.label || 'What is wrong with a code?',
|
|
28
|
+
},
|
|
29
|
+
onSubmit: hideReportDialog,
|
|
30
|
+
onCancel: hideReportDialog,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
return { isReportDialogShown, isReportButtonShown, reportButtonProps, reportDialogProps };
|
|
34
|
+
}
|
|
@@ -3,9 +3,7 @@ import styled, { css } from 'styled-components';
|
|
|
3
3
|
|
|
4
4
|
import { ClipboardService } from '@theme/utils/ClipboardService';
|
|
5
5
|
import { useThemeConfig } from '@theme/hooks/useThemeConfig';
|
|
6
|
-
import {
|
|
7
|
-
import { useSubmitFeedback } from '@portal/Feedback/useSubmitFeedback';
|
|
8
|
-
import { useReportDialog } from '@theme/hooks/useReportDialog';
|
|
6
|
+
import { ReportDialog, useReportDialog } from '@theme/Feedback';
|
|
9
7
|
|
|
10
8
|
export type CodeSampleProps = {
|
|
11
9
|
language: string;
|
|
@@ -15,16 +13,16 @@ export type CodeSampleProps = {
|
|
|
15
13
|
|
|
16
14
|
export function CodeSample({ rawContent, highlighted, language }: CodeSampleProps): JSX.Element {
|
|
17
15
|
const langClassName = language ? `language-${language}` : '';
|
|
18
|
-
const { codeSnippet: { copy = {}, report = {
|
|
19
|
-
const { submitFeedback } = useSubmitFeedback();
|
|
16
|
+
const { codeSnippet: { copy = {}, report = {} } = {} } = useThemeConfig();
|
|
20
17
|
|
|
21
18
|
const [isCopied, setIsCopied] = useState(false);
|
|
22
|
-
const
|
|
19
|
+
const { isReportDialogShown, isReportButtonShown, reportButtonProps, reportDialogProps } =
|
|
20
|
+
useReportDialog(report);
|
|
23
21
|
|
|
24
22
|
const copyCode = (code: string) => {
|
|
25
23
|
ClipboardService.copyCustom(code);
|
|
26
24
|
setIsCopied(true);
|
|
27
|
-
setTimeout(() => setIsCopied(false), copy.toasterDuration ||
|
|
25
|
+
setTimeout(() => setIsCopied(false), copy.toasterDuration || 1500);
|
|
28
26
|
};
|
|
29
27
|
|
|
30
28
|
return (
|
|
@@ -44,28 +42,9 @@ export function CodeSample({ rawContent, highlighted, language }: CodeSampleProp
|
|
|
44
42
|
</>
|
|
45
43
|
)}
|
|
46
44
|
|
|
47
|
-
{
|
|
48
|
-
<Button onClick={() => showDialog()} title={report.tooltipText || 'Report a problem'}>
|
|
49
|
-
Report
|
|
50
|
-
</Button>
|
|
51
|
-
)}
|
|
45
|
+
{isReportButtonShown && <Button {...reportButtonProps}>Report</Button>}
|
|
52
46
|
|
|
53
|
-
{
|
|
54
|
-
<ReportDialog id="modal">
|
|
55
|
-
<Comment
|
|
56
|
-
settings={{
|
|
57
|
-
label: report.label || 'What is wrong with a code?',
|
|
58
|
-
onCancel: () => {
|
|
59
|
-
hideDialog();
|
|
60
|
-
},
|
|
61
|
-
}}
|
|
62
|
-
onSubmit={(value) => {
|
|
63
|
-
submitFeedback('problem', { ...value, location: rawContent });
|
|
64
|
-
hideDialog();
|
|
65
|
-
}}
|
|
66
|
-
/>
|
|
67
|
-
</ReportDialog>
|
|
68
|
-
)}
|
|
47
|
+
{isReportDialogShown && <ReportDialog {...reportDialogProps} location={rawContent} />}
|
|
69
48
|
</CodeSampleButtonContainer>
|
|
70
49
|
<pre className={langClassName}>
|
|
71
50
|
<code className={langClassName} dangerouslySetInnerHTML={{ __html: highlighted }} />
|
|
@@ -242,25 +221,3 @@ const Wrapper = styled.div`
|
|
|
242
221
|
${darkStyleTokens};
|
|
243
222
|
}
|
|
244
223
|
`;
|
|
245
|
-
|
|
246
|
-
const ReportDialog = styled.div`
|
|
247
|
-
position: fixed;
|
|
248
|
-
top: 0;
|
|
249
|
-
left: 0;
|
|
250
|
-
width: 100vw;
|
|
251
|
-
height: 100vh;
|
|
252
|
-
background: var(--modal-overlay-background-color);
|
|
253
|
-
z-index: 10000;
|
|
254
|
-
display: flex;
|
|
255
|
-
align-items: center;
|
|
256
|
-
justify-content: center;
|
|
257
|
-
|
|
258
|
-
& > * {
|
|
259
|
-
background: var(--modal-background-color);
|
|
260
|
-
box-shadow: var(--modal-box-shadow);
|
|
261
|
-
padding: 15px;
|
|
262
|
-
margin: 15px;
|
|
263
|
-
max-width: 500px;
|
|
264
|
-
max-height: 300px;
|
|
265
|
-
}
|
|
266
|
-
`;
|
|
@@ -7,7 +7,7 @@ const Arrow = ({ className }: { className?: string }): JSX.Element => (
|
|
|
7
7
|
fill="none"
|
|
8
8
|
xmlns="http://www.w3.org/2000/svg"
|
|
9
9
|
viewBox="0 0 12 10"
|
|
10
|
-
width="
|
|
10
|
+
width="10px"
|
|
11
11
|
height="10px"
|
|
12
12
|
className={className}
|
|
13
13
|
>
|
|
@@ -19,7 +19,7 @@ const Arrow = ({ className }: { className?: string }): JSX.Element => (
|
|
|
19
19
|
|
|
20
20
|
export const ArrowBack = styled(Arrow)`
|
|
21
21
|
fill: var(--sidebar-back-button-icon-color);
|
|
22
|
-
margin-right: calc(var(--sidebar-spacing-unit)
|
|
22
|
+
margin-right: calc(var(--sidebar-spacing-unit));
|
|
23
23
|
|
|
24
24
|
background-image: var(--sidebar-back-button-icon);
|
|
25
25
|
background-repeat: no-repeat;
|
|
@@ -7,13 +7,23 @@ import { MobileSidebarButton } from '@theme/Sidebar/MobileSidebarButton';
|
|
|
7
7
|
import { MenuContainer } from '@theme/Sidebar/MenuContainer';
|
|
8
8
|
import { SidebarSearch } from '@theme/Search/SidebarSearch';
|
|
9
9
|
import { useThemeConfig } from '@theme/hooks/useThemeConfig';
|
|
10
|
+
import { ArrowBack } from '@theme/Sidebar/ArrowBack';
|
|
11
|
+
import { Link } from '@portal/Link';
|
|
10
12
|
|
|
11
13
|
interface SidebarLayoutProps {
|
|
12
14
|
versions: React.ReactNode;
|
|
13
15
|
menu: React.ReactNode;
|
|
16
|
+
backLink?: {
|
|
17
|
+
label: string;
|
|
18
|
+
slug: string;
|
|
19
|
+
};
|
|
14
20
|
}
|
|
15
21
|
|
|
16
|
-
export function SidebarLayout({
|
|
22
|
+
export function SidebarLayout({
|
|
23
|
+
versions,
|
|
24
|
+
menu,
|
|
25
|
+
backLink,
|
|
26
|
+
}: SidebarLayoutProps): JSX.Element | null {
|
|
17
27
|
const [isOpen, setIsOpen] = useMobileMenu();
|
|
18
28
|
const toggleMenu = () => setIsOpen(!isOpen);
|
|
19
29
|
const { search, sidebar } = useThemeConfig();
|
|
@@ -28,6 +38,15 @@ export function SidebarLayout({ versions, menu }: SidebarLayoutProps): JSX.Eleme
|
|
|
28
38
|
|
|
29
39
|
{!search?.hide && search?.placement === 'sidebar' ? <SidebarSearch /> : null}
|
|
30
40
|
<Sidebar animate={true} opened={isOpen}>
|
|
41
|
+
{(backLink && (
|
|
42
|
+
<BackLinkWrapper>
|
|
43
|
+
<Link to={backLink.slug}>
|
|
44
|
+
<ArrowBack />
|
|
45
|
+
Back to {backLink.label}
|
|
46
|
+
</Link>
|
|
47
|
+
</BackLinkWrapper>
|
|
48
|
+
)) ||
|
|
49
|
+
null}
|
|
31
50
|
{versions}
|
|
32
51
|
<MenuContainer>{menu}</MenuContainer>
|
|
33
52
|
</Sidebar>
|
|
@@ -35,4 +54,22 @@ export function SidebarLayout({ versions, menu }: SidebarLayoutProps): JSX.Eleme
|
|
|
35
54
|
);
|
|
36
55
|
}
|
|
37
56
|
|
|
57
|
+
const BackLinkWrapper = styled.div`
|
|
58
|
+
padding: var(--sidebar-offset-top) var(--sidebar-item-padding-horizontal)
|
|
59
|
+
var(--sidebar-item-padding-horizontal)
|
|
60
|
+
calc(var(--sidebar-offset-left) + var(--sidebar-item-padding-horizontal));
|
|
61
|
+
|
|
62
|
+
a {
|
|
63
|
+
color: var(--sidebar-back-button-text-color);
|
|
64
|
+
font-size: var(--sidebar-back-button-font-size);
|
|
65
|
+
font-family: var(--sidebar-back-button-font-family);
|
|
66
|
+
text-decoration: none;
|
|
67
|
+
&:hover {
|
|
68
|
+
color: var(--sidebar-back-button-hover-text-color);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
border-bottom: 1px solid var(--sidebar-border-color);
|
|
73
|
+
`;
|
|
74
|
+
|
|
38
75
|
const Wrapper = styled.div``;
|
package/src/config.ts
CHANGED
|
@@ -132,7 +132,7 @@ export const ThemeConfig = z
|
|
|
132
132
|
.object({
|
|
133
133
|
buttonText: z.string().default('Copy').optional(),
|
|
134
134
|
tooltipText: z.string().default('Copy to clipboard').optional(),
|
|
135
|
-
toasterText: z.string().default('Copied').optional(),
|
|
135
|
+
toasterText: z.string().default('Copied!').optional(),
|
|
136
136
|
toasterDuration: z.number().default(1500).optional(),
|
|
137
137
|
})
|
|
138
138
|
.extend(HideConfig.shape)
|
|
@@ -145,7 +145,7 @@ export const ThemeConfig = z
|
|
|
145
145
|
})
|
|
146
146
|
.extend(HideConfig.shape)
|
|
147
147
|
.optional()
|
|
148
|
-
.default({}),
|
|
148
|
+
.default({ hide: true }),
|
|
149
149
|
})
|
|
150
150
|
.strict()
|
|
151
151
|
.default({})
|
package/src/globalStyle.ts
CHANGED
|
@@ -517,7 +517,7 @@ const sidebar = css`
|
|
|
517
517
|
--sidebar-back-button-font-family: var(--sidebar-item-font-family);
|
|
518
518
|
--sidebar-back-button-font-size: var(--sidebar-item-font-size);
|
|
519
519
|
--sidebar-back-button-transform: inherit;
|
|
520
|
-
--sidebar-back-button-text-color: var(--
|
|
520
|
+
--sidebar-back-button-text-color: var(--link-text-color);
|
|
521
521
|
--sidebar-back-button-background-color: transparent;
|
|
522
522
|
--sidebar-back-button-hover-text-color: var(--sidebar-item-active-color);
|
|
523
523
|
--sidebar-back-button-hover-background-color: transparent;
|
|
@@ -1706,7 +1706,7 @@ const inputs = css`
|
|
|
1706
1706
|
--input-border: none; // @presenter Border
|
|
1707
1707
|
--input-border-radius: var(--border-radius); // @presenter BorderRadius
|
|
1708
1708
|
--input-font-size: var(--font-size-base); // @presenter FontSize
|
|
1709
|
-
--input-font-family: var(--
|
|
1709
|
+
--input-font-family: var(--font-family-base); // @presenter FontFamily
|
|
1710
1710
|
--input-line-height: 1.15em; // @presenter LineHeight
|
|
1711
1711
|
--input-padding: 8px;
|
|
1712
1712
|
|
|
@@ -1716,6 +1716,8 @@ const inputs = css`
|
|
|
1716
1716
|
--input-focus-text-color: var(--text-color-inverse); // @presenter Color
|
|
1717
1717
|
--input-placeholder-text-color: var(--text-color-inverse); // @presenter Color
|
|
1718
1718
|
|
|
1719
|
+
--checkbox-backround-color: var(--background-color);
|
|
1720
|
+
--checkbox-checked-backround-color: var(--color-primary-500);
|
|
1719
1721
|
// @tokens End
|
|
1720
1722
|
`;
|
|
1721
1723
|
|
|
@@ -1925,7 +1927,7 @@ const pages = css`
|
|
|
1925
1927
|
|
|
1926
1928
|
--page-404-font-family: var(--font-family-base); // @presenter FontFamily
|
|
1927
1929
|
|
|
1928
|
-
--page-404-header-text-color: #000;
|
|
1930
|
+
--page-404-header-text-color: #000;
|
|
1929
1931
|
--page-404-header-font-size: 14em; // @presenter FontSize
|
|
1930
1932
|
--page-404-header-font-weight: 600; // @presenter FontWeight
|
|
1931
1933
|
--page-404-header-line-height: 1.2; // @presenter LineHeight
|
|
@@ -1945,31 +1947,31 @@ const pages = css`
|
|
|
1945
1947
|
* @tokens 403 Page
|
|
1946
1948
|
* @presenter Color
|
|
1947
1949
|
*/
|
|
1948
|
-
|
|
1950
|
+
|
|
1949
1951
|
--page-403-font-family: var(--font-family-base); // @presenter FontFamily
|
|
1950
|
-
|
|
1952
|
+
|
|
1951
1953
|
--page-403-header-text-color: #000;
|
|
1952
1954
|
--page-403-header-font-size: 14em; // @presenter FontSize
|
|
1953
1955
|
--page-403-header-font-weight: 600; // @presenter FontWeight
|
|
1954
1956
|
--page-403-header-line-height: 1.2; // @presenter LineHeight
|
|
1955
1957
|
--page-403-header-margin: 0; // @presenter Spacing
|
|
1956
|
-
|
|
1958
|
+
|
|
1957
1959
|
--page-403-description-text-color: #000;
|
|
1958
1960
|
--page-403-description-font-size: 2em; // @presenter FontSize
|
|
1959
1961
|
--page-403-description-font-weight: 400; // @presenter FontWeight
|
|
1960
1962
|
--page-403-description-line-height: 1; // @presenter LineHeight
|
|
1961
1963
|
--page-403-description-margin: 0; // @presenter Spacing
|
|
1962
|
-
|
|
1964
|
+
|
|
1963
1965
|
--page-403-button-margin: 4em; // @presenter Spacing
|
|
1964
|
-
|
|
1966
|
+
|
|
1965
1967
|
// @tokens End
|
|
1966
1968
|
`
|
|
1967
1969
|
|
|
1968
1970
|
const modal = css`
|
|
1969
|
-
body:has(
|
|
1971
|
+
body:has(.modal) {
|
|
1970
1972
|
overflow: hidden;
|
|
1971
1973
|
}
|
|
1972
|
-
|
|
1974
|
+
|
|
1973
1975
|
--modal-box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.6);
|
|
1974
1976
|
--modal-overlay-background-color: rgba(206, 206, 206, 0.49);
|
|
1975
1977
|
--modal-background-color: var(--background-color);
|
package/src/mocks/hooks/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ThemeUIConfig } from '@theme/config';
|
|
2
|
-
|
|
2
|
+
import type { ResolvedNavItem } from '@theme/types/portal';
|
|
3
|
+
import type { CatalogConfig, FilteredCatalog } from '@theme/types/portal/src/shared/types/catalog';
|
|
3
4
|
interface PageLink {
|
|
4
5
|
label: string;
|
|
5
6
|
link: string;
|
|
@@ -65,3 +66,11 @@ export function useSidebarSiblingsData(): { nextPage: PageLink | null; prevPage:
|
|
|
65
66
|
},
|
|
66
67
|
};
|
|
67
68
|
}
|
|
69
|
+
|
|
70
|
+
export function usePageSharedData<T = unknown>(_id: string): T {
|
|
71
|
+
throw new Error('Mock not implemented yet.');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function useCatalog(_items: ResolvedNavItem[], _config: CatalogConfig): FilteredCatalog {
|
|
75
|
+
throw new Error('Mock not implemented yet.');
|
|
76
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { NavItem } from './nav';
|
|
2
|
+
|
|
3
|
+
export type FilteredCatalog = {
|
|
4
|
+
groups: { title: string; items: CatalogItem[] }[];
|
|
5
|
+
filters: ResolvedFilter[];
|
|
6
|
+
filterTerm: string;
|
|
7
|
+
setFilterTerm: (term: string) => void;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type Filter = {
|
|
11
|
+
type?: 'select' | 'checkboxes';
|
|
12
|
+
title: string;
|
|
13
|
+
property: string;
|
|
14
|
+
parentFilter?: string;
|
|
15
|
+
missingCategoryName?: string;
|
|
16
|
+
options?: string[];
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type CatalogConfig = {
|
|
20
|
+
slug: string;
|
|
21
|
+
filters: Filter[];
|
|
22
|
+
groupByFirstFilter: boolean;
|
|
23
|
+
items: NavItem[];
|
|
24
|
+
requiredPermission?: string;
|
|
25
|
+
separateVersions?: boolean;
|
|
26
|
+
title?: string;
|
|
27
|
+
description?: string;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export type CatalogThemeConfig = {
|
|
31
|
+
catalog: Record<string, CatalogConfig>;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type ResolvedFilter = Omit<Filter, 'options'> & {
|
|
35
|
+
options: {
|
|
36
|
+
value: string;
|
|
37
|
+
count: number;
|
|
38
|
+
}[];
|
|
39
|
+
filteredOptions: {
|
|
40
|
+
value: string;
|
|
41
|
+
count: number;
|
|
42
|
+
}[];
|
|
43
|
+
toggleOption: (option: string) => void;
|
|
44
|
+
selectOption: (option: string) => void;
|
|
45
|
+
parentUsed: boolean;
|
|
46
|
+
selectedOptions: Set<string>;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export type CatalogItem = {
|
|
50
|
+
title: string;
|
|
51
|
+
link: string;
|
|
52
|
+
description?: string;
|
|
53
|
+
image?: string;
|
|
54
|
+
[k: string]: unknown;
|
|
55
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
|
|
3
|
+
export const Checkbox = styled.input`
|
|
4
|
+
position: absolute;
|
|
5
|
+
opacity: 0;
|
|
6
|
+
|
|
7
|
+
& + label {
|
|
8
|
+
position: relative;
|
|
9
|
+
cursor: pointer;
|
|
10
|
+
padding: 0;
|
|
11
|
+
display: flex;
|
|
12
|
+
|
|
13
|
+
div {
|
|
14
|
+
margin-top: 1px;
|
|
15
|
+
}
|
|
16
|
+
p {
|
|
17
|
+
line-height: 1.2;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
&::before {
|
|
21
|
+
content: '';
|
|
22
|
+
margin-right: 10px;
|
|
23
|
+
display: inline-block;
|
|
24
|
+
vertical-align: top;
|
|
25
|
+
width: 18px;
|
|
26
|
+
height: 18px;
|
|
27
|
+
background: var(--checkbox-backround-color);
|
|
28
|
+
border: 1px solid rgba(0, 0, 0, 0.23);
|
|
29
|
+
border-radius: 2px;
|
|
30
|
+
flex-shrink: 0;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&:focus + label:before {
|
|
35
|
+
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.12);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&:checked + label {
|
|
39
|
+
&::before {
|
|
40
|
+
background: var(--checkbox-checked-backround-color);
|
|
41
|
+
}
|
|
42
|
+
&::after {
|
|
43
|
+
content: '';
|
|
44
|
+
position: absolute;
|
|
45
|
+
left: 5px;
|
|
46
|
+
top: 10px;
|
|
47
|
+
background: var(--checkbox-backround-color);
|
|
48
|
+
width: 2px;
|
|
49
|
+
height: 2px;
|
|
50
|
+
box-shadow: 2px 0 0 white, 4px 0 0 white, 4px -2px 0 white, 4px -4px 0 white, 4px -6px 0 white,
|
|
51
|
+
4px -8px 0 white;
|
|
52
|
+
transform: rotate(45deg);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
&:disabled + label {
|
|
57
|
+
color: #b8b8b8;
|
|
58
|
+
cursor: auto;
|
|
59
|
+
&::before {
|
|
60
|
+
box-shadow: none;
|
|
61
|
+
background: #ddd;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
`;
|