diff --git a/packages/documentation-framework/app.js b/packages/documentation-framework/app.js index bf7285a132..555b93d6e8 100644 --- a/packages/documentation-framework/app.js +++ b/packages/documentation-framework/app.js @@ -19,7 +19,7 @@ import './layouts/sideNavLayout/sideNavLayout.css'; const AppRoute = ({ child, katacodaLayout, title, path }) => { const pathname = useLocation().pathname; if (typeof window !== 'undefined' && window.gtag) { - gtag('config', 'UA-47523816-6', { + gtag('config', process.env.googleAnalyticsID, { 'page_path': pathname, 'page_title': (title || pathname) }); diff --git a/packages/documentation-framework/components/sideNav/sideNav.js b/packages/documentation-framework/components/sideNav/sideNav.js index 5fd462dac0..3700b574a8 100644 --- a/packages/documentation-framework/components/sideNav/sideNav.js +++ b/packages/documentation-framework/components/sideNav/sideNav.js @@ -12,6 +12,8 @@ const getIsActive = (location, section, subsection = null) => { return location.pathname.startsWith(`${process.env.pathPrefix}${slug}`); } +const defaultValue = 50; + const NavItem = ({ text, href }) => { const isMobileView = window.innerWidth < Number.parseInt(globalBreakpointXl.value, 10); return ( @@ -67,9 +69,14 @@ const ExpandableNav = ({groupedRoutes, location, section, subsection = null}) => }} > {Object.entries(routes || {}) - .filter(([id, { hideNavItem }]) => !Boolean(hideNavItem) && (id !== 'isSubsection')) - .map(([id, { slug, isSubsection = false }]) => ({ text: id, href: slug, isSubsection })) - .sort(({ text: text1 }, { text: text2 }) => text1.localeCompare(text2)) + .filter(([id, navObj]) => !Boolean(navObj.hideNavItem) && (Object.entries(navObj).length > 0)) + .map(([id, { slug, isSubsection = false, sortValue = defaultValue, subsectionSortValue = defaultValue }]) => ({ text: id, href: slug, isSubsection, sortValue: (isSubsection ? subsectionSortValue : sortValue) })) + .sort(({text: text1, sortValue: sortValue1}, {text: text2, sortValue: sortValue2}) => { + if (sortValue1 === sortValue2) { + return text1.localeCompare(text2); + } + return sortValue1 > sortValue2 ? 1 : -1; + }) .map(navObj => navObj.isSubsection ? ExpandableNav({groupedRoutes, location, section, subsection: navObj.text}) : NavItem(navObj) diff --git a/packages/documentation-framework/routes.js b/packages/documentation-framework/routes.js index f8d0c244f3..c50bb2cd82 100644 --- a/packages/documentation-framework/routes.js +++ b/packages/documentation-framework/routes.js @@ -9,6 +9,8 @@ const routes = { ...generatedRoutes }; +const defaultOrder = 50; + for (let route in routes) { const pageData = routes[route]; if (pageData.SyncComponent) { @@ -28,7 +30,7 @@ const isNull = o => o === null || o === undefined; const groupedRoutes = Object.entries(routes) .filter(([_slug, { id, section }]) => !isNull(id) && !isNull(section)) .reduce((accum, [slug, pageData]) => { - const { section, subsection = null, id, title, source, katacodaLayout, hideNavItem, relPath } = pageData; + const { section, subsection = null, id, title, source, katacodaLayout, hideNavItem, relPath, sortValue = null, subsectionSortValue = null } = pageData; pageData.slug = slug; // add section to groupedRoutes obj if not yet created accum[section] = accum[section] || {}; @@ -42,7 +44,9 @@ const groupedRoutes = Object.entries(routes) sources: [], katacodaLayout, hideNavItem, - relPath + relPath, + ...(sortValue && { sortValue }), + ...(subsectionSortValue && { subsectionSortValue }) } // add page to groupedRoutes obj section or subsection if (subsection) { @@ -52,10 +56,21 @@ const groupedRoutes = Object.entries(routes) // add page to subsection accum[section][subsection][id] = accum[section][subsection][id] || data; accum[section][subsection][id].sources.push(pageData); + // nav item ordering + if (sortValue) { + accum[section][subsection].sortValue = sortValue; + } + if (subsectionSortValue) { + accum[section][subsection].subsectionSortValue = subsectionSortValue; + } } else { // add page to section accum[section][id] = accum[section][id] || data; accum[section][id].sources.push(pageData); + // nav item ordering + if (sortValue) { + accum[section][id].sortValue = sortValue; + } } return accum; @@ -73,7 +88,6 @@ const sourceOrder = { 'design-guidelines': 99, 'accessibility': 100 }; -const defaultOrder = 50; const sortSources = ({ source: s1 }, { source: s2 }) => { const s1Index = sourceOrder[s1] || defaultOrder; @@ -108,7 +122,8 @@ Object.entries(groupedRoutes) // Loop through each page in expandable subsection if (pageData.isSubsection) { Object.entries(pageData).map(([section, ids]) => { - if (section !== 'isSubsection') { + // only push nested page objects + if (ids && ids?.id) { pageDataArr.push(ids); } }) diff --git a/packages/documentation-framework/scripts/md/parseMD.js b/packages/documentation-framework/scripts/md/parseMD.js index 294ea9a60e..a0436018e4 100644 --- a/packages/documentation-framework/scripts/md/parseMD.js +++ b/packages/documentation-framework/scripts/md/parseMD.js @@ -85,6 +85,7 @@ function toReactComponent(mdFilePath, source, buildMode) { section: frontmatter.section || '', subsection: frontmatter.subsection || '', source, + tabName: frontmatter.tabName || null, slug, sourceLink: frontmatter.sourceLink || `https://github.com/patternfly/${ sourceRepo}/blob/main/${ @@ -126,6 +127,12 @@ function toReactComponent(mdFilePath, source, buildMode) { if (frontmatter.hideNavItem) { pageData.hideNavItem = frontmatter.hideNavItem; } + if (frontmatter.sortValue) { + pageData.sortValue = frontmatter.sortValue; + } + if (frontmatter.subsectionSortValue) { + pageData.subsectionSortValue = frontmatter.subsectionSortValue; + } }) // Delete HTML comments .use(require('./remove-comments')) @@ -266,8 +273,11 @@ function sourceMDFile(file, source, buildMode) { section: pageData.section, subsection: pageData.subsection, source: pageData.source, + tabName: pageData.tabName, ...(pageData.katacodaLayout && { katacodaLayout: pageData.katacodaLayout }), - ...(pageData.hideNavItem && { hideNavItem: pageData.hideNavItem }) + ...(pageData.hideNavItem && { hideNavItem: pageData.hideNavItem }), + ...(pageData.sortValue && { sortValue: pageData.sortValue }), + ...(pageData.subsectionSortValue && { subsectionSortValue: pageData.subsectionSortValue }) }; } } diff --git a/packages/documentation-framework/scripts/webpack/webpack.base.config.js b/packages/documentation-framework/scripts/webpack/webpack.base.config.js index 44c927961b..d27bfc4eed 100644 --- a/packages/documentation-framework/scripts/webpack/webpack.base.config.js +++ b/packages/documentation-framework/scripts/webpack/webpack.base.config.js @@ -8,6 +8,7 @@ module.exports = (_env, argv) => { const { pathPrefix = '', mode, + googleAnalyticsID = false, algolia = {}, hasGdprBanner = false, hasFooter = false, @@ -40,9 +41,12 @@ module.exports = (_env, argv) => { include: [ path.resolve(process.cwd(), 'src'), path.resolve(process.cwd(), 'patternfly-docs'), + path.resolve(process.cwd(), 'examples'), path.resolve(__dirname, '../..'), // Temporarily compile theme using webpack for development /react-[\w-]+\/src\/.*\/examples/, /react-[\w-]+\\src\\.*\\examples/, // fix for Windows + /react-[\w-]+\/patternfly-docs\/.*\/examples/, //fixes for extensions + /react-[\w-]+\\patternfly-docs\\.*\\examples/, ].concat(includePaths.map(path => new RegExp(path))), exclude: [ path.resolve(__dirname, '../../node_modules'), // Temporarily compile theme using webpack for development @@ -134,6 +138,7 @@ module.exports = (_env, argv) => { new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(mode), 'process.env.pathPrefix': JSON.stringify(isProd ? pathPrefix : ''), + 'process.env.googleAnalyticsID': JSON.stringify(isProd ? googleAnalyticsID : ''), 'process.env.algolia': JSON.stringify(algolia), 'process.env.hasGdprBanner': JSON.stringify(hasGdprBanner), 'process.env.hasFooter': JSON.stringify(hasFooter), diff --git a/packages/documentation-framework/templates/mdx.js b/packages/documentation-framework/templates/mdx.js index d1caf1edfb..d90e8cbd94 100644 --- a/packages/documentation-framework/templates/mdx.js +++ b/packages/documentation-framework/templates/mdx.js @@ -121,7 +121,15 @@ export const MDXTemplate = ({ id, componentsData }) => { - const sourceKeys = sources.map(v => v.source); + // Build obj mapping source names to text displayed on tabs + const tabNames = sources.reduce((acc, curSrc) => { + const { source, tabName } = curSrc; + // use tabName for tab name if present, otherwise default to source + const tabLinkText = tabName || capitalize(source.replace('html', 'HTML').replace(/-/g, ' ')); + acc[source] = tabLinkText; + return acc; + }, {}); + const sourceKeys = Object.keys(tabNames); const isSinglePage = sourceKeys.length === 1; let isDevResources, isComponent, isExtension, isChart, isDemo, isLayout, isUtility; @@ -223,7 +231,7 @@ export const MDXTemplate = ({ onClick={() => trackEvent('tab_click', 'click_event', source.toUpperCase())} > - {capitalize(source.replace('html', 'HTML').replace(/-/g, ' '))} + {tabNames[source]} ))} diff --git a/packages/documentation-framework/templates/patternfly-docs/content/extensions/extension/design-guidelines/design-guidelines.md b/packages/documentation-framework/templates/patternfly-docs/content/extensions/extension/design-guidelines/design-guidelines.md index 2440f18153..99900b9518 100644 --- a/packages/documentation-framework/templates/patternfly-docs/content/extensions/extension/design-guidelines/design-guidelines.md +++ b/packages/documentation-framework/templates/patternfly-docs/content/extensions/extension/design-guidelines/design-guidelines.md @@ -7,6 +7,8 @@ section: extensions id: My extension # Tab (react | react-demos | html | html-demos | design-guidelines | accessibility) source: design-guidelines +# Optional custom text to display in tab in place of source +tabName: My custom tab-name --- Design guidelines intro diff --git a/packages/documentation-framework/templates/patternfly-docs/content/extensions/extension/examples/basic.md b/packages/documentation-framework/templates/patternfly-docs/content/extensions/extension/examples/basic.md index b1faa04353..cee78a3a11 100644 --- a/packages/documentation-framework/templates/patternfly-docs/content/extensions/extension/examples/basic.md +++ b/packages/documentation-framework/templates/patternfly-docs/content/extensions/extension/examples/basic.md @@ -7,6 +7,8 @@ section: extensions id: My extension # Tab (react | react-demos | html | html-demos | design-guidelines | accessibility) source: react +# Optional custom text to display in tab in place of source +tabName: My custom tab-name # If you use typescript, the name of the interface to display props for # These are found through the sourceProps function provdided in patternfly-docs.source.js # Can also pass object { component: string, source: string } allowing to specify the source diff --git a/packages/documentation-framework/versions.json b/packages/documentation-framework/versions.json index e3ee8625b7..51a15455e9 100644 --- a/packages/documentation-framework/versions.json +++ b/packages/documentation-framework/versions.json @@ -21,10 +21,29 @@ "@patternfly/react-virtualized-extension": "4.88.113" } }, + { + "name": "2023.02", + "date": "2022-03-27", + "versions": { + "@patternfly/patternfly": "4.224.4", + "@patternfly/react-catalog-view-extension": "4.96.0", + "@patternfly/react-charts": "6.94.19", + "@patternfly/react-code-editor": "4.82.115", + "@patternfly/react-console": "4.95.5", + "@patternfly/react-core": "4.276.8", + "@patternfly/react-icons": "4.93.6", + "@patternfly/react-inline-edit-extension": "4.86.122", + "@patternfly/react-log-viewer": "4.87.100", + "@patternfly/react-styles": "4.92.6", + "@patternfly/react-table": "4.113.0", + "@patternfly/react-tokens": "4.94.6", + "@patternfly/react-topology": "4.91.40", + "@patternfly/react-virtualized-extension": "4.88.115" + } + }, { "name": "2023.01", "date": "2022-01-31", - "latest": true, "versions": { "@patternfly/patternfly": "4.224.2", "@patternfly/react-catalog-view-extension": "4.95.1", diff --git a/packages/v4/CHANGELOG.md b/packages/v4/CHANGELOG.md index e5fe11b973..a67a9dde3b 100644 --- a/packages/v4/CHANGELOG.md +++ b/packages/v4/CHANGELOG.md @@ -3,6 +3,120 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## 4.21.4 (2023-03-27) + + +### Bug Fixes + +* **release:** update docs for 2023.02 release ([#3453](https://github.com/patternfly/patternfly-org/issues/3453)) ([f5066aa](https://github.com/patternfly/patternfly-org/commit/f5066aa0faff8e0ac0045daf4a689cf40b1bddcf)) + + + + + +## 4.21.3 (2023-03-13) + +**Note:** Version bump only for package patternfly-org-4 + + + + + +## 4.21.2 (2023-03-08) + + +### Bug Fixes + +* **menu:** update and clarify description ([#3438](https://github.com/patternfly/patternfly-org/issues/3438)) ([d06eb61](https://github.com/patternfly/patternfly-org/commit/d06eb619e6bfd185ade10fcfcd703003ec0e606f)) + + + + + +## 4.21.1 (2023-03-02) + +**Note:** Version bump only for package patternfly-org-4 + + + + + +# 4.21.0 (2023-03-01) + + +### Features + +* **docs:** add react console documentation ([#3366](https://github.com/patternfly/patternfly-org/issues/3366)) ([f3eb5bf](https://github.com/patternfly/patternfly-org/commit/f3eb5bf0ee2557c93068e01e68de1953d6f67716)) + + + + + +## 4.20.2 (2023-03-01) + +**Note:** Version bump only for package patternfly-org-4 + + + + + +## 4.20.1 (2023-02-27) + +**Note:** Version bump only for package patternfly-org-4 + + + + + +# 4.20.0 (2023-02-27) + + +### Features + +* **trainings:** remove broken trainings and replace some with blog style training ([#3353](https://github.com/patternfly/patternfly-org/issues/3353)) ([a8dee99](https://github.com/patternfly/patternfly-org/commit/a8dee99d6b4d1f702b070653a6823e389f7d9759)) + + + + + +## 4.19.1 (2023-02-20) + +**Note:** Version bump only for package patternfly-org-4 + + + + + +# 4.19.0 (2023-02-09) + + +### Features + +* **docs:** enabled manual ordering of sidenav ([#3403](https://github.com/patternfly/patternfly-org/issues/3403)) ([b630ed9](https://github.com/patternfly/patternfly-org/commit/b630ed9e7062e1302d58793bfec65d49da7764d3)) + + + + + +# 4.18.0 (2023-02-09) + + +### Features + +* **docs:** customize tabs with optional tabText frontmatter ([#3394](https://github.com/patternfly/patternfly-org/issues/3394)) ([093c6c7](https://github.com/patternfly/patternfly-org/commit/093c6c77053f544605d40f8918dc5621829ac7c3)) + + + + + +## 4.17.1 (2023-02-09) + +**Note:** Version bump only for package patternfly-org-4 + + + + + # 4.17.0 (2023-02-07) diff --git a/packages/v4/package.json b/packages/v4/package.json index 784fbd565f..905294cd73 100644 --- a/packages/v4/package.json +++ b/packages/v4/package.json @@ -2,7 +2,7 @@ "name": "patternfly-org-4", "description": "Documentation for PatternFly 4.", "private": true, - "version": "4.17.0", + "version": "4.21.4", "author": "Red Hat", "license": "MIT", "scripts": { @@ -18,11 +18,12 @@ }, "dependencies": { "@patternfly/documentation-framework": "^2.0.0-alpha.0", - "@patternfly/quickstarts": "^2.3.3", - "@patternfly/react-catalog-view-extension": "4.95.1", + "@patternfly/quickstarts": "^2.4.0", + "@patternfly/react-catalog-view-extension": "^4.96.0", + "@patternfly/react-console": "^4.95.5", "@patternfly/react-docs": "6.0.0-alpha.8", "@patternfly/react-log-viewer": "4.87.100", - "@patternfly/react-topology": "^4.91.27", + "@patternfly/react-topology": "^4.91.40", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0" }, diff --git a/packages/v4/patternfly-docs/components-data.json b/packages/v4/patternfly-docs/components-data.json index 614adedb94..85a8e4c637 100644 --- a/packages/v4/patternfly-docs/components-data.json +++ b/packages/v4/patternfly-docs/components-data.json @@ -203,7 +203,7 @@ }, "menu": { "illustration": "./images/component-illustrations/menu.png", - "summary": "A menu is a list of options or actions that users can choose from. It can be used in a variety of contexts whenever the user needs to choose between multiple values, options, or actions. A menu can be opened in a dropdown or select list, or it can be revealed by right clicking on a specific region within a page." + "summary": "A menu is a list of options or actions that users can choose from. It can be used in a variety of contexts whenever the user needs to choose between multiple values, options, or actions. A menu is most often paired with a menu toggle as its trigger, but can also be used inline or can be attached to other interactable elements to toggle it open and close." }, "modal": { "illustration": "./images/component-illustrations/modal.png", diff --git a/packages/v4/patternfly-docs/content/accessibility/badge/badge.md b/packages/v4/patternfly-docs/content/accessibility/badge/badge.md index be6feb7013..3fdb035788 100644 --- a/packages/v4/patternfly-docs/content/accessibility/badge/badge.md +++ b/packages/v4/patternfly-docs/content/accessibility/badge/badge.md @@ -15,7 +15,7 @@ To implement an accessible PatternFly **badge**: - A heading or other text element prefacing the badge or visually hidden text content accessible only to assistive technologies are some examples of a surrounding context. ``` -

Notificaitons 5

+

Notifications 5

5 unread notifications ``` diff --git a/packages/v4/patternfly-docs/content/design-guidelines/components/dropdown/dropdown.md b/packages/v4/patternfly-docs/content/design-guidelines/components/dropdown/dropdown.md index 96a114f87e..7781634497 100644 --- a/packages/v4/patternfly-docs/content/design-guidelines/components/dropdown/dropdown.md +++ b/packages/v4/patternfly-docs/content/design-guidelines/components/dropdown/dropdown.md @@ -22,23 +22,41 @@ In addition to the basic dropdown shown above, you may apply the following varia The primary toggle should be used in the same way as you would use a primary button. If you want to draw the user’s attention to a dropdown menu as the primary place to take action on a page, consider using a dropdown with primary styling. ### Secondary toggle -The secondary toggle is a variation of the primary toggle. It has less visual prominence than the primary toggle, but more visual prominence than the basic toggle and other toggle variations. +The secondary toggle is a variation of the primary toggle. It has less visual prominence than the primary toggle, but more visual prominence than the basic toggle and other toggle variations. Use a secondary toggle when the actions in the dropdown are the secondary actions you’d want a user to take. Image showing usage of secondary toggle Use a secondary toggle when other toggle variations would appear visually inconsistent, or lack the sufficient prominence needed to create a visual hierarchy. ### Plain toggle -Plain styling removes the border treatment from a dropdown toggle. This is useful in places where the default border treatment might make your layout feel visually cluttered or crowded. +Plain styling removes the border treatment from a dropdown toggle. This is useful in places where the default border treatment might make your layout feel visually cluttered or crowded. Use a plain toggle when further action hierarchy needs to be established and you already have primary or secondary action toggle on the page. ### Icon toggle When there is not enough space for a labeled button, an icon can be used instead. Icon toggles are best used when you can use a common icon that has a well understood meaning or when you are working with limited space. A common default is to use the vertical ellipses (kebab) icon to generally indicate that it is connected with a menu as shown above. ### Split button -A split button can be used when you want to combine an action button or other control with a dropdown menu. Here are some examples of split buttons. +A split button can be used when you want to combine an action button or other control with a dropdown menu. Use a split button action dropdown when you have multiple actions to show that are related to each other, but one action is more likely or important than the rest. -split button +There are two types of split buttons: split buttons with checkboxes and split buttons with actions. + +#### Split button with checkbox A split button with a checkbox can be used in bulk selection use cases for a list, table, or card grid. Here, the checkbox provides immediate access to bulk selection, and the user can also open the dropdown menu to expose other actions. Text can also be added within the toggle to reflect current state. -A split button with actions is useful when you want to expose a default action with a single click, but also allow access to other actions via the dropdown menu. This can be thought of as providing a shortcut to the most recent or frequently used item in the menu. A split button with actions can contain a labeled action as shown above or an icon in place of the label for use when there is limited space. +split button + +#### Split button with actions + +A split button with actions is useful when you want to expose a default action with a single click, but also allow access to other actions via the dropdown menu. This can be thought of as providing a shortcut to the most recent or frequently used item in the menu. A split button with actions can contain a labeled action or an icon in place of the label for use when there is limited space. + +split button + +**Behavior** + +In this case, the user can either click on the primary button, or on the caret to open/view the rest of the related options. When a user clicks on an action whether the surfaced one, or one from inside the menu, the action will be selected and applied immediately. + +**Example** + +example of split button used inside of a modal + +A split action button is used in a modal where there are different possible submit variations. Here, all the buttons are related in that they are different ways to submit the modal, but the surfaced option is the most likely to be used, while the ones housed in the toggle are other less likely options. diff --git a/packages/v4/patternfly-docs/content/design-guidelines/components/dropdown/img/split-toggle-example.png b/packages/v4/patternfly-docs/content/design-guidelines/components/dropdown/img/split-toggle-example.png new file mode 100644 index 0000000000..d1e8391e48 Binary files /dev/null and b/packages/v4/patternfly-docs/content/design-guidelines/components/dropdown/img/split-toggle-example.png differ diff --git a/packages/v4/patternfly-docs/content/design-guidelines/components/dropdown/img/split-toggles.png b/packages/v4/patternfly-docs/content/design-guidelines/components/dropdown/img/split-toggles.png new file mode 100644 index 0000000000..817f709ff9 Binary files /dev/null and b/packages/v4/patternfly-docs/content/design-guidelines/components/dropdown/img/split-toggles.png differ diff --git a/packages/v4/patternfly-docs/content/design-guidelines/components/menu/img/dropdown-disabled-action-tooltip.png b/packages/v4/patternfly-docs/content/design-guidelines/components/menu/img/dropdown-disabled-action-tooltip.png new file mode 100644 index 0000000000..eefd9bbf94 Binary files /dev/null and b/packages/v4/patternfly-docs/content/design-guidelines/components/menu/img/dropdown-disabled-action-tooltip.png differ diff --git a/packages/v4/patternfly-docs/content/design-guidelines/components/menu/menu.md b/packages/v4/patternfly-docs/content/design-guidelines/components/menu/menu.md index ac91c756b6..f33eb0b006 100644 --- a/packages/v4/patternfly-docs/content/design-guidelines/components/menu/menu.md +++ b/packages/v4/patternfly-docs/content/design-guidelines/components/menu/menu.md @@ -4,7 +4,7 @@ section: components --- ## Elements -Elements vary depending on [menu variation](#Variations) +Elements vary depending on [menu variation](#variations). ## Usage @@ -97,6 +97,41 @@ When using red text for destructive actions, it is still recommended to require drilldown menu +### Disabled menus and menu options + +#### When to use disabled menus and menu options + +Menus or menu items can be disabled for multiple reasons. The reason an action is disabled informs which design pattern you should use. + +Use a disabled menu when: + +* **An action is unavailable due to an unmet prerequisite, condition, permission, or status.** + + If a user needs to complete a prerequisite to enable an action, disable the action and add a [tooltip](/components/tooltip). The tooltip should explain what the user needs to do to enable the action. + + disabled action tooltip + + Example: A user can’t perform bulk actions until they select resources in the list. + + Example: A user cannot view past logs until their container is finished restarting. + +* **An action cannot be performed due to a product constraint or rule.** + + If an action cannot be taken because of a product constraint or rule, hide the action. + + Example: While a user can delete a resource they own, they cannot delete a template or default resource. + +#### When not to use a disabled menu + +Do not use a disabled menu when: + +* **An action can be performed, but is not recommended.** + + When an action can be performed but may result in an undesirable outcome, do not disable it. Instead, add a [confirmation modal](/components/modal). When the user clicks on the action, use a modal to explain the potential consequences and ask the user if they are sure they want to proceed. + + Example: A user wants to delete a system. + + ## Content considerations When creating menu item labels, keep in mind the following guidelines: diff --git a/packages/v4/patternfly-docs/content/design-guidelines/components/skeleton/skeleton.md b/packages/v4/patternfly-docs/content/design-guidelines/components/skeleton/skeleton.md index 8447e5816c..7e3fa852e8 100644 --- a/packages/v4/patternfly-docs/content/design-guidelines/components/skeleton/skeleton.md +++ b/packages/v4/patternfly-docs/content/design-guidelines/components/skeleton/skeleton.md @@ -4,16 +4,24 @@ section: components --- ## Usage -Skeleton loading should be progressive –– it should load static text first, followed by variable elements of the UI. +A skeleton is a type of loading state that allows you to expose content incrementally, once the structure of the page has been loaded in. A skeleton should match the exact structure of the element you’re loading in and can be used in components on top of the page, such as in a drop down menu, or a card. Skeleton loading should be progressive –– it should load static text first, followed by variable elements of the UI. ### When to use a skeleton vs. a loading spinner +Use a skeleton when: +- The structure of a page has loaded in but the content has not. +- Some content of a page has loaded, but not all. For example, in a dashboard, you may have some loaded cards, while others are still loading. +- You want to show loading content inside of a card, table, data list or more. **Show a skeleton when:** - You know what the populated data is going to look like (even if it results in an empty state). +**Do not show a skeleton when:** +- You don’t know what the structure of the component is going to look like. + **Show a [spinner](/components/spinner/react) when:** -- You do not know what the populated data may look like. For example, if you are loading a form (as they are not all structured the same). -- When it is likely it will fail or show an empty state while waiting for actions to complete. +- You have multiple elements on the page that are loading at different speeds, use a spinner once the structure of at least one element is loaded on the page. +- You are attempting to load in a component that sits on top of a page with an expected structure. +- It is likely it will fail or show an empty state while waiting for actions to complete. ## Accessibility For information regarding accessibility, visit the [skeleton accessibility](/components/skeleton/accessibility) tab. diff --git a/packages/v4/patternfly-docs/content/design-guidelines/components/spinner/img/spinner-full-page.png b/packages/v4/patternfly-docs/content/design-guidelines/components/spinner/img/spinner-full-page.png index 5e33f60ea2..ecd5e5c9fb 100644 Binary files a/packages/v4/patternfly-docs/content/design-guidelines/components/spinner/img/spinner-full-page.png and b/packages/v4/patternfly-docs/content/design-guidelines/components/spinner/img/spinner-full-page.png differ diff --git a/packages/v4/patternfly-docs/content/design-guidelines/components/spinner/img/spinner-in-modal.png b/packages/v4/patternfly-docs/content/design-guidelines/components/spinner/img/spinner-in-modal.png new file mode 100644 index 0000000000..83866c3d4f Binary files /dev/null and b/packages/v4/patternfly-docs/content/design-guidelines/components/spinner/img/spinner-in-modal.png differ diff --git a/packages/v4/patternfly-docs/content/design-guidelines/components/spinner/img/wizard-with-spinner.png b/packages/v4/patternfly-docs/content/design-guidelines/components/spinner/img/wizard-with-spinner.png new file mode 100644 index 0000000000..43b2b641b2 Binary files /dev/null and b/packages/v4/patternfly-docs/content/design-guidelines/components/spinner/img/wizard-with-spinner.png differ diff --git a/packages/v4/patternfly-docs/content/design-guidelines/components/spinner/spinner.md b/packages/v4/patternfly-docs/content/design-guidelines/components/spinner/spinner.md index 5ec1bfaa5e..d58dcf7c5d 100644 --- a/packages/v4/patternfly-docs/content/design-guidelines/components/spinner/spinner.md +++ b/packages/v4/patternfly-docs/content/design-guidelines/components/spinner/spinner.md @@ -7,40 +7,47 @@ section: components Spinners are used to demonstrate data loading. Spinners are offered in different sizes that follow the sizing of our icons. These sizes include extra small, small, medium and large. Depending on the size of information you are loading and the space you are dealing with, we recommend using the spinner size that generally matches. + Visual of different spinner sizes +## Placement + +Position the spinner in the center of the element that is loading. To ensure proper background contrast, use a white or light background. + +Example of spinner in full page + ### When to use Use a spinner: -- when the data you are dealing with is unknown in both quantity and shape. -- when in progress of loading a screen that may not have any data, for example an [empty state screen or failed outcome](/components/empty-state). -- within a table view, where the spinner can take up the area of the table before it loads. -- when the expected wait time is between 1-5 seconds. +- When the user is advancing to a new page or step where the structure has not been loaded in yet. +- When the data you are dealing with is unknown in both quantity and shape. +- When the expected wait time is between 1-5 seconds. ### When not to use Don't use a spinner: -- to replace a [progress bar](/components/progress). - -- if the loading process is less than 1 second. For experiences longer than 5 seconds, use a progress bar. +- To replace a [progress bar](/components/progress). +- If the loading process is less than 1 second. For experiences longer than 5 seconds, use a progress bar. +- In components that load on top of the page, for example in cards or dropdowns. In this case use a [skeleton](/components/skeleton) to reflect the structure of the data. +- When a loading screen does not have any data, use an [empty state screen or failed outcome](/components/empty-state) instead. ### Spinner in context -Spinners are centered within the container AND the viewport by default in all use cases. Although this is the standard position of it, the spinner may be repositioned if necessary for particular screens and screen sizes. +Spinners are centered within the container AND the viewport by default in all use cases. -### Spinner in select list (small) +### Spinner in a wizard -Example of spinner in select menu +Example of spinner in a wizard -### Spinner in cards within a dashboard (medium) +### Spinner in a full page -Example of spinner in cards +Example of spinner in full page -### Spinner in a data list or table (large) +### Spinner in a modal window -Example of spinner in table +Example of spinner in a modal window -### Spinner in a full page (large) +### Spinner in a data list or table (large) -Example of spinner in full page +Example of spinner in table ### When to use a loading spinner vs. a skeleton @@ -50,3 +57,4 @@ Spinners are centered within the container AND the viewport by default in all us **Use a [skeleton](/components/skeleton/react) when:** - You know what the populated data is going to look like (even if it results in an empty state). +- The structure of the data has fully loaded and can be displayed. diff --git a/packages/v4/patternfly-docs/content/design-guidelines/components/tooltip/img/tooltip-on-bar-chart.png b/packages/v4/patternfly-docs/content/design-guidelines/components/tooltip/img/tooltip-on-bar-chart.png new file mode 100644 index 0000000000..487554b7d4 Binary files /dev/null and b/packages/v4/patternfly-docs/content/design-guidelines/components/tooltip/img/tooltip-on-bar-chart.png differ diff --git a/packages/v4/patternfly-docs/content/design-guidelines/components/tooltip/img/tooltip-on-disabled-button.png b/packages/v4/patternfly-docs/content/design-guidelines/components/tooltip/img/tooltip-on-disabled-button.png new file mode 100644 index 0000000000..6ed784fb8d Binary files /dev/null and b/packages/v4/patternfly-docs/content/design-guidelines/components/tooltip/img/tooltip-on-disabled-button.png differ diff --git a/packages/v4/patternfly-docs/content/design-guidelines/components/tooltip/img/tooltip-on-hyperlink.png b/packages/v4/patternfly-docs/content/design-guidelines/components/tooltip/img/tooltip-on-hyperlink.png new file mode 100644 index 0000000000..9f638c413e Binary files /dev/null and b/packages/v4/patternfly-docs/content/design-guidelines/components/tooltip/img/tooltip-on-hyperlink.png differ diff --git a/packages/v4/patternfly-docs/content/design-guidelines/components/tooltip/img/tooltip-on-unlabeled-icons.png b/packages/v4/patternfly-docs/content/design-guidelines/components/tooltip/img/tooltip-on-unlabeled-icons.png new file mode 100644 index 0000000000..8448b34649 Binary files /dev/null and b/packages/v4/patternfly-docs/content/design-guidelines/components/tooltip/img/tooltip-on-unlabeled-icons.png differ diff --git a/packages/v4/patternfly-docs/content/design-guidelines/components/tooltip/tooltip.md b/packages/v4/patternfly-docs/content/design-guidelines/components/tooltip/tooltip.md index 72f8a981ad..936f3ff9d9 100644 --- a/packages/v4/patternfly-docs/content/design-guidelines/components/tooltip/tooltip.md +++ b/packages/v4/patternfly-docs/content/design-guidelines/components/tooltip/tooltip.md @@ -9,15 +9,19 @@ For information on other forms of on-screen help, see [popover](/components/popo Use tooltips to: - Provide labels for unlabeled icons. -kebab icon with a “More options” tooltip label + table with tooltip on an unlabeled kebab icon to provide more information - Provide additional information on a data point or element in a chart or table. -bar chart with a tooltip for Asia Pacific + bar chart with a tooltip on data point to describe it as Asia Pacific - Define new or unfamiliar UI elements that aren’t described directly in the user interface. For example, you can use a tooltip on a disabled button. -disabled edit button with a tooltip about access + table with tooltip on a disabled edit button to provide more information regarding access + +- Provide additional information on text or labels on hover. A way for users to see more information before clicking the element and being directed to a new page or producing an action on the page. + + table with tooltip on clickable text to provide more information ### Tooltip delay on hover By default, tooltips have a 300ms entry delay when hovering over an object. Although this is the recommended delay time, you may customize it via prop. For example, if you have a tooltip on an icon, and you would like for it to appear immediately on hover, you may set the delay to 0 ms. diff --git a/packages/v4/patternfly-docs/content/design-guidelines/styles/colors/colors.md b/packages/v4/patternfly-docs/content/design-guidelines/styles/colors/colors.md index 61a93108ca..c0087ba788 100644 --- a/packages/v4/patternfly-docs/content/design-guidelines/styles/colors/colors.md +++ b/packages/v4/patternfly-docs/content/design-guidelines/styles/colors/colors.md @@ -12,10 +12,10 @@ import './colors.css'; ### PatternFly blue

- Primary colors are the colors displayed most frequently across your application screens and components. Our primary colors are used within a variety of components and are typically applied to default or active states and hover states. + Primary colors are those displayed most frequently across your application screens and components. Our primary colors are used across components and are typically applied to default, active, focus, and hover states.

- This color is most commonly used as as default or active state for many components including badges and spinners. + This color usually indicates a default or active state for many components, including badges and spinners. This color is most commonly used as the hover or focus state for components that use the default primary color, such as buttons and dropdowns. @@ -33,16 +33,16 @@ import './colors.css'; ### Text and icons

- Typography and iconography colors are extremely similar because they can both be used in the same context, such as a link button. We have multiple shades of text colors on light and dark backgrounds so that you can emphasize hierarchy. + Typography and iconography colors are extremely similar because they can be used in the same context, such as for a link button. We have multiple shades of text colors on light and dark backgrounds so that you can emphasize hierarchy.

- This color is used as a standard text and icon color as well as a hover state color for icon buttons. It is most commonly used as a text color for many components and application screens. + This color is used for standard text, icons, and as a hover state color for icon buttons. It is most commonly used as a text color for many components and application screens. - This color is used as a secondary text color as well as a default color for icon buttons. It is most commonly used for many components, such as the app launcher and empty states. + This color is used as a secondary text color and as a default color for icon buttons. It is most commonly used for many components, such as the app launcher and empty states. - This color is most commonly used as a link text and icon color for many components, such as navigation and accordions. Blue icons use the same primary color variable as the blue text. + This color is most commonly used for link text and icons for many components, such as navigation and accordions. Blue icons use the same primary color variable as the blue text.
@@ -56,7 +56,7 @@ import './colors.css';

- Background colors are used throughout components and can be used for certain screens depending on the use case. The light colors can be interchangeable for full-screen backgrounds. The dark background colors are strictly used within components. + Background colors are used throughout components and for certain screens, depending on the use case. Light colors can be used interchangeably with full-screen backgrounds, while dark background colors are strictly used within components.

This color is most commonly used as a secondary background color for full application screens and hover backgrounds. @@ -87,72 +87,81 @@ import './colors.css'; ## Status and state colors - Status and state colors are important when communicating data and action aspects through the UI with the user. Our status colors cover a variety of statuses including default, danger, success, information, and warning. + Status and state colors are indicators that communicate data and actions to users through the UI. Our status colors cover default, danger, success, information, and warning statuses, as well as disabled states. PatternFly status colors -

Danger

- - This color is used as the icon color for the danger alert component. +

Default

+ + This color is used as the title color for the default alert component. - - This color is used as the title color for the danger alert as well as the background color for the danger button. + + This color is used as the icon color for the default alert component. - - This color is most commonly used as an indication of danger or error for components, such as alerts and form inputs. + + This color is used as the background color for the default inline alert component.
-

Default

- - This color is used as the icon and title color for the default alert component. - - - This color is used as the background and icon color for the default inline alert component. +

Danger

+ + This color is used as the title color for the danger alert component. - - This color is used as the icon background color for the default alert component. + + This color is used as the icon color for the danger alert component. + + + This color is used as the background color for danger inline alert component.
-

Info

- - This color is used as the icon and title color for the info alert component. +

Success

+ + This color is used as the title color for the success alert component. + + + This color is used as the icon color for the success alert component. - - This color is used as the icon background color for the info alert component as well as the background and icon color for the info inline alert component. + + This color is used as the background color for the success inline alert component.
-

Success

- - This color is used as an indication of success for components, such as alerts and forms. It is used as the icon and title color for the success alert component. +

Info

+ + This color is used as the title color for the info alert component. - - This color is most commonly used as an indication of success for components, such as alerts and forms. It is used as the background color for the success alert component as well as the background and icon color for the success inline alert component. + + This color is used as the icon color for the default alert component. + + + This color is used as the background color for the info inline alert component.

Warning

- - This color is used as the icon and title color for the warning alert component. + + This color is used as the title color for the warning alert component. + + + This color is used as the icon color for the warning alert component. - - This color is used as the icon background color for the warning alert component as well as the background and icon color for the warning inline alert component. + + This color is used as the background color for the warning inline alert component.
- +

Disabled

- This color is used as the disabled text color when text is indicated as disabled. + This color is used as the text color when components are disabled. - This color is most commonly used as a disabled background color for many components, such as buttons and the app launcher. + This color is used as the background color for many components when they are disabled, such as buttons and the application launcher. - This color is most commonly used as an alternate disabled background color for many components, such as dropdowns and options menus. + This color is used as an alternate background color for components when they are disabled, such as dropdowns and options menus.
@@ -163,16 +172,16 @@ import './colors.css';

- Shadows provide specifics about depth, direction of movement, and surface edges. Depending on the surface’s elevation and relationships to other surfaces, the type of shadow will change. + Shadows provide specifics about depth, movement direction, and surface edges. Depending on the surface’s elevation and relationships to other surfaces, the type of shadow will change.

- This variable is used to indicate a large shadow for many components, such as alerts and modals. + This variable displays a large shadow for many components, such as alerts and modals. - This variable is used to indicate a medium shadow for many components, such as accordion and dropdowns. + This variable displays a medium shadow for many components, such as accordions and dropdowns. - This variable is used to indicate a small shadow for the card component. + This variable displays a small shadow for the card component.
@@ -184,21 +193,21 @@ import './colors.css'; ## Contrast ratios

- Level AA in the Web Content Accessibility Guidelines 2.1 requires a contrast ratio of at least 4.5:1 for normal text and 3:1 for large text, and a contrast ratio of at least 3:1 for graphics and user interface components (such as form input borders). + Level AA in the Web Content Accessibility Guidelines 2.1 requires a contrast ratio of at least 4.5:1 for normal text, 3:1 for large text, and 3:1 for graphics and UI components (such as form input borders).

-Check color contrast between background color and text color using a WCAG AA-compliance tool. +Check the contrast between the background color and text color using a WCAG AA-compliance tool. -Make sure that, on hover, link texts provides ample contrast from both background color and from the default state of link text. +Make sure that, on hover, the link text color has ample contrast from both the background color and the default state link color. ## Color palette -Our palettes are created as a system designed to reinforce application content and workflows. Bright colors are reserved for specific interactions such as reinforcing status and are used sparingly. Our palettes are simple and consolidated to allow them to be easily deployed and versatile for any situation. +Our palettes are created as a system designed to reinforce application content and workflows. Bright colors are reserved for specific interactions, such as reinforcing status, and are used sparingly. Our palettes are simple, consolidated, and versatile to allow them to be easily deployed for any situation. - + diff --git a/packages/v4/patternfly-docs/content/training/copyCodeBlock/copyCodeBlock.js b/packages/v4/patternfly-docs/content/training/copyCodeBlock/copyCodeBlock.js new file mode 100644 index 0000000000..46d8d28fcb --- /dev/null +++ b/packages/v4/patternfly-docs/content/training/copyCodeBlock/copyCodeBlock.js @@ -0,0 +1,43 @@ +import React from 'react'; +import { CodeBlock, CodeBlockAction, CodeBlockCode, ClipboardCopyButton } from '@patternfly/react-core'; + +export const CopyCodeBlock = ({ + children +}) => { + const [copied, setCopied] = React.useState(false); + + const clipboardCopyFunc = (event, text) => { + navigator.clipboard.writeText(text.toString()); + }; + + const onClick = (event, text) => { + clipboardCopyFunc(event, text); + setCopied(true); + }; + + const actions = ( + + + onClick(e, children)} + exitDelay={copied ? 1500 : 600} + maxWidth="110px" + variant="plain" + onTooltipHidden={() => setCopied(false)} + > + {copied ? 'Successfully copied to clipboard!' : 'Copy to clipboard'} + + + + ); + + + return ( + + {children} + + ); +}; diff --git a/packages/v4/patternfly-docs/content/training/design.md b/packages/v4/patternfly-docs/content/training/design.md index 252967746a..0430329ddd 100644 --- a/packages/v4/patternfly-docs/content/training/design.md +++ b/packages/v4/patternfly-docs/content/training/design.md @@ -15,7 +15,7 @@ import './design.css' The Sketch design training is powered with a tool called Thinkific. You will need to create a free account in order to complete this training. - @@ -29,7 +29,7 @@ import './design.css' level="beginner" time="5 minutes" description="Set up your design environment with Sketch." - designUrl="https://patternflyt-training.thinkific.com/courses/take/pf-sketch-e-training/lessons/12824668-video" + designUrl="https://patternfly-training.thinkific.com/courses/take/pf-sketch-e-training/lessons/12824668-video" /> @@ -39,7 +39,7 @@ import './design.css' level="beginner" time="20 minutes" description="Learn the types of mockup fidelity as well as pros and cons of each." - designUrl="https://patternflyt-training.thinkific.com/courses/take/pf-sketch-e-training/lessons/12854000-video" + designUrl="https://patternfly-training.thinkific.com/courses/take/pf-sketch-e-training/lessons/12854000-video" /> @@ -49,7 +49,7 @@ import './design.css' level="beginner" time="5 minutes" description="Learn what the PatternFly Library and the PatternFly Template are and highlight the connections between them." - designUrl="https://patternflyt-training.thinkific.com/courses/take/pf-sketch-e-training/lessons/12855027-video" + designUrl="https://patternfly-training.thinkific.com/courses/take/pf-sketch-e-training/lessons/12855027-video" /> @@ -59,7 +59,7 @@ import './design.css' level="beginner" time="45 minutes" description="Get up to speed with common Sketch shortcuts and skills." - designUrl="https://patternflyt-training.thinkific.com/courses/take/pf-sketch-e-training/lessons/12855102-video" + designUrl="https://patternfly-training.thinkific.com/courses/take/pf-sketch-e-training/lessons/12855102-video" /> @@ -69,7 +69,7 @@ import './design.css' level="intermediate" time="20 minutes" description="Learn about symbol overrides, what they are, and why they are important." - designUrl="https://patternflyt-training.thinkific.com/courses/take/pf-sketch-e-training/lessons/12855787-video" + designUrl="https://patternfly-training.thinkific.com/courses/take/pf-sketch-e-training/lessons/12855787-video" /> @@ -79,7 +79,7 @@ import './design.css' level="intermediate" time="25 minutes" description="Get familiar with the PatternFly spacing system and explain how it fits into the design kit." - designUrl="https://patternflyt-training.thinkific.com/courses/take/pf-sketch-e-training/lessons/12856030-video" + designUrl="https://patternfly-training.thinkific.com/courses/take/pf-sketch-e-training/lessons/12856030-video" /> @@ -89,7 +89,7 @@ import './design.css' level="advanced" time="15 minutes" description="Learn when designers should detach from symbols in the PatternFly library and how to retain PatternFly standards when doing so." - designUrl="https://patternflyt-training.thinkific.com/courses/take/pf-sketch-e-training/lessons/12856104-video" + designUrl="https://patternfly-training.thinkific.com/courses/take/pf-sketch-e-training/lessons/12856104-video" /> @@ -99,7 +99,7 @@ import './design.css' level="beginner" time="10 minutes" description="Learn how to stay up to date with design components, how to contribute, and where to ask questions." - designUrl="https://patternflyt-training.thinkific.com/courses/take/pf-sketch-e-training/lessons/12856217-video" + designUrl="https://patternfly-training.thinkific.com/courses/take/pf-sketch-e-training/lessons/12856217-video" /> diff --git a/packages/v4/patternfly-docs/content/training/html-css/css-variables-and-overrides.md b/packages/v4/patternfly-docs/content/training/html-css/css-variables-and-overrides.md new file mode 100644 index 0000000000..4e6c7808bb --- /dev/null +++ b/packages/v4/patternfly-docs/content/training/html-css/css-variables-and-overrides.md @@ -0,0 +1,238 @@ +--- +id: HTML CSS variables and overrides training +section: training +hideNavItem: true +--- +import { Button, ClipboardCopy, Divider, PageSection } from '@patternfly/react-core'; + + +# CSS variables and overrides +PatternFly Core is based on the principles of Atomic Design and BEM (Block, Element, Modifier). BEM is a popular CSS methodology for building modular, scalable applications. It provides scope, avoids inheritance, and reduces CSS specificity and conflicts. + +BEM works perfectly with a modular design system, as each unique component can be represented as an independent block. Since a block is tied to a component, developers are able to develop, move around, and nest components without conflicts in their application’s CSS. +PatternFly uses a modified version of BEM for its CSS architecture. PatternFly deviates from BEM in relation to modifiers. + +This tutorial covers how PatternFly uses BEM as a framework for its component library. You'll learn how to override and create both global and component-level custom properties and component elements. + + +## Part 1: Overriding PatternFly component-level properties +In PatternFly, component-level custom properties follow this general formula: +`--pf-c-block[__element][--modifier][--state][--breakpoint][--pseudo-element]--PropertyCamelCase.` + - `--pf-c-block` refers to the block, usually the component or layout name (for example, `--pf-c-alert`). + - `__element` refers to the element inside of the block (for example, `__title`). + - `--modifier` refers to a modifier class such as `.pf-m-danger`, and is prefixed with `m-` in the component variable (for example`--m-danger`). + - `--state` is something like hover or active. + - `--breakpoint` is a media query breakpoint such as `sm` for `$pf-global--breakpoint--sm`. + - `--pseudo-element` is one of either `before` or `after`. + - `PropertyCamelCase` refers to the property that is being changed. + +To explore this concept, you can practice overriding the title color custom property in the success variation of the alert component using the provided CodeSandbox. + + + +### Step 1. Familiarize with `index.html` +Note the alert component in the `` of `index.html`. + +### Step 2. Create custom property name and styles +Write the CSS for the custom property name in the `style.css` file. Overriding the success variation’s title color means overriding its custom property. + +#### Step 2.1 +In the `style.css` file, in the `.pf-c-alert{}` block, write the custom property name. + +In reference to the formula described in Part 1, this should be: `--pf-c-alert` + +#### Step 2.2 +Add the modifier to the custom property name. As displayed in the CSS variables of PatternFly's alert component documentation, the success variation modifier class `pf-m-success` applies to `pf-c-alert`. Add that modifier to the custom property. + +The custom property name should now be: `--pf-c-alert--m-success` + +#### Step 2.3 +Add the element to the custom property name. The element that is being changed is the title of the alert. + +The custom property name should now be: `--pf-c-alert--m-success__title` + +#### Step 2.4 +Add the property that is being modified. In this case, modify the color property of the title in the alert component. + +The custom property name should now be: `--pf-c-alert--m-success__title--Color` + +#### Step 2.5 +Define the value of the component-level CSS variable. PatternFly's global danger color is: `--pf-global--danger-color--100`. You can reference PatternFly’s global colors documentation for more information. + +Assign the custom property name `(--pf-c-alert--m-success__title--Color)` that is already inside the `.pf-c-alert{}` block to the global danger color. + +It should look like this: `--pf-c-alert--m-success__title--Color: var(--pf-global--danger-color--100);` + +The resulting alert should match Figure 1. + +**Figure 1** +Alert component with a red title + + + +## Part 2: Overriding PatternFly global properties +In PatternFly, global properties follow this general formula: +`--pf-global--concept--PropertyCamelCase--modifier--state` + +Global properties are prefixed with the word global. + - A `concept` is something like a spacer or main-title. + - A `PropertyCamelCase` is something like `BackgroundColor` or `FontSize`. + - A `modifier` is something like `sm`, or `lg`. + - A `state` is something like `hover` or `expanded`. They are concepts, never tied to an element or component. This is incorrect: `--pf-global--h1--FontSize`. This is correct: `--pf-global--FontSize--3xl`. + +To explore this concept, override the global link color by setting it to the custom property for danger using the provided CodeSandbox for part 2. The `index.html` file contains a button and expandable component to demonstrate how changing a global variable has an impact across components. + + + +### Step 1. Familiarize with `index.html` +Note the button component and the expandable section component in the `` of the `index.html` file. + +### Step 2. Override a global custom property + +#### Step 2.1 +Write the prefix for the global custom property in the `:root` block in the `styles.css` file. Since global custom properties are prefixed with the word global, use that for the beginning of the custom property. + +It should look like this: `--pf-global` + +#### Step 2.2 +Add the concept to the global custom property. The concept for the link color is `link`. + +The global custom property should now look like this: `--pf-global--link` + +#### Step 2.3 +Add the property to the global custom property. As the color is being modified, add the color property as the next step. + +The global custom property should now look like: `--pf-global--link--Color` + +#### Step 2.4 +Define the value of the global variable. PatternFly's global danger color is: `--pf-global--danger-color--100`. +Assign the custom property name `(--pf-global--link--Color)` that is already inside of the `:root` block to the global danger color. + +It should look like this: `--pf-global--link--Color: var(--pf-global--danger-color--100);` + +The resulting UI in the CodeSandbox should match Figure 2. + +**Note:** The links in the button component and expandable component both have inherited the new red link color. + +**Figure 2.** + +An inline button and a 'show more' expandable section toggle both colored red + + + +## Part 3: Create and use component level CSS variables to override PatternFly styles +It is important to understand how BEM is used to create and override variables. + +To explore this concept, add a BEM element and custom styles with CSS custom properties to support a badge element in the label component using the provided CodeSandbox for part 3. Assume there is a common use case for adding a badge to the left of text in the label component. When adding the custom badge element to the label component, also apply a margin-right of 8px. + + + +### Step 1. Familiarize with `index.html` +Note the label component in the `` of the `index.html`. This label contains a badge component and some text. The default PatternFly label component only styles the label itself and the text inside. Since there has been a badge component passed into the label, it is necessary to add space between the badge and the text beside it. + +To do this the BEM way, a BEM element class `(pf-c-label__badge)` has been applied to the badge. + +### Step 2. Style the badge +**Note:** Never apply a global custom property as the value for a property in a component's CSS. + +#### Step 2.1 +Create a new variable to represent the badge's margin. Within style.css, in the `.pf-c-label{}` block, define the beginning of the custom property, which is the name of the component. + +It should look like: `--pf-c-label` + +#### Step 2.2 +Define the value of the new custom property. Add the element after the name of the component. + +The custom property should now be: `--pf-c-label__badge` + +#### Step 2.3 +Add the property being applied to the badge after the element. + +It should look like this: `--pf-c-label__badge--MarginRight` + +#### Step 2.4 +Define the value of the new custom CSS variable. PatternFly's global variable for 8px of space is `--pf-global--spacer--sm`. You can reference PatternFly’s documentation about spacers for more information. + +Assign the custom property name `--pf-c-label__badge--MarginRight` that is already inside of the `.pf-c-label{}` block to the global variable for 8px of space. + +It should look like this: `--pf-c-label__badge--MarginRight: var(--pf-global--spacer--sm);` + +#### Step 2.5 +Assign the new custom property name to the property that is being overridden. Add a margin-right declaration inside of `.pf-c-label__badge{}` and assign it to the new margin variable. + +It should look like this: `margin-right: var(--pf-c-label__badge--MarginRight);` + +**Note:** Once the preview reloads, there should be space to the right of the badge. + + + +## Part 4: Create and use global CSS variables to override PatternFly styles +To explore this concept, create a new global custom property for a 5xl font size. Use this new global property to make a new variation of the title component using the provided CodeSandbox for part 4. + +Referencing PatternFly's typography design guidelines, the largest font size PatternFly offers is a "super hero heading" size. It is 36px represented by the global variable `pf-global--FontSize--4xl`. Assume that there is a need for a larger font size for the title component that is used across the entire application. + + + +### Step 1. Familiarize with `index.html` +Note the title component in the `` of the `index.html` file. It has a modifier class applied to it which has no PatternFly styles defined for it thus far. + +### Step 2. Define a global custom property name +Follow the existing convention for global font size custom properties. + +#### Step 2.1 +Add the new custom property for font size inside of the `:root{}` block. This applies it to the global scope of the application. It should look like this: `--pf-global--FontSize--5xl` + +#### Step 2.2 +Define the value of the new global variable. Assign the property name to the pixel value for the new font size. +Update the line added in step 2.1 to be 42px. + +It should look like this: `--pf-global--FontSize--5xl: 42px;` + +### Step 3. Create a local component level custom property +Create a local component level custom property in the `.pf-c-title{}` block in the styles.css file. Set its value to the newly defined global property. +The local custom property should represent the 5xl variation's font size. + +#### Step 3.1 +Beginning with the component name, write the custom property and add it to the `.pf-c-title{}` block in the `style.css` file. + +It should look like this: `--pf-c-title` + +#### Step 3.2 +Add the new modifier to the custom property name. + +It should look like this: `--pf-c-title--m-5xl` + +#### Step 3.3 +Add the property that the custom property represents. + +It should look like this: `--pf-c-title--m-5xl--FontSize` + +#### Step 3.4 +Define the value of the component level custom property to be equal to the newly defined global variable. + +It should look like this: `--pf-c-title--m-5xl--FontSize: var(--pf-global--FontSize--5xl);` + +### Step 4. Define the styles for the new 5xl variation. + +#### Step 4.1 Chain selectors +Knowing that the modifier `.pf-m-5xl` will apply to the title component, in the CSS, chain the selector to create `.pf-c-title.pf-m-5xl` +Add this block inside of `.pf-c-title`, underneath the declaration from step 3. + +```noLive +.pf-c-title.pf-m-5xl { + /* styles go here */ +} +``` + +#### Step 4.2 +Create a declaration within the modifier block for the font-size CSS rule using the new component level custom property. + +It should look like: `font-size: var(--pf-c-title--m-5xl--FontSize);` inside of `.pf-m-5xl{}`. + + + +### Compare your results. +A fully constructed card can be viewed and modified in the CodeSandbox solution for part 4. Compare your work with the solution. + + + \ No newline at end of file diff --git a/packages/v4/patternfly-docs/content/training/html-css/fundamentals.md b/packages/v4/patternfly-docs/content/training/html-css/fundamentals.md new file mode 100644 index 0000000000..6fc47873cf --- /dev/null +++ b/packages/v4/patternfly-docs/content/training/html-css/fundamentals.md @@ -0,0 +1,180 @@ +--- +id: HTML fundamentals training +section: training +hideNavItem: true +--- +import { Button, ClipboardCopy, Divider, PageSection } from '@patternfly/react-core'; +import { CopyCodeBlock } from '../copyCodeBlock/copyCodeBlock'; + + +# Fundamentals + +PatternFly Core is based on the principles of Atomic Design and BEM (Block, Element, Modifier). + +Atomic Design is a methodology for creating design systems. Using Atomic Design, user interfaces are broken down into reusable components that can be reassembled to create reusable interaction patterns. +PatternFly consists of isolated and modular structures that fall into three categories: +- Components are modular and independent structures concerned with presentation. +- Layouts allow for the organization and grouping of their immediate children on the page. +- Demos illustrate how to assemble components and layouts into complex structures. + +## Components +In PatternFly, components are the basic building blocks of user interfaces. They cannot be broken down into smaller parts. Examples include the button, label, and badge components. A CodeSandbox link has been provided to experiment with and follow the proceeding steps. + + + + + +### Step 1. Add a button component. +Add a button element to the `` of the `index.html` file. To apply PatternFly styling to the button, add the class `pf-c-button`. To also apply ‘primary’ styling to the button and make it a bright blue color, add the `pf-m-primary` class. + + +{``} + + +**Note:** A simple component can be reused multiple times. + + +{`\n`} + + +### Step 2. Build more complex components +Simple components can be combined to make more complex components that are still reusable. +When simpler components are used within more complex components, the layout of the elements are defined in the stylesheet for the complex component. +In this step, add a badge component to the chip component. + +#### Step 2.1 +To build a chip component, replace the contents of the `` in the index.html file with the following code snippet. + + +{`
+ + Chip + +\n
`} +
+ +This is the default chip component that already has another component in it: the button. This is why the chip can be considered as a more complex component. + +#### Step 2.2 +Add the badge inside the chip. To do this, add this block of code between `pf-c-chip__text` and `pf-c-button`. + + +{` +7\n`} + + +**Note:** Remember, this is a component and not a demo because the chip component includes styles that handle how the badge looks within the chip. For example, when the badge component is added to the chip, it receives styling that gives it a margin. You can see that the badge in a chip has its own CSS variable, `--pf-c-chip__c-badge--MarginLeft`, defined for the right margin under the CSS Variables section of the chip documentation. + +The resulting chip should match the following image. + +Example of a rendered and styled chip component +
+ + +## Layouts + +In PatternFly, layouts allow for organizing and grouping elements. This tutorial covers just 1 of the 7 layouts. + +### Step 1 +Copy code into the `` of the `index.html` file. + + +{`
+
+
+ Title +
+
+ Body +
+ +
\n
`} +
+ +### Step 2 +Add the `pf-l-bullseye` class to the card. This will center the card horizontally and vertically on the page. +Find the outermost `
` wrapper for the card and add the class `pf-l-bullseye`. +It should look like: `
` + +**Note:** It’s important to follow the documentation for layouts because it demonstrates where to add the layout class. The documentation for bullseye specifies to add the class `pf-l-bullseye` to the parent container of its child. + + + +## Demos +Demos show how PatternFly’s components and layouts are put together to build more complex structures. Demos have no additional styling; they are strictly made from components and layouts. If styling is needed for a certain demo, then instead create new components or layouts, or variants of the components or layouts. + +Create a form demo using components and layouts. + +### Step 1. Add five form components +Copy and paste this block of code 5 times in the index.html file. + + +{`
+
+
+ +
+
+ +
+
\n
`} +
+ +### Step 2. Apply a grid layout + +#### Step 2.1 +Add one `
` wrapper around all 5 form components with the `pf-l-grid` layout class. It should look like this: + +```noLive +
+ /* 5 form components are here */ +
+``` + +### Step 3. +Wrap each form component in its own `pf-l-grid__item` layout class. To do this, look for each `pf-c-form` in `index.html` and wrap it in the `pf-l-grid__item` class. +The wrapper should look like this: + +```noLive +
+ /* code for individual form component */ +
+``` + +### Step 4. Add the `pf-m-gutter` modifier class to the grid layout +Adding the `pf-m-gutter` modifier class to the grid layout ensures there is equal spacing around all children. + +Add the class `pf-m-gutter` after `pf-l-grid` to the outermost wrapper, inside the quotation marks. +It should look like: `
` +**Note:** Learn how modifier classes work with layout classes by looking at PatternFly's grid documentation. + +### Step 5. Add modifier classes to the grid item classes. +This step modifies the number of columns that a grid item spans. The maximum number of columns that a grid item can span is 12 (which is equivalent to 100%). +#### Step 5.1 +Find each `pf-l-grid__item` that was added in step 3 and add the class `pf-m-[number from 1 - 12]`. The numbers across a row should add up to 12. + +#### Step 5.2 +Add `pf-m-6-col` to the first 2 grid items and add `pf-m-4-col` to the last 3 grid items. + +The first 2 grid items should look like: `
` +The second 2 grid items should look like: `
` + + + +## Compare your results. + +A fully constructed demo can be viewed and modified in the provided CodeSandbox solution. Compare your work with the solution. + + + + diff --git a/packages/v4/patternfly-docs/content/training/html.md b/packages/v4/patternfly-docs/content/training/html.md index 4006a830b8..94dd9a9e33 100644 --- a/packages/v4/patternfly-docs/content/training/html.md +++ b/packages/v4/patternfly-docs/content/training/html.md @@ -16,47 +16,22 @@ import { TrainingCard } from './trainingCard/trainingCard'; level="beginner" time="20 minutes" description="Learn about components, layouts, and demos." - katacodaId="the-building-blocks-of-patternfly" - /> - - - - - - - - - + + +## CSS Overrides + + diff --git a/packages/v4/patternfly-docs/content/training/img/alert-red-title.png b/packages/v4/patternfly-docs/content/training/img/alert-red-title.png new file mode 100644 index 0000000000..426226bd4d Binary files /dev/null and b/packages/v4/patternfly-docs/content/training/img/alert-red-title.png differ diff --git a/packages/v4/patternfly-docs/content/training/img/basic-card.png b/packages/v4/patternfly-docs/content/training/img/basic-card.png new file mode 100644 index 0000000000..1ecac3f9a2 Binary files /dev/null and b/packages/v4/patternfly-docs/content/training/img/basic-card.png differ diff --git a/packages/v4/patternfly-docs/content/training/img/card-layout.png b/packages/v4/patternfly-docs/content/training/img/card-layout.png new file mode 100644 index 0000000000..e99b5ce355 Binary files /dev/null and b/packages/v4/patternfly-docs/content/training/img/card-layout.png differ diff --git a/packages/v4/patternfly-docs/content/training/img/chip.png b/packages/v4/patternfly-docs/content/training/img/chip.png new file mode 100644 index 0000000000..c5e323fb41 Binary files /dev/null and b/packages/v4/patternfly-docs/content/training/img/chip.png differ diff --git a/packages/v4/patternfly-docs/content/training/img/global-link-color-red.png b/packages/v4/patternfly-docs/content/training/img/global-link-color-red.png new file mode 100644 index 0000000000..c5e04c62be Binary files /dev/null and b/packages/v4/patternfly-docs/content/training/img/global-link-color-red.png differ diff --git a/packages/v4/patternfly-docs/content/training/react-charts.md b/packages/v4/patternfly-docs/content/training/react-charts.md index ad76021a89..f025390c5a 100644 --- a/packages/v4/patternfly-docs/content/training/react-charts.md +++ b/packages/v4/patternfly-docs/content/training/react-charts.md @@ -1,6 +1,5 @@ --- id: React charts -section: training --- import { Gallery, GalleryItem } from '@patternfly/react-core'; diff --git a/packages/v4/patternfly-docs/content/training/react.md b/packages/v4/patternfly-docs/content/training/react.md index 5754e2234b..de41efde61 100644 --- a/packages/v4/patternfly-docs/content/training/react.md +++ b/packages/v4/patternfly-docs/content/training/react.md @@ -14,53 +14,10 @@ import { TrainingCard } from './trainingCard/trainingCard'; trainingType="react" title="PatternFly React basics" level="beginner" - time="10 minutes" - description="Build your first PatternFly component." - katacodaId="patternfly-react-basics" - /> - - - -## Components - - - - - - - - - - - diff --git a/packages/v4/patternfly-docs/content/training/react/fundamentals.md b/packages/v4/patternfly-docs/content/training/react/fundamentals.md new file mode 100644 index 0000000000..0491c680aa --- /dev/null +++ b/packages/v4/patternfly-docs/content/training/react/fundamentals.md @@ -0,0 +1,159 @@ +--- +id: React fundamentals training +section: training +hideNavItem: true +--- + +import { Button, ClipboardCopy, Divider, PageSection } from '@patternfly/react-core'; +import { CopyCodeBlock } from '../copyCodeBlock/copyCodeBlock'; + + +# React fundamentals +PatternFly React is made up of components, layouts, and demos. The PatternFly React library provides a collection of React components used to build interfaces with consistent markup, styling, and behavior. + +To become familiar with building UIs with PatternFly, you will build a PatternFly card. A card is a flexible element for containing any type of content. Cards are used on dashboards, in data displays, or for positioning content on a page. + + +## Step 1. Consider and evaluate the design +Consider the design in Figure 1 and evaluate which components and subcomponents compose the design. + + +**Figure 1** +Basic card layout + +Figure 1 is a design using PatternFly's card component. To learn more, read the documentation for a card's React implementation and the HTML structure. +In PatternFly, subcomponents compose the various regions of a card so its structure is flexible enough to accommodate a range of designs. For example, a card can contain 1 or more of its various subcomponents such as `CardHeader`, `CardHeaderMain`, `CardActions`, or `CardTitle`. +In this exercise, create a card to match the design in figure 1 with an image, close action, header, body, and footer. + +**Figure 2** + +Basic card visually segmented into various subcomponents + +The design in Figure 1 can be broken down into the card’s various subcomponents, as demonstrated in Figure 2. The React components used to construct this card can be arranged, as demonstrated in the card structure code snippet below. You can also view and modify this code in the provided CodeSandbox. + + + + + +**Card structure** + + +{` + + + + + + +\n`} + + + + + +## Step 2. Build out the `CardHeader` +The `CardHeader` contains `CardHeaderMain` and `CardActions`. + +### Step 2.1 +Add a `brand` component to the `CardHeaderMain` component to place a product logotype on a screen. All that is needed is the source image or SVG and alt text. Here the PatternFly logo is used. + + +{``} + + +### Step 2.2 +Add a close button to the `CardActions` component. Buttons communicate and trigger actions a user can take in an application or website. They come in several variants, such as `primary`, `secondary`, `tertiary`, `danger`, `plain`, `link`, and `control`. +Add a button using the `plain` variant. + + +{`Button variant="plain"> `} + + +### Step 2.3 +Add an icon inside the button. PatternFly React provides a variety of icons. They're easy to use and compile into SVG files. Use them inside buttons and other components. +Add a `TimesIcon` so that the card can be closed. + + +{``} + + + + +## Step 3. Build out the `CardTitle` + +### Step 3.1 +Add the text component with a variant inside of the ``. The text component can wrap any static HTML content that is placed on the page to provide correct formatting when using standard HTML tags. The text component comes in several variations, such as `h1`, `p`, `a`, `small`, `blockquote`, and `pre`. +Use the ‘p’ variation, which is specified with `component={TextVariants.p}`. +Add the following code inside the `CardTitle` component: + + +{` +PatternFly\n`} + + +### Step 3.2 +Add a subhead below the text added in Step 3.1. `TextContent` is used to wrap `Text` components and provides text with extra spacing and styling. +Add the following code inside of the Text component that is inside of the `CardTitle`: + + +{` + + Provided by Red Hat +\n`} + + + + +## Step 4. Add content to the `CardBody` component +Any filler text can be added as a child of the `CardBody` component. + + + +## Step 5. Add content and a layout to the `CardFooter` + +### Step 5.1 +Add a split layout to the `CardFooter` component. + +PatternFly offers several layout options, including grid, bullseye, and split layouts. +Use a split layout to separate a pair of buttons in the footer of the card. The split layout is designed to position items horizontally. Add a `` component inside `` for each item in the layout. + + +{` + + + +\n`} + + +### Step 5.2 +Add a button to the first `SplitItem` component. Use the link variant of the button and add an `isInline` property so that the buttons are inline rather than block elements. + + +{``} + + +### Step 5.3 +Add a button to the second `SplitItem` component. Use the same variant and properties as Step 5.2. + + +{``} + + +### Step 5.4 +Add a `hasGutter` property to the `Split` component to add more spacing between the buttons. The `Split` component should look like this with the `hasGutter` property set. + + +{``} + + + + +## Compare your results + +A fully constructed card can be viewed and modified in the CodeSandbox solution. Compare your work with the solution. + + + + \ No newline at end of file diff --git a/packages/v4/patternfly-docs/content/training/trainingCard/trainingCard.js b/packages/v4/patternfly-docs/content/training/trainingCard/trainingCard.js index 62b4ad01c0..8074a3beb1 100644 --- a/packages/v4/patternfly-docs/content/training/trainingCard/trainingCard.js +++ b/packages/v4/patternfly-docs/content/training/trainingCard/trainingCard.js @@ -32,7 +32,7 @@ export const TrainingCard = ({ time, description, subsection, - katacodaId = null, + name = null, designUrl = null }) => ( @@ -56,8 +56,8 @@ export const TrainingCard = ({ {description} - {katacodaId && ( - + {name && ( +