+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis aliquam tempus rutrum. Morbi consequat, mi quis pharetra eleifend, ipsum arcu porta arcu, malesuada egestas sapien enim ac nisi. Maecenas ipsum nibh, viverra viverra feugiat quis, convallis pulvinar nisi. Fusce eget erat in nulla vestibulum posuere id eu augue. Aliquam eget nulla volutpat, suscipit leo quis, vulputate risus. Cras orci arcu, aliquet ac eleifend placerat, interdum id augue. Morbi mollis urna sed euismod condimentum. Nulla ut mauris ex. Pellentesque id volutpat arcu. In ligula est, varius at facilisis eu, blandit ornare turpis. Nullam consequat venenatis magna sed sodales. Nam ornare nibh augue, non suscipit quam feugiat ut. Vivamus mollis libero mauris, vel venenatis justo feugiat sed. Ut consectetur nunc condimentum egestas vestibulum. Integer metus metus, elementum at magna vel, cursus commodo urna.
+
+
+
+
+
+
diff --git a/packages/grid/examples/preview/styles.scss b/packages/grid/examples/preview/styles.scss
index 7906a7699b68..955ac0137691 100644
--- a/packages/grid/examples/preview/styles.scss
+++ b/packages/grid/examples/preview/styles.scss
@@ -41,13 +41,19 @@ article {
.example .outside {
min-height: 80px;
- height: 100%;
}
.example .inside {
background-color: #edf4ff;
min-height: 80px;
- height: 100%;
+}
+
+.example [class*='--aspect-ratio--'] {
+ .inside,
+ .outside,
+ &.outside {
+ height: 100%;
+ }
}
.example [class*='col'] {
diff --git a/packages/grid/scss/_mixins.scss b/packages/grid/scss/_mixins.scss
index fc2d9098db3b..0b73e3b90982 100644
--- a/packages/grid/scss/_mixins.scss
+++ b/packages/grid/scss/_mixins.scss
@@ -209,36 +209,63 @@
/// @type List
/// @access public
/// @group @carbon/grid
-$carbon--aspect-ratios: ((16, 9), (2, 1), (4, 3), (1, 1), (1, 2));
-
-/// Output the CSS classes for generating aspect ratio classes
-/// @param {List} $aspect-ratios [$carbon--aspect-ratios] - A list of aspect ratios to generate
+$carbon--aspect-ratios: (
+ (16, 9),
+ (9, 16),
+ (2, 1),
+ (1, 2),
+ (4, 3),
+ (3, 4),
+ (1, 1)
+);
+
+/// Generates the CSS classname utilities for the aspect ratios
+///
+/// CSS Tricks article on aspect ratios and all the different ways it can be done.
+/// https://css-tricks.com/aspect-ratio-boxes/#article-header-id-6
+///
+/// That article references an earlier article on the topic.
+/// https://keithjgrant.com/posts/2017/03/aspect-ratios/
+///
+/// @param {Number} $width width from an aspect ratio
+/// @param {Number} $height height from an aspect ratio
/// @access private
/// @group @carbon/grid
@mixin carbon--aspect-ratio($aspect-ratios: $carbon--aspect-ratios) {
.#{$prefix}--aspect-ratio {
- height: 0;
position: relative;
}
+ .#{$prefix}--aspect-ratio::before {
+ content: '';
+ width: 1px;
+ margin-left: -1px;
+ float: left;
+ height: 0;
+ }
+
+ .#{$prefix}--aspect-ratio::after {
+ content: '';
+ display: table;
+ clear: both;
+ }
+
+ @each $aspect-ratio in $aspect-ratios {
+ $width: nth($aspect-ratio, 1);
+ $height: nth($aspect-ratio, 2);
+
+ .#{$prefix}--aspect-ratio--#{$width}x#{$height}::before {
+ padding-top: percentage($height / $width);
+ }
+ }
+
+ // leaving here for legacy support
.#{$prefix}--aspect-ratio--object {
position: absolute;
top: 0;
- right: 0;
- bottom: 0;
left: 0;
width: 100%;
height: 100%;
- z-index: 100;
- }
-
- @each $ratio in $aspect-ratios {
- $width: nth($ratio, 1);
- $height: nth($ratio, 2);
-
- .#{$prefix}--aspect-ratio--#{$width}x#{$height} {
- padding-bottom: percentage($height / $width);
- }
}
}
diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
index 37a8d2b200cf..21b7a4fc60b6 100644
--- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
+++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
@@ -1077,6 +1077,15 @@ Map {
"children": Object {
"type": "node",
},
+ "size": Object {
+ "args": Array [
+ Array [
+ "small",
+ "normal",
+ ],
+ ],
+ "type": "oneOf",
+ },
},
},
"TableToolbarAction": Object {
@@ -1196,6 +1205,7 @@ Map {
"defaultProps": Object {
"filterRows": [Function],
"locale": "en",
+ "size": "normal",
"sortRow": [Function],
"translateWithId": [Function],
},
@@ -1259,6 +1269,17 @@ Map {
"isRequired": true,
"type": "arrayOf",
},
+ "size": Object {
+ "args": Array [
+ Array [
+ "compact",
+ "short",
+ "normal",
+ "tall",
+ ],
+ ],
+ "type": "oneOf",
+ },
"sortRow": Object {
"type": "func",
},
@@ -1641,6 +1662,15 @@ Map {
"children": Object {
"type": "node",
},
+ "size": Object {
+ "args": Array [
+ Array [
+ "small",
+ "normal",
+ ],
+ ],
+ "type": "oneOf",
+ },
},
},
"TableToolbarAction" => Object {
@@ -3538,7 +3568,6 @@ Map {
"type": "bool",
},
"iconDescription": Object {
- "isRequired": true,
"type": "string",
},
"kind": Object {
@@ -3567,7 +3596,6 @@ Map {
"type": "string",
},
"statusIconDescription": Object {
- "isRequired": true,
"type": "string",
},
"subtitle": Object {
@@ -3604,7 +3632,6 @@ Map {
"type": "bool",
},
"iconDescription": Object {
- "isRequired": true,
"type": "string",
},
"kind": Object {
@@ -3633,7 +3660,6 @@ Map {
"type": "string",
},
"statusIconDescription": Object {
- "isRequired": true,
"type": "string",
},
"subtitle": Object {
@@ -4724,6 +4750,9 @@ Map {
"filter": Object {
"type": "bool",
},
+ "onClose": Object {
+ "type": "func",
+ },
"title": Object {
"type": "string",
},
diff --git a/packages/react/src/components/DataTable/DataTable.js b/packages/react/src/components/DataTable/DataTable.js
index 12223ba7afd5..7bb9ecace5fc 100644
--- a/packages/react/src/components/DataTable/DataTable.js
+++ b/packages/react/src/components/DataTable/DataTable.js
@@ -105,6 +105,11 @@ export default class DataTable extends React.Component {
*/
translateWithId: PropTypes.func,
+ /**
+ * `normal` Change the row height of table
+ */
+ size: PropTypes.oneOf(['compact', 'short', 'normal', 'tall']),
+
/**
* Specify whether the control should be a radio button or inline checkbox
*/
@@ -126,6 +131,7 @@ export default class DataTable extends React.Component {
sortRow: defaultSortRow,
filterRows: defaultFilterRows,
locale: 'en',
+ size: 'normal',
translateWithId,
};
@@ -330,6 +336,14 @@ export default class DataTable extends React.Component {
};
};
+ getToolbarProps = (props = {}) => {
+ const { size } = this.props;
+ return {
+ ...props,
+ size: size === 'compact' || size === 'short' ? 'small' : 'normal',
+ };
+ };
+
getBatchActionProps = (props = {}) => {
const { shouldShowBatchActions } = this.state;
const totalSelected = this.getSelectedRows().length;
@@ -614,6 +628,7 @@ export default class DataTable extends React.Component {
getExpandHeaderProps: this.getExpandHeaderProps,
getRowProps: this.getRowProps,
getSelectionProps: this.getSelectionProps,
+ getToolbarProps: this.getToolbarProps,
getBatchActionProps: this.getBatchActionProps,
getTableProps: this.getTableProps,
getTableContainerProps: this.getTableContainerProps,
diff --git a/packages/react/src/components/DataTable/TableToolbar.js b/packages/react/src/components/DataTable/TableToolbar.js
index 947e5757007c..6a2d734ff6ba 100644
--- a/packages/react/src/components/DataTable/TableToolbar.js
+++ b/packages/react/src/components/DataTable/TableToolbar.js
@@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
+import cx from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import { settings } from 'carbon-components';
@@ -12,11 +13,17 @@ import { AriaLabelPropType } from '../../prop-types/AriaPropTypes';
const { prefix } = settings;
-const TableToolbar = ({ children, ...rest }) => (
-
-);
+const TableToolbar = ({ children, size, ...rest }) => {
+ const className = cx({
+ [`${prefix}--table-toolbar`]: true,
+ [`${prefix}--table-toolbar--${size}`]: size,
+ });
+ return (
+
+ );
+};
TableToolbar.propTypes = {
/**
@@ -24,6 +31,11 @@ TableToolbar.propTypes = {
*/
children: PropTypes.node,
+ /**
+ * `normal` Change the row height of table
+ */
+ size: PropTypes.oneOf(['small', 'normal']),
+
/**
* Required props for the accessibility label of the TableToolbar
*/
diff --git a/packages/react/src/components/DataTable/__tests__/__snapshots__/DataTable-test.js.snap b/packages/react/src/components/DataTable/__tests__/__snapshots__/DataTable-test.js.snap
index 235ae31e0f48..95d252a12916 100644
--- a/packages/react/src/components/DataTable/__tests__/__snapshots__/DataTable-test.js.snap
+++ b/packages/react/src/components/DataTable/__tests__/__snapshots__/DataTable-test.js.snap
@@ -31,6 +31,7 @@ exports[`DataTable selection -- radio buttons should not have select-all checkbo
"getSelectionProps": [Function],
"getTableContainerProps": [Function],
"getTableProps": [Function],
+ "getToolbarProps": [Function],
"headers": Array [
Object {
"header": "Field A",
@@ -94,6 +95,7 @@ exports[`DataTable selection -- radio buttons should not have select-all checkbo
}
}
rows={Array []}
+ size="normal"
sortRow={[Function]}
translateWithId={[Function]}
>
@@ -212,6 +214,7 @@ exports[`DataTable selection -- radio buttons should render 1`] = `
"getSelectionProps": [Function],
"getTableContainerProps": [Function],
"getTableProps": [Function],
+ "getToolbarProps": [Function],
"headers": Array [
Object {
"header": "Field A",
@@ -436,6 +439,7 @@ exports[`DataTable selection -- radio buttons should render 1`] = `
},
]
}
+ size="normal"
sortRow={[Function]}
translateWithId={[Function]}
>
@@ -812,6 +816,7 @@ exports[`DataTable selection should have select-all default to un-checked if no
"getSelectionProps": [Function],
"getTableContainerProps": [Function],
"getTableProps": [Function],
+ "getToolbarProps": [Function],
"headers": Array [
Object {
"header": "Field A",
@@ -883,6 +888,7 @@ exports[`DataTable selection should have select-all default to un-checked if no
}
}
rows={Array []}
+ size="normal"
sortRow={[Function]}
translateWithId={[Function]}
>
@@ -1048,6 +1054,7 @@ exports[`DataTable selection should render 1`] = `
"getSelectionProps": [Function],
"getTableContainerProps": [Function],
"getTableProps": [Function],
+ "getToolbarProps": [Function],
"headers": Array [
Object {
"header": "Field A",
@@ -1280,6 +1287,7 @@ exports[`DataTable selection should render 1`] = `
},
]
}
+ size="normal"
sortRow={[Function]}
translateWithId={[Function]}
>
@@ -1653,6 +1661,7 @@ exports[`DataTable should render 1`] = `
"getSelectionProps": [Function],
"getTableContainerProps": [Function],
"getTableProps": [Function],
+ "getToolbarProps": [Function],
"headers": Array [
Object {
"header": "Field A",
@@ -1861,6 +1870,7 @@ exports[`DataTable should render 1`] = `
@@ -1939,6 +1949,7 @@ exports[`DataTable should render 1`] = `
},
]
}
+ size="normal"
sortRow={[Function]}
translateWithId={[Function]}
>
@@ -2493,6 +2504,7 @@ exports[`DataTable should render 1`] = `
@@ -2936,6 +2950,7 @@ exports[`DataTable sticky header should render 1`] = `
},
]
}
+ size="normal"
sortRow={[Function]}
stickyHeader={true}
translateWithId={[Function]}
@@ -3492,6 +3507,7 @@ exports[`DataTable sticky header should render 1`] = `
(
getHeaderProps,
getRowProps,
getSelectionProps,
+ getToolbarProps,
getBatchActionProps,
onInputChange,
selectedRows,
@@ -56,7 +57,7 @@ export default props => (
title="DataTable"
description="With batch actions"
{...getTableContainerProps()}>
-
+
{
headers,
getHeaderProps,
getSelectionProps,
+ getToolbarProps,
getBatchActionProps,
getRowProps,
onInputChange,
@@ -118,7 +119,7 @@ export default props => {
title="DataTable"
description="Use the toolbar menu to add rows and headers"
{...getTableContainerProps()}>
-
+
(
getHeaderProps,
getRowProps,
getTableProps,
+ getToolbarProps,
onInputChange,
getTableContainerProps,
}) => (
@@ -43,7 +44,7 @@ export default props => (
title="DataTable"
description="With toolbar"
{...getTableContainerProps()}>
-
+
diff --git a/packages/react/src/components/Notification/Notification.js b/packages/react/src/components/Notification/Notification.js
index 4cbe5008a749..5ae619b1fee6 100644
--- a/packages/react/src/components/Notification/Notification.js
+++ b/packages/react/src/components/Notification/Notification.js
@@ -358,12 +358,12 @@ ToastNotification.propTypes = {
/**
* Provide a description for "close" icon that can be read by screen readers
*/
- iconDescription: PropTypes.string.isRequired,
+ iconDescription: PropTypes.string,
/**
* Provide a description for "status" icon that can be read by screen readers
*/
- statusIconDescription: PropTypes.string.isRequired,
+ statusIconDescription: PropTypes.string,
/**
* By default, this value is "toast". You can also provide an alternate type
@@ -504,12 +504,12 @@ InlineNotification.propTypes = {
/**
* Provide a description for "close" icon that can be read by screen readers
*/
- iconDescription: PropTypes.string.isRequired,
+ iconDescription: PropTypes.string,
/**
* Provide a description for "status" icon that can be read by screen readers
*/
- statusIconDescription: PropTypes.string.isRequired,
+ statusIconDescription: PropTypes.string,
/**
* By default, this value is "inline". You can also provide an alternate type
diff --git a/packages/react/src/components/Tag/Tag-story.js b/packages/react/src/components/Tag/Tag-story.js
index 1b9ddcf8971a..7a3e2c261fb2 100644
--- a/packages/react/src/components/Tag/Tag-story.js
+++ b/packages/react/src/components/Tag/Tag-story.js
@@ -29,7 +29,11 @@ const props = {
title: 'Clear Filter',
}),
filter() {
- return { ...this.regular(), onClick: action('onClick') };
+ return {
+ ...this.regular(),
+ onClick: action('onClick'),
+ onClose: action('onClose'),
+ };
},
};
diff --git a/packages/react/src/components/Tag/Tag.js b/packages/react/src/components/Tag/Tag.js
index 2b484c81b6b8..60c54f0daf5f 100644
--- a/packages/react/src/components/Tag/Tag.js
+++ b/packages/react/src/components/Tag/Tag.js
@@ -10,9 +10,10 @@ import React from 'react';
import classNames from 'classnames';
import { settings } from 'carbon-components';
import { Close16 } from '@carbon/icons-react';
+import setupGetInstanceId from '../../tools/setupGetInstanceId';
const { prefix } = settings;
-
+const getInstanceId = setupGetInstanceId();
const TYPES = {
red: 'Red',
magenta: 'Magenta',
@@ -29,32 +30,45 @@ const TYPES = {
const Tag = ({
children,
className,
+ id,
type,
filter,
title,
disabled,
+ onClose,
...other
}) => {
+ const tagId = id || `tag-${getInstanceId()}`;
const tagClass = `${prefix}--tag--${type}`;
const tagClasses = classNames(`${prefix}--tag`, tagClass, className, {
[`${prefix}--tag--disabled`]: disabled,
[`${prefix}--tag--filter`]: filter,
});
+ const handleClose = event => {
+ event.stopPropagation();
+ onClose(event);
+ };
return filter ? (
-
{children !== null && children !== undefined ? children : TYPES[type]}
-
-
+
+
+
+
) : (
{children !== null && children !== undefined ? children : TYPES[type]}
@@ -92,6 +106,11 @@ Tag.propTypes = {
* Text to show on clear filters
*/
title: PropTypes.string,
+
+ /**
+ * Click handler for filter tag close button.
+ */
+ onClose: PropTypes.func,
};
export const types = Object.keys(TYPES);
diff --git a/packages/react/src/components/Tile/Tile.js b/packages/react/src/components/Tile/Tile.js
index 23bca02b54bb..0517a0f4a6ed 100644
--- a/packages/react/src/components/Tile/Tile.js
+++ b/packages/react/src/components/Tile/Tile.js
@@ -147,7 +147,6 @@ export class ClickableTile extends Component {
} = this.props;
const classes = classNames(
- `${prefix}--link`,
`${prefix}--tile`,
`${prefix}--tile--clickable`,
{
diff --git a/packages/react/src/components/UIShell/SideNav.js b/packages/react/src/components/UIShell/SideNav.js
index 6c566763e50e..066f2d3ba816 100644
--- a/packages/react/src/components/UIShell/SideNav.js
+++ b/packages/react/src/components/UIShell/SideNav.js
@@ -99,7 +99,7 @@ const SideNav = React.forwardRef(function SideNav(props, ref) {
eventHandlers.onBlur = event => handleToggle(event, false);
}
- if (addMouseListeners) {
+ if (addMouseListeners && isRail) {
eventHandlers.onMouseEnter = () => handleToggle(true, true);
eventHandlers.onMouseLeave = () => handleToggle(false, false);
}
diff --git a/packages/react/src/components/UIShell/__tests__/SideNav-test.js b/packages/react/src/components/UIShell/__tests__/SideNav-test.js
index 9c92bbb94580..4799ae27c89d 100644
--- a/packages/react/src/components/UIShell/__tests__/SideNav-test.js
+++ b/packages/react/src/components/UIShell/__tests__/SideNav-test.js
@@ -8,6 +8,7 @@
import React from 'react';
import { mount } from 'enzyme';
import SideNav from '../SideNav';
+import SideNavLink from '../SideNavLink';
describe('SideNav', () => {
let mockProps, wrapper;
@@ -15,7 +16,7 @@ describe('SideNav', () => {
beforeEach(() => {
mockProps = {
'aria-label': 'Navigation',
- children: Navigation ,
+ children: Navigation ,
};
});
@@ -28,12 +29,18 @@ describe('SideNav', () => {
expect(wrapper).toMatchSnapshot();
});
- it('by default, all event listeners are added', () => {
+ it('by default, focus event listeners are added', () => {
wrapper = mount( );
expect(wrapper.find('nav').props().onFocus).toBeDefined();
expect(wrapper.find('nav').props().onBlur).toBeDefined();
- expect(wrapper.find('nav').props().onMouseEnter).toBeDefined();
- expect(wrapper.find('nav').props().onMouseLeave).toBeDefined();
+ });
+
+ it('by default, mouse event listeners are not added', () => {
+ wrapper = mount( );
+ expect(wrapper.find('nav').props().onFocus).toBeDefined();
+ expect(wrapper.find('nav').props().onBlur).toBeDefined();
+ expect(wrapper.find('nav').props().onMouseEnter).not.toBeDefined();
+ expect(wrapper.find('nav').props().onMouseLeave).not.toBeDefined();
});
it('if addFocusListeners is specified as false, no focus event listeners props are added', () => {
@@ -41,6 +48,15 @@ describe('SideNav', () => {
wrapper.setProps({ addFocusListeners: false });
expect(wrapper.find('nav').props().onFocus).not.toBeDefined();
expect(wrapper.find('nav').props().onBlur).not.toBeDefined();
+ expect(wrapper.find('nav').props().onMouseEnter).not.toBeDefined();
+ expect(wrapper.find('nav').props().onMouseLeave).not.toBeDefined();
+ });
+
+ it('if addFocusListeners is specified as false in rail SideNav, no event listeners props are added', () => {
+ wrapper = mount( );
+ wrapper.setProps({ addFocusListeners: false });
+ expect(wrapper.find('nav').props().onFocus).not.toBeDefined();
+ expect(wrapper.find('nav').props().onBlur).not.toBeDefined();
expect(wrapper.find('nav').props().onMouseEnter).toBeDefined();
expect(wrapper.find('nav').props().onMouseLeave).toBeDefined();
});
diff --git a/packages/react/src/components/UIShell/__tests__/__snapshots__/SideNav-test.js.snap b/packages/react/src/components/UIShell/__tests__/__snapshots__/SideNav-test.js.snap
index 895d20bd1db4..df53d1e1b86d 100644
--- a/packages/react/src/components/UIShell/__tests__/__snapshots__/SideNav-test.js.snap
+++ b/packages/react/src/components/UIShell/__tests__/__snapshots__/SideNav-test.js.snap
@@ -19,12 +19,39 @@ exports[`SideNav should render 1`] = `
className="bx--side-nav__navigation bx--side-nav bx--side-nav--ux"
onBlur={[Function]}
onFocus={[Function]}
- onMouseEnter={[Function]}
- onMouseLeave={[Function]}
>
-
- Navigation
-
+
+
+
+
+
+
+
+ Navigation
+
+
+
+
+
+
+
`;