@patternfly/quickstarts 6.3.0-prerelease.1 → 6.3.0-prerelease.10

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 (137) hide show
  1. package/dist/ConsoleInternal/components/markdown-view.d.ts +2 -2
  2. package/dist/ConsoleInternal/components/utils/camel-case-wrap.d.ts +1 -1
  3. package/dist/ConsoleInternal/components/utils/status-box.d.ts +3 -3
  4. package/dist/ConsoleShared/src/components/markdown-extensions/MarkdownCopyClipboard.d.ts +3 -3
  5. package/dist/ConsoleShared/src/components/markdown-extensions/accordion-extension.d.ts +1 -1
  6. package/dist/ConsoleShared/src/components/markdown-extensions/accordion-render-extension.d.ts +2 -2
  7. package/dist/ConsoleShared/src/components/markdown-extensions/admonition-extension.d.ts +1 -1
  8. package/dist/ConsoleShared/src/components/markdown-highlight-extension/MarkdownHighlightExtension.d.ts +2 -2
  9. package/dist/ConsoleShared/src/components/modal/Modal.d.ts +3 -3
  10. package/dist/ConsoleShared/src/components/popper/Portal.d.ts +3 -3
  11. package/dist/ConsoleShared/src/components/popper/SimplePopper.d.ts +3 -3
  12. package/dist/ConsoleShared/src/components/spotlight/InteractiveSpotlight.d.ts +3 -2
  13. package/dist/ConsoleShared/src/components/spotlight/Spotlight.d.ts +2 -2
  14. package/dist/ConsoleShared/src/components/spotlight/StaticSpotlight.d.ts +3 -2
  15. package/dist/ConsoleShared/src/components/status/GenericStatus.d.ts +4 -4
  16. package/dist/ConsoleShared/src/components/status/NotStartedIcon.d.ts +1 -2
  17. package/dist/ConsoleShared/src/components/status/PopoverStatus.d.ts +4 -4
  18. package/dist/ConsoleShared/src/components/status/Status.d.ts +3 -3
  19. package/dist/ConsoleShared/src/components/status/StatusIconAndText.d.ts +3 -3
  20. package/dist/ConsoleShared/src/components/status/icons.d.ts +4 -4
  21. package/dist/ConsoleShared/src/components/status/statuses.d.ts +4 -4
  22. package/dist/ConsoleShared/src/components/utils/FallbackImg.d.ts +3 -3
  23. package/dist/ConsoleShared/src/utils/useCombineRefs.d.ts +2 -2
  24. package/dist/HelpTopicDrawer.d.ts +3 -3
  25. package/dist/HelpTopicPanelContent.d.ts +2 -2
  26. package/dist/QuickStartCatalogPage.d.ts +3 -3
  27. package/dist/QuickStartCloseModal.d.ts +2 -2
  28. package/dist/QuickStartContainer.d.ts +2 -2
  29. package/dist/QuickStartController.d.ts +2 -2
  30. package/dist/QuickStartDrawer.d.ts +2 -2
  31. package/dist/QuickStartDrawerContent.d.ts +2 -2
  32. package/dist/QuickStartMarkdownView.d.ts +2 -2
  33. package/dist/QuickStartPanelContent.d.ts +2 -2
  34. package/dist/catalog/Catalog/QuickStartCatalogHeader.d.ts +2 -2
  35. package/dist/catalog/Catalog/QuickStartCatalogSection.d.ts +2 -2
  36. package/dist/catalog/Catalog/QuickStartCatalogToolbar.d.ts +2 -2
  37. package/dist/catalog/QuickStartCatalog.d.ts +2 -2
  38. package/dist/catalog/QuickStartTile.d.ts +2 -2
  39. package/dist/catalog/QuickStartTileDescription.d.ts +2 -2
  40. package/dist/catalog/QuickStartTileFooter.d.ts +2 -2
  41. package/dist/catalog/QuickStartTileFooterExternal.d.ts +2 -2
  42. package/dist/catalog/QuickStartTileHeader.d.ts +2 -2
  43. package/dist/catalog/Toolbar/QuickStartCatalogFilter.d.ts +2 -2
  44. package/dist/catalog/Toolbar/QuickStartCatalogFilterItems.d.ts +7 -7
  45. package/dist/controller/QuickStartConclusion.d.ts +2 -2
  46. package/dist/controller/QuickStartContent.d.ts +2 -2
  47. package/dist/controller/QuickStartFooter.d.ts +2 -2
  48. package/dist/controller/QuickStartIntroduction.d.ts +2 -2
  49. package/dist/controller/QuickStartTaskHeader.d.ts +2 -2
  50. package/dist/controller/QuickStartTaskHeaderList.d.ts +2 -2
  51. package/dist/controller/QuickStartTaskReview.d.ts +2 -2
  52. package/dist/controller/QuickStartTasks.d.ts +2 -2
  53. package/dist/index.es.js +489 -561
  54. package/dist/index.es.js.map +1 -1
  55. package/dist/index.js +500 -574
  56. package/dist/index.js.map +1 -1
  57. package/dist/quickstarts-base.css +61 -0
  58. package/dist/quickstarts-full.es.js +1963 -693
  59. package/dist/quickstarts-full.es.js.map +1 -1
  60. package/dist/quickstarts.css +61 -0
  61. package/dist/quickstarts.min.css +1 -1
  62. package/dist/utils/help-topic-context.d.ts +2 -2
  63. package/dist/utils/quick-start-context.d.ts +3 -3
  64. package/package.json +5 -6
  65. package/src/ConsoleInternal/components/markdown-view.tsx +112 -22
  66. package/src/ConsoleInternal/components/utils/camel-case-wrap.tsx +3 -3
  67. package/src/ConsoleInternal/components/utils/status-box.tsx +4 -4
  68. package/src/ConsoleShared/src/components/markdown-extensions/MarkdownCopyClipboard.tsx +8 -15
  69. package/src/ConsoleShared/src/components/markdown-extensions/__tests__/MarkdownCopyClipboard.spec.tsx +0 -1
  70. package/src/ConsoleShared/src/components/markdown-extensions/__tests__/accordion-extension.spec.tsx +105 -0
  71. package/src/ConsoleShared/src/components/markdown-extensions/__tests__/admonition-extension.spec.tsx +121 -0
  72. package/src/ConsoleShared/src/components/markdown-extensions/accordion-extension.tsx +22 -15
  73. package/src/ConsoleShared/src/components/markdown-extensions/accordion-render-extension.tsx +23 -9
  74. package/src/ConsoleShared/src/components/markdown-extensions/admonition-extension.tsx +19 -8
  75. package/src/ConsoleShared/src/components/markdown-extensions/code-extension.tsx +2 -2
  76. package/src/ConsoleShared/src/components/markdown-extensions/inline-clipboard-extension.tsx +3 -3
  77. package/src/ConsoleShared/src/components/markdown-extensions/multiline-clipboard-extension.tsx +3 -3
  78. package/src/ConsoleShared/src/components/markdown-highlight-extension/MarkdownHighlightExtension.tsx +5 -5
  79. package/src/ConsoleShared/src/components/modal/Modal.tsx +3 -3
  80. package/src/ConsoleShared/src/components/popper/Portal.tsx +5 -5
  81. package/src/ConsoleShared/src/components/popper/SimplePopper.tsx +15 -15
  82. package/src/ConsoleShared/src/components/spotlight/InteractiveSpotlight.tsx +6 -5
  83. package/src/ConsoleShared/src/components/spotlight/Spotlight.tsx +3 -3
  84. package/src/ConsoleShared/src/components/spotlight/StaticSpotlight.tsx +4 -3
  85. package/src/ConsoleShared/src/components/spotlight/spotlight.scss +63 -0
  86. package/src/ConsoleShared/src/components/status/GenericStatus.tsx +5 -5
  87. package/src/ConsoleShared/src/components/status/NotStartedIcon.tsx +0 -1
  88. package/src/ConsoleShared/src/components/status/PopoverStatus.tsx +4 -4
  89. package/src/ConsoleShared/src/components/status/Status.tsx +3 -11
  90. package/src/ConsoleShared/src/components/status/StatusIconAndText.tsx +6 -6
  91. package/src/ConsoleShared/src/components/status/icons.tsx +4 -8
  92. package/src/ConsoleShared/src/components/status/statuses.tsx +4 -5
  93. package/src/ConsoleShared/src/components/utils/FallbackImg.tsx +4 -4
  94. package/src/ConsoleShared/src/hooks/scroll.ts +4 -4
  95. package/src/ConsoleShared/src/hooks/useBoundingClientRect.ts +3 -3
  96. package/src/ConsoleShared/src/hooks/useForceRender.ts +2 -2
  97. package/src/ConsoleShared/src/hooks/useResizeObserver.ts +3 -6
  98. package/src/ConsoleShared/src/hooks/useScrollShadows.ts +4 -4
  99. package/src/ConsoleShared/src/utils/useCombineRefs.ts +4 -4
  100. package/src/HelpTopicDrawer.tsx +6 -6
  101. package/src/HelpTopicPanelContent.tsx +4 -4
  102. package/src/QuickStartCatalogPage.tsx +9 -9
  103. package/src/QuickStartCloseModal.tsx +3 -7
  104. package/src/QuickStartContainer.tsx +4 -4
  105. package/src/QuickStartController.tsx +11 -11
  106. package/src/QuickStartDrawer.tsx +6 -6
  107. package/src/QuickStartDrawerContent.tsx +6 -4
  108. package/src/QuickStartMarkdownView.tsx +3 -3
  109. package/src/QuickStartPanelContent.tsx +8 -8
  110. package/src/catalog/Catalog/QuickStartCatalogHeader.tsx +2 -2
  111. package/src/catalog/Catalog/QuickStartCatalogSection.tsx +2 -2
  112. package/src/catalog/Catalog/QuickStartCatalogToolbar.tsx +2 -2
  113. package/src/catalog/QuickStartCatalog.tsx +3 -3
  114. package/src/catalog/QuickStartTile.tsx +4 -4
  115. package/src/catalog/QuickStartTileDescription.tsx +4 -4
  116. package/src/catalog/QuickStartTileFooter.tsx +6 -6
  117. package/src/catalog/QuickStartTileFooterExternal.tsx +2 -5
  118. package/src/catalog/QuickStartTileHeader.tsx +2 -6
  119. package/src/catalog/Toolbar/QuickStartCatalogFilter.tsx +2 -2
  120. package/src/catalog/Toolbar/QuickStartCatalogFilterItems.tsx +17 -20
  121. package/src/catalog/__tests__/QuickStartCatalog.spec.tsx +0 -1
  122. package/src/catalog/__tests__/QuickStartTile.spec.tsx +0 -1
  123. package/src/catalog/__tests__/QuickStartTileDescription.spec.tsx +1 -2
  124. package/src/controller/QuickStartConclusion.tsx +3 -3
  125. package/src/controller/QuickStartContent.tsx +2 -2
  126. package/src/controller/QuickStartFooter.tsx +10 -11
  127. package/src/controller/QuickStartIntroduction.tsx +5 -5
  128. package/src/controller/QuickStartTaskHeader.tsx +5 -5
  129. package/src/controller/QuickStartTaskHeaderList.tsx +2 -2
  130. package/src/controller/QuickStartTaskReview.tsx +4 -4
  131. package/src/controller/QuickStartTasks.tsx +5 -5
  132. package/src/controller/__tests__/QuickStartConclusion.spec.tsx +3 -3
  133. package/src/controller/__tests__/QuickStartContent.spec.tsx +2 -2
  134. package/src/controller/__tests__/QuickStartTaskHeader.spec.tsx +2 -2
  135. package/src/controller/__tests__/QuickStartTaskReview.spec.tsx +2 -2
  136. package/src/utils/help-topic-context.tsx +7 -10
  137. package/src/utils/quick-start-context.tsx +11 -11
@@ -207,6 +207,67 @@
207
207
  font-size: var(--pf-t--global--font--size--body--default);
208
208
  color: var(--pf-t--global--text--color--subtle);
209
209
  font-weight: var(--pf-t--global--font--weight--body);
210
+ }
211
+
212
+ @keyframes pfext-spotlight-expand {
213
+ 0% {
214
+ outline-offset: -4px;
215
+ outline-width: 4px;
216
+ opacity: 1;
217
+ }
218
+ 100% {
219
+ outline-offset: 21px;
220
+ outline-width: 12px;
221
+ opacity: 0;
222
+ }
223
+ }
224
+ @keyframes pfext-spotlight-fade-in {
225
+ 0% {
226
+ opacity: 0;
227
+ }
228
+ 100% {
229
+ opacity: 1;
230
+ }
231
+ }
232
+ @keyframes pfext-spotlight-fade-out {
233
+ 0% {
234
+ opacity: 1;
235
+ }
236
+ 100% {
237
+ opacity: 0;
238
+ }
239
+ }
240
+ .pfext-spotlight {
241
+ pointer-events: none;
242
+ position: absolute;
243
+ }
244
+ .pfext-spotlight__with-backdrop {
245
+ mix-blend-mode: hard-light;
246
+ }
247
+ .pfext-spotlight__element-highlight-noanimate {
248
+ border: var(--pf-t--global--border--width--strong) solid var(--pf-t--global--border--color--brand--default);
249
+ background-color: var(--pf-t--color--gray--40);
250
+ z-index: 9999;
251
+ }
252
+ .pfext-spotlight__element-highlight-animate {
253
+ pointer-events: none;
254
+ position: absolute;
255
+ box-shadow: inset 0px 0px 0px 4px var(--pf-t--global--color--brand--default);
256
+ opacity: 0;
257
+ animation: 0.4s pfext-spotlight-fade-in 0s ease-in-out, 5s pfext-spotlight-fade-out 12.8s ease-in-out;
258
+ animation-fill-mode: forwards;
259
+ }
260
+ .pfext-spotlight__element-highlight-animate::after {
261
+ content: "";
262
+ position: absolute;
263
+ left: 0;
264
+ right: 0;
265
+ top: 0;
266
+ bottom: 0;
267
+ animation: 1.2s pfext-spotlight-expand 1.6s ease-out;
268
+ animation-fill-mode: forwards;
269
+ outline: 4px solid var(--pf-t--global--color--brand--default);
270
+ outline-offset: -4px;
210
271
  }.pf-v6-c-clipboard-copy {
211
272
  --pf-v6-c-clipboard-copy__toggle-icon--Transition: .2s ease-in 0s;
212
273
  --pf-v6-c-clipboard-copy--m-expanded__toggle-icon--Rotate: 90deg;
@@ -1 +1 @@
1
- .pfext-quick-start-panel{--pf-v6-c-drawer__panel--PaddingBlockStart:0}.pfext-popover__base ul{list-style-type:var(--pf-t--global--list-style)}.pfext-markdown-view .h1,.pfext-markdown-view .h2,.pfext-markdown-view .h3,.pfext-markdown-view .h4,.pfext-markdown-view .h5,.pfext-markdown-view .h6,.pfext-markdown-view h1,.pfext-markdown-view h2,.pfext-markdown-view h3,.pfext-markdown-view h4,.pfext-markdown-view h5,.pfext-markdown-view h6{font-family:var(--pf-t--global--font--family--heading);font-weight:var(--pf-t--global--font--weight--heading);line-height:1.1;color:inherit}.pfext-markdown-view .h1,.pfext-markdown-view .h2,.pfext-markdown-view .h3,.pfext-markdown-view h1,.pfext-markdown-view h2,.pfext-markdown-view h3{margin-top:23px;margin-bottom:11.5px}.pfext-markdown-view .h4,.pfext-markdown-view .h5,.pfext-markdown-view .h6,.pfext-markdown-view h4,.pfext-markdown-view h5,.pfext-markdown-view h6{margin-top:11.5px;margin-bottom:11.5px}.pfext-markdown-view .h1,.pfext-markdown-view h1{font-size:var(--pf-t--global--font--size--heading--h1)}.pfext-markdown-view .h2,.pfext-markdown-view h2{font-size:var(--pf-t--global--font--size--heading--h2)}.pfext-markdown-view .h3,.pfext-markdown-view h3{font-size:var(--pf-t--global--font--size--heading--h3)}.pfext-markdown-view .h4,.pfext-markdown-view h4{font-size:var(--pf-t--global--font--size--heading--h4)}.pfext-markdown-view .h5,.pfext-markdown-view h5{font-size:var(--pf-t--global--font--size--heading--h5)}.pfext-markdown-view .h6,.pfext-markdown-view h6{font-size:var(--pf-t--global--font--size--heading--h6)}.pfext-markdown-view p{margin:0 0 11.5px}.pfext-markdown-view ol,.pfext-markdown-view ul{margin-top:0;margin-bottom:11.5px}.pfext-markdown-view ol ol,.pfext-markdown-view ol ul,.pfext-markdown-view ul ol,.pfext-markdown-view ul ul{margin-bottom:0}.pfext-markdown-view dl{margin-top:0;margin-bottom:23px}.pfext-markdown-view dd,.pfext-markdown-view dt{line-height:1.66666667}.pfext-markdown-view dt{font-weight:700}.pfext-markdown-view dd{margin-left:0}.pfext-markdown-view blockquote{padding:11.5px 23px;margin:0 0 23px;font-size:17.5px;border-left:5px solid #f1f1f1}.pfext-markdown-view blockquote ol:last-child,.pfext-markdown-view blockquote p:last-child,.pfext-markdown-view blockquote ul:last-child{margin-bottom:0}.pfext-markdown-view code,.pfext-markdown-view pre{font-family:Menlo,Monaco,Consolas,monospace}.pfext-markdown-view code{padding:2px 4px;font-size:90%;color:#004368;background-color:#def3ff;border-radius:1px}.pfext-markdown-view pre{display:block;padding:11px;margin:0 0 11.5px;font-size:13px;line-height:1.66666667;color:#363636;word-break:break-all;word-wrap:break-word;background-color:#fafafa;border:1px solid #ccc;border-radius:1px}.pfext-markdown-view pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pfext-markdown-view table{background-color:transparent}.pfext-markdown-view table col[class*=col-]{position:static;display:table-column;float:none}.pfext-markdown-view table td[class*=col-],.pfext-markdown-view table th[class*=col-]{position:static;display:table-cell;float:none}.pfext-markdown-view caption{padding-top:10px;padding-bottom:10px;color:#9c9c9c;text-align:left}.pfext-markdown-view th{text-align:left}.pfext-quick-start-panel-content{background-color:var(--pf-t--global--color--brand--default);color:var(--pf-t--global--text--color--inverse);padding:var(--pf-t--global--spacer--md) var(--pf-t--global--spacer--lg)}.pfext-quick-start-panel-content__body{display:flex;flex-direction:column}.pfext-quick-start-panel-content span.pf-v6-c-button__icon{color:var(--pf-t--global--text--color--inverse)}.pf-v6-theme-dark .pfext-catalog-item-icon__img{filter:brightness(1.5) invert(1) hue-rotate(180deg) saturate(4)}.pfext-catalog-item .pf-v6-c-card__header-main .pf-v6-c-icon__content{display:contents}.pfext-catalog-item.pf-v6-c-card.pf-m-clickable::before,.pfext-catalog-item.pf-v6-c-card.pf-m-selectable::before{border:var(--pf-v6-c-card--BorderColor) var(--pf-v6-c-card--BorderStyle) var(--pf-v6-c-card--BorderWidth)}.pfext-quick-start-footer{padding-top:var(--pf-t--global--spacer--md)}.pfext-quick-start-task{flex:1 1 0;overflow:auto}.pfext-quick-start-task .pf-v6-c-accordion,.pfext-quick-start-task .pf-v6-c-alert,.pfext-quick-start-task .pf-v6-c-code-block{margin-block-end:var(--pf-v6-c-content--MarginBlockEnd)}.pfext-quick-start-task .pf-v6-c-wizard{height:initial}.pfext-quick-start-task-header button.pf-v6-c-wizard__nav-link{margin-bottom:var(--pf-t--global--spacer--md)}.pfext-quick-start-task-header button.pf-v6-c-wizard__nav-link.pf-m-current{--pf-v6-c-wizard__nav-link-main--BackgroundColor:transparent}.pfext-quick-start-task-header button.pf-v6-c-wizard__nav-link::before{background-color:var(--pf-v6-c-wizard__nav-link--m-current--before--BackgroundColor);color:var(--pf-v6-c-wizard__nav-link--m-current--before--Color);min-width:var(--pf-v6-c-wizard__nav-link--before--Width)}.pfext-quick-start-task-header__title{font-family:var(--pf-t--global--font--family--body);font-weight:var(---pf-t--global--font--weight--body--bold);font-size:var(--pf-t--global--font--size--body--lg)}.pfext-quick-start-task-header__subtitle{font-size:var(--pf-t--global--font--size--body--default);color:var(--pf-t--global--text--color--subtle);font-weight:var(--pf-t--global--font--weight--body)}.pfext-quick-start-task-header__tryagain{display:block;font-size:var(--pf-t--global--font--size--body--default);color:var(--pf-t--global--text--color--subtle);font-weight:var(--pf-t--global--font--weight--body)}.pf-v6-c-clipboard-copy{--pf-v6-c-clipboard-copy__toggle-icon--Transition:.2s ease-in 0s;--pf-v6-c-clipboard-copy--m-expanded__toggle-icon--Rotate:90deg;--pf-v6-c-clipboard-copy__expandable-content--MarginBlockStart:var(--pf-t--global--spacer--xs);--pf-v6-c-clipboard-copy__expandable-content--PaddingBlockStart:var(--pf-t--global--spacer--md);--pf-v6-c-clipboard-copy__expandable-content--PaddingInlineEnd:var(--pf-t--global--spacer--md);--pf-v6-c-clipboard-copy__expandable-content--PaddingBlockEnd:var(--pf-t--global--spacer--md);--pf-v6-c-clipboard-copy__expandable-content--PaddingInlineStart:var(--pf-t--global--spacer--md);--pf-v6-c-clipboard-copy__expandable-content--BackgroundColor:var(--pf-t--global--background--color--primary--default);--pf-v6-c-clipboard-copy__expandable-content--BorderBlockStartWidth:var(--pf-t--global--border--width--control--default);--pf-v6-c-clipboard-copy__expandable-content--BorderInlineEndWidth:var(--pf-t--global--border--width--control--default);--pf-v6-c-clipboard-copy__expandable-content--BorderBlockEndWidth:var(--pf-t--global--border--width--control--default);--pf-v6-c-clipboard-copy__expandable-content--BorderInlineStartWidth:var(--pf-t--global--border--width--control--default);--pf-v6-c-clipboard-copy__expandable-content--BorderColor:var(--pf-t--global--border--color--default);--pf-v6-c-clipboard-copy__expandable-content--BorderRadius:var(--pf-t--global--border--radius--small);--pf-v6-c-clipboard-copy__expandable-content--OutlineOffset:var(--pf-t--global--spacer--xs);--pf-v6-c-clipboard-copy__group--Gap:var(--pf-t--global--spacer--gap--control-to-control--default);--pf-v6-c-clipboard-copy--m-inline--PaddingInlineStart:var(--pf-t--global--spacer--xs);--pf-v6-c-clipboard-copy--m-inline--PaddingInlineEnd:var(--pf-t--global--spacer--xs);--pf-v6-c-clipboard-copy--m-inline--BackgroundColor:var(--pf-t--global--background--color--secondary--default);--pf-v6-c-clipboard-copy__actions--Gap:var(--pf-t--global--spacer--gap--action-to-action--plain);--pf-v6-c-clipboard-copy__actions--MarginInlineStart:var(--pf-t--global--spacer--gap--text-to-element--compact);--pf-v6-c-clipboard-copy__actions-item--button--Color:var(--pf-t--global--icon--color--subtle);--pf-v6-c-clipboard-copy__actions-item--button--hover--Color:var(--pf-t--global--icon--color--regular);--pf-v6-c-clipboard-copy__text--m-code--FontFamily:var(--pf-t--global--font--family--mono);--pf-v6-c-clipboard-copy__text--m-code--FontSize:var(--pf-t--global--font--size--body--default)}.pf-v6-c-clipboard-copy.pf-m-inline{display:inline;padding-inline-start:var(--pf-v6-c-clipboard-copy--m-inline--PaddingInlineStart);padding-inline-end:var(--pf-v6-c-clipboard-copy--m-inline--PaddingInlineEnd);white-space:nowrap;background-color:var(--pf-v6-c-clipboard-copy--m-inline--BackgroundColor)}.pf-v6-c-clipboard-copy.pf-m-inline.pf-m-block{display:block}.pf-v6-c-clipboard-copy__text{word-break:break-word;white-space:normal}.pf-v6-c-clipboard-copy__actions{display:inline-flex;gap:var(--pf-v6-c-clipboard-copy__actions--Gap);margin-inline-start:var(--pf-v6-c-clipboard-copy__actions--MarginInlineStart)}.pf-v6-c-clipboard-copy__actions-item .pf-v6-c-button.pf-m-plain{--pf-v6-c-button--m-plain__icon--Color:var(--pf-v6-c-clipboard-copy__actions-item--button--Color);--pf-v6-c-button--m-plain--hover__icon--Color:var(--pf-v6-c-clipboard-copy__actions-item--button--hover--Color)}.pf-v6-c-code-block{--pf-v6-c-code-block--BackgroundColor:var(--pf-t--global--background--color--secondary--default);--pf-v6-c-code-block--BorderRadius:var(--pf-t--global--border--radius--medium);--pf-v6-c-code-block__header--BorderBlockEndWidth:var(--pf-t--global--border--width--divider--default);--pf-v6-c-code-block__header--BorderBlockEndColor:var(--pf-t--global--border--color--default);--pf-v6-c-code-block__header--PaddingBlockStart:var(--pf-t--global--spacer--xs);--pf-v6-c-code-block__header--PaddingBlockEnd:var(--pf-t--global--spacer--xs);--pf-v6-c-code-block__header--PaddingInlineEnd:var(--pf-t--global--spacer--sm);--pf-v6-c-code-block__header--PaddingInlineStart:var(--pf-t--global--spacer--sm);--pf-v6-c-code-block__content--PaddingBlockStart:var(--pf-t--global--spacer--md);--pf-v6-c-code-block__content--PaddingInlineEnd:var(--pf-t--global--spacer--md);--pf-v6-c-code-block__content--PaddingBlockEnd:var(--pf-t--global--spacer--md);--pf-v6-c-code-block__content--PaddingInlineStart:var(--pf-t--global--spacer--md);--pf-v6-c-code-block__pre--FontFamily:var(--pf-t--global--font--family--mono);--pf-v6-c-code-block__pre--FontSize:var(--pf-t--global--font--size--xs)}.pf-v6-c-code-block{background-color:var(--pf-v6-c-code-block--BackgroundColor);border-radius:var(--pf-v6-c-code-block--BorderRadius)}.pf-v6-c-code-block__header{display:flex;padding-block-start:var(--pf-v6-c-code-block__header--PaddingBlockStart);padding-block-end:var(--pf-v6-c-code-block__header--PaddingBlockEnd);padding-inline-start:var(--pf-v6-c-code-block__header--PaddingInlineStart);padding-inline-end:var(--pf-v6-c-code-block__header--PaddingInlineEnd);border-block-end:var(--pf-v6-c-code-block__header--BorderBlockEndWidth) solid var(--pf-v6-c-code-block__header--BorderBlockEndColor)}.pf-v6-c-code-block__actions{display:flex;margin-inline-start:auto}.pf-v6-c-code-block__content{padding-block-start:var(--pf-v6-c-code-block__content--PaddingBlockStart);padding-block-end:var(--pf-v6-c-code-block__content--PaddingBlockEnd);padding-inline-start:var(--pf-v6-c-code-block__content--PaddingInlineStart);padding-inline-end:var(--pf-v6-c-code-block__content--PaddingInlineEnd)}.pf-v6-c-code-block__pre{font-family:var(--pf-v6-c-code-block__pre--FontFamily);font-size:var(--pf-v6-c-code-block__pre--FontSize);overflow-wrap:break-word;white-space:pre-wrap}.pf-v6-c-code-block__code{font-family:var(--pf-v6-c-code-block__code--FontFamily,inherit)}
1
+ .pfext-quick-start-panel{--pf-v6-c-drawer__panel--PaddingBlockStart:0}.pfext-popover__base ul{list-style-type:var(--pf-t--global--list-style)}.pfext-markdown-view .h1,.pfext-markdown-view .h2,.pfext-markdown-view .h3,.pfext-markdown-view .h4,.pfext-markdown-view .h5,.pfext-markdown-view .h6,.pfext-markdown-view h1,.pfext-markdown-view h2,.pfext-markdown-view h3,.pfext-markdown-view h4,.pfext-markdown-view h5,.pfext-markdown-view h6{font-family:var(--pf-t--global--font--family--heading);font-weight:var(--pf-t--global--font--weight--heading);line-height:1.1;color:inherit}.pfext-markdown-view .h1,.pfext-markdown-view .h2,.pfext-markdown-view .h3,.pfext-markdown-view h1,.pfext-markdown-view h2,.pfext-markdown-view h3{margin-top:23px;margin-bottom:11.5px}.pfext-markdown-view .h4,.pfext-markdown-view .h5,.pfext-markdown-view .h6,.pfext-markdown-view h4,.pfext-markdown-view h5,.pfext-markdown-view h6{margin-top:11.5px;margin-bottom:11.5px}.pfext-markdown-view .h1,.pfext-markdown-view h1{font-size:var(--pf-t--global--font--size--heading--h1)}.pfext-markdown-view .h2,.pfext-markdown-view h2{font-size:var(--pf-t--global--font--size--heading--h2)}.pfext-markdown-view .h3,.pfext-markdown-view h3{font-size:var(--pf-t--global--font--size--heading--h3)}.pfext-markdown-view .h4,.pfext-markdown-view h4{font-size:var(--pf-t--global--font--size--heading--h4)}.pfext-markdown-view .h5,.pfext-markdown-view h5{font-size:var(--pf-t--global--font--size--heading--h5)}.pfext-markdown-view .h6,.pfext-markdown-view h6{font-size:var(--pf-t--global--font--size--heading--h6)}.pfext-markdown-view p{margin:0 0 11.5px}.pfext-markdown-view ol,.pfext-markdown-view ul{margin-top:0;margin-bottom:11.5px}.pfext-markdown-view ol ol,.pfext-markdown-view ol ul,.pfext-markdown-view ul ol,.pfext-markdown-view ul ul{margin-bottom:0}.pfext-markdown-view dl{margin-top:0;margin-bottom:23px}.pfext-markdown-view dd,.pfext-markdown-view dt{line-height:1.66666667}.pfext-markdown-view dt{font-weight:700}.pfext-markdown-view dd{margin-left:0}.pfext-markdown-view blockquote{padding:11.5px 23px;margin:0 0 23px;font-size:17.5px;border-left:5px solid #f1f1f1}.pfext-markdown-view blockquote ol:last-child,.pfext-markdown-view blockquote p:last-child,.pfext-markdown-view blockquote ul:last-child{margin-bottom:0}.pfext-markdown-view code,.pfext-markdown-view pre{font-family:Menlo,Monaco,Consolas,monospace}.pfext-markdown-view code{padding:2px 4px;font-size:90%;color:#004368;background-color:#def3ff;border-radius:1px}.pfext-markdown-view pre{display:block;padding:11px;margin:0 0 11.5px;font-size:13px;line-height:1.66666667;color:#363636;word-break:break-all;word-wrap:break-word;background-color:#fafafa;border:1px solid #ccc;border-radius:1px}.pfext-markdown-view pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pfext-markdown-view table{background-color:transparent}.pfext-markdown-view table col[class*=col-]{position:static;display:table-column;float:none}.pfext-markdown-view table td[class*=col-],.pfext-markdown-view table th[class*=col-]{position:static;display:table-cell;float:none}.pfext-markdown-view caption{padding-top:10px;padding-bottom:10px;color:#9c9c9c;text-align:left}.pfext-markdown-view th{text-align:left}.pfext-quick-start-panel-content{background-color:var(--pf-t--global--color--brand--default);color:var(--pf-t--global--text--color--inverse);padding:var(--pf-t--global--spacer--md) var(--pf-t--global--spacer--lg)}.pfext-quick-start-panel-content__body{display:flex;flex-direction:column}.pfext-quick-start-panel-content span.pf-v6-c-button__icon{color:var(--pf-t--global--text--color--inverse)}.pf-v6-theme-dark .pfext-catalog-item-icon__img{filter:brightness(1.5) invert(1) hue-rotate(180deg) saturate(4)}.pfext-catalog-item .pf-v6-c-card__header-main .pf-v6-c-icon__content{display:contents}.pfext-catalog-item.pf-v6-c-card.pf-m-clickable::before,.pfext-catalog-item.pf-v6-c-card.pf-m-selectable::before{border:var(--pf-v6-c-card--BorderColor) var(--pf-v6-c-card--BorderStyle) var(--pf-v6-c-card--BorderWidth)}.pfext-quick-start-footer{padding-top:var(--pf-t--global--spacer--md)}.pfext-quick-start-task{flex:1 1 0;overflow:auto}.pfext-quick-start-task .pf-v6-c-accordion,.pfext-quick-start-task .pf-v6-c-alert,.pfext-quick-start-task .pf-v6-c-code-block{margin-block-end:var(--pf-v6-c-content--MarginBlockEnd)}.pfext-quick-start-task .pf-v6-c-wizard{height:initial}.pfext-quick-start-task-header button.pf-v6-c-wizard__nav-link{margin-bottom:var(--pf-t--global--spacer--md)}.pfext-quick-start-task-header button.pf-v6-c-wizard__nav-link.pf-m-current{--pf-v6-c-wizard__nav-link-main--BackgroundColor:transparent}.pfext-quick-start-task-header button.pf-v6-c-wizard__nav-link::before{background-color:var(--pf-v6-c-wizard__nav-link--m-current--before--BackgroundColor);color:var(--pf-v6-c-wizard__nav-link--m-current--before--Color);min-width:var(--pf-v6-c-wizard__nav-link--before--Width)}.pfext-quick-start-task-header__title{font-family:var(--pf-t--global--font--family--body);font-weight:var(---pf-t--global--font--weight--body--bold);font-size:var(--pf-t--global--font--size--body--lg)}.pfext-quick-start-task-header__subtitle{font-size:var(--pf-t--global--font--size--body--default);color:var(--pf-t--global--text--color--subtle);font-weight:var(--pf-t--global--font--weight--body)}.pfext-quick-start-task-header__tryagain{display:block;font-size:var(--pf-t--global--font--size--body--default);color:var(--pf-t--global--text--color--subtle);font-weight:var(--pf-t--global--font--weight--body)}@keyframes pfext-spotlight-expand{0%{outline-offset:-4px;outline-width:4px;opacity:1}100%{outline-offset:21px;outline-width:12px;opacity:0}}@keyframes pfext-spotlight-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes pfext-spotlight-fade-out{0%{opacity:1}100%{opacity:0}}.pfext-spotlight{pointer-events:none;position:absolute}.pfext-spotlight__with-backdrop{mix-blend-mode:hard-light}.pfext-spotlight__element-highlight-noanimate{border:var(--pf-t--global--border--width--strong) solid var(--pf-t--global--border--color--brand--default);background-color:var(--pf-t--color--gray--40);z-index:9999}.pfext-spotlight__element-highlight-animate{pointer-events:none;position:absolute;box-shadow:inset 0 0 0 4px var(--pf-t--global--color--brand--default);opacity:0;animation:.4s pfext-spotlight-fade-in 0s ease-in-out,5s pfext-spotlight-fade-out 12.8s ease-in-out;animation-fill-mode:forwards}.pfext-spotlight__element-highlight-animate::after{content:"";position:absolute;left:0;right:0;top:0;bottom:0;animation:1.2s pfext-spotlight-expand 1.6s ease-out;animation-fill-mode:forwards;outline:4px solid var(--pf-t--global--color--brand--default);outline-offset:-4px}.pf-v6-c-clipboard-copy{--pf-v6-c-clipboard-copy__toggle-icon--Transition:.2s ease-in 0s;--pf-v6-c-clipboard-copy--m-expanded__toggle-icon--Rotate:90deg;--pf-v6-c-clipboard-copy__expandable-content--MarginBlockStart:var(--pf-t--global--spacer--xs);--pf-v6-c-clipboard-copy__expandable-content--PaddingBlockStart:var(--pf-t--global--spacer--md);--pf-v6-c-clipboard-copy__expandable-content--PaddingInlineEnd:var(--pf-t--global--spacer--md);--pf-v6-c-clipboard-copy__expandable-content--PaddingBlockEnd:var(--pf-t--global--spacer--md);--pf-v6-c-clipboard-copy__expandable-content--PaddingInlineStart:var(--pf-t--global--spacer--md);--pf-v6-c-clipboard-copy__expandable-content--BackgroundColor:var(--pf-t--global--background--color--primary--default);--pf-v6-c-clipboard-copy__expandable-content--BorderBlockStartWidth:var(--pf-t--global--border--width--control--default);--pf-v6-c-clipboard-copy__expandable-content--BorderInlineEndWidth:var(--pf-t--global--border--width--control--default);--pf-v6-c-clipboard-copy__expandable-content--BorderBlockEndWidth:var(--pf-t--global--border--width--control--default);--pf-v6-c-clipboard-copy__expandable-content--BorderInlineStartWidth:var(--pf-t--global--border--width--control--default);--pf-v6-c-clipboard-copy__expandable-content--BorderColor:var(--pf-t--global--border--color--default);--pf-v6-c-clipboard-copy__expandable-content--BorderRadius:var(--pf-t--global--border--radius--small);--pf-v6-c-clipboard-copy__expandable-content--OutlineOffset:var(--pf-t--global--spacer--xs);--pf-v6-c-clipboard-copy__group--Gap:var(--pf-t--global--spacer--gap--control-to-control--default);--pf-v6-c-clipboard-copy--m-inline--PaddingInlineStart:var(--pf-t--global--spacer--xs);--pf-v6-c-clipboard-copy--m-inline--PaddingInlineEnd:var(--pf-t--global--spacer--xs);--pf-v6-c-clipboard-copy--m-inline--BackgroundColor:var(--pf-t--global--background--color--secondary--default);--pf-v6-c-clipboard-copy__actions--Gap:var(--pf-t--global--spacer--gap--action-to-action--plain);--pf-v6-c-clipboard-copy__actions--MarginInlineStart:var(--pf-t--global--spacer--gap--text-to-element--compact);--pf-v6-c-clipboard-copy__actions-item--button--Color:var(--pf-t--global--icon--color--subtle);--pf-v6-c-clipboard-copy__actions-item--button--hover--Color:var(--pf-t--global--icon--color--regular);--pf-v6-c-clipboard-copy__text--m-code--FontFamily:var(--pf-t--global--font--family--mono);--pf-v6-c-clipboard-copy__text--m-code--FontSize:var(--pf-t--global--font--size--body--default)}.pf-v6-c-clipboard-copy.pf-m-inline{display:inline;padding-inline-start:var(--pf-v6-c-clipboard-copy--m-inline--PaddingInlineStart);padding-inline-end:var(--pf-v6-c-clipboard-copy--m-inline--PaddingInlineEnd);white-space:nowrap;background-color:var(--pf-v6-c-clipboard-copy--m-inline--BackgroundColor)}.pf-v6-c-clipboard-copy.pf-m-inline.pf-m-block{display:block}.pf-v6-c-clipboard-copy__text{word-break:break-word;white-space:normal}.pf-v6-c-clipboard-copy__actions{display:inline-flex;gap:var(--pf-v6-c-clipboard-copy__actions--Gap);margin-inline-start:var(--pf-v6-c-clipboard-copy__actions--MarginInlineStart)}.pf-v6-c-clipboard-copy__actions-item .pf-v6-c-button.pf-m-plain{--pf-v6-c-button--m-plain__icon--Color:var(--pf-v6-c-clipboard-copy__actions-item--button--Color);--pf-v6-c-button--m-plain--hover__icon--Color:var(--pf-v6-c-clipboard-copy__actions-item--button--hover--Color)}.pf-v6-c-code-block{--pf-v6-c-code-block--BackgroundColor:var(--pf-t--global--background--color--secondary--default);--pf-v6-c-code-block--BorderRadius:var(--pf-t--global--border--radius--medium);--pf-v6-c-code-block__header--BorderBlockEndWidth:var(--pf-t--global--border--width--divider--default);--pf-v6-c-code-block__header--BorderBlockEndColor:var(--pf-t--global--border--color--default);--pf-v6-c-code-block__header--PaddingBlockStart:var(--pf-t--global--spacer--xs);--pf-v6-c-code-block__header--PaddingBlockEnd:var(--pf-t--global--spacer--xs);--pf-v6-c-code-block__header--PaddingInlineEnd:var(--pf-t--global--spacer--sm);--pf-v6-c-code-block__header--PaddingInlineStart:var(--pf-t--global--spacer--sm);--pf-v6-c-code-block__content--PaddingBlockStart:var(--pf-t--global--spacer--md);--pf-v6-c-code-block__content--PaddingInlineEnd:var(--pf-t--global--spacer--md);--pf-v6-c-code-block__content--PaddingBlockEnd:var(--pf-t--global--spacer--md);--pf-v6-c-code-block__content--PaddingInlineStart:var(--pf-t--global--spacer--md);--pf-v6-c-code-block__pre--FontFamily:var(--pf-t--global--font--family--mono);--pf-v6-c-code-block__pre--FontSize:var(--pf-t--global--font--size--xs)}.pf-v6-c-code-block{background-color:var(--pf-v6-c-code-block--BackgroundColor);border-radius:var(--pf-v6-c-code-block--BorderRadius)}.pf-v6-c-code-block__header{display:flex;padding-block-start:var(--pf-v6-c-code-block__header--PaddingBlockStart);padding-block-end:var(--pf-v6-c-code-block__header--PaddingBlockEnd);padding-inline-start:var(--pf-v6-c-code-block__header--PaddingInlineStart);padding-inline-end:var(--pf-v6-c-code-block__header--PaddingInlineEnd);border-block-end:var(--pf-v6-c-code-block__header--BorderBlockEndWidth) solid var(--pf-v6-c-code-block__header--BorderBlockEndColor)}.pf-v6-c-code-block__actions{display:flex;margin-inline-start:auto}.pf-v6-c-code-block__content{padding-block-start:var(--pf-v6-c-code-block__content--PaddingBlockStart);padding-block-end:var(--pf-v6-c-code-block__content--PaddingBlockEnd);padding-inline-start:var(--pf-v6-c-code-block__content--PaddingInlineStart);padding-inline-end:var(--pf-v6-c-code-block__content--PaddingInlineEnd)}.pf-v6-c-code-block__pre{font-family:var(--pf-v6-c-code-block__pre--FontFamily);font-size:var(--pf-v6-c-code-block__pre--FontSize);overflow-wrap:break-word;white-space:pre-wrap}.pf-v6-c-code-block__code{font-family:var(--pf-v6-c-code-block__code--FontFamily,inherit)}
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ /// <reference types="react" />
2
2
  import { HelpTopic } from './help-topic-types';
3
3
  export interface HelpTopicContextValues {
4
4
  helpTopics?: HelpTopic[];
@@ -19,5 +19,5 @@ export declare const HelpTopicContextDefaults: {
19
19
  setFilteredHelpTopics: () => void;
20
20
  loading: boolean;
21
21
  };
22
- export declare const HelpTopicContext: React.Context<HelpTopicContextValues>;
22
+ export declare const HelpTopicContext: import("react").Context<HelpTopicContextValues>;
23
23
  export declare const useValuesForHelpTopicContext: (value?: HelpTopicContextValues) => HelpTopicContextValues;
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import { FC } from 'react';
2
2
  import { AllQuickStartStates, QuickStart, QuickStartState, QuickStartStatus, QuickStartTaskStatus } from './quick-start-types';
3
3
  export interface FooterProps {
4
4
  show?: boolean;
@@ -74,10 +74,10 @@ export declare const QuickStartContextDefaults: {
74
74
  alwaysShowTaskReview: boolean;
75
75
  focusOnQuickStart: boolean;
76
76
  };
77
- export declare const QuickStartContext: React.Context<QuickStartContextValues>;
77
+ export declare const QuickStartContext: import("react").Context<QuickStartContextValues>;
78
78
  export declare const getResource: (resource: string, options: any, resourceBundle: any, lng: string) => any;
79
79
  export declare const useValuesForQuickStartContext: (value?: QuickStartContextValues) => QuickStartContextValues;
80
- export declare const QuickStartContextProvider: React.FC<{
80
+ export declare const QuickStartContextProvider: FC<{
81
81
  children: React.ReactNode;
82
82
  value: QuickStartContextValues;
83
83
  }>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/quickstarts",
3
- "version": "6.3.0-prerelease.1",
3
+ "version": "6.3.0-prerelease.10",
4
4
  "description": "PatternFly quick starts",
5
5
  "files": [
6
6
  "src",
@@ -46,12 +46,12 @@
46
46
  },
47
47
  "peerDependencies": {
48
48
  "@patternfly/react-core": "^6.0.0",
49
- "react": "^17 || ^18",
50
- "react-dom": ">=18.0.0",
49
+ "react": "^17 || ^18 || ^19",
50
+ "react-dom": "^17 || ^18 || ^19",
51
51
  "marked": "^15.0.6"
52
52
  },
53
53
  "dependencies": {
54
- "dompurify": "^3.1.3",
54
+ "dompurify": "^3.2.4",
55
55
  "history": "^5.0.0"
56
56
  },
57
57
  "devDependencies": {
@@ -66,7 +66,7 @@
66
66
  "@rollup/plugin-commonjs": "^17.0.0",
67
67
  "@rollup/plugin-json": "^4.1.0",
68
68
  "@rollup/plugin-node-resolve": "^11.1.0",
69
- "@testing-library/react": "^11.2.2",
69
+ "@testing-library/react": "^13.4.0",
70
70
  "@types/dompurify": "^3.0.5",
71
71
  "@types/enzyme": "^3.10.7",
72
72
  "@types/enzyme-adapter-react-16": "^1.0.6",
@@ -88,7 +88,6 @@
88
88
  "react-axe": "^3.5.4",
89
89
  "react-docgen-typescript-loader": "^3.7.2",
90
90
  "react-dom": "^18.2.0",
91
- "react-monaco-editor": "0.51.0",
92
91
  "regenerator-runtime": "^0.13.7",
93
92
  "rimraf": "^3.0.2",
94
93
  "rollup": "^2.79.2",
@@ -1,4 +1,4 @@
1
- import * as React from 'react';
1
+ import { FC, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
2
2
  import { css } from '@patternfly/react-styles';
3
3
  import { marked } from 'marked';
4
4
  import { useForceRender } from '@console/shared';
@@ -25,7 +25,7 @@ export const markdownConvert = async (markdown: string, extensions?: ShowdownExt
25
25
  return node;
26
26
  }
27
27
 
28
- // add PF content classes
28
+ // add PF content classes to standard elements (details blocks get handled separately)
29
29
  if (node.nodeType === 1) {
30
30
  const contentElements = [
31
31
  'ul',
@@ -85,7 +85,90 @@ export const markdownConvert = async (markdown: string, extensions?: ShowdownExt
85
85
  );
86
86
  const markdownWithSubstitutedCodeFences = reverseString(reverseMarkdownWithSubstitutedCodeFences);
87
87
 
88
- const parsedMarkdown = await marked.parse(markdownWithSubstitutedCodeFences);
88
+ // Fix malformed HTML entities early in the process
89
+ let preprocessedMarkdown = markdownWithSubstitutedCodeFences;
90
+ preprocessedMarkdown = preprocessedMarkdown
91
+ .replace(/&nbsp([^;])/g, '&nbsp;$1')
92
+ .replace(/&amp;nbsp;/g, '&nbsp;');
93
+ preprocessedMarkdown = preprocessedMarkdown.replace(/&nbsp(?![;])/g, '&nbsp;');
94
+
95
+ // Process content in segments to ensure markdown parsing continues after HTML blocks
96
+ const htmlBlockRegex =
97
+ /(<(?:details|div|section|article)[^>]*>[\s\S]*?<\/(?:details|div|section|article)>)/g;
98
+
99
+ let parsedMarkdown = '';
100
+
101
+ // Check if there are any HTML blocks
102
+ if (htmlBlockRegex.test(preprocessedMarkdown)) {
103
+ // Reset regex for actual processing
104
+ htmlBlockRegex.lastIndex = 0;
105
+
106
+ let lastIndex = 0;
107
+ let match;
108
+
109
+ while ((match = htmlBlockRegex.exec(preprocessedMarkdown)) !== null) {
110
+ // Process markdown before the HTML block
111
+ const markdownBefore = preprocessedMarkdown.slice(lastIndex, match.index).trim();
112
+ if (markdownBefore) {
113
+ const parsed = await marked.parse(markdownBefore);
114
+ parsedMarkdown += parsed;
115
+ }
116
+
117
+ // Process the HTML block: parse markdown content inside while preserving HTML structure
118
+ let htmlBlock = match[1];
119
+
120
+ // Find and process markdown content inside HTML tags
121
+ const contentRegex = />(\s*[\s\S]*?)\s*</g;
122
+ const contentMatches = [];
123
+ let contentMatch;
124
+
125
+ while ((contentMatch = contentRegex.exec(htmlBlock)) !== null) {
126
+ const content = contentMatch[1];
127
+ // Only process content that has markdown formatting but no extension syntax
128
+ if (
129
+ content.trim() &&
130
+ !content.includes('{{') &&
131
+ (content.includes('**') || content.includes('- ') || content.includes('\n'))
132
+ ) {
133
+ // This looks like markdown content without extensions - parse it as block content
134
+ const parsedContent = await marked.parse(content.trim());
135
+ // Remove wrapping <p> tags if they exist since we're inside HTML already
136
+ const cleanedContent = parsedContent.replace(/^<p[^>]*>([\s\S]*)<\/p>[\s]*$/g, '$1');
137
+ contentMatches.push({
138
+ original: contentMatch[0],
139
+ replacement: `>${cleanedContent}<`,
140
+ });
141
+ }
142
+ }
143
+
144
+ // Apply the content replacements
145
+ contentMatches.forEach(({ original, replacement }) => {
146
+ htmlBlock = htmlBlock.replace(original, replacement);
147
+ });
148
+
149
+ // Apply extensions (like admonitions) to the processed HTML block
150
+ if (extensions) {
151
+ extensions.forEach(({ regex, replace }) => {
152
+ if (regex) {
153
+ htmlBlock = htmlBlock.replace(regex, replace);
154
+ }
155
+ });
156
+ }
157
+
158
+ parsedMarkdown += htmlBlock;
159
+ lastIndex = htmlBlockRegex.lastIndex;
160
+ }
161
+
162
+ // Process any remaining markdown after the last HTML block
163
+ const markdownAfter = preprocessedMarkdown.slice(lastIndex).trim();
164
+ if (markdownAfter) {
165
+ const parsed = await marked.parse(markdownAfter);
166
+ parsedMarkdown += parsed;
167
+ }
168
+ } else {
169
+ // No HTML blocks found, process normally
170
+ parsedMarkdown = await marked.parse(preprocessedMarkdown);
171
+ }
89
172
  // Swap the temporary tokens back to code fences before we run the extensions
90
173
  let md = parsedMarkdown.replace(/@@@/g, '```');
91
174
 
@@ -93,7 +176,7 @@ export const markdownConvert = async (markdown: string, extensions?: ShowdownExt
93
176
  // Convert code spans back to md format before we run the custom extension regexes
94
177
  md = md.replace(/<code>(.*)<\/code>/g, '`$1`');
95
178
 
96
- extensions.forEach(({ regex, replace }) => {
179
+ extensions.forEach(({ regex, replace }, _index) => {
97
180
  if (regex) {
98
181
  md = md.replace(regex, replace);
99
182
  }
@@ -102,6 +185,7 @@ export const markdownConvert = async (markdown: string, extensions?: ShowdownExt
102
185
  // Convert any remaining backticks back into code spans
103
186
  md = md.replace(/`(.*)`/g, '<code>$1</code>');
104
187
  }
188
+
105
189
  return DOMPurify.sanitize(md);
106
190
  };
107
191
 
@@ -121,7 +205,7 @@ type InnerSyncMarkdownProps = Pick<SyncMarkdownProps, 'renderExtension' | 'exact
121
205
  className?: string;
122
206
  };
123
207
 
124
- export const SyncMarkdownView: React.FC<SyncMarkdownProps> = ({
208
+ export const SyncMarkdownView: FC<SyncMarkdownProps> = ({
125
209
  content,
126
210
  emptyMsg,
127
211
  extensions,
@@ -130,10 +214,10 @@ export const SyncMarkdownView: React.FC<SyncMarkdownProps> = ({
130
214
  inline,
131
215
  className,
132
216
  }) => {
133
- const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
134
- const [markup, setMarkup] = React.useState<string>('');
217
+ const { getResource } = useContext<QuickStartContextValues>(QuickStartContext);
218
+ const [markup, setMarkup] = useState<string>('');
135
219
 
136
- React.useEffect(() => {
220
+ useEffect(() => {
137
221
  async function getMd() {
138
222
  const md = await markdownConvert(
139
223
  content || emptyMsg || getResource('Not available'),
@@ -176,8 +260,8 @@ const RenderExtension: React.FC<RenderExtensionProps> = ({
176
260
  docContext,
177
261
  }) => {
178
262
  const forceRender = useForceRender();
179
- const markupRef = React.useRef<string>(null);
180
- const shouldRenderExtension = React.useCallback(() => {
263
+ const markupRef = useRef<string>(null);
264
+ const shouldRenderExtension = useCallback(() => {
181
265
  if (markupRef.current === markup) {
182
266
  return true;
183
267
  }
@@ -190,7 +274,7 @@ const RenderExtension: React.FC<RenderExtensionProps> = ({
190
274
  * which causes the component rendered by renderExtension to receive old copy of document
191
275
  * use forceRender to delay the rendering of extension by one render cycle
192
276
  */
193
- React.useEffect(() => {
277
+ useEffect(() => {
194
278
  if (renderExtension) {
195
279
  forceRender();
196
280
  }
@@ -201,16 +285,19 @@ const RenderExtension: React.FC<RenderExtensionProps> = ({
201
285
  );
202
286
  };
203
287
 
204
- const InlineMarkdownView: React.FC<InnerSyncMarkdownProps> = ({
288
+ const InlineMarkdownView: FC<InnerSyncMarkdownProps> = ({
205
289
  markup,
206
290
  isEmpty,
207
291
  renderExtension,
208
292
  className,
209
293
  }) => {
210
- const id = React.useMemo(() => uniqueId('markdown'), []);
294
+ const id = useMemo(() => uniqueId('markdown'), []);
211
295
  return (
212
296
  <div className={css({ 'is-empty': isEmpty } as any, className)} id={id}>
213
- <div dangerouslySetInnerHTML={{ __html: markup }} />
297
+ <div
298
+ style={{ marginBlockEnd: 'var(--pf-t-global--spacer--md)' }}
299
+ dangerouslySetInnerHTML={{ __html: markup }}
300
+ />
214
301
  {renderExtension && (
215
302
  <RenderExtension renderExtension={renderExtension} selector={`#${id}`} markup={markup} />
216
303
  )}
@@ -218,18 +305,18 @@ const InlineMarkdownView: React.FC<InnerSyncMarkdownProps> = ({
218
305
  );
219
306
  };
220
307
 
221
- const IFrameMarkdownView: React.FC<InnerSyncMarkdownProps> = ({
308
+ const IFrameMarkdownView: FC<InnerSyncMarkdownProps> = ({
222
309
  exactHeight,
223
310
  markup,
224
311
  isEmpty,
225
312
  renderExtension,
226
313
  className,
227
314
  }) => {
228
- const [frame, setFrame] = React.useState<HTMLIFrameElement>();
229
- const [loaded, setLoaded] = React.useState(false);
230
- const updateTimeoutHandle = React.useRef<NodeJS.Timeout>();
315
+ const [frame, setFrame] = useState<HTMLIFrameElement>();
316
+ const [loaded, setLoaded] = useState(false);
317
+ const updateTimeoutHandle = useRef<NodeJS.Timeout>(null);
231
318
 
232
- const updateDimensions = React.useCallback(() => {
319
+ const updateDimensions = useCallback(() => {
233
320
  if (!frame?.contentWindow?.document.body.firstChild) {
234
321
  return;
235
322
  }
@@ -248,14 +335,14 @@ const IFrameMarkdownView: React.FC<InnerSyncMarkdownProps> = ({
248
335
  });
249
336
  }, [frame, exactHeight]);
250
337
 
251
- React.useEffect(
338
+ useEffect(
252
339
  () => () => {
253
340
  clearTimeout(updateTimeoutHandle.current);
254
341
  },
255
342
  [],
256
343
  );
257
344
 
258
- const onLoad = React.useCallback(() => {
345
+ const onLoad = useCallback(() => {
259
346
  updateDimensions();
260
347
  setLoaded(true);
261
348
  }, [updateDimensions]);
@@ -299,10 +386,13 @@ const IFrameMarkdownView: React.FC<InnerSyncMarkdownProps> = ({
299
386
  return (
300
387
  <>
301
388
  <iframe
389
+ title="Markdown content preview"
302
390
  sandbox="allow-popups allow-popups-to-escape-sandbox allow-same-origin"
303
391
  srcDoc={contents}
304
392
  style={{ border: '0px', display: 'block', width: '100%', height: '0' }}
305
- ref={(r) => setFrame(r)}
393
+ ref={(r) => {
394
+ setFrame(r);
395
+ }}
306
396
  onLoad={() => onLoad()}
307
397
  className={className}
308
398
  />
@@ -1,4 +1,4 @@
1
- import * as React from 'react';
1
+ import { Fragment } from 'react';
2
2
 
3
3
  const MEMO = {};
4
4
 
@@ -16,10 +16,10 @@ export const CamelCaseWrap: React.FC<CamelCaseWrapProps> = ({ value, dataTest })
16
16
  const rendered = (
17
17
  <span data-test={dataTest}>
18
18
  {words.map((word, i) => (
19
- <React.Fragment key={i}>
19
+ <Fragment key={i}>
20
20
  {word}
21
21
  {i !== words.length - 1 && <wbr />}
22
- </React.Fragment>
22
+ </Fragment>
23
23
  ))}
24
24
  </span>
25
25
  );
@@ -1,4 +1,4 @@
1
- import * as React from 'react';
1
+ import { FC, useContext } from 'react';
2
2
  import { css } from '@patternfly/react-styles';
3
3
  import { QuickStartContext, QuickStartContextValues } from '../../../utils/quick-start-context';
4
4
 
@@ -6,7 +6,7 @@ export const Box: React.FC<BoxProps> = ({ children, className }) => (
6
6
  <div className={css('pfext-status-box', className)}>{children}</div>
7
7
  );
8
8
 
9
- export const Loading: React.FC<LoadingProps> = ({ className }) => (
9
+ export const Loading: FC<LoadingProps> = ({ className }) => (
10
10
  <div className={css('pfext-m-loader', className)}>
11
11
  <div className="pfext-m-loader-dot__one" />
12
12
  <div className="pfext-m-loader-dot__two" />
@@ -15,7 +15,7 @@ export const Loading: React.FC<LoadingProps> = ({ className }) => (
15
15
  );
16
16
  Loading.displayName = 'Loading';
17
17
 
18
- export const LoadingBox: React.FC<LoadingBoxProps> = ({ className, message }) => (
18
+ export const LoadingBox: FC<LoadingBoxProps> = ({ className, message }) => (
19
19
  <Box className={css('pfext-status-box--loading', className)}>
20
20
  <Loading />
21
21
  {message && <div className="pfext-status-box__loading-message">{message}</div>}
@@ -24,7 +24,7 @@ export const LoadingBox: React.FC<LoadingBoxProps> = ({ className, message }) =>
24
24
  LoadingBox.displayName = 'LoadingBox';
25
25
 
26
26
  export const EmptyBox: React.FC<EmptyBoxProps> = ({ label }) => {
27
- const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
27
+ const { getResource } = useContext<QuickStartContextValues>(QuickStartContext);
28
28
  return (
29
29
  <Box>
30
30
  <div data-test="empty-message" className="text-center">
@@ -1,4 +1,4 @@
1
- import * as React from 'react';
1
+ import { FC, useCallback, useContext, useMemo, useState } from 'react';
2
2
  import { Tooltip } from '@patternfly/react-core';
3
3
  import { QuickStartContext, QuickStartContextValues } from '@quickstarts/utils/quick-start-context';
4
4
  import { useEventListener } from '../../hooks';
@@ -10,14 +10,10 @@ interface CopyClipboardProps {
10
10
  docContext: Document;
11
11
  }
12
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(() => {
13
+ export const CopyClipboard: FC<CopyClipboardProps> = ({ element, rootSelector, docContext }) => {
14
+ const { getResource } = useContext<QuickStartContextValues>(QuickStartContext);
15
+ const [showSuccessContent, setShowSuccessContent] = useState<boolean>(false);
16
+ const textToCopy = useMemo(() => {
21
17
  const copyTextId = element.getAttribute(MARKDOWN_COPY_BUTTON_ID);
22
18
  return (
23
19
  docContext.querySelector(
@@ -29,7 +25,7 @@ export const CopyClipboard: React.FC<CopyClipboardProps> = ({
29
25
  useEventListener(
30
26
  element,
31
27
  'click',
32
- React.useCallback(() => {
28
+ useCallback(() => {
33
29
  navigator.clipboard
34
30
  .writeText(textToCopy.trim())
35
31
  .then(() => {
@@ -42,7 +38,7 @@ export const CopyClipboard: React.FC<CopyClipboardProps> = ({
42
38
  useEventListener(
43
39
  element,
44
40
  'mouseleave',
45
- React.useCallback(() => {
41
+ useCallback(() => {
46
42
  setShowSuccessContent(false);
47
43
  }, []),
48
44
  );
@@ -70,10 +66,7 @@ interface MarkdownCopyClipboardProps {
70
66
  rootSelector: string;
71
67
  }
72
68
 
73
- const MarkdownCopyClipboard: React.FC<MarkdownCopyClipboardProps> = ({
74
- docContext,
75
- rootSelector,
76
- }) => {
69
+ const MarkdownCopyClipboard: FC<MarkdownCopyClipboardProps> = ({ docContext, rootSelector }) => {
77
70
  const elements = docContext.querySelectorAll(`${rootSelector} [${MARKDOWN_COPY_BUTTON_ID}]`);
78
71
  return elements.length > 0 ? (
79
72
  <>
@@ -1,4 +1,3 @@
1
- import * as React from 'react';
2
1
  import { shallow } from 'enzyme';
3
2
  import MarkdownCopyClipboard, { CopyClipboard } from '../MarkdownCopyClipboard';
4
3
  import { htmlDocumentForCopyClipboard } from './test-data';
@@ -0,0 +1,105 @@
1
+ // Generated by Cursor
2
+ // AI-assisted implementation with human review and modifications
3
+ import { renderHook } from '@testing-library/react';
4
+ import useAccordionShowdownExtension from '../accordion-extension';
5
+ import { ACCORDION_MARKDOWN_BUTTON_ID, ACCORDION_MARKDOWN_CONTENT_ID } from '../const';
6
+ import { marked } from 'marked';
7
+
8
+ // Mock marked
9
+ jest.mock('marked', () => ({
10
+ marked: {
11
+ parseInline: jest.fn((text) => `<em>${text}</em>`),
12
+ },
13
+ }));
14
+
15
+ // Mock DOMPurify
16
+ jest.mock('dompurify', () => ({
17
+ sanitize: jest.fn((html) => html),
18
+ }));
19
+
20
+ describe('useAccordionShowdownExtension', () => {
21
+ beforeEach(() => {
22
+ jest.clearAllMocks();
23
+ });
24
+
25
+ it('should return a showdown extension with correct properties', () => {
26
+ const { result } = renderHook(() => useAccordionShowdownExtension());
27
+ const extension = result.current;
28
+
29
+ expect(extension.type).toBe('lang');
30
+ expect(extension.regex).toEqual(/\[(.+)]{{(accordion) (&quot;(.*?)&quot;)}}/g);
31
+ expect(typeof extension.replace).toBe('function');
32
+ });
33
+
34
+ it('should match accordion syntax with HTML-encoded quotes', () => {
35
+ const { result } = renderHook(() => useAccordionShowdownExtension());
36
+ const { regex } = result.current;
37
+
38
+ const testText = '[Some content]{{accordion &quot;My Title&quot;}}';
39
+ const matches = regex.exec(testText);
40
+
41
+ expect(matches).not.toBeNull();
42
+ if (matches) {
43
+ expect(matches[1]).toBe('Some content');
44
+ expect(matches[2]).toBe('accordion');
45
+ expect(matches[4]).toBe('My Title');
46
+ }
47
+ });
48
+
49
+ it('should not match accordion syntax with regular quotes', () => {
50
+ const { result } = renderHook(() => useAccordionShowdownExtension());
51
+ const { regex } = result.current;
52
+
53
+ const testText = '[Some content]{{accordion "My Title"}}';
54
+ expect(testText.match(regex)).toBeNull();
55
+ });
56
+
57
+ it('should generate correct accordion HTML structure', () => {
58
+ const { result } = renderHook(() => useAccordionShowdownExtension());
59
+ const { replace } = result.current;
60
+
61
+ const html = replace(
62
+ '[Test content]{{accordion &quot;Test Title&quot;}}',
63
+ 'Test content',
64
+ 'accordion',
65
+ '&quot;Test Title&quot;',
66
+ 'Test Title',
67
+ );
68
+
69
+ expect(html).toContain('pf-v6-c-accordion');
70
+ expect(html).toContain('pf-v6-c-accordion__toggle');
71
+ expect(html).toContain(`${ACCORDION_MARKDOWN_BUTTON_ID}-Test-Title`);
72
+ expect(html).toContain(`${ACCORDION_MARKDOWN_CONTENT_ID}-Test-Title`);
73
+ expect(html).toContain('Test Title');
74
+ });
75
+
76
+ it('should process content through marked and sanitize HTML', () => {
77
+ const { result } = renderHook(() => useAccordionShowdownExtension());
78
+ const { replace } = result.current;
79
+
80
+ replace(
81
+ '[**Bold text**]{{accordion &quot;Title&quot;}}',
82
+ '**Bold text**',
83
+ 'accordion',
84
+ '&quot;Title&quot;',
85
+ 'Title',
86
+ );
87
+
88
+ expect(marked.parseInline).toHaveBeenCalledWith('**Bold text**');
89
+ });
90
+
91
+ it('should handle titles with spaces in IDs', () => {
92
+ const { result } = renderHook(() => useAccordionShowdownExtension());
93
+ const { replace } = result.current;
94
+
95
+ const html = replace(
96
+ '[Content]{{accordion &quot;My Test Title&quot;}}',
97
+ 'Content',
98
+ 'accordion',
99
+ '&quot;My Test Title&quot;',
100
+ 'My Test Title',
101
+ );
102
+
103
+ expect(html).toContain(`${ACCORDION_MARKDOWN_BUTTON_ID}-My-Test-Title`);
104
+ });
105
+ });