@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.
Files changed (115) hide show
  1. package/CHANGELOG.md +3964 -0
  2. package/README.md +92 -0
  3. package/app.js +118 -0
  4. package/assets/android-chrome-36x36.png +0 -0
  5. package/assets/android-chrome-48x48.png +0 -0
  6. package/assets/android-chrome-96x96.png +0 -0
  7. package/assets/favicon-16x16.png +0 -0
  8. package/assets/favicon-32x32.png +0 -0
  9. package/assets/favicon-48x48.png +0 -0
  10. package/assets/favicon.ico +0 -0
  11. package/assets/manifest.json +29 -0
  12. package/components/autoLinkHeader/autoLinkHeader.css +22 -0
  13. package/components/autoLinkHeader/autoLinkHeader.js +41 -0
  14. package/components/cssVariables/cssSearch.js +32 -0
  15. package/components/cssVariables/cssVariables.css +15 -0
  16. package/components/cssVariables/cssVariables.js +233 -0
  17. package/components/example/example.css +106 -0
  18. package/components/example/example.js +196 -0
  19. package/components/example/exampleToolbar.js +208 -0
  20. package/components/example/missing-thumbnail.jpg +0 -0
  21. package/components/footer/RHLogo.png +0 -0
  22. package/components/footer/footer.css +114 -0
  23. package/components/footer/footer.js +262 -0
  24. package/components/gdprBanner/gdprBanner.css +14 -0
  25. package/components/gdprBanner/gdprBanner.js +31 -0
  26. package/components/index.js +12 -0
  27. package/components/inlineAlert/inlineAlert.js +19 -0
  28. package/components/link/link.js +68 -0
  29. package/components/propsTable/propTypeWithLinks.js +33 -0
  30. package/components/propsTable/propsTable.js +82 -0
  31. package/components/sideNav/sideNav.css +17 -0
  32. package/components/sideNav/sideNav.js +95 -0
  33. package/components/tableOfContents/tableOfContents.css +77 -0
  34. package/components/tableOfContents/tableOfContents.js +89 -0
  35. package/components/topNav/topNav.css +30 -0
  36. package/components/topNav/topNav.js +24 -0
  37. package/global.css +7 -0
  38. package/helpers/asyncComponentFactory.js +41 -0
  39. package/helpers/capitalize.js +7 -0
  40. package/helpers/codeTitleTransformer.js +40 -0
  41. package/helpers/codesandbox.js +204 -0
  42. package/helpers/copy.js +19 -0
  43. package/helpers/createHandlebars.js +26 -0
  44. package/helpers/d3-timer.js +7 -0
  45. package/helpers/extractExampleHelpers.js +24 -0
  46. package/helpers/fonts.js +164 -0
  47. package/helpers/getId.js +6 -0
  48. package/helpers/getTitle.js +5 -0
  49. package/helpers/index.js +9 -0
  50. package/helpers/liveCodeTypes.js +4 -0
  51. package/helpers/slugger.js +35 -0
  52. package/helpers/trackEvent.js +17 -0
  53. package/helpers/xterm-addon-fit.js +3 -0
  54. package/helpers/xterm.js +8 -0
  55. package/images/patternfly-logo.svg +14 -0
  56. package/images/patternfly-orb.svg +28 -0
  57. package/layouts/index.js +1 -0
  58. package/layouts/logo.svg +33 -0
  59. package/layouts/sideNavLayout/sideNavLayout.css +104 -0
  60. package/layouts/sideNavLayout/sideNavLayout.js +237 -0
  61. package/package.json +87 -0
  62. package/pages/404/404.css +16 -0
  63. package/pages/404/404.svg +26 -0
  64. package/pages/404/chart.svg +24 -0
  65. package/pages/404/components.svg +1 -0
  66. package/pages/404/guidelines.svg +1 -0
  67. package/pages/404/index.js +136 -0
  68. package/pages/404/patternfly-flat.svg +1 -0
  69. package/pages/global-css-variables.md +108 -0
  70. package/pages/img/component-variable-mapping.png +0 -0
  71. package/pages/red-hat-font.md +40 -0
  72. package/routes-client.js +1 -0
  73. package/routes-generated.js +1 -0
  74. package/routes.js +155 -0
  75. package/scripts/cli/build.js +95 -0
  76. package/scripts/cli/buildClient.js +23 -0
  77. package/scripts/cli/buildServer.js +24 -0
  78. package/scripts/cli/cli.js +63 -0
  79. package/scripts/cli/generate.js +23 -0
  80. package/scripts/cli/helpers.js +9 -0
  81. package/scripts/cli/init.js +68 -0
  82. package/scripts/cli/serve.js +13 -0
  83. package/scripts/cli/start.js +32 -0
  84. package/scripts/md/anchor-header.js +69 -0
  85. package/scripts/md/auto-link-url.js +33 -0
  86. package/scripts/md/example-captions.js +67 -0
  87. package/scripts/md/jsxAttributes.js +20 -0
  88. package/scripts/md/mdx-ast-to-mdx-hast.js +210 -0
  89. package/scripts/md/mdx-hast-to-jsx.js +233 -0
  90. package/scripts/md/parseMD.js +308 -0
  91. package/scripts/md/remove-comments.js +21 -0
  92. package/scripts/md/styled-tags.js +87 -0
  93. package/scripts/md/typecheck.js +133 -0
  94. package/scripts/tsDocgen.js +155 -0
  95. package/scripts/webpack/getHtmlWebpackPlugins.js +78 -0
  96. package/scripts/webpack/prerender.js +59 -0
  97. package/scripts/webpack/webpack.base.config.js +159 -0
  98. package/scripts/webpack/webpack.client.config.js +146 -0
  99. package/scripts/webpack/webpack.server.config.js +55 -0
  100. package/scripts/writeScreenshots.js +66 -0
  101. package/templates/design-guidelines.js +13 -0
  102. package/templates/html.ejs +52 -0
  103. package/templates/mdx.css +308 -0
  104. package/templates/mdx.js +185 -0
  105. package/templates/patternfly-docs/content/extensions/extension/design-guidelines/design-guidelines.md +25 -0
  106. package/templates/patternfly-docs/content/extensions/extension/design-guidelines/img/card-elements.png +0 -0
  107. package/templates/patternfly-docs/content/extensions/extension/examples/Basic.jsx +4 -0
  108. package/templates/patternfly-docs/content/extensions/extension/examples/basic.md +25 -0
  109. package/templates/patternfly-docs/pages/index.js +27 -0
  110. package/templates/patternfly-docs/patternfly-docs.config.js +6 -0
  111. package/templates/patternfly-docs/patternfly-docs.css.js +8 -0
  112. package/templates/patternfly-docs/patternfly-docs.routes.js +12 -0
  113. package/templates/patternfly-docs/patternfly-docs.source.js +24 -0
  114. package/templates/sitemap.ejs +10 -0
  115. package/versions.json +870 -0
package/README.md ADDED
@@ -0,0 +1,92 @@
1
+ # @patternfly/documentation-framework
2
+
3
+ ## Install
4
+
5
+ We publish this theme [on npm.](https://www.npmjs.com/package/@patternfly/documentation-framework) Install it as a devDependency with your package manager.
6
+
7
+ `npm i --save-dev @patternfly/documentation-framework`
8
+
9
+ `yarn add -D @patternfly/documentation-framework`
10
+
11
+ ## First time setup
12
+
13
+ ### Puppeteer
14
+
15
+ Puppeteer is used to create screenshots, it requires chromium to be installed on your machine
16
+
17
+ - install chromium using brew:
18
+
19
+ `brew install chromium`
20
+ - check the chromium path, should point to /opt/homebrew/bin/chromium:
21
+
22
+ `which chromium`
23
+ - export out the path:
24
+
25
+ export PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
26
+
27
+ export PUPPETEER_EXECUTABLE_PATH=\`which chromium\`
28
+
29
+ - So you don't have to retype this in the future, save to your shell rc file like .bashrc or .zshrc:
30
+
31
+ echo 'export PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true' >> ~/.zshrc
32
+
33
+ echo 'export PUPPETEER_EXECUTABLE_PATH=\`which chromium\`' >> ~/.zshrc
34
+
35
+ ### Init documentation project
36
+
37
+ To get started, you can scaffold out a sample extension docs setup:
38
+
39
+ `npx pf-docs-framework init --name "My extension"`
40
+
41
+ If you also want to add relevant script targets to package.json, pass in `--scripts` as well:
42
+
43
+ `npx pf-docs-framework init --name "My extension" --scripts`
44
+
45
+ ## Usage
46
+
47
+ For all CLI options, run `npx pf-docs-framework --help`
48
+
49
+ For individual CLI commands, you can also display more information by running `npx pf-docs-framework <COMMAND> --help`
50
+
51
+ ### Develop docs
52
+
53
+ `yarn docs:develop`
54
+
55
+ or
56
+
57
+ `npx pf-docs-framework start`
58
+
59
+ ### Build docs
60
+
61
+ `yarn docs:build`
62
+
63
+ or
64
+
65
+ `npx pf-docs-framework build all --output public`
66
+
67
+ > NOTE: If you have `sideEffects: false` in your package.json, that will prevent the CSS from loading in the documentation production build. Set it to true or remove it to enable the CSS from being loaded.
68
+
69
+ ### Generate screenshots
70
+
71
+ You can generate screenshots against development or production builds.
72
+
73
+ - Development:
74
+
75
+ Terminal 1:
76
+
77
+ `yarn docs:develop` or `npx pf-docs-framework start` (Take note of the port it started on, you can modify it in patternfly-docs.config)
78
+
79
+ Terminal 2:
80
+
81
+ `yarn docs:screenshots` or `npx pf-docs-framework screenshots --urlPrefix http://localhost:<PORT>`
82
+
83
+ - Production:
84
+
85
+ Terminal 1:
86
+
87
+ - `yarn docs:build` or `npx pf-docs-framework build all --output public`
88
+ - `yarn docs:serve` or `npx pf-docs-framework serve public --port 5000`
89
+
90
+ Terminal 2:
91
+
92
+ `yarn docs:screenshots` or `npx pf-docs-framework screenshots --urlPrefix http://localhost:5000`
package/app.js ADDED
@@ -0,0 +1,118 @@
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom';
3
+ import { Router, useLocation } from '@reach/router';
4
+ import { SideNavLayout } from '@patternfly/documentation-framework/layouts';
5
+ import { Footer } from '@patternfly/documentation-framework/components';
6
+ import { MDXTemplate } from '@patternfly/documentation-framework/templates/mdx';
7
+ import { routes, groupedRoutes, fullscreenRoutes, getAsyncComponent } from './routes';
8
+ import { trackEvent } from './helpers';
9
+ import 'client-styles'; // Webpack replaces this import: patternfly-docs.css.js
10
+ import './components/autoLinkHeader/autoLinkHeader.css';
11
+ import './components/cssVariables/cssVariables.css';
12
+ import './components/tableOfContents/tableOfContents.css';
13
+ import './components/example/example.css';
14
+ import './components/footer/footer.css';
15
+ import './components/sideNav/sideNav.css';
16
+ import './components/topNav/topNav.css';
17
+ import './layouts/sideNavLayout/sideNavLayout.css';
18
+
19
+ const AppRoute = ({ child, katacodaLayout, title, path }) => {
20
+ const pathname = useLocation().pathname;
21
+ if (typeof window !== 'undefined' && window.gtag) {
22
+ gtag('config', 'UA-47523816-6', {
23
+ 'page_path': pathname,
24
+ 'page_title': (title || pathname)
25
+ });
26
+ }
27
+ // Send 404 event if redirected to 404 page
28
+ if (path === '/404' && pathname.split('/').pop() !== '404') {
29
+ trackEvent('404_redirect', 'redirect', pathname);
30
+ }
31
+ return (
32
+ <React.Fragment>
33
+ {child}
34
+ {!katacodaLayout && process.env.hasFooter && <Footer />}
35
+ </React.Fragment>
36
+ );
37
+ }
38
+
39
+ const SideNavRouter = () => {
40
+ const pathname = useLocation().pathname.replace(process.env.pathPrefix, '');
41
+ const navOpen = !routes[pathname] || !routes[pathname].katacodaLayout;
42
+ return (
43
+ <SideNavLayout groupedRoutes={groupedRoutes} navOpen={navOpen} >
44
+ <Router id="ws-page-content-router">
45
+ {Object.entries(routes)
46
+ .map(([path, { Component, title, sources, katacodaLayout }]) => Component
47
+ ? <AppRoute
48
+ key={path}
49
+ path={path}
50
+ default={path === '/404'}
51
+ child={<Component />}
52
+ katacodaLayout={katacodaLayout}
53
+ title={title}
54
+ />
55
+ : <AppRoute
56
+ key={path}
57
+ path={path + '/*'}
58
+ child={
59
+ <MDXTemplate
60
+ path={path}
61
+ title={title}
62
+ sources={sources}
63
+ />
64
+ }
65
+ katacodaLayout={katacodaLayout}
66
+ title={title}
67
+ />
68
+ )
69
+ }
70
+ </Router>
71
+ </SideNavLayout>
72
+ );
73
+ }
74
+
75
+ const FullscreenComponent = ({ Component, title }) => {
76
+ const [isLoaded, setIsLoaded] = React.useState(false);
77
+ React.useEffect(() => {
78
+ Component.preload().then(() => setIsLoaded(true));
79
+ }, []);
80
+ const { examples = {} } = Component.getPageData();
81
+ const Example = examples[title];
82
+ return isLoaded ? <Example isFullscreen={false} isFullscreenPreview /> : <Component />;
83
+ };
84
+
85
+ // Export for SSR
86
+ export const App = () => (
87
+ <Router basepath={process.env.pathPrefix} id="ws-router">
88
+ <SideNavRouter path="/*" />
89
+ {Object.entries(fullscreenRoutes)
90
+ .map(([path, { title, Component }]) =>
91
+ <FullscreenComponent
92
+ key={path}
93
+ path={path}
94
+ Component={Component}
95
+ title={title}
96
+ />
97
+ )
98
+ }
99
+ </Router>
100
+ );
101
+
102
+ const isProd = process.env.NODE_ENV === 'production';
103
+ const isPrerender = process.env.PRERENDER;
104
+ // Don't use ReactDOM in SSR
105
+ if (!isPrerender) {
106
+ function render() {
107
+ const renderFn = isProd ? ReactDOM.hydrate : ReactDOM.render;
108
+ renderFn(<App />, document.getElementById('root'));
109
+ }
110
+ // On first load, await promise for the current page to avoid flashing a "Loading..." state
111
+ const Component = getAsyncComponent(null);
112
+ if (Component) {
113
+ Component.preload().then(render);
114
+ }
115
+ else {
116
+ render();
117
+ }
118
+ }
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "PatternFly docs",
3
+ "short_name": "PatternFly docs",
4
+ "description": "Home of PatternFly Design.",
5
+ "dir": "auto",
6
+ "lang": "en-US",
7
+ "display": "standalone",
8
+ "orientation": "any",
9
+ "start_url": "/",
10
+ "background_color": "#4F5255",
11
+ "theme_color": "#151515",
12
+ "icons": [
13
+ {
14
+ "src": "/assets/android-chrome-36x36.png",
15
+ "sizes": "36x36",
16
+ "type": "image/png"
17
+ },
18
+ {
19
+ "src": "/assets/android-chrome-48x48.png",
20
+ "sizes": "48x48",
21
+ "type": "image/png"
22
+ },
23
+ {
24
+ "src": "/assets/android-chrome-96x96.png",
25
+ "sizes": "96x96",
26
+ "type": "image/png"
27
+ }
28
+ ]
29
+ }
@@ -0,0 +1,22 @@
1
+ .ws-heading {
2
+ position: relative;
3
+ }
4
+
5
+ .ws-heading-anchor {
6
+ color: var(--pf-global--Color--100);
7
+ transform: translate(calc(-100% - var(--pf-global--spacer--xs)), -50%);
8
+ opacity: 0;
9
+ position: absolute;
10
+ left: 0;
11
+ top: 50%;
12
+ }
13
+
14
+ .ws-heading-anchor-icon {
15
+ height: 0.5em;
16
+ width: 0.5em;
17
+ }
18
+
19
+ .ws-heading:hover .ws-heading-anchor,
20
+ .ws-heading-anchor:focus {
21
+ opacity: 1;
22
+ }
@@ -0,0 +1,41 @@
1
+ import React from 'react';
2
+ import { Title } from '@patternfly/react-core';
3
+ import LinkIcon from '@patternfly/react-icons/dist/esm/icons/link-icon';
4
+ import { Link } from '../link/link';
5
+ import { slugger } from '../../helpers/slugger';
6
+
7
+ // "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl"
8
+ const sizes = {
9
+ h1: '3xl',
10
+ h2: '2xl',
11
+ h3: 'xl',
12
+ h4: 'lg',
13
+ h5: 'md',
14
+ h6: 'sm'
15
+ }
16
+
17
+ export const AutoLinkHeader = ({
18
+ id,
19
+ size,
20
+ headingLevel,
21
+ children,
22
+ metaText,
23
+ className
24
+ }) => {
25
+ const slug = id || slugger(children);
26
+
27
+ return (
28
+ <Title
29
+ id={slug}
30
+ size={sizes[size]}
31
+ headingLevel={headingLevel || size}
32
+ className={`ws-heading ${className}`}
33
+ tabIndex={-1}
34
+ >
35
+ <Link href={`#${slug}`} className="ws-heading-anchor" tabIndex="-1" aria-hidden>
36
+ <LinkIcon className="ws-heading-anchor-icon" style={{ verticalAlign: 'middle' }} />
37
+ </Link>
38
+ {children} {metaText}
39
+ </Title>
40
+ )
41
+ };
@@ -0,0 +1,32 @@
1
+ import React from "react";
2
+ import { TextInput } from "@patternfly/react-core";
3
+
4
+ export class CSSSearch extends React.Component {
5
+ constructor(props) {
6
+ super(props);
7
+ this.state = {
8
+ filterValue: ""
9
+ };
10
+ }
11
+
12
+ onFilterChange = (_change, event) => {
13
+ this.setState(
14
+ {
15
+ filterValue: event.target.value
16
+ },
17
+ () => this.props.getDebouncedFilteredRows(this.state.filterValue)
18
+ );
19
+ };
20
+
21
+ render() {
22
+ return (
23
+ <TextInput
24
+ type="text"
25
+ aria-label="Filter CSS Variables"
26
+ placeholder="Filter CSS Variables"
27
+ value={this.state.filterValue}
28
+ onChange={this.onFilterChange}
29
+ />
30
+ );
31
+ }
32
+ }
@@ -0,0 +1,15 @@
1
+ .ws-color-box {
2
+ display: inline-block;
3
+ height: 18px;
4
+ width: 18px;
5
+ border: var(--pf-global--BorderWidth--sm) solid var(--pf-global--BorderColor--200);
6
+ border-radius: var(--pf-global--BorderRadius--lg);
7
+ }
8
+
9
+ .ws-td-text {
10
+ font-size: var(--pf-global--FontSize--sm) !important;
11
+ }
12
+
13
+ .ws-css-property {
14
+ padding: var(--pf-global--spacer--xs) var(--pf-global--spacer--md);
15
+ }
@@ -0,0 +1,233 @@
1
+ import React from "react";
2
+ import { debounce } from "@patternfly/react-core";
3
+ import {
4
+ Table,
5
+ TableHeader,
6
+ TableBody,
7
+ sortable,
8
+ SortByDirection,
9
+ expandable
10
+ } from "@patternfly/react-table";
11
+ import * as tokensModule from "@patternfly/react-tokens/dist/esm/componentIndex";
12
+ import global_spacer_md from "@patternfly/react-tokens/dist/esm/global_spacer_md";
13
+ import LevelUpAltIcon from "@patternfly/react-icons/dist/esm/icons/level-up-alt-icon";
14
+ import { CSSSearch } from './cssSearch';
15
+
16
+ const isColorRegex = /^(#|rgb)/;
17
+
18
+ const mappingAsList = (property, values) => (
19
+ <div>
20
+ <div className="ws-css-property">
21
+ <span>
22
+ {property}
23
+ </span>
24
+ </div>
25
+ {values.map((entry, index) => (
26
+ <div
27
+ key={index}
28
+ style={{
29
+ padding: `4px 0 4px calc(${global_spacer_md.value} * ${index + 3})`
30
+ }}
31
+ >
32
+ <LevelUpAltIcon style={{ transform: 'rotate(90deg)' }} />
33
+ <span style={{ paddingLeft: '16px' }}>
34
+ {entry}
35
+ </span>
36
+ </div>
37
+ ))}
38
+ </div>
39
+ );
40
+
41
+ const flattenList = files => {
42
+ let list = [];
43
+ files.forEach(file => {
44
+ Object.entries(file).forEach(([selector, values]) => {
45
+ Object.entries(values).forEach(([key, val]) => {
46
+ list.push({
47
+ selector,
48
+ property: val.name,
49
+ token: key,
50
+ value: val.value,
51
+ values: val.values
52
+ });
53
+ });
54
+ });
55
+ });
56
+ return list;
57
+ };
58
+
59
+ export class CSSVariables extends React.Component {
60
+ constructor(props) {
61
+ super(props);
62
+ // Ensure array in case of multiple prefixes
63
+ this.prefix =
64
+ typeof props.prefix === "string" ? [props.prefix] : props.prefix;
65
+ const prefixTokens = this.prefix.map(prefix => prefix.replace("pf-", "").replace(/-+/g, "_"));
66
+ const applicableFiles = Object.entries(tokensModule)
67
+ .filter(([key, val]) => prefixTokens.includes(key))
68
+ .sort(([key1], [key2]) => key1.localeCompare(key2))
69
+ .map(([key, val]) => {
70
+ if (props.selector) {
71
+ return {
72
+ [props.selector]: val[props.selector]
73
+ }
74
+ }
75
+ return val;
76
+ });
77
+
78
+ this.flatList = flattenList(applicableFiles);
79
+
80
+ this.columns = [
81
+ ...props.hideSelectorColumn ? [] : [{
82
+ title: "Selector",
83
+ transforms: [sortable],
84
+ cellFormatters: [expandable]
85
+ }],
86
+ { title: "Variable", transforms: [sortable] },
87
+ { title: "Value", transforms: [sortable] }
88
+ ]
89
+
90
+ this.state = {
91
+ searchRE: '',
92
+ rows: this.getFilteredRows(),
93
+ sortBy: {
94
+ index: 0,
95
+ direction: "asc" // a-z
96
+ }
97
+ };
98
+ }
99
+
100
+ getFilteredRows = (searchRE) => {
101
+ let filteredRows = [];
102
+ let rowNumber = -1;
103
+ this.flatList.forEach(row => {
104
+ const { selector, property, token, value, values} = row;
105
+ const passes =
106
+ !searchRE ||
107
+ searchRE.test(selector) ||
108
+ searchRE.test(property) ||
109
+ searchRE.test(value) ||
110
+ (values && searchRE.test(JSON.stringify(values)));
111
+ if (passes) {
112
+ const rowKey = `${selector}_${property}`;
113
+ const cells = [
114
+ ...this.props.hideSelectorColumn ? [] : [selector],
115
+ property,
116
+ <div key={rowKey}>
117
+ <div
118
+ key={`${rowKey}_1`}
119
+ className="pf-l-flex pf-m-space-items-sm"
120
+ >
121
+ {isColorRegex.test(value) && (
122
+ <div
123
+ key={`${rowKey}_2`}
124
+ className="pf-l-flex pf-m-column pf-m-align-self-center"
125
+ >
126
+ <span
127
+ className="ws-color-box"
128
+ style={{ backgroundColor: value }}
129
+ />
130
+ </div>
131
+ )}
132
+ <div
133
+ key={`${rowKey}_3`}
134
+ className="pf-l-flex pf-m-column pf-m-align-self-center ws-td-text"
135
+ >
136
+ {value}
137
+ </div>
138
+ </div>
139
+ </div>
140
+ ];
141
+ filteredRows.push({
142
+ isOpen: values ? false : undefined,
143
+ cells
144
+ });
145
+ rowNumber += 1;
146
+ if (values) {
147
+ filteredRows.push({
148
+ parent: rowNumber,
149
+ fullWidth: true,
150
+ cells: [
151
+ {
152
+ title: mappingAsList(property, values)
153
+ }
154
+ ]
155
+ });
156
+ rowNumber += 1;
157
+ }
158
+ }
159
+ });
160
+ return filteredRows;
161
+ };
162
+
163
+ onCollapse = (event, rowKey, isOpen) => {
164
+ const { rows } = this.state;
165
+ const collapseAll = rowKey === undefined;
166
+ let newRows = Array.from(rows);
167
+
168
+ if (collapseAll) {
169
+ newRows = newRows.map(r => (r.isOpen === undefined ? r : { ...r, isOpen }));
170
+ } else {
171
+ newRows[rowKey] = { ...newRows[rowKey], isOpen };
172
+ }
173
+ this.setState({
174
+ rows: newRows,
175
+ });
176
+ };
177
+
178
+ getDebouncedFilteredRows = debounce(value => {
179
+ const searchRE = new RegExp(value, "i");
180
+ this.setState({
181
+ searchRE,
182
+ rows: this.getFilteredRows(searchRE)
183
+ });
184
+ }, 500);
185
+
186
+ onSort = (_event, index, direction) => {
187
+ this.flatList = this.flatList.sort((a, b) => {
188
+ const indexToColMap = {
189
+ '1': 'selector',
190
+ '2': 'property',
191
+ '3': 'value'
192
+ };
193
+ const column = indexToColMap[index];
194
+ if (direction === SortByDirection.asc) {
195
+ return a[column] < b[column] ? -1 : a[column] > b[column] ? 1 : 0;
196
+ } else {
197
+ return a[column] > b[column] ? -1 : a[column] < b[column] ? 1 : 0;
198
+ }
199
+ });
200
+ this.setState({
201
+ sortBy: {
202
+ index,
203
+ direction
204
+ },
205
+ rows: this.getFilteredRows(this.state.searchRE)
206
+ });
207
+ };
208
+
209
+ render() {
210
+ return (
211
+ <React.Fragment>
212
+ <CSSSearch getDebouncedFilteredRows={this.getDebouncedFilteredRows} />
213
+ <Table
214
+ variant="compact"
215
+ aria-label={`CSS Variables for prefixes ${this.prefix.join(" ")}`}
216
+ sortBy={this.state.sortBy}
217
+ onSort={this.onSort}
218
+ cells={this.columns}
219
+ rows={this.state.rows}
220
+ onCollapse={this.onCollapse}
221
+ canCollapseAll={true}
222
+ collapseAllAriaLabel="expand all css variables"
223
+ gridBreakPoint="grid-lg"
224
+ contentId="css-variables-content"
225
+ expandId="css-variables-toggle"
226
+ >
227
+ <TableHeader />
228
+ <TableBody />
229
+ </Table>
230
+ </React.Fragment>
231
+ );
232
+ }
233
+ }