@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,78 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
|
3
|
+
const { prerender } = require('./prerender');
|
|
4
|
+
const { getTitle } = require('../../helpers/getTitle');
|
|
5
|
+
|
|
6
|
+
const templateDir = path.join(__dirname, '../../templates');
|
|
7
|
+
|
|
8
|
+
async function getHtmlWebpackPlugin({
|
|
9
|
+
isProd,
|
|
10
|
+
googleAnalyticsID,
|
|
11
|
+
algolia,
|
|
12
|
+
pathPrefix = '',
|
|
13
|
+
url,
|
|
14
|
+
title,
|
|
15
|
+
isFullscreen
|
|
16
|
+
}) {
|
|
17
|
+
return new HtmlWebpackPlugin({
|
|
18
|
+
template: path.join(templateDir, 'html.ejs'),
|
|
19
|
+
filename: `${url}/index.html`.replace(/^\/+/, ''),
|
|
20
|
+
templateParameters: {
|
|
21
|
+
title: getTitle(title),
|
|
22
|
+
// Don't prerender fullscreen pages (expensive!)
|
|
23
|
+
prerendering: (isProd && !isFullscreen && !url.includes('extensions')) ? await prerender(url, pathPrefix) : 'Loading...',
|
|
24
|
+
// Don't use GA in dev mode
|
|
25
|
+
googleAnalyticsID: isProd ? googleAnalyticsID : false,
|
|
26
|
+
algolia
|
|
27
|
+
},
|
|
28
|
+
scriptLoading: 'defer',
|
|
29
|
+
inject: false,
|
|
30
|
+
minify: false
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function getHtmlWebpackPlugins(options) {
|
|
35
|
+
const { isProd } = options;
|
|
36
|
+
const { routes, fullscreenRoutes } = require('../../routes');
|
|
37
|
+
const res = [
|
|
38
|
+
// Sitemap
|
|
39
|
+
new HtmlWebpackPlugin({
|
|
40
|
+
template: path.join(templateDir, 'sitemap.ejs'),
|
|
41
|
+
filename: 'sitemap.xml',
|
|
42
|
+
templateParameters: {
|
|
43
|
+
urls: Object.entries(routes)
|
|
44
|
+
.map(([path, { sources }]) => [path, ...(sources || []).slice(1).map(source => source.slug)])
|
|
45
|
+
.flat()
|
|
46
|
+
},
|
|
47
|
+
inject: false,
|
|
48
|
+
minify: false,
|
|
49
|
+
})
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
if (!isProd) {
|
|
53
|
+
// Only render the index page in dev mode and rely on historyApiFallback
|
|
54
|
+
res.push(await getHtmlWebpackPlugin({ isProd, url: '', title: 'Dev', ...options }));
|
|
55
|
+
return res;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const titledRoutes = Object.entries(routes)
|
|
59
|
+
.concat(Object.entries(fullscreenRoutes))
|
|
60
|
+
.map(([url, { sources = [], title, isFullscreen }]) => [
|
|
61
|
+
[url, { title, isFullscreen }],
|
|
62
|
+
// Add pages for sources
|
|
63
|
+
...sources.slice(1).map(source => [source.slug, source])
|
|
64
|
+
])
|
|
65
|
+
.flat()
|
|
66
|
+
.sort();
|
|
67
|
+
|
|
68
|
+
for (const [url, { title, isFullscreen }] of titledRoutes) {
|
|
69
|
+
res.push(await getHtmlWebpackPlugin({ url, title, isFullscreen, ...options }));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
console.log('done prerendering');
|
|
73
|
+
return res;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
module.exports = {
|
|
77
|
+
getHtmlWebpackPlugins
|
|
78
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const React = require('react');
|
|
2
|
+
const ReactDOMServer = require('react-dom/server');
|
|
3
|
+
const { ServerLocation } = require('@reach/router');
|
|
4
|
+
const ssrPrepass = require('react-ssr-prepass');
|
|
5
|
+
// react, react-dom, and @reach/router are all EXCLUDED from the ssr-bundle.js
|
|
6
|
+
// The versions imported above are used instead, which allows us to use <ServerLocation>
|
|
7
|
+
// const ssrPrepass = require('react-ssr-prepass');
|
|
8
|
+
|
|
9
|
+
// This function is effectively synchronous because it mutates global.setTimeout
|
|
10
|
+
// Only allow one copy at a time to run
|
|
11
|
+
async function prerender(url, pathPrefix) {
|
|
12
|
+
url = `${pathPrefix}${url}`;
|
|
13
|
+
const location = { pathname: url };
|
|
14
|
+
// For @reach/router
|
|
15
|
+
global.history = {};
|
|
16
|
+
global.location = location
|
|
17
|
+
global.window = {
|
|
18
|
+
location,
|
|
19
|
+
// For virtualized-edit-extension
|
|
20
|
+
getBoundingClientRect: () => ({
|
|
21
|
+
height: 0,
|
|
22
|
+
width: 0
|
|
23
|
+
})
|
|
24
|
+
};
|
|
25
|
+
// For monaco
|
|
26
|
+
global.navigator = {
|
|
27
|
+
userAgent: '',
|
|
28
|
+
maxTouchPoints: 1
|
|
29
|
+
};
|
|
30
|
+
global.document = {
|
|
31
|
+
queryCommandSupported: () => true,
|
|
32
|
+
// For react-consoles
|
|
33
|
+
createElementNS: () => ({
|
|
34
|
+
download: {}
|
|
35
|
+
})
|
|
36
|
+
};
|
|
37
|
+
global.self = {
|
|
38
|
+
// For react-console
|
|
39
|
+
document: global.document
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
console.log('prender', url);
|
|
43
|
+
const { App } = require(`${process.cwd()}/.cache/ssr-build/main`);
|
|
44
|
+
const WrappedApp = React.createElement(ServerLocation, { url },
|
|
45
|
+
React.createElement(App)
|
|
46
|
+
);
|
|
47
|
+
await ssrPrepass(WrappedApp, element => {
|
|
48
|
+
if (element.type.name === 'AsyncComponent') {
|
|
49
|
+
return element.type.preload();
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
const string = ReactDOMServer.renderToString(WrappedApp);
|
|
53
|
+
|
|
54
|
+
return string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
module.exports = {
|
|
58
|
+
prerender
|
|
59
|
+
};
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const webpack = require('webpack');
|
|
3
|
+
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
|
4
|
+
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
|
5
|
+
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
|
|
6
|
+
|
|
7
|
+
module.exports = (_env, argv) => {
|
|
8
|
+
const {
|
|
9
|
+
pathPrefix = '',
|
|
10
|
+
mode,
|
|
11
|
+
algolia = {},
|
|
12
|
+
hasGdprBanner = false,
|
|
13
|
+
hasFooter = false,
|
|
14
|
+
hasVersionSwitcher = false,
|
|
15
|
+
hasDesignGuidelines = false,
|
|
16
|
+
sideNavItems = [],
|
|
17
|
+
topNavItems = [],
|
|
18
|
+
includePaths = []
|
|
19
|
+
} = argv;
|
|
20
|
+
|
|
21
|
+
const isProd = mode === 'production';
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
entry: path.resolve(__dirname, '../../app.js'),
|
|
25
|
+
output: {
|
|
26
|
+
publicPath: isProd ? `${pathPrefix}/` : '/',
|
|
27
|
+
pathinfo: false, // https://webpack.js.org/guides/build-performance/#output-without-path-info,
|
|
28
|
+
hashDigestLength: 8
|
|
29
|
+
},
|
|
30
|
+
amd: false, // We don't use any AMD modules, helps performance
|
|
31
|
+
mode: isProd ? 'production' : 'development',
|
|
32
|
+
devtool: isProd ? false : 'cheap-module-source-map',
|
|
33
|
+
module: {
|
|
34
|
+
rules: [
|
|
35
|
+
{
|
|
36
|
+
test: /\.[tj]sx?$/,
|
|
37
|
+
include: [
|
|
38
|
+
path.resolve(process.cwd(), 'src'),
|
|
39
|
+
path.resolve(process.cwd(), 'patternfly-docs'),
|
|
40
|
+
path.resolve(__dirname, '../..'), // Temporarily compile theme using webpack for development
|
|
41
|
+
/react-[\w-]+\/src\/.*\/examples/,
|
|
42
|
+
/react-[\w-]+\\src\\.*\\examples/, // fix for Windows
|
|
43
|
+
].concat(includePaths.map(path => new RegExp(path))),
|
|
44
|
+
exclude: [
|
|
45
|
+
path.resolve(__dirname, '../../node_modules'), // Temporarily compile theme using webpack for development
|
|
46
|
+
],
|
|
47
|
+
use: {
|
|
48
|
+
loader: 'babel-loader',
|
|
49
|
+
options: {
|
|
50
|
+
cacheDirectory: '.cache/babel',
|
|
51
|
+
cacheCompression: false,
|
|
52
|
+
presets: [['@babel/preset-env', {
|
|
53
|
+
loose: true,
|
|
54
|
+
corejs: 3,
|
|
55
|
+
useBuiltIns: 'entry',
|
|
56
|
+
exclude: ['transform-regenerator', 'transform-async-to-generator'],
|
|
57
|
+
modules: false,
|
|
58
|
+
targets: "> 0.25%, not dead"
|
|
59
|
+
}]],
|
|
60
|
+
plugins: [
|
|
61
|
+
'@babel/plugin-transform-react-jsx',
|
|
62
|
+
'@babel/plugin-proposal-class-properties',
|
|
63
|
+
["@babel/plugin-proposal-private-methods", { "loose": false }],
|
|
64
|
+
["@babel/plugin-proposal-private-property-in-object", { "loose": false }]
|
|
65
|
+
],
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
test: /\.(png|jpe?g|webp)$/,
|
|
71
|
+
use: {
|
|
72
|
+
loader: 'responsive-loader',
|
|
73
|
+
options: {
|
|
74
|
+
adapter: require('responsive-loader/sharp'),
|
|
75
|
+
name: '[name].[contenthash].[ext]',
|
|
76
|
+
outputPath: 'images/'
|
|
77
|
+
},
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
test: /\.(gif|svg)$/,
|
|
82
|
+
use: {
|
|
83
|
+
loader: 'file-loader',
|
|
84
|
+
options: {
|
|
85
|
+
name: '[name].[contenthash].[ext]',
|
|
86
|
+
outputPath: 'images/'
|
|
87
|
+
},
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
test: /\.(pdf)$/,
|
|
92
|
+
use: {
|
|
93
|
+
loader: 'file-loader',
|
|
94
|
+
options: {
|
|
95
|
+
name: '[name].[contenthash].[ext]',
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
test: /.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
|
|
101
|
+
use: [
|
|
102
|
+
{
|
|
103
|
+
loader: 'file-loader',
|
|
104
|
+
options: {
|
|
105
|
+
name: '[name].[ext]',
|
|
106
|
+
outputPath: 'fonts/'
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
},
|
|
113
|
+
resolve: {
|
|
114
|
+
// Allow importing client routes
|
|
115
|
+
alias: {
|
|
116
|
+
'client-styles': path.resolve(process.cwd(), 'patternfly-docs/patternfly-docs.css.js'),
|
|
117
|
+
'./routes-client': path.resolve(process.cwd(), 'patternfly-docs/patternfly-docs.routes.js'),
|
|
118
|
+
'./routes-generated': path.resolve(process.cwd(), 'patternfly-docs/generated/index.js'),
|
|
119
|
+
'lodash': 'lodash-es' // Sanely bundle react-charts.
|
|
120
|
+
},
|
|
121
|
+
modules: [
|
|
122
|
+
'node_modules',
|
|
123
|
+
...module.paths,
|
|
124
|
+
]
|
|
125
|
+
},
|
|
126
|
+
// Use this module's node_modules first (for use in Core/React workspaces)
|
|
127
|
+
resolveLoader: {
|
|
128
|
+
modules: module.paths,
|
|
129
|
+
},
|
|
130
|
+
plugins: [
|
|
131
|
+
new webpack.DefinePlugin({
|
|
132
|
+
'process.env.NODE_ENV': JSON.stringify(mode),
|
|
133
|
+
'process.env.pathPrefix': JSON.stringify(isProd ? pathPrefix : ''),
|
|
134
|
+
'process.env.algolia': JSON.stringify(algolia),
|
|
135
|
+
'process.env.hasGdprBanner': JSON.stringify(hasGdprBanner),
|
|
136
|
+
'process.env.hasFooter': JSON.stringify(hasFooter),
|
|
137
|
+
'process.env.hasVersionSwitcher': JSON.stringify(hasVersionSwitcher),
|
|
138
|
+
'process.env.hasDesignGuidelines': JSON.stringify(hasDesignGuidelines),
|
|
139
|
+
'process.env.sideNavItems': JSON.stringify(sideNavItems),
|
|
140
|
+
'process.env.topNavItems': JSON.stringify(topNavItems),
|
|
141
|
+
'process.env.prnum': JSON.stringify(process.env.CIRCLE_PR_NUMBER || process.env.PR_NUMBER || ''),
|
|
142
|
+
'process.env.prurl': JSON.stringify(process.env.CIRCLE_PULL_REQUEST || ''),
|
|
143
|
+
}),
|
|
144
|
+
new CopyWebpackPlugin({
|
|
145
|
+
patterns: [
|
|
146
|
+
{ from: path.join(__dirname, '../../assets'), to: 'assets' }
|
|
147
|
+
]
|
|
148
|
+
}),
|
|
149
|
+
new MonacoWebpackPlugin(),
|
|
150
|
+
...(isProd
|
|
151
|
+
? [
|
|
152
|
+
new CleanWebpackPlugin()
|
|
153
|
+
]
|
|
154
|
+
: []
|
|
155
|
+
)
|
|
156
|
+
],
|
|
157
|
+
stats: 'minimal'
|
|
158
|
+
};
|
|
159
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const { merge } = require('webpack-merge');
|
|
4
|
+
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
|
5
|
+
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
|
6
|
+
const TerserPlugin = require('terser-webpack-plugin');
|
|
7
|
+
const CopyPlugin = require('copy-webpack-plugin');
|
|
8
|
+
const baseConfig = require('./webpack.base.config');
|
|
9
|
+
const { getHtmlWebpackPlugins } = require('./getHtmlWebpackPlugins');
|
|
10
|
+
|
|
11
|
+
let pfDir;
|
|
12
|
+
try {
|
|
13
|
+
pfDir = path.dirname(require.resolve('@patternfly/patternfly/package.json'));
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
// Inside core workspace
|
|
17
|
+
pfDir = path.join(process.cwd(), 'dist');
|
|
18
|
+
}
|
|
19
|
+
const staticDir = path.join(process.cwd(), 'static/');
|
|
20
|
+
// Don't include PatternFly styles twice
|
|
21
|
+
const reactCSSRegex = /(react-[\w-]+\/dist|react-styles\/css)\/.*\.css$/;
|
|
22
|
+
const reactJSRegex = /react-([^\\/]*)[\\/]dist[\\/].*\.js$/
|
|
23
|
+
|
|
24
|
+
const clientConfig = async (env, argv) => {
|
|
25
|
+
const isProd = argv.mode === 'production';
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
output: {
|
|
29
|
+
path: argv.output ? path.resolve(argv.output) : path.resolve('public'),
|
|
30
|
+
filename: '[name].[hash].bundle.js'
|
|
31
|
+
},
|
|
32
|
+
devServer: {
|
|
33
|
+
hot: true,
|
|
34
|
+
historyApiFallback: true,
|
|
35
|
+
port: argv.port,
|
|
36
|
+
clientLogLevel: 'info',
|
|
37
|
+
stats: 'minimal'
|
|
38
|
+
},
|
|
39
|
+
optimization: {
|
|
40
|
+
splitChunks: {
|
|
41
|
+
chunks: 'all',
|
|
42
|
+
// https://webpack.js.org/plugins/mini-css-extract-plugin/#extracting-all-css-in-a-single-file
|
|
43
|
+
cacheGroups: {
|
|
44
|
+
vendorStyles: {
|
|
45
|
+
test: /[\\/]node_modules[\\/].*\.css$/,
|
|
46
|
+
priority: 9
|
|
47
|
+
},
|
|
48
|
+
mainStyles: {
|
|
49
|
+
test: /\.css$/,
|
|
50
|
+
priority: 10
|
|
51
|
+
},
|
|
52
|
+
// This speeds up reloads 2x in React and doesn't affect org's reload times
|
|
53
|
+
...(!isProd && {
|
|
54
|
+
reactPackage: {
|
|
55
|
+
test: reactJSRegex,
|
|
56
|
+
name(module, _chunks, cacheGroupKey) {
|
|
57
|
+
const package = module.identifier().match(reactJSRegex)[1];
|
|
58
|
+
return `${cacheGroupKey}-${package}`;
|
|
59
|
+
},
|
|
60
|
+
reuseExistingChunk: true,
|
|
61
|
+
priority: 5
|
|
62
|
+
},
|
|
63
|
+
}),
|
|
64
|
+
defaultVendors: {
|
|
65
|
+
test: /[\\/]node_modules[\\/]/,
|
|
66
|
+
enforce: true,
|
|
67
|
+
reuseExistingChunk: true,
|
|
68
|
+
priority: 3
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
minimize: isProd ? true : false,
|
|
73
|
+
minimizer: [
|
|
74
|
+
new TerserPlugin({
|
|
75
|
+
cache: path.join(process.cwd(), '.cache/terser'),
|
|
76
|
+
...(process.env.CI ? { parallel: 2 } : {})
|
|
77
|
+
}),
|
|
78
|
+
],
|
|
79
|
+
runtimeChunk: 'single',
|
|
80
|
+
},
|
|
81
|
+
module: {
|
|
82
|
+
rules: [
|
|
83
|
+
{
|
|
84
|
+
test: /\.css$/,
|
|
85
|
+
exclude: reactCSSRegex,
|
|
86
|
+
use: [
|
|
87
|
+
{
|
|
88
|
+
loader: MiniCssExtractPlugin.loader,
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
loader: 'css-loader'
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
loader: 'postcss-loader',
|
|
95
|
+
options: {
|
|
96
|
+
postcssOptions: {
|
|
97
|
+
plugins: [
|
|
98
|
+
require('autoprefixer')({
|
|
99
|
+
env: '>0.25%, not ie 11, not op_mini all',
|
|
100
|
+
flexbox: false,
|
|
101
|
+
grid: false
|
|
102
|
+
})
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
test: reactCSSRegex,
|
|
111
|
+
use: 'null-loader'
|
|
112
|
+
},
|
|
113
|
+
]
|
|
114
|
+
},
|
|
115
|
+
plugins: [
|
|
116
|
+
new MiniCssExtractPlugin(!isProd ? {} : {
|
|
117
|
+
filename: '[name].[contenthash].css',
|
|
118
|
+
chunkFilename: '[name].[contenthash].css',
|
|
119
|
+
}),
|
|
120
|
+
new CopyPlugin({
|
|
121
|
+
patterns: [
|
|
122
|
+
// versions.json will later be copied to the root www dir
|
|
123
|
+
{ from: path.join(__dirname, '../../versions.json'), to: 'versions.json' },
|
|
124
|
+
{ from: path.join(pfDir, 'assets/images/'), to: 'assets/images/' },
|
|
125
|
+
{ from: path.join(pfDir, 'assets/fonts/'), to: 'assets/fonts/' },
|
|
126
|
+
...(fs.existsSync(staticDir) ? [{ from: staticDir, to: '' }] : [])
|
|
127
|
+
]
|
|
128
|
+
}),
|
|
129
|
+
...await getHtmlWebpackPlugins({ isProd, ...argv }), // Create an HTML page per route
|
|
130
|
+
...(env === 'analyze'
|
|
131
|
+
? [
|
|
132
|
+
new BundleAnalyzerPlugin({
|
|
133
|
+
generateStatsFile: true,
|
|
134
|
+
statsFilename: 'webpack.stats.json'
|
|
135
|
+
})
|
|
136
|
+
]
|
|
137
|
+
: [])
|
|
138
|
+
]
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// https://webpack.js.org/configuration/configuration-types/#exporting-a-promise
|
|
143
|
+
module.exports = async (env = {}, argv) => merge(
|
|
144
|
+
baseConfig(env, argv),
|
|
145
|
+
await clientConfig(env, argv)
|
|
146
|
+
);
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const webpack = require('webpack');
|
|
3
|
+
const { merge } = require('webpack-merge');
|
|
4
|
+
const baseConfig = require('./webpack.base.config');
|
|
5
|
+
|
|
6
|
+
const serverConfig = () => {
|
|
7
|
+
return {
|
|
8
|
+
output: {
|
|
9
|
+
path: path.resolve('.cache/ssr-build'), // Don't bloat `public` dir
|
|
10
|
+
libraryTarget: 'commonjs2' // Use module.exports
|
|
11
|
+
},
|
|
12
|
+
target: 'node', // Load chunks using require
|
|
13
|
+
plugins: [
|
|
14
|
+
new webpack.DefinePlugin({
|
|
15
|
+
'process.env.PRERENDER': true // In app.js don't call ReactDOM.render
|
|
16
|
+
}),
|
|
17
|
+
],
|
|
18
|
+
optimization: {
|
|
19
|
+
removeAvailableModules: false,
|
|
20
|
+
removeEmptyChunks: false,
|
|
21
|
+
splitChunks: false,
|
|
22
|
+
minimize: false // Faster build, easier debugging
|
|
23
|
+
},
|
|
24
|
+
module: {
|
|
25
|
+
rules: [
|
|
26
|
+
{
|
|
27
|
+
test: /\.css$/,
|
|
28
|
+
use: 'null-loader'
|
|
29
|
+
},
|
|
30
|
+
// This does weird things to document
|
|
31
|
+
{
|
|
32
|
+
test: /(novnc-core|@novnc\/novnc)\/.*\.js/,
|
|
33
|
+
use: 'null-loader'
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
resolve: {
|
|
38
|
+
alias: {
|
|
39
|
+
// This stops prerender from hanging in `yarn build:client`
|
|
40
|
+
'd3-timer': '@patternfly/documentation-framework/helpers/d3-timer',
|
|
41
|
+
// The maintainer will not allow his bundle to be required from a node context
|
|
42
|
+
// https://github.com/xtermjs/xterm.js/pull/3134
|
|
43
|
+
'xterm': '@patternfly/documentation-framework/helpers/xterm',
|
|
44
|
+
'xterm-addon-fit': '@patternfly/documentation-framework/helpers/xterm-addon-fit'
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
// Load in prerender.js instead
|
|
48
|
+
externals: ['react', 'react-dom', '@reach/router']
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = (env = {}, argv) => merge(
|
|
53
|
+
baseConfig(env, argv),
|
|
54
|
+
serverConfig(env, argv)
|
|
55
|
+
);
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const os = require('os');
|
|
3
|
+
const fs = require('fs-extra');
|
|
4
|
+
const { Cluster } = require('puppeteer-cluster');
|
|
5
|
+
const sharp = require('sharp');
|
|
6
|
+
const { fullscreenRoutes } = require('../routes.js');
|
|
7
|
+
|
|
8
|
+
const screenshotBase = path.join(process.cwd(), 'patternfly-docs/generated');
|
|
9
|
+
sharp.cache(false);
|
|
10
|
+
|
|
11
|
+
async function writeScreenshot({ page, data: { url, urlPrefix } }) {
|
|
12
|
+
// Default viewport is 800x600
|
|
13
|
+
await page.setViewport({
|
|
14
|
+
width: 1920,
|
|
15
|
+
height: 1080,
|
|
16
|
+
});
|
|
17
|
+
await page.goto(url);
|
|
18
|
+
await page.waitForSelector('.pf-u-h-100');
|
|
19
|
+
// Wait extra 300ms
|
|
20
|
+
await new Promise(resolve => {
|
|
21
|
+
setTimeout(resolve, 300);
|
|
22
|
+
});
|
|
23
|
+
const outfile = path.join(
|
|
24
|
+
screenshotBase,
|
|
25
|
+
url.replace(`${urlPrefix}/`, '') + '.png'
|
|
26
|
+
);
|
|
27
|
+
fs.ensureDirSync(path.dirname(outfile));
|
|
28
|
+
await page.screenshot({ path: outfile });
|
|
29
|
+
console.log(path.relative(process.cwd(), outfile));
|
|
30
|
+
// Resize since max-width allowed for thumbnails in CSS is 800px
|
|
31
|
+
let buffer = await sharp(outfile)
|
|
32
|
+
.resize(800, 450)
|
|
33
|
+
.toBuffer();
|
|
34
|
+
// Overwrite old file
|
|
35
|
+
await sharp(buffer).toFile(outfile);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function writeScreenshots({ urlPrefix }) {
|
|
39
|
+
const cluster = await Cluster.launch({
|
|
40
|
+
concurrency: Cluster.CONCURRENCY_CONTEXT,
|
|
41
|
+
maxConcurrency: os.cpus().length,
|
|
42
|
+
puppeteerOptions: {
|
|
43
|
+
headless: true, // set to false for testing...
|
|
44
|
+
args: ["--no-sandbox", "--disable-setuid-sandbox"]
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Define a task (in this case: screenshot of page)
|
|
49
|
+
await cluster.task(writeScreenshot);
|
|
50
|
+
|
|
51
|
+
// Add some pages to queue
|
|
52
|
+
Object.entries(fullscreenRoutes)
|
|
53
|
+
.filter(([, { isFullscreenOnly }]) => isFullscreenOnly)
|
|
54
|
+
.forEach(([url,]) => cluster.queue({
|
|
55
|
+
url: `${urlPrefix}${url}`,
|
|
56
|
+
urlPrefix
|
|
57
|
+
}));
|
|
58
|
+
|
|
59
|
+
// Shutdown after everything is done
|
|
60
|
+
await cluster.idle();
|
|
61
|
+
await cluster.close();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
module.exports = {
|
|
65
|
+
writeScreenshots
|
|
66
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Link } from '@patternfly/documentation-framework/components/link/link';
|
|
3
|
+
|
|
4
|
+
export const DesignGuidelineTemplate = (
|
|
5
|
+
<React.Fragment>
|
|
6
|
+
We’re working on some guidelines for this component.
|
|
7
|
+
{' '}If you have any questions in the meantime, feel free to
|
|
8
|
+
{' '}
|
|
9
|
+
<Link to="/community#get-in-touch">
|
|
10
|
+
get in touch with us.
|
|
11
|
+
</Link>
|
|
12
|
+
</React.Fragment>
|
|
13
|
+
);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en-US">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
|
|
6
|
+
<meta name="description" content="PatternFly is Red Hat's open source design system. It consists of components, documentation, and code for building enterprise applications at scale.">
|
|
7
|
+
<title><%= title %></title>
|
|
8
|
+
<link rel="shortcut icon" href="/assets/favicon.ico">
|
|
9
|
+
<link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16.png">
|
|
10
|
+
<link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png">
|
|
11
|
+
<link rel="icon" type="image/png" sizes="48x48" href="/assets/favicon-48x48.png">
|
|
12
|
+
<link rel="manifest" href="/assets/manifest.json">
|
|
13
|
+
<meta name="mobile-web-app-capable" content="yes">
|
|
14
|
+
<meta name="theme-color" content="#151515">
|
|
15
|
+
<meta name="application-name" content="PatternFly docs">
|
|
16
|
+
<%= htmlWebpackPlugin.tags.headTags %>
|
|
17
|
+
</head>
|
|
18
|
+
<body class="pf-m-redhat-updated-font pf-m-redhatmono-font">
|
|
19
|
+
<div id="root">
|
|
20
|
+
<%= prerendering %>
|
|
21
|
+
</div>
|
|
22
|
+
<%= htmlWebpackPlugin.tags.bodyTags %>
|
|
23
|
+
<% if (algolia) { %>
|
|
24
|
+
<script
|
|
25
|
+
async
|
|
26
|
+
crossorigin
|
|
27
|
+
type="module"
|
|
28
|
+
src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js"
|
|
29
|
+
></script>
|
|
30
|
+
<link
|
|
31
|
+
href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css"
|
|
32
|
+
crossorigin
|
|
33
|
+
rel="stylesheet"
|
|
34
|
+
media="print"
|
|
35
|
+
onload="this.media='all'; this.onload=null;"
|
|
36
|
+
>
|
|
37
|
+
<% } %>
|
|
38
|
+
<% if (googleAnalyticsID) { %>
|
|
39
|
+
<!-- Global site tag (gtag.js) - Google Analytics -->
|
|
40
|
+
<script async src="https://www.googletagmanager.com/gtag/js?id=<%= googleAnalyticsID %>"></script>
|
|
41
|
+
<script>
|
|
42
|
+
if(!(parseInt(navigator.doNotTrack) === 1 || parseInt(window.doNotTrack) === 1 || parseInt(navigator.msDoNotTrack) === 1 || navigator.doNotTrack === "yes")) {
|
|
43
|
+
window.dataLayer = window.dataLayer || [];
|
|
44
|
+
function gtag(){dataLayer.push(arguments);}
|
|
45
|
+
gtag('js', new Date());
|
|
46
|
+
|
|
47
|
+
gtag('config', '<%= googleAnalyticsID %>');
|
|
48
|
+
}
|
|
49
|
+
</script>
|
|
50
|
+
<% } %>
|
|
51
|
+
</body>
|
|
52
|
+
</html>
|