Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "office-ui-fabric-react",
"comment": "Align cell and column padding in DetailsList",
"type": "minor"
}
],
"packageName": "office-ui-fabric-react",
"email": "tmichon@microsoft.com"
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { IColumn, ColumnActionsMode } from './DetailsList.types';
import { ITooltipHostProps } from '../../Tooltip';
import { IDragDropHelper, IDragDropOptions } from './../../utilities/dragdrop/interfaces';
import { IDetailsHeaderStyles } from './DetailsHeader.types';
import { DEFAULT_CELL_STYLE_PROPS } from './DetailsRow.styles';
import { ICellStyleProps } from './DetailsRow.types';

const INNER_PADDING = 16; // Account for padding around the cell.
const ISPADDED_WIDTH = 24;
const MOUSEDOWN_PRIMARY_BUTTON = 0; // for mouse down event we are using ev.button property, 0 means left button

export interface IDetailsColumnProps extends React.Props<DetailsColumn> {
Expand All @@ -24,6 +24,7 @@ export interface IDetailsColumnProps extends React.Props<DetailsColumn> {
setDraggedItemIndex?: (itemIndex: number) => void;
isDropped?: boolean;
headerClassNames: IClassNames<IDetailsHeaderStyles>;
cellStyleProps?: ICellStyleProps;
}

export class DetailsColumn extends BaseComponent<IDetailsColumnProps> {
Expand All @@ -40,7 +41,14 @@ export class DetailsColumn extends BaseComponent<IDetailsColumnProps> {
}

public render(): JSX.Element {
const { column, columnIndex, parentId, isDraggable, headerClassNames } = this.props;
const {
column,
columnIndex,
parentId,
isDraggable,
headerClassNames,
cellStyleProps = DEFAULT_CELL_STYLE_PROPS
} = this.props;
const { onRenderColumnHeaderTooltip = this._onRenderColumnHeaderTooltip } = this.props;

return (
Expand All @@ -62,7 +70,13 @@ export class DetailsColumn extends BaseComponent<IDetailsColumnProps> {
)}
data-is-draggable={isDraggable}
draggable={isDraggable}
style={{ width: column.calculatedWidth! + INNER_PADDING + (column.isPadded ? ISPADDED_WIDTH : 0) }}
style={{
width:
column.calculatedWidth! +
cellStyleProps.cellLeftPadding +
cellStyleProps.cellRightPadding +
(column.isPadded ? cellStyleProps.cellExtraRightPadding : 0)
}}
data-automationid={'ColumnsHeaderColumn'}
data-item-key={column.key}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ export class DetailsHeaderBase extends BaseComponent<IDetailsHeaderProps, IDetai
]
: null}
{groupNestingDepth! > 0 && this.props.collapseAllVisibility === CollapseAllVisibility.visible ? (
<div className={classNames.cell} onClick={this._onToggleCollapseAll} data-is-focusable={true}>
<div className={classNames.cellIsGroupExpander} onClick={this._onToggleCollapseAll} data-is-focusable={true}>
<Icon className={classNames.collapseButton} iconName="ChevronDown" />
</div>
) : null}
Expand All @@ -276,6 +276,7 @@ export class DetailsHeaderBase extends BaseComponent<IDetailsHeaderProps, IDetai
onColumnContextMenu={onColumnContextMenu}
isDropped={this._onDropIndexInfo.targetIndex === columnIndex}
headerClassNames={classNames}
cellStyleProps={this.props.cellStyleProps}
/>,
column.isResizable && this._renderColumnSizer(columnIndex)
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
keyframes
} from '../../Styling';
import { IsFocusVisibleClassName } from '../../Utilities';
import { DEFAULT_CELL_STYLE_PROPS } from './DetailsRow.styles';

const GlobalClassNames = {
tooltipHost: 'ms-TooltipHost',
Expand All @@ -31,13 +32,21 @@ const GlobalClassNames = {
};

const values = {
rowHeight: 32,
cellPadding: 8,
isPaddedMargin: 24
rowHeight: 32
};

export const getStyles = (props: IDetailsHeaderStyleProps): IDetailsHeaderStyles => {
const { theme, className, isSelectAllHidden, isAllSelected, isResizingColumn, isSizing, isAllCollapsed } = props;
const {
theme,
className,
isSelectAllHidden,
isAllSelected,
isResizingColumn,
isSizing,
isAllCollapsed,
cellStyleProps = DEFAULT_CELL_STYLE_PROPS
} = props;

const { semanticColors, palette } = theme;
const classNames = getGlobalClassNames(GlobalClassNames, theme);

Expand Down Expand Up @@ -84,7 +93,7 @@ export const getStyles = (props: IDetailsHeaderStyleProps): IDetailsHeaderStyles
position: 'relative',
display: 'inline-block;',
boxSizing: 'border-box',
padding: `0 ${values.cellPadding}px`,
padding: `0 ${cellStyleProps.cellRightPadding}px 0 ${cellStyleProps.cellLeftPadding}px`,
border: 'none',
lineHeight: 'inherit',
margin: '0',
Expand Down Expand Up @@ -149,7 +158,7 @@ export const getStyles = (props: IDetailsHeaderStyleProps): IDetailsHeaderStyles

cellWrapperPadded: [
{
paddingRight: values.isPaddedMargin + values.cellPadding
paddingRight: cellStyleProps.cellExtraRightPadding + cellStyleProps.cellRightPadding
}
],

Expand All @@ -168,6 +177,15 @@ export const getStyles = (props: IDetailsHeaderStyleProps): IDetailsHeaderStyles
}
],

cellIsGroupExpander: [
cellStyles,
{
paddingLeft: '8px',
paddingRight: '8px',
width: '36px'
}
],

cellIsActionable: [
{
selectors: {
Expand Down Expand Up @@ -318,7 +336,7 @@ export const getStyles = (props: IDetailsHeaderStyleProps): IDetailsHeaderStyles
alignItems: 'stretch',
boxSizing: 'border-box',
overflow: 'hidden',
padding: '0 8px 0 12px'
padding: `0 ${cellStyleProps.cellRightPadding}px 0 ${cellStyleProps.cellLeftPadding}px`
}
],

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ISelection, SelectionMode } from '../../utilities/selection/interfaces'
import { ITheme, IStyle } from '../../Styling';
import { DetailsHeaderBase } from './DetailsHeader.base';
import { IColumn, DetailsListLayoutMode, IColumnReorderOptions } from './DetailsList.types';
import { ICellStyleProps } from './DetailsRow.types';

export interface IDetailsHeader {
/** sets focus into the header */
Expand Down Expand Up @@ -91,6 +92,8 @@ export interface IDetailsHeaderProps extends React.Props<DetailsHeaderBase> {

/** Overriding class name */
className?: string;

cellStyleProps?: ICellStyleProps;
}

export enum SelectAllVisibility {
Expand Down Expand Up @@ -139,6 +142,8 @@ export type IDetailsHeaderStyleProps = Required<Pick<IDetailsHeaderProps, 'theme

/** Whether checkbox is hidden */
isCheckboxHidden?: boolean;

cellStyleProps?: ICellStyleProps;
};

export interface IDetailsHeaderStyles {
Expand All @@ -154,6 +159,7 @@ export interface IDetailsHeaderStyles {
cellSizerStart: IStyle;
cellSizerEnd: IStyle;
cellIsResizing: IStyle;
cellIsGroupExpander: IStyle;
collapseButton: IStyle;
iconOnlyHeader: IStyle;
nearIcon: IStyle;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import { IGroupedList, GroupedList, IGroupDividerProps, IGroupRenderProps } from
import { IList, List, IListProps, ScrollToMode } from '../../List';
import { withViewport } from '../../utilities/decorators/withViewport';
import { GetGroupCount } from '../../utilities/groupedList/GroupedListUtility';
import { DEFAULT_CELL_STYLE_PROPS } from './DetailsRow.styles';

const getClassNames = classNamesFunction<IDetailsListStyleProps, IDetailsListStyles>();

Expand All @@ -60,8 +61,6 @@ export interface IDetailsListState {
const MIN_COLUMN_WIDTH = 100; // this is the global min width
const CHECKBOX_WIDTH = 40;
const GROUP_EXPAND_WIDTH = 36;
const DEFAULT_INNER_PADDING = 16;
const ISPADDED_WIDTH = 24;

const DEFAULT_RENDERED_WINDOWS_AHEAD = 2;
const DEFAULT_RENDERED_WINDOWS_BEHIND = 2;
Expand Down Expand Up @@ -403,7 +402,8 @@ export class DetailsListBase extends BaseComponent<IDetailsListProps, IDetailsLi
collapseAllVisibility: groupProps && groupProps.collapseAllVisibility,
viewport: viewport,
columnReorderOptions: columnReorderOptions,
minimumPixelsForDrag: minimumPixelsForDrag
minimumPixelsForDrag: minimumPixelsForDrag,
cellStyleProps: DEFAULT_CELL_STYLE_PROPS
},
this._onRenderDetailsHeader
)}
Expand Down Expand Up @@ -515,7 +515,8 @@ export class DetailsListBase extends BaseComponent<IDetailsListProps, IDetailsLi
checkButtonAriaLabel,
checkboxCellClassName,
groupProps,
useReducedRowRenderer
useReducedRowRenderer,
cellStyleProps = DEFAULT_CELL_STYLE_PROPS
} = this.props;
const collapseAllVisibility = groupProps && groupProps.collapseAllVisibility;
const selection = this._selection;
Expand Down Expand Up @@ -543,7 +544,8 @@ export class DetailsListBase extends BaseComponent<IDetailsListProps, IDetailsLi
getRowAriaDescribedBy: getRowAriaDescribedBy,
checkButtonAriaLabel: checkButtonAriaLabel,
checkboxCellClassName: checkboxCellClassName,
useReducedRowRenderer: useReducedRowRenderer
useReducedRowRenderer: useReducedRowRenderer,
cellStyleProps: cellStyleProps
};

if (!item) {
Expand Down Expand Up @@ -750,7 +752,7 @@ export class DetailsListBase extends BaseComponent<IDetailsListProps, IDetailsLi
const fixedColumns = newColumns.slice(0, resizingColumnIndex);
fixedColumns.forEach(column => (column.calculatedWidth = this._getColumnOverride(column.key).currentWidth));

const fixedWidth = fixedColumns.reduce((total, column, i) => total + getPaddedWidth(column, i === 0), 0);
const fixedWidth = fixedColumns.reduce((total, column, i) => total + getPaddedWidth(column, i === 0, props), 0);

const remainingColumns = newColumns.slice(resizingColumnIndex);
const remainingWidth = viewportWidth - fixedWidth;
Expand All @@ -769,24 +771,20 @@ export class DetailsListBase extends BaseComponent<IDetailsListProps, IDetailsLi
firstIndex: number
): IColumn[] {
const { selectionMode, checkboxVisibility, groups } = props;
const outerPadding = DEFAULT_INNER_PADDING;
const rowCheckWidth =
selectionMode !== SelectionMode.none && checkboxVisibility !== CheckboxVisibility.hidden ? CHECKBOX_WIDTH : 0;
const groupExpandWidth = groups ? GROUP_EXPAND_WIDTH : 0;
let totalWidth = 0; // offset because we have one less inner padding.
const availableWidth = viewportWidth - (outerPadding + rowCheckWidth + groupExpandWidth);
const availableWidth = viewportWidth - (rowCheckWidth + groupExpandWidth);
const adjustedColumns: IColumn[] = newColumns.map((column, i) => {
const newColumn = assign(
{},
column,
{
calculatedWidth: column.minWidth || MIN_COLUMN_WIDTH
},
this._columnOverrides[column.key]
);
const newColumn = {
...column,
calculatedWidth: column.minWidth || MIN_COLUMN_WIDTH,
...this._columnOverrides[column.key]
};

const isFirst = i + firstIndex === 0;
totalWidth += getPaddedWidth(newColumn, isFirst);
totalWidth += getPaddedWidth(newColumn, isFirst, props);

return newColumn;
});
Expand All @@ -804,7 +802,7 @@ export class DetailsListBase extends BaseComponent<IDetailsListProps, IDetailsLi
column.calculatedWidth = Math.max(column.calculatedWidth! - overflowWidth, minWidth);
totalWidth = availableWidth;
} else {
totalWidth -= getPaddedWidth(column, false);
totalWidth -= getPaddedWidth(column, false, props);
adjustedColumns.splice(lastIndex, 1);
}
lastIndex--;
Expand Down Expand Up @@ -1046,6 +1044,13 @@ function isRightArrow(event: React.KeyboardEvent<HTMLElement>): boolean {
return event.which === getRTLSafeKeyCode(KeyCodes.right);
}

function getPaddedWidth(column: IColumn, isFirst: boolean): number {
return column.calculatedWidth! + (isFirst ? 0 : DEFAULT_INNER_PADDING) + (column.isPadded ? ISPADDED_WIDTH : 0);
function getPaddedWidth(column: IColumn, isFirst: boolean, props: IDetailsListProps): number {
const { cellStyleProps = DEFAULT_CELL_STYLE_PROPS } = props;

return (
column.calculatedWidth! +
cellStyleProps.cellLeftPadding +
cellStyleProps.cellRightPadding +
(column.isPadded ? cellStyleProps.cellExtraRightPadding : 0)
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { IDetailsFooterProps } from './DetailsFooter.types';
import { IWithViewportProps, IViewport } from '../../utilities/decorators/withViewport';
import { IList, IListProps, ScrollToMode } from '../List/index';
import { ITheme, IStyle } from '../../Styling';
import { ICellStyleProps } from './DetailsRow.types';

export { IDetailsHeaderProps };

Expand Down Expand Up @@ -280,6 +281,12 @@ export interface IDetailsListProps extends IBaseProps<IDetailsList>, IWithViewpo
* @default false
*/
useReducedRowRenderer?: boolean;

/**
* Props impacting the render style of cells. Since these have an impact on calculated column widths, they are
* handled separately from normal theme styling, but they are passed to the styling system.
*/
cellStyleProps?: ICellStyleProps;
}

export interface IColumn {
Expand Down
Loading