@patternfly/quickstarts 2.2.2 → 2.3.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/README.md +4 -4
- package/dist/HelpTopicDrawer.d.ts +8 -2
- package/dist/QuickStartDrawer.d.ts +21 -2
- package/dist/controller/QuickStartTaskHeader.d.ts +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +104 -4
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +104 -3
- package/dist/index.js.map +1 -1
- package/dist/patternfly-docs/quick-starts/design-guidelines/design-guidelines.md +105 -0
- package/dist/patternfly-docs/quick-starts/design-guidelines/img/card-elements copy.png +0 -0
- package/dist/patternfly-docs/quick-starts/design-guidelines/img/card-elements.png +0 -0
- package/dist/patternfly-docs/quick-starts/design-guidelines/img/catalog-elements.png +0 -0
- package/dist/patternfly-docs/quick-starts/design-guidelines/img/check-your-work.png +0 -0
- package/dist/patternfly-docs/quick-starts/design-guidelines/img/introduction-screen.png +0 -0
- package/dist/patternfly-docs/quick-starts/design-guidelines/img/mixed-catalog.png +0 -0
- package/dist/patternfly-docs/quick-starts/design-guidelines/img/prerequisites.png +0 -0
- package/dist/patternfly-docs/quick-starts/design-guidelines/img/qs-context.png +0 -0
- package/dist/patternfly-docs/quick-starts/design-guidelines/img/side-panel-elements.png +0 -0
- package/dist/patternfly-docs/quick-starts/design-guidelines/img/side-panel-resized.png +0 -0
- package/dist/patternfly-docs/quick-starts/design-guidelines/img/side-panel.png +0 -0
- package/dist/patternfly-docs/quick-starts/design-guidelines/img/task-no.png +0 -0
- package/dist/patternfly-docs/quick-starts/design-guidelines/img/task-yes.png +0 -0
- package/dist/patternfly-docs/quick-starts/design-guidelines/img/task.png +0 -0
- package/dist/patternfly-docs/quick-starts/examples/Basic.jsx +73 -0
- package/dist/patternfly-docs/quick-starts/examples/HelpTopic.jsx +53 -0
- package/dist/patternfly-docs/quick-starts/examples/about.md +77 -0
- package/dist/patternfly-docs/quick-starts/examples/basic.md +27 -0
- package/dist/patternfly-docs/quick-starts/examples/example-data/example-help-topics.js +173 -0
- package/dist/patternfly-docs/quick-starts/examples/example-data/example-quickstarts.js +215 -0
- package/dist/patternfly-docs/quick-starts/examples/example-data/index.js +15 -0
- package/dist/patternfly-docs/quick-starts/examples/help-topics.md +25 -0
- package/dist/patternfly-docs/quick-starts/examples/img/catalog.png +0 -0
- package/dist/patternfly-docs/quick-starts/examples/img/help-topic.png +0 -0
- package/dist/patternfly-docs/quick-starts/examples/img/side-panel.png +0 -0
- package/dist/quickstarts-full.es.js +104 -4
- package/dist/quickstarts-full.es.js.map +1 -1
- package/dist/utils/asciidoc-procedure-parser.d.ts +12 -0
- package/package.json +11 -4
- package/src/ConsoleInternal/components/_icon-and-text.scss +14 -0
- package/src/ConsoleInternal/components/_markdown-view.scss +19 -0
- package/src/ConsoleInternal/components/catalog/_catalog.scss +390 -0
- package/src/ConsoleInternal/components/markdown-view.tsx +305 -0
- package/src/ConsoleInternal/components/utils/_status-box.scss +58 -0
- package/src/ConsoleInternal/components/utils/camel-case-wrap.tsx +33 -0
- package/src/ConsoleInternal/components/utils/index.tsx +3 -0
- package/src/ConsoleInternal/components/utils/router.ts +47 -0
- package/src/ConsoleInternal/components/utils/status-box.tsx +94 -0
- package/src/ConsoleInternal/module/k8s/types.ts +53 -0
- package/src/ConsoleShared/index.ts +1 -0
- package/src/ConsoleShared/src/components/index.ts +7 -0
- package/src/ConsoleShared/src/components/layout/PageLayout.scss +29 -0
- package/src/ConsoleShared/src/components/markdown-extensions/MarkdownCopyClipboard.tsx +93 -0
- package/src/ConsoleShared/src/components/markdown-extensions/__tests__/MarkdownCopyClipboard.spec.tsx +25 -0
- package/src/ConsoleShared/src/components/markdown-extensions/__tests__/test-data.ts +5 -0
- package/src/ConsoleShared/src/components/markdown-extensions/admonition-extension.tsx +66 -0
- package/src/ConsoleShared/src/components/markdown-extensions/code-extension.tsx +25 -0
- package/src/ConsoleShared/src/components/markdown-extensions/const.ts +3 -0
- package/src/ConsoleShared/src/components/markdown-extensions/index.ts +5 -0
- package/src/ConsoleShared/src/components/markdown-extensions/inline-clipboard-extension.tsx +45 -0
- package/src/ConsoleShared/src/components/markdown-extensions/multiline-clipboard-extension.tsx +50 -0
- package/src/ConsoleShared/src/components/markdown-extensions/showdown-extension.scss +52 -0
- package/src/ConsoleShared/src/components/markdown-extensions/utils.ts +3 -0
- package/src/ConsoleShared/src/components/markdown-highlight-extension/MarkdownHighlightExtension.tsx +64 -0
- package/src/ConsoleShared/src/components/markdown-highlight-extension/highlight-consts.ts +9 -0
- package/src/ConsoleShared/src/components/markdown-highlight-extension/index.ts +1 -0
- package/src/ConsoleShared/src/components/modal/Modal.scss +3 -0
- package/src/ConsoleShared/src/components/modal/Modal.tsx +19 -0
- package/src/ConsoleShared/src/components/modal/index.ts +1 -0
- package/src/ConsoleShared/src/components/popper/Portal.tsx +23 -0
- package/src/ConsoleShared/src/components/popper/SimplePopper.tsx +90 -0
- package/src/ConsoleShared/src/components/popper/index.ts +2 -0
- package/src/ConsoleShared/src/components/spotlight/InteractiveSpotlight.tsx +58 -0
- package/src/ConsoleShared/src/components/spotlight/Spotlight.tsx +35 -0
- package/src/ConsoleShared/src/components/spotlight/StaticSpotlight.tsx +32 -0
- package/src/ConsoleShared/src/components/spotlight/index.ts +1 -0
- package/src/ConsoleShared/src/components/spotlight/spotlight.scss +63 -0
- package/src/ConsoleShared/src/components/status/GenericStatus.tsx +33 -0
- package/src/ConsoleShared/src/components/status/NotStartedIcon.tsx +27 -0
- package/src/ConsoleShared/src/components/status/PopoverStatus.tsx +42 -0
- package/src/ConsoleShared/src/components/status/Status.tsx +38 -0
- package/src/ConsoleShared/src/components/status/StatusIconAndText.tsx +42 -0
- package/src/ConsoleShared/src/components/status/icons.tsx +77 -0
- package/src/ConsoleShared/src/components/status/index.tsx +1 -0
- package/src/ConsoleShared/src/components/status/statuses.tsx +36 -0
- package/src/ConsoleShared/src/components/status/types.ts +7 -0
- package/src/ConsoleShared/src/components/utils/FallbackImg.tsx +20 -0
- package/src/ConsoleShared/src/components/utils/index.ts +1 -0
- package/src/ConsoleShared/src/constants/index.ts +1 -0
- package/src/ConsoleShared/src/constants/ui.ts +1 -0
- package/src/ConsoleShared/src/hooks/index.ts +6 -0
- package/src/ConsoleShared/src/hooks/scroll.ts +52 -0
- package/src/ConsoleShared/src/hooks/useBoundingClientRect.ts +18 -0
- package/src/ConsoleShared/src/hooks/useEventListener.ts +14 -0
- package/src/ConsoleShared/src/hooks/useForceRender.ts +6 -0
- package/src/ConsoleShared/src/hooks/useResizeObserver.ts +20 -0
- package/src/ConsoleShared/src/hooks/useScrollShadows.ts +45 -0
- package/src/ConsoleShared/src/index.ts +4 -0
- package/src/ConsoleShared/src/utils/index.ts +1 -0
- package/src/ConsoleShared/src/utils/useCombineRefs.ts +17 -0
- package/src/HelpTopicDrawer.tsx +124 -0
- package/src/HelpTopicPanelContent.tsx +152 -0
- package/src/QuickStartCatalogPage.tsx +190 -0
- package/src/QuickStartCloseModal.tsx +47 -0
- package/src/QuickStartController.tsx +113 -0
- package/src/QuickStartDrawer.scss +11 -0
- package/src/QuickStartDrawer.tsx +265 -0
- package/src/QuickStartMarkdownView.tsx +75 -0
- package/src/QuickStartPanelContent.scss +46 -0
- package/src/QuickStartPanelContent.tsx +153 -0
- package/src/__tests__/quick-start-utils.spec.tsx +16 -0
- package/src/catalog/Catalog/QuickStartCatalogHeader.tsx +18 -0
- package/src/catalog/Catalog/QuickStartCatalogSection.tsx +9 -0
- package/src/catalog/Catalog/QuickStartCatalogToolbar.tsx +12 -0
- package/src/catalog/Catalog/index.ts +3 -0
- package/src/catalog/QuickStartCatalog.scss +8 -0
- package/src/catalog/QuickStartCatalog.tsx +42 -0
- package/src/catalog/QuickStartTile.scss +11 -0
- package/src/catalog/QuickStartTile.tsx +105 -0
- package/src/catalog/QuickStartTileDescription.scss +29 -0
- package/src/catalog/QuickStartTileDescription.tsx +79 -0
- package/src/catalog/QuickStartTileFooter.tsx +101 -0
- package/src/catalog/QuickStartTileFooterExternal.tsx +40 -0
- package/src/catalog/QuickStartTileHeader.scss +12 -0
- package/src/catalog/QuickStartTileHeader.tsx +77 -0
- package/src/catalog/Toolbar/QuickStartCatalogFilter.scss +25 -0
- package/src/catalog/Toolbar/QuickStartCatalogFilter.tsx +34 -0
- package/src/catalog/Toolbar/QuickStartCatalogFilterItems.tsx +199 -0
- package/src/catalog/__tests__/QuickStartCatalog.spec.tsx +35 -0
- package/src/catalog/__tests__/QuickStartTile.spec.tsx +38 -0
- package/src/catalog/__tests__/QuickStartTileDescription.spec.tsx +44 -0
- package/src/catalog/index.ts +9 -0
- package/src/controller/QuickStartConclusion.tsx +63 -0
- package/src/controller/QuickStartContent.scss +12 -0
- package/src/controller/QuickStartContent.tsx +72 -0
- package/src/controller/QuickStartFooter.scss +13 -0
- package/src/controller/QuickStartFooter.tsx +128 -0
- package/src/controller/QuickStartIntroduction.scss +35 -0
- package/src/controller/QuickStartIntroduction.tsx +66 -0
- package/src/controller/QuickStartTaskHeader.scss +58 -0
- package/src/controller/QuickStartTaskHeader.tsx +116 -0
- package/src/controller/QuickStartTaskHeaderList.scss +17 -0
- package/src/controller/QuickStartTaskHeaderList.tsx +35 -0
- package/src/controller/QuickStartTaskReview.scss +30 -0
- package/src/controller/QuickStartTaskReview.tsx +81 -0
- package/src/controller/QuickStartTasks.scss +89 -0
- package/src/controller/QuickStartTasks.tsx +75 -0
- package/src/controller/__tests__/QuickStartConclusion.spec.tsx +95 -0
- package/src/controller/__tests__/QuickStartContent.spec.tsx +52 -0
- package/src/controller/__tests__/QuickStartFooter.spec.tsx +148 -0
- package/src/controller/__tests__/QuickStartTaskHeader.spec.tsx +56 -0
- package/src/controller/__tests__/QuickStartTaskReview.spec.tsx +45 -0
- package/src/controller/__tests__/QuickStartTasks.spec.tsx +81 -0
- package/src/data/mocks/json/explore-pipeline-quickstart.ts +66 -0
- package/src/data/mocks/json/explore-serverless-quickstart.ts +90 -0
- package/src/data/mocks/json/monitor-sampleapp-quickstart.ts +77 -0
- package/src/data/mocks/json/tour-icons.ts +3 -0
- package/src/data/mocks/yamls/add-healthchecks-quickstart.yaml +67 -0
- package/src/data/mocks/yamls/explore-pipeline-quickstart.yaml +57 -0
- package/src/data/mocks/yamls/explore-serverless-quickstart.yaml +83 -0
- package/src/data/mocks/yamls/install-associate-pipeline-quickstart.yaml +74 -0
- package/src/data/mocks/yamls/monitor-sampleapp-quickstart.yaml +66 -0
- package/src/data/mocks/yamls/sample-application-quickstart.yaml +97 -0
- package/src/data/mocks/yamls/serverless-application-quickstart.yaml +141 -0
- package/src/data/quick-start-test-data.ts +10 -0
- package/src/data/test-utils.ts +11 -0
- package/src/declaration.d.ts +2 -0
- package/src/index.ts +17 -0
- package/src/locales/en/quickstart.json +46 -0
- package/src/styles/_base.scss +54 -0
- package/src/styles/_dark-custom-override.scss +62 -0
- package/src/styles/legacy-bootstrap/README.md +21 -0
- package/src/styles/legacy-bootstrap/_code.scss +44 -0
- package/src/styles/legacy-bootstrap/_tables.scss +38 -0
- package/src/styles/legacy-bootstrap/_type.scss +90 -0
- package/src/styles/legacy-bootstrap/_variables.scss +48 -0
- package/src/styles/legacy-bootstrap.scss +5 -0
- package/src/styles/patternfly-global-entry.ts +1 -0
- package/src/styles/patternfly-global.scss +28 -0
- package/src/styles/patternfly-nested-entry.ts +1 -0
- package/src/styles/patternfly-nested.scss +18 -0
- package/src/styles/quickstarts-standalone-entry.ts +1 -0
- package/src/styles/quickstarts-standalone.scss +7 -0
- package/src/styles/style.scss +12 -0
- package/src/styles/vendor-entry.ts +1 -0
- package/src/styles/vendor.scss +7 -0
- package/src/utils/PluralResolver.ts +356 -0
- package/src/utils/asciidoc-procedure-parser.ts +132 -0
- package/src/utils/const.ts +10 -0
- package/src/utils/help-topic-context.tsx +74 -0
- package/src/utils/help-topic-types.ts +16 -0
- package/src/utils/quick-start-context.tsx +477 -0
- package/src/utils/quick-start-types.ts +72 -0
- package/src/utils/quick-start-utils.ts +92 -0
- package/src/utils/useLocalStorage.ts +38 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Tooltip } from '@patternfly/react-core';
|
|
3
|
+
import { QuickStartContext, QuickStartContextValues } from '@quickstarts/utils/quick-start-context';
|
|
4
|
+
import { useEventListener } from '../../hooks';
|
|
5
|
+
import { MARKDOWN_COPY_BUTTON_ID, MARKDOWN_SNIPPET_ID } from './const';
|
|
6
|
+
|
|
7
|
+
type CopyClipboardProps = {
|
|
8
|
+
element: HTMLElement;
|
|
9
|
+
rootSelector: string;
|
|
10
|
+
docContext: HTMLDocument;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const CopyClipboard: React.FC<CopyClipboardProps> = ({
|
|
14
|
+
element,
|
|
15
|
+
rootSelector,
|
|
16
|
+
docContext,
|
|
17
|
+
}) => {
|
|
18
|
+
const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
|
|
19
|
+
const [showSuccessContent, setShowSuccessContent] = React.useState<boolean>(false);
|
|
20
|
+
const textToCopy = React.useMemo(() => {
|
|
21
|
+
const copyTextId = element.getAttribute(MARKDOWN_COPY_BUTTON_ID);
|
|
22
|
+
return (docContext.querySelector(
|
|
23
|
+
`${rootSelector} [${MARKDOWN_SNIPPET_ID}="${copyTextId}"]`,
|
|
24
|
+
) as HTMLElement).innerText;
|
|
25
|
+
}, [element, docContext, rootSelector]);
|
|
26
|
+
|
|
27
|
+
useEventListener(
|
|
28
|
+
element,
|
|
29
|
+
'click',
|
|
30
|
+
React.useCallback(() => {
|
|
31
|
+
navigator.clipboard
|
|
32
|
+
.writeText(textToCopy)
|
|
33
|
+
.then(() => {
|
|
34
|
+
setShowSuccessContent(true);
|
|
35
|
+
})
|
|
36
|
+
.catch(() => {});
|
|
37
|
+
}, [textToCopy]),
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
useEventListener(
|
|
41
|
+
element,
|
|
42
|
+
'mouseleave',
|
|
43
|
+
React.useCallback(() => {
|
|
44
|
+
setShowSuccessContent(false);
|
|
45
|
+
}, []),
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
return showSuccessContent ? (
|
|
49
|
+
<Tooltip
|
|
50
|
+
key="after-copy"
|
|
51
|
+
isVisible
|
|
52
|
+
reference={() => element as HTMLElement}
|
|
53
|
+
content={getResource('Successfully copied to clipboard!')}
|
|
54
|
+
className="pfext-quick-start__base"
|
|
55
|
+
/>
|
|
56
|
+
) : (
|
|
57
|
+
<Tooltip
|
|
58
|
+
key="before-copy"
|
|
59
|
+
reference={() => element as HTMLElement}
|
|
60
|
+
content={getResource('Copy to clipboard')}
|
|
61
|
+
className="pfext-quick-start__base"
|
|
62
|
+
/>
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
type MarkdownCopyClipboardProps = {
|
|
67
|
+
docContext: HTMLDocument;
|
|
68
|
+
rootSelector: string;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const MarkdownCopyClipboard: React.FC<MarkdownCopyClipboardProps> = ({
|
|
72
|
+
docContext,
|
|
73
|
+
rootSelector,
|
|
74
|
+
}) => {
|
|
75
|
+
const elements = docContext.querySelectorAll(`${rootSelector} [${MARKDOWN_COPY_BUTTON_ID}]`);
|
|
76
|
+
return elements.length > 0 ? (
|
|
77
|
+
<>
|
|
78
|
+
{Array.from(elements).map((elm) => {
|
|
79
|
+
const attributeValue = elm.getAttribute(MARKDOWN_COPY_BUTTON_ID);
|
|
80
|
+
return (
|
|
81
|
+
<CopyClipboard
|
|
82
|
+
key={attributeValue}
|
|
83
|
+
element={elm as HTMLElement}
|
|
84
|
+
rootSelector={rootSelector}
|
|
85
|
+
docContext={docContext}
|
|
86
|
+
/>
|
|
87
|
+
);
|
|
88
|
+
})}
|
|
89
|
+
</>
|
|
90
|
+
) : null;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export default MarkdownCopyClipboard;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { shallow } from 'enzyme';
|
|
3
|
+
import MarkdownCopyClipboard, { CopyClipboard } from '../MarkdownCopyClipboard';
|
|
4
|
+
import { htmlDocumentForCopyClipboard } from './test-data';
|
|
5
|
+
|
|
6
|
+
describe('MarkdownCopyClipboard', () => {
|
|
7
|
+
beforeAll(() => {
|
|
8
|
+
document.body.innerHTML = htmlDocumentForCopyClipboard;
|
|
9
|
+
});
|
|
10
|
+
it('should render null if no element is found', () => {
|
|
11
|
+
const wrapper = shallow(
|
|
12
|
+
<MarkdownCopyClipboard docContext={document} rootSelector="#copy-markdown-3" />,
|
|
13
|
+
);
|
|
14
|
+
expect(wrapper.isEmptyRender()).toBe(true);
|
|
15
|
+
expect(wrapper.find(CopyClipboard).exists()).toBe(false);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should render null if no element is found', () => {
|
|
19
|
+
const wrapper = shallow(
|
|
20
|
+
<MarkdownCopyClipboard docContext={document} rootSelector="#copy-markdown-1" />,
|
|
21
|
+
);
|
|
22
|
+
expect(wrapper.isEmptyRender()).toBe(false);
|
|
23
|
+
expect(wrapper.find(CopyClipboard).exists()).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { MARKDOWN_COPY_BUTTON_ID, MARKDOWN_SNIPPET_ID, MARKDOWN_EXECUTE_BUTTON_ID } from '../const';
|
|
2
|
+
|
|
3
|
+
export const htmlDocumentForCopyClipboard = `<div id="copy-markdown-1"><div ${MARKDOWN_SNIPPET_ID}="1234">some test data for testing</div><button ${MARKDOWN_COPY_BUTTON_ID}="1234"</button><div ${MARKDOWN_SNIPPET_ID}="12354">some test data for testing</div><button ${MARKDOWN_COPY_BUTTON_ID}="12354"</button></div>`;
|
|
4
|
+
|
|
5
|
+
export const htmlDocumentForExecuteButton = `<div id="execute-markdown-1"><div ${MARKDOWN_SNIPPET_ID}="1234">some test data for testing</div><button ${MARKDOWN_EXECUTE_BUTTON_ID}="1234"</button><div ${MARKDOWN_SNIPPET_ID}="12354">some test data for testing</div><button ${MARKDOWN_EXECUTE_BUTTON_ID}="12354"</button></div>`;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { removeTemplateWhitespace } from './utils';
|
|
3
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
|
4
|
+
import { Alert } from '@patternfly/react-core';
|
|
5
|
+
import LightbulbIcon from '@patternfly/react-icons/dist/js/icons/lightbulb-icon';
|
|
6
|
+
import FireIcon from '@patternfly/react-icons/dist/js/icons/fire-icon';
|
|
7
|
+
import './showdown-extension.scss';
|
|
8
|
+
|
|
9
|
+
enum AdmonitionType {
|
|
10
|
+
TIP = 'TIP',
|
|
11
|
+
NOTE = 'NOTE',
|
|
12
|
+
IMPORTANT = 'IMPORTANT',
|
|
13
|
+
WARNING = 'WARNING',
|
|
14
|
+
CAUTION = 'CAUTION',
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const admonitionToAlertVariantMap = {
|
|
18
|
+
[AdmonitionType.NOTE]: { variant: 'info' },
|
|
19
|
+
[AdmonitionType.TIP]: { variant: 'default', customIcon: <LightbulbIcon /> },
|
|
20
|
+
[AdmonitionType.IMPORTANT]: { variant: 'danger' },
|
|
21
|
+
[AdmonitionType.CAUTION]: { variant: 'warning', customIcon: <FireIcon /> },
|
|
22
|
+
[AdmonitionType.WARNING]: { variant: 'warning' },
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const useAdmonitionShowdownExtension = () => {
|
|
26
|
+
// const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
|
|
27
|
+
return React.useMemo(
|
|
28
|
+
() => ({
|
|
29
|
+
type: 'lang',
|
|
30
|
+
regex: /\[(.+)]{{(admonition) ([\w-]+)}}/g,
|
|
31
|
+
replace: (
|
|
32
|
+
text: string,
|
|
33
|
+
content: string,
|
|
34
|
+
admonitionLabel: string,
|
|
35
|
+
admonitionType: string,
|
|
36
|
+
groupId: string,
|
|
37
|
+
): string => {
|
|
38
|
+
if (!content || !admonitionLabel || !admonitionType || !groupId) {
|
|
39
|
+
return text;
|
|
40
|
+
}
|
|
41
|
+
admonitionType = admonitionType.toUpperCase();
|
|
42
|
+
|
|
43
|
+
const { variant, customIcon } = admonitionToAlertVariantMap[admonitionType];
|
|
44
|
+
const style =
|
|
45
|
+
admonitionType === AdmonitionType.CAUTION ? { backgroundColor: '#ec7a0915' } : {};
|
|
46
|
+
|
|
47
|
+
const pfAlert = (
|
|
48
|
+
<Alert
|
|
49
|
+
variant={variant}
|
|
50
|
+
customIcon={customIcon && customIcon}
|
|
51
|
+
isInline
|
|
52
|
+
title={admonitionType}
|
|
53
|
+
className="pfext-markdown-admonition"
|
|
54
|
+
style={style}
|
|
55
|
+
>
|
|
56
|
+
{content}
|
|
57
|
+
</Alert>
|
|
58
|
+
);
|
|
59
|
+
return removeTemplateWhitespace(renderToStaticMarkup(pfAlert));
|
|
60
|
+
},
|
|
61
|
+
}),
|
|
62
|
+
[],
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export default useAdmonitionShowdownExtension;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { removeTemplateWhitespace } from './utils';
|
|
3
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
|
4
|
+
import { CodeBlock } from '@patternfly/react-core';
|
|
5
|
+
import './showdown-extension.scss';
|
|
6
|
+
|
|
7
|
+
const useCodeShowdownExtension = () => {
|
|
8
|
+
return React.useMemo(
|
|
9
|
+
() => ({
|
|
10
|
+
type: 'output',
|
|
11
|
+
regex: /<pre><code>(.*?)\n?<\/code><\/pre>/g,
|
|
12
|
+
replace: (text: string, content: string): string => {
|
|
13
|
+
if (!content) {
|
|
14
|
+
return text;
|
|
15
|
+
}
|
|
16
|
+
const pfCodeBlock = <CodeBlock>{content}</CodeBlock>;
|
|
17
|
+
|
|
18
|
+
return removeTemplateWhitespace(renderToStaticMarkup(pfCodeBlock));
|
|
19
|
+
},
|
|
20
|
+
}),
|
|
21
|
+
[],
|
|
22
|
+
);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default useCodeShowdownExtension;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as MarkdownCopyClipboard } from './MarkdownCopyClipboard';
|
|
2
|
+
export { default as useInlineCopyClipboardShowdownExtension } from './inline-clipboard-extension';
|
|
3
|
+
export { default as useMultilineCopyClipboardShowdownExtension } from './multiline-clipboard-extension';
|
|
4
|
+
export { default as useAdmonitionShowdownExtension } from './admonition-extension';
|
|
5
|
+
export { default as useCodeShowdownExtension } from './code-extension';
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { QuickStartContext, QuickStartContextValues } from '@quickstarts/utils/quick-start-context';
|
|
3
|
+
import { MARKDOWN_COPY_BUTTON_ID, MARKDOWN_SNIPPET_ID } from './const';
|
|
4
|
+
import { removeTemplateWhitespace } from './utils';
|
|
5
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
|
6
|
+
import CopyIcon from '@patternfly/react-icons/dist/js/icons/copy-icon';
|
|
7
|
+
import './showdown-extension.scss';
|
|
8
|
+
|
|
9
|
+
const useInlineCopyClipboardShowdownExtension = () => {
|
|
10
|
+
const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
|
|
11
|
+
return React.useMemo(
|
|
12
|
+
() => ({
|
|
13
|
+
type: 'lang',
|
|
14
|
+
regex: /```[\n]\s*((((?!```).)*?\n)+)\s*```{{copy}}/g,
|
|
15
|
+
replace: (
|
|
16
|
+
text: string,
|
|
17
|
+
group: string,
|
|
18
|
+
subGroup: string,
|
|
19
|
+
groupType: string,
|
|
20
|
+
groupId: string,
|
|
21
|
+
): string => {
|
|
22
|
+
if (!group || !subGroup || !groupType || !groupId) {
|
|
23
|
+
return text;
|
|
24
|
+
}
|
|
25
|
+
return removeTemplateWhitespace(
|
|
26
|
+
`<span class="pf-c-clipboard-copy pf-m-inline">
|
|
27
|
+
<span class="pf-c-clipboard-copy__text" ${MARKDOWN_SNIPPET_ID}="${groupType}">${group}</span>
|
|
28
|
+
<span class="pf-c-clipboard-copy__actions">
|
|
29
|
+
<span class="pf-c-clipboard-copy__actions-item">
|
|
30
|
+
<button class="pf-c-button pf-m-plain" aria-label="${getResource(
|
|
31
|
+
'Copy to clipboard',
|
|
32
|
+
)}" ${MARKDOWN_COPY_BUTTON_ID}="${groupType}">
|
|
33
|
+
${renderToStaticMarkup(<CopyIcon />)}
|
|
34
|
+
</button>
|
|
35
|
+
</span>
|
|
36
|
+
</span>
|
|
37
|
+
</span>`,
|
|
38
|
+
);
|
|
39
|
+
},
|
|
40
|
+
}),
|
|
41
|
+
[getResource],
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default useInlineCopyClipboardShowdownExtension;
|
package/src/ConsoleShared/src/components/markdown-extensions/multiline-clipboard-extension.tsx
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { QuickStartContext, QuickStartContextValues } from '@quickstarts/utils/quick-start-context';
|
|
3
|
+
import { MARKDOWN_COPY_BUTTON_ID, MARKDOWN_SNIPPET_ID } from './const';
|
|
4
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
|
5
|
+
import CopyIcon from '@patternfly/react-icons/dist/js/icons/copy-icon';
|
|
6
|
+
|
|
7
|
+
import './showdown-extension.scss';
|
|
8
|
+
|
|
9
|
+
const useMultilineCopyClipboardShowdownExtension = () => {
|
|
10
|
+
const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
|
|
11
|
+
return React.useMemo(
|
|
12
|
+
() => ({
|
|
13
|
+
type: 'lang',
|
|
14
|
+
regex: /```[\n]((.*?\n)+)```{{copy}}/g,
|
|
15
|
+
replace: (
|
|
16
|
+
text: string,
|
|
17
|
+
group: string,
|
|
18
|
+
subgroup: string,
|
|
19
|
+
groupType: string,
|
|
20
|
+
groupId: string,
|
|
21
|
+
): string => {
|
|
22
|
+
if (!group || !subgroup || !groupType || !groupId) {
|
|
23
|
+
return text;
|
|
24
|
+
}
|
|
25
|
+
return `<div class="pf-c-code-block">
|
|
26
|
+
<div class="pf-c-code-block__header">
|
|
27
|
+
<div class="pf-c-code-block__actions">
|
|
28
|
+
<div class="pf-c-code-block__actions-item">
|
|
29
|
+
<button class="pf-c-button pf-m-plain" type="button" aria-label="${getResource(
|
|
30
|
+
'Copy to clipboard',
|
|
31
|
+
)}" ${MARKDOWN_COPY_BUTTON_ID}="${groupType}">
|
|
32
|
+
${renderToStaticMarkup(<CopyIcon />)}
|
|
33
|
+
</button>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
<div class="pf-c-code-block__content">
|
|
38
|
+
<pre class="pf-c-code-block__pre pfext-code-block__pre">
|
|
39
|
+
<code class="pf-c-code-block__code"
|
|
40
|
+
${MARKDOWN_SNIPPET_ID}="${groupType}">${group}</code>
|
|
41
|
+
</pre>
|
|
42
|
+
</div>
|
|
43
|
+
</div>`;
|
|
44
|
+
},
|
|
45
|
+
}),
|
|
46
|
+
[getResource],
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export default useMultilineCopyClipboardShowdownExtension;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
.pfext-markdown-view {
|
|
2
|
+
.pfext-code-block__pre {
|
|
3
|
+
/* override the styles applied by showdown while parsing <pre /> */
|
|
4
|
+
display: flex;
|
|
5
|
+
border: none;
|
|
6
|
+
border-radius: none;
|
|
7
|
+
background-color: transparent;
|
|
8
|
+
margin: 0;
|
|
9
|
+
padding: 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.pfext-markdown-execute-snippet {
|
|
13
|
+
|
|
14
|
+
&__button {
|
|
15
|
+
& > i.fa-check {
|
|
16
|
+
display: none;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
& > i.fa-play {
|
|
20
|
+
display: inline;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
&[data-executed] {
|
|
24
|
+
& > i.fa-check {
|
|
25
|
+
display: inline;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
& > i.fa-play {
|
|
29
|
+
display: none;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.pfext-markdown-admonition {
|
|
36
|
+
&.pf-c-alert {
|
|
37
|
+
// add margins to match design
|
|
38
|
+
margin: var(--pf-global--spacer--md) 0;
|
|
39
|
+
.pf-c-alert__title {
|
|
40
|
+
// remove margins from markdown css
|
|
41
|
+
margin-top: 0;
|
|
42
|
+
margin-bottom: 0;
|
|
43
|
+
// lift PF style specificity to override markdown css
|
|
44
|
+
font-weight: var(--pf-c-alert__title--FontWeight);
|
|
45
|
+
font-family: inherit;
|
|
46
|
+
line-height: inherit;
|
|
47
|
+
color: var(--pf-c-alert__title--Color);
|
|
48
|
+
word-break: break-word;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
package/src/ConsoleShared/src/components/markdown-highlight-extension/MarkdownHighlightExtension.tsx
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Spotlight } from '../spotlight';
|
|
3
|
+
|
|
4
|
+
type MarkdownHighlightExtensionProps = {
|
|
5
|
+
docContext: HTMLDocument;
|
|
6
|
+
rootSelector: string;
|
|
7
|
+
};
|
|
8
|
+
const MarkdownHighlightExtension: React.FC<MarkdownHighlightExtensionProps> = ({
|
|
9
|
+
docContext,
|
|
10
|
+
rootSelector,
|
|
11
|
+
}) => {
|
|
12
|
+
const [selector, setSelector] = React.useState<string>(null);
|
|
13
|
+
React.useEffect(() => {
|
|
14
|
+
const elements = docContext.querySelectorAll(`${rootSelector} [data-highlight]`);
|
|
15
|
+
let timeoutId: NodeJS.Timeout;
|
|
16
|
+
function startHighlight(e) {
|
|
17
|
+
const highlightId = e.target.getAttribute('data-highlight');
|
|
18
|
+
if (!highlightId) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
setSelector(null);
|
|
22
|
+
timeoutId = setTimeout(() => {
|
|
23
|
+
setSelector(`[data-quickstart-id="${highlightId}"]`);
|
|
24
|
+
}, 0);
|
|
25
|
+
}
|
|
26
|
+
elements && elements.forEach((elm) => elm.addEventListener('click', startHighlight));
|
|
27
|
+
return () => {
|
|
28
|
+
clearTimeout(timeoutId);
|
|
29
|
+
elements && elements.forEach((elm) => elm.removeEventListener('click', startHighlight));
|
|
30
|
+
};
|
|
31
|
+
}, [docContext, rootSelector]);
|
|
32
|
+
React.useEffect(() => {
|
|
33
|
+
const elements = docContext.querySelectorAll(`${rootSelector} [class^=data-highlight__]`);
|
|
34
|
+
let timeoutId: NodeJS.Timeout;
|
|
35
|
+
function startHighlight(e) {
|
|
36
|
+
e.preventDefault();
|
|
37
|
+
const classes = e.target.getAttribute('class').split(' ');
|
|
38
|
+
let highlightId;
|
|
39
|
+
for (let i = 0; i < classes.length; i++) {
|
|
40
|
+
if (classes[0].startsWith('data-highlight__')) {
|
|
41
|
+
highlightId = classes[0].split('__')[1];
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (!highlightId) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
setSelector(null);
|
|
49
|
+
timeoutId = setTimeout(() => {
|
|
50
|
+
setSelector(`[data-quickstart-id="${highlightId}"]`);
|
|
51
|
+
}, 0);
|
|
52
|
+
}
|
|
53
|
+
elements && elements.forEach((elm) => elm.addEventListener('click', startHighlight));
|
|
54
|
+
return () => {
|
|
55
|
+
clearTimeout(timeoutId);
|
|
56
|
+
elements && elements.forEach((elm) => elm.removeEventListener('click', startHighlight));
|
|
57
|
+
};
|
|
58
|
+
}, [docContext, rootSelector]);
|
|
59
|
+
if (!selector) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
return <Spotlight selector={selector} interactive />;
|
|
63
|
+
};
|
|
64
|
+
export default MarkdownHighlightExtension;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const LINK_LABEL = '[\\d\\w\\s-()$!]+';
|
|
2
|
+
export const HIGHLIGHT_ACTIONS = ['highlight'];
|
|
3
|
+
export const SELECTOR_ID = `[\\w-]+`;
|
|
4
|
+
|
|
5
|
+
// [linkLabel]{{action id}}
|
|
6
|
+
export const HIGHLIGHT_REGEXP = new RegExp(
|
|
7
|
+
`\\[(${LINK_LABEL})]{{(${HIGHLIGHT_ACTIONS.join('|')}) (${SELECTOR_ID})}}`,
|
|
8
|
+
'g',
|
|
9
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as MarkdownHighlightExtension } from './MarkdownHighlightExtension';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import './Modal.scss';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { Modal as PfModal, ModalProps as PfModalProps } from '@patternfly/react-core';
|
|
4
|
+
import { css } from '@patternfly/react-styles';
|
|
5
|
+
|
|
6
|
+
type ModalProps = {
|
|
7
|
+
isFullScreen?: boolean;
|
|
8
|
+
ref?: React.LegacyRef<PfModal>;
|
|
9
|
+
} & PfModalProps;
|
|
10
|
+
|
|
11
|
+
const Modal: React.FC<ModalProps> = ({ isFullScreen = false, className, ...props }) => (
|
|
12
|
+
<PfModal
|
|
13
|
+
{...props}
|
|
14
|
+
className={css('pfext-modal', className)}
|
|
15
|
+
appendTo={() => (isFullScreen ? document.body : document.querySelector('#modal-container'))}
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
export default Modal;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Modal } from './Modal';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as ReactDOM from 'react-dom';
|
|
3
|
+
|
|
4
|
+
type GetContainer = Element | null | undefined | (() => Element);
|
|
5
|
+
|
|
6
|
+
type PortalProps = {
|
|
7
|
+
container?: GetContainer;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const getContainer = (container: GetContainer): Element | null | undefined =>
|
|
11
|
+
typeof container === 'function' ? container() : container;
|
|
12
|
+
|
|
13
|
+
const Portal: React.FC<PortalProps> = ({ children, container }) => {
|
|
14
|
+
const [containerNode, setContainerNode] = React.useState<Element>();
|
|
15
|
+
|
|
16
|
+
React.useLayoutEffect(() => {
|
|
17
|
+
setContainerNode(getContainer(container) || document.body);
|
|
18
|
+
}, [container]);
|
|
19
|
+
|
|
20
|
+
return containerNode ? ReactDOM.createPortal(children, containerNode) : null;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export default Portal;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import Portal from './Portal';
|
|
3
|
+
|
|
4
|
+
const SimplePopper: React.FC = ({ children }) => {
|
|
5
|
+
const openProp = true;
|
|
6
|
+
const nodeRef = React.useRef<Element>();
|
|
7
|
+
const popperRef = React.useRef(null);
|
|
8
|
+
const [isOpen, setOpenState] = React.useState(openProp);
|
|
9
|
+
|
|
10
|
+
const setOpen = React.useCallback((newOpen: boolean) => {
|
|
11
|
+
setOpenState(newOpen);
|
|
12
|
+
}, []);
|
|
13
|
+
|
|
14
|
+
React.useEffect(() => {
|
|
15
|
+
setOpen(openProp);
|
|
16
|
+
}, [openProp, setOpen]);
|
|
17
|
+
|
|
18
|
+
const onKeyDown = React.useCallback(
|
|
19
|
+
(e: KeyboardEvent) => {
|
|
20
|
+
if (e.keyCode === 27) {
|
|
21
|
+
setOpen(false);
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
[setOpen],
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
const onClickOutside = React.useCallback(
|
|
28
|
+
(e: MouseEvent) => {
|
|
29
|
+
if (!nodeRef.current || (e.target instanceof Node && !nodeRef.current.contains(e.target))) {
|
|
30
|
+
setOpen(false);
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
[setOpen],
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const destroy = React.useCallback(() => {
|
|
37
|
+
if (popperRef.current) {
|
|
38
|
+
popperRef.current.destroy();
|
|
39
|
+
document.removeEventListener('keydown', onKeyDown, true);
|
|
40
|
+
document.removeEventListener('mousedown', onClickOutside, true);
|
|
41
|
+
document.removeEventListener('touchstart', onClickOutside, true);
|
|
42
|
+
}
|
|
43
|
+
}, [onClickOutside, onKeyDown]);
|
|
44
|
+
|
|
45
|
+
const initialize = React.useCallback(() => {
|
|
46
|
+
if (!nodeRef.current || !isOpen) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
destroy();
|
|
51
|
+
}, [isOpen, destroy]);
|
|
52
|
+
|
|
53
|
+
const nodeRefCallback = React.useCallback(
|
|
54
|
+
(node) => {
|
|
55
|
+
nodeRef.current = node;
|
|
56
|
+
initialize();
|
|
57
|
+
},
|
|
58
|
+
[initialize],
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
React.useEffect(() => {
|
|
62
|
+
initialize();
|
|
63
|
+
}, [initialize]);
|
|
64
|
+
|
|
65
|
+
React.useEffect(() => {
|
|
66
|
+
return () => {
|
|
67
|
+
destroy();
|
|
68
|
+
};
|
|
69
|
+
}, [destroy]);
|
|
70
|
+
|
|
71
|
+
React.useEffect(() => {
|
|
72
|
+
if (!isOpen) {
|
|
73
|
+
destroy();
|
|
74
|
+
}
|
|
75
|
+
}, [destroy, isOpen]);
|
|
76
|
+
|
|
77
|
+
return isOpen ? (
|
|
78
|
+
<Portal>
|
|
79
|
+
<div
|
|
80
|
+
ref={nodeRefCallback}
|
|
81
|
+
style={{ zIndex: 9999, position: 'absolute', top: 0, left: 0 }}
|
|
82
|
+
className="pfext-quick-start__base"
|
|
83
|
+
>
|
|
84
|
+
{children}
|
|
85
|
+
</div>
|
|
86
|
+
</Portal>
|
|
87
|
+
) : null;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export default SimplePopper;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import './spotlight.scss';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { Portal, SimplePopper } from '../popper';
|
|
4
|
+
|
|
5
|
+
type InteractiveSpotlightProps = {
|
|
6
|
+
element: Element;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const isInViewport = (elementToCheck: Element) => {
|
|
10
|
+
const rect = elementToCheck.getBoundingClientRect();
|
|
11
|
+
return (
|
|
12
|
+
rect.top >= 0 &&
|
|
13
|
+
rect.left >= 0 &&
|
|
14
|
+
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
|
|
15
|
+
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
|
|
16
|
+
);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const InteractiveSpotlight: React.FC<InteractiveSpotlightProps> = ({ element }) => {
|
|
20
|
+
const { top, bottom, left, right, height, width } = element.getBoundingClientRect();
|
|
21
|
+
const style: React.CSSProperties = {
|
|
22
|
+
height,
|
|
23
|
+
width,
|
|
24
|
+
top,
|
|
25
|
+
left,
|
|
26
|
+
bottom,
|
|
27
|
+
right,
|
|
28
|
+
};
|
|
29
|
+
const [clicked, setClicked] = React.useState(false);
|
|
30
|
+
|
|
31
|
+
React.useEffect(() => {
|
|
32
|
+
if (!clicked) {
|
|
33
|
+
if (!isInViewport(element)) {
|
|
34
|
+
element.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });
|
|
35
|
+
}
|
|
36
|
+
const handleClick = () => setClicked(true);
|
|
37
|
+
document.addEventListener('click', handleClick);
|
|
38
|
+
return () => {
|
|
39
|
+
document.removeEventListener('click', handleClick);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return () => {};
|
|
43
|
+
}, [element, clicked]);
|
|
44
|
+
|
|
45
|
+
if (clicked) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<Portal>
|
|
51
|
+
<SimplePopper>
|
|
52
|
+
<div className="pfext-spotlight pfext-spotlight__element-highlight-animate" style={style} />
|
|
53
|
+
</SimplePopper>
|
|
54
|
+
</Portal>
|
|
55
|
+
);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export default InteractiveSpotlight;
|