@patternfly/documentation-framework 1.0.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/CHANGELOG.md +3964 -0
- package/README.md +92 -0
- package/app.js +118 -0
- package/assets/android-chrome-36x36.png +0 -0
- package/assets/android-chrome-48x48.png +0 -0
- package/assets/android-chrome-96x96.png +0 -0
- package/assets/favicon-16x16.png +0 -0
- package/assets/favicon-32x32.png +0 -0
- package/assets/favicon-48x48.png +0 -0
- package/assets/favicon.ico +0 -0
- package/assets/manifest.json +29 -0
- package/components/autoLinkHeader/autoLinkHeader.css +22 -0
- package/components/autoLinkHeader/autoLinkHeader.js +41 -0
- package/components/cssVariables/cssSearch.js +32 -0
- package/components/cssVariables/cssVariables.css +15 -0
- package/components/cssVariables/cssVariables.js +233 -0
- package/components/example/example.css +106 -0
- package/components/example/example.js +196 -0
- package/components/example/exampleToolbar.js +208 -0
- package/components/example/missing-thumbnail.jpg +0 -0
- package/components/footer/RHLogo.png +0 -0
- package/components/footer/footer.css +114 -0
- package/components/footer/footer.js +262 -0
- package/components/gdprBanner/gdprBanner.css +14 -0
- package/components/gdprBanner/gdprBanner.js +31 -0
- package/components/index.js +12 -0
- package/components/inlineAlert/inlineAlert.js +19 -0
- package/components/link/link.js +68 -0
- package/components/propsTable/propTypeWithLinks.js +33 -0
- package/components/propsTable/propsTable.js +82 -0
- package/components/sideNav/sideNav.css +17 -0
- package/components/sideNav/sideNav.js +95 -0
- package/components/tableOfContents/tableOfContents.css +77 -0
- package/components/tableOfContents/tableOfContents.js +89 -0
- package/components/topNav/topNav.css +30 -0
- package/components/topNav/topNav.js +24 -0
- package/global.css +7 -0
- package/helpers/asyncComponentFactory.js +41 -0
- package/helpers/capitalize.js +7 -0
- package/helpers/codeTitleTransformer.js +40 -0
- package/helpers/codesandbox.js +204 -0
- package/helpers/copy.js +19 -0
- package/helpers/createHandlebars.js +26 -0
- package/helpers/d3-timer.js +7 -0
- package/helpers/extractExampleHelpers.js +24 -0
- package/helpers/fonts.js +164 -0
- package/helpers/getId.js +6 -0
- package/helpers/getTitle.js +5 -0
- package/helpers/index.js +9 -0
- package/helpers/liveCodeTypes.js +4 -0
- package/helpers/slugger.js +35 -0
- package/helpers/trackEvent.js +17 -0
- package/helpers/xterm-addon-fit.js +3 -0
- package/helpers/xterm.js +8 -0
- package/images/patternfly-logo.svg +14 -0
- package/images/patternfly-orb.svg +28 -0
- package/layouts/index.js +1 -0
- package/layouts/logo.svg +33 -0
- package/layouts/sideNavLayout/sideNavLayout.css +104 -0
- package/layouts/sideNavLayout/sideNavLayout.js +237 -0
- package/package.json +87 -0
- package/pages/404/404.css +16 -0
- package/pages/404/404.svg +26 -0
- package/pages/404/chart.svg +24 -0
- package/pages/404/components.svg +1 -0
- package/pages/404/guidelines.svg +1 -0
- package/pages/404/index.js +136 -0
- package/pages/404/patternfly-flat.svg +1 -0
- package/pages/global-css-variables.md +108 -0
- package/pages/img/component-variable-mapping.png +0 -0
- package/pages/red-hat-font.md +40 -0
- package/routes-client.js +1 -0
- package/routes-generated.js +1 -0
- package/routes.js +155 -0
- package/scripts/cli/build.js +95 -0
- package/scripts/cli/buildClient.js +23 -0
- package/scripts/cli/buildServer.js +24 -0
- package/scripts/cli/cli.js +63 -0
- package/scripts/cli/generate.js +23 -0
- package/scripts/cli/helpers.js +9 -0
- package/scripts/cli/init.js +68 -0
- package/scripts/cli/serve.js +13 -0
- package/scripts/cli/start.js +32 -0
- package/scripts/md/anchor-header.js +69 -0
- package/scripts/md/auto-link-url.js +33 -0
- package/scripts/md/example-captions.js +67 -0
- package/scripts/md/jsxAttributes.js +20 -0
- package/scripts/md/mdx-ast-to-mdx-hast.js +210 -0
- package/scripts/md/mdx-hast-to-jsx.js +233 -0
- package/scripts/md/parseMD.js +308 -0
- package/scripts/md/remove-comments.js +21 -0
- package/scripts/md/styled-tags.js +87 -0
- package/scripts/md/typecheck.js +133 -0
- package/scripts/tsDocgen.js +155 -0
- package/scripts/webpack/getHtmlWebpackPlugins.js +78 -0
- package/scripts/webpack/prerender.js +59 -0
- package/scripts/webpack/webpack.base.config.js +159 -0
- package/scripts/webpack/webpack.client.config.js +146 -0
- package/scripts/webpack/webpack.server.config.js +55 -0
- package/scripts/writeScreenshots.js +66 -0
- package/templates/design-guidelines.js +13 -0
- package/templates/html.ejs +52 -0
- package/templates/mdx.css +308 -0
- package/templates/mdx.js +185 -0
- package/templates/patternfly-docs/content/extensions/extension/design-guidelines/design-guidelines.md +25 -0
- package/templates/patternfly-docs/content/extensions/extension/design-guidelines/img/card-elements.png +0 -0
- package/templates/patternfly-docs/content/extensions/extension/examples/Basic.jsx +4 -0
- package/templates/patternfly-docs/content/extensions/extension/examples/basic.md +25 -0
- package/templates/patternfly-docs/pages/index.js +27 -0
- package/templates/patternfly-docs/patternfly-docs.config.js +6 -0
- package/templates/patternfly-docs/patternfly-docs.css.js +8 -0
- package/templates/patternfly-docs/patternfly-docs.routes.js +12 -0
- package/templates/patternfly-docs/patternfly-docs.source.js +24 -0
- package/templates/sitemap.ejs +10 -0
- package/versions.json +870 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
.ws-example {
|
|
2
|
+
margin-top: var(--pf-global--spacer--lg);
|
|
3
|
+
margin-bottom: var(--pf-global--spacer--lg);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.ws-example > .ws-example-header {
|
|
7
|
+
padding: var(--pf-global--spacer--md);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.ws-example-header > .ws-example-heading:not(:last-child) {
|
|
11
|
+
margin-bottom: var(--pf-global--spacer--md);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.ws-code-editor:not(.ws-example-code-expanded) > .pf-c-code-editor__header::before {
|
|
15
|
+
--pf-c-code-editor__header--before--BorderBottomWidth: 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.ws-code-editor-control {
|
|
19
|
+
--pf-c-button--m-control--BackgroundColor: transparent;
|
|
20
|
+
--pf-c-button--m-control--active--BackgroundColor: transparent;
|
|
21
|
+
--pf-c-button--m-control--focus--BackgroundColor: transparent;
|
|
22
|
+
--pf-c-button--m-control--hover--BackgroundColor: transparent;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.ws-code-editor-control.pf-c-button {
|
|
26
|
+
--pf-c-button--after--BorderWidth: 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.ws-preview {
|
|
30
|
+
padding: var(--pf-global--spacer--md);
|
|
31
|
+
background-color: var(--pf-global--BackgroundColor--100);
|
|
32
|
+
border-bottom: var(--pf-global--BorderWidth--sm) solid var(--pf-global--BorderColor--300);
|
|
33
|
+
transition: width .2s ease-in-out;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.ws-preview-html {
|
|
37
|
+
overflow: hidden;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.ws-editor {
|
|
41
|
+
font-size: var(--pf-global--FontSize--md);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.ws-editor .token.punctuation,
|
|
45
|
+
.ws-editor .token.operator {
|
|
46
|
+
color: var(--pf-global--danger-color--100);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.ws-preview__thumbnail-link {
|
|
50
|
+
position: relative;
|
|
51
|
+
line-height: 0;
|
|
52
|
+
overflow: hidden;
|
|
53
|
+
display: inline-block;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.ws-preview__thumbnail-link::before,
|
|
57
|
+
.ws-preview__thumbnail-link::after {
|
|
58
|
+
position: absolute;
|
|
59
|
+
z-index: 500;
|
|
60
|
+
transition: .2s;
|
|
61
|
+
opacity: 0;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.ws-preview__thumbnail-link:hover::before,
|
|
65
|
+
.ws-preview__thumbnail-link:hover::after {
|
|
66
|
+
opacity: 1;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.ws-preview__thumbnail-link::before {
|
|
70
|
+
top: 0;
|
|
71
|
+
right: 0;
|
|
72
|
+
bottom: 0;
|
|
73
|
+
left: 0;
|
|
74
|
+
content: '';
|
|
75
|
+
background-color: rgba(0,0,0,.5);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.ws-preview__thumbnail-link::after {
|
|
79
|
+
top: 50%;
|
|
80
|
+
left: 50%;
|
|
81
|
+
transform: translate(-50%, -50%);
|
|
82
|
+
font-family: "Font Awesome 5 Free";
|
|
83
|
+
content: "\f35d";
|
|
84
|
+
font-size: 52px;
|
|
85
|
+
color: rgba(255,255,255,.4);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.ws-preview__thumbnail-link::after {
|
|
89
|
+
top: 50%;
|
|
90
|
+
left: 50%;
|
|
91
|
+
transform: translate(-50%, -50%);
|
|
92
|
+
font-family: "Font Awesome 5 Free";
|
|
93
|
+
content: "\f35d";
|
|
94
|
+
font-size: 52px;
|
|
95
|
+
color: rgba(255,255,255,.4);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.pf-c-badge.ws-beta-badge {
|
|
99
|
+
--pf-c-badge--m-unread--BackgroundColor: var(--pf-global--BackgroundColor--100);
|
|
100
|
+
--pf-c-badge--m-unread--Color: var(--pf-global--primary-color--100);
|
|
101
|
+
border: var(--pf-global--BorderWidth--sm) solid var(--pf-global--primary-color--100);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.ws-prop-required {
|
|
105
|
+
color: var(--pf-global--danger-color--100);
|
|
106
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useLocation } from '@reach/router';
|
|
3
|
+
import { Badge, CodeBlock, CodeBlockCode, debounce } from '@patternfly/react-core';
|
|
4
|
+
import * as reactCoreModule from '@patternfly/react-core';
|
|
5
|
+
import * as reactTableModule from '@patternfly/react-table';
|
|
6
|
+
import { css } from '@patternfly/react-styles';
|
|
7
|
+
import { getParameters } from 'codesandbox/lib/api/define';
|
|
8
|
+
import { ExampleToolbar } from './exampleToolbar';
|
|
9
|
+
import { AutoLinkHeader } from '../autoLinkHeader/autoLinkHeader';
|
|
10
|
+
import {
|
|
11
|
+
slugger,
|
|
12
|
+
getStaticParams,
|
|
13
|
+
getReactParams,
|
|
14
|
+
getExampleClassName,
|
|
15
|
+
getExampleId,
|
|
16
|
+
liveCodeTypes
|
|
17
|
+
} from '../../helpers';
|
|
18
|
+
import { convertToReactComponent } from '@patternfly/ast-helpers';
|
|
19
|
+
import missingThumbnail from './missing-thumbnail.jpg';
|
|
20
|
+
|
|
21
|
+
const errorComponent = err => <pre>{err.toString()}</pre>;
|
|
22
|
+
|
|
23
|
+
class ErrorBoundary extends React.Component {
|
|
24
|
+
constructor(props) {
|
|
25
|
+
super(props);
|
|
26
|
+
this.state = { error: null, errorInfo: null };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
componentDidCatch(error, errorInfo) {
|
|
30
|
+
errorInfo._suppressLogging = true;
|
|
31
|
+
this.setState({
|
|
32
|
+
error: error,
|
|
33
|
+
errorInfo: errorInfo
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
componentDidUpdate(prevProps) {
|
|
38
|
+
if (prevProps.children !== this.props.children) {
|
|
39
|
+
this.setState({ error: null, errorInfo: null });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
render() {
|
|
44
|
+
if (this.state.errorInfo) {
|
|
45
|
+
return errorComponent(this.state.error);
|
|
46
|
+
}
|
|
47
|
+
return this.props.children;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Props come from mdx-ast-to-mdx-hast.js
|
|
52
|
+
export const Example = ({
|
|
53
|
+
// The ts/js/html code for the example
|
|
54
|
+
code,
|
|
55
|
+
// The language of the code
|
|
56
|
+
lang = '',
|
|
57
|
+
// Second parameter to sourceMD for file containing this code
|
|
58
|
+
// Should match tab name
|
|
59
|
+
source,
|
|
60
|
+
// Whether to disable the live code editor
|
|
61
|
+
noLive = !liveCodeTypes.includes(lang),
|
|
62
|
+
// Nearest parent h3
|
|
63
|
+
title = 'Untitled',
|
|
64
|
+
// Whether the example is fullscreen only and we should show a thumbnail
|
|
65
|
+
isFullscreen,
|
|
66
|
+
// Whether the example is open on the fullscreen page
|
|
67
|
+
isFullscreenPreview,
|
|
68
|
+
// The image src thumbnail for the example
|
|
69
|
+
thumbnail = missingThumbnail,
|
|
70
|
+
// Whether the example shows demo capability
|
|
71
|
+
isBeta,
|
|
72
|
+
// Slugified source + title
|
|
73
|
+
id,
|
|
74
|
+
// Section in frontmatter of MD file (components, demos, etc)
|
|
75
|
+
section,
|
|
76
|
+
// Extra constants for example (images, extra JS files, etc)
|
|
77
|
+
liveContext,
|
|
78
|
+
// Content that appears between h3 and code block to explain example
|
|
79
|
+
children,
|
|
80
|
+
}) => {
|
|
81
|
+
if (isFullscreenPreview) {
|
|
82
|
+
isFullscreen = false;
|
|
83
|
+
}
|
|
84
|
+
if (!lang) {
|
|
85
|
+
// Inline code
|
|
86
|
+
return <code className="ws-code">{code}</code>;
|
|
87
|
+
} else if (noLive) {
|
|
88
|
+
// Code block
|
|
89
|
+
return (
|
|
90
|
+
<CodeBlock>
|
|
91
|
+
<CodeBlockCode>{code}</CodeBlockCode>
|
|
92
|
+
</CodeBlock>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const [editorCode, setEditorCode] = React.useState(code);
|
|
97
|
+
const loc = useLocation();
|
|
98
|
+
|
|
99
|
+
const scope = {
|
|
100
|
+
...liveContext,
|
|
101
|
+
// These 2 are in the bundle anyways for the site since we dogfood
|
|
102
|
+
...reactCoreModule,
|
|
103
|
+
...reactTableModule,
|
|
104
|
+
};
|
|
105
|
+
let livePreview = null;
|
|
106
|
+
if (lang === 'html') {
|
|
107
|
+
livePreview = (
|
|
108
|
+
<div
|
|
109
|
+
className={css('ws-preview-html', isFullscreenPreview && 'pf-u-h-100')}
|
|
110
|
+
dangerouslySetInnerHTML={{ __html: editorCode }}
|
|
111
|
+
/>
|
|
112
|
+
);
|
|
113
|
+
} else {
|
|
114
|
+
try {
|
|
115
|
+
const { code: transformedCode, hasTS } = convertToReactComponent(editorCode);
|
|
116
|
+
if (hasTS) {
|
|
117
|
+
lang = 'ts';
|
|
118
|
+
} else {
|
|
119
|
+
lang = 'js';
|
|
120
|
+
}
|
|
121
|
+
const getPreviewComponent = new Function('React', ...Object.keys(scope), transformedCode);
|
|
122
|
+
const PreviewComponent = getPreviewComponent(React, ...Object.values(scope));
|
|
123
|
+
livePreview = (
|
|
124
|
+
<ErrorBoundary>
|
|
125
|
+
<PreviewComponent />
|
|
126
|
+
</ErrorBoundary>
|
|
127
|
+
);
|
|
128
|
+
} catch (err) {
|
|
129
|
+
livePreview = errorComponent(err);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const previewId = getExampleId(source, section[0], id, title);
|
|
133
|
+
const className = getExampleClassName(source, section[0], id);
|
|
134
|
+
|
|
135
|
+
if (isFullscreenPreview) {
|
|
136
|
+
return (
|
|
137
|
+
<div id={previewId} className={css(className, 'pf-u-h-100')}>
|
|
138
|
+
{livePreview}
|
|
139
|
+
</div>
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const codeBoxParams = getParameters(
|
|
144
|
+
lang === 'html'
|
|
145
|
+
? getStaticParams(title, editorCode)
|
|
146
|
+
: getReactParams(title, editorCode, scope, lang)
|
|
147
|
+
);
|
|
148
|
+
const fullscreenLink = loc.pathname.replace(/\/$/, '')
|
|
149
|
+
+ (loc.pathname.endsWith(source) ? '' : `/${source}`)
|
|
150
|
+
+ '/'
|
|
151
|
+
+ slugger(title);
|
|
152
|
+
|
|
153
|
+
return (
|
|
154
|
+
<div className="ws-example">
|
|
155
|
+
<div className="ws-example-header">
|
|
156
|
+
<AutoLinkHeader
|
|
157
|
+
metaText={isBeta && <Badge className="ws-beta-badge pf-u-ml-xs">Beta</Badge>}
|
|
158
|
+
size="h4"
|
|
159
|
+
headingLevel="h3"
|
|
160
|
+
className="ws-example-heading"
|
|
161
|
+
>
|
|
162
|
+
{title}
|
|
163
|
+
</AutoLinkHeader>
|
|
164
|
+
{children}
|
|
165
|
+
</div>
|
|
166
|
+
{isFullscreen
|
|
167
|
+
? <div className="ws-preview">
|
|
168
|
+
<a
|
|
169
|
+
className="ws-preview__thumbnail-link"
|
|
170
|
+
href={fullscreenLink}
|
|
171
|
+
target="_blank"
|
|
172
|
+
aria-label={`Open fullscreen ${title} example`}
|
|
173
|
+
>
|
|
174
|
+
<img src={thumbnail.src} width={thumbnail.width} height={thumbnail.height} alt={`${title} screenshot`} />
|
|
175
|
+
</a>
|
|
176
|
+
</div>
|
|
177
|
+
: <div
|
|
178
|
+
id={previewId}
|
|
179
|
+
className={css(className, isFullscreen ? 'ws-preview-fullscreen' : 'ws-preview')}
|
|
180
|
+
>
|
|
181
|
+
{livePreview}
|
|
182
|
+
</div>
|
|
183
|
+
}
|
|
184
|
+
<ExampleToolbar
|
|
185
|
+
lang={lang}
|
|
186
|
+
isFullscreen={isFullscreen}
|
|
187
|
+
fullscreenLink={fullscreenLink}
|
|
188
|
+
originalCode={code}
|
|
189
|
+
code={editorCode}
|
|
190
|
+
setCode={debounce(setEditorCode, 300)}
|
|
191
|
+
codeBoxParams={codeBoxParams}
|
|
192
|
+
exampleTitle={title}
|
|
193
|
+
/>
|
|
194
|
+
</div>
|
|
195
|
+
);
|
|
196
|
+
}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Button, Form, Tooltip } from '@patternfly/react-core';
|
|
3
|
+
import { CodeEditor, CodeEditorControl, Language } from '@patternfly/react-code-editor';
|
|
4
|
+
import { convertToJSX } from '@patternfly/ast-helpers';
|
|
5
|
+
import ExternalLinkAltIcon from '@patternfly/react-icons/dist/esm/icons/external-link-alt-icon';
|
|
6
|
+
import CodepenIcon from '@patternfly/react-icons/dist/esm/icons/codepen-icon';
|
|
7
|
+
import CopyIcon from '@patternfly/react-icons/dist/esm/icons/copy-icon';
|
|
8
|
+
import CodeIcon from '@patternfly/react-icons/dist/esm/icons/code-icon';
|
|
9
|
+
import AngleDoubleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-double-right-icon';
|
|
10
|
+
import ReplyAllIcon from '@patternfly/react-icons/dist/esm/icons/reply-all-icon';
|
|
11
|
+
import { copy } from '../../helpers';
|
|
12
|
+
import { trackEvent } from '../../helpers';
|
|
13
|
+
|
|
14
|
+
function getLanguage(lang) {
|
|
15
|
+
if (lang === 'js') {
|
|
16
|
+
return Language.javascript;
|
|
17
|
+
} else if (lang === 'ts') {
|
|
18
|
+
return Language.typescript;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return lang;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const ExampleToolbar = ({
|
|
25
|
+
// Link to fullscreen example page (each example has one)
|
|
26
|
+
fullscreenLink,
|
|
27
|
+
// Params to pass to codesandbox
|
|
28
|
+
codeBoxParams,
|
|
29
|
+
// Language of code
|
|
30
|
+
lang,
|
|
31
|
+
// Whether the example is fullscreen only
|
|
32
|
+
isFullscreen,
|
|
33
|
+
// Original version of the code
|
|
34
|
+
originalCode,
|
|
35
|
+
// Current code in editor
|
|
36
|
+
code,
|
|
37
|
+
// Callback to set code in parent component
|
|
38
|
+
setCode,
|
|
39
|
+
// Title of example used in creating unique labels
|
|
40
|
+
exampleTitle
|
|
41
|
+
}) => {
|
|
42
|
+
const [isEditorOpen, setIsEditorOpen] = React.useState(false);
|
|
43
|
+
const [isCopied, setCopied] = React.useState(false);
|
|
44
|
+
|
|
45
|
+
const copyCode = () => {
|
|
46
|
+
copy(code);
|
|
47
|
+
|
|
48
|
+
setCopied(true);
|
|
49
|
+
// Reset isCopied after Tooltip fades out
|
|
50
|
+
setTimeout(() => {
|
|
51
|
+
setCopied(false);
|
|
52
|
+
}, 2500);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const copyLabel = 'Copy code to clipboard';
|
|
56
|
+
const languageLabel = `Toggle ${lang.toUpperCase()} code`;
|
|
57
|
+
const codesandboxLabel = 'Open example in CodeSandbox';
|
|
58
|
+
const fullscreenLabel = 'Open example in new window';
|
|
59
|
+
const convertLabel = 'Convert example from Typescript to JavaScript';
|
|
60
|
+
const undoAllLabel = 'Undo all changes';
|
|
61
|
+
|
|
62
|
+
const copyAriaLabel = `Copy ${exampleTitle} example code to clipboard`;
|
|
63
|
+
const languageAriaLabel = `Toggle ${lang.toUpperCase()} code in ${exampleTitle} example`;
|
|
64
|
+
const codesandboxAriaLabel = `Open ${exampleTitle} example in CodeSandbox`;
|
|
65
|
+
const fullscreenAriaLabel = `Open ${exampleTitle} example in new window`;
|
|
66
|
+
const convertAriaLabel = `Convert ${exampleTitle} example from Typescript to JavaScript`;
|
|
67
|
+
const undoAllAriaLabel = `Undo all changes to ${exampleTitle}`;
|
|
68
|
+
|
|
69
|
+
const customControls = (
|
|
70
|
+
<React.Fragment>
|
|
71
|
+
<CodeEditorControl
|
|
72
|
+
icon={
|
|
73
|
+
<React.Fragment>
|
|
74
|
+
<CodeIcon />
|
|
75
|
+
{' ' + lang.toUpperCase()}
|
|
76
|
+
</React.Fragment>
|
|
77
|
+
}
|
|
78
|
+
onClick={() => {
|
|
79
|
+
setIsEditorOpen(!isEditorOpen);
|
|
80
|
+
// 1 === expand code, 0 === collapse code
|
|
81
|
+
trackEvent('code_editor_control_click', 'click_event', 'TOGGLE_CODE', isEditorOpen ? 0 : 1);
|
|
82
|
+
}}
|
|
83
|
+
aria-label={languageAriaLabel}
|
|
84
|
+
toolTipText={languageLabel}
|
|
85
|
+
aria-expanded={isEditorOpen}
|
|
86
|
+
className="ws-code-editor-control"
|
|
87
|
+
/>
|
|
88
|
+
<Tooltip
|
|
89
|
+
trigger="mouseenter"
|
|
90
|
+
content={<div>{isCopied ? 'Code copied' : copyLabel}</div>}
|
|
91
|
+
exitDelay={isCopied ? 1600 : 300}
|
|
92
|
+
entryDelay={300}
|
|
93
|
+
maxWidth="100px"
|
|
94
|
+
position="top"
|
|
95
|
+
>
|
|
96
|
+
<Button onClick={() => {
|
|
97
|
+
copyCode();
|
|
98
|
+
trackEvent('code_editor_control_click', 'click_event', 'COPY_CODE');
|
|
99
|
+
}} variant="control" aria-label={copyAriaLabel} className="ws-code-editor-control">
|
|
100
|
+
<CopyIcon />
|
|
101
|
+
</Button>
|
|
102
|
+
</Tooltip>
|
|
103
|
+
{codeBoxParams &&
|
|
104
|
+
<Tooltip
|
|
105
|
+
trigger="mouseenter"
|
|
106
|
+
content={codesandboxLabel}
|
|
107
|
+
exitDelay={300}
|
|
108
|
+
entryDelay={300}
|
|
109
|
+
maxWidth="100px"
|
|
110
|
+
position="top"
|
|
111
|
+
>
|
|
112
|
+
<Form
|
|
113
|
+
aria-label={`${codesandboxAriaLabel} form` }
|
|
114
|
+
action="https://codesandbox.io/api/v1/sandboxes/define"
|
|
115
|
+
method="POST"
|
|
116
|
+
target="_blank"
|
|
117
|
+
style={{ display: "inline-block" }}
|
|
118
|
+
>
|
|
119
|
+
<Button
|
|
120
|
+
aria-label={codesandboxAriaLabel}
|
|
121
|
+
variant="control"
|
|
122
|
+
type="submit"
|
|
123
|
+
onClick={() => {
|
|
124
|
+
trackEvent('code_editor_control_click', 'click_event', 'CODESANDBOX_LINK');
|
|
125
|
+
}}
|
|
126
|
+
className="ws-code-editor-control"
|
|
127
|
+
>
|
|
128
|
+
<input type="hidden" name="parameters" value={codeBoxParams} />
|
|
129
|
+
<CodepenIcon />
|
|
130
|
+
</Button>
|
|
131
|
+
</Form>
|
|
132
|
+
</Tooltip>
|
|
133
|
+
}
|
|
134
|
+
{fullscreenLink &&
|
|
135
|
+
<CodeEditorControl
|
|
136
|
+
component="a"
|
|
137
|
+
icon={<ExternalLinkAltIcon />}
|
|
138
|
+
href={fullscreenLink}
|
|
139
|
+
target="_blank"
|
|
140
|
+
rel="noopener noreferrer"
|
|
141
|
+
aria-label={fullscreenAriaLabel}
|
|
142
|
+
toolTipText={fullscreenLabel}
|
|
143
|
+
onClick={() => {
|
|
144
|
+
trackEvent('code_editor_control_click', 'click_event', 'FULLSCREEN_LINK');
|
|
145
|
+
}}
|
|
146
|
+
className="ws-code-editor-control"
|
|
147
|
+
/>
|
|
148
|
+
}
|
|
149
|
+
{isEditorOpen && lang === 'ts' &&
|
|
150
|
+
<CodeEditorControl
|
|
151
|
+
icon={(
|
|
152
|
+
<React.Fragment>
|
|
153
|
+
{'TS '}<AngleDoubleRightIcon />{' JS'}
|
|
154
|
+
</React.Fragment>
|
|
155
|
+
)}
|
|
156
|
+
aria-label={convertAriaLabel}
|
|
157
|
+
toolTipText={convertLabel}
|
|
158
|
+
onClick={() => {
|
|
159
|
+
setCode(convertToJSX(code).code);
|
|
160
|
+
trackEvent('code_editor_control_click', 'click_event', 'TS_TO_JS');
|
|
161
|
+
}}
|
|
162
|
+
className="ws-code-editor-control"
|
|
163
|
+
/>
|
|
164
|
+
}
|
|
165
|
+
{code !== originalCode &&
|
|
166
|
+
<CodeEditorControl
|
|
167
|
+
icon={<ReplyAllIcon />}
|
|
168
|
+
aria-label={undoAllAriaLabel}
|
|
169
|
+
toolTipText={undoAllLabel}
|
|
170
|
+
onClick={() => {
|
|
171
|
+
setCode(originalCode);
|
|
172
|
+
trackEvent('code_editor_control_click', 'click_event', 'RESET_CODE');
|
|
173
|
+
}}
|
|
174
|
+
className="ws-code-editor-control"
|
|
175
|
+
/>
|
|
176
|
+
}
|
|
177
|
+
</React.Fragment>
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
// TODO: check if worth adding react, patternfly, and example types
|
|
181
|
+
// https://microsoft.github.io/monaco-editor/api/interfaces/monaco.languages.typescript.languageservicedefaults.html#addextralib
|
|
182
|
+
const onEditorDidMount = (_editor, monaco) => {
|
|
183
|
+
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
|
|
184
|
+
jsx: true,
|
|
185
|
+
...monaco.languages.typescript.typescriptDefaults.getCompilerOptions()
|
|
186
|
+
});
|
|
187
|
+
monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
|
|
188
|
+
noSemanticValidation: true,
|
|
189
|
+
noSyntaxValidation: true,
|
|
190
|
+
noSuggestionDiagnostics: true,
|
|
191
|
+
onlyVisible: true
|
|
192
|
+
});
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
return (
|
|
196
|
+
<CodeEditor
|
|
197
|
+
customControls={customControls}
|
|
198
|
+
showEditor={isEditorOpen}
|
|
199
|
+
language={getLanguage(lang)}
|
|
200
|
+
height="400px"
|
|
201
|
+
code={code}
|
|
202
|
+
onChange={newCode => setCode(newCode)}
|
|
203
|
+
onEditorDidMount={onEditorDidMount}
|
|
204
|
+
isReadOnly={isFullscreen}
|
|
205
|
+
className={`${isEditorOpen ? 'ws-example-code-expanded ' : ''}ws-code-editor`}
|
|
206
|
+
/>
|
|
207
|
+
);
|
|
208
|
+
}
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
.ws-org-pfsite-l-footer.pf-c-page__main-section {
|
|
2
|
+
font-family: "RedHatText";
|
|
3
|
+
font-weight: 300;
|
|
4
|
+
background-color: #1a1a1a !important;
|
|
5
|
+
padding: 48px;
|
|
6
|
+
padding-top: 32px;
|
|
7
|
+
/* Hide long overflowing tocs */
|
|
8
|
+
z-index: 1;
|
|
9
|
+
}
|
|
10
|
+
.ws-org-pfsite-l-footer .ws-org-pfsite-footer-menu-list-title {
|
|
11
|
+
margin: 0;
|
|
12
|
+
padding: 6px 0;
|
|
13
|
+
font-weight: 700 !important;
|
|
14
|
+
font-size: 14px !important;
|
|
15
|
+
color: #fff;
|
|
16
|
+
text-transform: uppercase;
|
|
17
|
+
}
|
|
18
|
+
.ws-org-pfsite-l-footer .ws-org-pfsite-l-footer-column {
|
|
19
|
+
background-color: #333;
|
|
20
|
+
height: 100%;
|
|
21
|
+
}
|
|
22
|
+
.ws-org-pfsite-l-footer-column .ws-org-pfsite-footer-menu-about-logo {
|
|
23
|
+
padding-top: 12px;
|
|
24
|
+
}
|
|
25
|
+
.ws-org-pfsite-l-footer-column .ws-org-pfsite-footer-menu-about-description {
|
|
26
|
+
font-size: 14px !important;
|
|
27
|
+
color: #fff;
|
|
28
|
+
}
|
|
29
|
+
@media (max-width: 992px) {
|
|
30
|
+
.ws-org-pfsite-l-footer-column .ws-org-pfsite-footer-menu-about-description {
|
|
31
|
+
padding-bottom: 16px;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
.ws-org-pfsite-l-footer-column .ws-org-pfsite-footer-menu-social-links a {
|
|
35
|
+
margin-right: var(--pf-global--spacer--md);
|
|
36
|
+
color: var(--pf-global--Color--light-100) !important;
|
|
37
|
+
}
|
|
38
|
+
.ws-org-pfsite-l-footer-column
|
|
39
|
+
.ws-org-pfsite-footer-menu-social-links
|
|
40
|
+
a:last-of-type {
|
|
41
|
+
margin-right: 0;
|
|
42
|
+
}
|
|
43
|
+
.ws-org-pfsite-l-footer-column .ws-org-pfsite-footer-menu-social-links {
|
|
44
|
+
margin-top: var(--pf-global--spacer--md);
|
|
45
|
+
margin-bottom: var(--pf-global--spacer--md);
|
|
46
|
+
}
|
|
47
|
+
@media (max-width: 768px) {
|
|
48
|
+
.ws-org-pfsite-l-footer-column .ws-org-pfsite-footer-menu-social-links {
|
|
49
|
+
margin-bottom: 32px;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
.ws-org-pfsite-l-footer .ws-org-pfsite-footer-menu-list {
|
|
53
|
+
margin: 0.8rem 0 0;
|
|
54
|
+
}
|
|
55
|
+
@media (min-width: 992px) {
|
|
56
|
+
.ws-org-pfsite-l-footer .ws-org-pfsite-footer-menu-list {
|
|
57
|
+
width: 84%;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
@media (min-width: 768px) {
|
|
61
|
+
.ws-org-pfsite-l-footer .ws-org-pfsite-footer-menu-list {
|
|
62
|
+
display: block;
|
|
63
|
+
height: auto !important;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
.ws-org-pfsite-l-footer .ws-org-pfsite-footer-menu-list-item {
|
|
67
|
+
font-size: 1.2rem;
|
|
68
|
+
line-height: 1.3;
|
|
69
|
+
padding-right: 10px;
|
|
70
|
+
}
|
|
71
|
+
.ws-org-pfsite-l-footer .ws-org-pfsite-footer-menu-link {
|
|
72
|
+
color: var(--pf-global--Color--light-100);
|
|
73
|
+
font-size: 14px !important;
|
|
74
|
+
}
|
|
75
|
+
.ws-org-pfsite-l-footer .ws-org-pfsite-footer-menu-link:hover {
|
|
76
|
+
text-decoration: underline;
|
|
77
|
+
}
|
|
78
|
+
@media screen and (max-width: 768px) {
|
|
79
|
+
.pfsite-l-footer-column {
|
|
80
|
+
margin-left: -16px;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.ws-org-pfsite-l-footer-dark {
|
|
85
|
+
background: #151515 !important;
|
|
86
|
+
}
|
|
87
|
+
.pf-c-page .pf-c-page__main-section.ws-org-pfsite-l-footer-dark {
|
|
88
|
+
/* Hide long overflowing tocs */
|
|
89
|
+
z-index: 1;
|
|
90
|
+
}
|
|
91
|
+
.pf-c-page__main-section.ws-org-pfsite-l-footer-dark > * {
|
|
92
|
+
font-weight: 300;
|
|
93
|
+
font-size: 12px;
|
|
94
|
+
color: #d2d2d2;
|
|
95
|
+
}
|
|
96
|
+
.ws-org-pfsite-l-footer-dark a {
|
|
97
|
+
padding-right: var(--pf-global--spacer--sm);
|
|
98
|
+
padding-left: var(--pf-global--spacer--sm);
|
|
99
|
+
border-right: var(--pf-global--BorderWidth--sm) solid #d2d2d2;
|
|
100
|
+
font-weight: 300;
|
|
101
|
+
color: #d2d2d2;
|
|
102
|
+
text-decoration: underline;
|
|
103
|
+
}
|
|
104
|
+
.ws-org-pfsite-l-footer-dark a:first-of-type {
|
|
105
|
+
padding-left: 0;
|
|
106
|
+
}
|
|
107
|
+
.ws-org-pfsite-l-footer-dark a:last-of-type {
|
|
108
|
+
padding-right: 0;
|
|
109
|
+
border: none;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.ws-org-pfsite-site-copyright {
|
|
113
|
+
white-space: nowrap;
|
|
114
|
+
}
|