@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.
- package/dist/ConsoleInternal/components/markdown-view.d.ts +2 -2
- package/dist/ConsoleInternal/components/utils/camel-case-wrap.d.ts +1 -1
- package/dist/ConsoleInternal/components/utils/status-box.d.ts +3 -3
- package/dist/ConsoleShared/src/components/markdown-extensions/MarkdownCopyClipboard.d.ts +3 -3
- package/dist/ConsoleShared/src/components/markdown-extensions/accordion-extension.d.ts +1 -1
- package/dist/ConsoleShared/src/components/markdown-extensions/accordion-render-extension.d.ts +2 -2
- package/dist/ConsoleShared/src/components/markdown-extensions/admonition-extension.d.ts +1 -1
- package/dist/ConsoleShared/src/components/markdown-highlight-extension/MarkdownHighlightExtension.d.ts +2 -2
- package/dist/ConsoleShared/src/components/modal/Modal.d.ts +3 -3
- package/dist/ConsoleShared/src/components/popper/Portal.d.ts +3 -3
- package/dist/ConsoleShared/src/components/popper/SimplePopper.d.ts +3 -3
- package/dist/ConsoleShared/src/components/spotlight/InteractiveSpotlight.d.ts +3 -2
- package/dist/ConsoleShared/src/components/spotlight/Spotlight.d.ts +2 -2
- package/dist/ConsoleShared/src/components/spotlight/StaticSpotlight.d.ts +3 -2
- package/dist/ConsoleShared/src/components/status/GenericStatus.d.ts +4 -4
- package/dist/ConsoleShared/src/components/status/NotStartedIcon.d.ts +1 -2
- package/dist/ConsoleShared/src/components/status/PopoverStatus.d.ts +4 -4
- package/dist/ConsoleShared/src/components/status/Status.d.ts +3 -3
- package/dist/ConsoleShared/src/components/status/StatusIconAndText.d.ts +3 -3
- package/dist/ConsoleShared/src/components/status/icons.d.ts +4 -4
- package/dist/ConsoleShared/src/components/status/statuses.d.ts +4 -4
- package/dist/ConsoleShared/src/components/utils/FallbackImg.d.ts +3 -3
- package/dist/ConsoleShared/src/utils/useCombineRefs.d.ts +2 -2
- package/dist/HelpTopicDrawer.d.ts +3 -3
- package/dist/HelpTopicPanelContent.d.ts +2 -2
- package/dist/QuickStartCatalogPage.d.ts +3 -3
- package/dist/QuickStartCloseModal.d.ts +2 -2
- package/dist/QuickStartContainer.d.ts +2 -2
- package/dist/QuickStartController.d.ts +2 -2
- package/dist/QuickStartDrawer.d.ts +2 -2
- package/dist/QuickStartDrawerContent.d.ts +2 -2
- package/dist/QuickStartMarkdownView.d.ts +2 -2
- package/dist/QuickStartPanelContent.d.ts +2 -2
- package/dist/catalog/Catalog/QuickStartCatalogHeader.d.ts +2 -2
- package/dist/catalog/Catalog/QuickStartCatalogSection.d.ts +2 -2
- package/dist/catalog/Catalog/QuickStartCatalogToolbar.d.ts +2 -2
- package/dist/catalog/QuickStartCatalog.d.ts +2 -2
- package/dist/catalog/QuickStartTile.d.ts +2 -2
- package/dist/catalog/QuickStartTileDescription.d.ts +2 -2
- package/dist/catalog/QuickStartTileFooter.d.ts +2 -2
- package/dist/catalog/QuickStartTileFooterExternal.d.ts +2 -2
- package/dist/catalog/QuickStartTileHeader.d.ts +2 -2
- package/dist/catalog/Toolbar/QuickStartCatalogFilter.d.ts +2 -2
- package/dist/catalog/Toolbar/QuickStartCatalogFilterItems.d.ts +7 -7
- package/dist/controller/QuickStartConclusion.d.ts +2 -2
- package/dist/controller/QuickStartContent.d.ts +2 -2
- package/dist/controller/QuickStartFooter.d.ts +2 -2
- package/dist/controller/QuickStartIntroduction.d.ts +2 -2
- package/dist/controller/QuickStartTaskHeader.d.ts +2 -2
- package/dist/controller/QuickStartTaskHeaderList.d.ts +2 -2
- package/dist/controller/QuickStartTaskReview.d.ts +2 -2
- package/dist/controller/QuickStartTasks.d.ts +2 -2
- package/dist/index.es.js +489 -561
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +500 -574
- package/dist/index.js.map +1 -1
- package/dist/quickstarts-base.css +61 -0
- package/dist/quickstarts-full.es.js +1963 -693
- package/dist/quickstarts-full.es.js.map +1 -1
- package/dist/quickstarts.css +61 -0
- package/dist/quickstarts.min.css +1 -1
- package/dist/utils/help-topic-context.d.ts +2 -2
- package/dist/utils/quick-start-context.d.ts +3 -3
- package/package.json +5 -6
- package/src/ConsoleInternal/components/markdown-view.tsx +112 -22
- package/src/ConsoleInternal/components/utils/camel-case-wrap.tsx +3 -3
- package/src/ConsoleInternal/components/utils/status-box.tsx +4 -4
- package/src/ConsoleShared/src/components/markdown-extensions/MarkdownCopyClipboard.tsx +8 -15
- package/src/ConsoleShared/src/components/markdown-extensions/__tests__/MarkdownCopyClipboard.spec.tsx +0 -1
- package/src/ConsoleShared/src/components/markdown-extensions/__tests__/accordion-extension.spec.tsx +105 -0
- package/src/ConsoleShared/src/components/markdown-extensions/__tests__/admonition-extension.spec.tsx +121 -0
- package/src/ConsoleShared/src/components/markdown-extensions/accordion-extension.tsx +22 -15
- package/src/ConsoleShared/src/components/markdown-extensions/accordion-render-extension.tsx +23 -9
- package/src/ConsoleShared/src/components/markdown-extensions/admonition-extension.tsx +19 -8
- package/src/ConsoleShared/src/components/markdown-extensions/code-extension.tsx +2 -2
- package/src/ConsoleShared/src/components/markdown-extensions/inline-clipboard-extension.tsx +3 -3
- package/src/ConsoleShared/src/components/markdown-extensions/multiline-clipboard-extension.tsx +3 -3
- package/src/ConsoleShared/src/components/markdown-highlight-extension/MarkdownHighlightExtension.tsx +5 -5
- package/src/ConsoleShared/src/components/modal/Modal.tsx +3 -3
- package/src/ConsoleShared/src/components/popper/Portal.tsx +5 -5
- package/src/ConsoleShared/src/components/popper/SimplePopper.tsx +15 -15
- package/src/ConsoleShared/src/components/spotlight/InteractiveSpotlight.tsx +6 -5
- package/src/ConsoleShared/src/components/spotlight/Spotlight.tsx +3 -3
- package/src/ConsoleShared/src/components/spotlight/StaticSpotlight.tsx +4 -3
- package/src/ConsoleShared/src/components/spotlight/spotlight.scss +63 -0
- package/src/ConsoleShared/src/components/status/GenericStatus.tsx +5 -5
- package/src/ConsoleShared/src/components/status/NotStartedIcon.tsx +0 -1
- package/src/ConsoleShared/src/components/status/PopoverStatus.tsx +4 -4
- package/src/ConsoleShared/src/components/status/Status.tsx +3 -11
- package/src/ConsoleShared/src/components/status/StatusIconAndText.tsx +6 -6
- package/src/ConsoleShared/src/components/status/icons.tsx +4 -8
- package/src/ConsoleShared/src/components/status/statuses.tsx +4 -5
- package/src/ConsoleShared/src/components/utils/FallbackImg.tsx +4 -4
- package/src/ConsoleShared/src/hooks/scroll.ts +4 -4
- package/src/ConsoleShared/src/hooks/useBoundingClientRect.ts +3 -3
- package/src/ConsoleShared/src/hooks/useForceRender.ts +2 -2
- package/src/ConsoleShared/src/hooks/useResizeObserver.ts +3 -6
- package/src/ConsoleShared/src/hooks/useScrollShadows.ts +4 -4
- package/src/ConsoleShared/src/utils/useCombineRefs.ts +4 -4
- package/src/HelpTopicDrawer.tsx +6 -6
- package/src/HelpTopicPanelContent.tsx +4 -4
- package/src/QuickStartCatalogPage.tsx +9 -9
- package/src/QuickStartCloseModal.tsx +3 -7
- package/src/QuickStartContainer.tsx +4 -4
- package/src/QuickStartController.tsx +11 -11
- package/src/QuickStartDrawer.tsx +6 -6
- package/src/QuickStartDrawerContent.tsx +6 -4
- package/src/QuickStartMarkdownView.tsx +3 -3
- package/src/QuickStartPanelContent.tsx +8 -8
- package/src/catalog/Catalog/QuickStartCatalogHeader.tsx +2 -2
- package/src/catalog/Catalog/QuickStartCatalogSection.tsx +2 -2
- package/src/catalog/Catalog/QuickStartCatalogToolbar.tsx +2 -2
- package/src/catalog/QuickStartCatalog.tsx +3 -3
- package/src/catalog/QuickStartTile.tsx +4 -4
- package/src/catalog/QuickStartTileDescription.tsx +4 -4
- package/src/catalog/QuickStartTileFooter.tsx +6 -6
- package/src/catalog/QuickStartTileFooterExternal.tsx +2 -5
- package/src/catalog/QuickStartTileHeader.tsx +2 -6
- package/src/catalog/Toolbar/QuickStartCatalogFilter.tsx +2 -2
- package/src/catalog/Toolbar/QuickStartCatalogFilterItems.tsx +17 -20
- package/src/catalog/__tests__/QuickStartCatalog.spec.tsx +0 -1
- package/src/catalog/__tests__/QuickStartTile.spec.tsx +0 -1
- package/src/catalog/__tests__/QuickStartTileDescription.spec.tsx +1 -2
- package/src/controller/QuickStartConclusion.tsx +3 -3
- package/src/controller/QuickStartContent.tsx +2 -2
- package/src/controller/QuickStartFooter.tsx +10 -11
- package/src/controller/QuickStartIntroduction.tsx +5 -5
- package/src/controller/QuickStartTaskHeader.tsx +5 -5
- package/src/controller/QuickStartTaskHeaderList.tsx +2 -2
- package/src/controller/QuickStartTaskReview.tsx +4 -4
- package/src/controller/QuickStartTasks.tsx +5 -5
- package/src/controller/__tests__/QuickStartConclusion.spec.tsx +3 -3
- package/src/controller/__tests__/QuickStartContent.spec.tsx +2 -2
- package/src/controller/__tests__/QuickStartTaskHeader.spec.tsx +2 -2
- package/src/controller/__tests__/QuickStartTaskReview.spec.tsx +2 -2
- package/src/utils/help-topic-context.tsx +7 -10
- package/src/utils/quick-start-context.tsx +11 -11
package/dist/quickstarts.css
CHANGED
|
@@ -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;
|
package/dist/quickstarts.min.css
CHANGED
|
@@ -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
|
-
|
|
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:
|
|
22
|
+
export declare const HelpTopicContext: import("react").Context<HelpTopicContextValues>;
|
|
23
23
|
export declare const useValuesForHelpTopicContext: (value?: HelpTopicContextValues) => HelpTopicContextValues;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
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:
|
|
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:
|
|
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.
|
|
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": "
|
|
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.
|
|
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": "^
|
|
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
|
|
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
|
-
|
|
88
|
+
// Fix malformed HTML entities early in the process
|
|
89
|
+
let preprocessedMarkdown = markdownWithSubstitutedCodeFences;
|
|
90
|
+
preprocessedMarkdown = preprocessedMarkdown
|
|
91
|
+
.replace(/ ([^;])/g, ' $1')
|
|
92
|
+
.replace(/&nbsp;/g, ' ');
|
|
93
|
+
preprocessedMarkdown = preprocessedMarkdown.replace(/ (?![;])/g, ' ');
|
|
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:
|
|
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 } =
|
|
134
|
-
const [markup, setMarkup] =
|
|
217
|
+
const { getResource } = useContext<QuickStartContextValues>(QuickStartContext);
|
|
218
|
+
const [markup, setMarkup] = useState<string>('');
|
|
135
219
|
|
|
136
|
-
|
|
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 =
|
|
180
|
-
const shouldRenderExtension =
|
|
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
|
-
|
|
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:
|
|
288
|
+
const InlineMarkdownView: FC<InnerSyncMarkdownProps> = ({
|
|
205
289
|
markup,
|
|
206
290
|
isEmpty,
|
|
207
291
|
renderExtension,
|
|
208
292
|
className,
|
|
209
293
|
}) => {
|
|
210
|
-
const id =
|
|
294
|
+
const id = useMemo(() => uniqueId('markdown'), []);
|
|
211
295
|
return (
|
|
212
296
|
<div className={css({ 'is-empty': isEmpty } as any, className)} id={id}>
|
|
213
|
-
<div
|
|
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:
|
|
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] =
|
|
229
|
-
const [loaded, setLoaded] =
|
|
230
|
-
const updateTimeoutHandle =
|
|
315
|
+
const [frame, setFrame] = useState<HTMLIFrameElement>();
|
|
316
|
+
const [loaded, setLoaded] = useState(false);
|
|
317
|
+
const updateTimeoutHandle = useRef<NodeJS.Timeout>(null);
|
|
231
318
|
|
|
232
|
-
const updateDimensions =
|
|
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
|
-
|
|
338
|
+
useEffect(
|
|
252
339
|
() => () => {
|
|
253
340
|
clearTimeout(updateTimeoutHandle.current);
|
|
254
341
|
},
|
|
255
342
|
[],
|
|
256
343
|
);
|
|
257
344
|
|
|
258
|
-
const onLoad =
|
|
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) =>
|
|
393
|
+
ref={(r) => {
|
|
394
|
+
setFrame(r);
|
|
395
|
+
}}
|
|
306
396
|
onLoad={() => onLoad()}
|
|
307
397
|
className={className}
|
|
308
398
|
/>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
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
|
-
<
|
|
19
|
+
<Fragment key={i}>
|
|
20
20
|
{word}
|
|
21
21
|
{i !== words.length - 1 && <wbr />}
|
|
22
|
-
</
|
|
22
|
+
</Fragment>
|
|
23
23
|
))}
|
|
24
24
|
</span>
|
|
25
25
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
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:
|
|
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:
|
|
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 } =
|
|
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
|
|
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:
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
<>
|
package/src/ConsoleShared/src/components/markdown-extensions/__tests__/accordion-extension.spec.tsx
ADDED
|
@@ -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) ("(.*?)")}}/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 "My Title"}}';
|
|
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 "Test Title"}}',
|
|
63
|
+
'Test content',
|
|
64
|
+
'accordion',
|
|
65
|
+
'"Test Title"',
|
|
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 "Title"}}',
|
|
82
|
+
'**Bold text**',
|
|
83
|
+
'accordion',
|
|
84
|
+
'"Title"',
|
|
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 "My Test Title"}}',
|
|
97
|
+
'Content',
|
|
98
|
+
'accordion',
|
|
99
|
+
'"My Test Title"',
|
|
100
|
+
'My Test Title',
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
expect(html).toContain(`${ACCORDION_MARKDOWN_BUTTON_ID}-My-Test-Title`);
|
|
104
|
+
});
|
|
105
|
+
});
|