@patternfly/documentation-framework 6.44.4 → 6.44.5

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/CHANGELOG.md CHANGED
@@ -3,6 +3,14 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## 6.44.5 (2026-06-25)
7
+
8
+ **Note:** Version bump only for package @patternfly/documentation-framework
9
+
10
+
11
+
12
+
13
+
6
14
  ## 6.44.4 (2026-06-23)
7
15
 
8
16
  **Note:** Version bump only for package @patternfly/documentation-framework
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@patternfly/documentation-framework",
3
3
  "description": "A framework to build documentation for PatternFly.",
4
- "version": "6.44.4",
4
+ "version": "6.44.5",
5
5
  "author": "Red Hat",
6
6
  "license": "MIT",
7
7
  "bin": {
@@ -92,5 +92,5 @@
92
92
  "http-cache-semantics": ">=4.1.1",
93
93
  "nanoid": "3.3.8"
94
94
  },
95
- "gitHead": "e780cd97bc1ba8ebae0d2a60d965655baf8cddbe"
95
+ "gitHead": "d16437a28753407cf536af5a700f86b12b6e11f3"
96
96
  }
@@ -8,7 +8,7 @@ function getSource(options) {
8
8
  async function generate(options) {
9
9
  const start = new Date();
10
10
  console.log('write source files to patternfly-docs/generated');
11
- const sourceMDWithOptions = (glob, source, ignore) => sourceMD(glob, source, ignore, options._name);
11
+ const sourceMDWithOptions = (glob, source, ignore, mdOptions) => sourceMD(glob, source, ignore, options._name, mdOptions);
12
12
  getSource(options)(sourceMDWithOptions, sourceProps, sourceFunctionDocs);
13
13
  await waitForProps();
14
14
  processMD();
@@ -25,10 +25,15 @@ const globs = {
25
25
  md: [],
26
26
  };
27
27
 
28
- function toReactComponent(mdFilePath, source, buildMode) {
28
+ function toReactComponent(mdFilePath, source, buildMode, { frontmatterDefaults, frontmatterMapping } = {}) {
29
29
  // vfiles allow for nicer error messages and have native `unified` support
30
30
  const vfile = toVfile.readSync(mdFilePath);
31
31
 
32
+ // Normalize void HTML elements to self-closing for MDX compatibility
33
+ const voidElements = 'area|base|br|col|embed|hr|img|input|link|meta|param|source|track|wbr';
34
+ const voidTagRegex = new RegExp(`<(${voidElements})(\\s[^>]*?)\\s*(?<!/)>`, 'g');
35
+ vfile.contents = String(vfile.contents).replace(voidTagRegex, '<$1$2 />');
36
+
32
37
  const relPath = path.relative(path.join(process.cwd(), '../..'), vfile.path).split(path.sep).join(path.posix.sep);
33
38
 
34
39
  let jsx;
@@ -47,6 +52,23 @@ function toReactComponent(mdFilePath, source, buildMode) {
47
52
  }
48
53
  frontmatter = yaml.load(yamlNode.value);
49
54
 
55
+ // Apply frontmatter mapping (e.g., { title: "id" } maps title -> id)
56
+ if (frontmatterMapping) {
57
+ Object.entries(frontmatterMapping).forEach(([fromKey, toKey]) => {
58
+ if (frontmatter[fromKey] !== undefined && frontmatter[toKey] === undefined) {
59
+ frontmatter[toKey] = frontmatter[fromKey];
60
+ }
61
+ });
62
+ }
63
+ // Apply frontmatter defaults (e.g., { section: "AI" })
64
+ if (frontmatterDefaults) {
65
+ Object.entries(frontmatterDefaults).forEach(([key, value]) => {
66
+ if (frontmatter[key] === undefined) {
67
+ frontmatter[key] = value;
68
+ }
69
+ });
70
+ }
71
+
50
72
  // Fail early
51
73
  if (!frontmatter.id) {
52
74
  file.fail('id attribute is required in frontmatter for PatternFly docs');
@@ -276,7 +298,7 @@ async function sourcePropsFile(file) {
276
298
  });
277
299
  }
278
300
 
279
- function sourceMDFile(file, source, buildMode) {
301
+ function sourceMDFile(file, source, buildMode, options) {
280
302
  if (path.basename(file).startsWith('_')) {
281
303
  return;
282
304
  }
@@ -285,7 +307,7 @@ function sourceMDFile(file, source, buildMode) {
285
307
  if (source === 'design-guidelines' && file.includes('/accessibility/')) {
286
308
  return;
287
309
  }
288
- const { jsx, pageData, outPath } = toReactComponent(file, source, buildMode);
310
+ const { jsx, pageData, outPath } = toReactComponent(file, source, buildMode, options);
289
311
 
290
312
  if (jsx) {
291
313
  fs.outputFileSync(outPath, jsx);
@@ -352,12 +374,12 @@ module.exports = {
352
374
  async waitForProps() {
353
375
  await Promise.all(pendingProps);
354
376
  },
355
- sourceMD(glob, source, ignore, buildMode) {
356
- globs.md.push({ glob, source, ignore, buildMode });
377
+ sourceMD(glob, source, ignore, buildMode, options) {
378
+ globs.md.push({ glob, source, ignore, buildMode, options });
357
379
  },
358
380
  processMD() {
359
- globs.md.forEach(({ glob, source, ignore, buildMode }) => {
360
- globSync(glob, { ignore }).forEach(file => sourceMDFile(file, source, buildMode));
381
+ globs.md.forEach(({ glob, source, ignore, buildMode, options }) => {
382
+ globSync(glob, { ignore }).forEach(file => sourceMDFile(file, source, buildMode, options));
361
383
  });
362
384
  },
363
385
  sourceFunctionDocs,
@@ -373,10 +395,10 @@ module.exports = {
373
395
  propWatcher.on('add', onPropFile);
374
396
  propWatcher.on('change', onPropFile);
375
397
  });
376
- globs.md.forEach(({ glob, source, ignore }) => {
398
+ globs.md.forEach(({ glob, source, ignore, options }) => {
377
399
  const mdWatcher = chokidar.watch(globSync(glob, { ignored: ignore, ignoreInitial: true }));
378
400
  function onMDFileChange(file) {
379
- sourceMDFile(file, source, 'start');
401
+ sourceMDFile(file, source, 'start', options);
380
402
  writeIndex();
381
403
  }
382
404
  mdWatcher.on('add', onMDFileChange);
@@ -22,13 +22,35 @@ const styledMdTags = [
22
22
 
23
23
  function styledTags() {
24
24
  return tree => {
25
- visit(tree, 'element', node => {
25
+ visit(tree, 'element', (node, index, parent) => {
26
26
  node.properties.className = node.properties.className || '';
27
-
28
- if (contentStyledMdTags.includes(node.tagName)) {
27
+
28
+ const hasDataType = node.properties && (node.properties.dataType || node.properties['data-type']);
29
+ const parentHasDataType = parent && parent.properties && (parent.properties.dataType || parent.properties['data-type']);
30
+ if (contentStyledMdTags.includes(node.tagName) && !hasDataType && !parentHasDataType) {
29
31
  node.properties.className += `pf-v6-c-content--${node.tagName} pf-m-editorial`;
30
32
  }
31
33
 
34
+ // GitHub-style admonitions: > [!NOTE], > [!TIP], > [!WARNING], etc.
35
+ if (node.tagName === 'blockquote') {
36
+ const firstP = node.children && node.children.find(c => c.tagName === 'p');
37
+ if (firstP && firstP.children) {
38
+ const firstText = firstP.children.find(c => c.type === 'text');
39
+ if (firstText) {
40
+ const match = firstText.value.match(/^\[!(NOTE|TIP|WARNING|IMPORTANT|CAUTION)\]\s*/i);
41
+ if (match) {
42
+ const type = match[1].toLowerCase();
43
+ node.properties['data-admonition'] = type;
44
+ node.properties.className += ` ws-admonition ws-admonition-${type}`;
45
+ firstText.value = firstText.value.slice(match[0].length);
46
+ if (!firstText.value.trim() && firstP.children.length === 1) {
47
+ node.children = node.children.filter(c => c !== firstP);
48
+ }
49
+ }
50
+ }
51
+ }
52
+ }
53
+
32
54
  if (styledMdTags.includes(node.tagName)) {
33
55
  node.properties.className += node.properties.className ? ' ' : '';
34
56
  node.properties.className += `ws-${node.tagName} `;
@@ -0,0 +1,171 @@
1
+ /* Styles for @project-felt/ai-guidelines content */
2
+
3
+ /* Figure base styles */
4
+ [data-content-source="ai-guidelines"] figure[data-type] {
5
+ margin: var(--pf-t--global--spacer--lg) 0;
6
+ padding: var(--pf-t--global--spacer--md);
7
+ border: var(--pf-t--global--border--width--regular) solid var(--pf-t--global--border--color--default);
8
+ border-radius: var(--pf-t--global--border--radius--medium);
9
+ background-color: var(--pf-t--global--background--color--primary--default);
10
+ text-align: center;
11
+ max-width: 700px;
12
+ margin-inline: auto;
13
+ width: 100%;
14
+ }
15
+
16
+ [data-content-source="ai-guidelines"] figure[data-type="example landscape"] {
17
+ max-width: 100%;
18
+ }
19
+
20
+ [data-content-source="ai-guidelines"] figure[data-type] img {
21
+ max-width: 100%;
22
+ height: auto;
23
+ }
24
+
25
+ [data-content-source="ai-guidelines"] figure[data-type] figcaption {
26
+ margin-top: var(--pf-t--global--spacer--sm);
27
+ font-size: var(--pf-t--global--font--size--sm);
28
+ color: var(--pf-t--global--text--color--subtle);
29
+ text-align: left;
30
+ }
31
+
32
+ [data-content-source="ai-guidelines"] figure[data-type] figcaption:first-child {
33
+ margin-top: 0;
34
+ }
35
+
36
+ /* Inline icons in lists and paragraphs */
37
+ [data-content-source="ai-guidelines"] li img,
38
+ [data-content-source="ai-guidelines"] p img {
39
+ height: 1em;
40
+ width: auto;
41
+ max-width: none;
42
+ vertical-align: middle;
43
+ }
44
+
45
+ /* Do examples — green accent */
46
+ [data-content-source="ai-guidelines"] figure[data-type="do"] {
47
+ border-color: var(--pf-t--global--color--status--success--default);
48
+ }
49
+
50
+ [data-content-source="ai-guidelines"] figure[data-type="do"] figcaption::before {
51
+ content: "Do";
52
+ display: block;
53
+ font-weight: var(--pf-t--global--font--weight--body--bold);
54
+ color: var(--pf-t--global--color--status--success--default);
55
+ margin-bottom: var(--pf-t--global--spacer--xs);
56
+ }
57
+
58
+ /* Don't examples — red accent */
59
+ [data-content-source="ai-guidelines"] figure[data-type="dont"] {
60
+ border-color: var(--pf-t--global--color--status--danger--default);
61
+ }
62
+
63
+ [data-content-source="ai-guidelines"] figure[data-type="dont"] figcaption::before {
64
+ content: "Don't";
65
+ display: block;
66
+ font-weight: var(--pf-t--global--font--weight--body--bold);
67
+ color: var(--pf-t--global--color--status--danger--default);
68
+ margin-bottom: var(--pf-t--global--spacer--xs);
69
+ }
70
+
71
+ /* Figure groups */
72
+ [data-content-source="ai-guidelines"] ul[data-type] {
73
+ list-style: none;
74
+ padding: 0;
75
+ margin: var(--pf-t--global--spacer--lg) 0;
76
+ display: grid;
77
+ gap: var(--pf-t--global--spacer--md);
78
+ }
79
+
80
+ [data-content-source="ai-guidelines"] ul[data-type="dos-donts"] {
81
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
82
+ }
83
+
84
+ [data-content-source="ai-guidelines"] ul[data-type="examples"] {
85
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
86
+ }
87
+
88
+ [data-content-source="ai-guidelines"] ul[data-type] > li {
89
+ list-style: none;
90
+ padding: 0;
91
+ margin: 0;
92
+ }
93
+
94
+ [data-content-source="ai-guidelines"] ul[data-type] > li > figure[data-type] {
95
+ margin: 0;
96
+ height: 100%;
97
+ }
98
+
99
+ /* GitHub-style admonitions */
100
+ [data-content-source="ai-guidelines"] .ws-admonition {
101
+ border-left-width: 4px;
102
+ padding: var(--pf-t--global--spacer--md);
103
+ margin: var(--pf-t--global--spacer--md) 0;
104
+ }
105
+
106
+ [data-content-source="ai-guidelines"] .ws-admonition::before {
107
+ display: block;
108
+ font-weight: var(--pf-t--global--font--weight--body--bold);
109
+ margin-bottom: var(--pf-t--global--spacer--xs);
110
+ }
111
+
112
+ [data-content-source="ai-guidelines"] .ws-admonition-note {
113
+ border-left-color: var(--pf-t--global--color--status--info--default);
114
+ }
115
+
116
+ [data-content-source="ai-guidelines"] .ws-admonition-note::before {
117
+ content: "Note";
118
+ color: var(--pf-t--global--color--status--info--default);
119
+ }
120
+
121
+ [data-content-source="ai-guidelines"] .ws-admonition-tip {
122
+ border-left-color: var(--pf-t--global--color--status--success--default);
123
+ }
124
+
125
+ [data-content-source="ai-guidelines"] .ws-admonition-tip::before {
126
+ content: "Tip";
127
+ color: var(--pf-t--global--color--status--success--default);
128
+ }
129
+
130
+ [data-content-source="ai-guidelines"] .ws-admonition-warning {
131
+ border-left-color: var(--pf-t--global--color--status--warning--default);
132
+ }
133
+
134
+ [data-content-source="ai-guidelines"] .ws-admonition-warning::before {
135
+ content: "Warning";
136
+ color: var(--pf-t--global--color--status--warning--default);
137
+ }
138
+
139
+ [data-content-source="ai-guidelines"] .ws-admonition-important {
140
+ border-left-color: var(--pf-t--global--color--status--danger--default);
141
+ }
142
+
143
+ [data-content-source="ai-guidelines"] .ws-admonition-important::before {
144
+ content: "Important";
145
+ color: var(--pf-t--global--color--status--danger--default);
146
+ }
147
+
148
+ [data-content-source="ai-guidelines"] .ws-admonition-caution {
149
+ border-left-color: var(--pf-t--global--color--status--warning--default);
150
+ }
151
+
152
+ [data-content-source="ai-guidelines"] .ws-admonition-caution::before {
153
+ content: "Caution";
154
+ color: var(--pf-t--global--color--status--warning--default);
155
+ }
156
+
157
+ /* Internal Red Hat links — lock icon + sr-only text */
158
+ [data-content-source="ai-guidelines"] a[href*="url.corp.redhat.com"]::after {
159
+ content: " (requires Red Hat login)";
160
+ overflow: hidden;
161
+ display: inline-block;
162
+ width: 0.85em;
163
+ height: 0.85em;
164
+ margin-left: 0.25em;
165
+ vertical-align: middle;
166
+ text-indent: -9999px;
167
+ background-color: currentColor;
168
+ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3E%3Cpath d='M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zm-104 0H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z'/%3E%3C/svg%3E");
169
+ mask-size: contain;
170
+ mask-repeat: no-repeat;
171
+ }
package/templates/mdx.css CHANGED
@@ -1,3 +1,5 @@
1
+ @import './content-sources/ai-guidelines.css';
2
+
1
3
  p.pf-v6-c-content--p.ws-p {
2
4
  margin: 0;
3
5
  }
package/templates/mdx.js CHANGED
@@ -109,7 +109,7 @@ const MDXChildTemplate = ({ Component, source, toc = [], index = 0, id }) => {
109
109
  );
110
110
  // Create dynamic component for @reach/router
111
111
  const ChildComponent = () => (
112
- <div className={source !== 'landing-pages' ? 'pf-v6-l-flex pf-v6-m-column pf-m-nowrap-on-2xl' : ''}>
112
+ <div className={source !== 'landing-pages' ? 'pf-v6-l-flex pf-v6-m-column pf-m-nowrap-on-2xl' : ''} data-content-source={source}>
113
113
  {toc.length > 1 && <TableOfContents items={toc} />}
114
114
  <Stack hasGutter className={(source !== 'landing-pages' && 'ws-example-page-wrapper')}>
115
115
  {InlineAlerts}