diff --git a/.circleci/config.yml b/.circleci/config.yml index b7bc9b941bd..977a2f70e32 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -12,7 +12,6 @@ references: - packages/react-inline-edit-extension/node_modules/ - packages/react-integration/demo-app-ts/node_modules/ - packages/react-integration/node_modules/ - - packages/react-styled-system/node_modules/ - packages/react-styles/node_modules/ - packages/react-table/node_modules/ - packages/react-tokens/node_modules/ @@ -26,7 +25,6 @@ references: - packages/react-charts/dist/ - packages/react-core/dist/ - packages/react-inline-edit-extension/dist/ - - packages/react-styled-system/dist/ - packages/react-styles/css/ - packages/react-styles/dist/ - packages/react-table/dist/ @@ -289,4 +287,4 @@ jobs: command: mkdir ~/.ssh/ && echo -e "Host github.com\n\tStrictHostKeyChecking no\n" > ~/.ssh/config - run: name: Deploy to NPM and Github - command: .circleci/release.sh + command: if [[ -z $CIRCLE_PULL_REQUEST ]]; then .circleci/release.sh; fi; diff --git a/.eslintrc.json b/.eslintrc.json index dce5c439bfe..2700f274705 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,7 +1,8 @@ { "env": { "browser": true, - "node": true + "node": true, + "es6": true }, "plugins": [ "@typescript-eslint", diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 92afcae44c3..172a4757a34 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -4,6 +4,100 @@ section: overview releaseNoteTOC: true --- +## 2020.03 release notes (2020-03-10) +Packages released: +- [@patternfly/react-catalog-view-extension: 1.4.29](https://www.npmjs.com/package/@patternfly/react-catalog-view-extension/v/1.4.29) +- [@patternfly/react-charts: 5.3.12](https://www.npmjs.com/package/@patternfly/react-charts/v/5.3.12) +- [@patternfly/react-core: 3.146.0](https://www.npmjs.com/package/@patternfly/react-core/v/3.146.0) +- [@patternfly/react-inline-edit-extension: 2.17.29](https://www.npmjs.com/package/@patternfly/react-inline-edit-extension/v/2.17.29) +- [@patternfly/react-styles: 3.7.8](https://www.npmjs.com/package/@patternfly/react-styles/v/3.7.8) +- [@patternfly/react-table: 2.28.10](https://www.npmjs.com/package/@patternfly/react-table/v/2.28.10) +- [@patternfly/react-tokens: 2.8.8](https://www.npmjs.com/package/@patternfly/react-tokens/v/2.8.8) +- [@patternfly/react-topology: 2.14.29](https://www.npmjs.com/package/@patternfly/react-topology/v/2.14.29) +- [@patternfly/react-virtualized-extension: 1.4.30](https://www.npmjs.com/package/@patternfly/react-virtualized-extension/v/1.4.30) +- [@patternfly/react-icons: 3.15.11](https://www.npmjs.com/package/@patternfly/react-icons/v/3.15.11) + +### Components: +- **Background image:** + - Remove width attr from background image filter element ([#3758](https://github.com/patternfly/patternfly-react/pull/3758)) +- **Data toolbar:** + - Cleaned up beta warning for data toolbar ([#3755](https://github.com/patternfly/patternfly-react/pull/3755)) +- **Drawer:** + - Added console warning to Drawer beta component ([#3856](https://github.com/patternfly/patternfly-react/pull/3856)) + - Updated drawer for Master/Detail support ([#3884](https://github.com/patternfly/patternfly-react/pull/3884)) +- **Dropdown** + - Updated to Destructure bubbleEvent from props to avoid it passing to button el ([#3894](https://github.com/patternfly/patternfly-react/pull/3894)) +- **Button:** + - Added link icon position for link buttons ([#3798](https://github.com/patternfly/patternfly-react/pull/3798)) +- **Card:** + - Added selectable and selected variation ([#3587](https://github.com/patternfly/patternfly-react/pull/3587)) +- **Chip group:** + - Added a tooltip to the Chipgroup label ([#3826](https://github.com/patternfly/patternfly-react/pull/3826)) +- **Data list:** + - Added compact data list ([#3807](https://github.com/patternfly/patternfly-react/pull/3807)) +- **Data toolbar:** + - Added support for key with categoryName. ([#3880](https://github.com/patternfly/patternfly-react/pull/3880)) +- **Dropdown:** + - Fixed keyboard selection of toggle causing selection of parent ([#3816](https://github.com/patternfly/patternfly-react/pull/3816)) +- **File upload:** + - Added new beta file upload component ([#3865](https://github.com/patternfly/patternfly-react/pull/3865)) +- **Input group:** + - Updated docs to be more readable ([#3839](https://github.com/patternfly/patternfly-react/pull/3839)) +- **Modal:** + - Added description property ([#3821](https://github.com/patternfly/patternfly-react/pull/3821)) + - Moved description to separate component ([#3897](https://github.com/patternfly/patternfly-react/pull/3897)) +- **Pagination:** + - Updated to calculate navigation input according to last page ([#3534](https://github.com/patternfly/patternfly-react/pull/3534)) +- **Select:** + - Added inline filtering to checkbox select ([#3843](https://github.com/patternfly/patternfly-react/pull/3843)) + - Fix panel checkbox labels ([#3820](https://github.com/patternfly/patternfly-react/pull/3820)) +- **Switch:** + - Updated to avoid switch id override by props ([#3706](https://github.com/patternfly/patternfly-react/pull/3706)) +- **Tabs:** + - Updated tabs with nav examples + add Tab component to props docs ([#3527](https://github.com/patternfly/patternfly-react/pull/3527)) +- **Tooltip:** + - Removed TooltipContent from propComponents ([#3800](https://github.com/patternfly/patternfly-react/pull/3800)) +- **Wizard:** + - Used patternfly-styles to set the no padding modifier ([#3871](https://github.com/patternfly/patternfly-react/pull/3871)) + +### Catalog view extension +- **Catalog tile:** + - Removed truncation and maxLength props ([#3830](https://github.com/patternfly/patternfly-react/pull/3830)) + +### Other: +- **Chore:** + - Added experimental exports ([#3775](https://github.com/patternfly/patternfly-react/pull/3775)) + - Wrapped layout examples to fix codesandbox ([#3818](https://github.com/patternfly/patternfly-react/pull/3818)) + - Tested prerelease workflow ([#3868](https://github.com/patternfly/patternfly-react/pull/3868)) + - Removed exenv and lodash ([#3882](https://github.com/patternfly/patternfly-react/pull/3882)) + - Added jest test generator ([#3828](https://github.com/patternfly/patternfly-react/pull/3828)) + - Added experimental/components directory ([#3764](https://github.com/patternfly/patternfly-react/pull/3764)) + - Improved promote script ([#3812](https://github.com/patternfly/patternfly-react/pull/3812)) + - Fixed react-docs version ([#3879](https://github.com/patternfly/patternfly-react/pull/3879)) + - Updated Gatsby theme for patternfly org ([#3813](https://github.com/patternfly/patternfly-react/pull/3813)) + - Updated versions in react-core for react-icons ([#3760](https://github.com/patternfly/patternfly-react/pull/3760)) + - Updated additional versions in react-core for react-icons ([#3761](https://github.com/patternfly/patternfly-react/pull/3761)) +- **Docs:** + - Updated readme to match new guidelines ([#3837](https://github.com/patternfly/patternfly-react/pull/3837)) + - Added GDPR banner to all pages ([#3831](https://github.com/patternfly/patternfly-react/pull/3831)) + - Added page titles for react docs & react icons pages ([#3851](https://github.com/patternfly/patternfly-react/pull/3851)) + - Fixed typo in README ([#3769](https://github.com/patternfly/patternfly-react/pull/3769)) +- **Linting:** + - Fixed eslint recommendations ([#3858](https://github.com/patternfly/patternfly-react/pull/3858)) + - Added linting to react styles ([#3723](https://github.com/patternfly/patternfly-react/pull/3723)) + - Added linting react tokens ([#3725](https://github.com/patternfly/patternfly-react/pull/3725)) +- **Ouia:** + - Updated to not omit ouiaContext ([#3872](https://github.com/patternfly/patternfly-react/pull/3872)) + +### Virtualized extension +- Resolved linter errors ([#3726](https://github.com/patternfly/patternfly-react/pull/3726)) + +### PF3: +- **Chore:** + - Enabled releasing patternfly 3 ([#3863](https://github.com/patternfly/patternfly-react/pull/3863)) + - Removed patternfly-3 packages ([#3852](https://github.com/patternfly/patternfly-react/pull/3852)) + - Created patternfly-3 branch ([#3846](https://github.com/patternfly/patternfly-react/pull/3846)) + ## 2020.02 release notes (2020-02-18) Packages released: - [@patternfly/react-catalog-view-extension: 1.4.11](https://www.npmjs.com/package/@patternfly/react-catalog-view-extension/v/1.4.11) diff --git a/packages/react-codemods/CHANGELOG.md b/packages/react-codemods/CHANGELOG.md deleted file mode 100644 index b0056ee92c0..00000000000 --- a/packages/react-codemods/CHANGELOG.md +++ /dev/null @@ -1,55 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.0.2](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-codemods@2.0.1...@patternfly/react-codemods@2.0.2) (2020-03-17) - -**Note:** Version bump only for package @patternfly/react-codemods - - - - - -## [2.0.1](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-codemods@1.1.4...@patternfly/react-codemods@2.0.1) (2020-03-05) - -**Note:** Version bump only for package @patternfly/react-codemods - - - - - -## 1.1.4 (2019-04-15) - - -### Bug Fixes - -* Update React with changes from core ([#1703](https://github.com/patternfly/patternfly-react/issues/1703)) ([a219cae](https://github.com/patternfly/patternfly-react/commit/a219cae)), closes [#1680](https://github.com/patternfly/patternfly-react/issues/1680) [#1684](https://github.com/patternfly/patternfly-react/issues/1684) [#1684](https://github.com/patternfly/patternfly-react/issues/1684) - - - - - -## [1.1.3](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-codemods@1.1.2...@patternfly/react-codemods@1.1.3) (2019-03-12) - -**Note:** Version bump only for package @patternfly/react-codemods - - - - - -## 1.1.2 (2019-03-11) - - -### Bug Fixes - -* **build:** Support running the test suite under Windows ([#1255](https://github.com/patternfly/patternfly-react/issues/1255)) [ci skip] ([851756e](https://github.com/patternfly/patternfly-react/commit/851756e)) -* **tsconfig:** avatar tsx change ([#1535](https://github.com/patternfly/patternfly-react/issues/1535)) ([8107f5c](https://github.com/patternfly/patternfly-react/commit/8107f5c)) - - - - - -## 1.1.1 (2019-03-04) - -**Note:** Version bump only for package @patternfly/react-codemods diff --git a/packages/react-codemods/README.md b/packages/react-codemods/README.md deleted file mode 100644 index 4802faa462f..00000000000 --- a/packages/react-codemods/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# @patternfly/react-codemods - -_PatternFly React codemods are currently experimental only._ - -This repository contains a collection of codemod scripts for use with -[JSCodeshift](https://github.com/facebook/jscodeshift) that help update Patternfly React projects. - -## Setup & Run - -1. `yarn global add jscodeshift` -2. `yarn install @patternfly/react-codemods` -3. `jscodeshift -t node_modules/@patternfly/react-codemods/transforms/[transform].js [files]` - * `path` - files or directory to transform; - * use the `-d` option for a dry-run and use `-p` to print the output for comparison; - * use the `--extensions` option if your files have different extensions than `.js` (for example, `--extensions js,jsx`); - * if you use flowtype, you might also need to use `--parser=flow`; - * see all available [jscodeshift options](https://github.com/facebook/jscodeshift#usage-cli). -4. Review changes via git diff. Keep what you want, throw it out if you don't. Magic! - -## Included Scripts - -## `pf3-pf4` - -Converts PF3 components of `patternfly-react` to compatible PF4 `@patternfly/react-core` components; - -```sh -jscodeshift -t node_modules/@patternfly/react-codemods/transforms/pf3-pf4.js [--component]=comma,separated,components -``` - -## Options -```text ---components Comma separated list of components to transform. Defaults to "*". EX: --components=Button,Alert -``` - -## Components - -### `Button` - -### Supported Props -| In Prop | Out Prop | Value Tranforms | -|------------------|--------------|---------------------------| -| `block` | `isBlock` | n/a | -| `active` | `isActive` | n/a | -| `disabled` | `isDisabled` | n/a | -| `componentClass` | `component` | n/a | -| `bsClass` | `undefined` | n/a (removed) | -| `bsStyle` | `variant` | primary -> primary | -| | | secondary -> secondary | -| | | danger -> danger | -| | | link -> link | -| | | info -> secondary | -| | | `undefined` -> secondary | - -### Unsupported props -* `componentClass` -* `href` - - -#### Before - -```jsx -import { Button } from 'patternfly-react'; - -const primary = ; -``` - -#### After - -```jsx -import { Button } from '@patternfly/react-core'; - -const primary = ; -``` diff --git a/packages/react-codemods/componentConfig.js b/packages/react-codemods/componentConfig.js deleted file mode 100644 index fb0d2fbc7d9..00000000000 --- a/packages/react-codemods/componentConfig.js +++ /dev/null @@ -1,23 +0,0 @@ -module.exports = { - Button: { - package: '@patternfly/react-core', - props: { - bsStyle: { - name: 'variant', - values: { - primary: 'primary', - link: 'link', - danger: 'danger' - }, - defaultValue: 'secondary', - fallbackValue: 'secondary' - }, - active: 'isActive', - componentClass: 'component', - disabled: 'isDisabled', - block: 'isBlock', - bsClass: { remove: true } - }, - unsupportedProps: ['bsSize'] - } -}; diff --git a/packages/react-codemods/package.json b/packages/react-codemods/package.json deleted file mode 100644 index 8f0fa09d4f8..00000000000 --- a/packages/react-codemods/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "@patternfly/react-codemods", - "version": "2.0.2", - "private": false, - "license": "MIT", - "publishConfig": { - "access": "public" - }, - "repository": { - "type": "git", - "url": "https://github.com/patternfly/patternfly-react.git" - }, - "author": "Red Hat", - "keywords": [ - "react", - "patternfly", - "eslint" - ], - "bugs": { - "url": "https://github.com/patternfly/patternfly-react/issues" - }, - "homepage": "https://github.com/patternfly/patternfly-react/blob/master/packages/codemods/README.md", - "devDependencies": { - "jscodeshift": "^0.5.0" - }, - "dependencies": { - "colors": "^1.3.0" - } -} diff --git a/packages/react-codemods/transforms/__snapshots__/pf3-pf4.test.js.snap b/packages/react-codemods/transforms/__snapshots__/pf3-pf4.test.js.snap deleted file mode 100644 index 5d5e62ff5d9..00000000000 --- a/packages/react-codemods/transforms/__snapshots__/pf3-pf4.test.js.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`throws error for components that are not supported 1`] = `"UnsupportedComponent is not a supported component"`; diff --git a/packages/react-codemods/transforms/pf3-pf4.button.test.js b/packages/react-codemods/transforms/pf3-pf4.button.test.js deleted file mode 100644 index 14879f24bec..00000000000 --- a/packages/react-codemods/transforms/pf3-pf4.button.test.js +++ /dev/null @@ -1,121 +0,0 @@ -import prettier from 'prettier'; -import { defineInlineTest } from 'jscodeshift/dist/testUtils'; -import transform from './pf3-pf4'; - -const prettierConfig = { - ...prettier.resolveConfig.sync(process.cwd()), - parser: 'babel' -}; -const pretty = src => prettier.format(src, prettierConfig); - -global.console.log = jest.fn(); - -defineInlineTest( - transform, - {}, - ` -import { Button as PFButton } from 'patternfly-react'; -const btn = Button; -`, - pretty(` - import { Button as PFButton } from '@patternfly/react-core'; - const btn = Button; - `), - 'Supports import alias' -); - -defineInlineTest( - transform, - {}, - ` -import { Button } from 'patternfly-react'; -const btn = ; -`, - pretty(` - import { Button } from '@patternfly/react-core'; - const btn = ; - `), - 'Transforms bsStyle primary to variant primary' -); - -defineInlineTest( - transform, - {}, - ` -import { Button } from 'patternfly-react'; -const btn = ; -`, - pretty(` - import { Button } from '@patternfly/react-core'; - const btn = ; - `), - 'Transforms block to isBlock' -); - -defineInlineTest( - transform, - {}, - ` - import { Button } from 'patternfly-react'; - const btn = ; -`, - pretty(` - import { Button } from '@patternfly/react-core'; - const btn = ; - `), - 'Transforms disabled to isDisabled' -); - -defineInlineTest( - transform, - {}, - ` -import { Button } from 'patternfly-react'; -const btn = ; -`, - pretty(` - import { Button } from '@patternfly/react-core'; - const btn = ; - `), - 'Transforms active to isActive' -); - -defineInlineTest( - transform, - {}, - ` -import { Button } from 'patternfly-react'; -const btn = ; -`, - pretty(` - import { Button } from '@patternfly/react-core'; - const btn = ; - `), - 'Transforms componentClass to component' -); - -defineInlineTest( - transform, - {}, - ` -import { Button } from 'patternfly-react'; -const btn = ; -`, - pretty(` - import { Button } from '@patternfly/react-core'; - const btn = ; - `), - 'Removes bsClass prop' -); - -defineInlineTest( - transform, - {}, - ` -import { Button } from 'patternfly-react'; -const btn = ; -const supported = ; -`, - '', - 'Ignores file for bsSize references' -); diff --git a/packages/react-codemods/transforms/pf3-pf4.js b/packages/react-codemods/transforms/pf3-pf4.js deleted file mode 100644 index b06e335ec86..00000000000 --- a/packages/react-codemods/transforms/pf3-pf4.js +++ /dev/null @@ -1,229 +0,0 @@ -/* eslint-disable no-console */ -const colors = require('colors'); -const componentConfigs = require('../componentConfig'); - -let prettier; -try { - // not all projects use prettier, but we want to use it if possible - prettier = require('prettier'); // eslint-disable-line -} catch (err) { - prettier = null; -} - -const oldPackage = 'patternfly-react'; -const newPackage = '@patternfly/react-core'; - -/** - * @param {string} specifiedComponents glob of specified components - */ -function getFilteredComponentConfig(specifiedComponents = '*') { - if (specifiedComponents === '*') { - return componentConfigs; - } - - return specifiedComponents - .split(',') - .map(k => k.trim()) - .reduce((conf, key) => { - if (!componentConfigs[key]) { - throw new Error(`${key} is not a supported component`); - } - return { - ...conf, - [key]: componentConfigs[key] - }; - }, {}); -} - -module.exports = (file, api, options) => { - const j = api.jscodeshift; - const root = j(file.source); - const filteredConfig = getFilteredComponentConfig(options.components); - - /** - * @param {string} importName import name - * @param {string} localName local name - */ - function addComponentToReactCoreImport(importName, localName) { - const reactCoreImport = getReactCoreImport(); - if (reactCoreImport.length > 0) { - reactCoreImport.get().node.specifiers.push(j.importSpecifier(j.identifier(importName), j.identifier(localName))); - return; - } - - const path = findImportAfterReactCore(); - if (path) { - const importStatement = j.importDeclaration( - [j.importSpecifier(j.identifier(importName), j.identifier(localName))], - j.literal(newPackage) - ); - - // If there is a leading comment, retain it - // https://github.com/facebook/jscodeshift/blob/master/recipes/retain-first-comment.md - const firstNode = root.find(j.Program).get('body', 0).node; - if (firstNode === path.node) { - const { comments } = firstNode; - if (comments) { - delete firstNode.comments; - importStatement.leadingComments = comments; - } - } - - j(path).insertBefore(importStatement); - } - } - - /** - * @returns {string} import after react core - */ - function findImportAfterReactCore() { - let target; - let targetName; - - root.find(j.ImportDeclaration).forEach(path => { - const name = path.value.source.value.toLowerCase(); - if (name > newPackage && (!target || name < targetName)) { - targetName = name; - target = path; - } - }); - - return target; - } - - /** - * @returns {object} @patternfly/react-core import - */ - function getReactCoreImport() { - return root.find(j.ImportDeclaration, { - source: { value: newPackage } - }); - } - - /** - * @returns {object} patternfly-react import - */ - function getPatternflyReactImport() { - return root.find(j.ImportDeclaration, { - source: { value: oldPackage } - }); - } - - /** - * @param {object[]} jsxElements array of JSX Elements - * @param {object[]} unsupportedProps deprecated props - */ - function verifyNoUnsupportedPropReferences(jsxElements, unsupportedProps) { - let hasSupportedPropReferences = false; - jsxElements.find(j.JSXAttribute).forEach(attrPath => { - const propName = attrPath.node.name.name; - if (unsupportedProps.includes(propName)) { - const { start } = attrPath.node.name.loc; - console.log(colors.yellow(`UnsupportedProp: ${propName} (./${file.path}:${start.line}:${start.column})`)); - hasSupportedPropReferences = true; - } - }); - return hasSupportedPropReferences; - } - - /** - * @param {object} componentConfig component config - * @param {string} propName prop name - */ - function getConfigForProp(componentConfig, propName) { - const propConfig = componentConfig.props[propName]; - return typeof propConfig === 'string' ? { name: propConfig } : propConfig; - } - - /** - * @param {string} prop property - * @param {string} jsxElementPath element path - * @param {object} propConfig property config - */ - function transformProp(prop, jsxElementPath, propConfig) { - const propInstances = j(jsxElementPath).find(j.JSXAttribute, { - name: { name: prop } - }); - - if (propConfig.defaultValue && propInstances.length === 0) { - jsxElementPath.node.openingElement.attributes.push( - j.jsxAttribute(j.jsxIdentifier(propConfig.name), j.literal(propConfig.defaultValue)) - ); - return; - } - - propInstances.forEach(propPath => { - if (propConfig.remove) { - j(propPath).remove(); - return; - } - - propPath.node.name.name = propConfig.name; - }); - } - - /** - * Removes patternfly-react import - */ - function removePatternflyReactImport() { - getPatternflyReactImport().forEach(path => { - if (path.node.specifiers.length === 0) { - j(path).remove(); - } - }); - } - - /** - * @returns {string} pretty babel'ed version of source - */ - function getPrettySource() { - const transformedSource = root.toSource({ - quote: 'auto', - tabWidth: 2 - }); - - return prettier - ? prettier.format(transformedSource, { - parser: 'babel', - ...prettier.resolveConfig.sync(process.cwd()) - }) - : transformedSource; - } - - let hasModifications = false; - - getPatternflyReactImport() - .find(j.ImportSpecifier) - .forEach(path => { - const importedName = path.node.imported.name; - const localName = path.node.local.name; - const transformConfig = filteredConfig[importedName]; - - if (!transformConfig) { - return; - } - - const allElements = root.findJSXElements(localName); - - if (verifyNoUnsupportedPropReferences(allElements, transformConfig.unsupportedProps)) { - return; - } - - hasModifications = true; - - allElements.forEach(elementPath => { - Object.keys(transformConfig.props).forEach(prop => { - transformProp(prop, elementPath, getConfigForProp(transformConfig, prop)); - }); - }); - addComponentToReactCoreImport(importedName, localName); - j(path).remove(); - }); - - if (hasModifications) { - removePatternflyReactImport(); - return getPrettySource(); - } - - return null; -}; diff --git a/packages/react-codemods/transforms/pf3-pf4.test.js b/packages/react-codemods/transforms/pf3-pf4.test.js deleted file mode 100644 index b879360dd3c..00000000000 --- a/packages/react-codemods/transforms/pf3-pf4.test.js +++ /dev/null @@ -1,80 +0,0 @@ -import prettier from 'prettier'; -import { defineInlineTest, runInlineTest } from 'jscodeshift/dist/testUtils'; -import transform from './pf3-pf4'; - -const prettierConfig = { - ...prettier.resolveConfig.sync(process.cwd()), - parser: 'babel' -}; -const pretty = src => prettier.format(src, prettierConfig); - -global.console.log = jest.fn(); - -test('throws error for components that are not supported', () => { - expect(() => { - const options = { - components: 'Button,UnsupportedComponent' - }; - runInlineTest(transform, options, { source: '' }, ''); - }).toThrowErrorMatchingSnapshot(); -}); - -defineInlineTest( - transform, - { components: '*' }, - ` -import { Button } from 'patternfly-react'; -const Btn = diff --git a/packages/react-core/src/components/AboutModal/AboutModalContainer.tsx b/packages/react-core/src/components/AboutModal/AboutModalContainer.tsx index 77e75c05231..bf0d32ee619 100644 --- a/packages/react-core/src/components/AboutModal/AboutModalContainer.tsx +++ b/packages/react-core/src/components/AboutModal/AboutModalContainer.tsx @@ -37,6 +37,8 @@ export interface AboutModalContainerProps extends React.HTMLProps = ({ @@ -51,6 +53,7 @@ export const AboutModalContainer: React.FunctionComponent { if (!isOpen) { @@ -61,7 +64,7 @@ export const AboutModalContainer: React.FunctionComponent - + {productName && } { const view = shallow(); expect(view).toMatchSnapshot(); }); + +test('AboutModalBoxCloseButton Test close button aria label', () => { + const closeButtonAriaLabel = 'Klose Daylok' + const view = shallow(); + expect(view).toMatchSnapshot(); +}); diff --git a/packages/react-core/src/components/AboutModal/__tests__/__snapshots__/AboutModalBoxCloseButton.test.tsx.snap b/packages/react-core/src/components/AboutModal/__tests__/__snapshots__/AboutModalBoxCloseButton.test.tsx.snap index d001a6a5701..998d2db76f9 100644 --- a/packages/react-core/src/components/AboutModal/__tests__/__snapshots__/AboutModalBoxCloseButton.test.tsx.snap +++ b/packages/react-core/src/components/AboutModal/__tests__/__snapshots__/AboutModalBoxCloseButton.test.tsx.snap @@ -19,6 +19,25 @@ exports[`AboutModalBoxCloseButton Test 1`] = ` `; +exports[`AboutModalBoxCloseButton Test close button aria label 1`] = ` +
+ + + +
+`; + exports[`AboutModalBoxCloseButton Test onclose 1`] = `
{ void; /** Aria label for close button */ closeBtnAriaLabel?: string; + /** Position of the tooltip which is displayed if the category name text is longer */ + tooltipPosition?: 'auto' | 'top' | 'bottom' | 'left' | 'right'; } -export const ChipGroupToolbarItem: React.FunctionComponent = ({ - categoryName = '', - children = null, - className = '', - isClosable = false, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - onClick = (_e: React.MouseEvent) => undefined as any, - closeBtnAriaLabel = 'Close chip group', - ...props -}: ChipGroupToolbarItemProps) => { - if (React.Children.count(children)) { - const renderChipGroup = (id: string, HeadingLevel: any) => ( -
    -
  • - - {categoryName} - -
      {children}
    - {isClosable && ( -
    - - -
    - )} -
  • -
- ); +interface ChipGroupToolbarItemState { + isTooltipVisible: boolean; +} + +export class ChipGroupToolbarItem extends React.Component { + constructor(props: ChipGroupToolbarItemProps) { + super(props); + this.state = { + isTooltipVisible: false + }; + } + + heading = React.createRef(); + + static defaultProps: ChipGroupToolbarItemProps = { + categoryName: '', + children: null, + className: '', + isClosable: false, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + onClick: (_e: React.MouseEvent) => undefined as any, + closeBtnAriaLabel: 'Close chip group', + tooltipPosition: 'top' + }; - return ( - - {(HeadingLevel: any) => {randomId => renderChipGroup(randomId, HeadingLevel)}} - - ); + componentDidMount() { + this.setState({ + isTooltipVisible: Boolean( + this.heading.current && this.heading.current.offsetWidth < this.heading.current.scrollWidth + ) + }); } - return null; -}; + + render() { + const { + categoryName, + children, + className, + isClosable, + closeBtnAriaLabel, + onClick, + tooltipPosition, + ...rest + } = this.props; + + if (React.Children.count(children)) { + const renderChipGroup = (id: string, HeadingLevel: any) => ( +
    +
  • + {this.state.isTooltipVisible ? ( + + + {categoryName} + + + ) : ( + + {categoryName} + + )} +
      {children}
    + {isClosable && ( +
    + + +
    + )} +
  • +
+ ); + + return ( + + {(HeadingLevel: any) => {randomId => renderChipGroup(randomId, HeadingLevel)}} + + ); + } + return null; + } +} diff --git a/packages/react-core/src/components/ChipGroup/__tests__/ChipGroup.test.tsx b/packages/react-core/src/components/ChipGroup/__tests__/ChipGroup.test.tsx index 0c58ea39507..b1d4d29e452 100644 --- a/packages/react-core/src/components/ChipGroup/__tests__/ChipGroup.test.tsx +++ b/packages/react-core/src/components/ChipGroup/__tests__/ChipGroup.test.tsx @@ -54,4 +54,15 @@ describe('ChipGroup', () => { const view = shallow(); expect(view.html()).toBeNull(); }); + + test('chip group with toolbar and tooltip', () => { + const view = shallow( + + + 1.1 + + + ); + expect(view).toMatchSnapshot(); + }); }); diff --git a/packages/react-core/src/components/ChipGroup/__tests__/__snapshots__/ChipGroup.test.tsx.snap b/packages/react-core/src/components/ChipGroup/__tests__/__snapshots__/ChipGroup.test.tsx.snap index 5eca64b3158..e40ce7ecbb6 100644 --- a/packages/react-core/src/components/ChipGroup/__tests__/__snapshots__/ChipGroup.test.tsx.snap +++ b/packages/react-core/src/components/ChipGroup/__tests__/__snapshots__/ChipGroup.test.tsx.snap @@ -36,7 +36,12 @@ exports[`ChipGroup chip group with closable toolbar 1`] = ` withToolbar={true} > 1.1 @@ -60,7 +65,44 @@ exports[`ChipGroup chip group with toolbar 1`] = ` onToggleCollapse={[Function]} withToolbar={true} > - + + + 1.1 + + + + +`; + +exports[`ChipGroup chip group with toolbar and tooltip 1`] = ` + + + 1.1 diff --git a/packages/react-core/src/components/ChipGroup/examples/ChipGroup.md b/packages/react-core/src/components/ChipGroup/examples/ChipGroup.md index 9f914c07c85..1f4b2e32286 100644 --- a/packages/react-core/src/components/ChipGroup/examples/ChipGroup.md +++ b/packages/react-core/src/components/ChipGroup/examples/ChipGroup.md @@ -85,7 +85,7 @@ class ToolbarChipGroup extends React.Component { this.state = { chipGroups: [ { - category: 'Category 1', + category: 'Category 1 has a very long name', chips: ['Chip 1', 'Chip 2'] }, { diff --git a/packages/react-core/src/components/DataList/DataList.tsx b/packages/react-core/src/components/DataList/DataList.tsx index 788cd14a695..6439d6b653b 100644 --- a/packages/react-core/src/components/DataList/DataList.tsx +++ b/packages/react-core/src/components/DataList/DataList.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; -import { isUndefined } from 'lodash'; import { css } from '@patternfly/react-styles'; import styles from '@patternfly/react-styles/css/components/DataList/data-list'; @@ -15,6 +14,8 @@ export interface DataListProps extends React.HTMLProps { onSelectDataListItem?: (id: string) => void; /* Id of DataList item currently selected */ selectedDataListItemId?: string; + /** Flag indicating if DataList should have compact styling */ + isCompact?: boolean; } interface DataListContextProps { @@ -33,9 +34,10 @@ export const DataList: React.FunctionComponent = ({ 'aria-label': ariaLabel, selectedDataListItemId = '', onSelectDataListItem, + isCompact = false, ...props }: DataListProps) => { - const isSelectable = !isUndefined(onSelectDataListItem); + const isSelectable = onSelectDataListItem !== undefined; const updateSelectedDataListItem = (id: string) => { onSelectDataListItem(id); @@ -49,7 +51,11 @@ export const DataList: React.FunctionComponent = ({ updateSelectedDataListItem }} > -
    +
      {children}
    diff --git a/packages/react-core/src/components/DataList/__tests__/DataList.test.tsx b/packages/react-core/src/components/DataList/__tests__/DataList.test.tsx index fef16bad9aa..6ebb33d023f 100644 --- a/packages/react-core/src/components/DataList/__tests__/DataList.test.tsx +++ b/packages/react-core/src/components/DataList/__tests__/DataList.test.tsx @@ -18,6 +18,11 @@ describe('DataList', () => { expect(view).toMatchSnapshot(); }); + test('List compact', () => { + const view = shallow(); + expect(view).toMatchSnapshot(); + }); + test('List', () => { const view = shallow(); expect(view).toMatchSnapshot(); diff --git a/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataList.test.tsx.snap b/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataList.test.tsx.snap index d509507f326..a1458165bf7 100644 --- a/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataList.test.tsx.snap +++ b/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataList.test.tsx.snap @@ -128,6 +128,23 @@ exports[`DataList List 1`] = ` `; +exports[`DataList List compact 1`] = ` + +
      + +`; + exports[`DataList List default 1`] = ` ( + + + + + Primary content + , + Secondary content + ]} + /> + + + + + + Secondary content (pf-m-no-fill) + , + + Secondary content (pf-m-align-right pf-m-no-fill) + + ]} + /> + + + +); +``` + +```js title=Compact import React from 'react'; import { Button, @@ -45,7 +108,7 @@ import { } from '@patternfly/react-core'; SimpleDataList = () => ( - + } dropdownItems={[ - Primary, - Secondary, + + Primary + , + + Secondary + ]} /> @@ -249,10 +316,18 @@ class CheckboxActionDataList extends React.Component { onSelect={this.onSelect3} toggle={} dropdownItems={[ - Primary, - Secondary, - Secondary, - Secondary, + + Primary + , + + Secondary + , + + Secondary + , + + Secondary + ]} /> @@ -825,6 +900,7 @@ class ModifiersDataList extends React.Component { } } ``` + ```js title=Selectable-rows import React from 'react'; import { @@ -845,17 +921,17 @@ import { class SelectableDataList extends React.Component { constructor(props) { super(props); - this.state = { + this.state = { isOpen1: false, isOpen2: false, selectedDataListItemId: '' }; - this.onToggle1 = isOpen1 => { + this.onToggle1 = isOpen1 => { this.setState({ isOpen1 }); }; - - this.onToggle2 = isOpen2 => { + + this.onToggle2 = isOpen2 => { this.setState({ isOpen2 }); }; @@ -864,22 +940,26 @@ class SelectableDataList extends React.Component { isOpen1: !prevState.isOpen1 })); }; - + this.onSelect2 = event => { this.setState(prevState => ({ isOpen2: !prevState.isOpen2 })); }; - - this.onSelectDataListItem = (id) => { + + this.onSelectDataListItem = id => { this.setState({ selectedDataListItemId: id }); - } + }; } render() { return ( - + {!this.state.isDeleted && ( diff --git a/packages/react-core/src/components/DataToolbar/DataToolbar.tsx b/packages/react-core/src/components/DataToolbar/DataToolbar.tsx index b8b76d1daf6..d90e7c04987 100644 --- a/packages/react-core/src/components/DataToolbar/DataToolbar.tsx +++ b/packages/react-core/src/components/DataToolbar/DataToolbar.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; -import { sum, values } from 'lodash'; import styles from '@patternfly/react-styles/css/components/DataToolbar/data-toolbar'; import { css } from '@patternfly/react-styles'; import { DataToolbarContext } from './DataToolbarUtils'; @@ -91,7 +90,7 @@ export class DataToolbar extends React.Component sum(values(this.state.filterInfo)); + getNumberOfFilters = () => Object.values(this.state.filterInfo).reduce((acc, cur) => acc + cur, 0); render() { const { diff --git a/packages/react-core/src/components/DataToolbar/DataToolbarFilter.tsx b/packages/react-core/src/components/DataToolbar/DataToolbarFilter.tsx index cb3e38ca2dd..0f4ab10f735 100644 --- a/packages/react-core/src/components/DataToolbar/DataToolbarFilter.tsx +++ b/packages/react-core/src/components/DataToolbar/DataToolbarFilter.tsx @@ -5,6 +5,13 @@ import { ChipGroup, Chip, ChipGroupToolbarItem } from '../../components/ChipGrou import { DataToolbarContentContext, DataToolbarContext } from './DataToolbarUtils'; import { PickOptional } from '../../helpers/typeUtils'; +export interface DataToolbarChipGroup { + /** A unique key to identify this chip group category */ + key: string; + /** The category name to display for the chip group */ + name: string; +} + export interface DataToolbarChip { /** A unique key to identify this chip */ key: string; @@ -16,11 +23,11 @@ export interface DataToolbarFilterProps extends DataToolbarItemProps { /** An array of strings to be displayed as chips in the expandable content */ chips?: (string | DataToolbarChip)[]; /** Callback passed by consumer used to delete a chip from the chips[] */ - deleteChip?: (category: string, chip: DataToolbarChip | string) => void; + deleteChip?: (category: string | DataToolbarChipGroup, chip: DataToolbarChip | string) => void; /** Content to be rendered inside the data toolbar item associated with the chip group */ children: React.ReactNode; /** Unique category name to be used as a label for the chip group */ - categoryName: string; + categoryName: string | DataToolbarChipGroup; /** Flag to show the toolbar item */ showToolbarItem?: boolean; } @@ -32,7 +39,7 @@ interface DataToolbarFilterState { export class DataToolbarFilter extends React.Component { static contextType: any = DataToolbarContext; static defaultProps: PickOptional = { - chips: [] as string[], + chips: [] as (string | DataToolbarChip)[], showToolbarItem: true }; @@ -44,12 +51,14 @@ export class DataToolbarFilter extends React.Component - + {chips.map(chip => typeof chip === 'string' ? ( deleteChip(categoryName, chip)}> diff --git a/packages/react-core/src/components/DataToolbar/__tests__/__snapshots__/DataToolbar.test.tsx.snap b/packages/react-core/src/components/DataToolbar/__tests__/__snapshots__/DataToolbar.test.tsx.snap index 4acda4e3df0..9cf9983e513 100644 --- a/packages/react-core/src/components/DataToolbar/__tests__/__snapshots__/DataToolbar.test.tsx.snap +++ b/packages/react-core/src/components/DataToolbar/__tests__/__snapshots__/DataToolbar.test.tsx.snap @@ -171,6 +171,7 @@ exports[`data toolbar DataToolbarFilter 1`] = ` isChecked={false} isDisabled={false} isFocused={false} + isNoResultsOption={false} isPlaceholder={false} isSelected={false} keyHandler={[Function]} @@ -185,6 +186,7 @@ exports[`data toolbar DataToolbarFilter 1`] = ` isChecked={false} isDisabled={false} isFocused={false} + isNoResultsOption={false} isPlaceholder={false} isSelected={false} keyHandler={[Function]} @@ -213,6 +215,7 @@ exports[`data toolbar DataToolbarFilter 1`] = ` createText="Create" customContent={null} direction="down" + hasInlineFilter={false} isCreatable={false} isDisabled={false} isExpanded={false} @@ -250,6 +253,7 @@ exports[`data toolbar DataToolbarFilter 1`] = ` ariaLabelledBy=" pf-toggle-id-4" className="" handleTypeaheadKeys={[Function]} + hasClearButton={false} id="pf-toggle-id-4" isActive={false} isDisabled={false} @@ -530,7 +534,12 @@ exports[`data toolbar DataToolbarFilter 1`] = ` > { - const drawerContent = - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate.'; - test(`Drawer isExpanded = ${isExpanded} and isInline = ${isInline}`, () => { - const view = mount( - - {drawerContent} - drawer-panel - - ); - expect(view).toMatchSnapshot(); - }); -}); diff --git a/packages/react-core/src/components/Drawer/Drawer.tsx b/packages/react-core/src/components/Drawer/Drawer.tsx index 4c02f0de64b..039d6eb213a 100644 --- a/packages/react-core/src/components/Drawer/Drawer.tsx +++ b/packages/react-core/src/components/Drawer/Drawer.tsx @@ -7,41 +7,46 @@ export interface DrawerProps extends React.HTMLProps { className?: string; /** Content rendered in the left hand panel */ children?: React.ReactNode; - /** Indicate if the drawer is expanded */ + /** Indicates if the drawer is expanded */ isExpanded?: boolean; /** Indicates if the content element and panel element are displayed side by side. */ isInline?: boolean; + /* Indicates if the drawer will always show both content and panel. */ + isStatic?: boolean; + /* Position of the drawer panel */ + position?: 'left' | 'right'; } -export class Drawer extends React.Component { - static hasWarnBeta = false; - constructor(props: DrawerProps) { - super(props); - } - - componentDidMount() { - if (!Drawer.hasWarnBeta && process.env.NODE_ENV !== 'production') { - // eslint-disable-next-line no-console - console.warn('This component is in beta and subject to change.'); - Drawer.hasWarnBeta = true; - } - } +export interface DrawerContextProps { + isExpanded: boolean; +} - render() { - const { className = '', children, isExpanded = false, isInline = false, ...props } = this.props; +export const DrawerContext = React.createContext>({ + isExpanded: false +}); - return ( -
      - {children} -
      - ); - } -} +export const Drawer: React.SFC = ({ + className = '', + children, + isExpanded = false, + isInline = false, + isStatic = false, + position = 'right', + ...props +}: DrawerProps) => ( + +
      + {children} +
      +
      +); diff --git a/packages/react-core/src/components/Drawer/DrawerActions.tsx b/packages/react-core/src/components/Drawer/DrawerActions.tsx new file mode 100644 index 00000000000..317067a4cd7 --- /dev/null +++ b/packages/react-core/src/components/Drawer/DrawerActions.tsx @@ -0,0 +1,21 @@ +import * as React from 'react'; +import styles from '@patternfly/react-styles/css/components/Drawer/drawer'; +import { css } from '@patternfly/react-styles'; + +export interface DrawerActionsProps extends React.HTMLProps { + /** Additional classes added to the drawer actions button. */ + className?: string; + /** Actions to be rendered in the panel head. */ + children?: React.ReactNode; +} + +export const DrawerActions: React.SFC = ({ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + className = '', + children, + ...props +}: DrawerActionsProps) => ( +
      + {children} +
      +); diff --git a/packages/react-core/src/components/Drawer/DrawerCloseButton.tsx b/packages/react-core/src/components/Drawer/DrawerCloseButton.tsx new file mode 100644 index 00000000000..6e45dead97f --- /dev/null +++ b/packages/react-core/src/components/Drawer/DrawerCloseButton.tsx @@ -0,0 +1,28 @@ +import * as React from 'react'; +import styles from '@patternfly/react-styles/css/components/Drawer/drawer'; +import { css } from '@patternfly/react-styles'; +import { Button } from '../Button'; +import TimesIcon from '@patternfly/react-icons/dist/js/icons/times-icon'; + +export interface DrawerCloseButtonProps extends React.HTMLProps { + /** Additional classes added to the drawer close button outer
      . */ + className?: string; + /** A callback for when the close button is clicked */ + onClose?: () => void; + /** Accessible label for the drawer close button */ + 'aria-label'?: string; +} + +export const DrawerCloseButton: React.SFC = ({ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + className = '', + onClose = () => undefined as any, + 'aria-label': ariaLabel = 'Close drawer panel', + ...props +}: DrawerCloseButtonProps) => ( +
      + +
      +); diff --git a/packages/react-core/src/components/Drawer/DrawerContent.tsx b/packages/react-core/src/components/Drawer/DrawerContent.tsx index 8276d67e41d..e62a64ee99f 100644 --- a/packages/react-core/src/components/Drawer/DrawerContent.tsx +++ b/packages/react-core/src/components/Drawer/DrawerContent.tsx @@ -1,21 +1,28 @@ import * as React from 'react'; import styles from '@patternfly/react-styles/css/components/Drawer/drawer'; import { css } from '@patternfly/react-styles'; +import { DrawerMain } from './DrawerMain'; export interface DrawerContentProps extends React.HTMLProps { /** Additional classes added to the Drawer. */ className?: string; - /** Content to rendered in the drawer */ + /** Content to be rendered in the drawer. */ children?: React.ReactNode; + /** Content rendered in the drawer panel. */ + panelContent: React.ReactNode; } export const DrawerContent: React.SFC = ({ // eslint-disable-next-line @typescript-eslint/no-unused-vars className = '', children, + panelContent, ...props }: DrawerContentProps) => ( -
      - {children} -
      + +
      + {children} +
      + {panelContent} +
      ); diff --git a/packages/react-core/src/components/Drawer/DrawerContentBody.tsx b/packages/react-core/src/components/Drawer/DrawerContentBody.tsx new file mode 100644 index 00000000000..068d190feea --- /dev/null +++ b/packages/react-core/src/components/Drawer/DrawerContentBody.tsx @@ -0,0 +1,24 @@ +import * as React from 'react'; +import styles from '@patternfly/react-styles/css/components/Drawer/drawer'; +import { css } from '@patternfly/react-styles'; + +export interface DrawerContentBodyProps extends React.HTMLProps { + /** Additional classes added to the Drawer. */ + className?: string; + /** Content to be rendered in the drawer */ + children?: React.ReactNode; + /** Indicates if there should be padding around the drawer content body */ + hasPadding?: boolean; +} + +export const DrawerContentBody: React.SFC = ({ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + className = '', + children, + hasPadding = false, + ...props +}: DrawerContentBodyProps) => ( +
      + {children} +
      +); diff --git a/packages/react-core/src/components/Drawer/DrawerHead.tsx b/packages/react-core/src/components/Drawer/DrawerHead.tsx new file mode 100644 index 00000000000..c3e26c497b3 --- /dev/null +++ b/packages/react-core/src/components/Drawer/DrawerHead.tsx @@ -0,0 +1,27 @@ +import * as React from 'react'; +import styles from '@patternfly/react-styles/css/components/Drawer/drawer'; +import { css } from '@patternfly/react-styles'; +import { DrawerPanelBody } from './DrawerPanelBody'; + +export interface DrawerHeadProps extends React.HTMLProps { + /** Additional classes added to the drawer head. */ + className?: string; + /** Content to be rendered in the drawer head */ + children?: React.ReactNode; + /** Indicates if there should be no padding around the drawer panel body of the head*/ + noPadding?: boolean; +} + +export const DrawerHead: React.SFC = ({ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + className = '', + children, + noPadding = false, + ...props +}: DrawerHeadProps) => ( + +
      + {children} +
      +
      +); diff --git a/packages/react-core/src/components/Drawer/DrawerMain.tsx b/packages/react-core/src/components/Drawer/DrawerMain.tsx new file mode 100644 index 00000000000..a30eae98fed --- /dev/null +++ b/packages/react-core/src/components/Drawer/DrawerMain.tsx @@ -0,0 +1,21 @@ +import * as React from 'react'; +import styles from '@patternfly/react-styles/css/components/Drawer/drawer'; +import { css } from '@patternfly/react-styles'; + +export interface DrawerMainProps extends React.HTMLProps { + /** Additional classes added to the drawer main wrapper. */ + className?: string; + /** Content to be rendered in the drawer main wrapper*/ + children?: React.ReactNode; +} + +export const DrawerMain: React.SFC = ({ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + className = '', + children, + ...props +}: DrawerMainProps) => ( +
      + {children} +
      +); diff --git a/packages/react-core/src/components/Drawer/DrawerPanelBody.tsx b/packages/react-core/src/components/Drawer/DrawerPanelBody.tsx new file mode 100644 index 00000000000..ec546f3fe39 --- /dev/null +++ b/packages/react-core/src/components/Drawer/DrawerPanelBody.tsx @@ -0,0 +1,24 @@ +import * as React from 'react'; +import styles from '@patternfly/react-styles/css/components/Drawer/drawer'; +import { css } from '@patternfly/react-styles'; + +export interface DrawerPanelBodyProps extends React.HTMLProps { + /** Additional classes added to the Drawer. */ + className?: string; + /** Content to be rendered in the drawer */ + children?: React.ReactNode; + /** Indicates if there should be no padding around the drawer panel body */ + noPadding?: boolean; +} + +export const DrawerPanelBody: React.SFC = ({ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + className = '', + children, + noPadding = false, + ...props +}: DrawerPanelBodyProps) => ( +
      + {children} +
      +); diff --git a/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx b/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx index 8c94360bc6d..ebda8029459 100644 --- a/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx +++ b/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx @@ -1,23 +1,34 @@ import * as React from 'react'; import styles from '@patternfly/react-styles/css/components/Drawer/drawer'; import { css } from '@patternfly/react-styles'; +import { DrawerContext } from './Drawer'; export interface DrawerPanelContentProps extends React.HTMLProps { - /** Additional classes added to the Drawer. */ + /** Additional classes added to the drawer. */ className?: string; - /** Content to rendered in the drawer */ + /** Content to be rendered in the drawer panel. */ children?: React.ReactNode; - /** Indicates if there should be padding around the drawer */ - noPadding?: boolean; + /* Flag indicating that the drawer panel should have a border. */ + hasBorder?: boolean; } export const DrawerPanelContent: React.SFC = ({ className = '', children, - noPadding = false, + hasBorder = false, ...props }: DrawerPanelContentProps) => ( - + + {({ isExpanded }) => ( + + )} + ); diff --git a/packages/react-core/src/components/Drawer/DrawerSection.tsx b/packages/react-core/src/components/Drawer/DrawerSection.tsx new file mode 100644 index 00000000000..68b36e9cc7c --- /dev/null +++ b/packages/react-core/src/components/Drawer/DrawerSection.tsx @@ -0,0 +1,21 @@ +import * as React from 'react'; +import styles from '@patternfly/react-styles/css/components/Drawer/drawer'; +import { css } from '@patternfly/react-styles'; + +export interface DrawerSectionProps extends React.HTMLProps { + /** Additional classes added to the drawer section. */ + className?: string; + /** Content to be rendered in the drawer section. */ + children?: React.ReactNode; +} + +export const DrawerSection: React.SFC = ({ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + className = '', + children, + ...props +}: DrawerSectionProps) => ( +
      + {children} +
      +); diff --git a/packages/react-core/src/components/Drawer/__snapshots__/Drawer.test.tsx.snap b/packages/react-core/src/components/Drawer/__snapshots__/Drawer.test.tsx.snap deleted file mode 100644 index 9d85498007b..00000000000 --- a/packages/react-core/src/components/Drawer/__snapshots__/Drawer.test.tsx.snap +++ /dev/null @@ -1,121 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Drawer isExpanded = false and isInline = false 1`] = ` - -
      - -
      - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate. -
      -
      - - - -
      -
      -`; - -exports[`Drawer isExpanded = false and isInline = true 1`] = ` - -
      - -
      - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate. -
      -
      - - - -
      -
      -`; - -exports[`Drawer isExpanded = true and isInline = false 1`] = ` - -
      - -
      - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate. -
      -
      - - - -
      -
      -`; - -exports[`Drawer isExpanded = true and isInline = true 1`] = ` - -
      - -
      - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate. -
      -
      - - - -
      -
      -`; diff --git a/packages/react-core/src/components/Drawer/__tests__/Drawer.test.tsx b/packages/react-core/src/components/Drawer/__tests__/Drawer.test.tsx index e72d45a1df8..a9d67556be5 100644 --- a/packages/react-core/src/components/Drawer/__tests__/Drawer.test.tsx +++ b/packages/react-core/src/components/Drawer/__tests__/Drawer.test.tsx @@ -1,22 +1,33 @@ -import { Drawer, DrawerPanelContent, DrawerContent } from '../'; +import { Drawer, DrawerPanelContent, DrawerContent, DrawerHead, DrawerActions, DrawerCloseButton, DrawerContentBody, DrawerPanelBody} from '../'; import React from 'react'; import { mount } from 'enzyme'; Object.values([ - { isExpanded: true, isInline: false }, - { isExpanded: false, isInline: false }, - { isExpanded: true, isInline: true }, - { isExpanded: false, isInline: true } -]).forEach(({ isExpanded, isInline }) => { - const drawerContent = + { isExpanded: true, isInline: false, isStatic:false }, + { isExpanded: false, isInline: false, isStatic:false }, + { isExpanded: true, isInline: true, isStatic:false }, + { isExpanded: false, isInline: true, isStatic:false }, + { isExpanded: true, isInline: false, isStatic:true} +]).forEach(({ isExpanded, isInline, isStatic }) => { + const panelContent = ( + + + drawer-panel + + + + + drawer-panel + ); + const drawerContent = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate.'; - test(`Drawer isExpanded = ${isExpanded} and isInline = ${isInline}`, () => { + test(`Drawer isExpanded = ${isExpanded} and isInline = ${isInline} and isStatic = ${isStatic}`, () => { const view = mount( - - {drawerContent} - drawer-panel - - ); + + + {drawerContent} + + ); expect(view).toMatchSnapshot(); }); }); diff --git a/packages/react-core/src/components/Drawer/__tests__/Generated/__snapshots__/Drawer.test.tsx.snap b/packages/react-core/src/components/Drawer/__tests__/Generated/__snapshots__/Drawer.test.tsx.snap index 63039c95cff..ab2f9badd87 100644 --- a/packages/react-core/src/components/Drawer/__tests__/Generated/__snapshots__/Drawer.test.tsx.snap +++ b/packages/react-core/src/components/Drawer/__tests__/Generated/__snapshots__/Drawer.test.tsx.snap @@ -1,11 +1,19 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Drawer should match snapshot (auto-generated) 1`] = ` -
      -
      - ReactNode +
      +
      + ReactNode +
      -
      + `; diff --git a/packages/react-core/src/components/Drawer/__tests__/Generated/__snapshots__/DrawerContent.test.tsx.snap b/packages/react-core/src/components/Drawer/__tests__/Generated/__snapshots__/DrawerContent.test.tsx.snap index 4ffdb1b6774..a6e69b88182 100644 --- a/packages/react-core/src/components/Drawer/__tests__/Generated/__snapshots__/DrawerContent.test.tsx.snap +++ b/packages/react-core/src/components/Drawer/__tests__/Generated/__snapshots__/DrawerContent.test.tsx.snap @@ -1,11 +1,13 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`DrawerContent should match snapshot (auto-generated) 1`] = ` -
      -
      - ReactNode + +
      +
      + ReactNode +
      -
      + `; diff --git a/packages/react-core/src/components/Drawer/__tests__/Generated/__snapshots__/DrawerPanelContent.test.tsx.snap b/packages/react-core/src/components/Drawer/__tests__/Generated/__snapshots__/DrawerPanelContent.test.tsx.snap index c9e64cd125d..af9714ac9d9 100644 --- a/packages/react-core/src/components/Drawer/__tests__/Generated/__snapshots__/DrawerPanelContent.test.tsx.snap +++ b/packages/react-core/src/components/Drawer/__tests__/Generated/__snapshots__/DrawerPanelContent.test.tsx.snap @@ -1,15 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`DrawerPanelContent should match snapshot (auto-generated) 1`] = ` - + + + `; diff --git a/packages/react-core/src/components/Drawer/__tests__/__snapshots__/Drawer.test.tsx.snap b/packages/react-core/src/components/Drawer/__tests__/__snapshots__/Drawer.test.tsx.snap index 9d85498007b..ee4d69b1754 100644 --- a/packages/react-core/src/components/Drawer/__tests__/__snapshots__/Drawer.test.tsx.snap +++ b/packages/react-core/src/components/Drawer/__tests__/__snapshots__/Drawer.test.tsx.snap @@ -1,121 +1,816 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Drawer isExpanded = false and isInline = false 1`] = ` +exports[`Drawer isExpanded = false and isInline = false and isStatic = false 1`] = `
      - -
      - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate. -
      -
      - - - + +
      `; -exports[`Drawer isExpanded = false and isInline = true 1`] = ` +exports[`Drawer isExpanded = false and isInline = true and isStatic = false 1`] = `
      - -
      - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate. -
      -
      - - - + +
      `; -exports[`Drawer isExpanded = true and isInline = false 1`] = ` +exports[`Drawer isExpanded = true and isInline = false and isStatic = false 1`] = `
      - -
      - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate. -
      -
      - - - + +
      `; -exports[`Drawer isExpanded = true and isInline = true 1`] = ` +exports[`Drawer isExpanded = true and isInline = false and isStatic = true 1`] = `
      - -
      - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate. -
      + + + + drawer-panel + + + + + + + drawer-panel + + + } + > + +
      +
      + +
      + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate. +
      +
      +
      + + + +
      +
      - -
      +
      +`; + +exports[`Drawer isExpanded = true and isInline = true and isStatic = false 1`] = ` + +
      + + + + drawer-panel + + + + + + + drawer-panel + + + } + > +
      - drawer-panel +
      + +
      + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate. +
      +
      +
      + + +
      - - +
      +
      `; diff --git a/packages/react-core/src/components/Drawer/examples/Drawer.md b/packages/react-core/src/components/Drawer/examples/Drawer.md index 9e563288abe..778af888492 100644 --- a/packages/react-core/src/components/Drawer/examples/Drawer.md +++ b/packages/react-core/src/components/Drawer/examples/Drawer.md @@ -2,18 +2,16 @@ title: 'Drawer' cssPrefix: 'pf-c-drawer' typescript: true -propComponents: ['Drawer', 'DrawerPanelContent', 'DrawerContent'] +propComponents: ['Drawer', 'DrawerContent', 'DrawerPanelContent', DrawerContentBody, DrawerPanelBody, DrawerSection, DrawerHead, DrawerActions, DrawerCloseButton] section: 'components' beta: true --- -import { Drawer, DrawerPanelContent, DrawerContent } from '@patternfly/react-core'; -import { Alert } from '@patternfly/react-core'; +import { Drawer, DrawerPanelContent, DrawerContent, DrawerContentBody, DrawerPanelBody, DrawerSection, DrawerHead, DrawerActions, DrawerCloseButton } from '@patternfly/react-core'; ## Examples ```js title=Basic import React, { ReactFragment } from 'react'; -import { Drawer, DrawerPanelContent, DrawerContent } from '@patternfly/react-core'; -import { Button } from '@patternfly/react-core'; +import { Drawer, DrawerPanelContent, DrawerContent, DrawerContentBody, DrawerPanelBody, DrawerHead, DrawerActions, DrawerCloseButton, Button } from '@patternfly/react-core'; class SimpleDrawer extends React.Component { @@ -29,18 +27,86 @@ class SimpleDrawer extends React.Component { isExpanded }); }; + + this.onCloseClick = () => { + this.setState({ + isExpanded: false + }); + }; } render() { const { isExpanded } = this.state; + const panelContent = ( + + + drawer-panel + + + + + ); const drawerContent = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate."; return ( - {drawerContent} - drawer-panel + + {drawerContent} + + + ); + } +} +``` + +```js title=Panel-on-left +import React, { ReactFragment } from 'react'; +import { Drawer, DrawerPanelContent, DrawerContent, DrawerContentBody, DrawerPanelBody, DrawerHead, DrawerActions, DrawerCloseButton, Button } from '@patternfly/react-core'; + +class SimpleDrawerPanelLeft extends React.Component { + + constructor(props) { + super(props); + this.state = { + isExpanded: false + }; + + this.onClick = () => { + const isExpanded = !this.state.isExpanded; + this.setState({ + isExpanded + }); + }; + + this.onCloseClick = () => { + this.setState({ + isExpanded: false + }); + }; + } + + render() { + const { isExpanded } = this.state; + const panelContent = ( + + + drawer-panel + + + + + ); + + const drawerContent = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate."; + + return ( + + + + {drawerContent} + ); } @@ -49,8 +115,7 @@ class SimpleDrawer extends React.Component { ```js title=Basic-inline import React, { ReactFragment } from 'react'; -import { Drawer, DrawerPanelContent, DrawerContent } from '@patternfly/react-core'; -import { Button } from '@patternfly/react-core'; +import { Drawer, DrawerPanelContent, DrawerContent, DrawerContentBody, DrawerPanelBody, DrawerHead, DrawerActions, DrawerCloseButton, Button } from '@patternfly/react-core'; class SimpleDrawerInlineContent extends React.Component { @@ -66,20 +131,378 @@ class SimpleDrawerInlineContent extends React.Component { isExpanded }); }; + + this.onCloseClick = () => { + this.setState({ + isExpanded: false + }); + }; } render() { const { isExpanded } = this.state; + const panelContent = ( + + + drawer-panel + + + + + ); const drawerContent = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate."; return ( - {drawerContent} - drawer-panel + + {drawerContent} + + + ); + } +} +``` + +```js title=-Inline-panel-on-left +import React, { ReactFragment } from 'react'; +import { Drawer, DrawerPanelContent, DrawerContent, DrawerContentBody, DrawerPanelBody, DrawerHead, DrawerActions, DrawerCloseButton, Button } from '@patternfly/react-core'; + +class DrawerInlineContentPanelLeft extends React.Component { + + constructor(props) { + super(props); + this.state = { + isExpanded: false + }; + + this.onClick = () => { + const isExpanded = !this.state.isExpanded; + this.setState({ + isExpanded + }); + }; + + this.onCloseClick = () => { + this.setState({ + isExpanded: false + }); + }; + } + + render() { + const { isExpanded } = this.state; + const panelContent = ( + + + drawer-panel + + + + + ); + + const drawerContent = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate."; + + return ( + + + + {drawerContent} + + + ); + } +} +``` + +```js title=Stacked-content-body-elements +import React, { ReactFragment } from 'react'; +import { Drawer, DrawerPanelContent, DrawerContent, DrawerContentBody, DrawerPanelBody, DrawerHead, DrawerActions, DrawerCloseButton, Button } from '@patternfly/react-core'; + +class DrawerStackedContentBodyElements extends React.Component { + + constructor(props) { + super(props); + this.state = { + isExpanded: false + }; + + this.onClick = () => { + const isExpanded = !this.state.isExpanded; + this.setState({ + isExpanded + }); + }; + + this.onCloseClick = () => { + this.setState({ + isExpanded: false + }); + }; + } + + render() { + const { isExpanded } = this.state; + const panelContent = ( + + + + + + drawer-panel + + drawer-panel with no padding + drawer-panel + ); + + return ( + + + + content-body + content-body with padding + content-body + ); } } ``` + +```js title=Modified-content-padding +import React, { ReactFragment } from 'react'; +import { Drawer, DrawerPanelContent, DrawerContent, DrawerContentBody, DrawerPanelBody, DrawerHead, DrawerActions, DrawerCloseButton, Button } from '@patternfly/react-core'; + +class DrawerModifiedContentPadding extends React.Component { + + constructor(props) { + super(props); + this.state = { + isExpanded: false + }; + + this.onClick = () => { + const isExpanded = !this.state.isExpanded; + this.setState({ + isExpanded + }); + }; + + this.onCloseClick = () => { + this.setState({ + isExpanded: false + }); + }; + } + + render() { + const { isExpanded } = this.state; + const panelContent = ( + + + drawer-panel + + + + + ); + + const drawerContent = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate."; + + return ( + + + + Drawer content padding. {drawerContent} + + + ); + } +} +``` + +```js title=Modified-panel-padding +import React, { ReactFragment } from 'react'; +import { Drawer, DrawerPanelContent, DrawerContent, DrawerContentBody, DrawerPanelBody, DrawerHead, DrawerActions, DrawerCloseButton, Button } from '@patternfly/react-core'; + +class DrawerModifiedPanelPadding extends React.Component { + + constructor(props) { + super(props); + this.state = { + isExpanded: false + }; + + this.onClick = () => { + const isExpanded = !this.state.isExpanded; + this.setState({ + isExpanded + }); + }; + + this.onCloseClick = () => { + this.setState({ + isExpanded: false + }); + }; + } + + render() { + const { isExpanded } = this.state; + const panelContent = ( + + + drawer-panel + + + + + ); + + const drawerContent = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate."; + + return ( + + + + {drawerContent} + + + ); + } +} +``` + +```js title=Modified-panel-border +import React, { ReactFragment } from 'react'; +import { Drawer, DrawerPanelContent, DrawerContent, DrawerContentBody, DrawerPanelBody, DrawerHead, DrawerActions, DrawerCloseButton, Button } from '@patternfly/react-core'; + +class DrawerPanelBorder extends React.Component { + + constructor(props) { + super(props); + this.state = { + isExpanded: false + }; + + this.onClick = () => { + const isExpanded = !this.state.isExpanded; + this.setState({ + isExpanded + }); + }; + + this.onCloseClick = () => { + this.setState({ + isExpanded: false + }); + }; + } + + render() { + const { isExpanded } = this.state; + const panelContent = ( + + + drawer-panel + + + + + ); + + const drawerContent = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate."; + + return ( + + + + {drawerContent} + + + ); + } +} +``` + +```js title=Additional-section-above-drawer-content +import React, { ReactFragment } from 'react'; +import { Drawer, DrawerPanelContent, DrawerContent, DrawerContentBody, DrawerPanelBody, DrawerHead, DrawerActions, DrawerCloseButton, DrawerSection, Button } from '@patternfly/react-core'; + +class DrawerWithSection extends React.Component { + + constructor(props) { + super(props); + this.state = { + isExpanded: false + }; + + this.onClick = () => { + const isExpanded = !this.state.isExpanded; + this.setState({ + isExpanded + }); + }; + + this.onCloseClick = () => { + this.setState({ + isExpanded: false + }); + }; + } + + render() { + const { isExpanded } = this.state; + const panelContent = ( + + + drawer-panel + + + + + ); + + const drawerContent = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate."; + + return ( + + + drawer-section + + {drawerContent} + + + ); + } +} +``` + +```js title=Static-drawer +import React, { ReactFragment } from 'react'; +import { Drawer, DrawerPanelContent, DrawerContent, DrawerContentBody, DrawerPanelBody, DrawerHead, DrawerActions, DrawerCloseButton } from '@patternfly/react-core'; + +StaticDrawer = () => { + const panelContent = ( + + + drawer-panel + + + + + ); + + const drawerContent = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate."; + + return ( + + + {drawerContent} + + + ); +} +``` \ No newline at end of file diff --git a/packages/react-core/src/components/Drawer/index.ts b/packages/react-core/src/components/Drawer/index.ts index 3fa991117da..75a59456ac8 100644 --- a/packages/react-core/src/components/Drawer/index.ts +++ b/packages/react-core/src/components/Drawer/index.ts @@ -1,3 +1,9 @@ export * from './Drawer'; -export * from './DrawerPanelContent'; +export * from './DrawerActions'; +export * from './DrawerCloseButton'; export * from './DrawerContent'; +export * from './DrawerContentBody'; +export * from './DrawerHead'; +export * from './DrawerPanelBody'; +export * from './DrawerPanelContent'; +export * from './DrawerSection'; diff --git a/packages/react-core/src/components/Dropdown/DropdownWithContext.tsx b/packages/react-core/src/components/Dropdown/DropdownWithContext.tsx index 910ab727433..75412344590 100644 --- a/packages/react-core/src/components/Dropdown/DropdownWithContext.tsx +++ b/packages/react-core/src/components/Dropdown/DropdownWithContext.tsx @@ -30,8 +30,9 @@ class DropdownWithContext extends React.Component 0 && props.children) { - throw new Error( - 'Children and dropdownItems props have been provided. Only the dropdownItems prop items will be rendered ' + // eslint-disable-next-line no-console + console.error( + 'Children and dropdownItems props have been provided. Only the dropdownItems prop items will be rendered' ); } } diff --git a/packages/react-core/src/components/Dropdown/Toggle.tsx b/packages/react-core/src/components/Dropdown/Toggle.tsx index e79a4da8818..5d3ed3a741e 100644 --- a/packages/react-core/src/components/Dropdown/Toggle.tsx +++ b/packages/react-core/src/components/Dropdown/Toggle.tsx @@ -138,6 +138,8 @@ export class Toggle extends React.Component { parentRef, id, type, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + bubbleEvent, ...props } = this.props; return ( diff --git a/packages/react-core/src/components/Dropdown/__tests__/Dropdown.test.tsx b/packages/react-core/src/components/Dropdown/__tests__/Dropdown.test.tsx index 96ca14e9523..dfbb4eceb24 100644 --- a/packages/react-core/src/components/Dropdown/__tests__/Dropdown.test.tsx +++ b/packages/react-core/src/components/Dropdown/__tests__/Dropdown.test.tsx @@ -185,7 +185,8 @@ describe('API', () => { }); test('dropdownItems and children console error ', () => { - expect(() => + const myMock = jest.fn(); + global.console = { error: myMock } as any; mount( {
      Children items
      ) - ).toThrowError(); + expect(myMock).toBeCalledWith('Children and dropdownItems props have been provided. Only the dropdownItems prop items will be rendered'); }); test('dropdownItems only, no console error ', () => { diff --git a/packages/react-core/src/components/Dropdown/__tests__/__snapshots__/Dropdown.test.tsx.snap b/packages/react-core/src/components/Dropdown/__tests__/__snapshots__/Dropdown.test.tsx.snap index aec92979b2e..b525f18c575 100644 --- a/packages/react-core/src/components/Dropdown/__tests__/__snapshots__/Dropdown.test.tsx.snap +++ b/packages/react-core/src/components/Dropdown/__tests__/__snapshots__/Dropdown.test.tsx.snap @@ -163,7 +163,6 @@ exports[`KebabToggle basic 1`] = ` aria-expanded={true} aria-haspopup={false} aria-label="Actions" - bubbleEvent={false} className="pf-c-dropdown__toggle" disabled={false} id="Dropdown Toggle" @@ -899,7 +898,6 @@ exports[`KebabToggle dropup + right aligned 1`] = ` aria-expanded={false} aria-haspopup={true} aria-label="Actions" - bubbleEvent={false} className="pf-c-dropdown__toggle" disabled={false} id="Dropdown Toggle" @@ -1610,7 +1608,6 @@ exports[`KebabToggle dropup 1`] = ` aria-expanded={false} aria-haspopup={true} aria-label="Actions" - bubbleEvent={false} className="pf-c-dropdown__toggle" disabled={false} id="Dropdown Toggle" @@ -2471,7 +2468,6 @@ exports[`KebabToggle expanded 1`] = ` aria-expanded={true} aria-haspopup={true} aria-label="Actions" - bubbleEvent={false} className="pf-c-dropdown__toggle" disabled={false} id="Dropdown Toggle" @@ -3451,7 +3447,6 @@ exports[`KebabToggle plain 1`] = ` aria-expanded={false} aria-haspopup={true} aria-label="Actions" - bubbleEvent={false} className="pf-c-dropdown__toggle pf-m-plain" disabled={false} id="Dropdown Toggle" @@ -4159,7 +4154,6 @@ exports[`KebabToggle regular 1`] = ` aria-expanded={false} aria-haspopup={true} aria-label="Actions" - bubbleEvent={false} className="pf-c-dropdown__toggle" disabled={false} id="Dropdown Toggle" @@ -4870,7 +4864,6 @@ exports[`KebabToggle right aligned 1`] = ` aria-expanded={false} aria-haspopup={true} aria-label="Actions" - bubbleEvent={false} className="pf-c-dropdown__toggle" disabled={false} id="Dropdown Toggle" @@ -5093,7 +5086,6 @@ exports[`dropdown basic 1`] = ` + + +
      +
      + {!hideDefaultPreview && type === fileReaderType.text && ( +