diff --git a/.eslintignore b/.eslintignore
deleted file mode 100644
index ca25f1637d5..00000000000
--- a/.eslintignore
+++ /dev/null
@@ -1,49 +0,0 @@
-# Javascript builds
-node_modules
-dist
-__tests__
-tsc_out
-.out
-.changelog
-.DS_Store
-coverage
-.cache
-.tmp
-**/Generated
-**/build
-css
-packages/react-docs/.cache
-packages/react-docs/static
-packages/react-docs/public
-packages/react-integration/results
-packages/react-integration/demo-app-ts/public
-
-# package managers
-yarn-error.log
-lerna-debug.log
-
-# IDEs and editors
-.idea
-.project
-.classpath
-.c9
-*.launch
-.settings
-*.sublime-workspace
-.history
-.vscode
-
-# IDE - VSCode
-.vscode
-# For vim
-*.swp
-
-# Deploy directory
-docs
-
-# Copied types
-DeprecatedPopperTypes.ts
-DeprecatedTippyTypes.ts
-
-# Copied thirdparty
-packages/react-core/src/helpers/Popper/thirdparty/**/*
diff --git a/.eslintrc-md.json b/.eslintrc-md.json
index 0f5929fbf83..9016f102667 100644
--- a/.eslintrc-md.json
+++ b/.eslintrc-md.json
@@ -1,6 +1,5 @@
{
"plugins": [
- "markdown",
"react",
"patternfly-react"
],
@@ -26,5 +25,6 @@
"react/jsx-uses-vars": "error",
"react/no-unknown-property": 2,
"react/jsx-no-undef": 2
- }
-}
\ No newline at end of file
+ },
+ "extends": "plugin:markdown/recommended-legacy"
+}
diff --git a/.eslintrc.json b/.eslintrc.json
deleted file mode 100644
index 1266039a489..00000000000
--- a/.eslintrc.json
+++ /dev/null
@@ -1,132 +0,0 @@
-{
- "env": {
- "browser": true,
- "node": true,
- "es6": true
- },
- "plugins": [
- "@typescript-eslint",
- "react",
- "react-hooks",
- "prettier",
- "patternfly-react"
- ],
- "extends": [
- "eslint:recommended",
- "plugin:@typescript-eslint/recommended",
- "plugin:react/recommended"
- ],
- "parserOptions": {
- "sourceType": "module",
- "ecmaFeatures": {
- "jsx": true
- }
- },
- "settings": {
- "react": {
- "version": "16.4.0"
- }
- },
- "globals": {
- "describe": "readonly",
- "test": "readonly",
- "jest": "readonly",
- "expect": "readonly",
- "require": "readonly",
- "global": "writable",
- "it": "readonly",
- "afterEach": "readonly",
- "beforeEach": "readonly"
- },
- "rules": {
- "@typescript-eslint/adjacent-overload-signatures": "error",
- "@typescript-eslint/array-type": "error",
- "@typescript-eslint/ban-types": "off",
- "@typescript-eslint/consistent-type-assertions": "error",
- "@typescript-eslint/consistent-type-definitions": "error",
- "@typescript-eslint/explicit-member-accessibility": "off",
- "@typescript-eslint/explicit-module-boundary-types": "off",
- "@typescript-eslint/indent": "off",
- "@typescript-eslint/no-empty-function": "off",
- "@typescript-eslint/no-empty-interface": "off",
- "@typescript-eslint/no-explicit-any": "off",
- "@typescript-eslint/no-inferrable-types": "off",
- "@typescript-eslint/no-misused-new": "error",
- "@typescript-eslint/no-namespace": "error",
- "@typescript-eslint/no-unused-vars": ["error", {
- "argsIgnorePattern": "^_"
- }],
- "@typescript-eslint/no-use-before-define": "off",
- "@typescript-eslint/no-var-requires": "off",
- "@typescript-eslint/prefer-for-of": "error",
- "@typescript-eslint/prefer-function-type": "error",
- "@typescript-eslint/prefer-namespace-keyword": "error",
- "@typescript-eslint/unified-signatures": "error",
- "@typescript-eslint/explicit-function-return-type": "off",
- "arrow-body-style": "error",
- "camelcase": ["error", {
- "ignoreDestructuring": true
- }],
- "constructor-super": "error",
- "curly": "error",
- "dot-notation": "error",
- "eqeqeq": [
- "error",
- "smart"
- ],
- "guard-for-in": "error",
- "max-classes-per-file": [
- "error",
- 1
- ],
- "max-len": "off",
- "no-nested-ternary": "error",
- "no-bitwise": "error",
- "no-caller": "error",
- "no-cond-assign": "error",
- "no-console": "error",
- "no-debugger": "error",
- "no-empty": "error",
- "no-eval": "error",
- "no-new-wrappers": "error",
- "no-prototype-builtins": "off",
- "no-shadow": "off",
- "no-throw-literal": "error",
- "no-trailing-spaces": "off",
- "no-undef-init": "error",
- "no-unsafe-finally": "error",
- "no-unused-expressions": ["error", {
- "allowTernary": true,
- "allowShortCircuit": true
- }],
- "no-unused-labels": "error",
- "no-var": "error",
- "object-shorthand": "error",
- "one-var": [
- "error",
- "never"
- ],
- "patternfly-react/import-tokens-icons": "error",
- "patternfly-react/no-anonymous-functions": "error",
- "prefer-const": "error",
- "prettier/prettier": "error",
- "radix": [
- "error",
- "as-needed"
- ],
- "react/prop-types": 0,
- "react/display-name": 0,
- "react/no-unescaped-entities": ["error", {"forbid": [">", "}"]}],
- "spaced-comment": "error",
- "use-isnan": "error",
- "patternfly-react/no-layout-effect": "error"
- },
- "overrides": [
- {
- "files": ["**/examples/*", "**/demos/examples/**/*"],
- "rules": {
- "patternfly-react/no-anonymous-functions": "off"
- }
- }
- ]
-}
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
deleted file mode 100644
index 5a29493d47f..00000000000
--- a/.github/ISSUE_TEMPLATE.md
+++ /dev/null
@@ -1,8 +0,0 @@
-**Describe the issue. What is the expected and unexpected behavior?**
-
-**Please provide the steps to reproduce. Feel free to link CodeSandbox or another tool.**
-
-
-**Is this a bug or enhancement? If this issue is a bug, is this issue blocking you or is there a work-around?**
-
-**What is your product and what release version are you targeting?**
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 00000000000..f808ffbd94e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,32 @@
+---
+name: Bug report
+about: Help us to improve PatternFly
+title: Bug - [Component] - [short description]
+type: bug
+assignees: ''
+
+---
+
+**Describe the problem**
+A clear and concise description of the problem. Which components are affected?
+
+**How do you reproduce the problem?**
+Provide steps to reproduce. A [codesandbox](https://codesandbox.io/s/serverless-cherry-q9t3f ) demonstrating the problem is appreciated.
+
+**Expected behavior**
+A clear and concise description of the expected behavior.
+
+**Is this issue blocking you?**
+List the workaround if there is one.
+
+**Screenshots**
+If applicable, add screenshots to help explain the issue.
+
+**What is your environment?**
+ - OS: [e.g. iOS]
+ - Browser [e.g. chrome, safari]
+ - Version [e.g. 22]
+
+**What is your product and what release date are you targeting?**
+
+**Any other information?**
diff --git a/.github/ISSUE_TEMPLATE/devX_request.md b/.github/ISSUE_TEMPLATE/devX_request.md
new file mode 100644
index 00000000000..10bfbe40624
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/devX_request.md
@@ -0,0 +1,14 @@
+---
+name: Developer experience
+about: Suggest an enhancement to the developer experience (DX). DX enhancements improve experience for those building UIs with PatternFly, but have little to no end user impact.
+title: "[short description]"
+type: DevX
+assignees: ''
+
+---
+**Describe the enhancement or change**
+A clear and concise description of the request. What is the expected outcome?
+
+**Is this request originating from a Red Hat product team? If so, which ones and is there any sort of deadline for this enhancement?**
+
+**Any other information?**
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644
index 00000000000..7e9c1bb19c3
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -0,0 +1,99 @@
+name: Feature request
+description: Suggest a new feature or component for PatternFly.
+title: "[Component] - [short description]"
+labels: ["extension", "needs-triage"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ ### Thanks for helping improve PatternFly!
+ Please fill out this form to help the team understand your proposal.
+
+ - type: dropdown
+ id: category
+ attributes:
+ label: Is this a new component or an extension?
+ options:
+ - New Component
+ - Variant of an existing component
+ - Enhancement to a current feature
+ validations:
+ required: true
+
+ - type: input
+ id: existing_component
+ attributes:
+ label: Existing Component
+ description: If this is a variant or enhancement, which component does it impact?
+ placeholder: e.g., Table, Select, Wizard
+ validations:
+ required: false
+
+ - type: textarea
+ id: description
+ attributes:
+ label: Describe the feature
+ description: A clear and concise description of the new feature.
+ placeholder: What is the expected behavior? Is there any specific error handling?
+ validations:
+ required: true
+
+ - type: textarea
+ id: user_story
+ attributes:
+ label: User Story
+ description: Providing context helps us understand the priority.
+ placeholder: As a [user role], I want to [action] so that [benefit].
+ validations:
+ required: true
+
+ - type: textarea
+ id: visuals
+ attributes:
+ label: Visuals & Mockups
+ description: Include links to Figma or upload screenshots for desktop/mobile views.
+ placeholder: |
+ - Figma link:
+ - Screenshots: (Drag images here)
+ validations:
+ required: false
+
+ - type: textarea
+ id: interaction_states
+ attributes:
+ label: Interaction States & Variations
+ description: Describe the behavior across different states.
+ placeholder: |
+ - Initial/Empty:
+ - Loading:
+ - Error/Validation:
+ - Mobile/Responsive Viewport:
+ validations:
+ required: true
+
+ - type: textarea
+ id: accessibility
+ attributes:
+ label: Accessibility (A11y)
+ description: Specific keyboard interaction or focus management requirements.
+ placeholder: e.g., Tab navigation, ARIA labels, or focus traps.
+ validations:
+ required: false
+
+ - type: input
+ id: product_release
+ attributes:
+ label: Product & Target Release
+ description: If applicable, what is your product and target release date?
+ placeholder: e.g., OpenShift 4.15
+ validations:
+ required: false
+
+ - type: checkboxes
+ id: contribution_check
+ attributes:
+ label: Contribution
+ options:
+ - label: I am interested in contributing this feature.
+ - label: I have searched for similar existing requests.
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/tech_debt_request.md b/.github/ISSUE_TEMPLATE/tech_debt_request.md
new file mode 100644
index 00000000000..fe899df86a0
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/tech_debt_request.md
@@ -0,0 +1,14 @@
+---
+name: Tech debt
+about: Improvements to code that do not affect either user or product developers’ experiences.
+title: "[short description]"
+type: 'Tech debt'
+assignees: ''
+
+---
+**Describe the enhancement or change**
+A clear and concise description of the request. What is the expected outcome?
+
+**Is this request originating from a Red Hat product team? If so, which ones and is there any sort of deadline for this enhancement?**
+
+**Any other information?**
diff --git a/.github/actions/setup-project/action.yml b/.github/actions/setup-project/action.yml
new file mode 100644
index 00000000000..07aaccbecde
--- /dev/null
+++ b/.github/actions/setup-project/action.yml
@@ -0,0 +1,54 @@
+name: Set up and build project
+inputs:
+ skip-build:
+ description: Skip the build step
+ required: false
+ default: 'false'
+ skip-build-cache:
+ description: Skip the build cache step
+ required: false
+ default: 'false'
+runs:
+ using: composite
+ steps:
+ - name: Set up Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: 22
+ check-latest: true
+
+ - name: Enable Corepack
+ shell: bash
+ run: corepack enable
+
+ - name: Get Yarn configuration
+ id: yarn-config
+ shell: bash
+ run: |
+ echo "cache-folder=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
+
+ # TODO: This can be simplified to use the `cache` option of the `actions/setup-node` action when it supports Corepack.
+ # See: https://github.com/actions/setup-node/issues/531
+ - uses: actions/cache@v4
+ name: Setup Yarn cache
+ with:
+ # Also cache Cypress binary.
+ path: |
+ ~/.cache/Cypress
+ ${{ steps.yarn-config.outputs.cache-folder }}
+ key: ${{ runner.os }}-yarn-cache-${{ hashFiles('yarn.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-yarn-cache-
+
+ - name: Install dependencies
+ shell: bash
+ run: yarn install --immutable
+
+ - name: Run build
+ if: inputs.skip-build != 'true'
+ shell: bash
+ run: yarn build && yarn build:umd
+ env:
+ # Disable V8 compile cache to hard crashes in Node.js. This can likely be removed once upgraded to the next LTS version (version 22).
+ # See: https://github.com/nodejs/node/issues/51555
+ DISABLE_V8_COMPILE_CACHE: 1
diff --git a/.github/generate-workflows.js b/.github/generate-workflows.js
deleted file mode 100644
index b4a9f17307b..00000000000
--- a/.github/generate-workflows.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/* For some reason Github's composite actions are limited to a small set
- * of actions AND even if you get them working, the composite actions don't
- * list all the steps out in an easily debuggable way.
- *
- * I've written this so common parts of pr preview/release builds need not
- * be repeated.
- */
-const path = require('path');
-const fs = require('fs');
-
-const inDir = path.join(__dirname, 'workflows-src');
-const outDir = path.join(__dirname, 'workflows');
-const partialsDir = path.join(inDir, 'partials');
-const yamlRegex = /\.ya?ml$/;
-
-const partials = fs.readdirSync(partialsDir).reduce((acc, f) => {
- acc[f.replace(yamlRegex, '')] = fs.readFileSync(path.join(partialsDir, f), 'utf8').trim();
- return acc;
-}, {});
-
-function templateReplace(contents) {
- Object.entries(partials).forEach(([key, val]) => {
- const regexText = `([ \\t]*)%${key}%`;
- const match = contents.match(new RegExp(regexText));
- if (match) {
- const spacing = match[1];
- val = `${spacing}${val.replace(/\n/g, '\n' + spacing)}`;
- contents = contents.replace(new RegExp(regexText, 'g'), val);
- }
- });
-
- return contents;
-}
-
-// Partials can have other partials
-Object.entries(partials).forEach(([key, val]) => {
- partials[key] = templateReplace(val);
-});
-
-if (!fs.existsSync(outDir)) {
- fs.mkdirSync(outDir);
-}
-
-fs.readdirSync(inDir)
- .filter(f => f.match(yamlRegex))
- .forEach(f => {
- let contents = fs.readFileSync(path.join(inDir, f), 'utf8');
-
- contents = templateReplace(contents);
- contents = `### WARNING -- this file was generated by ${process.argv[1].split(path.sep).pop()}\n${contents}`;
- fs.writeFileSync(path.join(outDir, f), contents);
- });
-
diff --git a/.github/promote.sh b/.github/promote.sh
new file mode 100755
index 00000000000..d8700acd96e
--- /dev/null
+++ b/.github/promote.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+GIT_USERNAME="patternfly-build"
+GH_REPO=${GITHUB_REPOSITORY}
+REPO="github.com/${GH_REPO}"
+echo "Preparing release environment..."
+git config user.email "patternfly-build@redhat.com"
+git config user.name ${GIT_USERNAME}
+echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
+
+# Lerna is complicated. Commands: https://github.com/lerna/lerna/tree/master/commands
+# Identify packages that have been updated since the previous tagged release
+# Update their versions and changelogs according to angular commit guidelines
+# https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit
+
+#if [[ ! -z "${PATTERNFLY_VERSION}" ]]; then
+# echo "Updating to @patternfly/patternfly: ${PATTERNFLY_VERSION}"
+# npm pkg set dependencies.@patternfly/patternfly=${PATTERNFLY_VERSION} --workspace @patternfly/react-docs
+# npm pkg set devDependencies.@patternfly/patternfly=${PATTERNFLY_VERSION} --workspace @patternfly/react-core --workspace @patternfly/react-styles --workspace @patternfly/react-tokens --workspace @patternfly/react-icons
+#fi
+
+# publish to npm
+# yarn run lerna publish --conventional-commits --conventional-graduate --no-private --dist-tag=latest --yes
+
+# immediately after promote - set up repo for next prerelease
+yarn run lerna version preminor --force-publish --conventional-commits --no-private --yes --preid prerelease
+
+# dry run
+# yarn run lerna version --conventional-commits --conventional-graduate --no-private --yes --no-git-tag-version --no-push
+
+
diff --git a/.github/release.sh b/.github/release.sh
index 374b2f3e514..506097c32a9 100755
--- a/.github/release.sh
+++ b/.github/release.sh
@@ -17,7 +17,10 @@ echo "Doing a release..."
LOG=$(git log --format="%s" -1 | grep -Poe "#\d+")
PR_NUM=${LOG:1}
-yarn run lerna publish --conventional-commits --create-release=github --no-verify-access --yes 2>&1 | tee lerna-output.txt
+yarn run lerna publish prerelease --preid=prerelease --dist-tag=prerelease --yes 2>&1 | tee lerna-output.txt
+
+# use lerna command below for dry run
+#yarn run lerna version prerelease --preid=prerelease --yes --no-git-tag-version --no-push | tee lerna-output.txt
if grep -i "Successfully published" lerna-output.txt; # Leave a Github comment
then
diff --git a/.github/renovate.json b/.github/renovate.json
index 63158b99095..663f5774573 100644
--- a/.github/renovate.json
+++ b/.github/renovate.json
@@ -1,31 +1,15 @@
{
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
- "config:base"
+ "config:recommended"
],
- "enabledManagers": ["npm"],
+ "rangeStrategy": "bump",
"packageRules": [
{
- "packagePatterns": ["*"],
- "excludePackagePatterns": [
- "@patternfly/patternfly",
- "@patternfly/patternfly-a11y",
- "theme-patternfly-org"
+ "matchUpdateTypes": [
+ "major"
],
"enabled": false
- },
- {
- "datasources": ["npm"],
- "packageNames": [
- "@patternfly/patternfly-a11y",
- "theme-patternfly-org"
- ]
- },
- {
- "datasources": ["npm"],
- "packageNames": [
- "@patternfly/patternfly"
- ],
- "followTag": "prerelease"
}
]
}
diff --git a/.github/split.js b/.github/split.js
deleted file mode 100644
index 11a6610de7c..00000000000
--- a/.github/split.js
+++ /dev/null
@@ -1,14 +0,0 @@
-const fs = require('fs');
-const path = require('path');
-
-const BASE_DIR = path.join(__dirname, '../packages/react-integration/cypress/integration');
-const WORKER_NUM = +process.env['WORKER_NUM'];
-const WORKER_COUNT = +process.env['WORKER_COUNT'];
-
-const testFiles = fs.readdirSync(BASE_DIR)
- .sort()
- .filter((_, i) => i % WORKER_COUNT === WORKER_NUM)
- .map(f => path.join(BASE_DIR, f));
-
-console.log(testFiles.join(' '));
-
diff --git a/.github/split.mjs b/.github/split.mjs
new file mode 100644
index 00000000000..46e12072955
--- /dev/null
+++ b/.github/split.mjs
@@ -0,0 +1,15 @@
+/* eslint-disable no-console */
+import fs from 'node:fs';
+import path from 'node:path';
+
+const BASE_DIR = path.resolve(import.meta.dirname, '../packages/react-integration/cypress/integration');
+const WORKER_NUM = +process.env.WORKER_NUM;
+const WORKER_COUNT = +process.env.WORKER_COUNT;
+
+const testFiles = fs
+ .readdirSync(BASE_DIR)
+ .sort()
+ .filter((_, i) => i % WORKER_COUNT === WORKER_NUM)
+ .map((f) => path.join(BASE_DIR, f));
+
+console.log(testFiles.join(' '));
diff --git a/.github/stale.yml b/.github/stale.yml
deleted file mode 100644
index f4e6ae06a53..00000000000
--- a/.github/stale.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-# Configuration for probot-stale - https://github.com/probot/stale
-# Number of days of inactivity before an Issue or Pull Request becomes stale
-daysUntilStale: 60
-
-# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
-# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
-daysUntilClose: 14
-
-# Issues with these labels will never be considered stale
-exemptLabels:
- - pinned
- - security
- - accessibility
- - "breaking change :boom:"
-
-# Label to use when marking as stale
-staleLabel: wontfix
-
-# Comment to post when marking as stale. Set to `false` to disable
-markComment: >
- This issue has been automatically marked as stale because it has not had
- recent activity. It will be closed if no further activity occurs.
-
-# Comment to post when closing a stale issue. Set to `false` to disable
-closeComment: false
-
-# Limit the number of actions per hour, from 1-30. Default is 30
-limitPerRun: 30
diff --git a/.github/upload-preview.js b/.github/upload-preview.js
deleted file mode 100644
index 5fc94f2a2eb..00000000000
--- a/.github/upload-preview.js
+++ /dev/null
@@ -1,92 +0,0 @@
-const fs = require('fs');
-const path = require('path');
-const { Octokit } = require('@octokit/rest');
-const octokit = new Octokit({ auth: process.env.GH_PR_TOKEN });
-const surge = require('surge');
-const publishFn = surge().publish();
-
-// From github actions
-const ghrepo = process.env.GITHUB_REPOSITORY || '';
-
-const owner = process.env.CIRCLE_PROJECT_USERNAME || ghrepo.split('/')[0]; // patternfly
-const repo = process.env.CIRCLE_PROJECT_REPONAME || ghrepo.split('/')[1];
-const prnum = process.env.CIRCLE_PR_NUMBER || process.env.GH_PR_NUM;
-const prbranch = process.env.CIRCLE_BRANCH || process.env.GITHUB_REF.split('/').pop();
-
-const uploadFolder = process.argv[2];
-if (!uploadFolder) {
- console.log('Usage: upload-preview uploadFolder');
- process.exit(1);
-}
-
-const uploadFolderName = path.basename(uploadFolder);
-let uploadURL = `${repo}-${prnum ? `pr-${prnum}` : prbranch}`.replace(/[\/|\.]/g, '-');
-
-switch(uploadFolderName) {
- case 'coverage':
- uploadURL += '-a11y.surge.sh';
- break;
- case 'public':
- uploadURL += '.surge.sh';
- break;
- default:
- uploadURL += `-${uploadFolderName}`;
- uploadURL += '.surge.sh';
- break;
-}
-
-publishFn({
- project: uploadFolder,
- p: uploadFolder,
- domain: uploadURL,
- d: uploadURL,
- e: 'https://surge.surge.sh',
- endpoint: 'https://surge.surge.sh'
-});
-
-function tryAddComment(comment, commentBody) {
- if (!commentBody.includes(comment)) {
- return comment;
- }
- return '';
-}
-
-if (prnum) {
- octokit.issues.listComments({
- owner,
- repo,
- issue_number: prnum
- })
- .then(res => res.data)
- .then(comments => {
- let commentBody = '';
- const existingComment = comments.find(comment => comment.user.login === 'patternfly-build');
- if (existingComment) {
- commentBody += existingComment.body.trim();
- commentBody += '\n\n';
- }
-
- if (uploadFolderName === 'public') {
- commentBody += tryAddComment(`Preview: https://${uploadURL}`, commentBody);
- }
- else if (uploadFolderName === 'dist') {
- commentBody += tryAddComment(`A11y report: https://${uploadURL}`, commentBody);
- }
-
- if (existingComment) {
- octokit.issues.updateComment({
- owner,
- repo,
- comment_id: existingComment.id,
- body: commentBody
- }).then(() => console.log('Updated comment!'));
- } else {
- octokit.issues.createComment({
- owner,
- repo,
- issue_number: prnum,
- body: commentBody
- }).then(() => console.log('Created comment!'));
- }
- });
-}
diff --git a/.github/upload-preview.mjs b/.github/upload-preview.mjs
new file mode 100644
index 00000000000..704f2347538
--- /dev/null
+++ b/.github/upload-preview.mjs
@@ -0,0 +1,98 @@
+/* eslint-disable no-console, camelcase */
+import { Octokit } from '@octokit/rest';
+import path from 'node:path';
+import surge from 'surge';
+
+const octokit = new Octokit({ auth: process.env.GH_PR_TOKEN });
+const publishFn = surge().publish();
+
+// From github actions
+const ghrepo = process.env.GITHUB_REPOSITORY || '';
+const [owner, repo] = ghrepo.split('/');
+const prnum = process.env.GH_PR_NUM;
+const prbranch = process.env.GITHUB_REF.split('/').pop();
+
+const uploadFolder = process.argv[2];
+if (!uploadFolder) {
+ process.exit(1);
+}
+
+const uploadFolderName = path.basename(uploadFolder);
+let uploadURL = `pf-react-${prnum ? `pr-${prnum}` : prbranch}`.replace(/[/|.]/g, '-');
+
+switch (uploadFolderName) {
+ case 'coverage':
+ uploadURL += '-a11y.surge.sh';
+ break;
+ case 'public':
+ if (!prnum && prbranch === 'main') {
+ uploadURL = 'pf-react-staging.patternfly.org';
+ } else {
+ uploadURL += '.surge.sh';
+ }
+ break;
+ default:
+ uploadURL += `-${uploadFolderName}`;
+ uploadURL += '.surge.sh';
+ break;
+}
+
+publishFn({
+ project: uploadFolder,
+ p: uploadFolder,
+ domain: uploadURL,
+ d: uploadURL,
+ e: 'https://surge.surge.sh',
+ endpoint: 'https://surge.surge.sh'
+});
+
+function tryAddComment(comment, commentBody) {
+ if (!commentBody.includes(comment)) {
+ return comment;
+ }
+ return '';
+}
+
+if (prnum) {
+ octokit.issues
+ .listComments({
+ owner,
+ repo,
+ issue_number: prnum
+ })
+ .then((res) => res.data)
+ .then((comments) => {
+ let commentBody = '';
+ const existingComment = comments.find((comment) => comment.user.login === 'patternfly-build');
+ if (existingComment) {
+ commentBody += existingComment.body.trim();
+ commentBody += '\n\n';
+ }
+
+ if (uploadFolderName === 'public') {
+ commentBody += tryAddComment(`Preview: https://${uploadURL}`, commentBody);
+ } else if (uploadFolderName === 'coverage') {
+ commentBody += tryAddComment(`A11y report: https://${uploadURL}`, commentBody);
+ }
+
+ if (existingComment) {
+ octokit.issues
+ .updateComment({
+ owner,
+ repo,
+ comment_id: existingComment.id,
+ body: commentBody
+ })
+ .then(() => console.log('Updated comment!'));
+ } else {
+ octokit.issues
+ .createComment({
+ owner,
+ repo,
+ issue_number: prnum,
+ body: commentBody
+ })
+ .then(() => console.log('Created comment!'));
+ }
+ });
+}
diff --git a/.github/workflows-src/partials/build.yml b/.github/workflows-src/partials/build.yml
deleted file mode 100644
index 3c3672e2b66..00000000000
--- a/.github/workflows-src/partials/build.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-build:
- runs-on: ubuntu-latest
- env:
- GH_PR_NUM: ${{ github.event.number }}
- steps:
- %checkout%
- %install%
- %dist%
diff --git a/.github/workflows-src/partials/checkout.yml b/.github/workflows-src/partials/checkout.yml
deleted file mode 100644
index 1cf27edd29d..00000000000
--- a/.github/workflows-src/partials/checkout.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-- uses: actions/checkout@v2
-# Yes, we really want to checkout the PR
-- run: |
- if [[ ! -z "${GH_PR_NUM}" ]]; then
- echo "Checking out PR"
- git fetch origin pull/$GH_PR_NUM/head:tmp
- git checkout tmp
- fi
diff --git a/.github/workflows-src/partials/demo_app.yml b/.github/workflows-src/partials/demo_app.yml
deleted file mode 100644
index ae66f8650e5..00000000000
--- a/.github/workflows-src/partials/demo_app.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-demo_app:
- runs-on: ubuntu-latest
- env:
- GH_PR_NUM: ${{ github.event.number }}
- needs: build
- steps:
- %checkout%
- %install%
- %dist%
- - name: Build demo app
- run: yarn build:integration
- - name: Upload demo app
- uses: actions/upload-artifact@v2
- with:
- name: demo-app
- path: packages/react-integration/demo-app-ts/public
diff --git a/.github/workflows-src/partials/dist.yml b/.github/workflows-src/partials/dist.yml
deleted file mode 100644
index 22e187f23f0..00000000000
--- a/.github/workflows-src/partials/dist.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-- uses: actions/cache@v2
- id: dist
- name: Cache dist
- with:
- path: |
- packages/*/dist
- packages/react-styles/css
- key: ${{ runner.os }}-dist-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock', 'package.json', 'packages/*/*', '!packages/*/dist', '!packages/*/node_modules') }}
-- name: Build dist
- run: yarn build && yarn build:umd
- if: steps.dist.outputs.cache-hit != 'true'
diff --git a/.github/workflows-src/partials/docs.yml b/.github/workflows-src/partials/docs.yml
deleted file mode 100644
index 4d5d49717bf..00000000000
--- a/.github/workflows-src/partials/docs.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-docs:
- runs-on: ubuntu-latest
- needs: build
- env:
- SURGE_LOGIN: ${{ secrets.SURGE_LOGIN }}
- SURGE_TOKEN: ${{ secrets.SURGE_TOKEN }}
- GH_PR_TOKEN: ${{ secrets.GH_PR_TOKEN }}
- GH_PR_NUM: ${{ github.event.number }}
- steps:
- %checkout%
- %install%
- %dist%
- - uses: actions/cache@v2
- id: docs-cache
- name: Cache webpack
- with:
- path: '.cache'
- key: ${{ runner.os }}-v4-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }}
- - name: Build docs
- run: yarn build:docs
- - name: Upload docs
- run: node .github/upload-preview.js packages/react-docs/public
- if: always()
-# - name: a11y tests
-# run: yarn serve:docs & yarn test:a11y
-# - name: Upload a11y results
-# run: node .github/upload-preview.js packages/react-docs/coverage
-# if: always()
diff --git a/.github/workflows-src/partials/install.yml b/.github/workflows-src/partials/install.yml
deleted file mode 100644
index 289194abc7d..00000000000
--- a/.github/workflows-src/partials/install.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-- uses: actions/setup-node@v1
- with:
- node-version: '14'
-- uses: actions/cache@v2
- id: yarn-cache
- name: Cache npm deps
- with:
- path: |
- node_modules
- **/node_modules
- ~/.cache/Cypress
- key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }}
-- run: yarn install --frozen-lockfile
- if: steps.yarn-cache.outputs.cache-hit != 'true'
-
diff --git a/.github/workflows-src/partials/lint.yml b/.github/workflows-src/partials/lint.yml
deleted file mode 100644
index 2cb58094e09..00000000000
--- a/.github/workflows-src/partials/lint.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-lint:
- runs-on: ubuntu-latest
- env:
- GH_PR_NUM: ${{ github.event.number }}
- needs: build
- steps:
- %checkout%
- %install%
- - uses: actions/cache@v2
- id: lint-cache
- name: Load lint cache
- with:
- path: '.eslintcache'
- key: ${{ runner.os }}-lint-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }}
- - name: ESLint
- run: yarn lint:ts
- - name: MDLint
- run: yarn lint:md
- - name: '@patternfly/patternfly versions match'
- run: yarn lint:versions
-
diff --git a/.github/workflows-src/partials/test_integration.yml b/.github/workflows-src/partials/test_integration.yml
deleted file mode 100644
index 292bd347657..00000000000
--- a/.github/workflows-src/partials/test_integration.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-test_integration:
- runs-on: ubuntu-latest
- env:
- GH_PR_NUM: ${{ github.event.number }}
- needs: demo_app
- strategy:
- fail-fast: false
- matrix:
- worker_num: [0, 1, 2, 3, 4]
- worker_count: [5]
- steps:
- %checkout%
- %install%
- %dist%
- - name: Download demo app
- uses: actions/download-artifact@v2
- with:
- name: demo-app
- path: packages/react-integration/demo-app-ts/public
- - run: printenv
- - name: Cypress tests
- run: yarn serve:integration & yarn test:integration -s $(node .github/split.js)
- env:
- WORKER_NUM: ${{ matrix.worker_num }}
- WORKER_COUNT: ${{ matrix.worker_count }}
diff --git a/.github/workflows-src/partials/test_jest.yml b/.github/workflows-src/partials/test_jest.yml
deleted file mode 100644
index a04be2eedff..00000000000
--- a/.github/workflows-src/partials/test_jest.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-test_jest:
- runs-on: ubuntu-latest
- env:
- GH_PR_NUM: ${{ github.event.number }}
- needs: build
- steps:
- %checkout%
- %install%
- %dist%
- - name: PF4 Jest Tests
- run: yarn test --maxWorkers=2
diff --git a/.github/workflows-src/pr-preview.yml b/.github/workflows-src/pr-preview.yml
deleted file mode 100644
index cc28536e0e2..00000000000
--- a/.github/workflows-src/pr-preview.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: build-test-deploy
-on: pull_request_target
-jobs:
- %build%
- %lint%
- %test_jest%
- %docs%
- %demo_app%
- %test_integration%
-
diff --git a/.github/workflows-src/release.yml b/.github/workflows-src/release.yml
deleted file mode 100644
index 3733ec2cd0c..00000000000
--- a/.github/workflows-src/release.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-name: release
-on:
- push:
- branches:
- - main
-jobs:
- %build%
- %lint%
- %test_jest%
- %docs%
- %demo_app%
- %test_integration%
- deploy:
- runs-on: ubuntu-latest
- needs: [lint, test_jest, docs, test_integration]
- env:
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- GH_TOKEN: ${{ secrets.GH_TOKEN_REDALLEN }} # needs to be an admin token to get around branch protection
- GH_PR_TOKEN: ${{ secrets.GH_PR_TOKEN }}
- steps:
- - uses: actions/checkout@v2
- with:
- token: ${{ secrets.GH_TOKEN_REDALLEN }} # needs to be an admin token to get around branch protection
- %install%
- %dist%
- - name: Deploy to NPM and Github
- run: .github/release.sh
-
diff --git a/.github/workflows/add-new-issues-to-project.yml b/.github/workflows/add-new-issues-to-project.yml
new file mode 100644
index 00000000000..ec999f05b1a
--- /dev/null
+++ b/.github/workflows/add-new-issues-to-project.yml
@@ -0,0 +1,40 @@
+name: Add new issues to PatternFly Issues project
+on:
+ issues:
+ types:
+ - opened
+jobs:
+ add-to-project:
+ name: Add issue to project
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/add-to-project@v1.0.2
+ with:
+ project-url: https://github.com/orgs/patternfly/projects/7
+ github-token: ${{ secrets.GH_PROJECTS }}
+ label-issue:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Team Membership Checker
+ id: teamcheck
+ # You may pin to the exact commit or the version.
+ # uses: TheModdingInquisition/actions-team-membership@a69636a92bc927f32c3910baac06bacc949c984c
+ uses: TheModdingInquisition/actions-team-membership@v1.0
+ with:
+ # Repository token. GitHub Action token is used by default(recommended). But you can also use the other token(e.g. personal access token).
+ token: ${{ secrets.GH_READ_ORG_TOKEN }}
+ # The team to check for.
+ team: 'frequent-flyers'
+ # The organization of the team to check for. Defaults to the context organization.
+ organization: 'patternfly'
+ # If the action should exit if the user is not part of the team.
+ exit: false
+
+ - name: Add label if user is a team member
+ if: steps.teamcheck.outputs.permitted == 'true'
+ run: |
+ curl -X POST \
+ -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
+ -H "Accept: application/vnd.github.v3+json" \
+ https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/labels \
+ -d '{"labels":["PF Team"]}'
diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml
new file mode 100644
index 00000000000..ba9dbe11555
--- /dev/null
+++ b/.github/workflows/documentation.yml
@@ -0,0 +1,49 @@
+name: Documentation
+on:
+ pull_request_target:
+ workflow_call:
+ secrets:
+ SURGE_LOGIN:
+ required: true
+ SURGE_TOKEN:
+ required: true
+ GH_PR_TOKEN:
+ required: true
+jobs:
+ deploy:
+ name: Build, test & deploy
+ runs-on: ubuntu-latest
+ env:
+ SURGE_LOGIN: ${{ secrets.SURGE_LOGIN }}
+ SURGE_TOKEN: ${{ secrets.SURGE_TOKEN }}
+ GH_PR_TOKEN: ${{ secrets.GH_PR_TOKEN }}
+ GH_PR_NUM: ${{ github.event.number }}
+ steps:
+ - name: Check out project from PR branch
+ if: github.event_name == 'pull_request_target'
+ uses: actions/checkout@v4
+ with:
+ # Checkout the merge commit so that we can access the PR's changes.
+ # This is nessesary because `pull_request_target` checks out the base branch (e.g. `main`) by default.
+ ref: refs/pull/${{ env.GH_PR_NUM }}/head
+
+ - name: Check out project
+ if: github.event_name != 'pull_request_target'
+ uses: actions/checkout@v4
+
+ - name: Set up and build project
+ uses: ./.github/actions/setup-project
+
+ - name: Build documentation
+ run: yarn build:docs
+
+ - name: Upload documentation
+ if: always()
+ run: node .github/upload-preview.mjs packages/react-docs/public
+
+ - name: Run accessibility tests
+ run: yarn serve:docs & yarn test:a11y
+
+ - name: Upload accessibility results
+ if: always()
+ run: node .github/upload-preview.mjs packages/react-docs/coverage
diff --git a/.github/workflows/extensions.yml b/.github/workflows/extensions.yml
new file mode 100644
index 00000000000..3f5632da74f
--- /dev/null
+++ b/.github/workflows/extensions.yml
@@ -0,0 +1,15 @@
+name: Add relevant issues to extensions project board
+on:
+ issues:
+ types:
+ - labeled
+jobs:
+ add-to-extensions:
+ if: github.event.label.name == 'extension'
+ name: Add issue to extensions board
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/add-to-project@v1.0.2
+ with:
+ project-url: https://github.com/orgs/patternfly/projects/12
+ github-token: ${{ secrets.GH_PROJECTS }}
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 00000000000..f0e9552023e
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,99 @@
+name: CI
+on:
+ pull_request:
+ workflow_call:
+jobs:
+ lint:
+ name: Lint
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check out project
+ uses: actions/checkout@v4
+
+ - name: Set up project
+ uses: ./.github/actions/setup-project
+ with:
+ skip-build: true
+
+ - uses: actions/cache@v4
+ name: Cache files proccesed by ESLint
+ with:
+ path: .eslintcache
+ key: ${{ runner.os }}-eslint-cache
+
+ - name: Run linter
+ run: yarn lint:all
+
+ build:
+ name: Build
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check out project
+ uses: actions/checkout@v4
+
+ - name: Set up and build project
+ uses: ./.github/actions/setup-project
+
+ unit-tests:
+ name: Unit tests
+ runs-on: ubuntu-latest
+ needs: build
+ steps:
+ - name: Check out project
+ uses: actions/checkout@v4
+
+ - name: Set up and build project
+ uses: ./.github/actions/setup-project
+
+ - name: Run tests
+ run: yarn test --maxWorkers=2
+
+ demo-app:
+ name: Build demo app
+ runs-on: ubuntu-latest
+ needs: build
+ steps:
+ - name: Check out project
+ uses: actions/checkout@v4
+
+ - name: Set up and build project
+ uses: ./.github/actions/setup-project
+
+ - name: Build demo app
+ run: yarn build:integration
+
+ - name: Upload demo app
+ uses: actions/upload-artifact@v4
+ with:
+ name: demo-app
+ path: packages/react-integration/demo-app-ts/dist
+
+ integration-tests:
+ name: Integration tests
+ runs-on: ubuntu-latest
+ needs: demo-app
+ strategy:
+ fail-fast: false
+ matrix:
+ worker: [0, 1, 2, 3, 4]
+ steps:
+ - name: Check out project
+ uses: actions/checkout@v4
+
+ - name: Set up and build project
+ uses: ./.github/actions/setup-project
+
+ - name: Download demo app
+ uses: actions/download-artifact@v4
+ with:
+ name: demo-app
+ path: packages/react-integration/demo-app-ts/dist
+
+ - name: Print environment variables
+ run: printenv
+
+ - name: Run Cypress tests
+ run: yarn serve:integration & yarn test:integration -s $(node .github/split.mjs)
+ env:
+ WORKER_NUM: ${{ matrix.worker }}
+ WORKER_COUNT: 5
diff --git a/.github/workflows/pr-preview.yml b/.github/workflows/pr-preview.yml
deleted file mode 100644
index 257b795deea..00000000000
--- a/.github/workflows/pr-preview.yml
+++ /dev/null
@@ -1,283 +0,0 @@
-### WARNING -- this file was generated by generate-workflows.js
-name: build-test-deploy
-on: pull_request_target
-jobs:
- build:
- runs-on: ubuntu-latest
- env:
- GH_PR_NUM: ${{ github.event.number }}
- steps:
- - uses: actions/checkout@v2
- # Yes, we really want to checkout the PR
- - run: |
- if [[ ! -z "${GH_PR_NUM}" ]]; then
- echo "Checking out PR"
- git fetch origin pull/$GH_PR_NUM/head:tmp
- git checkout tmp
- fi
- - uses: actions/setup-node@v1
- with:
- node-version: '14'
- - uses: actions/cache@v2
- id: yarn-cache
- name: Cache npm deps
- with:
- path: |
- node_modules
- **/node_modules
- ~/.cache/Cypress
- key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }}
- - run: yarn install --frozen-lockfile
- if: steps.yarn-cache.outputs.cache-hit != 'true'
- - uses: actions/cache@v2
- id: dist
- name: Cache dist
- with:
- path: |
- packages/*/dist
- packages/react-styles/css
- key: ${{ runner.os }}-dist-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock', 'package.json', 'packages/*/*', '!packages/*/dist', '!packages/*/node_modules') }}
- - name: Build dist
- run: yarn build && yarn build:umd
- if: steps.dist.outputs.cache-hit != 'true'
- lint:
- runs-on: ubuntu-latest
- env:
- GH_PR_NUM: ${{ github.event.number }}
- needs: build
- steps:
- - uses: actions/checkout@v2
- # Yes, we really want to checkout the PR
- - run: |
- if [[ ! -z "${GH_PR_NUM}" ]]; then
- echo "Checking out PR"
- git fetch origin pull/$GH_PR_NUM/head:tmp
- git checkout tmp
- fi
- - uses: actions/setup-node@v1
- with:
- node-version: '14'
- - uses: actions/cache@v2
- id: yarn-cache
- name: Cache npm deps
- with:
- path: |
- node_modules
- **/node_modules
- ~/.cache/Cypress
- key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }}
- - run: yarn install --frozen-lockfile
- if: steps.yarn-cache.outputs.cache-hit != 'true'
- - uses: actions/cache@v2
- id: lint-cache
- name: Load lint cache
- with:
- path: '.eslintcache'
- key: ${{ runner.os }}-lint-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }}
- - name: ESLint
- run: yarn lint:ts
- - name: MDLint
- run: yarn lint:md
- - name: '@patternfly/patternfly versions match'
- run: yarn lint:versions
- test_jest:
- runs-on: ubuntu-latest
- env:
- GH_PR_NUM: ${{ github.event.number }}
- needs: build
- steps:
- - uses: actions/checkout@v2
- # Yes, we really want to checkout the PR
- - run: |
- if [[ ! -z "${GH_PR_NUM}" ]]; then
- echo "Checking out PR"
- git fetch origin pull/$GH_PR_NUM/head:tmp
- git checkout tmp
- fi
- - uses: actions/setup-node@v1
- with:
- node-version: '14'
- - uses: actions/cache@v2
- id: yarn-cache
- name: Cache npm deps
- with:
- path: |
- node_modules
- **/node_modules
- ~/.cache/Cypress
- key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }}
- - run: yarn install --frozen-lockfile
- if: steps.yarn-cache.outputs.cache-hit != 'true'
- - uses: actions/cache@v2
- id: dist
- name: Cache dist
- with:
- path: |
- packages/*/dist
- packages/react-styles/css
- key: ${{ runner.os }}-dist-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock', 'package.json', 'packages/*/*', '!packages/*/dist', '!packages/*/node_modules') }}
- - name: Build dist
- run: yarn build && yarn build:umd
- if: steps.dist.outputs.cache-hit != 'true'
- - name: PF4 Jest Tests
- run: yarn test --maxWorkers=2
- docs:
- runs-on: ubuntu-latest
- needs: build
- env:
- SURGE_LOGIN: ${{ secrets.SURGE_LOGIN }}
- SURGE_TOKEN: ${{ secrets.SURGE_TOKEN }}
- GH_PR_TOKEN: ${{ secrets.GH_PR_TOKEN }}
- GH_PR_NUM: ${{ github.event.number }}
- steps:
- - uses: actions/checkout@v2
- # Yes, we really want to checkout the PR
- - run: |
- if [[ ! -z "${GH_PR_NUM}" ]]; then
- echo "Checking out PR"
- git fetch origin pull/$GH_PR_NUM/head:tmp
- git checkout tmp
- fi
- - uses: actions/setup-node@v1
- with:
- node-version: '14'
- - uses: actions/cache@v2
- id: yarn-cache
- name: Cache npm deps
- with:
- path: |
- node_modules
- **/node_modules
- ~/.cache/Cypress
- key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }}
- - run: yarn install --frozen-lockfile
- if: steps.yarn-cache.outputs.cache-hit != 'true'
- - uses: actions/cache@v2
- id: dist
- name: Cache dist
- with:
- path: |
- packages/*/dist
- packages/react-styles/css
- key: ${{ runner.os }}-dist-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock', 'package.json', 'packages/*/*', '!packages/*/dist', '!packages/*/node_modules') }}
- - name: Build dist
- run: yarn build && yarn build:umd
- if: steps.dist.outputs.cache-hit != 'true'
- - uses: actions/cache@v2
- id: docs-cache
- name: Cache webpack
- with:
- path: '.cache'
- key: ${{ runner.os }}-v4-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }}
- - name: Build docs
- run: yarn build:docs
- - name: Upload docs
- run: node .github/upload-preview.js packages/react-docs/public
- if: always()
- # - name: a11y tests
- # run: yarn serve:docs & yarn test:a11y
- # - name: Upload a11y results
- # run: node .github/upload-preview.js packages/react-docs/coverage
- # if: always()
- demo_app:
- runs-on: ubuntu-latest
- env:
- GH_PR_NUM: ${{ github.event.number }}
- needs: build
- steps:
- - uses: actions/checkout@v2
- # Yes, we really want to checkout the PR
- - run: |
- if [[ ! -z "${GH_PR_NUM}" ]]; then
- echo "Checking out PR"
- git fetch origin pull/$GH_PR_NUM/head:tmp
- git checkout tmp
- fi
- - uses: actions/setup-node@v1
- with:
- node-version: '14'
- - uses: actions/cache@v2
- id: yarn-cache
- name: Cache npm deps
- with:
- path: |
- node_modules
- **/node_modules
- ~/.cache/Cypress
- key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }}
- - run: yarn install --frozen-lockfile
- if: steps.yarn-cache.outputs.cache-hit != 'true'
- - uses: actions/cache@v2
- id: dist
- name: Cache dist
- with:
- path: |
- packages/*/dist
- packages/react-styles/css
- key: ${{ runner.os }}-dist-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock', 'package.json', 'packages/*/*', '!packages/*/dist', '!packages/*/node_modules') }}
- - name: Build dist
- run: yarn build && yarn build:umd
- if: steps.dist.outputs.cache-hit != 'true'
- - name: Build demo app
- run: yarn build:integration
- - name: Upload demo app
- uses: actions/upload-artifact@v2
- with:
- name: demo-app
- path: packages/react-integration/demo-app-ts/public
- test_integration:
- runs-on: ubuntu-latest
- env:
- GH_PR_NUM: ${{ github.event.number }}
- needs: demo_app
- strategy:
- fail-fast: false
- matrix:
- worker_num: [0, 1, 2, 3, 4]
- worker_count: [5]
- steps:
- - uses: actions/checkout@v2
- # Yes, we really want to checkout the PR
- - run: |
- if [[ ! -z "${GH_PR_NUM}" ]]; then
- echo "Checking out PR"
- git fetch origin pull/$GH_PR_NUM/head:tmp
- git checkout tmp
- fi
- - uses: actions/setup-node@v1
- with:
- node-version: '14'
- - uses: actions/cache@v2
- id: yarn-cache
- name: Cache npm deps
- with:
- path: |
- node_modules
- **/node_modules
- ~/.cache/Cypress
- key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }}
- - run: yarn install --frozen-lockfile
- if: steps.yarn-cache.outputs.cache-hit != 'true'
- - uses: actions/cache@v2
- id: dist
- name: Cache dist
- with:
- path: |
- packages/*/dist
- packages/react-styles/css
- key: ${{ runner.os }}-dist-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock', 'package.json', 'packages/*/*', '!packages/*/dist', '!packages/*/node_modules') }}
- - name: Build dist
- run: yarn build && yarn build:umd
- if: steps.dist.outputs.cache-hit != 'true'
- - name: Download demo app
- uses: actions/download-artifact@v2
- with:
- name: demo-app
- path: packages/react-integration/demo-app-ts/public
- - run: printenv
- - name: Cypress tests
- run: yarn serve:integration & yarn test:integration -s $(node .github/split.js)
- env:
- WORKER_NUM: ${{ matrix.worker_num }}
- WORKER_COUNT: ${{ matrix.worker_count }}
-
diff --git a/.github/workflows/promote.yml b/.github/workflows/promote.yml
new file mode 100644
index 00000000000..7d85ee4d25f
--- /dev/null
+++ b/.github/workflows/promote.yml
@@ -0,0 +1,27 @@
+name: Promote
+on:
+ workflow_dispatch:
+ inputs:
+ patternfly-version:
+ description: The version of PatternFly (`@patternfly/patternfly`) to promote to.
+ required: false
+jobs:
+ deploy:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check out project
+ uses: actions/checkout@v4
+ with:
+ # Pass in an administrator token to get around branch protection.
+ token: ${{ secrets.GH_TOKEN_REDALLEN }}
+
+ - name: Set up and build project
+ uses: ./.github/actions/setup-project
+ with:
+ skip-build-cache: true
+
+ - name: Deploy to NPM and Github
+ run: .github/promote.sh
+ env:
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
+ PATTERNFLY_VERSION: ${{ github.event.inputs.patternfly-version }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 088edbcf98f..66e9c84d2df 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -1,324 +1,42 @@
-### WARNING -- this file was generated by generate-workflows.js
-name: release
+name: Release
on:
push:
branches:
- main
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
jobs:
- build:
- runs-on: ubuntu-latest
- env:
- GH_PR_NUM: ${{ github.event.number }}
- steps:
- - uses: actions/checkout@v2
- # Yes, we really want to checkout the PR
- - run: |
- if [[ ! -z "${GH_PR_NUM}" ]]; then
- echo "Checking out PR"
- git fetch origin pull/$GH_PR_NUM/head:tmp
- git checkout tmp
- fi
- - uses: actions/setup-node@v1
- with:
- node-version: '14'
- - uses: actions/cache@v2
- id: yarn-cache
- name: Cache npm deps
- with:
- path: |
- node_modules
- **/node_modules
- ~/.cache/Cypress
- key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }}
- - run: yarn install --frozen-lockfile
- if: steps.yarn-cache.outputs.cache-hit != 'true'
- - uses: actions/cache@v2
- id: dist
- name: Cache dist
- with:
- path: |
- packages/*/dist
- packages/react-styles/css
- key: ${{ runner.os }}-dist-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock', 'package.json', 'packages/*/*', '!packages/*/dist', '!packages/*/node_modules') }}
- - name: Build dist
- run: yarn build && yarn build:umd
- if: steps.dist.outputs.cache-hit != 'true'
- lint:
- runs-on: ubuntu-latest
- env:
- GH_PR_NUM: ${{ github.event.number }}
- needs: build
- steps:
- - uses: actions/checkout@v2
- # Yes, we really want to checkout the PR
- - run: |
- if [[ ! -z "${GH_PR_NUM}" ]]; then
- echo "Checking out PR"
- git fetch origin pull/$GH_PR_NUM/head:tmp
- git checkout tmp
- fi
- - uses: actions/setup-node@v1
- with:
- node-version: '14'
- - uses: actions/cache@v2
- id: yarn-cache
- name: Cache npm deps
- with:
- path: |
- node_modules
- **/node_modules
- ~/.cache/Cypress
- key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }}
- - run: yarn install --frozen-lockfile
- if: steps.yarn-cache.outputs.cache-hit != 'true'
- - uses: actions/cache@v2
- id: lint-cache
- name: Load lint cache
- with:
- path: '.eslintcache'
- key: ${{ runner.os }}-lint-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }}
- - name: ESLint
- run: yarn lint:ts
- - name: MDLint
- run: yarn lint:md
- - name: '@patternfly/patternfly versions match'
- run: yarn lint:versions
- test_jest:
- runs-on: ubuntu-latest
- env:
- GH_PR_NUM: ${{ github.event.number }}
- needs: build
- steps:
- - uses: actions/checkout@v2
- # Yes, we really want to checkout the PR
- - run: |
- if [[ ! -z "${GH_PR_NUM}" ]]; then
- echo "Checking out PR"
- git fetch origin pull/$GH_PR_NUM/head:tmp
- git checkout tmp
- fi
- - uses: actions/setup-node@v1
- with:
- node-version: '14'
- - uses: actions/cache@v2
- id: yarn-cache
- name: Cache npm deps
- with:
- path: |
- node_modules
- **/node_modules
- ~/.cache/Cypress
- key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }}
- - run: yarn install --frozen-lockfile
- if: steps.yarn-cache.outputs.cache-hit != 'true'
- - uses: actions/cache@v2
- id: dist
- name: Cache dist
- with:
- path: |
- packages/*/dist
- packages/react-styles/css
- key: ${{ runner.os }}-dist-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock', 'package.json', 'packages/*/*', '!packages/*/dist', '!packages/*/node_modules') }}
- - name: Build dist
- run: yarn build && yarn build:umd
- if: steps.dist.outputs.cache-hit != 'true'
- - name: PF4 Jest Tests
- run: yarn test --maxWorkers=2
+ ci:
+ name: CI
+ uses: ./.github/workflows/main.yml
+
docs:
- runs-on: ubuntu-latest
- needs: build
- env:
- SURGE_LOGIN: ${{ secrets.SURGE_LOGIN }}
- SURGE_TOKEN: ${{ secrets.SURGE_TOKEN }}
- GH_PR_TOKEN: ${{ secrets.GH_PR_TOKEN }}
- GH_PR_NUM: ${{ github.event.number }}
- steps:
- - uses: actions/checkout@v2
- # Yes, we really want to checkout the PR
- - run: |
- if [[ ! -z "${GH_PR_NUM}" ]]; then
- echo "Checking out PR"
- git fetch origin pull/$GH_PR_NUM/head:tmp
- git checkout tmp
- fi
- - uses: actions/setup-node@v1
- with:
- node-version: '14'
- - uses: actions/cache@v2
- id: yarn-cache
- name: Cache npm deps
- with:
- path: |
- node_modules
- **/node_modules
- ~/.cache/Cypress
- key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }}
- - run: yarn install --frozen-lockfile
- if: steps.yarn-cache.outputs.cache-hit != 'true'
- - uses: actions/cache@v2
- id: dist
- name: Cache dist
- with:
- path: |
- packages/*/dist
- packages/react-styles/css
- key: ${{ runner.os }}-dist-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock', 'package.json', 'packages/*/*', '!packages/*/dist', '!packages/*/node_modules') }}
- - name: Build dist
- run: yarn build && yarn build:umd
- if: steps.dist.outputs.cache-hit != 'true'
- - uses: actions/cache@v2
- id: docs-cache
- name: Cache webpack
- with:
- path: '.cache'
- key: ${{ runner.os }}-v4-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }}
- - name: Build docs
- run: yarn build:docs
- - name: Upload docs
- run: node .github/upload-preview.js packages/react-docs/public
- if: always()
- # - name: a11y tests
- # run: yarn serve:docs & yarn test:a11y
- # - name: Upload a11y results
- # run: node .github/upload-preview.js packages/react-docs/coverage
- # if: always()
- demo_app:
- runs-on: ubuntu-latest
- env:
- GH_PR_NUM: ${{ github.event.number }}
- needs: build
- steps:
- - uses: actions/checkout@v2
- # Yes, we really want to checkout the PR
- - run: |
- if [[ ! -z "${GH_PR_NUM}" ]]; then
- echo "Checking out PR"
- git fetch origin pull/$GH_PR_NUM/head:tmp
- git checkout tmp
- fi
- - uses: actions/setup-node@v1
- with:
- node-version: '14'
- - uses: actions/cache@v2
- id: yarn-cache
- name: Cache npm deps
- with:
- path: |
- node_modules
- **/node_modules
- ~/.cache/Cypress
- key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }}
- - run: yarn install --frozen-lockfile
- if: steps.yarn-cache.outputs.cache-hit != 'true'
- - uses: actions/cache@v2
- id: dist
- name: Cache dist
- with:
- path: |
- packages/*/dist
- packages/react-styles/css
- key: ${{ runner.os }}-dist-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock', 'package.json', 'packages/*/*', '!packages/*/dist', '!packages/*/node_modules') }}
- - name: Build dist
- run: yarn build && yarn build:umd
- if: steps.dist.outputs.cache-hit != 'true'
- - name: Build demo app
- run: yarn build:integration
- - name: Upload demo app
- uses: actions/upload-artifact@v2
- with:
- name: demo-app
- path: packages/react-integration/demo-app-ts/public
- test_integration:
- runs-on: ubuntu-latest
- env:
- GH_PR_NUM: ${{ github.event.number }}
- needs: demo_app
- strategy:
- fail-fast: false
- matrix:
- worker_num: [0, 1, 2, 3, 4]
- worker_count: [5]
- steps:
- - uses: actions/checkout@v2
- # Yes, we really want to checkout the PR
- - run: |
- if [[ ! -z "${GH_PR_NUM}" ]]; then
- echo "Checking out PR"
- git fetch origin pull/$GH_PR_NUM/head:tmp
- git checkout tmp
- fi
- - uses: actions/setup-node@v1
- with:
- node-version: '14'
- - uses: actions/cache@v2
- id: yarn-cache
- name: Cache npm deps
- with:
- path: |
- node_modules
- **/node_modules
- ~/.cache/Cypress
- key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }}
- - run: yarn install --frozen-lockfile
- if: steps.yarn-cache.outputs.cache-hit != 'true'
- - uses: actions/cache@v2
- id: dist
- name: Cache dist
- with:
- path: |
- packages/*/dist
- packages/react-styles/css
- key: ${{ runner.os }}-dist-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock', 'package.json', 'packages/*/*', '!packages/*/dist', '!packages/*/node_modules') }}
- - name: Build dist
- run: yarn build && yarn build:umd
- if: steps.dist.outputs.cache-hit != 'true'
- - name: Download demo app
- uses: actions/download-artifact@v2
- with:
- name: demo-app
- path: packages/react-integration/demo-app-ts/public
- - run: printenv
- - name: Cypress tests
- run: yarn serve:integration & yarn test:integration -s $(node .github/split.js)
- env:
- WORKER_NUM: ${{ matrix.worker_num }}
- WORKER_COUNT: ${{ matrix.worker_count }}
+ name: Documentation
+ uses: ./.github/workflows/documentation.yml
+ secrets: inherit
+
deploy:
+ name: Deploy release
runs-on: ubuntu-latest
- needs: [lint, test_jest, docs, test_integration]
- env:
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- GH_TOKEN: ${{ secrets.GH_TOKEN_REDALLEN }} # needs to be an admin token to get around branch protection
- GH_PR_TOKEN: ${{ secrets.GH_PR_TOKEN }}
+ needs: [ci, docs]
steps:
- - uses: actions/checkout@v2
- with:
- token: ${{ secrets.GH_TOKEN_REDALLEN }} # needs to be an admin token to get around branch protection
- - uses: actions/setup-node@v1
+ - name: Check out project
+ uses: actions/checkout@v4
with:
- node-version: '14'
- - uses: actions/cache@v2
- id: yarn-cache
- name: Cache npm deps
- with:
- path: |
- node_modules
- **/node_modules
- ~/.cache/Cypress
- key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }}
- - run: yarn install --frozen-lockfile
- if: steps.yarn-cache.outputs.cache-hit != 'true'
- - uses: actions/cache@v2
- id: dist
- name: Cache dist
+ # Fetch all history for all branches and tags, which is needed for the release script.
+ fetch-depth: 0
+ # Pass in an administrator token to get around branch protection.
+ token: ${{ secrets.GH_TOKEN_REDALLEN }}
+
+ - name: Set up and build project
+ uses: ./.github/actions/setup-project
with:
- path: |
- packages/*/dist
- packages/react-styles/css
- key: ${{ runner.os }}-dist-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock', 'package.json', 'packages/*/*', '!packages/*/dist', '!packages/*/node_modules') }}
- - name: Build dist
- run: yarn build && yarn build:umd
- if: steps.dist.outputs.cache-hit != 'true'
+ skip-build-cache: true
+
- name: Deploy to NPM and Github
run: .github/release.sh
-
+ env:
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
+ GH_PR_TOKEN: ${{ secrets.GH_PR_TOKEN }}
+
\ No newline at end of file
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
new file mode 100644
index 00000000000..ad0513875e2
--- /dev/null
+++ b/.github/workflows/stale.yml
@@ -0,0 +1,16 @@
+name: Close stale issues and PRs
+on:
+ schedule:
+ - cron: 37 11 * * *
+jobs:
+ stale:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/stale@v9
+ with:
+ days-before-stale: 60
+ days-before-close: -1
+ exempt-issue-labels: breaking change :boom:,pinned
+ stale-issue-label: stale
+ stale-issue-message: This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
+ stale-pr-message: This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
diff --git a/.gitignore b/.gitignore
index 6ad8d9efed1..07168936c32 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@ coverage
.cache
.tmp
.eslintcache
+package-lock.json
# package managers
yarn-error.log
@@ -30,3 +31,4 @@ lerna-debug.log
.vscode
# For vim
*.swp
+.yarn
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100644
index 00000000000..081c653b345
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1 @@
+yarn exec lint-staged
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 00000000000..2adc63e5c96
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,4 @@
+# Generated icon files - these are auto-generated and should not be formatted
+packages/react-icons/scripts/icons/rhIcons*.mjs
+packages/react-icons/scripts/icons/rhdsIcons*.mjs
+
diff --git a/.yarnrc.yml b/.yarnrc.yml
new file mode 100644
index 00000000000..3186f3f0795
--- /dev/null
+++ b/.yarnrc.yml
@@ -0,0 +1 @@
+nodeLinker: node-modules
diff --git a/ADVANCED-USAGE-README.md b/ADVANCED-USAGE-README.md
deleted file mode 100644
index 88a6ecf801d..00000000000
--- a/ADVANCED-USAGE-README.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# PatternFly React
-This README covers advanced usage topics for PatternFly React users.
-
-### Table of contents
-1. [Applying Overpass Font](#Applying-Overpass-font)
-2. [Tree shaking](#Tree-shaking)
-
-## Applying Overpass font
-If you would like to use Overpass instead of the Red Hat font, simply add the class `.pf-m-overpass-font` to an element that wraps your application (ideally `` or `
`) to adopt the CSS changes that would allow opting in to the Overpass font.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 6d26e82931c..cb81f3e8134 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,59 +1,85 @@
# Contributing to PatternFly React
-> ### Looking for a quick guide to PatternFly 3 React Contribution? [Go Here](https://github.com/patternfly/patternfly-react/blob/patternfly-3/packages/patternfly-react/CONTRIBUTING.md)
->
-> ### Looking for a quick guide to PatternFly 4 React Contribution? [Go Here](./packages/react-core/CONTRIBUTING.md)
+> **Looking for a quick guide to PatternFly React Contribution?** [Go Here](./packages/react-core/CONTRIBUTING.md)
## Outline
+- [Quick Start for New Contributors](#quick-start-for-new-contributors)
+- [Community Contributors Hall of Fame](#community-contributors-hall-of-fame)
- [Code of Conduct](#code-of-conduct)
- [Issues and Project Board](#issues-and-project-board)
- [Issue Labels](#issue-labels)
- [PR Labels](#pr-labels)
- - [Project Board Columns](#project-board-columns)
- [Contribution Process](#contribution-process)
- [Creating Issues for Bugs](#creating-issues-for-bugs)
- [Creating Issues for New Components](#creating-issues-for-new-components)
- [Contributing Components](#contributing-components)
- [Adding Styling for your Components](#adding-styling-for-your-components)
- - [Using Generators](#using-generators)
+
- [Guidelines and Requirements](#guidelines-and-requirements)
- [React Component Requirements](#react-component-requirements)
- [Code Consistency](#code-consistency)
- [Code Contribution Guidelines](#code-contribution-guidelines)
+- [Troubleshooting](#troubleshooting)
- [Becoming a Maintainer](#becoming-a-maintainer)
- - [How do I become a maintainer?](how-do-i-become-a-maintainer?)
- - [How do I lose maintainers status?](how-do-i-lose-maintainers-status?)
- - [Quick Tips for New Maintainers](quick-tips-for-new-maintainers)
+ - [How do I become a maintainer?](#how-do-i-become-a-maintainer)
+ - [How do I lose maintainers status?](#how-do-i-lose-maintainers-status)
+ - [Quick Tips for New Maintainers](#quick-tips-for-new-maintainers)
+
+## Quick Start for New Contributors
+
+New to contributing to PatternFly React? Here's how to get started quickly:
+
+1. **🍴 Fork and Clone**: Fork the repository and clone it locally
+2. **📦 Install Dependencies**: Run `yarn install` to install dependencies
+3. **🏗️ Build**: Run `yarn build` to build the project
+4. **🔍 Find an Issue**: Look for issues labeled [`good first issue`](https://github.com/patternfly/patternfly-react/labels/good%20first%20issue)
+5. **🌿 Create a Branch**: Create a new branch for your changes
+6. **✅ Test**: Run `yarn test` to ensure tests pass
+7. **📝 Submit PR**: Create a pull request with a clear description
+
+**Need help?** Join us on [PatternFly Slack](https://patternfly.slack.com/) in the `#patternfly-react` channel!
+
+## Community Contributors Hall of Fame
+
+We want to recognize and celebrate our amazing community contributors who have made significant contributions to PatternFly React in the past year! 🎉
+
+### Top Community Contributors (Last 12 Months as on July 1, 2025)
+
+The following contributors (excluding PatternFly team members and bots) have made outstanding contributions to the project:
+
+1. **@Mash707** - 49 contributions
+2. **@adamviktora** - 10 contributions
+3. **@logonoff** - 5 contributions
+
+### Notable Contributors
-## Code of Conduct
+Thank you to all our community contributors for helping make PatternFly React better! Every contribution, whether it's code, documentation, bug reports, or feature requests, helps improve the library for everyone.
-This project is governed by the [Contributor Covenant version 1.4][1]. All contributors and participants
+*This list is updated periodically and reflects contributions over the past 12 months. If you'd like to join this list, check out our [contribution guidelines](#contribution-process) below!*
+
+## Code of conduct
+
+This project is governed by the [Contributor Covenant version 2.1][1]. All contributors and participants
agree to abide by its terms. To report violations, send an email to [patternfly@redhat.com][2].
-## Issues and Project Board
+## AI-assisted development guidelines
+
+Please reference [PatternFly's AI-assisted development guidelines](https://github.com/patternfly/.github/blob/main/CONTRIBUTING.md) if you'd like to contribute code generated using AI.
-We use issues to track work items, such as bug reports and feature requests. Issues can be found in the [issue tracker](https://github.com/patternfly/patternfly-react/issues) or [project board](https://github.com/patternfly/patternfly-react/projects/1). We use the project board to help visualize and manage status of an issue, and we use labels to help prioritize and identify issues.
+## Issues and project board
-### Issue Labels
+We use issues to track work items, such as bug reports and feature requests. Issues can be found in the [issue tracker](https://github.com/patternfly/patternfly-react/issues) or [project board](https://github.com/orgs/patternfly/projects/7). We use the project board to help visualize and manage status of an issue, and we use labels to help prioritize and identify issues.
+
+### Issue labels
Our issue tracker utilizes several labels to help organize and identify issues. Here's what they represent and how we use them:
-- `bug` - A bug is a _demonstrable problem_ that is caused by the code in the repository. Please check if the issue has already been reported before reporting a new bug.
-- `duplicate` - A duplicate signifies that another issue encapsulates or restates this issue. Duplicates will be closed and referenced as such.
-- `enhancement` - An enhancement is a feature request. Please provide as much detail as possible and consider whether your idea fits the scope and aims of this project.
- `breaking change` - this issue warrants a major release and potentially changes APIs for downstream consumers.
-- `chore` - this issue improves internal tooling or build processes only.
-- `documentation` - this issue affects documentation only.
-- `css` - this issue affects CSS or has stylistic changes.
- `good first issue` - Issues that are ideal for new contributors.
-- `help wanted` - Issues we need or would love help from the community to resolve.
-- `pending response` - This label indicates that the issue is awaiting reply from a contributor or a maintainer.
-- `question` - Use the question label to indicate you are having a problem with something and would like feedback from the community.
- `wontfix` - The issue is legitimate, but it is not something the team is currently able or willing to fix or implement. Issues with this label may be revisited in the future.
-- `p1`, `p2`, `p3` - These are priority labels.
-### PR Labels
+### PR labels
Since the components in patternfly-react are based on patternfly, we want to make sure these components stay in sync with the core patternfly components as documented on [patternfly.org](http://www.patternfly.org/pattern-library/). To help make sure component contributions are consistent with the [design documentation](http://www.patternfly.org/pattern-library/) and [html/css implementation](https://rawgit.com/patternfly/patternfly/master-dist/dist/tests/), we use the following labels during the PR review process.
@@ -62,30 +88,13 @@ Since the components in patternfly-react are based on patternfly, we want to mak
- `css approved` - The issue has been reviewed and approved by a member of the css team.
- `ux approved` - The issue has been reviewed and approved by a member of the ux team.
-The following labels also can be used to improve PatternFly React's [CHANGELOG.md](./CHANGELOG.md) when submitting PRs:
-
-- `bug` - this PR resolves a bug issue. Releasing will cause a patch level semantic version change.
-- `enhancement` - this PR adds a new feature and closes an `enhancement` issue. Releasing will cause a minor semantic version change.
-- `breaking change` - this PR warrants a major release and potentially changes APIs for downstream consumers. Releasing will cause a major semantic version change.
-- `chore` - this PR improves internal tooling or build processes only. These PRs do not effect release.
-- `documentation` - this PR affects documentation only. These PRs do not effect release.
-- `css` - this PR affects CSS or has minimal stylistic changes. Releasing will cause a patch level semantic version change.
-
-### Project Board Columns
+### Integration with Jira
-The project board uses the following columns to track issues:
+We sync our issues to PatternFly's private Jira board. Once an issue is sync'd, a link is added to the issue description in GitHub if someone were to want to track the Jira ticket. Any issue can be assigned an assignee in GitHub or Jira and that information will be sync'd. If an issue is closed in Jira, it will also be closed in GitHub.
-- `Backlog` - Issues that are ready to be worked and available for any contributor to take.
-- `Needs CSS/Design/Research` - Issues that require any work that would be completed outside of this repo related to css, design or research. For example some component contributions will require updates to css in the core [patternfly](https://github.com/patternfly/patternfly) repo.
-- `Assigned` - Issues that are ready to be worked and are already assigned.
-- `In Progress` - Issues that are actively being worked.
-- `PR in Review` - Issues for which a PR is open and are ready for review.
+## Contribution process
-Issues can be manually added to the project board from either the issue page or the project board page.
-
-## Contribution Process
-
-### Creating Issues for Bugs
+### Creating issues for bugs
If you find a bug within the repo, please help us track the issue by following these steps:
@@ -93,24 +102,22 @@ If you find a bug within the repo, please help us track the issue by following t
- If it does exist, but doesn’t capture key details that you have noticed, please add a comment to the existing bug.
2. Create an issue if one doesn’t already exist.
- Provide details like what component is affected, steps to reproduce, and any other information that is critical to addressing the issue
- - Assign the label “bug” to the issue
-### Creating Issues for New Components
+### Creating issues for new components
To create an issue for adding a new component to the repo, please observe the following process:
1. If the component does not yet exist as a PatternFly component, please do not start coding yet. Components contributed to PatternFly-React should have a design pattern in PatternFly or be approved PatternFly-Extension components.
2. If the component exists in PatternFly core (meaning CSS and the pattern design exists), then create an issue with the following details:
- - Assign the label `enhancement` to the issue
- Include the text “Component -“ in the beginning of the title if the issue captures a new component
- - If the component is documented as a [PatternFly Library Pattern](http://www.patternfly.org/pattern-library/), include a link to it.
+ - If the component is documented as a [PatternFly library pattern](http://www.patternfly.org/pattern-library/), include a link to it.
3. If a component is not in PatternFly, but you feel it would be a good addition to the library, please do the following:
- Open a new GitHub issue and tag it with the Extension label
- Reach out on the patternfly-react channel on slack, the mailing list or the forum to see if the issue is approved as an extension
- If it is approved, direction will be given as to which package it will go in. Generally, we are recommending most extension components go in individual packages. Several smaller common components may end up being grouped together. In the future, a generator for extension component packages will be created.
- Extension components do not undergo the same rigorous design or coding review process as core PatternFly components. If enough members of the community find them useful, we will work to move them into our core PatternFly system by starting the design process for the idea.
-### Contributing Components
+### Contributing components
Components that are ready to be contributed can be found on the project board in the backlog column. They are identified with the text “Component” in the issue title.
@@ -125,7 +132,7 @@ Once you’ve identified a component to contribute, component contributions shou
If you submit a pull request, then please also contribute by reviewing other pull requests. Please remember that reviewing other contributions is just as important!
-### Adding Styling for your Components
+### Adding styling for your components
Ideally, all the styles that are needed for the components in patternfly-react would be defined in the core [patternfly](https://github.com/patternfly/patternfly) repo. However, there may be cases where additional styles are needed to complete the patternfly-react component contribution. In the case where the styles are specific to the component implementation in the patternfly-react repo, then the styles would remain in the repo. In the case where the component does not exist yet in the core pattenrfly repo and styles are needed for the component in the patternfly-react repo, then the styles would only remain in the patternfly-react repo until the component is added to the core patternfly repo. Once the styles are available as part of core patternfly repo, it will be removed from the patternfly-react repo.
@@ -138,27 +145,11 @@ Inside the package directory:
- Add a Sass file to the `sass/patternfly-react/` directory and use the file name `_.scss`
- Import the Sass file into `sass/patternfly-react/_patternfly-react.scss` using `@import "";`
-### Using Generators
-
-To make contributing components and packages easier a generator utility has been provided.
-
-To start the generator run:
-
-```bash
-yarn generate
-```
-
-Follow the prompts to generate the desired component or package.
-
-Currently the following generators are provided
-- PatternFly 4 Component
-- PatternFly 3 Component (only available on the `patternfly-3` branch, see [this guide](https://github.com/patternfly/patternfly-react/blob/patternfly-3/packages/patternfly-react/CONTRIBUTING.md))
-- Package
-## Guidelines and Requirements
+## Guidelines and requirements
-### React Component Requirements
+### React component requirements
Please ensure that all React UI components contributed meet the following guidelines:
@@ -168,10 +159,10 @@ Please ensure that all React UI components contributed meet the following guidel
- Provide associated examples for documentation in the examples directory for the component.
- Provide a [jest snapshot test](https://facebook.github.io/jest/docs/snapshot-testing.html) to ensure your UI markup does not change unexpectedly.
- Ensure the component's rendered design and documentation examples meet [PatternFly design standard](https://github.com/patternfly/patternfly-design).
- **Note:** If your component does not yet have PatternFly design documentation, the PatternFly React design team will first confirm that the pattern passes the [PatternFly Decision Tree](https://github.com/patternfly/patternfly-design/blob/master/resources/decision-tree/PatternflyDecisionTree.pdf) and then start the process for generating design documentation.
+ **Note:** If your component does not yet have PatternFly design documentation, the PatternFly React design team will first confirm that the pattern passes the [PatternFly decision tree](https://github.com/patternfly/patternfly-design/blob/master/resources/decision-tree/PatternflyDecisionTree.pdf) and then start the process for generating design documentation.
- Ensure the code is properly formatted and there are no linting errors. PatternFly React uses custom eslint configuration based on [Javascript Standard Style](https://standardjs.com/) and [Prettier](https://github.com/prettier/prettier) for code formatting. You can automatically format your code with `yarn prettier` and run the project's linter with `yarn lint`.
-### Code Consistency
+### Code consistency
- All files and folders under your package's `src/components` should name with PascalCase except `index.js` files
- If you need a constant file, it should be called `{Component_Name}Constants.js` (Component_Name with PascalCase)
@@ -188,76 +179,55 @@ Please ensure that all React UI components contributed meet the following guidel
See how to write documentation in the [`react-docs` README](./packages/react-docs/README.md)
- When destructuring or spreading expressions , use ...props as the variable name.
- **Please see the [Getting Started Readme](./GETTING-STARTED.md) for additional information in getting started with building PatterFly 4 react components.**
+ **Please see the [getting started README](./GETTING-STARTED.md) for additional information in getting started with building PatterFly react components.**
-### Code Contribution Guidelines
+### Code contribution guidelines
Adhering to the following process is the best way to get your work included in the project:
-1. [Fork](https://help.github.com/fork-a-repo/) the project, clone your fork, and configure the remotes:
-
-```bash
-# Clone your fork of the repo into the current directory
-git clone https://github.com//patternfly-react.git
-# Navigate to the newly cloned directory
-cd patternfly-react
-# Assign the original repo to a remote called "upstream"
-git remote add upstream https://github.com/patternfly/patternfly-react.git
-# Fetch the code and branches from remote repo "upstream"
-git fetch upstream
-```
+1. **Fork and set up the repository** ([More information about forks from GitHub](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo))
-2. Create a branch:
+2. **Set up your development environment**
-```text
-$ git checkout -b my-branch upstream/main
-```
+**Prerequisites:**
+- [Node.js](https://nodejs.org/en/download/package-manager) version 22 or higher
+- [Enable Corepack](https://nodejs.org/api/corepack.html) for package manager management
+- Git configured with your GitHub account
-3. Generate your Component
+**Setup commands:**
+```sh
+# Install dependencies
+yarn install
-```bash
-# Run the tool to Generate the component scaffolding
- yarn generate
-```
+# Build the project
+yarn build
-- When you select the option to generate a PatternFly 4 component, a structure resembling the following is generated
- ```text
- packages/react-core/src/[type]/[ComponentName]/
- index.js - Barrel File exporting public exports
- ComponentName.js - Component Implementation
- ComponentName.test.js - Component Tests
- ComponentName.md - Component Docs
- ```
+# Run tests to verify setup
+yarn test
-4. Develop your component. After development is complete, run build and ensure tests and lint standards pass.
-
-```text
-$ yarn build
-$ yarn test
+# Start development server (optional)
+yarn start
```
-Ensure no lint errors are introduced in `yarn-error.log` after running this command.
-
-5. Add a commit using `git commit`:
-
-This project uses [`lerna`](https://lernajs.io/) to do automatic releases and generate a changelog based on the commit history. So we follow [a convention][3] for commit messages. Please follow this convention for your commit messages.
-
-6. Rebase
+**Verify your setup:**
+- All tests should pass
+- Build should complete without errors
+- Development server should start (if running yarn start)
-Use `git rebase` (not `git merge`) to sync your work from time to time. Ensure all commits related to a single issue have been [squashed](https://github.com/ginatrapani/todo.txt-android/wiki/Squash-All-Commits-Related-to-a-Single-Issue-into-a-Single-Commit).
+3. **Develop your component** - After development is complete, run build and ensure tests and lint standards pass.
-```text
-$ git fetch upstream
-$ git rebase upstream/main
+```sh
+yarn build
+yarn test
```
-7. Push
+Ensure no lint errors are introduced in `yarn-error.log` after running this command.
-```text
-$ git push origin my-branch
-```
+***Note to Windows users:*** you may need to change the path for the lint script in package.json to be `node_modules/eslint/bin/eslint`
+
+4. **Follow commit conventions** - This project uses [`lerna`](https://lernajs.io/) to do automatic releases and generate a changelog based on the commit history. So we follow [conventional commit formatting](https://www.conventionalcommits.org/en/v1.0.0/) for all commit messages. Please follow this convention for your commit messages.
-8. Create a Pull Request
+5. **Create a pull request**
[Open a pull request](https://help.github.com/articles/using-pull-requests/) with a clear title and description against the `main` branch. Please be sure to include all of the following in your PR:
@@ -271,7 +241,7 @@ Once your pull request has been reviewed, if all conditions above have been met
Please help in ensuring all relevant issues are closed and that any subsequent issues needed have been noted with this pull request.
-### Guidelines for React implementation from Core
+### Guidelines for React implementation from core
- PF-React components should demonstrate all states implemented in Core without adding any new states.
- If a new state is introduced in PF-React, it should not be accepted by the reviewer until an issue is created explaining why this example/modification is needed in Core and PF-React. Tag a UX/UI designer.
@@ -280,7 +250,36 @@ Please help in ensuring all relevant issues are closed and that any subsequent i
- If an issue in Core will affect a component in PF-React, this issue should link to the main PF-React issue.
- The CSS Developers and UX Designers should be tagged to review their respective PF-React issue.
-## Becoming a Maintainer
+## Troubleshooting
+
+### Common Issues and Solutions
+
+**Build Failures:**
+- Ensure you're using Node.js version 22 or higher: `node --version`
+- Clear node_modules and reinstall: `rm -rf node_modules && yarn install`
+- Clear yarn cache: `yarn cache clean`
+
+**Test Failures:**
+- Run tests in watch mode for debugging: `yarn test --watch`
+- Update snapshots if components have intentionally changed: `yarn test -u`
+
+**Linting Errors:**
+- Auto-fix linting issues: `yarn lint --fix`
+- Format code with Prettier: `yarn prettier`
+
+**Development Server Issues:**
+- Clear cache and restart: `rm -rf node_modules/.cache && rm -rf packages/react-docs/.cache && yarn start`
+
+**Integration Issues:**
+- Ensure your branch is up to date with the latest changes before submitting PR
+- Squash commits related to a single issue before submitting
+
+**Still having issues?**
+- Check existing [GitHub issues](https://github.com/patternfly/patternfly-react/issues)
+- Ask for help in [PatternFly Slack](https://patternfly.slack.com/) `#patternfly-react` channel
+- Create a new issue with detailed error information
+
+## Becoming a maintainer
The documentation for becoming a maintainer has been taken from [Foreman](https://theforeman.org/handbook.html#Becomingamaintainer) and adapted for the PatternFly project.
@@ -331,6 +330,7 @@ The process for revoking someone's maintainer status is a discussion limited to
- Do not merge commits blindly. If you do not fully understand a pull request, ask existing maintainers to take a look
- Do not merge if the build is failing. Wait until tests are green to merge.
-[1]: http://contributor-covenant.org/version/1/4/code-of-conduct.md
+[1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct/
[2]: mailto:patternfly@redhat.com
[3]: https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type
+
diff --git a/GETTING-STARTED.md b/GETTING-STARTED.md
index 877bc0973ed..abd574d3573 100644
--- a/GETTING-STARTED.md
+++ b/GETTING-STARTED.md
@@ -21,11 +21,11 @@ When writing examples:
## Testing
-PatternFly React currently uses [Jest](https://facebook.github.io/jest/) for running snapshot tests and [Cypress](https://www.cypress.io/) for running integration tests.
+PatternFly React currently uses [Jest](https://facebook.github.io/jest/) with [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/) for running unit tests and [Cypress](https://www.cypress.io/) for running integration tests.
-### Jest
+### Jest + React Testing Library
-Use Jest tests to capture how the DOM should look after rendering. Save Jest tests (`*.test.tsx` files) under a `__tests__` folder. The most commonly used test is to expect a rendered component to match a snapshot. You can run these with `yarn test`.
+Use Jest and React Testing Library to capture how the DOM should look after rendering and verify that it functions as you expect. Save tests (`*.test.tsx` files) under a `__tests__` folder. A common test is to expect a rendered component to match a snapshot. You can run these with `yarn test`. You can find more information about React Testing Library as it pertains to this project and the standards we're following on our [React Testing Library Basics](https://github.com/patternfly/patternfly-react/wiki/React-Testing-Library-Basics,-Best-Practices,-and-Guidelines) wiki article.
### Cypress
@@ -38,7 +38,3 @@ PatternFly React has 3 linters you can run all at once using `yarn lint:all`. Th
### ESLint
ESLint is run on .js, .jsx, .ts, and .tsx files. It uses the [@typescript-eslint](https://github.com/typescript-eslint/typescript-eslint) parser with custom config added over the years. We write some of our own ESLint rules in `eslint-plugin-patternfly-react`. You can run this linter with `yarn lint:ts` or on specific files with `yarn lint `.
-
-### Version lint
-
-The `@patternfly` version linter is run on all `package.json` files to ensure that versions of all `@patternfly/*` packages match. This is done to prevent mismatching versions of essential PatternFly packages from accidentally being published. You can run this linter with `yarn lint:versions`.
diff --git a/README.md b/README.md
index 7053a768d5b..6ad8857abff 100644
--- a/README.md
+++ b/README.md
@@ -1,22 +1,22 @@
# PatternFly React
-
+
[](https://lernajs.io/)
-[](https://www.npmjs.com/package/@patternfly/react-core)
+[](https://www.npmjs.com/package/@patternfly/react-core)
This project provides a set of React components for the [PatternFly project](https://patternfly.org).
**Community:** [PatternFly website](https://www.patternfly.org) | [Slack](https://slack.patternfly.org) | [Medium](https://medium.com/patternfly) | [Mailing list](https://www.redhat.com/mailman/listinfo/patternfly)
-
+
### Table of contents
1. [PatternFly React packages](#patternfly-react-packages)
2. [Setup](#Setup)
3. [Contribution guidelines](#Contribution-guidelines)
-4. [License](#License)
+4. [License](#License)
-Using PatternFly 3? Take a look at the [PatternFly 3 React component information](https://github.com/patternfly/patternfly-react/blob/patternfly-3/README.md).
+Using PatternFly 3? Take a look at the [PatternFly 3 React component information](https://github.com/patternfly/patternfly-react/blob/patternfly-3/README.md).
### PatternFly React packages
-
+
| Package link | Description |
| --- | --- |
| **:blue_heart: Core packages** |
@@ -26,28 +26,25 @@ Using PatternFly 3? Take a look at the [PatternFly 3 React component informatio
| [@patternfly/react-icons](./packages/react-icons/README.md) | Icon components |
| [@patternfly/react-styles](./packages/react-styles/README.md) | PatternFly CSS styles |
| [@patternfly/react-tokens](./packages/react-tokens/README.md) | PatternFly CSS variable tokens |
-| **:yellow_heart: Extension packages** *UXD supported* |
-| [@patternfly/react-log-viewer](./packages/react-log-viewer/README.md) | Virtualized log viewer component |
+| **:yellow_heart: Extension packages** |
+| [@patternfly/react-log-viewer](https://github.com/patternfly/react-log-viewer/blob/main/README.md) | Virtualized log viewer component |
+| [@patternfly/react-catalog-view-extension](https://github.com/patternfly/react-catalog-view/blob/main/README.md) | Catalog view extension |
+| [@patternfly/react-topology](https://github.com/patternfly/react-topology/blob/main/README.md) | Topology components |
| **:open_file_folder: Supporting packages** |
| [@patternfly/react-docs](./packages/react-docs/README.md) | Gatsby documentation site for components |
| [@patternfly/react-integration](./packages/react-integration/README.md) | Cypress integration tests |
-| **:family: Extension packages** *community supported* |
-| [@patternfly/react-catalog-view-extension](./packages/react-catalog-view-extension/README.md) | Catalog view extension |
-| [@patternfly/react-virtualized-extension](./packages/react-virtualized-extension/README.md) | Table and list row virtualization extension |
-| [@patternfly/react-topology](./packages/react-topology/README.md) | Topology components |
-| [@patternfly/react-console](./packages/react-console/README.md) | Console components |
| **:x: Deprecated packages** |
-| [@patternfly/react-inline-edit-extension](./packages/react-inline-edit-extension/README.md) | Table inline edit extension |
+| [@patternfly/react-virtualized-extension](https://github.com/patternfly/react-virtualized-extension/blob/main/README.md) | Table and list row virtualization extension |
-### Setup
+### Setup
-Before you begin, check out this [overview of PatternFly](http://patternfly.org/v4/get-started/about) to get familiar with the basic elements of the design system.
+Before you begin, check out this [overview of PatternFly](http://patternfly.org/get-started/about) to get familiar with the basic elements of the design system.
#### Install a package manager
Install a package manager before using the PatternFly libraries.
-* [Use npm](https://nodejs.org/en/download)
-* [Use Yarn](https://yarnpkg.com/en/docs/getting-started)
+* [Use npm](https://nodejs.org/en/download/package-manager)
+* [Use Yarn](https://yarnpkg.com/getting-started/install)
#### Start with PatternFly React seed
@@ -72,7 +69,7 @@ If you want to start with your existing project, skip to [Install and configure
```
npm install @patternfly/react-core --save
```
-
+
**OR**
* Using yarn, run the following command to install:
@@ -83,7 +80,8 @@ If you want to start with your existing project, skip to [Install and configure
Once the library is installed, use the specific setup instructions for that library to access the components it contains. These can be found in the readme for each [library](#patternfly-react-packages).
### Contribution guidelines
-All React contributors must first be [PatternFly community contributors](https://www.patternfly.org/v4/contribute/about). If you're already a PatternFly community contributor, check out the [React contribution guidelines](https://github.com/patternfly/patternfly-react/tree/main/CONTRIBUTING.md) to make React contributions.
+All React contributors must first be [PatternFly community contributors](https://www.patternfly.org/get-started/contribute/contributing-to-patternfly). If you're already a PatternFly community contributor, check out the [React contribution guidelines](https://github.com/patternfly/patternfly-react/tree/main/CONTRIBUTING.md) to make React contributions.
### License
PatternFly React is licensed under the [MIT License](https://github.com/patternfly/patternfly-react/tree/main/LICENSE).
+
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
deleted file mode 120000
index 9a251f8b3f6..00000000000
--- a/RELEASE-NOTES.md
+++ /dev/null
@@ -1 +0,0 @@
-packages/react-docs/RELEASE-NOTES.md
\ No newline at end of file
diff --git a/UPGRADE-GUIDE.md b/UPGRADE-GUIDE.md
deleted file mode 120000
index 270cde92801..00000000000
--- a/UPGRADE-GUIDE.md
+++ /dev/null
@@ -1 +0,0 @@
-packages/react-docs/UPGRADE-GUIDE.md
\ No newline at end of file
diff --git a/babel.config.js b/babel.config.js
index c03fd5c5ab3..48db1c06484 100644
--- a/babel.config.js
+++ b/babel.config.js
@@ -1,20 +1,4 @@
module.exports = {
- presets: [
- [
- '@babel/preset-env',
- {
- targets: {
- esmodules: true
- }
- }
- ],
- '@babel/preset-typescript',
- '@babel/preset-react'
- ],
- plugins: [
- ['@babel/plugin-proposal-decorators', { legacy: true }],
- '@babel/plugin-proposal-optional-chaining',
- '@babel/plugin-proposal-class-properties',
- '@babel/plugin-proposal-object-rest-spread'
- ]
+ presets: ['@babel/preset-typescript', ['@babel/preset-react', { runtime: 'automatic' }]],
+ plugins: ['@babel/plugin-transform-modules-commonjs']
};
diff --git a/eslint.config-md.mjs b/eslint.config-md.mjs
new file mode 100644
index 00000000000..da009687858
--- /dev/null
+++ b/eslint.config-md.mjs
@@ -0,0 +1,48 @@
+import markdown from 'eslint-plugin-markdown';
+import patternflyReact from 'eslint-plugin-patternfly-react';
+import react from 'eslint-plugin-react';
+import tseslint from 'typescript-eslint';
+
+export default [
+ {
+ ignores: ['.history/*']
+ },
+ ...markdown.configs.recommended,
+ {
+ plugins: {
+ react,
+ 'patternfly-react': patternflyReact
+ },
+ languageOptions: {
+ parser: tseslint.parser
+ },
+ settings: {
+ react: {
+ version: 'detect'
+ }
+ },
+ rules: {
+ 'eol-last': 'error',
+ 'spaced-comment': 'error',
+ 'no-unused-vars': 'off',
+ 'no-this-before-super': 'error',
+ 'patternfly-react/import-tokens-icons': 'error',
+ 'react/jsx-uses-react': 'error',
+ 'react/jsx-uses-vars': 'error',
+ 'react/no-unknown-property': 'error',
+ 'react/jsx-no-undef': 'error',
+ 'no-restricted-imports': [
+ 'error',
+ {
+ paths: [
+ {
+ name: 'react',
+ importNames: ['default'],
+ message: 'Please use named imports when importing from React.'
+ }
+ ]
+ }
+ ]
+ }
+ }
+];
diff --git a/eslint.config.mjs b/eslint.config.mjs
new file mode 100644
index 00000000000..567da2b099c
--- /dev/null
+++ b/eslint.config.mjs
@@ -0,0 +1,183 @@
+import { fixupPluginRules } from '@eslint/compat';
+import js from '@eslint/js';
+import patternflyReact from 'eslint-plugin-patternfly-react';
+import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
+import reactCompiler from 'eslint-plugin-react-compiler';
+import reactHooks from 'eslint-plugin-react-hooks';
+import react from 'eslint-plugin-react';
+import testingLibrary from 'eslint-plugin-testing-library';
+import globals from 'globals';
+import tseslint from 'typescript-eslint';
+
+export default [
+ {
+ ignores: [
+ '**/dist',
+ '**/css',
+ 'packages/react-core/src/helpers/Popper/thirdparty',
+ 'packages/react-docs/patternfly-docs/generated',
+ 'packages/react-docs/coverage',
+ '.history/*',
+ 'packages/react-docs/static',
+ 'packages/react-docs/public',
+ '**/.cache'
+ ]
+ },
+ js.configs.recommended,
+ ...tseslint.configs.recommended,
+ react.configs.flat.recommended,
+ react.configs.flat['jsx-runtime'],
+ eslintPluginPrettierRecommended,
+ {
+ plugins: {
+ 'patternfly-react': fixupPluginRules(patternflyReact),
+ 'react-hooks': fixupPluginRules(reactHooks),
+ 'react-compiler': reactCompiler
+ },
+ languageOptions: {
+ globals: {
+ ...globals.browser,
+ ...globals.node,
+ ...globals.jest
+ }
+ },
+ settings: {
+ react: {
+ version: 'detect'
+ }
+ },
+ rules: {
+ ...reactHooks.configs.recommended.rules,
+ '@typescript-eslint/no-wrapper-object-types': 'off',
+ '@typescript-eslint/no-empty-object-type': 'off',
+ '@typescript-eslint/no-unsafe-function-type': 'off',
+ '@typescript-eslint/no-unused-expressions': ['error', { allowShortCircuit: true, allowTernary: true }],
+ '@typescript-eslint/ban-ts-comment': 'off',
+ '@typescript-eslint/adjacent-overload-signatures': 'error',
+ '@typescript-eslint/array-type': 'error',
+ '@typescript-eslint/ban-types': 'off',
+ '@typescript-eslint/consistent-type-assertions': 'error',
+ '@typescript-eslint/consistent-type-definitions': 'error',
+ '@typescript-eslint/explicit-member-accessibility': 'off',
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
+ '@typescript-eslint/indent': 'off',
+ '@typescript-eslint/no-duplicate-enum-values': 'off',
+ '@typescript-eslint/no-empty-function': 'off',
+ '@typescript-eslint/no-empty-interface': 'off',
+ '@typescript-eslint/no-explicit-any': 'off',
+ '@typescript-eslint/no-inferrable-types': 'off',
+ '@typescript-eslint/no-misused-new': 'error',
+ '@typescript-eslint/no-namespace': 'error',
+ '@typescript-eslint/no-unused-vars': [
+ 'error',
+ {
+ argsIgnorePattern: '^_',
+ caughtErrors: 'none'
+ }
+ ],
+ '@typescript-eslint/no-use-before-define': 'off',
+ '@typescript-eslint/no-require-imports': 'off',
+ '@typescript-eslint/prefer-for-of': 'error',
+ '@typescript-eslint/prefer-function-type': 'error',
+ '@typescript-eslint/prefer-namespace-keyword': 'error',
+ '@typescript-eslint/unified-signatures': 'error',
+ '@typescript-eslint/explicit-function-return-type': 'off',
+ 'arrow-body-style': 'error',
+ camelcase: [
+ 'error',
+ {
+ ignoreDestructuring: true,
+ allow: ['^t_[global|chart]', '^chart_']
+ // TODO: Remove 'chart_' from the allowed patterns after updating all chart examples to use the 't_chart_' format
+ }
+ ],
+ 'constructor-super': 'error',
+ curly: 'error',
+ 'dot-notation': 'error',
+ eqeqeq: ['error', 'smart'],
+ 'guard-for-in': 'error',
+ 'max-classes-per-file': ['error', 1],
+ 'max-len': 'off',
+ 'no-nested-ternary': 'error',
+ 'no-bitwise': 'error',
+ 'no-caller': 'error',
+ 'no-cond-assign': 'error',
+ 'no-console': 'error',
+ 'no-debugger': 'error',
+ 'no-empty': 'error',
+ 'no-eval': 'error',
+ 'no-new-wrappers': 'error',
+ 'no-prototype-builtins': 'off',
+ 'no-restricted-imports': [
+ 'error',
+ {
+ paths: [
+ {
+ name: 'react',
+ importNames: ['default'],
+ message: 'Please use named imports when importing from React.'
+ }
+ ]
+ }
+ ],
+ 'no-shadow': 'off',
+ 'no-throw-literal': 'error',
+ 'no-trailing-spaces': 'off',
+ 'no-undef-init': 'error',
+ 'no-constant-binary-expression': 'off',
+ 'no-unsafe-finally': 'error',
+ 'no-unused-expressions': [
+ 'error',
+ {
+ allowTernary: true,
+ allowShortCircuit: true
+ }
+ ],
+ 'no-unused-labels': 'error',
+ 'no-var': 'error',
+ 'object-shorthand': 'error',
+ 'one-var': ['error', 'never'],
+ 'patternfly-react/import-tokens-icons': 'error',
+ 'patternfly-react/no-anonymous-functions': 'error',
+ 'prefer-const': 'error',
+ radix: ['error', 'as-needed'],
+ 'react/prop-types': 0,
+ 'react/display-name': 0,
+ 'react-compiler/react-compiler': 'warn',
+ 'react-hooks/exhaustive-deps': 'warn',
+ 'react/no-unescaped-entities': ['error', { forbid: ['>', '}'] }],
+ 'spaced-comment': 'error',
+ 'use-isnan': 'error',
+ 'patternfly-react/no-layout-effect': 'error',
+ 'valid-typeof': 'off'
+ }
+ },
+ {
+ files: ['**/examples/*', '**/demos/examples/**/*'],
+ rules: {
+ 'patternfly-react/no-anonymous-functions': 'off'
+ }
+ },
+ {
+ files: ['**/*.test.[jt]s?(x)'],
+ plugins: {
+ 'testing-library': fixupPluginRules(testingLibrary)
+ },
+ rules: {
+ ...testingLibrary.configs.react.rules,
+ '@typescript-eslint/no-unused-vars': 'off',
+ 'testing-library/no-node-access': 'off',
+ 'react/jsx-key': 'off',
+ 'react/no-children-prop': 'off',
+ 'no-console': 'off'
+ }
+ },
+ {
+ files: ['packages/react-integration/demo-app-ts/**/*'],
+ rules: {
+ 'patternfly-react/no-anonymous-functions': 'off',
+ 'react/react-in-jsx-scope': 'off',
+ 'spaced-comment': 'off'
+ }
+ }
+];
diff --git a/jest.config.js b/jest.config.js
deleted file mode 100644
index f860c9e2d6c..00000000000
--- a/jest.config.js
+++ /dev/null
@@ -1,24 +0,0 @@
-module.exports = {
- collectCoverage: true,
- coverageReporters: ['lcov'],
- clearMocks: true,
- testMatch: ['**/__tests__/**/*.{js,ts}?(x)', '**/*.test.{js,ts}?(x)'],
- modulePathIgnorePatterns: [
- '/packages/*.*/dist/*.*',
- '/packages/*.*/public/*.*',
- '/packages/*.*/.cache/*.*'
- ],
- roots: ['/packages'],
- setupFiles: ['/jest.env.js'],
- snapshotSerializers: ['enzyme-to-json/serializer'],
- transform: {
- '^.+\\.[jt]sx?$': 'babel-jest'
- },
- transformIgnorePatterns: ['node_modules/(?!@patternfly|@novnc|@popperjs|lodash|monaco-editor|react-monaco-editor)'],
- testPathIgnorePatterns: ['/packages/react-integration/'],
- coveragePathIgnorePatterns: ['/dist/'],
- moduleNameMapper: {
- '\\.(css|less)$': '/packages/react-styles/__mocks__/styleMock.js'
- },
- testEnvironment: 'jsdom'
-};
diff --git a/jest.config.ts b/jest.config.ts
new file mode 100644
index 00000000000..7263343f2c9
--- /dev/null
+++ b/jest.config.ts
@@ -0,0 +1,32 @@
+/**
+ * For a detailed explanation regarding each configuration property, visit:
+ * https://jestjs.io/docs/configuration
+ */
+import type { Config } from 'jest';
+
+const config: Config = {
+ collectCoverage: true,
+ coverageReporters: ['lcov'],
+ clearMocks: true,
+ testMatch: ['**/__tests__/**/*.{js,ts}?(x)', '**/*.test.{js,ts}?(x)'],
+ modulePathIgnorePatterns: [
+ '/packages/*.*/dist/*.*',
+ '/packages/*.*/public/*.*',
+ '/packages/*.*/.cache/*.*'
+ ],
+ roots: ['/packages'],
+ transform: {
+ '^.+\\.m?[jt]sx?$': 'babel-jest',
+ '^.+\\.svg$': 'jest-transform-stub'
+ },
+ setupFilesAfterEnv: ['/packages/testSetup.ts', 'jest-canvas-mock'],
+ testPathIgnorePatterns: ['/packages/react-integration/'],
+ transformIgnorePatterns: ['/node_modules/victory-*/', '/node_modules/(?!(case-anything|echarts|zrender)/)'],
+ coveragePathIgnorePatterns: ['/dist/'],
+ moduleNameMapper: {
+ '\\.(css|less)$': '/packages/react-styles/__mocks__/styleMock.js'
+ },
+ testEnvironment: 'jsdom'
+};
+
+export default config;
diff --git a/jest.env.js b/jest.env.js
deleted file mode 100644
index 453a1093871..00000000000
--- a/jest.env.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import 'raf/polyfill';
-import { configure } from 'enzyme';
-import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
-import MutationObserver from 'mutation-observer';
-
-configure({ adapter: new Adapter() });
-
-// referenced from '@novnc/nvnc/core/util/events.js'
-// The MutationObserver is available in supported browsers, this is workaround for "jest"
-global.MutationObserver = MutationObserver;
diff --git a/lerna.json b/lerna.json
index e69c1fbc061..c0c2c7cbe39 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,5 +1,4 @@
{
- "lerna": "3.10.5",
"npmClient": "yarn",
"publishConfig": {
"access": "public",
@@ -25,5 +24,7 @@
}
},
"version": "independent",
- "useWorkspaces": true
-}
\ No newline at end of file
+ "allowBranch": ["main", "v4", "5.0.x", "6.3.x", "v5"],
+ "packages": ["packages/*", "packages/react-integration/demo-app-ts"],
+ "$schema": "node_modules/lerna/schemas/lerna-schema.json"
+}
diff --git a/package.json b/package.json
index ff202abeacc..f1d16ae8737 100644
--- a/package.json
+++ b/package.json
@@ -8,9 +8,9 @@
"url": "https://github.com/patternfly/patternfly-react.git"
},
"engines": {
- "node": ">=14.0.0",
- "yarn": ">=1.6.0"
+ "node": ">=22.17.1"
},
+ "packageManager": "yarn@4.7.0",
"keywords": [
"react",
"patternfly",
@@ -24,88 +24,103 @@
},
"homepage": "https://github.com/patternfly/patternfly-react#readme",
"devDependencies": {
- "@babel/core": "^7.0.0",
- "@babel/plugin-proposal-class-properties": "^7.0.0",
- "@babel/plugin-proposal-decorators": "^7.8.3",
- "@babel/plugin-proposal-object-rest-spread": "^7.0.0",
- "@babel/plugin-proposal-optional-chaining": "^7.9.0",
- "@babel/preset-env": "^7.0.0",
- "@babel/preset-react": "^7.0.0",
- "@babel/preset-typescript": "^7.9.0",
- "@octokit/rest": "^16.43.2",
- "@types/enzyme": "3.9.0",
- "@types/jest": "27.0.2",
- "@types/react": "^17.0.0",
- "@types/react-dom": "^17.0.0",
- "@typescript-eslint/eslint-plugin": "^4.4.1",
- "@typescript-eslint/parser": "^4.4.1",
- "@wojtekmaj/enzyme-adapter-react-17": "^0.3.1",
- "babel-jest": "^27.2.5",
- "concurrently": "^5.3.0",
- "enzyme": "3.10.0",
- "enzyme-to-json": "3.4.0",
- "eslint": "^7.11.0",
- "eslint-plugin-markdown": "^1.0.2",
- "eslint-plugin-prettier": "^3.1.4",
- "eslint-plugin-react": "^7.21.4",
- "fs-extra": "^6.0.1",
- "glob": "^7.1.2",
- "husky": "^4.3.0",
- "jest": "27.2.5",
- "jest-cli": "27.2.5",
- "lerna": "^3.19.0",
- "lint-staged": "^10.4.2",
+ "@babel/core": "^7.28.5",
+ "@babel/plugin-transform-modules-commonjs": "^7.27.1",
+ "@babel/preset-env": "^7.28.5",
+ "@babel/preset-react": "^7.28.5",
+ "@babel/preset-typescript": "^7.28.5",
+ "@eslint/compat": "^1.4.1",
+ "@eslint/js": "^9.32.0",
+ "@octokit/rest": "^21.1.1",
+ "@rhds/icons": "^2.1.0",
+ "@rollup/plugin-commonjs": "^26.0.3",
+ "@rollup/plugin-node-resolve": "^15.3.1",
+ "@rollup/plugin-replace": "^5.0.7",
+ "@rollup/plugin-terser": "^0.4.4",
+ "@testing-library/dom": "^10.4.1",
+ "@testing-library/jest-dom": "^6.9.1",
+ "@testing-library/react": "^16.3.2",
+ "@testing-library/user-event": "^14.6.1",
+ "@types/jest": "29.5.14",
+ "@types/node": "^22.16.5",
+ "@types/react": "^18.3.28",
+ "@types/react-dom": "^18.3.7",
+ "babel-jest": "^29.7.0",
+ "concurrently": "^9.2.1",
+ "eslint": "^9.32.0",
+ "eslint-config-prettier": "^10.1.8",
+ "eslint-plugin-markdown": "^5.1.0",
+ "eslint-plugin-prettier": "^5.5.5",
+ "eslint-plugin-react": "^7.37.5",
+ "eslint-plugin-react-compiler": "19.0.0-beta-ebf51a3-20250411",
+ "eslint-plugin-react-hooks": "^5.2.0",
+ "eslint-plugin-testing-library": "^7.16.2",
+ "fs-extra": "^11.3.3",
+ "glob": "^11.1.0",
+ "globals": "^15.15.0",
+ "husky": "^9.1.7",
+ "jest": "^29.7.0",
+ "jest-environment-jsdom": "^29.7.0",
+ "jest-transform-stub": "^2.0.0",
+ "lerna": "^8.2.4",
+ "lint-staged": "^15.5.2",
"mutation-observer": "^1.0.3",
- "plop": "^2.0.0",
- "prettier": "^1.18.2",
- "react": "^17.0.0",
- "react-dom": "^17.0.0",
- "surge": "^0.21.3",
- "ts-patch": "^1.4.2",
- "typescript": "^4.0.0"
+ "plop": "^4.0.5",
+ "prettier": "^3.8.1",
+ "publint": "^0.3.18",
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
+ "rimraf": "^6.1.3",
+ "rollup": "^4.57.1",
+ "rollup-plugin-scss": "^4.0.1",
+ "rollup-plugin-svg": "^2.0.0",
+ "sass": "^1.86.0",
+ "surge": "^0.24.6",
+ "ts-node": "^10.9.2",
+ "ts-patch": "^3.3.0",
+ "typescript": "^5.4.5",
+ "typescript-eslint": "^8.22.0"
},
"scripts": {
- "build": "yarn build:generate && yarn build:esm && yarn build:cjs",
+ "build": "yarn clean && yarn build:generate && yarn build:esm && yarn build:cjs && yarn build:subpaths && yarn build:single:packages",
"build:cjs": "tsc --build --verbose packages/tsconfig.cjs.json",
"build:esm": "tsc --build --verbose packages/tsconfig.json",
- "build:integration": "lerna run build:demo-app --stream",
+ "build:integration": "lerna run build --scope=demo-app-ts --stream",
"build:docs": "yarn workspace @patternfly/react-docs build:docs",
"build:generate": "lerna run generate --parallel --stream",
+ "build:subpaths": "lerna run subpaths --parallel --stream",
"build:umd": "lerna run build:umd --parallel --stream",
+ "build:single:packages": "lerna run build:single:packages",
"clean": "yarn clean:build && lerna run clean --parallel",
"clean:build": "rimraf .cache .eslintcache coverage",
"generate": "yarn plop",
- "lint": "node --max-old-space-size=4096 node_modules/.bin/eslint --ext js,jsx,ts,tsx --cache",
- "lint:all": "yarn lint:md && yarn lint:versions && yarn lint:ts",
- "lint:md": "yarn eslint packages --ext md --no-eslintrc --config .eslintrc-md.json --cache",
- "lint:ts": "yarn lint packages",
- "lint:versions": "node scripts/verifyPatternflyVersions.js",
- "prepare": "ts-patch install -s",
+ "lint": "eslint . --cache --cache-strategy content",
+ "lint:all": "yarn lint:md && yarn lint:ts",
+ "lint:md": "eslint \"**/*.md\" --config eslint.config-md.mjs --cache --cache-strategy content --no-warn-ignored",
+ "lint:ts": "yarn lint packages/*/src",
+ "lint:tests": "yarn lint packages/*/src/components/*/__tests__/*.test.*",
+ "lint:publication": "yarn workspaces foreach --all --no-private --parallel exec publint --strict",
+ "postinstall": "ts-patch install -s && husky",
"serve:docs": "yarn workspace @patternfly/react-docs serve",
- "serve:integration": "lerna run serve:demo-app",
+ "serve:integration": "lerna run preview --scope=demo-app-ts",
"start": "yarn build && concurrently --kill-others \"yarn watch\" \"yarn workspace @patternfly/react-docs develop\"",
"start:cypress": "lerna run cypress:open",
- "start:demo-app": "lerna run start:demo-app --stream",
- "test": "jest packages",
+ "start:demo-app": "lerna run dev --scope=demo-app-ts --stream",
+ "test": "TZ=EST LC_ALL=en_US.UTF8 jest packages",
"test:a11y": "lerna run test:a11y --stream",
"test:integration": "yarn workspace @patternfly/react-integration test:integration",
"uninstall": "find . -name node_modules -type d | xargs rm -rf",
"watch": "yarn build:esm --watch",
"screenshots": "yarn workspace @patternfly/react-docs screenshots"
},
- "husky": {
- "hooks": {
- "pre-commit": "lint-staged"
- }
- },
"lint-staged": {
"*.md": "yarn lint:md --fix",
- "*.{js,jsx,ts,tsx}": "yarn lint --fix",
- "*.json": "yarn lint:versions --fix"
+ "*.{js,jsx,ts,tsx}": "yarn lint --fix"
},
"workspaces": {
"packages": [
- "packages/**"
+ "packages/*",
+ "packages/react-integration/demo-app-ts"
]
}
}
diff --git a/packages/code-connect/components/AboutModal/AboutModal.figma.tsx b/packages/code-connect/components/AboutModal/AboutModal.figma.tsx
new file mode 100644
index 00000000000..fb15f4065b1
--- /dev/null
+++ b/packages/code-connect/components/AboutModal/AboutModal.figma.tsx
@@ -0,0 +1,63 @@
+import figma from '@figma/code-connect';
+import { AboutModal, Button, Content } from '@patternfly/react-core';
+
+/**
+ * PatternFly AboutModal integration for Figma Code Connect
+ * @see https://www.patternfly.org/components/about-modal
+ */
+
+figma.connect(
+ AboutModal,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=2879-13973&t=15CEJpGgVui7qP5Q-11',
+ {
+ props: {
+ productName: figma.string('Product name')
+ },
+ example: ({ productName }) => {
+ /* eslint-disable */
+ const [isOpen, setIsOpen] = React.useState(false);
+ /* eslint-enable */
+
+ return (
+ <>
+
+ setIsOpen(false)}
+ productName={productName}
+ trademark="Copyright © 2024"
+ brandImageSrc="/assets/images/brand.svg"
+ brandImageAlt="Brand Image Alt Text"
+ backgroundImageSrc="/assets/images/background.png"
+ >
+
+
+ - CFME version
+ - 5.5.3.4.20102789036450
+ - Cloudforms Version
+ - 4.1
+ - Server name
+ - 40DemoMaster
+ - User name
+ - Administrator
+ - User role
+ - EvmRole-super_administrator
+ - Browser version
+ - 601.2
+ - Browser OS
+ - Mac
+
+
+
+ >
+ );
+ }
+ }
+);
diff --git a/packages/code-connect/components/Accordion/Accordion.figma.tsx b/packages/code-connect/components/Accordion/Accordion.figma.tsx
new file mode 100644
index 00000000000..9ef35289b62
--- /dev/null
+++ b/packages/code-connect/components/Accordion/Accordion.figma.tsx
@@ -0,0 +1,27 @@
+import figma from '@figma/code-connect';
+import { Accordion } from '@patternfly/react-core';
+
+// Documentation for Accordion can be found at https://www.patternfly.org/components/accordion
+
+figma.connect(
+ Accordion,
+ 'https://www.figma.com/file/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6%3A-Components-Test?node-id=2621-623',
+ {
+ props: {
+ // enum
+ displaySize: figma.enum('Type', { 'Large Bordered': 'lg' }),
+ isBordered: figma.enum('Type', {
+ Bordered: true,
+ 'Large Bordered': true
+ }),
+ togglePosition: figma.enum('Caret position', { Left: 'start' }),
+
+ children: figma.children('Accordion toggle')
+ },
+ example: (props) => (
+
+ {props.children}
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/Accordion/AccordionToggle.figma.tsx b/packages/code-connect/components/Accordion/AccordionToggle.figma.tsx
new file mode 100644
index 00000000000..4f5708cdb6a
--- /dev/null
+++ b/packages/code-connect/components/Accordion/AccordionToggle.figma.tsx
@@ -0,0 +1,34 @@
+import figma from '@figma/code-connect';
+import { AccordionItem, AccordionToggle, AccordionContent } from '@patternfly/react-core';
+
+// Documentation for AccordionToggle can be found at https://www.patternfly.org/components/accordion
+// Note: Adding on onClick event is recommended to initialize AccordionToggle
+
+figma.connect(
+ AccordionToggle,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=1423-687',
+ {
+ props: {
+ // string
+ expandText: figma.string('Expand Text'),
+
+ // enum
+ open: figma.enum('State', { Expanded: true }),
+ toggleTextExpanded: figma.enum('State', {
+ Default: figma.string('Toggle Text'),
+ Hover: figma.string('Toggle Text'),
+ Expanded: figma.string('Toggle Text Expanded')
+ })
+ },
+ example: (props) => (
+
+ {}} id="">
+ {props.toggleTextExpanded}
+
+
+ {props.expandText}
+
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/ActionList/ActionList.figma.tsx b/packages/code-connect/components/ActionList/ActionList.figma.tsx
new file mode 100644
index 00000000000..e92199479ab
--- /dev/null
+++ b/packages/code-connect/components/ActionList/ActionList.figma.tsx
@@ -0,0 +1,20 @@
+import figma from '@figma/code-connect';
+import { ActionList } from '@patternfly/react-core';
+
+// TODO: DESIGN: Add ActionListGroup component
+// TODO: DESIGN: Add ActionListItem component
+// Documentation for ActionList can be found at https://www.patternfly.org/components/action-list
+
+figma.connect(
+ ActionList,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=6780-15839',
+ {
+ props: {
+ // enum
+ isIconList: figma.enum('Type', { 'Action icons only': true }),
+
+ children: figma.children('*')
+ },
+ example: (props) => {props.children}
+ }
+);
diff --git a/packages/code-connect/components/Alert/InlineAlert.figma.tsx b/packages/code-connect/components/Alert/InlineAlert.figma.tsx
new file mode 100644
index 00000000000..e78a587fa5e
--- /dev/null
+++ b/packages/code-connect/components/Alert/InlineAlert.figma.tsx
@@ -0,0 +1,33 @@
+import figma from '@figma/code-connect';
+import { Alert } from '@patternfly/react-core';
+
+// Documentation for Alert can be found at https://www.patternfly.org/components/alert
+
+figma.connect(
+ Alert,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=1110-2698',
+ {
+ props: {
+ // string
+ description: figma.string('✏️ Title'),
+ title: figma.string('✏️ Title'),
+
+ // boolean
+ isExpandable: figma.boolean('Expandable'),
+
+ // enum
+ variant: figma.enum('Type', {
+ Info: 'info',
+ Success: 'success',
+ Warning: 'warning',
+ Danger: 'danger',
+ Custom: 'custom'
+ })
+ },
+ example: (props) => (
+
+ {props.description}
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/Alert/InlineAlertGroup.figma.tsx b/packages/code-connect/components/Alert/InlineAlertGroup.figma.tsx
new file mode 100644
index 00000000000..cefe226d00b
--- /dev/null
+++ b/packages/code-connect/components/Alert/InlineAlertGroup.figma.tsx
@@ -0,0 +1,19 @@
+import figma from '@figma/code-connect';
+import { AlertGroup } from '@patternfly/react-core';
+
+// Documentation for Alert can be found at https://www.patternfly.org/components/alert
+
+figma.connect(
+ AlertGroup,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=1110-2780',
+ {
+ props: {
+ children: figma.children('*')
+ },
+ example: (props) => (
+
+ {props.children}
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/Alert/InlinePlainAlert.figma.tsx b/packages/code-connect/components/Alert/InlinePlainAlert.figma.tsx
new file mode 100644
index 00000000000..2da8fbeb2e7
--- /dev/null
+++ b/packages/code-connect/components/Alert/InlinePlainAlert.figma.tsx
@@ -0,0 +1,32 @@
+import figma from '@figma/code-connect';
+import { Alert } from '@patternfly/react-core';
+
+// Documentation for Alert can be found at https://www.patternfly.org/components/alert
+
+figma.connect(
+ Alert,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=1110-2754',
+ {
+ props: {
+ // string
+ description: figma.string('✏️ Title'),
+ title: figma.string('✏️ Title'),
+
+ // enum
+ variant: figma.enum('Type', {
+ Info: 'info',
+ Success: 'success',
+ Warning: 'warning',
+ Danger: 'danger',
+ Custom: 'custom'
+ }),
+
+ children: figma.children('*')
+ },
+ example: (props) => (
+
+ {props.description}
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/Alert/OverflowFooter.figma.tsx b/packages/code-connect/components/Alert/OverflowFooter.figma.tsx
new file mode 100644
index 00000000000..04a73853b41
--- /dev/null
+++ b/packages/code-connect/components/Alert/OverflowFooter.figma.tsx
@@ -0,0 +1,42 @@
+import figma from '@figma/code-connect';
+import { Alert, AlertActionCloseButton, AlertGroup } from '@patternfly/react-core';
+
+// Documentation for Alert can be found at https://www.patternfly.org/components/alert
+
+figma.connect(
+ AlertGroup,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=1110-2784',
+ {
+ props: {
+ overflowMessage: figma.string('✏️ Title')
+ },
+ example: (props) => (
+ {}} overflowMessage={props.overflowMessage}>
+ {}} />}
+ key={1}
+ />
+ {}} />}
+ key={2}
+ />
+ {}} />}
+ key={3}
+ />
+ {}} />}
+ key={4}
+ />
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/Alert/ToastAlert.figma.tsx b/packages/code-connect/components/Alert/ToastAlert.figma.tsx
new file mode 100644
index 00000000000..b7d1ef87d50
--- /dev/null
+++ b/packages/code-connect/components/Alert/ToastAlert.figma.tsx
@@ -0,0 +1,40 @@
+import figma from '@figma/code-connect';
+import { Alert } from '@patternfly/react-core';
+
+// Documentation for Alert can be found at https://www.patternfly.org/components/alert
+
+figma.connect(
+ Alert,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=1110-2587',
+ {
+ props: {
+ // string
+ description: figma.string('✏️ Title'),
+ title: figma.string('✏️ Title'),
+
+ // boolean
+ isExpandable: figma.boolean('Expandable'),
+
+ // enum
+ variant: figma.enum('Type', {
+ Custom: 'custom',
+ Danger: 'danger',
+ Info: 'info',
+ Success: 'success',
+ Warning: 'warning'
+ })
+ },
+ example: (props) => (
+
+ {props.description}
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/Alert/ToastAlertGroup.figma.tsx b/packages/code-connect/components/Alert/ToastAlertGroup.figma.tsx
new file mode 100644
index 00000000000..7a16c09a440
--- /dev/null
+++ b/packages/code-connect/components/Alert/ToastAlertGroup.figma.tsx
@@ -0,0 +1,19 @@
+import figma from '@figma/code-connect';
+import { AlertGroup } from '@patternfly/react-core';
+
+// Documentation for AlertGroup can be found at https://www.patternfly.org/components/alert
+
+figma.connect(
+ AlertGroup,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=1110-2821',
+ {
+ props: {
+ children: figma.children('*')
+ },
+ example: (props) => (
+
+ {props.children}
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/Avatar/Avatar.figma.tsx b/packages/code-connect/components/Avatar/Avatar.figma.tsx
new file mode 100644
index 00000000000..8959f3c1c9c
--- /dev/null
+++ b/packages/code-connect/components/Avatar/Avatar.figma.tsx
@@ -0,0 +1,26 @@
+import figma from '@figma/code-connect';
+import { Avatar } from '@patternfly/react-core';
+
+// Documentation for Avatar can be found at https://www.patternfly.org/components/avatar
+
+figma.connect(
+ Avatar,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6%3A-Components-Test?node-id=1561-4342',
+ {
+ props: {
+ // boolean
+ isBordered: figma.boolean('Bordered'),
+
+ // enum
+ size: figma.enum('Size', {
+ small: 'sm',
+ med: 'md',
+ lg: 'lg',
+ XL: 'xl'
+ })
+ },
+ example: (props) => (
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/BackToTop/BackToTop.figma.tsx b/packages/code-connect/components/BackToTop/BackToTop.figma.tsx
new file mode 100644
index 00000000000..c6c58f7724e
--- /dev/null
+++ b/packages/code-connect/components/BackToTop/BackToTop.figma.tsx
@@ -0,0 +1,15 @@
+import figma from '@figma/code-connect';
+import { BackToTop } from '@patternfly/react-core';
+
+// Documentation for BackToTop can be found at https://www.patternfly.org/components/back-to-top
+
+figma.connect(
+ BackToTop,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=1521-958',
+ {
+ props: {
+ text: figma.string('Text')
+ },
+ example: (props) =>
+ }
+);
diff --git a/packages/code-connect/components/Backdrop/Backdrop.figma.tsx b/packages/code-connect/components/Backdrop/Backdrop.figma.tsx
new file mode 100644
index 00000000000..3c6e02acc70
--- /dev/null
+++ b/packages/code-connect/components/Backdrop/Backdrop.figma.tsx
@@ -0,0 +1,12 @@
+import figma from '@figma/code-connect';
+import { Backdrop } from '@patternfly/react-core';
+
+// Documentation for Backdrop can be found at https://www.patternfly.org/components/backdrop
+
+figma.connect(
+ Backdrop,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6%3A-Components-Test?node-id=2873-2900',
+ {
+ example: () =>
+ }
+);
diff --git a/packages/code-connect/components/BackgroundImage/BackgroundImage.figma.tsx b/packages/code-connect/components/BackgroundImage/BackgroundImage.figma.tsx
new file mode 100644
index 00000000000..bc8654807bc
--- /dev/null
+++ b/packages/code-connect/components/BackgroundImage/BackgroundImage.figma.tsx
@@ -0,0 +1,12 @@
+import figma from '@figma/code-connect';
+import { BackgroundImage } from '@patternfly/react-core';
+
+// Documentation for BackgroundImage can be found at https://www.patternfly.org/components/background-image
+
+figma.connect(
+ BackgroundImage,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=2722-13543',
+ {
+ example: () =>
+ }
+);
diff --git a/packages/code-connect/components/Badge/Badge.figma.tsx b/packages/code-connect/components/Badge/Badge.figma.tsx
new file mode 100644
index 00000000000..d45e66a0a9a
--- /dev/null
+++ b/packages/code-connect/components/Badge/Badge.figma.tsx
@@ -0,0 +1,24 @@
+import figma from '@figma/code-connect';
+import { Badge } from '@patternfly/react-core';
+
+// Documentation for Badge can be found at https://www.patternfly.org/components/badge
+
+figma.connect(
+ Badge,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=1259-1132',
+ {
+ props: {
+ // string
+ text: figma.string('Text'),
+
+ // enum
+ isDisabled: figma.enum('Type', { disabled: true }),
+ isRead: figma.enum('Type', { Read: true })
+ },
+ example: (props) => (
+
+ {props.text}
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/Banner/NonStatusBanner.figma.tsx b/packages/code-connect/components/Banner/NonStatusBanner.figma.tsx
new file mode 100644
index 00000000000..5b11678d0c7
--- /dev/null
+++ b/packages/code-connect/components/Banner/NonStatusBanner.figma.tsx
@@ -0,0 +1,28 @@
+import figma from '@figma/code-connect';
+import { Banner } from '@patternfly/react-core';
+
+// Documentation for Banner can be found at https://www.patternfly.org/components/banner
+
+figma.connect(
+ Banner,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6%3A-Components-Test?node-id=221-1443',
+ {
+ props: {
+ // string
+ text: figma.string('✏️ Center text'),
+
+ // enum
+ color: figma.enum('Color', {
+ Red: 'red',
+ Orangered: 'orangered',
+ Orange: 'orange',
+ Yellow: 'yellow',
+ Green: 'green',
+ Teal: 'teal',
+ Blue: 'blue',
+ Purple: 'purple'
+ })
+ },
+ example: (props) => {props.text}
+ }
+);
diff --git a/packages/code-connect/components/Banner/StatusBanner.figma.tsx b/packages/code-connect/components/Banner/StatusBanner.figma.tsx
new file mode 100644
index 00000000000..83272bdd787
--- /dev/null
+++ b/packages/code-connect/components/Banner/StatusBanner.figma.tsx
@@ -0,0 +1,36 @@
+import figma from '@figma/code-connect';
+import { Banner } from '@patternfly/react-core';
+
+// Documentation for Banner can be found at https://www.patternfly.org/components/banner
+
+figma.connect(
+ Banner,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6%3A-Components-Test?node-id=221-937',
+ {
+ props: {
+ // string
+ text: figma.string('✏️ Center text'),
+
+ // enum
+ status: figma.enum('Status', {
+ Success: 'success',
+ Warning: 'warning',
+ Danger: 'danger',
+ Info: 'info',
+ Custom: 'custom'
+ }),
+ screenReaderText: figma.enum('Status', {
+ Success: 'Success banner screen reader text',
+ Warning: 'Warning banner screen reader text',
+ Danger: 'Danger banner screen reader text',
+ Info: 'Info banner screen reader text',
+ Custom: 'Custom banner screen reader text'
+ })
+ },
+ example: (props) => (
+
+ {props.text}
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/Brand/FullLogo.figma.tsx b/packages/code-connect/components/Brand/FullLogo.figma.tsx
new file mode 100644
index 00000000000..28f7f91f853
--- /dev/null
+++ b/packages/code-connect/components/Brand/FullLogo.figma.tsx
@@ -0,0 +1,14 @@
+import figma from '@figma/code-connect';
+import { Brand } from '@patternfly/react-core';
+
+// Documentation for Brand can be found at https://www.patternfly.org/components/brand
+
+figma.connect(
+ Brand,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=2104-3689',
+ {
+ example: () => (
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/Brand/MastheadLogo.figma.tsx b/packages/code-connect/components/Brand/MastheadLogo.figma.tsx
new file mode 100644
index 00000000000..c78c3da6801
--- /dev/null
+++ b/packages/code-connect/components/Brand/MastheadLogo.figma.tsx
@@ -0,0 +1,21 @@
+import figma from '@figma/code-connect';
+import { Brand } from '@patternfly/react-core';
+
+// Documentation for Brand can be found at https://www.patternfly.org/components/brand
+
+figma.connect(
+ Brand,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=2104-3644',
+ {
+ example: () => (
+
+
+
+
+
+
+
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/Breadcrumbs/Breadcrumb.figma.tsx b/packages/code-connect/components/Breadcrumbs/Breadcrumb.figma.tsx
new file mode 100644
index 00000000000..6ad19b534e8
--- /dev/null
+++ b/packages/code-connect/components/Breadcrumbs/Breadcrumb.figma.tsx
@@ -0,0 +1,15 @@
+import figma from '@figma/code-connect';
+import { Breadcrumb } from '@patternfly/react-core';
+
+// Documentation for Breadcrumb can be found at https://www.patternfly.org/components/breadcrumb
+
+figma.connect(
+ Breadcrumb,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6%3A-Components-Test?node-id=3362-283',
+ {
+ props: {
+ children: figma.children('*')
+ },
+ example: (props) => {props.children}
+ }
+);
diff --git a/packages/code-connect/components/Breadcrumbs/BreadcrumbItem.figma.tsx b/packages/code-connect/components/Breadcrumbs/BreadcrumbItem.figma.tsx
new file mode 100644
index 00000000000..6e834534dcc
--- /dev/null
+++ b/packages/code-connect/components/Breadcrumbs/BreadcrumbItem.figma.tsx
@@ -0,0 +1,22 @@
+import figma from '@figma/code-connect';
+import { BreadcrumbItem } from '@patternfly/react-core';
+
+// Documentation for BreadcrumbItem can be found at https://www.patternfly.org/components/breadcrumb
+
+figma.connect(
+ BreadcrumbItem,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=3362-74',
+ {
+ props: {
+ // string
+ text: figma.string('Text'),
+
+ // enum
+ to: figma.enum('State', {
+ Link: '#',
+ Hover: '#'
+ })
+ },
+ example: (props) => {props.text}
+ }
+);
diff --git a/packages/code-connect/components/Breadcrumbs/ExpandableBreadcrumbs.figma.tsx b/packages/code-connect/components/Breadcrumbs/ExpandableBreadcrumbs.figma.tsx
new file mode 100644
index 00000000000..47f48d3ea6a
--- /dev/null
+++ b/packages/code-connect/components/Breadcrumbs/ExpandableBreadcrumbs.figma.tsx
@@ -0,0 +1,70 @@
+import figma from '@figma/code-connect';
+import { Badge, BreadcrumbItem, Dropdown, DropdownItem, DropdownList, Icon, MenuToggle } from '@patternfly/react-core';
+import RhMicronsCaretLeftIcon from '@patternfly/react-icons/dist/esm/icons/rh-microns-caret-left-icon';
+
+// Documentation for BreadcrumbItem can be found at https://www.patternfly.org/components/breadcrumb
+
+figma.connect(
+ BreadcrumbItem,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=19922-43760',
+ {
+ props: {},
+ example: () => (
+
+ {}}
+ onOpenChange={() => {}}
+ toggle={() => (
+
+ 01
+
+ }
+ onClick={() => {}}
+ isExpanded={false}
+ variant="plainText"
+ />
+ )}
+ isOpen={false}
+ >
+
+
+
+
+ }
+ key="edit"
+ >
+ Edit
+
+ ,
+
+
+
+ }
+ key="action"
+ >
+ Deployment
+
+ ,
+
+
+
+ }
+ key="apps"
+ >
+ Applications
+
+
+
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/ClipboardCopy/ClipboardCopyBasic.figma.tsx b/packages/code-connect/components/ClipboardCopy/ClipboardCopyBasic.figma.tsx
new file mode 100644
index 00000000000..8f5047d7e1c
--- /dev/null
+++ b/packages/code-connect/components/ClipboardCopy/ClipboardCopyBasic.figma.tsx
@@ -0,0 +1,37 @@
+import figma from '@figma/code-connect';
+import { ClipboardCopy } from '@patternfly/react-core';
+
+// TODO: DESIGN: ClipboardCopy is using InputGroup improperly. There's no InputGroup wrapper for InputGroupItems
+
+figma.connect(
+ ClipboardCopy,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=9914-75835',
+ {
+ props: {
+ // enum
+ isExpanded: figma.enum('State', { Expanded: true }),
+ isReadOnly: figma.enum('State', { 'Read only': true }),
+ expansion: figma.enum('State', {
+ Expanded: 'expansion',
+ false: undefined
+ }),
+
+ inputText: figma.nestedProps('Input Group Items', {
+ value: figma.string('✏️ Input text')
+ })
+ },
+ example: (props) => (
+ // Documentation for ClipboardCopy can be found at https://www.patternfly.org/components/clipboard-copy
+ {}}
+ clickTip="Copied"
+ hoverTip="Copy"
+ isExpanded={props.isExpanded}
+ isReadOnly={props.isReadOnly}
+ variant={props.expansion}
+ >
+ {props.inputText.value}
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/ClipboardCopy/ClipboardCopyInlineCompact.figma.tsx b/packages/code-connect/components/ClipboardCopy/ClipboardCopyInlineCompact.figma.tsx
new file mode 100644
index 00000000000..5a990fae565
--- /dev/null
+++ b/packages/code-connect/components/ClipboardCopy/ClipboardCopyInlineCompact.figma.tsx
@@ -0,0 +1,19 @@
+import figma from '@figma/code-connect';
+import { ClipboardCopy } from '@patternfly/react-core';
+
+// Documentation for ClipboardCopy can be found at https://www.patternfly.org/components/clipboard-copy
+
+figma.connect(
+ ClipboardCopy,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=9914-75768',
+ {
+ props: {
+ children: figma.children('*')
+ },
+ example: (props) => (
+ {}} variant="inline-compact">
+ {props.children}
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/CodeBlock/CodeBlock.figma.tsx b/packages/code-connect/components/CodeBlock/CodeBlock.figma.tsx
new file mode 100644
index 00000000000..1f0c5696ec1
--- /dev/null
+++ b/packages/code-connect/components/CodeBlock/CodeBlock.figma.tsx
@@ -0,0 +1,43 @@
+import figma from '@figma/code-connect';
+import { CodeBlock, CodeBlockCode, ExpandableSection, ExpandableSectionToggle } from '@patternfly/react-core';
+
+// TODO: DESIGN: Configure Actions layer to contain CodeBlockAction components
+
+figma.connect(
+ CodeBlock,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=9802-5857',
+ {
+ props: {
+ editorText: 'code block code',
+
+ actions: `action1, action2, action3, action4, action5`,
+
+ // boolean
+ expandableSectionToggle: figma.boolean('Expandable', {
+ true: (
+ {}} contentId="code-block-id">
+ Show More
+
+ ),
+ false: undefined
+ }),
+ expandableSectionContent: figma.boolean('Expandable', {
+ true: (
+
+ Expandable content
+
+ ),
+ false: undefined
+ })
+ },
+ example: (props) => (
+
+
+ {props.editorText}
+ {props.expandableSectionContent}
+
+ {props.expandableSectionToggle}
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/CodeEditor/CodeEditor.figma.tsx b/packages/code-connect/components/CodeEditor/CodeEditor.figma.tsx
new file mode 100644
index 00000000000..640c9412d02
--- /dev/null
+++ b/packages/code-connect/components/CodeEditor/CodeEditor.figma.tsx
@@ -0,0 +1,42 @@
+import figma from '@figma/code-connect';
+import { CodeEditor } from '@patternfly/react-code-editor';
+
+// TODO: DESIGN: Add support for actions, wrap each action in the appropriate compnent
+// TODO: DESIGN: When shortcuts is removed, presentation breaks
+// TODO: DESIGN: configure options for actions
+// TODO: DESIGN: Add viewshortcuts
+// TODO: DESIGN: ifshortcuts is true
+// Documentation for CodeEditor can be found at https://www.patternfly.org/components/code-editor
+
+figma.connect(
+ CodeEditor,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=16994-184502',
+ {
+ props: {
+ // boolean
+ hasCustomControls: '',
+ isUploadEnabled: figma.boolean('Action 1'),
+ isCopyEnabled: figma.boolean('Action 2'),
+ isDownloadEnabled: figma.boolean('Action 3'),
+ showsLineNumbers: figma.boolean('Show Line Numbers'),
+
+ // enum
+ isMinimapVisible: figma.enum('Type', { 'Mini Map': true })
+ },
+ example: (props) => (
+ <>
+
+ >
+ )
+ }
+);
diff --git a/packages/code-connect/components/DataList/DataList.figma.tsx b/packages/code-connect/components/DataList/DataList.figma.tsx
new file mode 100644
index 00000000000..cceb9c61217
--- /dev/null
+++ b/packages/code-connect/components/DataList/DataList.figma.tsx
@@ -0,0 +1,23 @@
+import figma from '@figma/code-connect';
+import { DataList } from '@patternfly/react-core';
+
+// TODO: DESIGN: Separate examples, rename files to match their react counterparts.
+// Documentation for DataList can be found at https://www.patternfly.org/components/data-list
+
+figma.connect(
+ DataList,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=6649-80542',
+ {
+ props: {
+ // enum
+ isCompact: figma.enum('Size', { Compact: true }),
+
+ children: figma.children('*')
+ },
+ example: (props) => (
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/DataList/_1BuildItYourselfBasicRows.figma.tsx b/packages/code-connect/components/DataList/_1BuildItYourselfBasicRows.figma.tsx
new file mode 100644
index 00000000000..6c8d4ecfe33
--- /dev/null
+++ b/packages/code-connect/components/DataList/_1BuildItYourselfBasicRows.figma.tsx
@@ -0,0 +1,18 @@
+import figma from '@figma/code-connect';
+import { DataListItem, DataListItemRow } from '@patternfly/react-core';
+
+figma.connect(
+ DataListItemRow,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=6649-69488&m=dev',
+ {
+ props: {
+ children: figma.children('*')
+ },
+ example: (props) => (
+ // aria-labelledby should point to an ID within the DataListItemRow/DataListItemCell
+
+ {props.children}
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/DataList/_1BuildItYourselfClickableRows.figma.tsx b/packages/code-connect/components/DataList/_1BuildItYourselfClickableRows.figma.tsx
new file mode 100644
index 00000000000..f06513ba576
--- /dev/null
+++ b/packages/code-connect/components/DataList/_1BuildItYourselfClickableRows.figma.tsx
@@ -0,0 +1,20 @@
+import figma from '@figma/code-connect';
+import { DataListItem, DataListItemRow } from '@patternfly/react-core';
+
+// Documentation for DataListItemRow can be found at https://www.patternfly.org/components/data-list
+
+figma.connect(
+ DataListItemRow,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=6649-96947',
+ {
+ props: {
+ children: figma.children('*')
+ },
+ example: (props) => (
+ // aria-labelledby should point to an ID within the DataListItemRow/DataListItemCell
+
+ {props.children}
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/DataList/_1BuildItYourselfDraggableRows.figma.tsx b/packages/code-connect/components/DataList/_1BuildItYourselfDraggableRows.figma.tsx
new file mode 100644
index 00000000000..f1c90db7194
--- /dev/null
+++ b/packages/code-connect/components/DataList/_1BuildItYourselfDraggableRows.figma.tsx
@@ -0,0 +1,26 @@
+import figma from '@figma/code-connect';
+import { DataList } from '@patternfly/react-core';
+
+// Documentation for DataListItemRow can be found at https://www.patternfly.org/components/data-list
+// This variant has been refactored to use the DragDropSort component.
+// In order to use this variant, you must wrap the DataList component in a DragDropSort component.
+
+figma.connect(
+ DataList,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=19618-55289',
+ {
+ example: () =>
+ 'Draggable DataList variant has been refactored to use the DragDropSort component. The design is the same, but the implementation is different. This component variant requires refactoring to work within the new context. For more information, see the example at https://www.patternfly.org/components/data-list/#draggable.'
+ // Code example:
+ // {
+ // setItems(newItems);
+ // }}
+ // variant="DataList"
+ // overlayProps={{ isCompact: true }}
+ // >
+ //
+ //
+ }
+);
diff --git a/packages/code-connect/components/DataList/_2BaseComponentsActionCell.figma.tsx b/packages/code-connect/components/DataList/_2BaseComponentsActionCell.figma.tsx
new file mode 100644
index 00000000000..75c18d6e8bf
--- /dev/null
+++ b/packages/code-connect/components/DataList/_2BaseComponentsActionCell.figma.tsx
@@ -0,0 +1,16 @@
+import figma from '@figma/code-connect';
+import { DataListAction } from '@patternfly/react-core';
+
+// Documentation for DataListItemRow can be found at https://www.patternfly.org/components/data-list
+
+figma.connect(
+ DataListAction,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=6596-33965',
+ {
+ example: () => (
+
+ 'Action'
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/DataList/_2BaseComponentsContentCell.figma.tsx b/packages/code-connect/components/DataList/_2BaseComponentsContentCell.figma.tsx
new file mode 100644
index 00000000000..a7d4356a90e
--- /dev/null
+++ b/packages/code-connect/components/DataList/_2BaseComponentsContentCell.figma.tsx
@@ -0,0 +1,44 @@
+import figma from '@figma/code-connect';
+import { Icon, DataListCell, DataListItem, DataListItemCells, DataListItemRow } from '@patternfly/react-core';
+
+// TODO: DESIGN: Either name layers uniquely or create a dataListCell component to house
+// Documentation for DataList can be found at https://www.patternfly.org/components/data-list
+
+figma.connect(
+ DataListCell,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=6596-33934',
+ {
+ props: {
+ showDescriptionText: figma.boolean('Show description text'),
+
+ // enum
+ isIcon: figma.enum('Type', {
+ 'Filled - Plain text': true
+ }),
+ isFilled: figma.enum('Type', {
+ 'Filled - Plain text': true,
+ 'Filled - Link text': true
+ }),
+
+ primaryContent: 'Main content',
+ secondaryContent: 'Second content block'
+ },
+ example: (props) => (
+
+
+
+
+ ,
+
+ {props.primaryContent}
+ ,
+ {props.secondaryContent}
+ ]}
+ />
+
+
+ )
+ }
+);
diff --git a/packages/code-connect/components/DataList/_2BaseComponentsControlCell.figma.tsx b/packages/code-connect/components/DataList/_2BaseComponentsControlCell.figma.tsx
new file mode 100644
index 00000000000..c709bd6ed9f
--- /dev/null
+++ b/packages/code-connect/components/DataList/_2BaseComponentsControlCell.figma.tsx
@@ -0,0 +1,49 @@
+import figma from '@figma/code-connect';
+import {
+ // DataListAction,
+ DataListCheck,
+ DataListControl,
+ DataListToggle
+} from '@patternfly/react-core';
+
+// TODO: 2. Base Components/Control cell - These cells need unique names. Either create components for DataListCell,
+// DataListToggle, DataListDragButton, DataListAction, DataListCheck
+// These component specifics are unreachable unless separated into their own entities
+// Documentation for DataListControl can be found at https://www.patternfly.org/components/data-list
+
+// const selectableCell = {
+//
+// return (
+// <>
+// {props.isSelectable}
+// {props.isExpandable}
+// {props.isDraggable}
+//
+// {props.children}
+//
+// >
+// );
+// };
+
+figma.connect(
+ DataListControl,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=6596-34013',
+ {
+ props: {
+ isExpandable: figma.boolean('Row expansion', {
+ true: {}} isExpanded={false} id="toggle1" aria-controls="expand1" />,
+ false: undefined
+ }),
+ isSelectable: figma.boolean('Row select', {
+ true: ,
+ false: undefined
+ })
+ },
+ example: (props) => (
+ <>
+ {props.isSelectable}
+ {props.isExpandable}
+ >
+ )
+ }
+);
diff --git a/packages/code-connect/components/DatePicker/BaseComponentsCalendarDay.figma.tsx b/packages/code-connect/components/DatePicker/BaseComponentsCalendarDay.figma.tsx
new file mode 100644
index 00000000000..8fde324c68f
--- /dev/null
+++ b/packages/code-connect/components/DatePicker/BaseComponentsCalendarDay.figma.tsx
@@ -0,0 +1,15 @@
+import figma from '@figma/code-connect';
+import { CalendarMonth } from '@patternfly/react-core';
+
+// Documentation for CalendarMonth can be found at https://www.patternfly.org/components/calendar-month
+
+figma.connect(
+ CalendarMonth,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=7741-2677',
+ {
+ props: {
+ date: '2025-06-16'
+ },
+ example: (props) => {}} onMonthChange={() => {}} />
+ }
+);
diff --git a/packages/code-connect/components/DatePicker/CalendarMonth.figma.tsx b/packages/code-connect/components/DatePicker/CalendarMonth.figma.tsx
new file mode 100644
index 00000000000..0f226f5a427
--- /dev/null
+++ b/packages/code-connect/components/DatePicker/CalendarMonth.figma.tsx
@@ -0,0 +1,51 @@
+import figma from '@figma/code-connect';
+import { CalendarMonth, Title } from '@patternfly/react-core';
+
+// Documentation for CalendarMonth can be found at https://www.patternfly.org/components/calendar-month
+const sharedProps = {
+ inlineProps: {
+ component: 'article',
+ title: (
+
+ Select your favorite date
+
+ )
+ }
+};
+
+figma.connect(
+ CalendarMonth,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=7958-136846',
+ {
+ props: {
+ ...sharedProps,
+ date: '2025-06-16'
+ },
+ example: (props) => (
+ {}} onMonthChange={() => {}} />
+ )
+ }
+);
+
+figma.connect(
+ CalendarMonth,
+ 'https://www.figma.com/design/aEBBvq0J3EPXxHvv6WgDx9/PatternFly-6--Components-Test?node-id=7958-136846',
+ {
+ props: {
+ ...sharedProps,
+ variant: { Type: 'With date range' },
+ startDate: new Date(2020, 10, 11),
+ endDate: new Date(2020, 10, 24)
+ },
+ example: (props) => (
+ {}}
+ onMonthChange={() => {}}
+ rangeStart={props.startDate}
+ />
+ )
+ }
+);
diff --git a/packages/code-connect/components/DatePicker/DateAndTimePicker.figma.tsx b/packages/code-connect/components/DatePicker/DateAndTimePicker.figma.tsx
new file mode 100644
index 00000000000..8d7366ab344
--- /dev/null
+++ b/packages/code-connect/components/DatePicker/DateAndTimePicker.figma.tsx
@@ -0,0 +1,94 @@
+import figma from '@figma/code-connect';
+import {
+ Button,
+ CalendarMonth,
+ Dropdown,
+ DropdownItem,
+ DropdownList,
+ InputGroup,
+ InputGroupItem,
+ MenuToggle,
+ Popover,
+ TextInput,
+ TimePicker
+} from '@patternfly/react-core';
+import OutlinedCalendarAltIcon from '@patternfly/react-icons/dist/esm/icons/outlined-calendar-alt-icon';
+import OutlinedClockIcon from '@patternfly/react-icons/dist/esm/icons/outlined-clock-icon';
+
+// Documentation for TimePicker can be found at https://www.patternfly.org/components/time-picker
+
+const sharedProps = {
+ time: (
+ {}}
+ isOpen={false}
+ onOpenChange={() => {}}
+ toggle={(toggleRef) => (
+ {}}
+ isExpanded={false}
+ aria-label="Time picker"
+ icon={}
+ />
+ )}
+ >
+
+
+ Action
+
+
+ Operation
+
+
+
+ ),
+ calendarButton: (
+