diff --git a/packages/react/src/components/DataTable/TableActionList.js b/packages/react/src/components/DataTable/TableActionList.js index 52e523099182..ed3f970615f2 100644 --- a/packages/react/src/components/DataTable/TableActionList.js +++ b/packages/react/src/components/DataTable/TableActionList.js @@ -10,7 +10,7 @@ import wrapComponent from '../../tools/wrapComponent'; const TableActionList = wrapComponent({ name: 'TableActionList', type: 'div', - className: `cds--action-list`, + className: (prefix) => `${prefix}--action-list`, }); export default TableActionList; diff --git a/packages/react/src/components/DataTable/TableToolbarContent.js b/packages/react/src/components/DataTable/TableToolbarContent.js index de75daf7371a..1994ce2d9c18 100644 --- a/packages/react/src/components/DataTable/TableToolbarContent.js +++ b/packages/react/src/components/DataTable/TableToolbarContent.js @@ -10,7 +10,7 @@ import wrapComponent from '../../tools/wrapComponent'; const TableToolbarContent = wrapComponent({ name: 'TableToolbarContent', type: 'div', - className: `cds--toolbar-content`, + className: (prefix) => `${prefix}--toolbar-content`, }); export default TableToolbarContent; diff --git a/packages/react/src/components/UIShell/HeaderGlobalBar.js b/packages/react/src/components/UIShell/HeaderGlobalBar.js index 74f149ef08d2..7464b97e7f98 100644 --- a/packages/react/src/components/UIShell/HeaderGlobalBar.js +++ b/packages/react/src/components/UIShell/HeaderGlobalBar.js @@ -12,6 +12,6 @@ import wrapComponent from '../../tools/wrapComponent'; */ export default wrapComponent({ name: 'HeaderGlobalBar', - className: `cds--header__global`, + className: (prefix) => `${prefix}--header__global`, type: 'div', }); diff --git a/packages/react/src/tools/__tests__/wrapComponent-test.js b/packages/react/src/tools/__tests__/wrapComponent-test.js new file mode 100644 index 000000000000..db78f7253c06 --- /dev/null +++ b/packages/react/src/tools/__tests__/wrapComponent-test.js @@ -0,0 +1,58 @@ +/** + * Copyright IBM Corp. 2016, 2018 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { render } from '@testing-library/react'; +import React from 'react'; +import wrapComponent from '../wrapComponent'; + +describe('wrapComponent', () => { + it('should render the outermost element as the given type', () => { + const WrappedComponent = wrapComponent({ + name: 'WrappedComponent', + type: 'div', + }); + const { container } = render(); + expect(container.firstChild.tagName).toBe('DIV'); + }); + + it('should set the `displayName` for a component', () => { + const WrappedComponent = wrapComponent({ + name: 'WrappedComponent', + type: 'div', + }); + expect(WrappedComponent.displayName).toBe('WrappedComponent'); + }); + + it('should support static class names with `className`', () => { + const WrappedComponent = wrapComponent({ + name: 'WrappedComponent', + type: 'div', + className: 'test', + }); + const { container } = render(); + expect(container.firstChild).toHaveClass('test'); + }); + + it('should support prefix class names with `className`', () => { + const WrappedComponent = wrapComponent({ + name: 'WrappedComponent', + type: 'div', + className: (prefix) => `${prefix}--test`, + }); + const { container } = render(); + expect(container.firstChild).toHaveClass('cds--test'); + }); + + it('should spread additional props on the outermost node', () => { + const WrappedComponent = wrapComponent({ + name: 'WrappedComponent', + type: 'div', + }); + const { container } = render(); + expect(container.firstChild).toHaveAttribute('data-testid', 'test'); + }); +}); diff --git a/packages/react/src/tools/wrapComponent.js b/packages/react/src/tools/wrapComponent.js index 42253c69ceb5..a9c427571e8c 100644 --- a/packages/react/src/tools/wrapComponent.js +++ b/packages/react/src/tools/wrapComponent.js @@ -8,10 +8,16 @@ import React from 'react'; import PropTypes from 'prop-types'; import cx from 'classnames'; +import { usePrefix } from '../internal/usePrefix'; + +const wrapComponent = ({ name, className: getClassName, type }) => { + function Component({ className: baseClassName, ...other }) { + const prefix = usePrefix(); + const componentClass = cx( + typeof getClassName === 'function' ? getClassName(prefix) : getClassName, + baseClassName + ); -const wrapComponent = ({ name, className, type }) => { - const Component = ({ className: baseClassName, ...other }) => { - const componentClass = cx(className, baseClassName); return React.createElement(type, { ...other, // Prevent Weird quirk where `cx` will evaluate to an empty string, '', @@ -19,11 +25,13 @@ const wrapComponent = ({ name, className, type }) => { // eslint-disable-next-line no-extra-boolean-cast className: !!componentClass ? componentClass : undefined, }); - }; + } + Component.displayName = name; Component.propTypes = { className: PropTypes.string, }; + return Component; };