@patternfly/quickstarts 2.2.1 → 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.
Files changed (203) hide show
  1. package/README.md +20 -20
  2. package/dist/ConsoleShared/src/components/markdown-extensions/code-extension.d.ts +7 -0
  3. package/dist/ConsoleShared/src/components/markdown-extensions/index.d.ts +1 -0
  4. package/dist/HelpTopicDrawer.d.ts +8 -2
  5. package/dist/QuickStartDrawer.d.ts +21 -2
  6. package/dist/index.d.ts +1 -0
  7. package/dist/index.es.js +127 -21
  8. package/dist/index.es.js.map +1 -1
  9. package/dist/index.js +126 -19
  10. package/dist/index.js.map +1 -1
  11. package/dist/patternfly-docs/quick-starts/design-guidelines/design-guidelines.md +105 -0
  12. package/dist/patternfly-docs/quick-starts/design-guidelines/img/card-elements copy.png +0 -0
  13. package/dist/patternfly-docs/quick-starts/design-guidelines/img/card-elements.png +0 -0
  14. package/dist/patternfly-docs/quick-starts/design-guidelines/img/catalog-elements.png +0 -0
  15. package/dist/patternfly-docs/quick-starts/design-guidelines/img/check-your-work.png +0 -0
  16. package/dist/patternfly-docs/quick-starts/design-guidelines/img/introduction-screen.png +0 -0
  17. package/dist/patternfly-docs/quick-starts/design-guidelines/img/mixed-catalog.png +0 -0
  18. package/dist/patternfly-docs/quick-starts/design-guidelines/img/prerequisites.png +0 -0
  19. package/dist/patternfly-docs/quick-starts/design-guidelines/img/qs-context.png +0 -0
  20. package/dist/patternfly-docs/quick-starts/design-guidelines/img/side-panel-elements.png +0 -0
  21. package/dist/patternfly-docs/quick-starts/design-guidelines/img/side-panel-resized.png +0 -0
  22. package/dist/patternfly-docs/quick-starts/design-guidelines/img/side-panel.png +0 -0
  23. package/dist/patternfly-docs/quick-starts/design-guidelines/img/task-no.png +0 -0
  24. package/dist/patternfly-docs/quick-starts/design-guidelines/img/task-yes.png +0 -0
  25. package/dist/patternfly-docs/quick-starts/design-guidelines/img/task.png +0 -0
  26. package/dist/patternfly-docs/quick-starts/examples/Basic.jsx +73 -0
  27. package/dist/patternfly-docs/quick-starts/examples/HelpTopic.jsx +53 -0
  28. package/dist/patternfly-docs/quick-starts/examples/about.md +77 -0
  29. package/dist/patternfly-docs/quick-starts/examples/basic.md +27 -0
  30. package/dist/patternfly-docs/quick-starts/examples/example-data/example-help-topics.js +173 -0
  31. package/dist/patternfly-docs/quick-starts/examples/example-data/example-quickstarts.js +215 -0
  32. package/dist/patternfly-docs/quick-starts/examples/example-data/index.js +15 -0
  33. package/dist/patternfly-docs/quick-starts/examples/help-topics.md +25 -0
  34. package/dist/patternfly-docs/quick-starts/examples/img/catalog.png +0 -0
  35. package/dist/patternfly-docs/quick-starts/examples/img/help-topic.png +0 -0
  36. package/dist/patternfly-docs/quick-starts/examples/img/side-panel.png +0 -0
  37. package/dist/patternfly-nested.css +11 -1
  38. package/dist/quickstarts-base.css +49 -11
  39. package/dist/quickstarts-full.es.js +451 -305
  40. package/dist/quickstarts-full.es.js.map +1 -1
  41. package/dist/quickstarts-standalone.css +5 -15
  42. package/dist/quickstarts-standalone.min.css +1 -1
  43. package/dist/quickstarts.css +49 -11
  44. package/dist/quickstarts.min.css +1 -1
  45. package/dist/utils/asciidoc-procedure-parser.d.ts +12 -0
  46. package/dist/utils/help-topic-types.d.ts +7 -1
  47. package/package.json +11 -4
  48. package/src/ConsoleInternal/components/_icon-and-text.scss +14 -0
  49. package/src/ConsoleInternal/components/_markdown-view.scss +19 -0
  50. package/src/ConsoleInternal/components/catalog/_catalog.scss +390 -0
  51. package/src/ConsoleInternal/components/markdown-view.tsx +305 -0
  52. package/src/ConsoleInternal/components/utils/_status-box.scss +58 -0
  53. package/src/ConsoleInternal/components/utils/camel-case-wrap.tsx +33 -0
  54. package/src/ConsoleInternal/components/utils/index.tsx +3 -0
  55. package/src/ConsoleInternal/components/utils/router.ts +47 -0
  56. package/src/ConsoleInternal/components/utils/status-box.tsx +94 -0
  57. package/src/ConsoleInternal/module/k8s/types.ts +53 -0
  58. package/src/ConsoleShared/index.ts +1 -0
  59. package/src/ConsoleShared/src/components/index.ts +7 -0
  60. package/src/ConsoleShared/src/components/layout/PageLayout.scss +29 -0
  61. package/src/ConsoleShared/src/components/markdown-extensions/MarkdownCopyClipboard.tsx +93 -0
  62. package/src/ConsoleShared/src/components/markdown-extensions/__tests__/MarkdownCopyClipboard.spec.tsx +25 -0
  63. package/src/ConsoleShared/src/components/markdown-extensions/__tests__/test-data.ts +5 -0
  64. package/src/ConsoleShared/src/components/markdown-extensions/admonition-extension.tsx +66 -0
  65. package/src/ConsoleShared/src/components/markdown-extensions/code-extension.tsx +25 -0
  66. package/src/ConsoleShared/src/components/markdown-extensions/const.ts +3 -0
  67. package/src/ConsoleShared/src/components/markdown-extensions/index.ts +5 -0
  68. package/src/ConsoleShared/src/components/markdown-extensions/inline-clipboard-extension.tsx +45 -0
  69. package/src/ConsoleShared/src/components/markdown-extensions/multiline-clipboard-extension.tsx +50 -0
  70. package/src/ConsoleShared/src/components/markdown-extensions/showdown-extension.scss +52 -0
  71. package/src/ConsoleShared/src/components/markdown-extensions/utils.ts +3 -0
  72. package/src/ConsoleShared/src/components/markdown-highlight-extension/MarkdownHighlightExtension.tsx +64 -0
  73. package/src/ConsoleShared/src/components/markdown-highlight-extension/highlight-consts.ts +9 -0
  74. package/src/ConsoleShared/src/components/markdown-highlight-extension/index.ts +1 -0
  75. package/src/ConsoleShared/src/components/modal/Modal.scss +3 -0
  76. package/src/ConsoleShared/src/components/modal/Modal.tsx +19 -0
  77. package/src/ConsoleShared/src/components/modal/index.ts +1 -0
  78. package/src/ConsoleShared/src/components/popper/Portal.tsx +23 -0
  79. package/src/ConsoleShared/src/components/popper/SimplePopper.tsx +90 -0
  80. package/src/ConsoleShared/src/components/popper/index.ts +2 -0
  81. package/src/ConsoleShared/src/components/spotlight/InteractiveSpotlight.tsx +58 -0
  82. package/src/ConsoleShared/src/components/spotlight/Spotlight.tsx +35 -0
  83. package/src/ConsoleShared/src/components/spotlight/StaticSpotlight.tsx +32 -0
  84. package/src/ConsoleShared/src/components/spotlight/index.ts +1 -0
  85. package/src/ConsoleShared/src/components/spotlight/spotlight.scss +63 -0
  86. package/src/ConsoleShared/src/components/status/GenericStatus.tsx +33 -0
  87. package/src/ConsoleShared/src/components/status/NotStartedIcon.tsx +27 -0
  88. package/src/ConsoleShared/src/components/status/PopoverStatus.tsx +42 -0
  89. package/src/ConsoleShared/src/components/status/Status.tsx +38 -0
  90. package/src/ConsoleShared/src/components/status/StatusIconAndText.tsx +42 -0
  91. package/src/ConsoleShared/src/components/status/icons.tsx +77 -0
  92. package/src/ConsoleShared/src/components/status/index.tsx +1 -0
  93. package/src/ConsoleShared/src/components/status/statuses.tsx +36 -0
  94. package/src/ConsoleShared/src/components/status/types.ts +7 -0
  95. package/src/ConsoleShared/src/components/utils/FallbackImg.tsx +20 -0
  96. package/src/ConsoleShared/src/components/utils/index.ts +1 -0
  97. package/src/ConsoleShared/src/constants/index.ts +1 -0
  98. package/src/ConsoleShared/src/constants/ui.ts +1 -0
  99. package/src/ConsoleShared/src/hooks/index.ts +6 -0
  100. package/src/ConsoleShared/src/hooks/scroll.ts +52 -0
  101. package/src/ConsoleShared/src/hooks/useBoundingClientRect.ts +18 -0
  102. package/src/ConsoleShared/src/hooks/useEventListener.ts +14 -0
  103. package/src/ConsoleShared/src/hooks/useForceRender.ts +6 -0
  104. package/src/ConsoleShared/src/hooks/useResizeObserver.ts +20 -0
  105. package/src/ConsoleShared/src/hooks/useScrollShadows.ts +45 -0
  106. package/src/ConsoleShared/src/index.ts +4 -0
  107. package/src/ConsoleShared/src/utils/index.ts +1 -0
  108. package/src/ConsoleShared/src/utils/useCombineRefs.ts +17 -0
  109. package/src/HelpTopicDrawer.tsx +124 -0
  110. package/src/HelpTopicPanelContent.tsx +152 -0
  111. package/src/QuickStartCatalogPage.tsx +190 -0
  112. package/src/QuickStartCloseModal.tsx +47 -0
  113. package/src/QuickStartController.tsx +113 -0
  114. package/src/QuickStartDrawer.scss +11 -0
  115. package/src/QuickStartDrawer.tsx +265 -0
  116. package/src/QuickStartMarkdownView.tsx +75 -0
  117. package/src/QuickStartPanelContent.scss +46 -0
  118. package/src/QuickStartPanelContent.tsx +153 -0
  119. package/src/__tests__/quick-start-utils.spec.tsx +16 -0
  120. package/src/catalog/Catalog/QuickStartCatalogHeader.tsx +18 -0
  121. package/src/catalog/Catalog/QuickStartCatalogSection.tsx +9 -0
  122. package/src/catalog/Catalog/QuickStartCatalogToolbar.tsx +12 -0
  123. package/src/catalog/Catalog/index.ts +3 -0
  124. package/src/catalog/QuickStartCatalog.scss +8 -0
  125. package/src/catalog/QuickStartCatalog.tsx +42 -0
  126. package/src/catalog/QuickStartTile.scss +11 -0
  127. package/src/catalog/QuickStartTile.tsx +105 -0
  128. package/src/catalog/QuickStartTileDescription.scss +29 -0
  129. package/src/catalog/QuickStartTileDescription.tsx +79 -0
  130. package/src/catalog/QuickStartTileFooter.tsx +101 -0
  131. package/src/catalog/QuickStartTileFooterExternal.tsx +40 -0
  132. package/src/catalog/QuickStartTileHeader.scss +12 -0
  133. package/src/catalog/QuickStartTileHeader.tsx +77 -0
  134. package/src/catalog/Toolbar/QuickStartCatalogFilter.scss +25 -0
  135. package/src/catalog/Toolbar/QuickStartCatalogFilter.tsx +34 -0
  136. package/src/catalog/Toolbar/QuickStartCatalogFilterItems.tsx +199 -0
  137. package/src/catalog/__tests__/QuickStartCatalog.spec.tsx +35 -0
  138. package/src/catalog/__tests__/QuickStartTile.spec.tsx +38 -0
  139. package/src/catalog/__tests__/QuickStartTileDescription.spec.tsx +44 -0
  140. package/src/catalog/index.ts +9 -0
  141. package/src/controller/QuickStartConclusion.tsx +63 -0
  142. package/src/controller/QuickStartContent.scss +12 -0
  143. package/src/controller/QuickStartContent.tsx +72 -0
  144. package/src/controller/QuickStartFooter.scss +13 -0
  145. package/src/controller/QuickStartFooter.tsx +128 -0
  146. package/src/controller/QuickStartIntroduction.scss +35 -0
  147. package/src/controller/QuickStartIntroduction.tsx +66 -0
  148. package/src/controller/QuickStartTaskHeader.scss +58 -0
  149. package/src/controller/QuickStartTaskHeader.tsx +116 -0
  150. package/src/controller/QuickStartTaskHeaderList.scss +17 -0
  151. package/src/controller/QuickStartTaskHeaderList.tsx +35 -0
  152. package/src/controller/QuickStartTaskReview.scss +30 -0
  153. package/src/controller/QuickStartTaskReview.tsx +81 -0
  154. package/src/controller/QuickStartTasks.scss +89 -0
  155. package/src/controller/QuickStartTasks.tsx +75 -0
  156. package/src/controller/__tests__/QuickStartConclusion.spec.tsx +95 -0
  157. package/src/controller/__tests__/QuickStartContent.spec.tsx +52 -0
  158. package/src/controller/__tests__/QuickStartFooter.spec.tsx +148 -0
  159. package/src/controller/__tests__/QuickStartTaskHeader.spec.tsx +56 -0
  160. package/src/controller/__tests__/QuickStartTaskReview.spec.tsx +45 -0
  161. package/src/controller/__tests__/QuickStartTasks.spec.tsx +81 -0
  162. package/src/data/mocks/json/explore-pipeline-quickstart.ts +66 -0
  163. package/src/data/mocks/json/explore-serverless-quickstart.ts +90 -0
  164. package/src/data/mocks/json/monitor-sampleapp-quickstart.ts +77 -0
  165. package/src/data/mocks/json/tour-icons.ts +3 -0
  166. package/src/data/mocks/yamls/add-healthchecks-quickstart.yaml +67 -0
  167. package/src/data/mocks/yamls/explore-pipeline-quickstart.yaml +57 -0
  168. package/src/data/mocks/yamls/explore-serverless-quickstart.yaml +83 -0
  169. package/src/data/mocks/yamls/install-associate-pipeline-quickstart.yaml +74 -0
  170. package/src/data/mocks/yamls/monitor-sampleapp-quickstart.yaml +66 -0
  171. package/src/data/mocks/yamls/sample-application-quickstart.yaml +97 -0
  172. package/src/data/mocks/yamls/serverless-application-quickstart.yaml +141 -0
  173. package/src/data/quick-start-test-data.ts +10 -0
  174. package/src/data/test-utils.ts +11 -0
  175. package/src/declaration.d.ts +2 -0
  176. package/src/index.ts +17 -0
  177. package/src/locales/en/quickstart.json +46 -0
  178. package/src/styles/_base.scss +54 -0
  179. package/src/styles/_dark-custom-override.scss +62 -0
  180. package/src/styles/legacy-bootstrap/README.md +21 -0
  181. package/src/styles/legacy-bootstrap/_code.scss +44 -0
  182. package/src/styles/legacy-bootstrap/_tables.scss +38 -0
  183. package/src/styles/legacy-bootstrap/_type.scss +90 -0
  184. package/src/styles/legacy-bootstrap/_variables.scss +48 -0
  185. package/src/styles/legacy-bootstrap.scss +5 -0
  186. package/src/styles/patternfly-global-entry.ts +1 -0
  187. package/src/styles/patternfly-global.scss +28 -0
  188. package/src/styles/patternfly-nested-entry.ts +1 -0
  189. package/src/styles/patternfly-nested.scss +18 -0
  190. package/src/styles/quickstarts-standalone-entry.ts +1 -0
  191. package/src/styles/quickstarts-standalone.scss +7 -0
  192. package/src/styles/style.scss +12 -0
  193. package/src/styles/vendor-entry.ts +1 -0
  194. package/src/styles/vendor.scss +7 -0
  195. package/src/utils/PluralResolver.ts +356 -0
  196. package/src/utils/asciidoc-procedure-parser.ts +132 -0
  197. package/src/utils/const.ts +10 -0
  198. package/src/utils/help-topic-context.tsx +74 -0
  199. package/src/utils/help-topic-types.ts +16 -0
  200. package/src/utils/quick-start-context.tsx +477 -0
  201. package/src/utils/quick-start-types.ts +72 -0
  202. package/src/utils/quick-start-utils.ts +92 -0
  203. package/src/utils/useLocalStorage.ts +38 -0
@@ -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,7 @@
1
+ export type StatusComponentProps = {
2
+ title?: string;
3
+ iconOnly?: boolean;
4
+ noTooltip?: boolean;
5
+ className?: string;
6
+ popoverTitle?: string;
7
+ };
@@ -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,6 @@
1
+ export * from './scroll';
2
+ export * from './useResizeObserver';
3
+ export * from './useScrollShadows';
4
+ export * from './useBoundingClientRect';
5
+ export * from './useForceRender';
6
+ export * from './useEventListener';
@@ -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,6 @@
1
+ import * as React from 'react';
2
+
3
+ /**
4
+ * React hook that forces component render.
5
+ */
6
+ export const useForceRender = () => React.useReducer((s: boolean) => !s, false)[1] as VoidFunction;
@@ -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,4 @@
1
+ export * from './components';
2
+ export * from './hooks';
3
+ export * from './utils';
4
+ export * from './constants';
@@ -0,0 +1 @@
1
+ export * from './useCombineRefs';
@@ -0,0 +1,17 @@
1
+ import * as React from 'react';
2
+
3
+ export const useCombineRefs = <RefType extends any>(...refs: (React.Ref<RefType> | undefined)[]) =>
4
+ React.useCallback(
5
+ (element: RefType | null): void =>
6
+ refs.forEach((ref) => {
7
+ if (ref) {
8
+ if (typeof ref === 'function') {
9
+ ref(element);
10
+ } else {
11
+ (ref as React.MutableRefObject<any>).current = element;
12
+ }
13
+ }
14
+ }),
15
+ // eslint-disable-next-line react-hooks/exhaustive-deps
16
+ refs,
17
+ );
@@ -0,0 +1,124 @@
1
+ import './QuickStartDrawer.scss';
2
+ import * as React from 'react';
3
+ import { Drawer, DrawerContent, DrawerContentBody } from '@patternfly/react-core';
4
+ import HelpTopicPanelContent from './HelpTopicPanelContent';
5
+ import {
6
+ HelpTopicContext,
7
+ HelpTopicContextValues,
8
+ useValuesForHelpTopicContext,
9
+ } from './utils/help-topic-context';
10
+ import { QuickStartContextValues } from './utils/quick-start-context';
11
+ import { HelpTopic } from './utils/help-topic-types';
12
+
13
+ export interface HelpTopicContainerProps extends React.HTMLProps<HTMLDivElement> {
14
+ /** array of HelpTopics */
15
+ helpTopics: HelpTopic[];
16
+ /** text resources object
17
+ * Add custom strings: https://github.com/patternfly/patternfly-quickstarts/tree/main/packages/module#localization
18
+ */
19
+ resourceBundle?: any;
20
+ /** language of the current resource bundle */
21
+ language?: string;
22
+ /** if true, will show a loading spinner on the catalog page (default false) */
23
+ loading?: boolean;
24
+ /**
25
+ * Additional markdown extensions and renderers to use
26
+ * Example usage: https://github.com/patternfly/patternfly-quickstarts/tree/main/packages/module#markdown-extensions
27
+ */
28
+ markdown?: {
29
+ extensions?: any[];
30
+ renderExtension?: (docContext: HTMLDocument, rootSelector: string) => React.ReactNode;
31
+ };
32
+ /** additional quick start context props */
33
+ contextProps?: QuickStartContextValues;
34
+ }
35
+
36
+ export const HelpTopicContainer: React.FC<HelpTopicContainerProps> = ({
37
+ helpTopics,
38
+ children,
39
+ resourceBundle,
40
+ language,
41
+ loading = false,
42
+ markdown,
43
+ contextProps,
44
+ ...props
45
+ }: HelpTopicContainerProps) => {
46
+ const valuesForHelpTopicContext: HelpTopicContextValues = useValuesForHelpTopicContext({
47
+ helpTopics,
48
+ language,
49
+ resourceBundle: {
50
+ ...resourceBundle,
51
+ // Start: "Let's go!",
52
+ // Continue: 'Resume',
53
+ // Restart: 'Start over',
54
+ },
55
+ loading,
56
+ markdown,
57
+ ...contextProps,
58
+ });
59
+
60
+ React.useEffect(() => {
61
+ if (loading !== valuesForHelpTopicContext.loading) {
62
+ valuesForHelpTopicContext.setLoading(loading);
63
+ }
64
+ }, [loading, valuesForHelpTopicContext]);
65
+
66
+ React.useEffect(() => {
67
+ if (
68
+ helpTopics &&
69
+ JSON.stringify(helpTopics) !== JSON.stringify(valuesForHelpTopicContext.helpTopics)
70
+ ) {
71
+ valuesForHelpTopicContext.setHelpTopics(helpTopics);
72
+ }
73
+ }, [helpTopics, valuesForHelpTopicContext]);
74
+
75
+ const drawerProps = {
76
+ //TODO add extras here?
77
+ ...props,
78
+ };
79
+
80
+ return (
81
+ <HelpTopicContext.Provider value={valuesForHelpTopicContext}>
82
+ <HelpTopicDrawer {...drawerProps}>{children}</HelpTopicDrawer>
83
+ </HelpTopicContext.Provider>
84
+ );
85
+ };
86
+
87
+ export interface HelpTopicDrawerProps extends React.HTMLProps<HTMLDivElement> {
88
+ helpTopics?: HelpTopic[];
89
+ children?: React.ReactNode;
90
+ }
91
+
92
+ export const HelpTopicDrawer: React.FC<HelpTopicDrawerProps> = ({ children, ...props }) => {
93
+ const { activeHelpTopic, filteredHelpTopics, setActiveHelpTopicByName } = React.useContext<
94
+ HelpTopicContextValues
95
+ >(HelpTopicContext);
96
+
97
+ const onClose = () => {
98
+ setActiveHelpTopicByName('');
99
+ };
100
+
101
+ const panelContent = (
102
+ <HelpTopicPanelContent
103
+ activeHelpTopic={activeHelpTopic}
104
+ filteredHelpTopics={filteredHelpTopics}
105
+ onClose={onClose}
106
+ />
107
+ );
108
+
109
+ return (
110
+ <>
111
+ <Drawer isExpanded={!!activeHelpTopic} isInline {...props}>
112
+ {children ? (
113
+ <DrawerContent panelContent={panelContent}>
114
+ <DrawerContentBody className="pfext-quick-start-drawer__body">
115
+ {children}
116
+ </DrawerContentBody>
117
+ </DrawerContent>
118
+ ) : (
119
+ <div className="pf-c-drawer__main">{panelContent}</div>
120
+ )}
121
+ </Drawer>
122
+ </>
123
+ );
124
+ };
@@ -0,0 +1,152 @@
1
+ import * as React from 'react';
2
+ import {
3
+ Button,
4
+ Divider,
5
+ DrawerActions,
6
+ DrawerCloseButton,
7
+ DrawerHead,
8
+ DrawerPanelBody,
9
+ DrawerPanelContent,
10
+ OptionsMenu,
11
+ OptionsMenuItem,
12
+ OptionsMenuToggle,
13
+ Stack,
14
+ StackItem,
15
+ Title,
16
+ } from '@patternfly/react-core';
17
+
18
+ import QuickStartMarkdownView from './QuickStartMarkdownView';
19
+ import { HelpTopic } from './utils/help-topic-types';
20
+ import BarsIcon from '@patternfly/react-icons/dist/js/icons/bars-icon';
21
+ import ExternalLinkAltIcon from '@patternfly/react-icons/dist/js/icons/external-link-alt-icon';
22
+
23
+ import './QuickStartPanelContent.scss';
24
+ import { HelpTopicContext, HelpTopicContextValues } from './utils/help-topic-context';
25
+
26
+ type HelpTopicPanelContentProps = {
27
+ activeHelpTopic: HelpTopic;
28
+ filteredHelpTopics?: HelpTopic[];
29
+ isResizable?: boolean;
30
+ onClose: () => void;
31
+ };
32
+
33
+ const HelpTopicPanelContent: React.FC<HelpTopicPanelContentProps> = ({
34
+ activeHelpTopic = null,
35
+ filteredHelpTopics = [],
36
+ isResizable = true,
37
+ onClose,
38
+ ...props
39
+ }) => {
40
+ const { setActiveHelpTopicByName } = React.useContext<HelpTopicContextValues>(HelpTopicContext);
41
+
42
+ const [isHelpTopicMenuOpen, setIsHelpTopicMenuOpen] = React.useState(false);
43
+
44
+ const toggleHelpTopicMenu = () => {
45
+ setIsHelpTopicMenuOpen(!isHelpTopicMenuOpen);
46
+ };
47
+
48
+ const onSelectHelpTopic = (event) => {
49
+ const topicName = event.currentTarget.id;
50
+ setActiveHelpTopicByName(topicName);
51
+ toggleHelpTopicMenu();
52
+ };
53
+
54
+ const menuItems =
55
+ filteredHelpTopics.length > 0 &&
56
+ filteredHelpTopics.map((topic) => {
57
+ return (
58
+ <OptionsMenuItem key={topic.name} onSelect={onSelectHelpTopic} id={topic.name}>
59
+ {topic.title}
60
+ </OptionsMenuItem>
61
+ );
62
+ });
63
+
64
+ const paddingContainer = (children) => <div style={{ padding: '24px' }}>{children}</div>;
65
+
66
+ const panelBodyItems = (
67
+ <>
68
+ {paddingContainer(<QuickStartMarkdownView content={activeHelpTopic?.content} />)}
69
+ {activeHelpTopic?.links?.length && <Divider />}
70
+ {paddingContainer(
71
+ <Stack hasGutter>
72
+ {activeHelpTopic?.links?.map(({ href, text, newTab, isExternal }, index) => {
73
+ return (
74
+ <StackItem key={index}>
75
+ <Button
76
+ component="a"
77
+ href={href}
78
+ target={newTab ? '_blank' : ''}
79
+ rel="noopener noreferrer"
80
+ variant="link"
81
+ aria-label={`Open documentation in new window`}
82
+ isInline
83
+ icon={isExternal ? <ExternalLinkAltIcon /> : null}
84
+ iconPosition="right"
85
+ style={{ fontSize: 'inherit' }}
86
+ >
87
+ {text || href}
88
+ </Button>
89
+ </StackItem>
90
+ );
91
+ })}
92
+ </Stack>,
93
+ )}
94
+ </>
95
+ );
96
+
97
+ const content = (
98
+ <DrawerPanelContent isResizable={isResizable} className="pfext-quick-start__base" {...props}>
99
+ <div>
100
+ <DrawerHead>
101
+ <div className="pfext-quick-start-panel-content__title">
102
+ {menuItems && (
103
+ <OptionsMenu
104
+ id={'helptopics'}
105
+ isPlain
106
+ isOpen={isHelpTopicMenuOpen}
107
+ toggle={
108
+ <OptionsMenuToggle
109
+ style={{ paddingLeft: '0px' }}
110
+ onToggle={toggleHelpTopicMenu}
111
+ toggleTemplate={<BarsIcon />}
112
+ />
113
+ }
114
+ menuItems={menuItems}
115
+ />
116
+ )}
117
+
118
+ <Title
119
+ headingLevel="h1"
120
+ size="xl"
121
+ className="pfext-quick-start-panel-content__name"
122
+ style={{ marginRight: 'var(--pf-global--spacer--md)' }}
123
+ >
124
+ {activeHelpTopic?.title}
125
+ </Title>
126
+ </div>
127
+ {
128
+ <DrawerActions>
129
+ <DrawerCloseButton
130
+ onClick={onClose}
131
+ className="pfext-quick-start-panel-content__close-button"
132
+ data-testid="qs-drawer-close"
133
+ />
134
+ </DrawerActions>
135
+ }
136
+ </DrawerHead>
137
+ <Divider />
138
+ <DrawerPanelBody
139
+ hasNoPadding
140
+ className="pfext-quick-start-panel-content__body"
141
+ data-test="content"
142
+ >
143
+ {panelBodyItems}
144
+ </DrawerPanelBody>
145
+ </div>
146
+ </DrawerPanelContent>
147
+ );
148
+
149
+ return content;
150
+ };
151
+
152
+ export default HelpTopicPanelContent;