@patternfly/quickstarts 6.3.0-prerelease.5 → 6.3.0-prerelease.7

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/index.js CHANGED
@@ -1191,6 +1191,155 @@ const useMultilineCopyClipboardShowdownExtension = () => {
1191
1191
  }), [getResource]);
1192
1192
  };
1193
1193
 
1194
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
1195
+ const DOMPurify$2 = require('dompurify');
1196
+ var AdmonitionType;
1197
+ (function (AdmonitionType) {
1198
+ AdmonitionType["TIP"] = "TIP";
1199
+ AdmonitionType["NOTE"] = "NOTE";
1200
+ AdmonitionType["IMPORTANT"] = "IMPORTANT";
1201
+ AdmonitionType["WARNING"] = "WARNING";
1202
+ AdmonitionType["CAUTION"] = "CAUTION";
1203
+ })(AdmonitionType || (AdmonitionType = {}));
1204
+ const admonitionToAlertVariantMap = {
1205
+ [AdmonitionType.NOTE]: { variant: 'info' },
1206
+ [AdmonitionType.TIP]: { variant: 'custom', customIcon: jsxRuntime.jsx(LightbulbIcon__default["default"], {}) },
1207
+ [AdmonitionType.IMPORTANT]: { variant: 'danger' },
1208
+ [AdmonitionType.CAUTION]: { variant: 'warning', customIcon: jsxRuntime.jsx(FireIcon__default["default"], {}) },
1209
+ [AdmonitionType.WARNING]: { variant: 'warning' },
1210
+ };
1211
+ const useAdmonitionShowdownExtension = () =>
1212
+ // const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
1213
+ react.useMemo(() => ({
1214
+ type: 'lang',
1215
+ regex: /\[(.+)]{{(admonition) ([\w-]+)}}/g,
1216
+ replace: (text, content, admonitionLabel, admonitionType) => {
1217
+ if (!content || !admonitionLabel || !admonitionType) {
1218
+ return text;
1219
+ }
1220
+ if (admonitionLabel !== 'admonition') {
1221
+ return text;
1222
+ }
1223
+ admonitionType = admonitionType.toUpperCase();
1224
+ // Process markdown content directly using marked
1225
+ const processedContent = marked.marked.parseInline(content);
1226
+ const sanitizedContent = DOMPurify$2.sanitize(processedContent);
1227
+ // Handle unknown admonition types by defaulting to NOTE
1228
+ const admonitionConfig = admonitionToAlertVariantMap[admonitionType] || admonitionToAlertVariantMap.NOTE;
1229
+ const { variant, customIcon } = admonitionConfig;
1230
+ const pfAlert = (jsxRuntime.jsx(reactCore.Alert, Object.assign({ variant: variant }, (customIcon && { customIcon }), { isInline: true, title: admonitionType, className: "pfext-markdown-admonition" }, { children: jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: sanitizedContent } }) })));
1231
+ return removeTemplateWhitespace(server.renderToStaticMarkup(pfAlert));
1232
+ },
1233
+ }), []);
1234
+
1235
+ const useCodeShowdownExtension = () => react.useMemo(() => ({
1236
+ type: 'output',
1237
+ regex: /<pre><code>(.*?)\n?<\/code><\/pre>/g,
1238
+ replace: (text, content) => {
1239
+ if (!content) {
1240
+ return text;
1241
+ }
1242
+ const pfCodeBlock = jsxRuntime.jsx(reactCore.CodeBlock, { children: content });
1243
+ return removeTemplateWhitespace(server.renderToStaticMarkup(pfCodeBlock));
1244
+ },
1245
+ }), []);
1246
+
1247
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
1248
+ const DOMPurify$1 = require('dompurify');
1249
+ const useAccordionShowdownExtension = () => react.useMemo(() => ({
1250
+ type: 'lang',
1251
+ regex: /\[(.+)]{{(accordion) (&quot;(.*?)&quot;)}}/g,
1252
+ replace: (_text, accordionContent, _command, _quotedHeading, accordionHeading) => {
1253
+ const accordionId = String(accordionHeading).replace(/\s/g, '-');
1254
+ // Process accordion content with markdown
1255
+ const processedContent = marked.marked.parseInline(accordionContent);
1256
+ const sanitizedContent = DOMPurify$1.sanitize(processedContent);
1257
+ return removeTemplateWhitespace(server.renderToStaticMarkup(jsxRuntime.jsx(reactCore.Accordion, { children: jsxRuntime.jsxs(reactCore.AccordionItem, { children: [jsxRuntime.jsx(reactCore.AccordionToggle, Object.assign({ id: `${ACCORDION_MARKDOWN_BUTTON_ID}-${accordionId}` }, { children: accordionHeading })), jsxRuntime.jsx(reactCore.AccordionContent, Object.assign({ id: `${ACCORDION_MARKDOWN_CONTENT_ID}-${accordionId}`, hidden: true }, { children: jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: sanitizedContent } }) }))] }) })));
1258
+ },
1259
+ }), []);
1260
+
1261
+ const AccordionShowdownHandler = ({ buttonElement, contentElement, }) => {
1262
+ const [expanded, setExpanded] = react.useState(false);
1263
+ const handleClick = () => {
1264
+ const newExpanded = !expanded;
1265
+ const expandedModifier = 'pf-m-expanded';
1266
+ // Find the accordion item element (parent of the button)
1267
+ const accordionItem = buttonElement.closest('.pf-v6-c-accordion__item');
1268
+ // Update button - both visual state and aria-expanded
1269
+ buttonElement.className = `pf-v6-c-accordion__toggle ${newExpanded ? expandedModifier : ''}`;
1270
+ buttonElement.setAttribute('aria-expanded', newExpanded.toString());
1271
+ // Update content - both visual state and hidden attribute
1272
+ contentElement.hidden = !newExpanded;
1273
+ contentElement.className = `pf-v6-c-accordion__expandable-content ${newExpanded ? expandedModifier : ''}`;
1274
+ // Update accordion item
1275
+ if (accordionItem) {
1276
+ accordionItem.className = `pf-v6-c-accordion__item ${newExpanded ? expandedModifier : ''}`;
1277
+ }
1278
+ setExpanded(newExpanded);
1279
+ };
1280
+ useEventListener(buttonElement, 'click', handleClick);
1281
+ return jsxRuntime.jsx(jsxRuntime.Fragment, {});
1282
+ };
1283
+ const AccordionRenderExtension = ({ docContext }) => {
1284
+ const buttonElements = docContext.querySelectorAll(`[id ^= ${ACCORDION_MARKDOWN_BUTTON_ID}]`);
1285
+ const contentElements = docContext.querySelectorAll(`[id ^= ${ACCORDION_MARKDOWN_CONTENT_ID}]`);
1286
+ return buttonElements.length > 0 ? (jsxRuntime.jsx(jsxRuntime.Fragment, { children: Array.from(buttonElements).map((elm) => {
1287
+ const content = Array.from(contentElements).find((elm2) => {
1288
+ const elmId = elm.id.split(ACCORDION_MARKDOWN_BUTTON_ID)[1];
1289
+ const elm2Id = elm2.id.split(ACCORDION_MARKDOWN_CONTENT_ID)[1];
1290
+ return elmId === elm2Id;
1291
+ });
1292
+ return (jsxRuntime.jsx(AccordionShowdownHandler, { buttonElement: elm, contentElement: content }, elm.id.split(ACCORDION_MARKDOWN_BUTTON_ID)[1]));
1293
+ }) })) : null;
1294
+ };
1295
+
1296
+ const FallbackImg = ({ src, alt, className, fallback }) => {
1297
+ const [isSrcValid, setIsSrcValid] = react.useState(true);
1298
+ if (src && isSrcValid) {
1299
+ return jsxRuntime.jsx("img", { className: className, src: src, alt: alt, onError: () => setIsSrcValid(false) });
1300
+ }
1301
+ return jsxRuntime.jsx(jsxRuntime.Fragment, { children: fallback });
1302
+ };
1303
+
1304
+ const DASH = '-';
1305
+
1306
+ const PopoverStatus = ({ hideHeader, children, isVisible = null, statusBody, title, onHide, onShow, }) => (jsxRuntime.jsx(reactCore.Popover, Object.assign({ position: reactCore.PopoverPosition.right, headerContent: hideHeader ? null : title, bodyContent: children, "aria-label": title, onHide: onHide, onShow: onShow, isVisible: isVisible }, { children: jsxRuntime.jsx(reactCore.Button, Object.assign({ variant: "link", isInline: true }, { children: statusBody })) })));
1307
+
1308
+ const StatusIconAndText = ({ icon, title, spin, iconOnly, noTooltip, className, }) => {
1309
+ if (!title) {
1310
+ return jsxRuntime.jsx(jsxRuntime.Fragment, { children: DASH });
1311
+ }
1312
+ return (jsxRuntime.jsxs("span", Object.assign({ className: reactStyles.css('pfext-icon-and-text', className), title: iconOnly && !noTooltip ? title : undefined }, { children: [icon &&
1313
+ react.cloneElement(icon, {
1314
+ className: reactStyles.css(spin && 'fa-spin', icon.props.className, !iconOnly && 'pfext-icon-and-text__icon pfext-icon-flex-child'),
1315
+ }), !iconOnly && jsxRuntime.jsx(CamelCaseWrap, { value: title, dataTest: "status-text" })] })));
1316
+ };
1317
+
1318
+ const GenericStatus = (props) => {
1319
+ const { Icon, children, popoverTitle, title, noTooltip, iconOnly } = props, restProps = tslib.__rest(props, ["Icon", "children", "popoverTitle", "title", "noTooltip", "iconOnly"]);
1320
+ const renderIcon = iconOnly && !noTooltip ? jsxRuntime.jsx(Icon, { title: title }) : jsxRuntime.jsx(Icon, {});
1321
+ const statusBody = (jsxRuntime.jsx(StatusIconAndText, Object.assign({}, restProps, { noTooltip: noTooltip, title: title, iconOnly: iconOnly, icon: renderIcon })));
1322
+ return react.Children.toArray(children).length ? (jsxRuntime.jsx(PopoverStatus, Object.assign({ title: popoverTitle || title }, restProps, { statusBody: statusBody }, { children: children }))) : (statusBody);
1323
+ };
1324
+
1325
+ const GreenCheckCircleIcon = ({ className, title, size }) => (jsxRuntime.jsx(reactCore.Icon, Object.assign({ size: size, status: "success" }, { children: jsxRuntime.jsx(CheckCircleIcon__default["default"], { "data-test": "success-icon", className: className, title: title }) })));
1326
+
1327
+ const SuccessStatus = (props) => (jsxRuntime.jsx(GenericStatus, Object.assign({}, props, { Icon: GreenCheckCircleIcon, title: props.title || 'Healthy' })));
1328
+ SuccessStatus.displayName = 'SuccessStatus';
1329
+
1330
+ const Status = ({ status, title, iconOnly, noTooltip, className }) => {
1331
+ const statusProps = { title: title || status, iconOnly, noTooltip, className };
1332
+ switch (status) {
1333
+ case 'In Progress':
1334
+ return jsxRuntime.jsx(StatusIconAndText, Object.assign({}, statusProps, { icon: jsxRuntime.jsx(SyncAltIcon__default["default"], {}) }));
1335
+ case 'Complete':
1336
+ return jsxRuntime.jsx(SuccessStatus, Object.assign({}, statusProps));
1337
+ default:
1338
+ return jsxRuntime.jsx(jsxRuntime.Fragment, { children: status || DASH });
1339
+ }
1340
+ };
1341
+ const StatusIcon = ({ status }) => jsxRuntime.jsx(Status, { status: status, iconOnly: true });
1342
+
1194
1343
  // eslint-disable-next-line @typescript-eslint/no-require-imports
1195
1344
  const DOMPurify = require('dompurify');
1196
1345
  const markdownConvert = (markdown, extensions) => tslib.__awaiter(void 0, void 0, void 0, function* () {
@@ -1202,7 +1351,7 @@ const markdownConvert = (markdown, extensions) => tslib.__awaiter(void 0, void 0
1202
1351
  node.setAttribute('rel', 'noopener noreferrer');
1203
1352
  return node;
1204
1353
  }
1205
- // add PF content classes
1354
+ // add PF content classes to standard elements (details blocks get handled separately)
1206
1355
  if (node.nodeType === 1) {
1207
1356
  const contentElements = [
1208
1357
  'ul',
@@ -1253,13 +1402,82 @@ const markdownConvert = (markdown, extensions) => tslib.__awaiter(void 0, void 0
1253
1402
  const reversedMarkdown = reverseString(markdown);
1254
1403
  const reverseMarkdownWithSubstitutedCodeFences = reversedMarkdown.replace(/{{```((.|\n)*?)```/g, '{{@@@$1@@@');
1255
1404
  const markdownWithSubstitutedCodeFences = reverseString(reverseMarkdownWithSubstitutedCodeFences);
1256
- const parsedMarkdown = yield marked.marked.parse(markdownWithSubstitutedCodeFences);
1405
+ // Fix malformed HTML entities early in the process
1406
+ let preprocessedMarkdown = markdownWithSubstitutedCodeFences;
1407
+ preprocessedMarkdown = preprocessedMarkdown
1408
+ .replace(/&nbsp([^;])/g, '&nbsp;$1')
1409
+ .replace(/&amp;nbsp;/g, '&nbsp;');
1410
+ preprocessedMarkdown = preprocessedMarkdown.replace(/&nbsp(?![;])/g, '&nbsp;');
1411
+ // Process content in segments to ensure markdown parsing continues after HTML blocks
1412
+ const htmlBlockRegex = /(<(?:details|div|section|article)[^>]*>[\s\S]*?<\/(?:details|div|section|article)>)/g;
1413
+ let parsedMarkdown = '';
1414
+ // Check if there are any HTML blocks
1415
+ if (htmlBlockRegex.test(preprocessedMarkdown)) {
1416
+ // Reset regex for actual processing
1417
+ htmlBlockRegex.lastIndex = 0;
1418
+ let lastIndex = 0;
1419
+ let match;
1420
+ while ((match = htmlBlockRegex.exec(preprocessedMarkdown)) !== null) {
1421
+ // Process markdown before the HTML block
1422
+ const markdownBefore = preprocessedMarkdown.slice(lastIndex, match.index).trim();
1423
+ if (markdownBefore) {
1424
+ const parsed = yield marked.marked.parse(markdownBefore);
1425
+ parsedMarkdown += parsed;
1426
+ }
1427
+ // Process the HTML block: parse markdown content inside while preserving HTML structure
1428
+ let htmlBlock = match[1];
1429
+ // Find and process markdown content inside HTML tags
1430
+ const contentRegex = />(\s*[\s\S]*?)\s*</g;
1431
+ const contentMatches = [];
1432
+ let contentMatch;
1433
+ while ((contentMatch = contentRegex.exec(htmlBlock)) !== null) {
1434
+ const content = contentMatch[1];
1435
+ // Only process content that has markdown formatting but no extension syntax
1436
+ if (content.trim() &&
1437
+ !content.includes('{{') &&
1438
+ (content.includes('**') || content.includes('- ') || content.includes('\n'))) {
1439
+ // This looks like markdown content without extensions - parse it as block content
1440
+ const parsedContent = yield marked.marked.parse(content.trim());
1441
+ // Remove wrapping <p> tags if they exist since we're inside HTML already
1442
+ const cleanedContent = parsedContent.replace(/^<p[^>]*>([\s\S]*)<\/p>[\s]*$/g, '$1');
1443
+ contentMatches.push({
1444
+ original: contentMatch[0],
1445
+ replacement: `>${cleanedContent}<`,
1446
+ });
1447
+ }
1448
+ }
1449
+ // Apply the content replacements
1450
+ contentMatches.forEach(({ original, replacement }) => {
1451
+ htmlBlock = htmlBlock.replace(original, replacement);
1452
+ });
1453
+ // Apply extensions (like admonitions) to the processed HTML block
1454
+ if (extensions) {
1455
+ extensions.forEach(({ regex, replace }) => {
1456
+ if (regex) {
1457
+ htmlBlock = htmlBlock.replace(regex, replace);
1458
+ }
1459
+ });
1460
+ }
1461
+ parsedMarkdown += htmlBlock;
1462
+ lastIndex = htmlBlockRegex.lastIndex;
1463
+ }
1464
+ // Process any remaining markdown after the last HTML block
1465
+ const markdownAfter = preprocessedMarkdown.slice(lastIndex).trim();
1466
+ if (markdownAfter) {
1467
+ const parsed = yield marked.marked.parse(markdownAfter);
1468
+ parsedMarkdown += parsed;
1469
+ }
1470
+ }
1471
+ else {
1472
+ // No HTML blocks found, process normally
1473
+ parsedMarkdown = yield marked.marked.parse(preprocessedMarkdown);
1474
+ }
1257
1475
  // Swap the temporary tokens back to code fences before we run the extensions
1258
1476
  let md = parsedMarkdown.replace(/@@@/g, '```');
1259
1477
  if (extensions) {
1260
1478
  // Convert code spans back to md format before we run the custom extension regexes
1261
1479
  md = md.replace(/<code>(.*)<\/code>/g, '`$1`');
1262
- extensions.forEach(({ regex, replace }) => {
1480
+ extensions.forEach(({ regex, replace }, _index) => {
1263
1481
  if (regex) {
1264
1482
  md = md.replace(regex, replace);
1265
1483
  }
@@ -1324,7 +1542,7 @@ const RenderExtension = ({ renderExtension, selector, markup, docContext, }) =>
1324
1542
  };
1325
1543
  const InlineMarkdownView = ({ markup, isEmpty, renderExtension, className, }) => {
1326
1544
  const id = react.useMemo(() => uniqueId('markdown'), []);
1327
- return (jsxRuntime.jsxs("div", Object.assign({ className: reactStyles.css({ 'is-empty': isEmpty }, className), id: id }, { children: [jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: markup } }), renderExtension && (jsxRuntime.jsx(RenderExtension, { renderExtension: renderExtension, selector: `#${id}`, markup: markup }))] })));
1545
+ return (jsxRuntime.jsxs("div", Object.assign({ className: reactStyles.css({ 'is-empty': isEmpty }, className), id: id }, { children: [jsxRuntime.jsx("div", { style: { marginBlockEnd: 'var(--pf-t-global--spacer--md)' }, dangerouslySetInnerHTML: { __html: markup } }), renderExtension && (jsxRuntime.jsx(RenderExtension, { renderExtension: renderExtension, selector: `#${id}`, markup: markup }))] })));
1328
1546
  };
1329
1547
  const IFrameMarkdownView = ({ exactHeight, markup, isEmpty, renderExtension, className, }) => {
1330
1548
  const [frame, setFrame] = react.useState();
@@ -1383,7 +1601,7 @@ const IFrameMarkdownView = ({ exactHeight, markup, isEmpty, renderExtension, cla
1383
1601
  }
1384
1602
  </style>
1385
1603
  <body class="pf-m-redhat-font"><div style="overflow-y: auto;">${markup}</div></body>`;
1386
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("iframe", { sandbox: "allow-popups allow-popups-to-escape-sandbox allow-same-origin", srcDoc: contents, style: { border: '0px', display: 'block', width: '100%', height: '0' }, ref: (r) => {
1604
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("iframe", { title: "Markdown content preview", sandbox: "allow-popups allow-popups-to-escape-sandbox allow-same-origin", srcDoc: contents, style: { border: '0px', display: 'block', width: '100%', height: '0' }, ref: (r) => {
1387
1605
  setFrame(r);
1388
1606
  }, onLoad: () => onLoad(), className: className }), loaded && frame && renderExtension && (jsxRuntime.jsx(RenderExtension, { markup: markup, selector: '', renderExtension: renderExtension, docContext: frame.contentDocument }))] }));
1389
1607
  };
@@ -1431,131 +1649,6 @@ const QuickStartMarkdownView = ({ content, exactHeight, className, }) => {
1431
1649
  markdown.renderExtension(docContext, rootSelector)] })), className: className }));
1432
1650
  };
1433
1651
 
1434
- var AdmonitionType;
1435
- (function (AdmonitionType) {
1436
- AdmonitionType["TIP"] = "TIP";
1437
- AdmonitionType["NOTE"] = "NOTE";
1438
- AdmonitionType["IMPORTANT"] = "IMPORTANT";
1439
- AdmonitionType["WARNING"] = "WARNING";
1440
- AdmonitionType["CAUTION"] = "CAUTION";
1441
- })(AdmonitionType || (AdmonitionType = {}));
1442
- const admonitionToAlertVariantMap = {
1443
- [AdmonitionType.NOTE]: { variant: 'info' },
1444
- [AdmonitionType.TIP]: { variant: 'custom', customIcon: jsxRuntime.jsx(LightbulbIcon__default["default"], {}) },
1445
- [AdmonitionType.IMPORTANT]: { variant: 'danger' },
1446
- [AdmonitionType.CAUTION]: { variant: 'warning', customIcon: jsxRuntime.jsx(FireIcon__default["default"], {}) },
1447
- [AdmonitionType.WARNING]: { variant: 'warning' },
1448
- };
1449
- const useAdmonitionShowdownExtension = () =>
1450
- // const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
1451
- react.useMemo(() => ({
1452
- type: 'lang',
1453
- regex: /\[(.+)]{{(admonition) ([\w-]+)}}/g,
1454
- replace: (text, content, admonitionLabel, admonitionType, groupId) => {
1455
- if (!content || !admonitionLabel || !admonitionType || !groupId) {
1456
- return text;
1457
- }
1458
- admonitionType = admonitionType.toUpperCase();
1459
- const { variant, customIcon } = admonitionToAlertVariantMap[admonitionType];
1460
- const mdContent = jsxRuntime.jsx(QuickStartMarkdownView, { content: content });
1461
- const pfAlert = (jsxRuntime.jsx(reactCore.Alert, Object.assign({ variant: variant }, (customIcon && { customIcon }), { isInline: true, title: admonitionType, className: "pfext-markdown-admonition" }, { children: mdContent })));
1462
- return removeTemplateWhitespace(server.renderToStaticMarkup(pfAlert));
1463
- },
1464
- }), []);
1465
-
1466
- const useCodeShowdownExtension = () => react.useMemo(() => ({
1467
- type: 'output',
1468
- regex: /<pre><code>(.*?)\n?<\/code><\/pre>/g,
1469
- replace: (text, content) => {
1470
- if (!content) {
1471
- return text;
1472
- }
1473
- const pfCodeBlock = jsxRuntime.jsx(reactCore.CodeBlock, { children: content });
1474
- return removeTemplateWhitespace(server.renderToStaticMarkup(pfCodeBlock));
1475
- },
1476
- }), []);
1477
-
1478
- const useAccordionShowdownExtension = () => react.useMemo(() => ({
1479
- type: 'lang',
1480
- regex: /\[(.+)]{{(accordion) ("(.*?)")}}/g,
1481
- replace: (_text, accordionContent, _command, accordionHeading) => {
1482
- const accordionId = String(accordionHeading).replace(/\s/g, '-');
1483
- return removeTemplateWhitespace(server.renderToStaticMarkup(jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsx(reactCore.Accordion, Object.assign({ asDefinitionList: true }, { children: jsxRuntime.jsxs(reactCore.AccordionItem, Object.assign({ isExpanded: false }, { children: [jsxRuntime.jsx(reactCore.AccordionToggle, Object.assign({ id: `${ACCORDION_MARKDOWN_BUTTON_ID}-${accordionId}` }, { children: accordionHeading })), jsxRuntime.jsx(reactCore.AccordionContent, Object.assign({ id: `${ACCORDION_MARKDOWN_CONTENT_ID}-${accordionId}` }, { children: accordionContent }))] })) })) })));
1484
- },
1485
- }), []);
1486
-
1487
- const AccordionShowdownHandler = ({ buttonElement, contentElement, }) => {
1488
- const [expanded, setExpanded] = react.useState(false);
1489
- const handleClick = () => {
1490
- const expandedModifier = 'pf-m-expanded';
1491
- buttonElement.className = `pf-v6-c-accordion__toggle ${!expanded ? expandedModifier : ''}`;
1492
- contentElement.hidden = expanded;
1493
- contentElement.className = `pf-v6-c-accordion__expanded-content ${!expanded ? expandedModifier : ''}`;
1494
- setExpanded(!expanded);
1495
- };
1496
- useEventListener(buttonElement, 'click', handleClick);
1497
- return jsxRuntime.jsx(jsxRuntime.Fragment, {});
1498
- };
1499
- const AccordionRenderExtension = ({ docContext }) => {
1500
- const buttonElements = docContext.querySelectorAll(`[id ^= ${ACCORDION_MARKDOWN_BUTTON_ID}]`);
1501
- const contentElements = docContext.querySelectorAll(`[id ^= ${ACCORDION_MARKDOWN_CONTENT_ID}]`);
1502
- return buttonElements.length > 0 ? (jsxRuntime.jsx(jsxRuntime.Fragment, { children: Array.from(buttonElements).map((elm) => {
1503
- const content = Array.from(contentElements).find((elm2) => {
1504
- const elmId = elm.id.split(ACCORDION_MARKDOWN_BUTTON_ID)[1];
1505
- const elm2Id = elm2.id.split(ACCORDION_MARKDOWN_CONTENT_ID)[1];
1506
- return elmId === elm2Id;
1507
- });
1508
- return (jsxRuntime.jsx(AccordionShowdownHandler, { buttonElement: elm, contentElement: content }, elm.id.split(ACCORDION_MARKDOWN_BUTTON_ID)[1]));
1509
- }) })) : null;
1510
- };
1511
-
1512
- const FallbackImg = ({ src, alt, className, fallback }) => {
1513
- const [isSrcValid, setIsSrcValid] = react.useState(true);
1514
- if (src && isSrcValid) {
1515
- return jsxRuntime.jsx("img", { className: className, src: src, alt: alt, onError: () => setIsSrcValid(false) });
1516
- }
1517
- return jsxRuntime.jsx(jsxRuntime.Fragment, { children: fallback });
1518
- };
1519
-
1520
- const DASH = '-';
1521
-
1522
- const PopoverStatus = ({ hideHeader, children, isVisible = null, statusBody, title, onHide, onShow, }) => (jsxRuntime.jsx(reactCore.Popover, Object.assign({ position: reactCore.PopoverPosition.right, headerContent: hideHeader ? null : title, bodyContent: children, "aria-label": title, onHide: onHide, onShow: onShow, isVisible: isVisible }, { children: jsxRuntime.jsx(reactCore.Button, Object.assign({ variant: "link", isInline: true }, { children: statusBody })) })));
1523
-
1524
- const StatusIconAndText = ({ icon, title, spin, iconOnly, noTooltip, className, }) => {
1525
- if (!title) {
1526
- return jsxRuntime.jsx(jsxRuntime.Fragment, { children: DASH });
1527
- }
1528
- return (jsxRuntime.jsxs("span", Object.assign({ className: reactStyles.css('pfext-icon-and-text', className), title: iconOnly && !noTooltip ? title : undefined }, { children: [icon &&
1529
- react.cloneElement(icon, {
1530
- className: reactStyles.css(spin && 'fa-spin', icon.props.className, !iconOnly && 'pfext-icon-and-text__icon pfext-icon-flex-child'),
1531
- }), !iconOnly && jsxRuntime.jsx(CamelCaseWrap, { value: title, dataTest: "status-text" })] })));
1532
- };
1533
-
1534
- const GenericStatus = (props) => {
1535
- const { Icon, children, popoverTitle, title, noTooltip, iconOnly } = props, restProps = tslib.__rest(props, ["Icon", "children", "popoverTitle", "title", "noTooltip", "iconOnly"]);
1536
- const renderIcon = iconOnly && !noTooltip ? jsxRuntime.jsx(Icon, { title: title }) : jsxRuntime.jsx(Icon, {});
1537
- const statusBody = (jsxRuntime.jsx(StatusIconAndText, Object.assign({}, restProps, { noTooltip: noTooltip, title: title, iconOnly: iconOnly, icon: renderIcon })));
1538
- return react.Children.toArray(children).length ? (jsxRuntime.jsx(PopoverStatus, Object.assign({ title: popoverTitle || title }, restProps, { statusBody: statusBody }, { children: children }))) : (statusBody);
1539
- };
1540
-
1541
- const GreenCheckCircleIcon = ({ className, title, size }) => (jsxRuntime.jsx(reactCore.Icon, Object.assign({ size: size, status: "success" }, { children: jsxRuntime.jsx(CheckCircleIcon__default["default"], { "data-test": "success-icon", className: className, title: title }) })));
1542
-
1543
- const SuccessStatus = (props) => (jsxRuntime.jsx(GenericStatus, Object.assign({}, props, { Icon: GreenCheckCircleIcon, title: props.title || 'Healthy' })));
1544
- SuccessStatus.displayName = 'SuccessStatus';
1545
-
1546
- const Status = ({ status, title, iconOnly, noTooltip, className }) => {
1547
- const statusProps = { title: title || status, iconOnly, noTooltip, className };
1548
- switch (status) {
1549
- case 'In Progress':
1550
- return jsxRuntime.jsx(StatusIconAndText, Object.assign({}, statusProps, { icon: jsxRuntime.jsx(SyncAltIcon__default["default"], {}) }));
1551
- case 'Complete':
1552
- return jsxRuntime.jsx(SuccessStatus, Object.assign({}, statusProps));
1553
- default:
1554
- return jsxRuntime.jsx(jsxRuntime.Fragment, { children: status || DASH });
1555
- }
1556
- };
1557
- const StatusIcon = ({ status }) => jsxRuntime.jsx(Status, { status: status, iconOnly: true });
1558
-
1559
1652
  const QuickStartTileDescription = ({ description, prerequisites, }) => {
1560
1653
  const { getResource } = react.useContext(QuickStartContext);
1561
1654
  const prereqs = prerequisites === null || prerequisites === void 0 ? void 0 : prerequisites.filter((p) => p);
@@ -1658,7 +1751,7 @@ const QuickStartCatalogFilterSelect = (_a) => {
1658
1751
  };
1659
1752
  const QuickStartCatalogFilterCount = ({ quickStartsCount }) => {
1660
1753
  const { getResource } = react.useContext(QuickStartContext);
1661
- return (jsxRuntime.jsx(reactCore.ToolbarItem, Object.assign({ align: { default: 'alignEnd' } }, { children: getResource('{{count, number}} item', quickStartsCount).replace('{{count, number}}', quickStartsCount) })));
1754
+ return (jsxRuntime.jsx(reactCore.ToolbarItem, Object.assign({ align: { default: 'alignEnd' } }, { children: getResource('{{count, number}} item', quickStartsCount) })));
1662
1755
  };
1663
1756
  const QuickStartCatalogFilterSearchWrapper = ({ onSearchInputChange = () => { } }) => {
1664
1757
  const { useQueryParams, filter, setFilter } = react.useContext(QuickStartContext);
@@ -1872,7 +1965,7 @@ const QuickStartIntroduction = ({ tasks, introduction, allTaskStatuses, prerequi
1872
1965
  const prereqs = prerequisites === null || prerequisites === void 0 ? void 0 : prerequisites.filter((p) => p);
1873
1966
  const [isPrereqsExpanded, setIsPrereqsExpanded] = react.useState(false);
1874
1967
  const prereqList = (prereqs === null || prereqs === void 0 ? void 0 : prereqs.length) > 0 && (jsxRuntime.jsx(reactCore.ExpandableSection, Object.assign({ toggleText: getResource('View Prerequisites ({{totalPrereqs}})').replace('{{totalPrereqs}}', prereqs.length), onToggle: () => setIsPrereqsExpanded(!isPrereqsExpanded) }, { children: jsxRuntime.jsx(reactCore.List, { children: prereqs.map((pr) => (jsxRuntime.jsx(reactCore.ListItem, { children: jsxRuntime.jsx(QuickStartMarkdownView, { content: pr }) }, pr))) }) })));
1875
- return (jsxRuntime.jsxs(reactCore.Stack, Object.assign({ hasGutter: true }, { children: [jsxRuntime.jsx(QuickStartMarkdownView, { content: introduction }), prereqList, jsxRuntime.jsxs("p", { children: [getResource('In this quick start, you will complete {{count, number}} task', tasks === null || tasks === void 0 ? void 0 : tasks.length).replace('{{count, number}}', (tasks === null || tasks === void 0 ? void 0 : tasks.length) || 0), ":"] }), jsxRuntime.jsx(QuickStartTaskHeaderList, { tasks: tasks, allTaskStatuses: allTaskStatuses, onTaskSelect: onTaskSelect })] })));
1968
+ return (jsxRuntime.jsxs(reactCore.Stack, Object.assign({ hasGutter: true }, { children: [jsxRuntime.jsx(QuickStartMarkdownView, { content: introduction }), prereqList, jsxRuntime.jsxs("p", { children: [getResource('In this quick start, you will complete {{count, number}} task', (tasks === null || tasks === void 0 ? void 0 : tasks.length) || 0).replace('{{count, number}}', (tasks === null || tasks === void 0 ? void 0 : tasks.length) || 0), ":"] }), jsxRuntime.jsx(QuickStartTaskHeaderList, { tasks: tasks, allTaskStatuses: allTaskStatuses, onTaskSelect: onTaskSelect })] })));
1876
1969
  };
1877
1970
 
1878
1971
  const getAlertVariant = (status) => {
@@ -2045,7 +2138,7 @@ const QuickStartPanelContent = (_a) => {
2045
2138
  const QuickStartDrawerContent = (_a) => {
2046
2139
  var { quickStarts = [], appendTo, fullWidth, handleDrawerClose } = _a, props = tslib.__rest(_a, ["quickStarts", "appendTo", "fullWidth", "handleDrawerClose"]);
2047
2140
  const { activeQuickStartID, allQuickStarts = [], activeQuickStartState, } = react.useContext(QuickStartContext);
2048
- const combinedQuickStarts = allQuickStarts.concat(quickStarts);
2141
+ const combinedQuickStarts = [...allQuickStarts, ...quickStarts].filter((qs, idx, arr) => arr.findIndex((q) => q.metadata.name === qs.metadata.name) === idx);
2049
2142
  const handleClose = () => {
2050
2143
  handleDrawerClose && handleDrawerClose(activeQuickStartState === null || activeQuickStartState === void 0 ? void 0 : activeQuickStartState.status);
2051
2144
  };