@patternfly/quickstarts 2.2.3 → 2.2.4
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/dist/HelpTopicDrawer.d.ts +8 -2
- package/dist/QuickStartDrawer.d.ts +21 -2
- package/dist/index.es.js.map +1 -1
- 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.map +1 -1
- 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,35 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import InteractiveSpotlight from './InteractiveSpotlight';
|
|
3
|
+
import StaticSpotlight from './StaticSpotlight';
|
|
4
|
+
|
|
5
|
+
type SpotlightProps = {
|
|
6
|
+
selector: string;
|
|
7
|
+
interactive?: boolean;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const Spotlight: React.FC<SpotlightProps> = ({ selector, interactive }) => {
|
|
11
|
+
// if target element is a hidden one return null
|
|
12
|
+
const element = React.useMemo(() => {
|
|
13
|
+
const highlightElement = document.querySelector(selector);
|
|
14
|
+
let hiddenElement = highlightElement;
|
|
15
|
+
while (hiddenElement) {
|
|
16
|
+
const ariaHidden = hiddenElement.getAttribute('aria-hidden');
|
|
17
|
+
if (ariaHidden === 'true') {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
hiddenElement = hiddenElement.parentElement;
|
|
21
|
+
}
|
|
22
|
+
return highlightElement;
|
|
23
|
+
}, [selector]);
|
|
24
|
+
|
|
25
|
+
if (!element) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
return interactive ? (
|
|
29
|
+
<InteractiveSpotlight element={element} />
|
|
30
|
+
) : (
|
|
31
|
+
<StaticSpotlight element={element} />
|
|
32
|
+
);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default Spotlight;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import './spotlight.scss';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { useBoundingClientRect } from '../../hooks';
|
|
4
|
+
import Portal from '../popper/Portal';
|
|
5
|
+
|
|
6
|
+
type StaticSpotlightProps = {
|
|
7
|
+
element: Element;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const StaticSpotlight: React.FC<StaticSpotlightProps> = ({ element }) => {
|
|
11
|
+
const clientRect = useBoundingClientRect(element as HTMLElement);
|
|
12
|
+
const style: React.CSSProperties = clientRect
|
|
13
|
+
? {
|
|
14
|
+
top: clientRect.top,
|
|
15
|
+
left: clientRect.left,
|
|
16
|
+
height: clientRect.height,
|
|
17
|
+
width: clientRect.width,
|
|
18
|
+
}
|
|
19
|
+
: {};
|
|
20
|
+
return clientRect ? (
|
|
21
|
+
<Portal>
|
|
22
|
+
<div className="pf-c-backdrop pfext-spotlight__with-backdrop">
|
|
23
|
+
<div
|
|
24
|
+
className="pfext-spotlight pfext-spotlight__element-highlight-noanimate"
|
|
25
|
+
style={style}
|
|
26
|
+
/>
|
|
27
|
+
</div>
|
|
28
|
+
</Portal>
|
|
29
|
+
) : null;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default StaticSpotlight;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Spotlight } from './Spotlight';
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
@keyframes pfext-spotlight-expand {
|
|
2
|
+
0% {
|
|
3
|
+
outline-offset: -4px;
|
|
4
|
+
outline-width: 4px;
|
|
5
|
+
opacity: 1;
|
|
6
|
+
}
|
|
7
|
+
100% {
|
|
8
|
+
outline-offset: 21px;
|
|
9
|
+
outline-width: 12px;
|
|
10
|
+
opacity: 0;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@keyframes pfext-spotlight-fade-in {
|
|
15
|
+
0% {
|
|
16
|
+
opacity: 0;
|
|
17
|
+
}
|
|
18
|
+
100% {
|
|
19
|
+
opacity: 1;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@keyframes pfext-spotlight-fade-out {
|
|
24
|
+
0% {
|
|
25
|
+
opacity: 1;
|
|
26
|
+
}
|
|
27
|
+
100% {
|
|
28
|
+
opacity: 0;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.pfext-spotlight {
|
|
33
|
+
pointer-events: none;
|
|
34
|
+
position: absolute;
|
|
35
|
+
&__with-backdrop {
|
|
36
|
+
mix-blend-mode: hard-light;
|
|
37
|
+
}
|
|
38
|
+
&__element-highlight-noanimate {
|
|
39
|
+
border: var(--pf-global--BorderWidth--xl) solid var(--pf-global--palette--blue-200);
|
|
40
|
+
background-color: var(--pf-global--palette--black-500);
|
|
41
|
+
z-index: 9999;
|
|
42
|
+
}
|
|
43
|
+
&__element-highlight-animate {
|
|
44
|
+
pointer-events: none;
|
|
45
|
+
position: absolute;
|
|
46
|
+
box-shadow: inset 0px 0px 0px 4px var(--pf-global--palette--blue-200);
|
|
47
|
+
opacity: 0;
|
|
48
|
+
animation: 0.4s pfext-spotlight-fade-in 0s ease-in-out, 5s pfext-spotlight-fade-out 12.8s ease-in-out;
|
|
49
|
+
animation-fill-mode: forwards;
|
|
50
|
+
&::after {
|
|
51
|
+
content: '';
|
|
52
|
+
position: absolute;
|
|
53
|
+
left: 0;
|
|
54
|
+
right: 0;
|
|
55
|
+
top: 0;
|
|
56
|
+
bottom: 0;
|
|
57
|
+
animation: 1.2s pfext-spotlight-expand 1.6s ease-out;
|
|
58
|
+
animation-fill-mode: forwards;
|
|
59
|
+
outline: 4px solid var(--pf-global--palette--blue-200);
|
|
60
|
+
outline-offset: -4px;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import PopoverStatus from './PopoverStatus';
|
|
3
|
+
import StatusIconAndText from './StatusIconAndText';
|
|
4
|
+
import { StatusComponentProps } from './types';
|
|
5
|
+
|
|
6
|
+
const GenericStatus: React.FC<GenericStatusProps> = (props) => {
|
|
7
|
+
const { Icon, children, popoverTitle, title, noTooltip, iconOnly, ...restProps } = props;
|
|
8
|
+
const renderIcon = iconOnly && !noTooltip ? <Icon title={title} /> : <Icon />;
|
|
9
|
+
const statusBody = (
|
|
10
|
+
<StatusIconAndText
|
|
11
|
+
{...restProps}
|
|
12
|
+
noTooltip={noTooltip}
|
|
13
|
+
title={title}
|
|
14
|
+
iconOnly={iconOnly}
|
|
15
|
+
icon={renderIcon}
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
18
|
+
return React.Children.toArray(children).length ? (
|
|
19
|
+
<PopoverStatus title={popoverTitle || title} {...restProps} statusBody={statusBody}>
|
|
20
|
+
{children}
|
|
21
|
+
</PopoverStatus>
|
|
22
|
+
) : (
|
|
23
|
+
statusBody
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
type GenericStatusProps = StatusComponentProps & {
|
|
28
|
+
Icon: React.ComponentType<{ title?: string }>;
|
|
29
|
+
popoverTitle?: string;
|
|
30
|
+
noTooltip?: boolean;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export default GenericStatus;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// TODO: Pull from Patternfly when they add it
|
|
2
|
+
// https://github.com/patternfly/patternfly-design/issues/921#issuecomment-726183814
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
|
|
5
|
+
export default (props) => (
|
|
6
|
+
<svg
|
|
7
|
+
width="12px"
|
|
8
|
+
height="13px"
|
|
9
|
+
{...props}
|
|
10
|
+
viewBox="0 0 12 13"
|
|
11
|
+
version="1.1"
|
|
12
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
13
|
+
xmlnsXlink="http://www.w3.org/1999/xlink"
|
|
14
|
+
>
|
|
15
|
+
<g id="icon_notstarted" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
|
|
16
|
+
<path
|
|
17
|
+
d="M5.99998569,12.3124969 C7.04685832,12.3124969 8.01560589,12.0507786 8.90622877,11.5273425 C9.79685164,11.0039064 10.5038813,10.2968767 11.0273175,9.4062538 C11.5507536,8.51563092 11.8124718,7.54688335 11.8124718,6.50001073 C11.8124718,5.45313811 11.5507536,4.48439053 11.0273175,3.59376766 C10.5038813,2.70314478 9.79685164,1.9961151 8.90622877,1.47267896 C8.01560589,0.949242832 7.04685832,0.687524587 5.99998569,0.687524587 C4.95311307,0.687524587 3.9843655,0.949242832 3.09374262,1.47267896 C2.20311975,1.9961151 1.49609006,2.70314478 0.972653931,3.59376766 C0.449217798,4.48439053 0.187499553,5.45313811 0.187499553,6.50001073 C0.187499553,7.54688335 0.449217798,8.51563092 0.972653931,9.4062538 C1.49609006,10.2968767 2.20311975,11.0039064 3.09374262,11.5273425 C3.9843655,12.0507786 4.95311307,12.3124969 5.99998569,12.3124969 Z M5.99998569,11.1874996 C5.15623771,11.1874996 4.37498969,10.9765626 3.65624128,10.5546886 C2.93749288,10.1328146 2.36718186,9.56250355 1.94530786,8.84375514 C1.52343387,8.12500674 1.31249687,7.34375872 1.31249687,6.50001073 C1.31249687,5.65626274 1.52343387,4.87501472 1.94530786,4.15626632 C2.36718186,3.43751791 2.93749288,2.86720689 3.65624128,2.4453329 C4.37498969,2.0234589 5.15623771,1.8125219 5.99998569,1.8125219 C6.84373368,1.8125219 7.6249817,2.0234589 8.34373011,2.4453329 C9.06247851,2.86720689 9.63278953,3.43751791 10.0546635,4.15626632 C10.4765375,4.87501472 10.6874745,5.65626274 10.6874745,6.50001073 C10.6874745,7.34375872 10.4765375,8.12500674 10.0546635,8.84375514 C9.63278953,9.56250355 9.06247851,10.1328146 8.34373011,10.5546886 C7.6249817,10.9765626 6.84373368,11.1874996 5.99998569,11.1874996 Z"
|
|
18
|
+
id="Circle"
|
|
19
|
+
fill="#6A6E73"
|
|
20
|
+
fillRule="nonzero"
|
|
21
|
+
/>
|
|
22
|
+
<circle id="Oval" fill="#6A6E73" cx="3" cy="6.5" r="1" />
|
|
23
|
+
<circle id="Oval-Copy-2" fill="#6A6E73" cx="6" cy="6.5" r="1" />
|
|
24
|
+
<circle id="Oval-Copy-3" fill="#6A6E73" cx="9" cy="6.5" r="1" />
|
|
25
|
+
</g>
|
|
26
|
+
</svg>
|
|
27
|
+
);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Button, Popover, PopoverPosition } from '@patternfly/react-core';
|
|
3
|
+
|
|
4
|
+
const PopoverStatus: React.FC<PopoverStatusProps> = ({
|
|
5
|
+
hideHeader,
|
|
6
|
+
children,
|
|
7
|
+
isVisible = null,
|
|
8
|
+
shouldClose = null,
|
|
9
|
+
statusBody,
|
|
10
|
+
title,
|
|
11
|
+
onHide,
|
|
12
|
+
onShow,
|
|
13
|
+
}) => {
|
|
14
|
+
return (
|
|
15
|
+
<Popover
|
|
16
|
+
position={PopoverPosition.right}
|
|
17
|
+
headerContent={hideHeader ? null : title}
|
|
18
|
+
bodyContent={children}
|
|
19
|
+
aria-label={title}
|
|
20
|
+
onHide={onHide}
|
|
21
|
+
onShow={onShow}
|
|
22
|
+
isVisible={isVisible}
|
|
23
|
+
shouldClose={shouldClose}
|
|
24
|
+
>
|
|
25
|
+
<Button variant="link" isInline>
|
|
26
|
+
{statusBody}
|
|
27
|
+
</Button>
|
|
28
|
+
</Popover>
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
type PopoverStatusProps = {
|
|
33
|
+
statusBody: React.ReactNode;
|
|
34
|
+
onHide?: () => void;
|
|
35
|
+
onShow?: () => void;
|
|
36
|
+
title?: string;
|
|
37
|
+
hideHeader?: boolean;
|
|
38
|
+
isVisible?: boolean;
|
|
39
|
+
shouldClose?: (hideFunction: any) => void;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export default PopoverStatus;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import SyncAltIcon from '@patternfly/react-icons/dist/js/icons/sync-alt-icon';
|
|
3
|
+
import { DASH } from '../../constants';
|
|
4
|
+
import { SuccessStatus } from './statuses';
|
|
5
|
+
import StatusIconAndText from './StatusIconAndText';
|
|
6
|
+
import { StatusComponentProps } from './types';
|
|
7
|
+
|
|
8
|
+
export const Status: React.FC<StatusProps> = ({
|
|
9
|
+
status,
|
|
10
|
+
title,
|
|
11
|
+
iconOnly,
|
|
12
|
+
noTooltip,
|
|
13
|
+
className,
|
|
14
|
+
}) => {
|
|
15
|
+
const statusProps = { title: title || status, iconOnly, noTooltip, className };
|
|
16
|
+
switch (status) {
|
|
17
|
+
case 'In Progress':
|
|
18
|
+
return <StatusIconAndText {...statusProps} icon={<SyncAltIcon />} />;
|
|
19
|
+
|
|
20
|
+
case 'Complete':
|
|
21
|
+
return <SuccessStatus {...statusProps} />;
|
|
22
|
+
|
|
23
|
+
default:
|
|
24
|
+
return <>{status || DASH}</>;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const StatusIcon: React.FC<StatusIconProps> = ({ status }) => (
|
|
29
|
+
<Status status={status} iconOnly />
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
type StatusIconProps = {
|
|
33
|
+
status: string;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
type StatusProps = StatusComponentProps & {
|
|
37
|
+
status: string;
|
|
38
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { css } from '@patternfly/react-styles';
|
|
3
|
+
import { CamelCaseWrap } from '@console/internal/components/utils';
|
|
4
|
+
import { DASH } from '../../constants';
|
|
5
|
+
import { StatusComponentProps } from './types';
|
|
6
|
+
|
|
7
|
+
type StatusIconAndTextProps = StatusComponentProps & {
|
|
8
|
+
icon?: React.ReactElement;
|
|
9
|
+
spin?: boolean;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const StatusIconAndText: React.FC<StatusIconAndTextProps> = ({
|
|
13
|
+
icon,
|
|
14
|
+
title,
|
|
15
|
+
spin,
|
|
16
|
+
iconOnly,
|
|
17
|
+
noTooltip,
|
|
18
|
+
className,
|
|
19
|
+
}) => {
|
|
20
|
+
if (!title) {
|
|
21
|
+
return <>{DASH}</>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<span
|
|
26
|
+
className={css('pfext-icon-and-text', className)}
|
|
27
|
+
title={iconOnly && !noTooltip ? title : undefined}
|
|
28
|
+
>
|
|
29
|
+
{icon &&
|
|
30
|
+
React.cloneElement(icon, {
|
|
31
|
+
className: css(
|
|
32
|
+
spin && 'fa-spin',
|
|
33
|
+
icon.props.className,
|
|
34
|
+
!iconOnly && 'pfext-icon-and-text__icon pfext-icon-flex-child',
|
|
35
|
+
),
|
|
36
|
+
})}
|
|
37
|
+
{!iconOnly && <CamelCaseWrap value={title} dataTest="status-text" />}
|
|
38
|
+
</span>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export default StatusIconAndText;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import CheckCircleIcon from '@patternfly/react-icons/dist/js/icons/check-circle-icon';
|
|
3
|
+
import ExclamationCircleIcon from '@patternfly/react-icons/dist/js/icons/exclamation-circle-icon';
|
|
4
|
+
// import ExclamationTriangleIcon from '@patternfly/react-icons/dist/js/icons/exclamation-triangle-icon';
|
|
5
|
+
import InfoCircleIcon from '@patternfly/react-icons/dist/js/icons/info-circle-icon';
|
|
6
|
+
import { global_danger_color_100 as dangerColor } from '@patternfly/react-tokens/dist/js/global_danger_color_100';
|
|
7
|
+
// import { global_default_color_200 as blueDefaultColor } from '@patternfly/react-tokens/dist/js/global_default_color_200';
|
|
8
|
+
// import { global_disabled_color_100 as disabledColor } from '@patternfly/react-tokens/dist/js/global_disabled_color_100';
|
|
9
|
+
import { global_palette_blue_300 as blueInfoColor } from '@patternfly/react-tokens/dist/js/global_palette_blue_300';
|
|
10
|
+
import { global_palette_green_500 as okColor } from '@patternfly/react-tokens/dist/js/global_palette_green_500';
|
|
11
|
+
// import { global_warning_color_100 as warningColor } from '@patternfly/react-tokens/dist/js/global_warning_color_100';
|
|
12
|
+
|
|
13
|
+
export const GreenCheckCircleIcon: React.FC<ColoredIconProps> = ({ className, title, size }) => (
|
|
14
|
+
<CheckCircleIcon
|
|
15
|
+
data-test="success-icon"
|
|
16
|
+
size={size}
|
|
17
|
+
color={okColor.value}
|
|
18
|
+
className={className}
|
|
19
|
+
title={title}
|
|
20
|
+
/>
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
export const RedExclamationCircleIcon: React.FC<ColoredIconProps> = ({
|
|
24
|
+
className,
|
|
25
|
+
title,
|
|
26
|
+
size,
|
|
27
|
+
}) => (
|
|
28
|
+
<ExclamationCircleIcon
|
|
29
|
+
size={size}
|
|
30
|
+
color={dangerColor.value}
|
|
31
|
+
className={className}
|
|
32
|
+
title={title}
|
|
33
|
+
/>
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
// export const YellowExclamationTriangleIcon: React.FC<ColoredIconProps> = ({
|
|
37
|
+
// className,
|
|
38
|
+
// title,
|
|
39
|
+
// size,
|
|
40
|
+
// }) => (
|
|
41
|
+
// <ExclamationTriangleIcon
|
|
42
|
+
// size={size}
|
|
43
|
+
// color={warningColor.value}
|
|
44
|
+
// className={className}
|
|
45
|
+
// title={title}
|
|
46
|
+
// />
|
|
47
|
+
// );
|
|
48
|
+
|
|
49
|
+
export const BlueInfoCircleIcon: React.FC<ColoredIconProps> = ({ className, title }) => (
|
|
50
|
+
<InfoCircleIcon color={blueInfoColor.value} className={className} title={title} />
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
// export const GrayUnknownIcon: React.FC<ColoredIconProps> = ({ className, title }) => (
|
|
54
|
+
// <UnknownIcon color={disabledColor.value} className={className} title={title} />
|
|
55
|
+
// );
|
|
56
|
+
|
|
57
|
+
// export const BlueSyncIcon: React.FC<ColoredIconProps> = ({ className, title }) => (
|
|
58
|
+
// <SyncAltIcon color={blueInfoColor.value} className={className} title={title} />
|
|
59
|
+
// );
|
|
60
|
+
|
|
61
|
+
// export const RedResourcesFullIcon: React.FC<ColoredIconProps> = ({ className, title }) => (
|
|
62
|
+
// <ResourcesFullIcon color={dangerColor.value} className={className} title={title} />
|
|
63
|
+
// );
|
|
64
|
+
|
|
65
|
+
// export const YellowResourcesAlmostFullIcon: React.FC<ColoredIconProps> = ({ className, title }) => (
|
|
66
|
+
// <ResourcesAlmostFullIcon color={warningColor.value} className={className} title={title} />
|
|
67
|
+
// );
|
|
68
|
+
|
|
69
|
+
// export const BlueArrowCircleUpIcon: React.FC<ColoredIconProps> = ({ className, title }) => (
|
|
70
|
+
// <ArrowCircleUpIcon color={blueDefaultColor.value} className={className} title={title} />
|
|
71
|
+
// );
|
|
72
|
+
|
|
73
|
+
export type ColoredIconProps = {
|
|
74
|
+
className?: string;
|
|
75
|
+
title?: string;
|
|
76
|
+
size?: 'sm' | 'md' | 'lg' | 'xl';
|
|
77
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Status';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
// import HourglassHalfIcon from '@patternfly/react-icons/dist/js/icons/hourglass-half-icon';
|
|
3
|
+
// import InProgressIcon from '@patternfly/react-icons/dist/js/icons/in-progress-icon';
|
|
4
|
+
import GenericStatus from './GenericStatus';
|
|
5
|
+
import { BlueInfoCircleIcon, GreenCheckCircleIcon, RedExclamationCircleIcon } from './icons';
|
|
6
|
+
import { StatusComponentProps } from './types';
|
|
7
|
+
|
|
8
|
+
export const ErrorStatus: React.FC<StatusComponentProps> = (props) => (
|
|
9
|
+
<GenericStatus {...props} Icon={RedExclamationCircleIcon} title={props.title || 'Error'} />
|
|
10
|
+
);
|
|
11
|
+
ErrorStatus.displayName = 'ErrorStatus';
|
|
12
|
+
|
|
13
|
+
export const InfoStatus: React.FC<StatusComponentProps> = (props) => (
|
|
14
|
+
<GenericStatus {...props} Icon={BlueInfoCircleIcon} title={props.title || 'Information'} />
|
|
15
|
+
);
|
|
16
|
+
InfoStatus.displayName = 'InfoStatus';
|
|
17
|
+
|
|
18
|
+
// export const PendingStatus: React.FC<StatusComponentProps> = (props) => (
|
|
19
|
+
// <GenericStatus {...props} Icon={HourglassHalfIcon} title={props.title || 'Pending'} />
|
|
20
|
+
// );
|
|
21
|
+
// PendingStatus.displayName = 'PendingStatus';
|
|
22
|
+
|
|
23
|
+
// export const ProgressStatus: React.FC<StatusComponentProps> = (props) => (
|
|
24
|
+
// <GenericStatus {...props} Icon={InProgressIcon} title={props.title || 'In progress'} />
|
|
25
|
+
// );
|
|
26
|
+
// ProgressStatus.displayName = 'ProgressStatus';
|
|
27
|
+
|
|
28
|
+
export const SuccessStatus: React.FC<StatusComponentProps> = (props) => (
|
|
29
|
+
<GenericStatus {...props} Icon={GreenCheckCircleIcon} title={props.title || 'Healthy'} />
|
|
30
|
+
);
|
|
31
|
+
SuccessStatus.displayName = 'SuccessStatus';
|
|
32
|
+
|
|
33
|
+
// export const WarningStatus: React.FC<StatusComponentProps> = (props) => (
|
|
34
|
+
// <GenericStatus {...props} Icon={YellowExclamationTriangleIcon} title={props.title || 'Warning'} />
|
|
35
|
+
// );
|
|
36
|
+
// WarningStatus.displayName = 'WarningStatus';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
type FallbackImgProps = {
|
|
4
|
+
src: string;
|
|
5
|
+
alt?: string;
|
|
6
|
+
className?: string;
|
|
7
|
+
fallback?: React.ReactNode;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const FallbackImg: React.FC<FallbackImgProps> = ({ src, alt, className, fallback }) => {
|
|
11
|
+
const [isSrcValid, setIsSrcValid] = React.useState<boolean>(true);
|
|
12
|
+
|
|
13
|
+
if (src && isSrcValid) {
|
|
14
|
+
return <img className={className} src={src} alt={alt} onError={() => setIsSrcValid(false)} />;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return <>{fallback}</>;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export default FallbackImg;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as FallbackImg } from './FallbackImg';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ui';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const DASH = '-';
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
export enum ScrollDirection {
|
|
4
|
+
scrollingUp = 'scrolling-up',
|
|
5
|
+
scrollingDown = 'scrolling-down',
|
|
6
|
+
scrolledToBottom = 'scrolled-to-bottom',
|
|
7
|
+
scrolledToTop = 'scrolled-to-top',
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const getScrollDirection = (
|
|
11
|
+
prevScrollTop: number,
|
|
12
|
+
currentScrollTop: number,
|
|
13
|
+
scrollHeight: number,
|
|
14
|
+
clientHeight: number,
|
|
15
|
+
) => {
|
|
16
|
+
let direction;
|
|
17
|
+
if (scrollHeight - currentScrollTop === clientHeight) {
|
|
18
|
+
direction = ScrollDirection.scrolledToBottom;
|
|
19
|
+
} else if (currentScrollTop === 0) {
|
|
20
|
+
direction = ScrollDirection.scrolledToTop;
|
|
21
|
+
} else if (prevScrollTop > currentScrollTop) {
|
|
22
|
+
direction = ScrollDirection.scrollingUp;
|
|
23
|
+
} else if (prevScrollTop < currentScrollTop) {
|
|
24
|
+
direction = ScrollDirection.scrollingDown;
|
|
25
|
+
}
|
|
26
|
+
return direction;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const useScrollDirection = (): [ScrollDirection, (event) => void] => {
|
|
30
|
+
const scrollPosition = React.useRef<number>(null);
|
|
31
|
+
const [scrollDirection, setScrollDirection] = React.useState<ScrollDirection>(null);
|
|
32
|
+
const handleScroll = React.useCallback(
|
|
33
|
+
(event) => {
|
|
34
|
+
const { scrollHeight, scrollTop, clientHeight } = event.target;
|
|
35
|
+
if (scrollPosition.current !== null) {
|
|
36
|
+
const direction = getScrollDirection(
|
|
37
|
+
scrollPosition.current,
|
|
38
|
+
scrollTop,
|
|
39
|
+
scrollHeight,
|
|
40
|
+
clientHeight,
|
|
41
|
+
);
|
|
42
|
+
if (direction && direction !== scrollDirection) {
|
|
43
|
+
setScrollDirection(direction);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
scrollPosition.current = scrollTop;
|
|
47
|
+
},
|
|
48
|
+
[scrollDirection],
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
return [scrollDirection, handleScroll];
|
|
52
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useResizeObserver } from './useResizeObserver';
|
|
3
|
+
|
|
4
|
+
type BoundingClientRect = ClientRect | null;
|
|
5
|
+
|
|
6
|
+
export const useBoundingClientRect = (targetElement: HTMLElement | null): BoundingClientRect => {
|
|
7
|
+
const [clientRect, setClientRect] = React.useState<BoundingClientRect>(() =>
|
|
8
|
+
targetElement ? targetElement.getBoundingClientRect() : null,
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
const observerCallback = React.useCallback(() => {
|
|
12
|
+
setClientRect(targetElement ? targetElement.getBoundingClientRect() : null);
|
|
13
|
+
}, [targetElement]);
|
|
14
|
+
|
|
15
|
+
useResizeObserver(observerCallback);
|
|
16
|
+
|
|
17
|
+
return clientRect;
|
|
18
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
export const useEventListener = (
|
|
4
|
+
target: EventTarget,
|
|
5
|
+
event: keyof WindowEventMap,
|
|
6
|
+
callback: EventListener,
|
|
7
|
+
) => {
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
target.addEventListener(event, callback);
|
|
10
|
+
return () => {
|
|
11
|
+
target.removeEventListener(event, callback);
|
|
12
|
+
};
|
|
13
|
+
}, [target, event, callback]);
|
|
14
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
// TODO: Remove the no-check
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
|
|
5
|
+
export const useResizeObserver = (
|
|
6
|
+
callback: ResizeObserverCallback,
|
|
7
|
+
targetElement?: HTMLElement | null,
|
|
8
|
+
observerOptions: ResizeObserverObserveOptions = undefined,
|
|
9
|
+
): void => {
|
|
10
|
+
const element = React.useMemo(() => targetElement ?? document.querySelector('body'), [
|
|
11
|
+
targetElement,
|
|
12
|
+
]);
|
|
13
|
+
React.useEffect(() => {
|
|
14
|
+
const observer = new ResizeObserver(callback);
|
|
15
|
+
observer.observe(element, observerOptions);
|
|
16
|
+
return () => {
|
|
17
|
+
observer.disconnect();
|
|
18
|
+
};
|
|
19
|
+
}, [callback, observerOptions, element]);
|
|
20
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useResizeObserver } from './useResizeObserver';
|
|
3
|
+
|
|
4
|
+
export enum Shadows {
|
|
5
|
+
none = 'none',
|
|
6
|
+
both = 'both',
|
|
7
|
+
top = 'top',
|
|
8
|
+
bottom = 'bottom',
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const useScrollShadows = (node: HTMLElement): Shadows => {
|
|
12
|
+
const [shadows, setShadows] = React.useState(Shadows.none);
|
|
13
|
+
const computeShadows = React.useCallback(() => {
|
|
14
|
+
if (node) {
|
|
15
|
+
const { scrollTop, clientHeight, scrollHeight } = node;
|
|
16
|
+
const top = scrollTop !== 0;
|
|
17
|
+
const bottom = scrollTop + clientHeight < scrollHeight;
|
|
18
|
+
if (top && bottom) {
|
|
19
|
+
setShadows(Shadows.both);
|
|
20
|
+
} else if (top) {
|
|
21
|
+
setShadows(Shadows.top);
|
|
22
|
+
} else if (bottom) {
|
|
23
|
+
setShadows(Shadows.bottom);
|
|
24
|
+
} else {
|
|
25
|
+
setShadows(Shadows.none);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}, [node]);
|
|
29
|
+
// recompute when the scroll container changes in size
|
|
30
|
+
useResizeObserver(computeShadows, node);
|
|
31
|
+
React.useEffect(() => {
|
|
32
|
+
if (node) {
|
|
33
|
+
// compute initial shadows
|
|
34
|
+
computeShadows();
|
|
35
|
+
// listen for scroll events
|
|
36
|
+
node.addEventListener('scroll', computeShadows);
|
|
37
|
+
}
|
|
38
|
+
return () => {
|
|
39
|
+
if (node) {
|
|
40
|
+
node.removeEventListener('scroll', computeShadows);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}, [node, computeShadows]);
|
|
44
|
+
return shadows;
|
|
45
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './useCombineRefs';
|