From a972a719cb736818a9d2b13a4536b2720c567337 Mon Sep 17 00:00:00 2001 From: Jan Hassel Date: Thu, 3 Dec 2020 15:58:46 +0100 Subject: [PATCH 1/5] fix(checkbox): correct line-height (#7373) Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- packages/components/src/components/checkbox/_checkbox.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/src/components/checkbox/_checkbox.scss b/packages/components/src/components/checkbox/_checkbox.scss index f00a6c2e870f..2430c6e1b4c6 100644 --- a/packages/components/src/components/checkbox/_checkbox.scss +++ b/packages/components/src/components/checkbox/_checkbox.scss @@ -53,8 +53,8 @@ position: relative; display: flex; min-height: rem(24px); + padding-top: rem(3px); padding-left: rem(20px); - line-height: 1.5rem; cursor: pointer; user-select: none; } From 0797f3112f8a97636d05d81a3457482884364528 Mon Sep 17 00:00:00 2001 From: carbon-bot Date: Thu, 3 Dec 2020 15:19:01 +0000 Subject: [PATCH 2/5] chore(project): sync generated files --- packages/components/docs/sass.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/docs/sass.md b/packages/components/docs/sass.md index 4a65cf4efb6b..a1160602d77c 100644 --- a/packages/components/docs/sass.md +++ b/packages/components/docs/sass.md @@ -14710,8 +14710,8 @@ Checkbox styles position: relative; display: flex; min-height: rem(24px); + padding-top: rem(3px); padding-left: rem(20px); - line-height: 1.5rem; cursor: pointer; user-select: none; } From cbcba120b7099adc5f1b673b948ef94fe8cc3f57 Mon Sep 17 00:00:00 2001 From: Josh Black Date: Thu, 3 Dec 2020 10:45:37 -0600 Subject: [PATCH 3/5] Add ref support to Breadcrumb (#7375) * feat(breadcrumb-item): add ref support for BreadcrumbItem * feat(breadcrumb): add ref support for Breadcrumb Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../__snapshots__/PublicAPI-test.js.snap | 6 +++++ .../src/components/Breadcrumb/Breadcrumb.js | 21 +++++++++------ .../components/Breadcrumb/BreadcrumbItem.js | 27 +++++++++++-------- .../Breadcrumb/__tests__/Breadcrumb-test.js | 20 ++++++++++++++ .../__tests__/BreadcrumbItem-test.js | 27 +++++++++++++++++++ 5 files changed, 82 insertions(+), 19 deletions(-) create mode 100644 packages/react/src/components/Breadcrumb/__tests__/BreadcrumbItem-test.js diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap index d80686786d6e..98eddd305ec2 100644 --- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap +++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap @@ -93,6 +93,8 @@ Map { }, }, "Breadcrumb" => Object { + "$$typeof": Symbol(react.forward_ref), + "displayName": "Breadcrumb", "propTypes": Object { "aria-label": Object { "type": "string", @@ -107,8 +109,11 @@ Map { "type": "bool", }, }, + "render": [Function], }, "BreadcrumbItem" => Object { + "$$typeof": Symbol(react.forward_ref), + "displayName": "BreadcrumbItem", "propTypes": Object { "aria-current": Object { "args": Array [ @@ -136,6 +141,7 @@ Map { "type": "bool", }, }, + "render": [Function], }, "Button" => Object { "$$typeof": Symbol(react.forward_ref), diff --git a/packages/react/src/components/Breadcrumb/Breadcrumb.js b/packages/react/src/components/Breadcrumb/Breadcrumb.js index b45948271b69..526823d67d3e 100644 --- a/packages/react/src/components/Breadcrumb/Breadcrumb.js +++ b/packages/react/src/components/Breadcrumb/Breadcrumb.js @@ -12,13 +12,16 @@ import { settings } from 'carbon-components'; const { prefix } = settings; -const Breadcrumb = ({ - 'aria-label': ariaLabel, - children, - className: customClassNameNav, - noTrailingSlash, - ...rest -}) => { +const Breadcrumb = React.forwardRef(function Breadcrumb( + { + 'aria-label': ariaLabel, + children, + className: customClassNameNav, + noTrailingSlash, + ...rest + }, + ref +) { const className = cx({ [`${prefix}--breadcrumb`]: true, [`${prefix}--breadcrumb--no-trailing-slash`]: noTrailingSlash, @@ -28,12 +31,14 @@ const Breadcrumb = ({ ); -}; +}); +Breadcrumb.displayName = 'Breadcrumb'; Breadcrumb.propTypes = { /** * Specify the label for the breadcrumb container diff --git a/packages/react/src/components/Breadcrumb/BreadcrumbItem.js b/packages/react/src/components/Breadcrumb/BreadcrumbItem.js index 3c01f1a22813..ce9e0c574f4f 100644 --- a/packages/react/src/components/Breadcrumb/BreadcrumbItem.js +++ b/packages/react/src/components/Breadcrumb/BreadcrumbItem.js @@ -13,14 +13,17 @@ import Link from '../Link'; const { prefix } = settings; -const BreadcrumbItem = ({ - 'aria-current': ariaCurrent, - children, - className: customClassName, - href, - isCurrentPage, - ...rest -}) => { +const BreadcrumbItem = React.forwardRef(function BreadcrumbItem( + { + 'aria-current': ariaCurrent, + children, + className: customClassName, + href, + isCurrentPage, + ...rest + }, + ref +) { const className = cx({ [`${prefix}--breadcrumb-item`]: true, // We set the current class only if `isCurrentPage` is passed in and we do @@ -32,7 +35,7 @@ const BreadcrumbItem = ({ if (typeof children === 'string' && href) { return ( -
  • +
  • {children} @@ -41,14 +44,16 @@ const BreadcrumbItem = ({ } return ( -
  • +
  • {React.cloneElement(children, { 'aria-current': ariaCurrent, className: `${prefix}--link`, })}
  • ); -}; +}); + +BreadcrumbItem.displayName = 'BreadcrumbItem'; BreadcrumbItem.propTypes = { 'aria-current': PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), diff --git a/packages/react/src/components/Breadcrumb/__tests__/Breadcrumb-test.js b/packages/react/src/components/Breadcrumb/__tests__/Breadcrumb-test.js index 82691c9ad85f..ead83b567f18 100644 --- a/packages/react/src/components/Breadcrumb/__tests__/Breadcrumb-test.js +++ b/packages/react/src/components/Breadcrumb/__tests__/Breadcrumb-test.js @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. */ +import { cleanup, render } from '@testing-library/react'; import React from 'react'; import { mount } from 'enzyme'; import { settings } from 'carbon-components'; @@ -95,4 +96,23 @@ describe('Breadcrumb', () => { ); expect(aria).toMatchSnapshot(); }); + + describe('Component API', () => { + afterEach(cleanup); + + it('should accept a `ref` for the outermost node', () => { + const ref = jest.fn(() => React.createRef()); + const { container } = render( + + A + B + + C + + + ); + expect(ref).toHaveBeenCalled(); + expect(ref).toHaveBeenCalledWith(container.firstChild); + }); + }); }); diff --git a/packages/react/src/components/Breadcrumb/__tests__/BreadcrumbItem-test.js b/packages/react/src/components/Breadcrumb/__tests__/BreadcrumbItem-test.js new file mode 100644 index 000000000000..a36aa5856e9c --- /dev/null +++ b/packages/react/src/components/Breadcrumb/__tests__/BreadcrumbItem-test.js @@ -0,0 +1,27 @@ +/** + * 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 { cleanup, render } from '@testing-library/react'; +import React from 'react'; +import { BreadcrumbItem } from '../../Breadcrumb'; + +describe('BreadcrumbItem', () => { + afterEach(cleanup); + + describe('Component API', () => { + it('should accept a `ref` for the outermost node', () => { + const ref = jest.fn(() => React.createRef()); + const { container } = render( + + Test + + ); + expect(ref).toHaveBeenCalled(); + expect(ref).toHaveBeenCalledWith(container.firstChild); + }); + }); +}); From 496e11c4de247a7fbaf7978b5db21364c5bd02c1 Mon Sep 17 00:00:00 2001 From: Josefina Mancilla <32556167+jnm2377@users.noreply.github.com> Date: Thu, 3 Dec 2020 12:27:39 -0600 Subject: [PATCH 4/5] fix(TableHeader): update sortable table header aria description for voice over (#7383) * fix: update voice over label for sortable header * fix: translation keys description Co-authored-by: TJ Egan --- .../src/components/DataTable/TableHeader.js | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/packages/react/src/components/DataTable/TableHeader.js b/packages/react/src/components/DataTable/TableHeader.js index 53d584d89aa2..1f8522023bad 100644 --- a/packages/react/src/components/DataTable/TableHeader.js +++ b/packages/react/src/components/DataTable/TableHeader.js @@ -18,24 +18,27 @@ import { sortStates } from './state/sorting'; const { prefix } = settings; const translationKeys = { - iconDescription: 'carbon.table.header.icon.description', + buttonDescription: 'carbon.table.header.icon.description', }; -const translateWithId = (key, { sortDirection, isSortHeader, sortStates }) => { - if (key === translationKeys.iconDescription) { +const translateWithId = ( + key, + { header, sortDirection, isSortHeader, sortStates } +) => { + if (key === translationKeys.buttonDescription) { if (isSortHeader) { // When transitioning, we know that the sequence of states is as follows: // NONE -> ASC -> DESC -> NONE if (sortDirection === sortStates.NONE) { - return 'Sort rows by this header in ascending order'; + return `Click to sort rows by ${header} header in ascending order`; } if (sortDirection === sortStates.ASC) { - return 'Sort rows by this header in descending order'; + return `Click to sort rows by ${header} header in descending order`; } - return 'Unsort rows by this header'; + return `Click to unsort rows by ${header} header`; } - return 'Sort rows by this header in ascending order'; + return `Click to sort rows by ${header} header in ascending order`; } return ''; @@ -85,6 +88,13 @@ const TableHeader = React.forwardRef(function TableHeader( isSortHeader && sortDirection === sortStates.DESC, }); const ariaSort = !isSortHeader ? 'none' : sortDirections[sortDirection]; + const uniqueId = Math.random(); + const sortDescription = t('carbon.table.header.icon.description', { + header: children, + sortDirection, + isSortHeader, + sortStates, + }); return ( - From 336b7dee8390eb101dd7610cc57a45908b5fef2f Mon Sep 17 00:00:00 2001 From: TJ Egan Date: Fri, 4 Dec 2020 10:26:17 -0500 Subject: [PATCH 5/5] feat(toggle): convert ToggleSmall to a variant of Toggle (#7380) * feat(toggle): convert ToggleSmall to a variant of Toggle * chore(tests): remove commented out code Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../__snapshots__/PublicAPI-test.js.snap | 8 ++++ .../src/components/Toggle/Toggle-story.js | 31 +++++-------- .../src/components/Toggle/Toggle-test.js | 21 +++++++++ .../react/src/components/Toggle/Toggle.js | 41 ++++++++++++++--- .../ToggleSmall/ToggleSmall-story.js | 45 +++++++------------ .../ToggleSmall/ToggleSmall-test.js | 35 ++++++++++----- .../src/components/ToggleSmall/ToggleSmall.js | 11 +++++ 7 files changed, 126 insertions(+), 66 deletions(-) diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap index 98eddd305ec2..f094bbfe8e41 100644 --- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap +++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap @@ -6000,6 +6000,14 @@ Map { "onToggle": Object { "type": "func", }, + "size": Object { + "args": Array [ + Array [ + "sm", + ], + ], + "type": "oneOf", + }, "toggled": Object { "type": "bool", }, diff --git a/packages/react/src/components/Toggle/Toggle-story.js b/packages/react/src/components/Toggle/Toggle-story.js index 3695a925899d..13b6ecf2a870 100644 --- a/packages/react/src/components/Toggle/Toggle-story.js +++ b/packages/react/src/components/Toggle/Toggle-story.js @@ -7,9 +7,14 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; -import { withKnobs, text, boolean } from '@storybook/addon-knobs'; +import { withKnobs, text, boolean, select } from '@storybook/addon-knobs'; import Toggle from '../Toggle'; +const sizes = { + 'Default size': undefined, + 'Small size (sm)': 'sm', +}; + const toggleProps = () => ({ labelText: text( 'Label toggle input control (labelText)', @@ -21,6 +26,7 @@ const toggleProps = () => ({ disabled: boolean('Disabled (disabled)', false), onChange: action('onChange'), onToggle: action('onToggle'), + size: select('Field size (size)', sizes, undefined) || undefined, }); export default { @@ -33,7 +39,7 @@ export default { }, }; -export const Toggled = () => ( +export const Default = () => ( ( /> ); -Toggled.storyName = 'toggled'; +Default.storyName = 'Toggle'; -Toggled.parameters = { +Default.parameters = { info: { text: ` Toggles are controls that are used to quickly switch between two possible states. The example below shows @@ -54,20 +60,3 @@ Toggled.parameters = { `, }, }; - -export const Untoggled = () => ( - -); - -Untoggled.storyName = 'untoggled'; - -Untoggled.parameters = { - info: { - text: ` - Toggles are controls that are used to quickly switch between two possible states. The example below shows - an uncontrolled Toggle component. To use the Toggle component as a controlled component, set the toggled property. - Setting the toggled property will allow you to change the value dynamically, whereas setting the defaultToggled - prop will only set the value initially. This example has defaultToggled set to false. - `, - }, -}; diff --git a/packages/react/src/components/Toggle/Toggle-test.js b/packages/react/src/components/Toggle/Toggle-test.js index 6b7fcd743bb0..fce60037e1fc 100644 --- a/packages/react/src/components/Toggle/Toggle-test.js +++ b/packages/react/src/components/Toggle/Toggle-test.js @@ -109,4 +109,25 @@ describe('Toggle', () => { expect(call[2].target).toBe(inputElement); }); }); + + describe('ToggleSmall', () => { + const wrapper = mount(); + + it('Sets the `ToggleSmall` className', () => { + const input = wrapper.find('input'); + expect(input.hasClass(`${prefix}--toggle-input--small`)).toEqual(true); + }); + + it('Renders a checkmark SVG', () => { + const svg = wrapper.find(`.${prefix}--toggle__check`); + expect(svg.length).toBe(1); + }); + + it('Does not render toggle text', () => { + const offLabel = wrapper.find(`.${prefix}--toggle__text--off`); + const onLabel = wrapper.find(`.${prefix}--toggle__text--on`); + expect(offLabel.length).toBe(0); + expect(onLabel.length).toBe(0); + }); + }); }); diff --git a/packages/react/src/components/Toggle/Toggle.js b/packages/react/src/components/Toggle/Toggle.js index 94506a5d9119..bc411c80b8a7 100644 --- a/packages/react/src/components/Toggle/Toggle.js +++ b/packages/react/src/components/Toggle/Toggle.js @@ -59,6 +59,11 @@ class Toggle extends React.Component { */ onToggle: PropTypes.func, + /** + * Specify the size of the Toggle. Currently only supports 'sm' + */ + size: PropTypes.oneOf(['sm']), + /** * Specify whether the control is toggled */ @@ -85,6 +90,7 @@ class Toggle extends React.Component { labelText, labelA, labelB, + size, ...other } = this.props; @@ -93,6 +99,10 @@ class Toggle extends React.Component { [className]: className, }); + const toggleClasses = classNames(`${prefix}--toggle-input`, { + [`${prefix}--toggle-input--small`]: size, + }); + const checkedProps = {}; if (typeof toggled !== 'undefined') { @@ -109,7 +119,7 @@ class Toggle extends React.Component { aria-label={null} type="checkbox" id={id} - className={`${prefix}--toggle-input`} + className={toggleClasses} onChange={(evt) => { onChange && onChange(evt); onToggle(input.checked, id, evt); @@ -133,12 +143,29 @@ class Toggle extends React.Component { }> {labelText} - - + {size && ( + + + + )} + {!size && ( + <> + + + + )} diff --git a/packages/react/src/components/ToggleSmall/ToggleSmall-story.js b/packages/react/src/components/ToggleSmall/ToggleSmall-story.js index 15966b88ec13..9cc3972b787a 100644 --- a/packages/react/src/components/ToggleSmall/ToggleSmall-story.js +++ b/packages/react/src/components/ToggleSmall/ToggleSmall-story.js @@ -24,7 +24,7 @@ const toggleProps = () => ({ }); export default { - title: 'ToggleSmall', + title: 'ToggleSmall [Deprecated]', decorators: [withKnobs], parameters: { @@ -33,18 +33,25 @@ export default { }, }; -export const Toggled = () => ( - +export const Default = () => ( + <> +

    + This component has been deprecated, please use the `size` prop provided by + Toggle instead +

    +
    + + ); -Toggled.storyName = 'toggled'; +Default.storyName = 'toggled'; -Toggled.parameters = { +Default.parameters = { info: { text: ` Toggles are controls that are used to quickly switch between two possible states. The example below shows @@ -55,21 +62,3 @@ Toggled.parameters = { `, }, }; - -export const Untoggled = () => ( - -); - -Untoggled.storyName = 'untoggled'; - -Untoggled.parameters = { - info: { - text: ` - Toggles are controls that are used to quickly switch between two possible states. The example below shows - an uncontrolled Toggle component. To use the Toggle component as a controlled component, set the toggled property. - Setting the toggled property will allow you to change the value dynamically, whereas setting the defaultToggled - prop will only set the value initially. Small toggles may be used when there is not enough space for a regular sized toggle. This issue is most - commonly found in tables. - `, - }, -}; diff --git a/packages/react/src/components/ToggleSmall/ToggleSmall-test.js b/packages/react/src/components/ToggleSmall/ToggleSmall-test.js index e2b8ee628b18..db64de91893b 100644 --- a/packages/react/src/components/ToggleSmall/ToggleSmall-test.js +++ b/packages/react/src/components/ToggleSmall/ToggleSmall-test.js @@ -6,24 +6,39 @@ */ import React from 'react'; -import ToggleSmall from '../ToggleSmall'; import ToggleSmallSkeleton from '../ToggleSmall/ToggleSmall.Skeleton'; import { mount, shallow } from 'enzyme'; import { settings } from 'carbon-components'; const { prefix } = settings; + describe('ToggleSmall', () => { + let ToggleSmall; + + beforeEach(() => { + jest.mock('warning', () => { + return jest.fn(); + }); + + ToggleSmall = require('../ToggleSmall').default; + }); + describe('Renders as expected', () => { - const wrapper = mount( - - ); + let input; + let wrapper; + + beforeEach(() => { + wrapper = mount( + + ); - const input = wrapper.find('input'); + input = wrapper.find('input'); + }); it('Switch and label Ids should match', () => { const toggleLabel = wrapper.find(`.${prefix}--toggle__label`); diff --git a/packages/react/src/components/ToggleSmall/ToggleSmall.js b/packages/react/src/components/ToggleSmall/ToggleSmall.js index 45c35e607691..2aa82fdbaabb 100644 --- a/packages/react/src/components/ToggleSmall/ToggleSmall.js +++ b/packages/react/src/components/ToggleSmall/ToggleSmall.js @@ -10,9 +10,12 @@ import React from 'react'; import classNames from 'classnames'; import { settings } from 'carbon-components'; import { keys, match } from '../../internal/keyboard'; +import warning from 'warning'; const { prefix } = settings; +let didWarnAboutDeprecation = false; + const ToggleSmall = ({ className, defaultToggled, @@ -25,6 +28,14 @@ const ToggleSmall = ({ labelB, ...other }) => { + if (__DEV__) { + warning( + didWarnAboutDeprecation, + '`` has been deprecated in favor of `` and will be removed in the next major release of `carbon-components-react`' + ); + didWarnAboutDeprecation = true; + } + let input; const wrapperClasses = classNames(`${prefix}--form-item`, { [className]: className,