[UI Framework] Update Popover, Table, and ContextMenu to support ContextMenus within Tables (#14682) (#14691)

* Update Popover, Table, and ContextMenu to support ContextMenus within Tables.
This commit is contained in:
CJ Cenizal 2017-10-31 10:52:50 -07:00 committed by GitHub
parent ffecd74619
commit 329288d63a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 179 additions and 73 deletions

View file

@ -883,7 +883,14 @@ main {
.kuiContextMenu__panel {
position: absolute; }
/**
* 1. Ensure icon is centered within a container with a consistent width.
*/
.kuiContextMenu__icon {
width: 16px;
/* 1 */
text-align: center;
/* 1 */
margin-right: 8px; }
.kuiContextMenu__itemLayout {
@ -3341,13 +3348,12 @@ main {
.kuiPopover.kuiPopover-isOpen .kuiPopover__panel {
opacity: 1;
visibility: visible;
z-index: 2000;
margin-top: 8px;
pointer-events: auto; }
.kuiPopover__panel {
position: absolute;
min-width: 256px;
z-index: 2000;
top: 100%;
left: 50%;
-webkit-transform: translateX(-50%) translateY(8px) translateZ(0);
@ -3601,9 +3607,34 @@ main {
color: #191E23;
border-top: 1px solid #D9D9D9; }
/**
* 1. Vertically align all children.
* 2. The padding on this div allows the ellipsis to show if the content is truncated. If
* the padding was on the cell, the ellipsis would be cropped.
* 3. Truncate content with an ellipsis.
*/
.kuiTableRowCell__liner {
padding: 7px 8px 8px;
/* 2 */
line-height: 1.5;
/* 1 */
overflow: hidden;
/* 3 */
text-overflow: ellipsis;
/* 3 */
white-space: nowrap;
/* 3 */ }
.kuiTableRowCell__liner > * {
vertical-align: middle;
/* 1 */ }
.kuiTableRowCell--wrap .kuiTableRowCell__liner {
white-space: normal; }
.kuiTableRowCell--overflowingContent .kuiTableRowCell__liner {
overflow: visible;
white-space: normal; }
/**
* 1. We don't want to create too strong a disconnect between the original row and the row
* that contains its expanded details.
@ -3612,26 +3643,6 @@ main {
border-top-color: #f0f0f0;
/* 1 */ }
/**
* 1. Vertically align all children.
* 2. Truncate text with an ellipsis. The padding on this div allows the ellipsis to show. If
* the padding was on the cell, the ellipsis would be cropped.
*/
.kuiTableRowCell__liner {
white-space: nowrap;
/* 2 */
overflow: hidden;
/* 2 */
text-overflow: ellipsis;
/* 2 */
padding: 7px 8px 8px;
/* 2 */
line-height: 1.5;
/* 1 */ }
.kuiTableRowCell__liner > * {
vertical-align: middle;
/* 1 */ }
.kuiTableRowCell--alignRight {
text-align: right; }
.kuiTableRowCell--alignRight .kuiTableRowCell__liner {

View file

@ -44,30 +44,32 @@ export default class extends Component {
isOpen={this.state.isPopoverOpen}
closePopover={this.closePopover.bind(this)}
>
<div className="kuiVerticalRhythmSmall">
<KuiFieldGroup>
<KuiFieldGroupSection isWide>
<div className="kuiSearchInput">
<div className="kuiSearchInput__icon kuiIcon fa-search" />
<input
className="kuiSearchInput__input"
type="text"
/>
</div>
</KuiFieldGroupSection>
<div style={{ width: '300px' }}>
<div className="kuiVerticalRhythmSmall">
<KuiFieldGroup>
<KuiFieldGroupSection isWide>
<div className="kuiSearchInput">
<div className="kuiSearchInput__icon kuiIcon fa-search" />
<input
className="kuiSearchInput__input"
type="text"
/>
</div>
</KuiFieldGroupSection>
<KuiFieldGroupSection>
<select className="kuiSelect">
<option>Animal</option>
<option>Mineral</option>
<option>Vegetable</option>
</select>
</KuiFieldGroupSection>
</KuiFieldGroup>
</div>
<KuiFieldGroupSection>
<select className="kuiSelect">
<option>Animal</option>
<option>Mineral</option>
<option>Vegetable</option>
</select>
</KuiFieldGroupSection>
</KuiFieldGroup>
</div>
<div className="kuiVerticalRhythmSmall">
<KuiButton buttonType="primary">Save</KuiButton>
<div className="kuiVerticalRhythmSmall">
<KuiButton buttonType="primary">Save</KuiButton>
</div>
</div>
</KuiPopover>
);

View file

@ -5,6 +5,11 @@ import React, {
import classNames from 'classnames';
import {
KuiButton,
KuiButtonIcon,
KuiPopover,
KuiContextMenuPanel,
KuiContextMenuItem,
KuiTable,
KuiTableBody,
KuiTableHeader,
@ -32,6 +37,7 @@ export class Table extends Component {
this.state = {
sortedColumn: 'title',
rowToSelectedStateMap: new Map(),
rowToOpenActionsPopoverMap: new Map(),
};
this.items = [{
@ -39,27 +45,23 @@ export class Table extends Component {
isLink: true,
status: 'success',
dateCreated: 'Tue Dec 06 2016 12:56:15 GMT-0800 (PST)',
dateModified: 'Tue Dec 06 2016 12:56:15 GMT-0800 (PST)',
}, {
title: 'Boomerang',
isLink: false,
status: 'success',
dateCreated: 'Tue Dec 06 2016 12:56:15 GMT-0800 (PST)',
dateModified: 'Tue Dec 06 2016 12:56:15 GMT-0800 (PST)',
details: 'All kinds of crazy information about boomerangs could go in here.',
}, {
title: 'Celebration of some very long content that will affect cell width and should eventually become truncated',
isLink: true,
status: 'warning',
dateCreated: 'Tue Dec 06 2016 12:56:15 GMT-0800 (PST)',
dateModified: 'Tue Dec 06 2016 12:56:15 GMT-0800 (PST)',
}, {
title: 'You can also specify that really long content wraps instead of becoming truncated with an ellipsis (which is the default behavior)', // eslint-disable-line max-len
isLink: true,
isWrapped: true,
status: 'danger',
dateCreated: 'Tue Dec 06 2016 12:56:15 GMT-0800 (PST)',
dateModified: 'Tue Dec 06 2016 12:56:15 GMT-0800 (PST)',
}];
this.sortableProperties = new SortableProperties([{
@ -93,6 +95,26 @@ export class Table extends Component {
return this.state.rowToSelectedStateMap.get(item);
};
togglePopover = item => {
this.setState(previousState => {
const rowToOpenActionsPopoverMap = new Map(previousState.rowToOpenActionsPopoverMap);
rowToOpenActionsPopoverMap.set(item, !rowToOpenActionsPopoverMap.get(item));
return { rowToOpenActionsPopoverMap };
});
};
closePopover = item => {
this.setState(previousState => {
const rowToOpenActionsPopoverMap = new Map(previousState.rowToOpenActionsPopoverMap);
rowToOpenActionsPopoverMap.set(item, false);
return { rowToOpenActionsPopoverMap };
});
};
isPopoverOpen = item => {
return this.state.rowToOpenActionsPopoverMap.get(item);
};
renderStatusIcon(status) {
const iconClasses = classNames('kuiIcon', statusToIconClassNameMap[status]);
return <div className={iconClasses} />;
@ -133,8 +155,53 @@ export class Table extends Component {
{item.dateCreated}
</KuiTableRowCell>
<KuiTableRowCell>
{item.dateModified}
<KuiTableRowCell textOnly={false}>
<KuiPopover
button={(
<KuiButton
buttonType="basic"
onClick={() => this.togglePopover(item)}
icon={<KuiButtonIcon className="fa-angle-down" />}
iconPosition="right"
>
Actions
</KuiButton>
)}
isOpen={this.isPopoverOpen(item)}
closePopover={() => this.closePopover(item)}
panelPaddingSize="none"
withTitle
anchorPosition="right"
>
<KuiContextMenuPanel
style={{ width: '100px' }}
items={[(
<KuiContextMenuItem
key="A"
icon={<span className="kuiIcon fa-pencil" />}
onClick={() => { this.closePopover(item); window.alert('Edit'); }}
>
Edit
</KuiContextMenuItem>
), (
<KuiContextMenuItem
key="B"
icon={<span className="kuiIcon fa-share" />}
onClick={() => { this.closePopover(item); window.alert('Share'); }}
>
Share
</KuiContextMenuItem>
), (
<KuiContextMenuItem
key="C"
icon={<span className="kuiIcon fa-trash-o" />}
onClick={() => { this.closePopover(item); window.alert('Delete'); }}
>
Delete
</KuiContextMenuItem>
)]}
/>
</KuiPopover>
</KuiTableRowCell>
</KuiTableRow>
);
@ -187,8 +254,8 @@ export class Table extends Component {
Date created
</KuiTableHeaderCell>
<KuiTableHeaderCell>
Date last modified
<KuiTableHeaderCell width="110px">
Actions
</KuiTableHeaderCell>
</KuiTableHeader>

View file

@ -16,7 +16,12 @@ $kuiContextMenuWidth: $kuiSize * 16;
position: absolute;
}
/**
* 1. Ensure icon is centered within a container with a consistent width.
*/
.kuiContextMenu__icon {
width: $kuiSize; /* 1 */
text-align: center; /* 1 */
margin-right: $kuiSizeS;
}

View file

@ -10,7 +10,6 @@
.kuiPopover__panel {
opacity: 1;
visibility: visible;
z-index: $kuiZContentMenu;
margin-top: $kuiSizeS;
pointer-events: auto;
}
@ -20,7 +19,7 @@
// Animation happens on the panel.
.kuiPopover__panel {
position: absolute;
min-width: $kuiSize * 16; // Can expand further, but this size is good for our menus.
z-index: $kuiZContentMenu;
top: 100%;
left: 50%;
transform: translateX(-50%) translateY($kuiSizeS) translateZ(0);

View file

@ -106,12 +106,37 @@
border-top: $kuiBorderThin;
}
/**
* 1. Vertically align all children.
* 2. The padding on this div allows the ellipsis to show if the content is truncated. If
* the padding was on the cell, the ellipsis would be cropped.
* 3. Truncate content with an ellipsis.
*/
.kuiTableRowCell__liner {
padding: $tableCellPadding; /* 2 */
line-height: $kuiLineHeight; /* 1 */
overflow: hidden; /* 3 */
text-overflow: ellipsis; /* 3 */
white-space: nowrap; /* 3 */
& > * {
vertical-align: middle; /* 1 */
}
}
.kuiTableRowCell--wrap {
.kuiTableRowCell__liner {
white-space: normal;
}
}
.kuiTableRowCell--overflowingContent {
.kuiTableRowCell__liner {
overflow: visible;
white-space: normal;
}
}
/**
* 1. We don't want to create too strong a disconnect between the original row and the row
* that contains its expanded details.
@ -120,23 +145,6 @@
border-top-color: $tableCellExpandedBorderColor; /* 1 */
}
/**
* 1. Vertically align all children.
* 2. Truncate text with an ellipsis. The padding on this div allows the ellipsis to show. If
* the padding was on the cell, the ellipsis would be cropped.
*/
.kuiTableRowCell__liner {
white-space: nowrap; /* 2 */
overflow: hidden; /* 2 */
text-overflow: ellipsis; /* 2 */
padding: $tableCellPadding; /* 2 */
line-height: $kuiLineHeight; /* 1 */
& > * {
vertical-align: middle; /* 1 */
}
}
.kuiTableRowCell--alignRight {
text-align: right;

View file

@ -8,10 +8,20 @@ export const ALIGNMENT = [
LEFT_ALIGNMENT
];
export const KuiTableRowCell = ({ children, align, className, ...rest }) => {
export const KuiTableRowCell = ({
children,
align,
className,
textOnly,
...rest
}) => {
const classes = classNames('kuiTableRowCell', className, {
'kuiTableRowCell--alignRight': align === RIGHT_ALIGNMENT,
// We're doing this rigamarole instead of creating kuiTabelRowCell--textOnly for BWC
// purposes for the time-being.
'kuiTableRowCell--overflowingContent': !textOnly,
});
return (
<td className={classes} {...rest} >
<div className="kuiTableRowCell__liner">
@ -20,11 +30,15 @@ export const KuiTableRowCell = ({ children, align, className, ...rest }) => {
</td>
);
};
KuiTableRowCell.propTypes = {
align: PropTypes.oneOf(ALIGNMENT),
children: PropTypes.node,
className: PropTypes.string,
textOnly: PropTypes.bool,
};
KuiTableRowCell.defaultProps = {
align: LEFT_ALIGNMENT
align: LEFT_ALIGNMENT,
textOnly: true,
};