first commit

This commit is contained in:
Stefan Hacker
2026-04-03 09:38:48 +02:00
commit 37ad745546
47450 changed files with 3120798 additions and 0 deletions
@@ -0,0 +1,36 @@
import * as React from 'react';
import type { IDetailsColumnProps } from './DetailsColumn.types';
import type { JSXElement } from '@fluentui/utilities';
/**
* Component for rendering columns in a `DetailsList`.
*
* {@docCategory DetailsList}
*/
export declare class DetailsColumnBase extends React.Component<IDetailsColumnProps> {
private _async;
private _events;
private _root;
private _dragDropSubscription?;
private _classNames;
private _tooltipRef;
constructor(props: IDetailsColumnProps);
render(): JSXElement;
componentDidMount(): void;
componentWillUnmount(): void;
componentDidUpdate(): void;
private _onRenderFilterIcon;
private _onRenderColumnHeaderTooltip;
private _onColumnClick;
private _onColumnKeyDown;
private _onColumnBlur;
private _onColumnFocus;
private _getColumnDragDropOptions;
private _hasAccessibleDescription;
private _renderAccessibleDescription;
private _onDragStart;
private _onDragEnd;
private _updateHeaderDragInfo;
private _onColumnContextMenu;
private _onRootMouseDown;
private _addDragDropHandling;
}
@@ -0,0 +1,278 @@
import { __assign, __extends, __rest } from "tslib";
import * as React from 'react';
import { Icon, FontIcon } from '../../Icon';
import { initializeComponentRef, EventGroup, Async, classNamesFunction, composeRenderFunction } from '../../Utilities';
import { ColumnActionsMode } from './DetailsList.types';
import { DEFAULT_CELL_STYLE_PROPS } from './DetailsRow.styles';
var MOUSEDOWN_PRIMARY_BUTTON = 0; // for mouse down event we are using ev.button property, 0 means left button
var getClassNames = classNamesFunction();
var TRANSITION_DURATION_DRAG = 200; // ms
var TRANSITION_DURATION_DROP = 1500; // ms
var CLASSNAME_ADD_INTERVAL = 20; // ms
var defaultOnRenderHeader = function (classNames) {
return function (props) {
if (!props) {
return null;
}
if (props.column.isIconOnly) {
return React.createElement("span", { className: classNames.accessibleLabel }, props.column.name);
}
return React.createElement(React.Fragment, null, props.column.name);
};
};
/**
* Component for rendering columns in a `DetailsList`.
*
* {@docCategory DetailsList}
*/
var DetailsColumnBase = /** @class */ (function (_super) {
__extends(DetailsColumnBase, _super);
function DetailsColumnBase(props) {
var _this = _super.call(this, props) || this;
_this._root = React.createRef();
_this._tooltipRef = React.createRef();
_this._onRenderFilterIcon = function (classNames) {
return function (props) {
var columnProps = props.columnProps, iconProps = __rest(props, ["columnProps"]);
var IconComponent = (columnProps === null || columnProps === void 0 ? void 0 : columnProps.useFastIcons) ? FontIcon : Icon;
return React.createElement(IconComponent, __assign({}, iconProps));
};
};
_this._onRenderColumnHeaderTooltip = function (tooltipHostProps) {
return React.createElement("span", { className: tooltipHostProps.hostClassName }, tooltipHostProps.children);
};
_this._onColumnClick = function (ev) {
var _a = _this.props, onColumnClick = _a.onColumnClick, column = _a.column;
if (column.columnActionsMode === ColumnActionsMode.disabled) {
return;
}
if (column.onColumnClick) {
column.onColumnClick(ev, column);
}
if (onColumnClick) {
onColumnClick(ev, column);
}
};
_this._onColumnKeyDown = function (ev) {
var _a = _this.props, onColumnKeyDown = _a.onColumnKeyDown, column = _a.column;
if (column.onColumnKeyDown) {
column.onColumnKeyDown(ev, column);
}
if (onColumnKeyDown) {
onColumnKeyDown(ev, column);
}
};
_this._onColumnBlur = function () {
_this._tooltipRef.current && _this._tooltipRef.current.dismiss();
};
_this._onColumnFocus = function () {
_this._tooltipRef.current && _this._tooltipRef.current.show();
};
_this._onDragStart = function (item, itemIndex, selectedItems, event) {
var classNames = _this._classNames;
if (itemIndex) {
_this._updateHeaderDragInfo(itemIndex);
_this._root.current.classList.add(classNames.borderWhileDragging);
_this._async.setTimeout(function () {
if (_this._root.current) {
_this._root.current.classList.add(classNames.noBorderWhileDragging);
}
}, CLASSNAME_ADD_INTERVAL);
}
};
_this._onDragEnd = function (item, event) {
var classNames = _this._classNames;
if (event) {
_this._updateHeaderDragInfo(-1, event);
}
_this._root.current.classList.remove(classNames.borderWhileDragging);
_this._root.current.classList.remove(classNames.noBorderWhileDragging);
};
_this._updateHeaderDragInfo = function (itemIndex, event) {
/* eslint-disable @typescript-eslint/no-deprecated */
if (_this.props.setDraggedItemIndex) {
_this.props.setDraggedItemIndex(itemIndex);
}
/* eslint-enable @typescript-eslint/no-deprecated */
if (_this.props.updateDragInfo) {
_this.props.updateDragInfo({ itemIndex: itemIndex }, event);
}
};
_this._onColumnContextMenu = function (ev) {
var _a = _this.props, onColumnContextMenu = _a.onColumnContextMenu, column = _a.column;
if (column.onColumnContextMenu) {
column.onColumnContextMenu(column, ev);
ev.preventDefault();
}
if (onColumnContextMenu) {
onColumnContextMenu(column, ev);
ev.preventDefault();
}
};
_this._onRootMouseDown = function (ev) {
var isDraggable = _this.props.isDraggable;
// Ignore anything except the primary button.
if (isDraggable && ev.button === MOUSEDOWN_PRIMARY_BUTTON) {
ev.stopPropagation();
}
};
initializeComponentRef(_this);
_this._async = new Async(_this);
_this._events = new EventGroup(_this);
return _this;
}
DetailsColumnBase.prototype.render = function () {
var _a = this.props, column = _a.column, parentId = _a.parentId, isDraggable = _a.isDraggable, styles = _a.styles, theme = _a.theme, _b = _a.cellStyleProps, cellStyleProps = _b === void 0 ? DEFAULT_CELL_STYLE_PROPS : _b, _c = _a.useFastIcons, useFastIcons = _c === void 0 ? true : _c;
var _d = this.props.onRenderColumnHeaderTooltip, onRenderColumnHeaderTooltip = _d === void 0 ? this._onRenderColumnHeaderTooltip : _d;
this._classNames = getClassNames(styles, {
theme: theme,
headerClassName: column.headerClassName,
iconClassName: column.iconClassName,
isActionable: column.columnActionsMode !== ColumnActionsMode.disabled,
isEmpty: !column.name,
isIconVisible: column.isSorted || column.isGrouped || column.isFiltered,
isPadded: column.isPadded,
isIconOnly: column.isIconOnly,
cellStyleProps: cellStyleProps,
transitionDurationDrag: TRANSITION_DURATION_DRAG,
transitionDurationDrop: TRANSITION_DURATION_DROP,
});
var classNames = this._classNames;
var IconComponent = useFastIcons ? FontIcon : Icon;
var onRenderFilterIcon = column.onRenderFilterIcon
? composeRenderFunction(column.onRenderFilterIcon, this._onRenderFilterIcon(this._classNames))
: this._onRenderFilterIcon(this._classNames);
var onRenderHeader = column.onRenderHeader
? composeRenderFunction(column.onRenderHeader, defaultOnRenderHeader(this._classNames))
: defaultOnRenderHeader(this._classNames);
var hasInnerButton = column.columnActionsMode !== ColumnActionsMode.disabled &&
(column.onColumnClick !== undefined || this.props.onColumnClick !== undefined);
// use aria-describedby to point to the tooltip if the tooltip is not using the ariaLabel string
var shouldAssociateTooltip = this.props.onRenderColumnHeaderTooltip
? !column.ariaLabel
: this._hasAccessibleDescription();
var accNameDescription = {
'aria-label': column.ariaLabel ? column.ariaLabel : column.isIconOnly ? column.name : undefined,
'aria-labelledby': column.ariaLabel || column.isIconOnly ? undefined : "".concat(parentId, "-").concat(column.key, "-name"),
'aria-describedby': shouldAssociateTooltip ? "".concat(parentId, "-").concat(column.key, "-tooltip") : undefined,
};
return (React.createElement(React.Fragment, null,
React.createElement("div", __assign({ key: column.key, ref: this._root, role: 'columnheader' }, (!hasInnerButton && accNameDescription), { "aria-sort": column.isSorted ? (column.isSortedDescending ? 'descending' : 'ascending') : 'none', "data-is-focusable": !hasInnerButton && column.columnActionsMode !== ColumnActionsMode.disabled ? 'true' : undefined, className: classNames.root, "data-is-draggable": isDraggable, draggable: isDraggable, style: {
width: (column.calculatedWidth || 0) +
cellStyleProps.cellLeftPadding +
cellStyleProps.cellRightPadding +
(column.isPadded ? cellStyleProps.cellExtraRightPadding : 0),
}, "data-automationid": 'ColumnsHeaderColumn', "data-item-key": column.key, onBlur: this._onColumnBlur, onFocus: this._onColumnFocus }),
isDraggable && (React.createElement(IconComponent, { iconName: "GripperBarVertical", className: classNames.gripperBarVerticalStyle })),
onRenderColumnHeaderTooltip({
hostClassName: classNames.cellTooltip,
id: "".concat(parentId, "-").concat(column.key, "-tooltip"),
setAriaDescribedBy: false,
column: column,
componentRef: this._tooltipRef,
content: column.columnActionsMode !== ColumnActionsMode.disabled ? column.ariaLabel : '',
children: (React.createElement("span", __assign({ id: "".concat(parentId, "-").concat(column.key), className: classNames.cellTitle, "data-is-focusable": hasInnerButton && column.columnActionsMode !== ColumnActionsMode.disabled ? 'true' : undefined, role: hasInnerButton ? 'button' : undefined }, (hasInnerButton && accNameDescription), { onContextMenu: this._onColumnContextMenu, onClick: this._onColumnClick, onKeyDown: this._onColumnKeyDown, "aria-haspopup": column.columnActionsMode === ColumnActionsMode.hasDropdown ? 'menu' : undefined, "aria-expanded": column.columnActionsMode === ColumnActionsMode.hasDropdown ? !!column.isMenuOpen : undefined }),
React.createElement("span", { id: "".concat(parentId, "-").concat(column.key, "-name"), className: classNames.cellName },
(column.iconName || column.iconClassName) && (React.createElement(IconComponent, { className: classNames.iconClassName, iconName: column.iconName })),
onRenderHeader(this.props)),
column.isFiltered && React.createElement(IconComponent, { className: classNames.nearIcon, iconName: "Filter" }),
(column.isSorted || column.showSortIconWhenUnsorted) && (React.createElement(IconComponent, { className: classNames.sortIcon, iconName: column.isSorted ? (column.isSortedDescending ? 'SortDown' : 'SortUp') : 'Sort' })),
column.isGrouped && React.createElement(IconComponent, { className: classNames.nearIcon, iconName: "GroupedDescending" }),
column.columnActionsMode === ColumnActionsMode.hasDropdown &&
!column.isIconOnly &&
onRenderFilterIcon({
'aria-hidden': true,
columnProps: this.props,
className: classNames.filterChevron,
iconName: 'ChevronDown',
}))),
}, this._onRenderColumnHeaderTooltip)),
!this.props.onRenderColumnHeaderTooltip ? this._renderAccessibleDescription() : null));
};
DetailsColumnBase.prototype.componentDidMount = function () {
var _this = this;
if (this.props.dragDropHelper && this.props.isDraggable) {
this._addDragDropHandling();
}
var classNames = this._classNames;
if (this.props.isDropped) {
if (this._root.current) {
this._root.current.classList.add(classNames.borderAfterDropping);
this._async.setTimeout(function () {
if (_this._root.current) {
_this._root.current.classList.add(classNames.noBorderAfterDropping);
}
}, CLASSNAME_ADD_INTERVAL);
}
this._async.setTimeout(function () {
if (_this._root.current) {
_this._root.current.classList.remove(classNames.borderAfterDropping);
_this._root.current.classList.remove(classNames.noBorderAfterDropping);
}
}, TRANSITION_DURATION_DROP + CLASSNAME_ADD_INTERVAL);
}
};
DetailsColumnBase.prototype.componentWillUnmount = function () {
if (this._dragDropSubscription) {
this._dragDropSubscription.dispose();
delete this._dragDropSubscription;
}
this._async.dispose();
this._events.dispose();
};
DetailsColumnBase.prototype.componentDidUpdate = function () {
if (!this._dragDropSubscription && this.props.dragDropHelper && this.props.isDraggable) {
this._addDragDropHandling();
}
if (this._dragDropSubscription && !this.props.isDraggable) {
this._dragDropSubscription.dispose();
this._events.off(this._root.current, 'mousedown');
delete this._dragDropSubscription;
}
};
DetailsColumnBase.prototype._getColumnDragDropOptions = function () {
var _this = this;
var columnIndex = this.props.columnIndex;
var options = {
selectionIndex: columnIndex,
context: { data: columnIndex, index: columnIndex },
canDrag: function () { return _this.props.isDraggable; },
canDrop: function () { return false; },
onDragStart: this._onDragStart,
updateDropState: function () { return undefined; },
onDrop: function () { return undefined; },
onDragEnd: this._onDragEnd,
};
return options;
};
DetailsColumnBase.prototype._hasAccessibleDescription = function () {
var column = this.props.column;
return !!(column.filterAriaLabel ||
column.sortAscendingAriaLabel ||
column.sortDescendingAriaLabel ||
column.groupAriaLabel ||
column.sortableAriaLabel);
};
DetailsColumnBase.prototype._renderAccessibleDescription = function () {
var _a = this.props, column = _a.column, parentId = _a.parentId;
var classNames = this._classNames;
return this._hasAccessibleDescription() && !this.props.onRenderColumnHeaderTooltip ? (React.createElement("label", { key: "".concat(column.key, "_label"), id: "".concat(parentId, "-").concat(column.key, "-tooltip"), className: classNames.accessibleLabel, hidden: true },
(column.isFiltered && column.filterAriaLabel) || null,
((column.isSorted || column.showSortIconWhenUnsorted) &&
(column.isSorted
? column.isSortedDescending
? column.sortDescendingAriaLabel
: column.sortAscendingAriaLabel
: column.sortableAriaLabel)) ||
null,
(column.isGrouped && column.groupAriaLabel) || null)) : null;
};
DetailsColumnBase.prototype._addDragDropHandling = function () {
this._dragDropSubscription = this.props.dragDropHelper.subscribe(this._root.current, this._events, this._getColumnDragDropOptions());
// We need to use native on this to prevent MarqueeSelection from handling the event before us.
this._events.on(this._root.current, 'mousedown', this._onRootMouseDown);
};
return DetailsColumnBase;
}(React.Component));
export { DetailsColumnBase };
//# sourceMappingURL=DetailsColumn.base.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
import * as React from 'react';
import type { IDetailsColumnProps } from './DetailsColumn.types';
export declare const DetailsColumn: React.FunctionComponent<IDetailsColumnProps>;
export type { IDetailsColumnProps };
@@ -0,0 +1,5 @@
import { styled } from '../../Utilities';
import { DetailsColumnBase } from './DetailsColumn.base';
import { getDetailsColumnStyles } from './DetailsColumn.styles';
export var DetailsColumn = styled(DetailsColumnBase, getDetailsColumnStyles, undefined, { scope: 'DetailsColumn' });
//# sourceMappingURL=DetailsColumn.js.map
@@ -0,0 +1 @@
{"version":3,"file":"DetailsColumn.js","sourceRoot":"../src/","sources":["components/DetailsList/DetailsColumn.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAGhE,MAAM,CAAC,IAAM,aAAa,GAAiD,MAAM,CAI/E,iBAAiB,EAAE,sBAAsB,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC","sourcesContent":["import * as React from 'react';\nimport { styled } from '../../Utilities';\nimport { DetailsColumnBase } from './DetailsColumn.base';\nimport { getDetailsColumnStyles } from './DetailsColumn.styles';\nimport type { IDetailsColumnProps, IDetailsColumnStyleProps, IDetailsColumnStyles } from './DetailsColumn.types';\n\nexport const DetailsColumn: React.FunctionComponent<IDetailsColumnProps> = styled<\n IDetailsColumnProps,\n IDetailsColumnStyleProps,\n IDetailsColumnStyles\n>(DetailsColumnBase, getDetailsColumnStyles, undefined, { scope: 'DetailsColumn' });\n\nexport type { IDetailsColumnProps };\n"]}
@@ -0,0 +1,2 @@
import type { IDetailsColumnStyleProps, IDetailsColumnStyles } from './DetailsColumn.types';
export declare const getDetailsColumnStyles: (props: IDetailsColumnStyleProps) => IDetailsColumnStyles;
@@ -0,0 +1,160 @@
import { __assign } from "tslib";
import { getFocusStyle, getGlobalClassNames, hiddenContentStyle, FontWeights } from '../../Styling';
import { DEFAULT_CELL_STYLE_PROPS } from './DetailsRow.styles';
import { getCellStyles } from './DetailsHeader.styles';
var GlobalClassNames = {
isActionable: 'is-actionable',
cellIsCheck: 'ms-DetailsHeader-cellIsCheck',
collapseButton: 'ms-DetailsHeader-collapseButton',
isCollapsed: 'is-collapsed',
isAllSelected: 'is-allSelected',
isSelectAllHidden: 'is-selectAllHidden',
isResizingColumn: 'is-resizingColumn',
isEmpty: 'is-empty',
isIconVisible: 'is-icon-visible',
cellSizer: 'ms-DetailsHeader-cellSizer',
isResizing: 'is-resizing',
dropHintCircleStyle: 'ms-DetailsHeader-dropHintCircleStyle',
dropHintLineStyle: 'ms-DetailsHeader-dropHintLineStyle',
cellTitle: 'ms-DetailsHeader-cellTitle',
cellName: 'ms-DetailsHeader-cellName',
filterChevron: 'ms-DetailsHeader-filterChevron',
gripperBarVerticalStyle: 'ms-DetailsColumn-gripperBar',
nearIcon: 'ms-DetailsColumn-nearIcon',
};
export var getDetailsColumnStyles = function (props) {
var _a;
var theme = props.theme, headerClassName = props.headerClassName, iconClassName = props.iconClassName, isActionable = props.isActionable, isEmpty = props.isEmpty, isIconVisible = props.isIconVisible, isPadded = props.isPadded, isIconOnly = props.isIconOnly, _b = props.cellStyleProps, cellStyleProps = _b === void 0 ? DEFAULT_CELL_STYLE_PROPS : _b, transitionDurationDrag = props.transitionDurationDrag, transitionDurationDrop = props.transitionDurationDrop;
var semanticColors = theme.semanticColors, palette = theme.palette, fonts = theme.fonts;
var classNames = getGlobalClassNames(GlobalClassNames, theme);
var colors = {
iconForegroundColor: semanticColors.bodySubtext,
headerForegroundColor: semanticColors.bodyText,
headerBackgroundColor: semanticColors.bodyBackground,
dropdownChevronForegroundColor: palette.neutralSecondary,
resizerColor: palette.neutralTertiaryAlt,
};
var nearIconStyle = {
color: colors.iconForegroundColor,
opacity: 1,
paddingLeft: 8,
};
var borderWhileDragging = {
outline: "1px solid ".concat(palette.themePrimary),
};
var borderAfterDragOrDrop = {
outlineColor: 'transparent',
};
return {
root: [
getCellStyles(props),
fonts.small,
isActionable && [
classNames.isActionable,
{
selectors: {
':hover': {
color: semanticColors.bodyText,
background: semanticColors.listHeaderBackgroundHovered,
},
':active': {
background: semanticColors.listHeaderBackgroundPressed,
},
},
},
],
isEmpty && [
classNames.isEmpty,
{
textOverflow: 'clip',
},
],
isIconVisible && classNames.isIconVisible,
isPadded && {
paddingRight: cellStyleProps.cellExtraRightPadding + cellStyleProps.cellRightPadding,
},
{
selectors: {
':hover i[data-icon-name="GripperBarVertical"]': {
display: 'block',
},
},
},
headerClassName,
],
gripperBarVerticalStyle: {
display: 'none',
position: 'absolute',
textAlign: 'left',
color: palette.neutralTertiary,
left: 1,
},
nearIcon: [classNames.nearIcon, nearIconStyle],
sortIcon: [
nearIconStyle,
{
paddingLeft: 4,
position: 'relative',
top: 1,
},
],
iconClassName: [
{
color: colors.iconForegroundColor,
opacity: 1,
},
iconClassName,
],
filterChevron: [
classNames.filterChevron,
{
color: colors.dropdownChevronForegroundColor,
paddingLeft: 6,
verticalAlign: 'middle',
fontSize: fonts.small.fontSize,
},
],
cellTitle: [
classNames.cellTitle,
getFocusStyle(theme),
__assign({ display: 'flex', flexDirection: 'row', justifyContent: 'flex-start', alignItems: 'stretch', boxSizing: 'border-box', overflow: 'hidden', padding: "0 ".concat(cellStyleProps.cellRightPadding, "px 0 ").concat(cellStyleProps.cellLeftPadding, "px") }, (isIconOnly
? {
alignContent: 'flex-end',
maxHeight: '100%',
flexWrap: 'wrap-reverse',
}
: {})),
],
cellName: [
classNames.cellName,
{
flex: '0 1 auto',
overflow: 'hidden',
textOverflow: 'ellipsis',
fontWeight: FontWeights.semibold,
fontSize: fonts.medium.fontSize,
},
isIconOnly && {
selectors: (_a = {},
_a[".".concat(classNames.nearIcon)] = {
paddingLeft: 0,
},
_a),
},
],
cellTooltip: {
display: 'block',
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
},
accessibleLabel: hiddenContentStyle,
borderWhileDragging: borderWhileDragging,
noBorderWhileDragging: [borderAfterDragOrDrop, { transition: "outline ".concat(transitionDurationDrag, "ms ease") }],
borderAfterDropping: borderWhileDragging,
noBorderAfterDropping: [borderAfterDragOrDrop, { transition: "outline ".concat(transitionDurationDrop, "ms ease") }],
};
};
//# sourceMappingURL=DetailsColumn.styles.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,237 @@
import * as React from 'react';
import { DetailsColumnBase } from './DetailsColumn.base';
import type { IColumn } from './DetailsList.types';
import type { IRenderFunction, IStyleFunctionOrObject } from '../../Utilities';
import type { ITooltipHostProps } from '../../Tooltip';
import type { IDragDropHelper } from '../../DragDrop';
import type { ICellStyleProps } from './DetailsRow.types';
import type { ITheme, IStyle } from '../../Styling';
import type { IIconProps } from '../Icon/Icon.types';
/**
* {@docgategory DetailsList}
*/
export interface IDetailsColumnRenderTooltipProps extends ITooltipHostProps {
/**
* Information about the column for which the tooltip is being rendered.
* Use this to format status information about the column, such as its filter or sort state.
*/
column?: IColumn;
}
/**
* {@docCategory DetailsList}
*/
export interface IDetailsColumnProps extends React.ClassAttributes<DetailsColumnBase> {
/**
* The theme object to respect during render.
*/
theme?: ITheme;
/**
* The component styles to respect during render.
*/
styles?: IStyleFunctionOrObject<IDetailsColumnStyleProps, IDetailsColumnStyles>;
/**
* A reference to the component instance.
*/
componentRef?: () => void;
/**
* The column definition for the component instance.
*/
column: IColumn;
/**
* The column index for the component instance.
*/
columnIndex: number;
/**
* Parent ID used for accessibility label(s).
*/
parentId?: string;
/**
* Render function for providing a column header tooltip.
*/
onRenderColumnHeaderTooltip?: IRenderFunction<IDetailsColumnRenderTooltipProps>;
/**
* Callback fired when click event occurs.
*/
onColumnClick?: (ev: React.MouseEvent<HTMLElement>, column: IColumn) => void;
/**
* Callback fired on contextual menu event to provide contextual menu UI.
*/
onColumnContextMenu?: (column: IColumn, ev: React.MouseEvent<HTMLElement>) => void;
/**
* Callback fired when keydown event occurs.
*/
onColumnKeyDown?: (ev: React.KeyboardEvent, column: IColumn) => void;
/**
* The drag and drop helper for the component instance.
*/
dragDropHelper?: IDragDropHelper | null;
/**
* Whether or not the column can be re-ordered via drag and drop.
*/
isDraggable?: boolean;
/**
* @deprecated use `updateDragInfo`
*/
setDraggedItemIndex?: (itemIndex: number) => void;
/**
* Callback on drag and drop event.
*/
updateDragInfo?: (props: {
itemIndex: number;
}, event?: MouseEvent) => void;
/**
* Whether or not the column has been dropped via drag and drop.
*/
isDropped?: boolean;
/**
* Custom styles for cell rendering.
*/
cellStyleProps?: ICellStyleProps;
/**
* Whether to use fast icon and check components. The icons can't be targeted by customization
* but are still customizable via class names.
* @defaultvalue true
*/
useFastIcons?: boolean;
}
/**
* {@docCategory DetailsList}
*/
export type IDetailsColumnStyleProps = Required<Pick<IDetailsColumnProps, 'theme' | 'cellStyleProps'>> & {
/**
* Classname to provide for header region.
*/
headerClassName?: string;
/**
* Whether or not the column is actionable.
*/
isActionable?: boolean;
/**
* Whether or not the column contains contents.
*/
isEmpty?: boolean;
/**
* Whether or not the column has a visible icon.
*/
isIconVisible?: boolean;
/**
* Whether or not the column is padded.
*/
isPadded?: boolean;
/**
* Whether or not the column has icon only content/
*/
isIconOnly?: boolean;
/**
* Classname to provide for the header's icon region.
*/
iconClassName?: string;
/**
* CSS transition duration on drag event.
*/
transitionDurationDrag?: number;
/**
* CSS transition duration on drop event.
*/
transitionDurationDrop?: number;
};
/**
* {@docCategory DetailsList}
*/
export interface IDetailsColumnStyles {
/**
* Styleable root region.
*/
root: IStyle;
/**
* Styleable resize glyph region.
*/
gripperBarVerticalStyle: IStyle;
/**
* Styleable cell tooltip region.
*/
cellTooltip: IStyle;
/**
* Styleable cell title region.
*/
cellTitle: IStyle;
/**
* Styleable cell name region.
*/
cellName: IStyle;
/**
* Styleable icon region.
*/
iconClassName: IStyle;
/**
* Styleable margin by icon region.
*/
nearIcon: IStyle;
/**
* Styleable label region.
*/
accessibleLabel: IStyle;
/**
* Styleable column sort icon region.
*/
sortIcon: IStyle;
/**
* Styleable filter glyph.
*/
filterChevron: IStyle;
/**
* Styleable border region after drag & drop.
*/
borderAfterDropping: IStyle;
/**
* Transparent no border region after drag & drop to avoid content shift.
*/
noBorderAfterDropping: IStyle;
/**
* Styleable border while drag & drop occurs.
*/
borderWhileDragging: IStyle;
/**
* Transparent no border region while drag & drop occurs to avoid content shift.
*/
noBorderWhileDragging: IStyle;
}
/**
* {@docCategory DetailsList}
*/
export interface IDetailsColumnFilterIconProps extends IIconProps {
columnProps?: IDetailsColumnProps;
}
/**
* {@docCategory DetailsList}
*/
export interface IDetailsColumnFieldProps {
/**
* Item data to render.
*/
item: any;
/**
* Index of the item in its list.
*/
itemIndex: number;
/**
* Whether or not the row is selected.
*/
isSelected?: boolean;
/**
* Column schema information.
*/
column: IColumn;
/**
* Key representing the cell value, for change-detection.
*/
cellValueKey?: string;
/**
* Class name to apply to the cell root element.
*/
className?: string;
/**
* Original content render function for the cell
*/
onRender: (item?: any, index?: any, column?: IColumn) => React.ReactNode;
}
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=DetailsColumn.types.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,26 @@
import { SelectionMode } from '../../Selection';
import type { IDetailsItemProps } from './DetailsRow.types';
import type { IColumn } from './DetailsList.types';
import type { ISelection } from '../../Selection';
/**
* {@docCategory DetailsList}
*/
export interface IDetailsFooterBaseProps extends IDetailsItemProps {
}
/**
* {@docCategory DetailsList}
*/
export interface IDetailsFooterProps extends IDetailsFooterBaseProps {
/**
* Column metadata
*/
columns: IColumn[];
/**
* Selection from utilities
*/
selection: ISelection;
/**
* Selection mode
*/
selectionMode: SelectionMode;
}
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=DetailsFooter.types.js.map
@@ -0,0 +1 @@
{"version":3,"file":"DetailsFooter.types.js","sourceRoot":"../src/","sources":["components/DetailsList/DetailsFooter.types.ts"],"names":[],"mappings":"","sourcesContent":["import { SelectionMode } from '../../Selection';\nimport type { IDetailsItemProps } from './DetailsRow.types';\nimport type { IColumn } from './DetailsList.types';\nimport type { ISelection } from '../../Selection';\n\n/**\n * {@docCategory DetailsList}\n */\nexport interface IDetailsFooterBaseProps extends IDetailsItemProps {}\n\n/**\n * {@docCategory DetailsList}\n */\nexport interface IDetailsFooterProps extends IDetailsFooterBaseProps {\n /**\n * Column metadata\n */\n columns: IColumn[];\n\n /**\n * Selection from utilities\n */\n selection: ISelection;\n\n /**\n * Selection mode\n */\n selectionMode: SelectionMode;\n}\n"]}
@@ -0,0 +1,93 @@
import * as React from 'react';
import { CollapseAllVisibility } from '../../GroupedList';
import { SelectAllVisibility } from './DetailsHeader.types';
import type { IDetailsHeaderBaseProps } from './DetailsList.types';
import type { IDetailsHeaderState, IDetailsHeader } from './DetailsHeader.types';
import type { JSXElement } from '@fluentui/utilities';
export declare class DetailsHeaderBase extends React.Component<IDetailsHeaderBaseProps, IDetailsHeaderState> implements IDetailsHeader {
static defaultProps: {
selectAllVisibility: SelectAllVisibility;
collapseAllVisibility: CollapseAllVisibility;
useFastIcons: boolean;
};
private _classNames;
private _rootElement;
private _events;
private _rootComponent;
private _id;
private _draggedColumnIndex;
private _dropHintDetails;
private _dragDropHelper;
private _currentDropHintIndex;
private _subscriptionObject?;
private _onDropIndexInfo;
constructor(props: IDetailsHeaderBaseProps);
componentDidMount(): void;
componentDidUpdate(prevProps: IDetailsHeaderBaseProps): void;
componentWillUnmount(): void;
render(): JSXElement;
/** Set focus to the active thing in the focus area. */
focus(): boolean;
/**
* Gets column reorder props from this.props. If the calling code is part of setting up or
* handling drag/drop events, it's safe to assume that this method's return value is defined
* (because drag/drop handling will only be set up if reorder props are given).
*/
private _getColumnReorderProps;
private _getHeaderDragDropOptions;
private _updateDroppingState;
private _isValidCurrentDropHintIndex;
private _onDragOver;
private _onDrop;
private _computeColumnIndexOffset;
/**
* @returns whether or not the "Select All" checkbox column is hidden.
*/
private _isCheckboxColumnHidden;
private _updateDragInfo;
private _resetDropHints;
private _updateDropHintElement;
private _getDropHintPositions;
/**
* Based on the given cursor position, finds the nearest drop hint and updates the state to make it visible
*/
private _computeDropHintToBeShown;
private _isEventOnHeader;
private _renderColumnSizer;
private _renderColumnDivider;
private _renderDropHint;
private _onRenderColumnHeaderTooltip;
/**
* double click on the column sizer will auto ajust column width
* to fit the longest content among current rendered rows.
*
* @param columnIndex - index of the column user double clicked
* @param ev - mouse double click event
*/
private _onSizerDoubleClick;
/**
* Called when the select all toggle is clicked.
*/
private _onSelectAllClicked;
private _onRootMouseDown;
private _onRootMouseMove;
private _onRootKeyDown;
/**
* mouse move event handler in the header
* it will set isSizing state to true when user clicked on the sizer and move the mouse.
*
* @param ev - mouse move event
*/
private _onSizerMouseMove;
private _onSizerBlur;
/**
* mouse up event handler in the header
* clear the resize related state.
* This is to ensure we can catch double click event
*
* @param ev - mouse up event
*/
private _onSizerMouseUp;
private _onSelectionChanged;
private _onToggleCollapseAll;
}
@@ -0,0 +1,636 @@
import { __assign, __extends } from "tslib";
import * as React from 'react';
import { initializeComponentRef, EventGroup, css, getRTL, getId, KeyCodes, classNamesFunction } from '../../Utilities';
import { ColumnDragEndLocation, CheckboxVisibility } from './DetailsList.types';
import { FocusZone, FocusZoneDirection } from '../../FocusZone';
import { Icon, FontIcon } from '../../Icon';
import { Layer } from '../../Layer';
import { GroupSpacer } from '../GroupedList/GroupSpacer';
import { CollapseAllVisibility } from '../../GroupedList';
import { DetailsRowCheck } from './DetailsRowCheck';
import { SelectionMode, SELECTION_CHANGE } from '../../Selection';
import { DragDropHelper } from '../../DragDrop';
import { DetailsColumn } from '../../components/DetailsList/DetailsColumn';
import { SelectAllVisibility } from './DetailsHeader.types';
var getClassNames = classNamesFunction();
var MOUSEDOWN_PRIMARY_BUTTON = 0; // for mouse down event we are using ev.button property, 0 means left button
var MOUSEMOVE_PRIMARY_BUTTON = 1; // for mouse move event we are using ev.buttons property, 1 means left button
var NO_COLUMNS = [];
var DetailsHeaderBase = /** @class */ (function (_super) {
__extends(DetailsHeaderBase, _super);
function DetailsHeaderBase(props) {
var _this = _super.call(this, props) || this;
_this._rootElement = React.createRef();
_this._rootComponent = React.createRef();
_this._draggedColumnIndex = -1;
_this._dropHintDetails = {};
_this._updateDroppingState = function (newValue, event) {
if (_this._draggedColumnIndex >= 0 && event.type !== 'drop' && !newValue) {
_this._resetDropHints();
}
};
_this._onDragOver = function (item, event) {
if (_this._draggedColumnIndex >= 0) {
event.stopPropagation();
_this._computeDropHintToBeShown(event.clientX);
}
};
_this._onDrop = function (item, event) {
// Safe to assume this is defined since we're handling a drop event
var columnReorderProps = _this._getColumnReorderProps();
// Target index will not get changed if draggeditem is after target item.
if (_this._draggedColumnIndex >= 0 && event) {
var targetIndex = _this._draggedColumnIndex > _this._currentDropHintIndex
? _this._currentDropHintIndex
: _this._currentDropHintIndex - 1;
var isValidDrop = _this._isValidCurrentDropHintIndex();
event.stopPropagation();
if (isValidDrop) {
_this._onDropIndexInfo.sourceIndex = _this._draggedColumnIndex;
_this._onDropIndexInfo.targetIndex = targetIndex;
if (columnReorderProps.onColumnDrop) {
var dragDropDetails = {
draggedIndex: _this._draggedColumnIndex,
targetIndex: targetIndex,
};
columnReorderProps.onColumnDrop(dragDropDetails);
/* eslint-disable @typescript-eslint/no-deprecated */
}
else if (columnReorderProps.handleColumnReorder) {
columnReorderProps.handleColumnReorder(_this._draggedColumnIndex, targetIndex);
/* eslint-enable @typescript-eslint/no-deprecated */
}
}
}
_this._resetDropHints();
_this._dropHintDetails = {};
_this._draggedColumnIndex = -1;
};
_this._computeColumnIndexOffset = function (showCheckbox) {
var hasGroupExpander = _this.props.groupNestingDepth && _this.props.groupNestingDepth > 0;
var offset = 1;
if (showCheckbox) {
offset += 1;
}
if (hasGroupExpander) {
offset += 1;
}
return offset;
};
_this._updateDragInfo = function (props, event) {
// Safe to assume this is defined since we're handling a drag event
var columnReorderProps = _this._getColumnReorderProps();
var itemIndex = props.itemIndex;
if (itemIndex >= 0) {
// Column index is set based on the checkbox
_this._draggedColumnIndex = itemIndex - _this._computeColumnIndexOffset(!_this._isCheckboxColumnHidden());
_this._getDropHintPositions();
if (columnReorderProps.onColumnDragStart) {
columnReorderProps.onColumnDragStart(true);
}
}
else if (event && _this._draggedColumnIndex >= 0) {
_this._resetDropHints();
_this._draggedColumnIndex = -1;
_this._dropHintDetails = {};
if (columnReorderProps.onColumnDragEnd) {
var columnDragEndLocation = _this._isEventOnHeader(event);
columnReorderProps.onColumnDragEnd({ dropLocation: columnDragEndLocation }, event);
}
}
};
_this._getDropHintPositions = function () {
var _a = _this.props.columns, columns = _a === void 0 ? NO_COLUMNS : _a;
// Safe to assume this is defined since we're handling a drag/drop event
var columnReorderProps = _this._getColumnReorderProps();
var prevX = 0;
var prevMid = 0;
var prevRef;
var frozenColumnCountFromStart = columnReorderProps.frozenColumnCountFromStart || 0;
var frozenColumnCountFromEnd = columnReorderProps.frozenColumnCountFromEnd || 0;
for (var i = frozenColumnCountFromStart; i < columns.length - frozenColumnCountFromEnd + 1; i++) {
if (_this._rootElement.current) {
var dropHintElement = _this._rootElement.current.querySelectorAll('#columnDropHint_' + i)[0];
if (dropHintElement) {
if (i === frozenColumnCountFromStart) {
prevX = dropHintElement.offsetLeft;
prevMid = dropHintElement.offsetLeft;
prevRef = dropHintElement;
}
else {
var newMid = (dropHintElement.offsetLeft + prevX) / 2;
_this._dropHintDetails[i - 1] = {
originX: prevX,
startX: prevMid,
endX: newMid,
dropHintElementRef: prevRef,
};
prevMid = newMid;
prevRef = dropHintElement;
prevX = dropHintElement.offsetLeft;
if (i === columns.length - frozenColumnCountFromEnd) {
_this._dropHintDetails[i] = {
originX: prevX,
startX: prevMid,
endX: dropHintElement.offsetLeft,
dropHintElementRef: prevRef,
};
}
}
}
}
}
};
/**
* Based on the given cursor position, finds the nearest drop hint and updates the state to make it visible
*/
_this._computeDropHintToBeShown = function (clientX) {
var isRtl = getRTL(_this.props.theme);
if (_this._rootElement.current) {
var clientRect = _this._rootElement.current.getBoundingClientRect();
var headerOriginX = clientRect.left;
var eventXRelativePosition = clientX - headerOriginX;
var currentDropHintIndex = _this._currentDropHintIndex;
if (_this._isValidCurrentDropHintIndex()) {
if (_liesBetween(isRtl, eventXRelativePosition, _this._dropHintDetails[currentDropHintIndex].startX, _this._dropHintDetails[currentDropHintIndex].endX)) {
return;
}
}
var _a = _this.props.columns, columns = _a === void 0 ? NO_COLUMNS : _a;
// Safe to assume this is defined since we're handling a drag/drop event
var columnReorderProps = _this._getColumnReorderProps();
var frozenColumnCountFromStart = columnReorderProps.frozenColumnCountFromStart || 0;
var frozenColumnCountFromEnd = columnReorderProps.frozenColumnCountFromEnd || 0;
var currentIndex = frozenColumnCountFromStart;
var lastValidColumn = columns.length - frozenColumnCountFromEnd;
var indexToUpdate = -1;
if (_isBefore(isRtl, eventXRelativePosition, _this._dropHintDetails[currentIndex].endX)) {
indexToUpdate = currentIndex;
}
else if (_isAfter(isRtl, eventXRelativePosition, _this._dropHintDetails[lastValidColumn].startX)) {
indexToUpdate = lastValidColumn;
}
else if (_this._isValidCurrentDropHintIndex()) {
if (_this._dropHintDetails[currentDropHintIndex + 1] &&
_liesBetween(isRtl, eventXRelativePosition, _this._dropHintDetails[currentDropHintIndex + 1].startX, _this._dropHintDetails[currentDropHintIndex + 1].endX)) {
indexToUpdate = currentDropHintIndex + 1;
}
else if (_this._dropHintDetails[currentDropHintIndex - 1] &&
_liesBetween(isRtl, eventXRelativePosition, _this._dropHintDetails[currentDropHintIndex - 1].startX, _this._dropHintDetails[currentDropHintIndex - 1].endX)) {
indexToUpdate = currentDropHintIndex - 1;
}
}
if (indexToUpdate === -1) {
var startIndex = frozenColumnCountFromStart;
var endIndex = lastValidColumn;
while (startIndex < endIndex) {
var middleIndex = Math.ceil((endIndex + startIndex) / 2);
if (_liesBetween(isRtl, eventXRelativePosition, _this._dropHintDetails[middleIndex].startX, _this._dropHintDetails[middleIndex].endX)) {
indexToUpdate = middleIndex;
break;
}
else if (_isBefore(isRtl, eventXRelativePosition, _this._dropHintDetails[middleIndex].originX)) {
endIndex = middleIndex;
}
else if (_isAfter(isRtl, eventXRelativePosition, _this._dropHintDetails[middleIndex].originX)) {
startIndex = middleIndex;
}
}
}
if (indexToUpdate === _this._draggedColumnIndex || indexToUpdate === _this._draggedColumnIndex + 1) {
if (_this._isValidCurrentDropHintIndex()) {
_this._resetDropHints();
}
}
else if (currentDropHintIndex !== indexToUpdate && indexToUpdate >= 0) {
_this._resetDropHints();
_this._updateDropHintElement(_this._dropHintDetails[indexToUpdate].dropHintElementRef, 'inline-block');
_this._currentDropHintIndex = indexToUpdate;
}
}
};
_this._renderColumnSizer = function (_a) {
var _b;
var columnIndex = _a.columnIndex;
var _c = _this.props.columns, columns = _c === void 0 ? NO_COLUMNS : _c;
var column = columns[columnIndex];
var columnResizeDetails = _this.state.columnResizeDetails;
var classNames = _this._classNames;
return column.isResizable ? (React.createElement("div", { key: "".concat(column.key, "_sizer"), "aria-hidden": true, role: "button", "data-is-focusable": false, onClick: _stopPropagation, "data-sizer-index": columnIndex, onBlur: _this._onSizerBlur, className: css(classNames.cellSizer, columnIndex < columns.length - 1 ? classNames.cellSizerStart : classNames.cellSizerEnd, (_b = {},
_b[classNames.cellIsResizing] = columnResizeDetails && columnResizeDetails.columnIndex === columnIndex,
_b)), onDoubleClick: _this._onSizerDoubleClick.bind(_this, columnIndex) })) : null;
};
_this._onRenderColumnHeaderTooltip = function (tooltipHostProps) {
return React.createElement("span", { className: tooltipHostProps.hostClassName }, tooltipHostProps.children);
};
/**
* Called when the select all toggle is clicked.
*/
_this._onSelectAllClicked = function () {
var selection = _this.props.selection;
if (selection) {
selection.toggleAllSelected();
}
};
_this._onRootMouseDown = function (ev) {
var columnIndexAttr = ev.target.getAttribute('data-sizer-index');
var columnIndex = Number(columnIndexAttr);
var _a = _this.props.columns, columns = _a === void 0 ? NO_COLUMNS : _a;
if (columnIndexAttr === null || ev.button !== MOUSEDOWN_PRIMARY_BUTTON) {
// Ignore anything except the primary button.
return;
}
_this.setState({
columnResizeDetails: {
columnIndex: columnIndex,
columnMinWidth: columns[columnIndex].calculatedWidth,
originX: ev.clientX,
},
});
ev.preventDefault();
ev.stopPropagation();
};
_this._onRootMouseMove = function (ev) {
var _a = _this.state, columnResizeDetails = _a.columnResizeDetails, isSizing = _a.isSizing;
if (columnResizeDetails && !isSizing && ev.clientX !== columnResizeDetails.originX) {
_this.setState({ isSizing: true });
}
};
_this._onRootKeyDown = function (ev) {
var _a = _this.state, columnResizeDetails = _a.columnResizeDetails, isSizing = _a.isSizing;
var _b = _this.props, _c = _b.columns, columns = _c === void 0 ? NO_COLUMNS : _c, onColumnResized = _b.onColumnResized;
var columnIndexAttr = ev.target.getAttribute('data-sizer-index');
if (!columnIndexAttr || isSizing) {
return;
}
var columnIndex = Number(columnIndexAttr);
if (!columnResizeDetails) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
if (ev.which === KeyCodes.enter) {
_this.setState({
columnResizeDetails: {
columnIndex: columnIndex,
columnMinWidth: columns[columnIndex].calculatedWidth,
},
});
ev.preventDefault();
ev.stopPropagation();
}
}
else {
var increment = void 0;
// eslint-disable-next-line @typescript-eslint/no-deprecated
if (ev.which === KeyCodes.enter) {
_this.setState({
columnResizeDetails: undefined,
});
ev.preventDefault();
ev.stopPropagation();
// eslint-disable-next-line @typescript-eslint/no-deprecated
}
else if (ev.which === KeyCodes.left) {
increment = getRTL(_this.props.theme) ? 1 : -1;
// eslint-disable-next-line @typescript-eslint/no-deprecated
}
else if (ev.which === KeyCodes.right) {
increment = getRTL(_this.props.theme) ? -1 : 1;
}
if (increment) {
if (!ev.shiftKey) {
increment *= 10;
}
_this.setState({
columnResizeDetails: __assign(__assign({}, columnResizeDetails), { columnMinWidth: columnResizeDetails.columnMinWidth + increment }),
});
if (onColumnResized) {
onColumnResized(columns[columnIndex], columnResizeDetails.columnMinWidth + increment, columnIndex);
}
ev.preventDefault();
ev.stopPropagation();
}
}
};
/**
* mouse move event handler in the header
* it will set isSizing state to true when user clicked on the sizer and move the mouse.
*
* @param ev - mouse move event
*/
_this._onSizerMouseMove = function (ev) {
var
// use buttons property here since ev.button in some edge case is not upding well during the move.
// but firefox doesn't support it, so we set the default value when it is not defined.
buttons = ev.buttons;
var _a = _this.props, onColumnIsSizingChanged = _a.onColumnIsSizingChanged, onColumnResized = _a.onColumnResized, _b = _a.columns, columns = _b === void 0 ? NO_COLUMNS : _b;
var columnResizeDetails = _this.state.columnResizeDetails;
if (buttons !== undefined && buttons !== MOUSEMOVE_PRIMARY_BUTTON) {
// cancel mouse down event and return early when the primary button is not pressed
_this._onSizerMouseUp(ev);
return;
}
if (ev.clientX !== columnResizeDetails.originX) {
if (onColumnIsSizingChanged) {
onColumnIsSizingChanged(columns[columnResizeDetails.columnIndex], true);
}
}
if (onColumnResized) {
var movement = ev.clientX - columnResizeDetails.originX;
if (getRTL(_this.props.theme)) {
movement = -movement;
}
onColumnResized(columns[columnResizeDetails.columnIndex], columnResizeDetails.columnMinWidth + movement, columnResizeDetails.columnIndex);
}
};
_this._onSizerBlur = function (ev) {
var columnResizeDetails = _this.state.columnResizeDetails;
if (columnResizeDetails) {
_this.setState({
columnResizeDetails: undefined,
isSizing: false,
});
}
};
/**
* mouse up event handler in the header
* clear the resize related state.
* This is to ensure we can catch double click event
*
* @param ev - mouse up event
*/
_this._onSizerMouseUp = function (ev) {
var _a = _this.props, _b = _a.columns, columns = _b === void 0 ? NO_COLUMNS : _b, onColumnIsSizingChanged = _a.onColumnIsSizingChanged;
var columnResizeDetails = _this.state.columnResizeDetails;
_this.setState({
columnResizeDetails: undefined,
isSizing: false,
});
if (onColumnIsSizingChanged) {
onColumnIsSizingChanged(columns[columnResizeDetails.columnIndex], false);
}
};
_this._onToggleCollapseAll = function () {
var onToggleCollapseAll = _this.props.onToggleCollapseAll;
var newCollapsed = !_this.state.isAllCollapsed;
_this.setState({
isAllCollapsed: newCollapsed,
});
if (onToggleCollapseAll) {
onToggleCollapseAll(newCollapsed);
}
};
initializeComponentRef(_this);
_this._events = new EventGroup(_this);
_this.state = {
columnResizeDetails: undefined,
isAllCollapsed: _this.props.isAllCollapsed,
isAllSelected: !!_this.props.selection && _this.props.selection.isAllSelected(),
};
_this._onDropIndexInfo = {
sourceIndex: -1,
targetIndex: -1,
};
_this._id = getId('header');
_this._currentDropHintIndex = -1;
// The drag drop handler won't do any work until subscribe() is called,
// so always set it up for convenience
_this._dragDropHelper = new DragDropHelper({
selection: {
getSelection: function () {
return;
},
},
minimumPixelsForDrag: _this.props.minimumPixelsForDrag,
});
return _this;
}
DetailsHeaderBase.prototype.componentDidMount = function () {
var selection = this.props.selection;
this._events.on(selection, SELECTION_CHANGE, this._onSelectionChanged);
// this._rootElement.current will be null in tests using react-test-renderer
if (this._rootElement.current) {
// We need to use native on this to prevent MarqueeSelection from handling the event before us.
this._events.on(this._rootElement.current, 'mousedown', this._onRootMouseDown);
this._events.on(this._rootElement.current, 'keydown', this._onRootKeyDown);
if (this._getColumnReorderProps()) {
this._subscriptionObject = this._dragDropHelper.subscribe(this._rootElement.current, this._events, this._getHeaderDragDropOptions());
}
}
};
DetailsHeaderBase.prototype.componentDidUpdate = function (prevProps) {
if (this._getColumnReorderProps()) {
if (!this._subscriptionObject && this._rootElement.current) {
this._subscriptionObject = this._dragDropHelper.subscribe(this._rootElement.current, this._events, this._getHeaderDragDropOptions());
}
}
else if (this._subscriptionObject) {
this._subscriptionObject.dispose();
delete this._subscriptionObject;
}
if (this.props !== prevProps && this._onDropIndexInfo.sourceIndex >= 0 && this._onDropIndexInfo.targetIndex >= 0) {
var _a = prevProps.columns, previousColumns = _a === void 0 ? NO_COLUMNS : _a;
var _b = this.props.columns, columns = _b === void 0 ? NO_COLUMNS : _b;
if (previousColumns[this._onDropIndexInfo.sourceIndex].key === columns[this._onDropIndexInfo.targetIndex].key) {
this._onDropIndexInfo = {
sourceIndex: -1,
targetIndex: -1,
};
}
}
if (this.props.isAllCollapsed !== prevProps.isAllCollapsed) {
this.setState({ isAllCollapsed: this.props.isAllCollapsed });
}
};
DetailsHeaderBase.prototype.componentWillUnmount = function () {
if (this._subscriptionObject) {
this._subscriptionObject.dispose();
delete this._subscriptionObject;
}
this._dragDropHelper.dispose();
this._events.dispose();
};
DetailsHeaderBase.prototype.render = function () {
var _this = this;
var _a = this.props, _b = _a.columns, columns = _b === void 0 ? NO_COLUMNS : _b, ariaLabel = _a.ariaLabel, ariaLabelForToggleAllGroupsButton = _a.ariaLabelForToggleAllGroupsButton, ariaLabelForSelectAllCheckbox = _a.ariaLabelForSelectAllCheckbox, selectAllVisibility = _a.selectAllVisibility, ariaLabelForSelectionColumn = _a.ariaLabelForSelectionColumn, indentWidth = _a.indentWidth, onColumnClick = _a.onColumnClick, onColumnContextMenu = _a.onColumnContextMenu, _c = _a.onRenderColumnHeaderTooltip, onRenderColumnHeaderTooltip = _c === void 0 ? this._onRenderColumnHeaderTooltip : _c, styles = _a.styles, selectionMode = _a.selectionMode, theme = _a.theme, onRenderDetailsCheckbox = _a.onRenderDetailsCheckbox, groupNestingDepth = _a.groupNestingDepth, useFastIcons = _a.useFastIcons, checkboxVisibility = _a.checkboxVisibility, className = _a.className;
var _d = this.state, isAllSelected = _d.isAllSelected, columnResizeDetails = _d.columnResizeDetails, isSizing = _d.isSizing, isAllCollapsed = _d.isAllCollapsed;
var showCheckbox = selectAllVisibility !== SelectAllVisibility.none;
var isCheckboxHidden = selectAllVisibility === SelectAllVisibility.hidden;
var isCheckboxAlwaysVisible = checkboxVisibility === CheckboxVisibility.always;
var columnReorderProps = this._getColumnReorderProps();
var frozenColumnCountFromStart = columnReorderProps && columnReorderProps.frozenColumnCountFromStart
? columnReorderProps.frozenColumnCountFromStart
: 0;
var frozenColumnCountFromEnd = columnReorderProps && columnReorderProps.frozenColumnCountFromEnd
? columnReorderProps.frozenColumnCountFromEnd
: 0;
this._classNames = getClassNames(styles, {
theme: theme,
isAllSelected: isAllSelected,
isSelectAllHidden: selectAllVisibility === SelectAllVisibility.hidden,
isResizingColumn: !!columnResizeDetails && isSizing,
isSizing: isSizing,
isAllCollapsed: isAllCollapsed,
isCheckboxHidden: isCheckboxHidden,
className: className,
});
var classNames = this._classNames;
var IconComponent = useFastIcons ? FontIcon : Icon;
var hasGroupExpander = groupNestingDepth > 0;
var showGroupExpander = hasGroupExpander && this.props.collapseAllVisibility === CollapseAllVisibility.visible;
var columnIndexOffset = this._computeColumnIndexOffset(showCheckbox);
var isRTL = getRTL(theme);
return (React.createElement(FocusZone, { role: "row", "aria-label": ariaLabel, className: classNames.root, componentRef: this._rootComponent,
// eslint-disable-next-line @typescript-eslint/no-deprecated
elementRef: this._rootElement, onMouseMove: this._onRootMouseMove, "data-automationid": "DetailsHeader", direction: FocusZoneDirection.horizontal },
showCheckbox
? [
React.createElement("div", { key: "__checkbox", className: classNames.cellIsCheck, "aria-labelledby": "".concat(this._id, "-checkTooltip"), onClick: !isCheckboxHidden ? this._onSelectAllClicked : undefined, role: 'columnheader' }, onRenderColumnHeaderTooltip({
hostClassName: classNames.checkTooltip,
id: "".concat(this._id, "-checkTooltip"),
setAriaDescribedBy: false,
content: ariaLabelForSelectAllCheckbox,
children: (React.createElement(DetailsRowCheck, { id: "".concat(this._id, "-check"), "aria-label": selectionMode === SelectionMode.multiple
? ariaLabelForSelectAllCheckbox
: ariaLabelForSelectionColumn, "data-is-focusable": !isCheckboxHidden || undefined, isHeader: true, selected: isAllSelected, anySelected: false, canSelect: !isCheckboxHidden, className: classNames.check, onRenderDetailsCheckbox: onRenderDetailsCheckbox, useFastIcons: useFastIcons, isVisible: isCheckboxAlwaysVisible })),
}, this._onRenderColumnHeaderTooltip)),
!this.props.onRenderColumnHeaderTooltip ? (ariaLabelForSelectAllCheckbox && !isCheckboxHidden ? (React.createElement("label", { key: "__checkboxLabel", id: "".concat(this._id, "-checkTooltip"), className: classNames.accessibleLabel, "aria-hidden": true }, ariaLabelForSelectAllCheckbox)) : ariaLabelForSelectionColumn && isCheckboxHidden ? (React.createElement("label", { key: "__checkboxLabel", id: "".concat(this._id, "-checkTooltip"), className: classNames.accessibleLabel, "aria-hidden": true }, ariaLabelForSelectionColumn)) : null) : null,
]
: null,
showGroupExpander ? (React.createElement("div", { className: classNames.cellIsGroupExpander, onClick: this._onToggleCollapseAll, "data-is-focusable": true, "aria-label": ariaLabelForToggleAllGroupsButton, "aria-expanded": !isAllCollapsed, role: "columnheader" },
React.createElement(IconComponent, { className: classNames.collapseButton, iconName: isRTL ? 'ChevronLeftMed' : 'ChevronRightMed' }),
React.createElement("span", { className: classNames.accessibleLabel }, ariaLabelForToggleAllGroupsButton))) : hasGroupExpander ? (React.createElement("div", { className: classNames.cellIsGroupExpander, "data-is-focusable": false, role: "columnheader" })) : null,
React.createElement(GroupSpacer, { indentWidth: indentWidth, role: "gridcell", count: groupNestingDepth - 1 }),
columns.map(function (column, columnIndex) {
var _isDraggable = columnReorderProps
? columnIndex >= frozenColumnCountFromStart && columnIndex < columns.length - frozenColumnCountFromEnd
: false;
return [
columnReorderProps &&
(_isDraggable || columnIndex === columns.length - frozenColumnCountFromEnd) &&
_this._renderDropHint(columnIndex),
React.createElement(DetailsColumn, { column: column, styles: column.styles, key: column.key, columnIndex: columnIndexOffset + columnIndex, parentId: _this._id, isDraggable: _isDraggable, updateDragInfo: _this._updateDragInfo, dragDropHelper: _this._dragDropHelper, onColumnClick: onColumnClick, onColumnContextMenu: onColumnContextMenu,
// Do not render tooltips by default, but allow for override via props.
onRenderColumnHeaderTooltip: _this.props.onRenderColumnHeaderTooltip, isDropped: _this._onDropIndexInfo.targetIndex === columnIndex, cellStyleProps: _this.props.cellStyleProps, useFastIcons: useFastIcons }),
_this._renderColumnDivider(columnIndex),
];
}),
columnReorderProps && frozenColumnCountFromEnd === 0 && this._renderDropHint(columns.length),
isSizing && (React.createElement(Layer, null,
React.createElement("div", { className: classNames.sizingOverlay, onMouseMove: this._onSizerMouseMove, onMouseUp: this._onSizerMouseUp })))));
};
/** Set focus to the active thing in the focus area. */
DetailsHeaderBase.prototype.focus = function () {
var _a;
return !!((_a = this._rootComponent.current) === null || _a === void 0 ? void 0 : _a.focus());
};
/**
* Gets column reorder props from this.props. If the calling code is part of setting up or
* handling drag/drop events, it's safe to assume that this method's return value is defined
* (because drag/drop handling will only be set up if reorder props are given).
*/
DetailsHeaderBase.prototype._getColumnReorderProps = function () {
var _a = this.props, columnReorderOptions = _a.columnReorderOptions, columnReorderProps = _a.columnReorderProps;
return columnReorderProps || (columnReorderOptions && __assign(__assign({}, columnReorderOptions), { onColumnDragEnd: undefined }));
};
DetailsHeaderBase.prototype._getHeaderDragDropOptions = function () {
var options = {
selectionIndex: 1,
context: { data: this, index: 0 },
canDrag: function () { return false; },
canDrop: function () { return true; },
onDragStart: function () { return undefined; },
updateDropState: this._updateDroppingState,
onDrop: this._onDrop,
onDragEnd: function () { return undefined; },
onDragOver: this._onDragOver,
};
return options;
};
DetailsHeaderBase.prototype._isValidCurrentDropHintIndex = function () {
return this._currentDropHintIndex >= 0;
};
/**
* @returns whether or not the "Select All" checkbox column is hidden.
*/
DetailsHeaderBase.prototype._isCheckboxColumnHidden = function () {
var _a = this.props, selectionMode = _a.selectionMode, checkboxVisibility = _a.checkboxVisibility;
return selectionMode === SelectionMode.none || checkboxVisibility === CheckboxVisibility.hidden;
};
DetailsHeaderBase.prototype._resetDropHints = function () {
if (this._currentDropHintIndex >= 0) {
this._updateDropHintElement(this._dropHintDetails[this._currentDropHintIndex].dropHintElementRef, 'none');
this._currentDropHintIndex = -1;
}
};
DetailsHeaderBase.prototype._updateDropHintElement = function (element, displayProperty) {
element.childNodes[1].style.display = displayProperty;
element.childNodes[0].style.display = displayProperty;
};
DetailsHeaderBase.prototype._isEventOnHeader = function (event) {
if (this._rootElement.current) {
var clientRect = this._rootElement.current.getBoundingClientRect();
if (event.clientX > clientRect.left &&
event.clientX < clientRect.right &&
event.clientY > clientRect.top &&
event.clientY < clientRect.bottom) {
return ColumnDragEndLocation.header;
}
}
};
DetailsHeaderBase.prototype._renderColumnDivider = function (columnIndex) {
var _a = this.props.columns, columns = _a === void 0 ? NO_COLUMNS : _a;
var column = columns[columnIndex];
var onRenderDivider = column.onRenderDivider;
return onRenderDivider
? onRenderDivider({ column: column, columnIndex: columnIndex }, this._renderColumnSizer)
: this._renderColumnSizer({ column: column, columnIndex: columnIndex });
};
DetailsHeaderBase.prototype._renderDropHint = function (dropHintIndex) {
var classNames = this._classNames;
var IconComponent = this.props.useFastIcons ? FontIcon : Icon;
return (React.createElement("div", { key: 'dropHintKey', className: classNames.dropHintStyle, id: "columnDropHint_".concat(dropHintIndex), "aria-hidden": true },
React.createElement("div", { role: "presentation", key: "dropHintCircleKey", className: classNames.dropHintCaretStyle, "data-is-focusable": false, "data-sizer-index": dropHintIndex, "aria-hidden": true },
React.createElement(IconComponent, { iconName: 'CircleShapeSolid' })),
React.createElement("div", { key: "dropHintLineKey", "aria-hidden": true, "data-is-focusable": false, "data-sizer-index": dropHintIndex, className: classNames.dropHintLineStyle })));
};
/**
* double click on the column sizer will auto ajust column width
* to fit the longest content among current rendered rows.
*
* @param columnIndex - index of the column user double clicked
* @param ev - mouse double click event
*/
DetailsHeaderBase.prototype._onSizerDoubleClick = function (columnIndex, ev) {
var _a = this.props, onColumnAutoResized = _a.onColumnAutoResized, _b = _a.columns, columns = _b === void 0 ? NO_COLUMNS : _b;
if (onColumnAutoResized) {
onColumnAutoResized(columns[columnIndex], columnIndex);
}
};
DetailsHeaderBase.prototype._onSelectionChanged = function () {
var isAllSelected = !!this.props.selection && this.props.selection.isAllSelected();
if (this.state.isAllSelected !== isAllSelected) {
this.setState({
isAllSelected: isAllSelected,
});
}
};
DetailsHeaderBase.defaultProps = {
selectAllVisibility: SelectAllVisibility.visible,
collapseAllVisibility: CollapseAllVisibility.visible,
useFastIcons: true,
};
return DetailsHeaderBase;
}(React.Component));
export { DetailsHeaderBase };
function _liesBetween(rtl, target, left, right) {
return rtl ? target <= left && target >= right : target >= left && target <= right;
}
function _isBefore(rtl, a, b) {
return rtl ? a >= b : a <= b;
}
function _isAfter(rtl, a, b) {
return rtl ? a <= b : a >= b;
}
function _stopPropagation(ev) {
ev.stopPropagation();
}
//# sourceMappingURL=DetailsHeader.base.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
import * as React from 'react';
import type { IDetailsHeaderProps, IDetailsHeaderBaseProps } from './DetailsHeader.types';
export declare const DetailsHeader: React.FunctionComponent<IDetailsHeaderBaseProps>;
export type { IDetailsHeaderProps, IDetailsHeaderBaseProps };
@@ -0,0 +1,5 @@
import { styled } from '../../Utilities';
import { DetailsHeaderBase } from './DetailsHeader.base';
import { getDetailsHeaderStyles } from './DetailsHeader.styles';
export var DetailsHeader = styled(DetailsHeaderBase, getDetailsHeaderStyles, undefined, { scope: 'DetailsHeader' });
//# sourceMappingURL=DetailsHeader.js.map
@@ -0,0 +1 @@
{"version":3,"file":"DetailsHeader.js","sourceRoot":"../src/","sources":["components/DetailsList/DetailsHeader.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAQhE,MAAM,CAAC,IAAM,aAAa,GAAqD,MAAM,CAInF,iBAAiB,EAAE,sBAAsB,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC","sourcesContent":["import * as React from 'react';\nimport { styled } from '../../Utilities';\nimport { DetailsHeaderBase } from './DetailsHeader.base';\nimport { getDetailsHeaderStyles } from './DetailsHeader.styles';\nimport type {\n IDetailsHeaderProps,\n IDetailsHeaderBaseProps,\n IDetailsHeaderStyleProps,\n IDetailsHeaderStyles,\n} from './DetailsHeader.types';\n\nexport const DetailsHeader: React.FunctionComponent<IDetailsHeaderBaseProps> = styled<\n IDetailsHeaderBaseProps,\n IDetailsHeaderStyleProps,\n IDetailsHeaderStyles\n>(DetailsHeaderBase, getDetailsHeaderStyles, undefined, { scope: 'DetailsHeader' });\n\nexport type { IDetailsHeaderProps, IDetailsHeaderBaseProps };\n"]}
@@ -0,0 +1,9 @@
import type { IDetailsHeaderStyleProps, IDetailsHeaderStyles } from './DetailsHeader.types';
import type { IStyle, ITheme } from '../../Styling';
import type { ICellStyleProps } from './DetailsRow.types';
export declare const HEADER_HEIGHT = 42;
export declare const getCellStyles: (props: {
theme: ITheme;
cellStyleProps?: ICellStyleProps;
}) => IStyle;
export declare const getDetailsHeaderStyles: (props: IDetailsHeaderStyleProps) => IDetailsHeaderStyles;
@@ -0,0 +1,294 @@
import { __assign } from "tslib";
import { getFocusStyle, focusClear, getGlobalClassNames, HighContrastSelector, hiddenContentStyle, getHighContrastNoAdjustStyle, } from '../../Styling';
import { getRTL, IsFocusVisibleClassName } from '../../Utilities';
import { DEFAULT_CELL_STYLE_PROPS } from './DetailsRow.styles';
// For every group level there is a GroupSpacer added. Importing this const to have the source value in one place.
import { SPACER_WIDTH as GROUP_EXPANDER_WIDTH } from '../GroupedList/GroupSpacer';
var GlobalClassNames = {
tooltipHost: 'ms-TooltipHost',
root: 'ms-DetailsHeader',
cell: 'ms-DetailsHeader-cell',
cellIsCheck: 'ms-DetailsHeader-cellIsCheck',
collapseButton: 'ms-DetailsHeader-collapseButton',
isCollapsed: 'is-collapsed',
isAllSelected: 'is-allSelected',
isSelectAllHidden: 'is-selectAllHidden',
isResizingColumn: 'is-resizingColumn',
cellSizer: 'ms-DetailsHeader-cellSizer',
isResizing: 'is-resizing',
dropHintCircleStyle: 'ms-DetailsHeader-dropHintCircleStyle',
dropHintCaretStyle: 'ms-DetailsHeader-dropHintCaretStyle',
dropHintLineStyle: 'ms-DetailsHeader-dropHintLineStyle',
cellTitle: 'ms-DetailsHeader-cellTitle',
cellName: 'ms-DetailsHeader-cellName',
filterChevron: 'ms-DetailsHeader-filterChevron',
gripperBarVertical: 'ms-DetailsColumn-gripperBarVertical',
checkTooltip: 'ms-DetailsHeader-checkTooltip',
check: 'ms-DetailsHeader-check',
};
export var HEADER_HEIGHT = 42;
export var getCellStyles = function (props) {
var theme = props.theme, _a = props.cellStyleProps, cellStyleProps = _a === void 0 ? DEFAULT_CELL_STYLE_PROPS : _a;
var semanticColors = theme.semanticColors;
var classNames = getGlobalClassNames(GlobalClassNames, theme);
return [
classNames.cell,
getFocusStyle(theme),
{
color: semanticColors.bodyText,
position: 'relative',
display: 'inline-block',
boxSizing: 'border-box',
padding: "0 ".concat(cellStyleProps.cellRightPadding, "px 0 ").concat(cellStyleProps.cellLeftPadding, "px"),
lineHeight: 'inherit',
margin: '0',
height: HEADER_HEIGHT,
verticalAlign: 'top',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
textAlign: 'left',
},
];
};
export var getDetailsHeaderStyles = function (props) {
var _a, _b, _c, _d;
var theme = props.theme, className = props.className, isAllSelected = props.isAllSelected, isResizingColumn = props.isResizingColumn, isSizing = props.isSizing, isAllCollapsed = props.isAllCollapsed, _e = props.cellStyleProps, cellStyleProps = _e === void 0 ? DEFAULT_CELL_STYLE_PROPS : _e;
var semanticColors = theme.semanticColors, palette = theme.palette, fonts = theme.fonts;
var classNames = getGlobalClassNames(GlobalClassNames, theme);
var colors = {
iconForegroundColor: semanticColors.bodySubtext,
headerForegroundColor: semanticColors.bodyText,
headerBackgroundColor: semanticColors.bodyBackground,
resizerColor: palette.neutralTertiaryAlt,
};
var cellSizerFadeInStyles = {
opacity: 1,
transition: 'opacity 0.3s linear',
};
var cellStyles = getCellStyles(props);
return {
root: [
classNames.root,
fonts.small,
{
display: 'inline-block',
background: colors.headerBackgroundColor,
position: 'relative',
minWidth: '100%',
verticalAlign: 'top',
height: HEADER_HEIGHT,
lineHeight: HEADER_HEIGHT,
whiteSpace: 'nowrap',
boxSizing: 'content-box',
paddingBottom: '1px',
paddingTop: '16px',
borderBottom: "1px solid ".concat(semanticColors.bodyDivider),
cursor: 'default',
userSelect: 'none',
selectors: (_a = {},
_a["&:hover .".concat(classNames.check)] = {
opacity: 1,
},
_a["& .".concat(classNames.tooltipHost, " .").concat(classNames.checkTooltip)] = {
display: 'block',
},
_a),
},
isAllSelected && classNames.isAllSelected,
isResizingColumn && classNames.isResizingColumn,
className,
],
check: [
classNames.check,
{
height: HEADER_HEIGHT,
},
{
selectors: (_b = {},
_b[".".concat(IsFocusVisibleClassName, " &:focus, :host(.").concat(IsFocusVisibleClassName, ") &:focus")] = {
opacity: 1,
},
_b),
},
],
cellWrapperPadded: {
paddingRight: cellStyleProps.cellExtraRightPadding + cellStyleProps.cellRightPadding,
},
cellIsCheck: [
cellStyles,
classNames.cellIsCheck,
{
position: 'relative',
padding: 0,
margin: 0,
display: 'inline-flex',
alignItems: 'center',
border: 'none',
},
isAllSelected && {
opacity: 1,
},
],
cellIsGroupExpander: [
cellStyles,
{
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: fonts.small.fontSize,
padding: 0,
border: 'none',
width: GROUP_EXPANDER_WIDTH, // align with GroupedList's first expandIcon cell width.
color: palette.neutralSecondary,
selectors: {
':hover': {
backgroundColor: palette.neutralLighter,
},
':active': {
backgroundColor: palette.neutralLight,
},
},
},
],
cellIsActionable: {
selectors: {
':hover': {
color: semanticColors.bodyText,
background: semanticColors.listHeaderBackgroundHovered,
},
':active': {
background: semanticColors.listHeaderBackgroundPressed,
},
},
},
cellIsEmpty: {
textOverflow: 'clip',
},
cellSizer: [
classNames.cellSizer,
focusClear(),
{
display: 'inline-block',
position: 'relative',
cursor: 'ew-resize',
bottom: 0,
top: 0,
overflow: 'hidden',
height: 'inherit',
background: 'transparent',
zIndex: 1,
width: 16,
selectors: (_c = {
':after': {
content: '""',
position: 'absolute',
top: 0,
bottom: 0,
width: 1,
background: colors.resizerColor,
opacity: 0,
left: '50%',
},
':focus:after': cellSizerFadeInStyles,
':hover:after': cellSizerFadeInStyles
},
_c["&.".concat(classNames.isResizing, ":after")] = [
cellSizerFadeInStyles,
{
boxShadow: '0 0 5px 0 rgba(0, 0, 0, 0.4)',
},
],
_c),
},
],
cellIsResizing: classNames.isResizing,
cellSizerStart: {
margin: '0 -8px',
},
cellSizerEnd: {
margin: 0,
marginLeft: -16,
},
collapseButton: [
classNames.collapseButton,
{
transformOrigin: '50% 50%',
transition: 'transform .1s linear',
},
isAllCollapsed
? [
classNames.isCollapsed,
{
transform: 'rotate(0deg)',
},
]
: {
transform: getRTL(theme) ? 'rotate(-90deg)' : 'rotate(90deg)',
},
],
checkTooltip: classNames.checkTooltip,
sizingOverlay: isSizing && {
position: 'absolute',
left: 0,
top: 0,
right: 0,
bottom: 0,
cursor: 'ew-resize',
background: 'rgba(255, 255, 255, 0)',
selectors: (_d = {},
_d[HighContrastSelector] = __assign({ background: 'transparent' }, getHighContrastNoAdjustStyle()),
_d),
},
accessibleLabel: hiddenContentStyle,
dropHintCircleStyle: [
classNames.dropHintCircleStyle,
{
display: 'inline-block',
visibility: 'hidden',
position: 'absolute',
bottom: 0,
height: 9,
width: 9,
borderRadius: '50%',
marginLeft: -5,
top: 34,
overflow: 'visible',
zIndex: 10,
border: "1px solid ".concat(palette.themePrimary),
background: palette.white,
},
],
dropHintCaretStyle: [
classNames.dropHintCaretStyle,
{
display: 'none',
position: 'absolute',
top: -28,
left: -6.5,
fontSize: fonts.medium.fontSize,
color: palette.themePrimary,
overflow: 'visible',
zIndex: 10,
},
],
dropHintLineStyle: [
classNames.dropHintLineStyle,
{
display: 'none',
position: 'absolute',
bottom: 0,
top: 0,
overflow: 'hidden',
height: 42,
width: 1,
background: palette.themePrimary,
zIndex: 10,
},
],
dropHintStyle: {
display: 'inline-block',
position: 'absolute',
},
};
};
//# sourceMappingURL=DetailsHeader.styles.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,190 @@
import * as React from 'react';
import { CollapseAllVisibility } from '../../GroupedList';
import { DetailsHeaderBase } from './DetailsHeader.base';
import { DetailsListLayoutMode, ColumnDragEndLocation } from './DetailsList.types';
import { SelectionMode } from '../../Selection';
import type { IRefObject, IRenderFunction, IStyleFunctionOrObject } from '../../Utilities';
import type { ITheme, IStyle } from '../../Styling';
import type { IColumn, IColumnReorderOptions } from './DetailsList.types';
import type { ICellStyleProps, IDetailsItemProps } from './DetailsRow.types';
import type { ISelection } from '../../Selection';
import type { IDetailsCheckboxProps } from './DetailsRowCheck.types';
import type { IDetailsColumnRenderTooltipProps } from './DetailsColumn.types';
/**
* {@docCategory DetailsList}
*/
export interface IDetailsHeader {
/** sets focus into the header */
focus: () => boolean;
}
/**
* {@docCategory DetailsList}
*/
export interface IDetailsHeaderBaseProps extends React.ClassAttributes<DetailsHeaderBase>, IDetailsItemProps {
/** Theme from the Higher Order Component */
theme?: ITheme;
/** Call to provide customized styling that will layer on top of the variant rules. */
styles?: IStyleFunctionOrObject<IDetailsHeaderStyleProps, IDetailsHeaderStyles>;
/** Ref to the component itself */
componentRef?: IRefObject<IDetailsHeader>;
/** Layout mode - fixedColumns or justified */
layoutMode: DetailsListLayoutMode;
/** Callback for when column sizing has changed */
onColumnIsSizingChanged?: (column: IColumn, isSizing: boolean) => void;
/** Callback for when column is resized */
onColumnResized?: (column: IColumn, newWidth: number, columnIndex: number) => void;
/** Callback for when column is automatically resized */
onColumnAutoResized?: (column: IColumn, columnIndex: number) => void;
/** Callback for when the column is clicked */
onColumnClick?: (ev: React.MouseEvent<HTMLElement>, column: IColumn) => void;
/** Callback for when the column needs to show a context menu */
onColumnContextMenu?: (column: IColumn, ev: React.MouseEvent<HTMLElement>) => void;
/** Callback to render a tooltip for the column header */
onRenderColumnHeaderTooltip?: IRenderFunction<IDetailsColumnRenderTooltipProps>;
/** Whether to collapse for all visibility */
collapseAllVisibility?: CollapseAllVisibility;
/** Whether or not all is collapsed */
isAllCollapsed?: boolean;
/** Callback for when collapse all is toggled */
onToggleCollapseAll?: (isAllCollapsed: boolean) => void;
/** ariaLabel for the entire header */
ariaLabel?: string;
/** ariaLabel for expand/collapse group button */
ariaLabelForToggleAllGroupsButton?: string;
/** ariaLabel for the header checkbox that selects or deselects everything */
ariaLabelForSelectAllCheckbox?: string;
/** ariaLabel for the selection column */
ariaLabelForSelectionColumn?: string;
/** Select all button visibility */
selectAllVisibility?: SelectAllVisibility;
/** Column reordering options */
columnReorderOptions?: IColumnReorderOptions;
/** Column reordering options */
columnReorderProps?: IColumnReorderHeaderProps;
/** Minimum pixels to be moved before dragging is registered */
minimumPixelsForDrag?: number;
/** Overriding class name */
className?: string;
/** If provided, can be used to render a custom checkbox */
onRenderDetailsCheckbox?: IRenderFunction<IDetailsCheckboxProps>;
/**
* Whether to use fast icon and check components. The icons can't be targeted by customization
* but are still customizable via class names.
* @defaultvalue true
*/
useFastIcons?: boolean;
}
/**
* {@docCategory DetailsList}
*/
export interface IDetailsHeaderProps extends IDetailsHeaderBaseProps {
/**
* Column metadata
*/
columns: IColumn[];
/**
* Selection from utilities
*/
selection: ISelection;
/**
* Selection mode
*/
selectionMode: SelectionMode;
}
/**
* {@docCategory DetailsList}
*/
export declare enum SelectAllVisibility {
none = 0,
hidden = 1,
visible = 2
}
/**
* {@docCategory DetailsList}
*/
export interface IDetailsHeaderState {
columnResizeDetails?: IColumnResizeDetails;
isAllSelected?: boolean;
isSizing?: boolean;
isAllCollapsed?: boolean;
}
/**
* {@docCategory DetailsList}
*/
export interface IColumnResizeDetails {
columnIndex: number;
originX?: number;
columnMinWidth: number;
}
/**
* {@docCategory DetailsList}
*/
export interface IColumnReorderHeaderProps extends IColumnReorderOptions {
/** Callback to notify the column dragEnd event to List
* Need this to check whether the dragEnd has happened on
* corresponding list or outside of the list
*/
onColumnDragEnd?: (props: {
dropLocation?: ColumnDragEndLocation;
}, event: MouseEvent) => void;
}
/**
* {@docCategory DetailsList}
*/
export interface IDropHintDetails {
originX: number;
startX: number;
endX: number;
dropHintElementRef: HTMLElement;
}
/**
* {@docCategory DetailsList}
*/
export type IDetailsHeaderStyleProps = Required<Pick<IDetailsHeaderProps, 'theme'>> & Pick<IDetailsHeaderProps, 'className'> & {
/** Whether to hide select all checkbox */
isSelectAllHidden?: boolean;
/** Whether the "select all" checkbox is checked */
isAllSelected?: boolean;
/** Is column being resized */
isResizingColumn?: boolean;
/** Are all columns collapsed */
isAllCollapsed?: boolean;
/** Whether the header is sizing */
isSizing?: boolean;
/** Whether checkbox is hidden */
isCheckboxHidden?: boolean;
cellStyleProps?: ICellStyleProps;
};
/**
* {@docCategory DetailsList}
*/
export interface IDetailsHeaderStyles {
root: IStyle;
check: IStyle;
/**
* @deprecated Not used
*/
cellWrapperPadded: IStyle;
cellIsCheck: IStyle;
/**
* @deprecated Not used
*/
cellIsActionable: IStyle;
/**
* @deprecated Not used
*/
cellIsEmpty: IStyle;
cellSizer: IStyle;
cellSizerStart: IStyle;
cellSizerEnd: IStyle;
cellIsResizing: IStyle;
cellIsGroupExpander: IStyle;
collapseButton: IStyle;
checkTooltip: IStyle;
sizingOverlay: IStyle;
dropHintCircleStyle: IStyle;
dropHintCaretStyle: IStyle;
dropHintLineStyle: IStyle;
dropHintStyle: IStyle;
accessibleLabel: IStyle;
}
@@ -0,0 +1,10 @@
/**
* {@docCategory DetailsList}
*/
export var SelectAllVisibility;
(function (SelectAllVisibility) {
SelectAllVisibility[SelectAllVisibility["none"] = 0] = "none";
SelectAllVisibility[SelectAllVisibility["hidden"] = 1] = "hidden";
SelectAllVisibility[SelectAllVisibility["visible"] = 2] = "visible";
})(SelectAllVisibility || (SelectAllVisibility = {}));
//# sourceMappingURL=DetailsHeader.types.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,104 @@
import * as React from 'react';
import { CheckboxVisibility, ColumnActionsMode, ConstrainMode, DetailsListLayoutMode } from '../DetailsList/DetailsList.types';
import { SelectionMode } from '../../Selection';
import { ScrollToMode } from '../../List';
import type { IRenderFunction } from '../../Utilities';
import type { IColumn, IDetailsList, IDetailsListProps } from '../DetailsList/DetailsList.types';
import type { IDetailsRowProps } from '../DetailsList/DetailsRow.types';
import type { JSXElement } from '@fluentui/utilities';
export interface IDetailsListState {
focusedItemIndex: number;
lastWidth?: number;
lastSelectionMode?: SelectionMode;
adjustedColumns: IColumn[];
isCollapsed?: boolean;
isSizing?: boolean;
isSomeGroupExpanded?: boolean;
/**
* A unique object used to force-update the List when it changes.
*/
version: {};
getDerivedStateFromProps(nextProps: IDetailsListProps, previousState: IDetailsListState): IDetailsListState;
}
export declare class DetailsListBase extends React.Component<IDetailsListProps, IDetailsListState> implements IDetailsList {
static defaultProps: {
layoutMode: DetailsListLayoutMode;
selectionMode: SelectionMode;
constrainMode: ConstrainMode;
checkboxVisibility: CheckboxVisibility;
isHeaderVisible: boolean;
compact: boolean;
useFastIcons: boolean;
};
static contextType: React.Context<import("@fluentui/react-window-provider").WindowProviderProps>;
context: any;
private _async;
private _root;
private _header;
private _groupedList;
private _list;
private _focusZone;
private _selectionZone;
private _selection;
private _activeRows;
private _dragDropHelper;
private _initialFocusedIndex;
private _columnOverrides;
static getDerivedStateFromProps(nextProps: IDetailsListProps, previousState: IDetailsListState): IDetailsListState;
constructor(props: IDetailsListProps);
scrollToIndex(index: number, measureItem?: (itemIndex: number) => number, scrollToMode?: ScrollToMode): void;
focusIndex(index: number, forceIntoFirstElement?: boolean, measureItem?: (itemIndex: number) => number, scrollToMode?: ScrollToMode): void;
getStartItemIndexInView(): number;
updateColumn(column: IColumn, options: {
width?: number;
newColumnIndex?: number;
}): void;
componentWillUnmount(): void;
componentDidUpdate(prevProps: IDetailsListProps, prevState: IDetailsListState): void;
render(): JSXElement;
forceUpdate(): void;
protected _onRenderRow: (props: IDetailsRowProps, defaultRender?: IRenderFunction<IDetailsRowProps>) => JSXElement;
private _getDerivedStateFromProps;
private _onGroupExpandStateChanged;
private _onColumnIsSizingChanged;
private _getGroupNestingDepth;
private _onRowDidMount;
private _setFocusToRowIfPending;
private _setFocusToRow;
private _onRowWillUnmount;
private _onToggleCollapse;
private _forceListUpdates;
private _notifyColumnsResized;
private _adjustColumns;
/** Returns adjusted columns, given the viewport size and layout mode. */
private _getAdjustedColumns;
/** Builds a set of columns based on the given columns mixed with the current overrides. */
private _getFixedColumns;
/** Builds a set of columns to fix within the viewport width. */
private _getJustifiedColumns;
private _onColumnResized;
private _rememberCalculatedWidth;
private _getColumnOverride;
/**
* Callback function when double clicked on the details header column resizer
* which will measure the column cells of all the active rows and resize the
* column to the max cell width.
*
* @param column - double clicked column definition
* @param columnIndex - double clicked column index
* TODO: min width 100 should be changed to const value and should be consistent with the
* value used on _onSizerMove method in DetailsHeader
*/
private _onColumnAutoResized;
/**
* Call back function when an element in FocusZone becomes active. It will translate it into item
* and call onActiveItemChanged callback if specified.
*
* @param row - element that became active in Focus Zone
* @param focus - event from Focus Zone
*/
private _onActiveRowChanged;
private _onBlur;
private _getItemKey;
}
export declare function buildColumns(items: any[], canResizeColumns?: boolean, onColumnClick?: (ev: React.MouseEvent<HTMLElement>, column: IColumn) => void, sortedColumnKey?: string, isSortedDescending?: boolean, groupedColumnKey?: string, isMultiline?: boolean, columnActionsMode?: ColumnActionsMode): IColumn[];
@@ -0,0 +1,989 @@
import { __assign, __decorate, __extends } from "tslib";
import * as React from 'react';
import { initializeComponentRef, FocusRects, Async, KeyCodes, elementContains, getRTLSafeKeyCode, classNamesFunction, css, memoizeFunction, warnMutuallyExclusive, } from '../../Utilities';
import { CheckboxVisibility, ColumnActionsMode, ConstrainMode, DetailsListLayoutMode, ColumnDragEndLocation, } from '../DetailsList/DetailsList.types';
import { DetailsHeader } from '../DetailsList/DetailsHeader';
import { SelectAllVisibility } from '../DetailsList/DetailsHeader.types';
import { DetailsRow } from '../DetailsList/DetailsRow';
import { FocusZone, FocusZoneDirection } from '../../FocusZone';
import { Selection, SelectionMode, SelectionZone } from '../../Selection';
import { DragDropHelper } from '../../DragDrop';
import { GroupedList } from '../../GroupedList';
import { List } from '../../List';
import { withViewport } from '../../utilities/decorators/withViewport';
import { GetGroupCount } from '../../utilities/groupedList/GroupedListUtility';
import { DEFAULT_CELL_STYLE_PROPS } from './DetailsRow.styles';
import { CHECK_CELL_WIDTH as CHECKBOX_WIDTH } from './DetailsRowCheck.styles';
// For every group level there is a GroupSpacer added. Importing this const to have the source value in one place.
import { SPACER_WIDTH as GROUP_EXPAND_WIDTH } from '../GroupedList/GroupSpacer';
import { composeComponentAs, composeRenderFunction, getId } from '@fluentui/utilities';
import { useConst } from '@fluentui/react-hooks';
import { WindowContext } from '@fluentui/react-window-provider';
import { getDocumentEx } from '../../utilities/dom';
var getClassNames = classNamesFunction();
var COMPONENT_NAME = 'DetailsList';
var MIN_COLUMN_WIDTH = 100; // this is the global min width
var DEFAULT_RENDERED_WINDOWS_AHEAD = 2;
var DEFAULT_RENDERED_WINDOWS_BEHIND = 2;
var rowFocusZoneAddTabIndexProps = { tabIndex: 0 };
var rowFocusZoneNoTabIndexProps = {};
/**
* Hooks-based implementation of DetailsList.
* Since many existing consumers of DetailsList expect `ref` to return a `DetailsList`,
* this inner component handles rendering while the outer maintains compatibility.
*/
var DetailsListInner = function (props) {
var selection = props.selection;
var ariaLabelForListHeader = props.ariaLabelForListHeader, ariaLabelForSelectAllCheckbox = props.ariaLabelForSelectAllCheckbox, ariaLabelForSelectionColumn = props.ariaLabelForSelectionColumn, className = props.className, checkboxVisibility = props.checkboxVisibility, compact = props.compact, constrainMode = props.constrainMode, dragDropEvents = props.dragDropEvents, groups = props.groups, groupProps = props.groupProps, indentWidth = props.indentWidth, items = props.items, isPlaceholderData = props.isPlaceholderData, isHeaderVisible = props.isHeaderVisible, layoutMode = props.layoutMode, onItemInvoked = props.onItemInvoked, onItemContextMenu = props.onItemContextMenu, onColumnHeaderClick = props.onColumnHeaderClick, onColumnHeaderContextMenu = props.onColumnHeaderContextMenu, _a = props.selectionMode, selectionMode = _a === void 0 ? selection.mode : _a, selectionPreservedOnEmptyClick = props.selectionPreservedOnEmptyClick, selectionZoneProps = props.selectionZoneProps,
// eslint-disable-next-line @typescript-eslint/no-deprecated
ariaLabel = props.ariaLabel, ariaLabelForGrid = props.ariaLabelForGrid, rowElementEventMap = props.rowElementEventMap,
// eslint-disable-next-line @typescript-eslint/no-deprecated
_b = props.shouldApplyApplicationRole,
// eslint-disable-next-line @typescript-eslint/no-deprecated
shouldApplyApplicationRole = _b === void 0 ? false : _b, getKey = props.getKey, listProps = props.listProps, usePageCache = props.usePageCache, onShouldVirtualize = props.onShouldVirtualize, viewport = props.viewport, minimumPixelsForDrag = props.minimumPixelsForDrag, getGroupHeight = props.getGroupHeight, styles = props.styles, theme = props.theme, _c = props.cellStyleProps, cellStyleProps = _c === void 0 ? DEFAULT_CELL_STYLE_PROPS : _c, onRenderCheckbox = props.onRenderCheckbox, useFastIcons = props.useFastIcons, dragDropHelper = props.dragDropHelper, adjustedColumns = props.adjustedColumns, isCollapsed = props.isCollapsed, isSizing = props.isSizing, isSomeGroupExpanded = props.isSomeGroupExpanded, version = props.version, rootRef = props.rootRef, listRef = props.listRef, focusZoneRef = props.focusZoneRef, columnReorderOptions = props.columnReorderOptions, groupedListRef = props.groupedListRef, headerRef = props.headerRef, onGroupExpandStateChanged = props.onGroupExpandStateChanged, onColumnIsSizingChanged = props.onColumnIsSizingChanged, onRowDidMount = props.onRowDidMount, onRowWillUnmount = props.onRowWillUnmount, disableSelectionZone = props.disableSelectionZone, _d = props.isSelectedOnFocus, isSelectedOnFocus = _d === void 0 ? true : _d, onColumnResized = props.onColumnResized, onColumnAutoResized = props.onColumnAutoResized, onToggleCollapse = props.onToggleCollapse, onActiveRowChanged = props.onActiveRowChanged, onBlur = props.onBlur, eventsToRegister = props.rowElementEventMap, onRenderMissingItem = props.onRenderMissingItem, onRenderItemColumn = props.onRenderItemColumn, onRenderField = props.onRenderField, getCellValueKey = props.getCellValueKey, getRowAriaLabel = props.getRowAriaLabel, getRowAriaDescribedBy = props.getRowAriaDescribedBy, checkButtonAriaLabel = props.checkButtonAriaLabel, checkButtonGroupAriaLabel = props.checkButtonGroupAriaLabel, checkboxCellClassName = props.checkboxCellClassName, useReducedRowRenderer = props.useReducedRowRenderer, enableUpdateAnimations = props.enableUpdateAnimations, enterModalSelectionOnTouch = props.enterModalSelectionOnTouch, onRenderDefaultRow = props.onRenderDefaultRow, selectionZoneRef = props.selectionZoneRef, focusZoneProps = props.focusZoneProps;
var defaultRole = 'grid';
var role = props.role ? props.role : defaultRole;
var rowId = getId('row');
var groupNestingDepth = getGroupNestingDepth(groups);
var groupedDetailsListIndexMap = useGroupedDetailsListIndexMap(groups);
var additionalListProps = React.useMemo(function () {
return __assign({ renderedWindowsAhead: isSizing ? 0 : DEFAULT_RENDERED_WINDOWS_AHEAD, renderedWindowsBehind: isSizing ? 0 : DEFAULT_RENDERED_WINDOWS_BEHIND, getKey: getKey, version: version }, listProps);
}, [isSizing, getKey, version, listProps]);
var selectAllVisibility = SelectAllVisibility.none; // for SelectionMode.none
if (selectionMode === SelectionMode.single) {
selectAllVisibility = SelectAllVisibility.hidden;
}
if (selectionMode === SelectionMode.multiple) {
// if isCollapsedGroupSelectVisible is false, disable select all when the list has all collapsed groups
var isCollapsedGroupSelectVisible = groupProps && groupProps.headerProps && groupProps.headerProps.isCollapsedGroupSelectVisible;
if (isCollapsedGroupSelectVisible === undefined) {
isCollapsedGroupSelectVisible = true;
}
var isSelectAllVisible = isCollapsedGroupSelectVisible || !groups || isSomeGroupExpanded;
selectAllVisibility = isSelectAllVisible ? SelectAllVisibility.visible : SelectAllVisibility.hidden;
}
if (checkboxVisibility === CheckboxVisibility.hidden) {
selectAllVisibility = SelectAllVisibility.none;
}
var defaultOnRenderDetailsHeader = React.useCallback(function (detailsHeaderProps) {
return React.createElement(DetailsHeader, __assign({}, detailsHeaderProps));
}, []);
var defaultOnRenderDetailsFooter = React.useCallback(function () {
return null;
}, []);
var propsOnRenderDetailsHeader = props.onRenderDetailsHeader;
var onRenderDetailsHeader = React.useMemo(function () {
return propsOnRenderDetailsHeader
? composeRenderFunction(propsOnRenderDetailsHeader, defaultOnRenderDetailsHeader)
: defaultOnRenderDetailsHeader;
}, [propsOnRenderDetailsHeader, defaultOnRenderDetailsHeader]);
var propsOnRenderDetailsFooter = props.onRenderDetailsFooter;
var onRenderDetailsFooter = React.useMemo(function () {
return propsOnRenderDetailsFooter
? composeRenderFunction(propsOnRenderDetailsFooter, defaultOnRenderDetailsFooter)
: defaultOnRenderDetailsFooter;
}, [propsOnRenderDetailsFooter, defaultOnRenderDetailsFooter]);
var detailsFooterProps = React.useMemo(function () {
return {
columns: adjustedColumns,
groupNestingDepth: groupNestingDepth,
selection: selection,
selectionMode: selectionMode,
viewport: viewport,
checkboxVisibility: checkboxVisibility,
indentWidth: indentWidth,
cellStyleProps: cellStyleProps,
};
}, [
adjustedColumns,
groupNestingDepth,
selection,
selectionMode,
viewport,
checkboxVisibility,
indentWidth,
cellStyleProps,
]);
var columnReorderOnDragEnd = columnReorderOptions && columnReorderOptions.onDragEnd;
var onColumnDragEnd = React.useCallback(function (_a, event) {
var dropLocation = _a.dropLocation;
var finalDropLocation = ColumnDragEndLocation.outside;
if (columnReorderOnDragEnd) {
if (dropLocation && dropLocation !== ColumnDragEndLocation.header) {
finalDropLocation = dropLocation;
}
else if (rootRef.current) {
var clientRect = rootRef.current.getBoundingClientRect();
if (event.clientX > clientRect.left &&
event.clientX < clientRect.right &&
event.clientY > clientRect.top &&
event.clientY < clientRect.bottom) {
finalDropLocation = ColumnDragEndLocation.surface;
}
}
columnReorderOnDragEnd(finalDropLocation);
}
}, [columnReorderOnDragEnd, rootRef]);
var columnReorderProps = React.useMemo(function () {
if (columnReorderOptions) {
return __assign(__assign({}, columnReorderOptions), { onColumnDragEnd: onColumnDragEnd });
}
}, [columnReorderOptions, onColumnDragEnd]);
var rowCount = (isHeaderVisible ? 1 : 0) +
(props.onRenderDetailsFooter ? 1 : 0) +
GetGroupCount(groups) +
(items ? items.length : 0);
var colCount = (selectAllVisibility !== SelectAllVisibility.none ? 1 : 0) +
(adjustedColumns ? adjustedColumns.length : 0) +
(groups ? 1 : 0);
var classNames = React.useMemo(function () {
return getClassNames(styles, {
theme: theme,
compact: compact,
isFixed: layoutMode === DetailsListLayoutMode.fixedColumns,
isHorizontalConstrained: constrainMode === ConstrainMode.horizontalConstrained,
className: className,
});
}, [styles, theme, compact, layoutMode, constrainMode, className]);
var onRenderDetailsGroupFooter = groupProps && groupProps.onRenderFooter;
var finalOnRenderDetailsGroupFooter = React.useMemo(function () {
return onRenderDetailsGroupFooter
? function (groupFooterProps, defaultRender) {
return onRenderDetailsGroupFooter(__assign(__assign({}, groupFooterProps), { columns: adjustedColumns, groupNestingDepth: groupNestingDepth, indentWidth: indentWidth, selection: selection, selectionMode: selectionMode, viewport: viewport, checkboxVisibility: checkboxVisibility, cellStyleProps: cellStyleProps }), defaultRender);
}
: undefined;
}, [
onRenderDetailsGroupFooter,
adjustedColumns,
groupNestingDepth,
indentWidth,
selection,
selectionMode,
viewport,
checkboxVisibility,
cellStyleProps,
]);
var onRenderDetailsGroupHeader = groupProps && groupProps.onRenderHeader;
var finalOnRenderDetailsGroupHeader = React.useMemo(function () {
return onRenderDetailsGroupHeader
? function (groupHeaderProps, defaultRender) {
var _a, _b;
var groupIndex = groupHeaderProps.groupIndex;
var groupKey = groupIndex !== undefined ? (_b = (_a = groupHeaderProps.groups) === null || _a === void 0 ? void 0 : _a[groupIndex]) === null || _b === void 0 ? void 0 : _b.key : undefined;
var totalRowCount = groupKey !== undefined && groupedDetailsListIndexMap[groupKey]
? groupedDetailsListIndexMap[groupKey].totalRowCount
: 0;
return onRenderDetailsGroupHeader(__assign(__assign({}, groupHeaderProps), { columns: adjustedColumns, groupNestingDepth: groupNestingDepth, indentWidth: indentWidth, selection: selection, selectionMode: checkboxVisibility !== CheckboxVisibility.hidden ? selectionMode : SelectionMode.none, viewport: viewport, checkboxVisibility: checkboxVisibility, cellStyleProps: cellStyleProps, ariaColSpan: adjustedColumns.length, ariaLevel: undefined, ariaPosInSet: undefined, ariaSetSize: undefined, ariaRowCount: undefined, ariaRowIndex: groupIndex !== undefined ? totalRowCount + (isHeaderVisible ? 1 : 0) : undefined }), defaultRender);
}
: function (groupHeaderProps, defaultRender) {
var _a, _b;
var groupIndex = groupHeaderProps.groupIndex;
var groupKey = groupIndex !== undefined ? (_b = (_a = groupHeaderProps.groups) === null || _a === void 0 ? void 0 : _a[groupIndex]) === null || _b === void 0 ? void 0 : _b.key : undefined;
var totalRowCount = groupKey !== undefined && groupedDetailsListIndexMap[groupKey]
? groupedDetailsListIndexMap[groupKey].totalRowCount
: 0;
return defaultRender(__assign(__assign({}, groupHeaderProps), { ariaColSpan: adjustedColumns.length, ariaLevel: undefined, ariaPosInSet: undefined, ariaSetSize: undefined, ariaRowCount: undefined, ariaRowIndex: groupIndex !== undefined ? totalRowCount + (isHeaderVisible ? 1 : 0) : undefined }));
};
}, [
onRenderDetailsGroupHeader,
adjustedColumns,
groupNestingDepth,
indentWidth,
isHeaderVisible,
selection,
selectionMode,
viewport,
checkboxVisibility,
cellStyleProps,
groupedDetailsListIndexMap,
]);
var finalGroupProps = React.useMemo(function () {
var _a;
return __assign(__assign({}, groupProps), { role: role === defaultRole ? 'rowgroup' : 'presentation', onRenderFooter: finalOnRenderDetailsGroupFooter, onRenderHeader: finalOnRenderDetailsGroupHeader,
// pass through custom group header checkbox label
headerProps: __assign(__assign({}, groupProps === null || groupProps === void 0 ? void 0 : groupProps.headerProps), { selectAllButtonProps: __assign({ 'aria-label': checkButtonGroupAriaLabel }, (_a = groupProps === null || groupProps === void 0 ? void 0 : groupProps.headerProps) === null || _a === void 0 ? void 0 : _a.selectAllButtonProps) }) });
}, [groupProps, finalOnRenderDetailsGroupFooter, finalOnRenderDetailsGroupHeader, checkButtonGroupAriaLabel, role]);
var sumColumnWidths = useConst(function () {
return memoizeFunction(function (columns) {
var totalWidth = 0;
columns.forEach(function (column) { return (totalWidth += column.calculatedWidth || column.minWidth); });
return totalWidth;
});
});
var collapseAllVisibility = groupProps && groupProps.collapseAllVisibility;
var rowWidth = React.useMemo(function () {
return sumColumnWidths(adjustedColumns);
}, [adjustedColumns, sumColumnWidths]);
var onRenderCell = React.useCallback(function (nestingDepth, item, index, group) {
var finalOnRenderRow = props.onRenderRow
? composeRenderFunction(props.onRenderRow, onRenderDefaultRow)
: onRenderDefaultRow;
var groupKey = group ? group.key : undefined;
var numOfGroupHeadersBeforeItem = groupKey && groupedDetailsListIndexMap[groupKey]
? groupedDetailsListIndexMap[groupKey].numOfGroupHeadersBeforeItem
: 0;
var rowRole = role === defaultRole ? undefined : 'presentation';
// add tabindex="0" to first row so if the header isn't rendered or isn't focusable,
// the focuszone still has content in the tab order.
var rowFocusZoneProps = index > 0 ? rowFocusZoneNoTabIndexProps : rowFocusZoneAddTabIndexProps;
var rowProps = {
item: item,
itemIndex: index,
flatIndexOffset: (isHeaderVisible ? 2 : 1) + numOfGroupHeadersBeforeItem,
compact: compact,
columns: adjustedColumns,
groupNestingDepth: nestingDepth,
id: "".concat(rowId, "-").concat(index),
selectionMode: selectionMode,
selection: selection,
onDidMount: onRowDidMount,
onWillUnmount: onRowWillUnmount,
onRenderItemColumn: onRenderItemColumn,
onRenderField: onRenderField,
getCellValueKey: getCellValueKey,
eventsToRegister: eventsToRegister,
dragDropEvents: dragDropEvents,
dragDropHelper: dragDropHelper,
viewport: viewport,
checkboxVisibility: checkboxVisibility,
collapseAllVisibility: collapseAllVisibility,
getRowAriaLabel: getRowAriaLabel,
getRowAriaDescribedBy: getRowAriaDescribedBy,
checkButtonAriaLabel: checkButtonAriaLabel,
checkboxCellClassName: checkboxCellClassName,
useReducedRowRenderer: useReducedRowRenderer,
indentWidth: indentWidth,
cellStyleProps: cellStyleProps,
onRenderDetailsCheckbox: onRenderCheckbox,
enableUpdateAnimations: enableUpdateAnimations,
rowWidth: rowWidth,
useFastIcons: useFastIcons,
role: rowRole,
isGridRow: true,
focusZoneProps: rowFocusZoneProps,
};
if (!item) {
if (onRenderMissingItem) {
return onRenderMissingItem(index, rowProps);
}
return null;
}
return finalOnRenderRow(rowProps);
}, [
compact,
adjustedColumns,
selectionMode,
selection,
rowId,
onRowDidMount,
onRowWillUnmount,
onRenderItemColumn,
onRenderField,
getCellValueKey,
eventsToRegister,
dragDropEvents,
dragDropHelper,
viewport,
checkboxVisibility,
collapseAllVisibility,
getRowAriaLabel,
getRowAriaDescribedBy,
isHeaderVisible,
checkButtonAriaLabel,
checkboxCellClassName,
useReducedRowRenderer,
indentWidth,
cellStyleProps,
onRenderCheckbox,
enableUpdateAnimations,
useFastIcons,
onRenderDefaultRow,
onRenderMissingItem,
props.onRenderRow,
rowWidth,
role,
groupedDetailsListIndexMap,
]);
var onRenderListCell = React.useCallback(function (nestingDepth) {
return function (item, itemIndex) {
return onRenderCell(nestingDepth, item, itemIndex);
};
}, [onRenderCell]);
var isRightArrow = React.useCallback(function (event) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
return event.which === getRTLSafeKeyCode(KeyCodes.right, theme);
}, [theme]);
var focusZoneInnerProps = __assign(__assign({}, focusZoneProps), { componentRef: focusZoneProps && focusZoneProps.componentRef ? focusZoneProps.componentRef : focusZoneRef, className: focusZoneProps && focusZoneProps.className
? css(classNames.focusZone, focusZoneProps.className)
: classNames.focusZone, direction: focusZoneProps ? focusZoneProps.direction : FocusZoneDirection.vertical, shouldEnterInnerZone: focusZoneProps && focusZoneProps.shouldEnterInnerZone ? focusZoneProps.shouldEnterInnerZone : isRightArrow, onActiveElementChanged: focusZoneProps && focusZoneProps.onActiveElementChanged
? focusZoneProps.onActiveElementChanged
: onActiveRowChanged, shouldRaiseClicksOnEnter: false, onBlur: focusZoneProps && focusZoneProps.onBlur ? focusZoneProps.onBlur : onBlur });
var FinalGroupedList = groups && (groupProps === null || groupProps === void 0 ? void 0 : groupProps.groupedListAs) ? composeComponentAs(groupProps.groupedListAs, GroupedList) : GroupedList;
var list = groups ? (React.createElement(FinalGroupedList, { focusZoneProps: focusZoneInnerProps, componentRef: groupedListRef, groups: groups, groupProps: finalGroupProps, items: items, onRenderCell: onRenderCell, role: "presentation", selection: selection, selectionMode: checkboxVisibility !== CheckboxVisibility.hidden ? selectionMode : SelectionMode.none, dragDropEvents: dragDropEvents, dragDropHelper: dragDropHelper, eventsToRegister: rowElementEventMap, listProps: additionalListProps, onGroupExpandStateChanged: onGroupExpandStateChanged, usePageCache: usePageCache, onShouldVirtualize: onShouldVirtualize, getGroupHeight: getGroupHeight, compact: compact })) : (React.createElement(FocusZone, __assign({}, focusZoneInnerProps),
React.createElement(List, __assign({ ref: listRef, role: "presentation", items: items, onRenderCell: onRenderListCell(0), usePageCache: usePageCache, onShouldVirtualize: onShouldVirtualize }, additionalListProps))));
var onHeaderKeyDown = React.useCallback(function (ev) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
if (ev.which === KeyCodes.down) {
if (focusZoneRef.current && focusZoneRef.current.focus()) {
// select the first item in list after down arrow key event
// only if nothing was selected; otherwise start with the already-selected item
if (isSelectedOnFocus && selection.getSelectedIndices().length === 0) {
selection.setIndexSelected(0, true, false);
}
ev.preventDefault();
ev.stopPropagation();
}
}
}, [selection, focusZoneRef, isSelectedOnFocus]);
var onContentKeyDown = React.useCallback(function (ev) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
if (ev.which === KeyCodes.up && !ev.altKey) {
if (headerRef.current && headerRef.current.focus()) {
ev.preventDefault();
ev.stopPropagation();
}
}
}, [headerRef]);
return (React.createElement("div", __assign({ ref: rootRef, className: classNames.root, "data-automationid": "DetailsList", "data-is-scrollable": "false" }, (shouldApplyApplicationRole ? { role: 'application' } : {})),
React.createElement(FocusRects, null),
React.createElement("div", { role: role, "aria-label": ariaLabelForGrid || ariaLabel, "aria-rowcount": isPlaceholderData ? 0 : rowCount, "aria-colcount": colCount, "aria-busy": isPlaceholderData },
React.createElement("div", { onKeyDown: onHeaderKeyDown, role: "presentation", className: classNames.headerWrapper }, isHeaderVisible &&
onRenderDetailsHeader({
componentRef: headerRef,
selectionMode: selectionMode,
layoutMode: layoutMode,
selection: selection,
columns: adjustedColumns,
onColumnClick: onColumnHeaderClick,
onColumnContextMenu: onColumnHeaderContextMenu,
onColumnResized: onColumnResized,
onColumnIsSizingChanged: onColumnIsSizingChanged,
onColumnAutoResized: onColumnAutoResized,
groupNestingDepth: groupNestingDepth,
isAllCollapsed: isCollapsed,
onToggleCollapseAll: onToggleCollapse,
ariaLabel: ariaLabelForListHeader,
ariaLabelForSelectAllCheckbox: ariaLabelForSelectAllCheckbox,
ariaLabelForSelectionColumn: ariaLabelForSelectionColumn,
selectAllVisibility: selectAllVisibility,
collapseAllVisibility: groupProps && groupProps.collapseAllVisibility,
viewport: viewport,
columnReorderProps: columnReorderProps,
minimumPixelsForDrag: minimumPixelsForDrag,
cellStyleProps: cellStyleProps,
checkboxVisibility: checkboxVisibility,
indentWidth: indentWidth,
onRenderDetailsCheckbox: onRenderCheckbox,
rowWidth: sumColumnWidths(adjustedColumns),
useFastIcons: useFastIcons,
}, onRenderDetailsHeader)),
React.createElement("div", { onKeyDown: onContentKeyDown, role: "presentation", className: classNames.contentWrapper }, !disableSelectionZone ? (React.createElement(SelectionZone, __assign({ ref: selectionZoneRef, selection: selection, selectionPreservedOnEmptyClick: selectionPreservedOnEmptyClick, selectionMode: selectionMode, isSelectedOnFocus: isSelectedOnFocus, selectionClearedOnEscapePress: isSelectedOnFocus, toggleWithoutModifierPressed: !isSelectedOnFocus, onItemInvoked: onItemInvoked, onItemContextMenu: onItemContextMenu, enterModalOnTouch: enterModalSelectionOnTouch }, (selectionZoneProps || {})), list)) : (list)),
onRenderDetailsFooter(__assign({}, detailsFooterProps)))));
};
var DetailsListBase = /** @class */ (function (_super) {
__extends(DetailsListBase, _super);
function DetailsListBase(props) {
var _this = _super.call(this, props) || this;
_this._root = React.createRef();
_this._header = React.createRef();
_this._groupedList = React.createRef();
_this._list = React.createRef();
_this._focusZone = React.createRef();
_this._selectionZone = React.createRef();
_this._onRenderRow = function (props, defaultRender) {
return React.createElement(DetailsRow, __assign({}, props));
};
_this._getDerivedStateFromProps = function (nextProps, previousState) {
var _a = _this.props, checkboxVisibility = _a.checkboxVisibility, items = _a.items, setKey = _a.setKey, _b = _a.selectionMode, selectionMode = _b === void 0 ? _this._selection.mode : _b, columns = _a.columns, viewport = _a.viewport, compact = _a.compact, dragDropEvents = _a.dragDropEvents;
var _c = (_this.props.groupProps || {}).isAllGroupsCollapsed, isAllGroupsCollapsed = _c === void 0 ? undefined : _c;
var newViewportWidth = (nextProps.viewport && nextProps.viewport.width) || 0;
var oldViewportWidth = (viewport && viewport.width) || 0;
var shouldResetSelection = nextProps.setKey !== setKey || nextProps.setKey === undefined;
var shouldForceUpdates = false;
if (nextProps.layoutMode !== _this.props.layoutMode) {
shouldForceUpdates = true;
}
var nextState = previousState;
if (shouldResetSelection) {
_this._initialFocusedIndex = nextProps.initialFocusedIndex;
// reset focusedItemIndex when setKey changes
nextState = __assign(__assign({}, nextState), { focusedItemIndex: _this._initialFocusedIndex !== undefined ? _this._initialFocusedIndex : -1 });
}
if (!_this.props.disableSelectionZone && nextProps.items !== items) {
_this._selection.setItems(nextProps.items, shouldResetSelection);
}
if (nextProps.checkboxVisibility !== checkboxVisibility ||
nextProps.columns !== columns ||
newViewportWidth !== oldViewportWidth ||
nextProps.compact !== compact) {
shouldForceUpdates = true;
}
nextState = __assign(__assign({}, nextState), _this._adjustColumns(nextProps, nextState, true));
if (nextProps.selectionMode !== selectionMode) {
shouldForceUpdates = true;
}
if (isAllGroupsCollapsed === undefined &&
nextProps.groupProps &&
nextProps.groupProps.isAllGroupsCollapsed !== undefined) {
nextState = __assign(__assign({}, nextState), { isCollapsed: nextProps.groupProps.isAllGroupsCollapsed, isSomeGroupExpanded: !nextProps.groupProps.isAllGroupsCollapsed });
}
if (nextProps.dragDropEvents !== dragDropEvents) {
_this._dragDropHelper && _this._dragDropHelper.dispose();
_this._dragDropHelper = nextProps.dragDropEvents
? new DragDropHelper({
selection: _this._selection,
minimumPixelsForDrag: nextProps.minimumPixelsForDrag,
})
: undefined;
shouldForceUpdates = true;
}
if (shouldForceUpdates) {
nextState = __assign(__assign({}, nextState), { version: {} });
}
return nextState;
};
_this._onGroupExpandStateChanged = function (isSomeGroupExpanded) {
_this.setState({ isSomeGroupExpanded: isSomeGroupExpanded });
};
_this._onColumnIsSizingChanged = function (column, isSizing) {
_this.setState({ isSizing: isSizing });
};
_this._onRowDidMount = function (row) {
var _a = row.props, item = _a.item, itemIndex = _a.itemIndex;
var itemKey = _this._getItemKey(item, itemIndex);
_this._activeRows[itemKey] = row; // this is used for column auto resize
_this._setFocusToRowIfPending(row);
var onRowDidMount = _this.props.onRowDidMount;
if (onRowDidMount) {
onRowDidMount(item, itemIndex);
}
};
_this._onRowWillUnmount = function (row) {
var onRowWillUnmount = _this.props.onRowWillUnmount;
var _a = row.props, item = _a.item, itemIndex = _a.itemIndex;
var itemKey = _this._getItemKey(item, itemIndex);
delete _this._activeRows[itemKey];
if (onRowWillUnmount) {
onRowWillUnmount(item, itemIndex);
}
};
_this._onToggleCollapse = function (collapsed) {
_this.setState({
isCollapsed: collapsed,
});
if (_this._groupedList.current) {
_this._groupedList.current.toggleCollapseAll(collapsed);
}
};
_this._onColumnResized = function (resizingColumn, newWidth, resizingColumnIndex) {
var newCalculatedWidth = Math.max(resizingColumn.minWidth || MIN_COLUMN_WIDTH, newWidth);
if (_this.props.onColumnResize) {
_this.props.onColumnResize(resizingColumn, newCalculatedWidth, resizingColumnIndex);
}
_this._rememberCalculatedWidth(resizingColumn, newCalculatedWidth);
_this.setState(__assign(__assign({}, _this._adjustColumns(_this.props, _this.state, true, resizingColumnIndex)), { version: {} }));
};
/**
* Callback function when double clicked on the details header column resizer
* which will measure the column cells of all the active rows and resize the
* column to the max cell width.
*
* @param column - double clicked column definition
* @param columnIndex - double clicked column index
* TODO: min width 100 should be changed to const value and should be consistent with the
* value used on _onSizerMove method in DetailsHeader
*/
_this._onColumnAutoResized = function (column, columnIndex) {
var max = 0;
var count = 0;
var totalCount = Object.keys(_this._activeRows).length;
for (var key in _this._activeRows) {
if (_this._activeRows.hasOwnProperty(key)) {
var currentRow = _this._activeRows[key];
currentRow.measureCell(columnIndex, function (width) {
max = Math.max(max, width);
count++;
if (count === totalCount) {
_this._onColumnResized(column, max, columnIndex);
}
});
}
}
};
/**
* Call back function when an element in FocusZone becomes active. It will translate it into item
* and call onActiveItemChanged callback if specified.
*
* @param row - element that became active in Focus Zone
* @param focus - event from Focus Zone
*/
_this._onActiveRowChanged = function (el, ev) {
var _a = _this.props, items = _a.items, onActiveItemChanged = _a.onActiveItemChanged;
if (!el) {
return;
}
// Check and assign index only if the event was raised from any DetailsRow element
if (el.getAttribute('data-item-index')) {
var index = Number(el.getAttribute('data-item-index'));
if (index >= 0) {
if (onActiveItemChanged) {
onActiveItemChanged(items[index], index, ev);
}
_this.setState({
focusedItemIndex: index,
});
}
}
};
_this._onBlur = function (event) {
_this.setState({
focusedItemIndex: -1,
});
};
initializeComponentRef(_this);
_this._async = new Async(_this);
_this._activeRows = {};
_this._columnOverrides = {};
_this.state = {
focusedItemIndex: -1,
lastWidth: 0,
adjustedColumns: _this._getAdjustedColumns(props, undefined),
isSizing: false,
isCollapsed: props.groupProps && props.groupProps.isAllGroupsCollapsed,
isSomeGroupExpanded: props.groupProps && !props.groupProps.isAllGroupsCollapsed,
version: {},
getDerivedStateFromProps: _this._getDerivedStateFromProps,
};
warnMutuallyExclusive(COMPONENT_NAME, props, {
selection: 'getKey',
});
_this._selection =
props.selection ||
new Selection({
onSelectionChanged: undefined,
getKey: props.getKey,
selectionMode: props.selectionMode,
});
if (!_this.props.disableSelectionZone) {
_this._selection.setItems(props.items, false);
}
_this._dragDropHelper = props.dragDropEvents
? new DragDropHelper({
selection: _this._selection,
minimumPixelsForDrag: props.minimumPixelsForDrag,
})
: undefined;
_this._initialFocusedIndex = props.initialFocusedIndex;
return _this;
}
DetailsListBase.getDerivedStateFromProps = function (nextProps, previousState) {
return previousState.getDerivedStateFromProps(nextProps, previousState);
};
DetailsListBase.prototype.scrollToIndex = function (index, measureItem, scrollToMode) {
this._list.current && this._list.current.scrollToIndex(index, measureItem, scrollToMode);
this._groupedList.current && this._groupedList.current.scrollToIndex(index, measureItem, scrollToMode);
};
DetailsListBase.prototype.focusIndex = function (index, forceIntoFirstElement, measureItem, scrollToMode) {
if (forceIntoFirstElement === void 0) { forceIntoFirstElement = false; }
var item = this.props.items[index];
if (item) {
this.scrollToIndex(index, measureItem, scrollToMode);
var itemKey = this._getItemKey(item, index);
var row = this._activeRows[itemKey];
if (row) {
this._setFocusToRow(row, forceIntoFirstElement);
}
}
};
DetailsListBase.prototype.getStartItemIndexInView = function () {
if (this._list && this._list.current) {
return this._list.current.getStartItemIndexInView();
}
else if (this._groupedList && this._groupedList.current) {
return this._groupedList.current.getStartItemIndexInView();
}
return 0;
};
DetailsListBase.prototype.updateColumn = function (column, options) {
var _a, _b;
var NO_COLUMNS = [];
var _c = this.props, _d = _c.columns, columns = _d === void 0 ? NO_COLUMNS : _d, selectionMode = _c.selectionMode, checkboxVisibility = _c.checkboxVisibility, columnReorderOptions = _c.columnReorderOptions;
var width = options.width, newColumnIndex = options.newColumnIndex;
var index = columns.findIndex(function (col) { return col.key === column.key; });
if (width) {
this._onColumnResized(column, width, index);
}
if (newColumnIndex !== undefined && columnReorderOptions) {
var isCheckboxColumnHidden = selectionMode === SelectionMode.none || checkboxVisibility === CheckboxVisibility.hidden;
var showCheckbox = checkboxVisibility !== CheckboxVisibility.hidden;
var columnIndex = (showCheckbox ? 2 : 1) + index;
var draggedIndex = isCheckboxColumnHidden ? columnIndex - 1 : columnIndex - 2;
var targetIndex = isCheckboxColumnHidden ? newColumnIndex - 1 : newColumnIndex - 2;
var frozenColumnCountFromStart = (_a = columnReorderOptions.frozenColumnCountFromStart) !== null && _a !== void 0 ? _a : 0;
var frozenColumnCountFromEnd = (_b = columnReorderOptions.frozenColumnCountFromEnd) !== null && _b !== void 0 ? _b : 0;
var isValidTargetIndex = targetIndex >= frozenColumnCountFromStart && targetIndex < columns.length - frozenColumnCountFromEnd;
if (isValidTargetIndex) {
if (columnReorderOptions.onColumnDrop) {
var dragDropDetails = {
draggedIndex: draggedIndex,
targetIndex: targetIndex,
};
columnReorderOptions.onColumnDrop(dragDropDetails);
/* eslint-disable @typescript-eslint/no-deprecated */
}
else if (columnReorderOptions.handleColumnReorder) {
columnReorderOptions.handleColumnReorder(draggedIndex, targetIndex);
/* eslint-enable @typescript-eslint/no-deprecated */
}
}
}
};
DetailsListBase.prototype.componentWillUnmount = function () {
if (this._dragDropHelper) {
// TODO If the DragDropHelper was passed via props, this will dispose it, which is incorrect behavior.
this._dragDropHelper.dispose();
}
this._async.dispose();
};
DetailsListBase.prototype.componentDidUpdate = function (prevProps, prevState) {
this._notifyColumnsResized();
var doc = getDocumentEx(this.context);
if (this._initialFocusedIndex !== undefined) {
var item = this.props.items[this._initialFocusedIndex];
if (item) {
var itemKey = this._getItemKey(item, this._initialFocusedIndex);
var row = this._activeRows[itemKey];
if (row) {
this._setFocusToRowIfPending(row);
}
}
}
if (this.props.items !== prevProps.items &&
this.props.items.length > 0 &&
this.state.focusedItemIndex !== -1 &&
!elementContains(this._root.current, doc === null || doc === void 0 ? void 0 : doc.activeElement, false)) {
// Item set has changed and previously-focused item is gone.
// Set focus to item at index of previously-focused item if it is in range,
// else set focus to the last item.
var index = this.state.focusedItemIndex < this.props.items.length
? this.state.focusedItemIndex
: this.props.items.length - 1;
var item = this.props.items[index];
var itemKey = this._getItemKey(item, this.state.focusedItemIndex);
var row = this._activeRows[itemKey];
if (row) {
this._setFocusToRow(row);
}
else {
this._initialFocusedIndex = index;
}
}
if (this.props.onDidUpdate) {
this.props.onDidUpdate(this);
}
};
DetailsListBase.prototype.render = function () {
return (React.createElement(DetailsListInner, __assign({}, this.props, this.state, { selection: this._selection, dragDropHelper: this._dragDropHelper, rootRef: this._root, listRef: this._list, groupedListRef: this._groupedList, focusZoneRef: this._focusZone, headerRef: this._header, selectionZoneRef: this._selectionZone, onGroupExpandStateChanged: this._onGroupExpandStateChanged, onColumnIsSizingChanged: this._onColumnIsSizingChanged, onRowDidMount: this._onRowDidMount, onRowWillUnmount: this._onRowWillUnmount, onColumnResized: this._onColumnResized, onColumnAutoResized: this._onColumnAutoResized, onToggleCollapse: this._onToggleCollapse, onActiveRowChanged: this._onActiveRowChanged, onBlur: this._onBlur, onRenderDefaultRow: this._onRenderRow })));
};
DetailsListBase.prototype.forceUpdate = function () {
_super.prototype.forceUpdate.call(this);
this._forceListUpdates();
};
DetailsListBase.prototype._getGroupNestingDepth = function () {
var groups = this.props.groups;
var level = 0;
var groupsInLevel = groups;
while (groupsInLevel && groupsInLevel.length > 0) {
level++;
groupsInLevel = groupsInLevel[0].children;
}
return level;
};
DetailsListBase.prototype._setFocusToRowIfPending = function (row) {
var itemIndex = row.props.itemIndex;
if (this._initialFocusedIndex !== undefined && itemIndex === this._initialFocusedIndex) {
this._setFocusToRow(row);
delete this._initialFocusedIndex;
}
};
DetailsListBase.prototype._setFocusToRow = function (row, forceIntoFirstElement) {
if (forceIntoFirstElement === void 0) { forceIntoFirstElement = false; }
if (this._selectionZone.current) {
this._selectionZone.current.ignoreNextFocus();
}
this._async.setTimeout(function () {
row.focus(forceIntoFirstElement);
}, 0);
};
DetailsListBase.prototype._forceListUpdates = function () {
if (this._groupedList.current) {
this._groupedList.current.forceUpdate();
}
if (this._list.current) {
this._list.current.forceUpdate();
}
};
DetailsListBase.prototype._notifyColumnsResized = function () {
this.state.adjustedColumns.forEach(function (column) {
if (column.onColumnResize) {
column.onColumnResize(column.currentWidth);
}
});
};
DetailsListBase.prototype._adjustColumns = function (newProps, previousState, forceUpdate, resizingColumnIndex) {
var adjustedColumns = this._getAdjustedColumns(newProps, previousState, forceUpdate, resizingColumnIndex);
var viewport = this.props.viewport;
var viewportWidth = viewport && viewport.width ? viewport.width : 0;
return __assign(__assign({}, previousState), { adjustedColumns: adjustedColumns, lastWidth: viewportWidth });
};
/** Returns adjusted columns, given the viewport size and layout mode. */
DetailsListBase.prototype._getAdjustedColumns = function (newProps, previousState, forceUpdate, resizingColumnIndex) {
var _this = this;
var newItems = newProps.items, layoutMode = newProps.layoutMode, selectionMode = newProps.selectionMode, viewport = newProps.viewport;
var viewportWidth = viewport && viewport.width ? viewport.width : 0;
var newColumns = newProps.columns;
var columns = this.props ? this.props.columns : [];
var lastWidth = previousState ? previousState.lastWidth : -1;
var lastSelectionMode = previousState ? previousState.lastSelectionMode : undefined;
if (!forceUpdate &&
lastWidth === viewportWidth &&
lastSelectionMode === selectionMode &&
(!columns || newColumns === columns)) {
return newColumns || [];
}
newColumns = newColumns || buildColumns(newItems, true);
var adjustedColumns;
if (layoutMode === DetailsListLayoutMode.fixedColumns) {
adjustedColumns = this._getFixedColumns(newColumns, viewportWidth, newProps);
// Preserve adjusted column calculated widths.
adjustedColumns.forEach(function (column) {
_this._rememberCalculatedWidth(column, column.calculatedWidth);
});
}
else {
adjustedColumns = this._getJustifiedColumns(newColumns, viewportWidth, newProps);
adjustedColumns.forEach(function (column) {
_this._getColumnOverride(column.key).currentWidth = column.calculatedWidth;
});
}
return adjustedColumns;
};
/** Builds a set of columns based on the given columns mixed with the current overrides. */
DetailsListBase.prototype._getFixedColumns = function (newColumns, viewportWidth, props) {
var _this = this;
var _a = this.props, _b = _a.selectionMode, selectionMode = _b === void 0 ? this._selection.mode : _b, checkboxVisibility = _a.checkboxVisibility, flexMargin = _a.flexMargin, skipViewportMeasures = _a.skipViewportMeasures;
var remainingWidth = viewportWidth - (flexMargin || 0);
var sumProportionalWidth = 0;
newColumns.forEach(function (col) {
if (skipViewportMeasures || !col.flexGrow) {
remainingWidth -= col.maxWidth || col.minWidth || MIN_COLUMN_WIDTH;
}
else {
remainingWidth -= col.minWidth || MIN_COLUMN_WIDTH;
sumProportionalWidth += col.flexGrow;
}
remainingWidth -= getPaddedWidth(col, props, true);
});
var rowCheckWidth = selectionMode !== SelectionMode.none && checkboxVisibility !== CheckboxVisibility.hidden ? CHECKBOX_WIDTH : 0;
var groupExpandWidth = this._getGroupNestingDepth() * GROUP_EXPAND_WIDTH;
remainingWidth -= rowCheckWidth + groupExpandWidth;
var widthFraction = remainingWidth / sumProportionalWidth;
// Shrinks proportional columns to their max width and adds the remaining width to distribute to other columns.
if (!skipViewportMeasures) {
newColumns.forEach(function (column) {
var newColumn = __assign(__assign({}, column), _this._columnOverrides[column.key]);
if (newColumn.flexGrow && newColumn.maxWidth) {
var fullWidth = newColumn.flexGrow * widthFraction + newColumn.minWidth;
var shrinkWidth = fullWidth - newColumn.maxWidth;
if (shrinkWidth > 0) {
remainingWidth += shrinkWidth;
sumProportionalWidth -= (shrinkWidth / (fullWidth - newColumn.minWidth)) * newColumn.flexGrow;
}
}
});
}
widthFraction = remainingWidth > 0 ? remainingWidth / sumProportionalWidth : 0;
return newColumns.map(function (column) {
var newColumn = __assign(__assign({}, column), _this._columnOverrides[column.key]);
// Delay computation until viewport width is available.
if (!skipViewportMeasures && newColumn.flexGrow && remainingWidth <= 0 && viewportWidth === 0) {
return newColumn;
}
if (!newColumn.calculatedWidth) {
if (!skipViewportMeasures && newColumn.flexGrow) {
// Assigns the proportion of the remaining extra width after all columns have met minimum widths.
newColumn.calculatedWidth = newColumn.minWidth + newColumn.flexGrow * widthFraction;
newColumn.calculatedWidth = Math.min(newColumn.calculatedWidth, newColumn.maxWidth || Number.MAX_VALUE);
}
else {
newColumn.calculatedWidth = newColumn.maxWidth || newColumn.minWidth || MIN_COLUMN_WIDTH;
}
}
return newColumn;
});
};
/** Builds a set of columns to fix within the viewport width. */
DetailsListBase.prototype._getJustifiedColumns = function (newColumns, viewportWidth, props) {
var _this = this;
var _a = props.selectionMode, selectionMode = _a === void 0 ? this._selection.mode : _a, checkboxVisibility = props.checkboxVisibility, skipViewportMeasures = props.skipViewportMeasures;
var rowCheckWidth = selectionMode !== SelectionMode.none && checkboxVisibility !== CheckboxVisibility.hidden ? CHECKBOX_WIDTH : 0;
var groupExpandWidth = this._getGroupNestingDepth() * GROUP_EXPAND_WIDTH;
var totalWidth = 0; // offset because we have one less inner padding.
var minimumWidth = 0;
var availableWidth = viewportWidth - (rowCheckWidth + groupExpandWidth);
var adjustedColumns = newColumns.map(function (column, i) {
var baseColumn = __assign(__assign({}, column), { calculatedWidth: column.minWidth || MIN_COLUMN_WIDTH });
var newColumn = __assign(__assign({}, baseColumn), _this._columnOverrides[column.key]);
// eslint-disable-next-line @typescript-eslint/no-deprecated
if (!(baseColumn.isCollapsible || baseColumn.isCollapsable)) {
minimumWidth += getPaddedWidth(baseColumn, props);
}
totalWidth += getPaddedWidth(newColumn, props);
return newColumn;
});
if (skipViewportMeasures) {
return adjustedColumns;
}
var lastIndex = adjustedColumns.length - 1;
// Shrink or remove collapsable columns.
while (lastIndex >= 0 && totalWidth > availableWidth) {
var column = adjustedColumns[lastIndex];
var minWidth = column.minWidth || MIN_COLUMN_WIDTH;
var overflowWidth = totalWidth - availableWidth;
// eslint-disable-next-line @typescript-eslint/no-deprecated
if (column.calculatedWidth - minWidth >= overflowWidth || !(column.isCollapsible || column.isCollapsable)) {
var originalWidth = column.calculatedWidth;
if (minimumWidth < availableWidth) {
// Only adjust in cases where all the columns fit within the viewport
column.calculatedWidth = Math.max(column.calculatedWidth - overflowWidth, minWidth);
}
totalWidth -= originalWidth - column.calculatedWidth;
}
else {
totalWidth -= getPaddedWidth(column, props);
adjustedColumns.splice(lastIndex, 1);
}
lastIndex--;
}
// Then expand columns starting at the beginning, until we've filled the width.
for (var i = 0; i < adjustedColumns.length && totalWidth < availableWidth; i++) {
var column = adjustedColumns[i];
var isLast = i === adjustedColumns.length - 1;
var overrides = this._columnOverrides[column.key];
if (overrides && overrides.calculatedWidth && !isLast) {
continue;
}
var spaceLeft = availableWidth - totalWidth;
var increment = void 0;
if (isLast) {
increment = spaceLeft;
}
else {
var maxWidth = column.maxWidth;
var minWidth = column.minWidth || maxWidth || MIN_COLUMN_WIDTH;
increment = maxWidth ? Math.min(spaceLeft, maxWidth - minWidth) : spaceLeft;
}
column.calculatedWidth = column.calculatedWidth + increment;
totalWidth += increment;
}
return adjustedColumns;
};
DetailsListBase.prototype._rememberCalculatedWidth = function (column, newCalculatedWidth) {
var overrides = this._getColumnOverride(column.key);
overrides.calculatedWidth = newCalculatedWidth;
overrides.currentWidth = newCalculatedWidth;
};
DetailsListBase.prototype._getColumnOverride = function (key) {
return (this._columnOverrides[key] = this._columnOverrides[key] || {});
};
DetailsListBase.prototype._getItemKey = function (item, itemIndex) {
var getKey = this.props.getKey;
var itemKey = undefined;
if (item) {
itemKey = item.key;
}
if (getKey) {
itemKey = getKey(item, itemIndex);
}
if (!itemKey) {
itemKey = itemIndex;
}
return itemKey;
};
DetailsListBase.defaultProps = {
layoutMode: DetailsListLayoutMode.justified,
selectionMode: SelectionMode.multiple,
constrainMode: ConstrainMode.horizontalConstrained,
checkboxVisibility: CheckboxVisibility.onHover,
isHeaderVisible: true,
compact: false,
useFastIcons: true,
};
DetailsListBase.contextType = WindowContext;
DetailsListBase = __decorate([
withViewport
], DetailsListBase);
return DetailsListBase;
}(React.Component));
export { DetailsListBase };
export function buildColumns(items, canResizeColumns, onColumnClick, sortedColumnKey, isSortedDescending, groupedColumnKey, isMultiline, columnActionsMode) {
var columns = [];
if (items && items.length) {
var firstItem = items[0];
for (var propName in firstItem) {
if (firstItem.hasOwnProperty(propName)) {
columns.push({
key: propName,
name: propName,
fieldName: propName,
minWidth: MIN_COLUMN_WIDTH,
maxWidth: 300,
isCollapsible: !!columns.length,
isMultiline: isMultiline === undefined ? false : isMultiline,
isSorted: sortedColumnKey === propName,
isSortedDescending: !!isSortedDescending,
isRowHeader: false,
columnActionsMode: columnActionsMode !== null && columnActionsMode !== void 0 ? columnActionsMode : ColumnActionsMode.clickable,
isResizable: canResizeColumns,
onColumnClick: onColumnClick,
isGrouped: groupedColumnKey === propName,
});
}
}
}
return columns;
}
function getPaddedWidth(column, props, paddingOnly) {
var _a = props.cellStyleProps, cellStyleProps = _a === void 0 ? DEFAULT_CELL_STYLE_PROPS : _a;
return ((paddingOnly ? 0 : column.calculatedWidth) +
cellStyleProps.cellLeftPadding +
cellStyleProps.cellRightPadding +
(column.isPadded ? cellStyleProps.cellExtraRightPadding : 0));
}
function getGroupNestingDepth(groups) {
var level = 0;
var groupsInLevel = groups;
while (groupsInLevel && groupsInLevel.length > 0) {
level++;
groupsInLevel = groupsInLevel[0].children;
}
return level;
}
function useGroupedDetailsListIndexMap(groups) {
return React.useMemo(function () {
var indexMap = {};
if (groups) {
var rowCount = 1;
var numGroupHeaders = 1;
for (var _i = 0, groups_1 = groups; _i < groups_1.length; _i++) {
var group = groups_1[_i];
var key = group.key;
indexMap[key] = { numOfGroupHeadersBeforeItem: numGroupHeaders, totalRowCount: rowCount };
numGroupHeaders++;
rowCount += group.count + 1;
}
}
return indexMap;
}, [groups]);
}
//# sourceMappingURL=DetailsList.base.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
import * as React from 'react';
import type { IDetailsListProps } from './DetailsList.types';
export declare const DetailsList: React.FunctionComponent<IDetailsListProps>;
export type { IDetailsListProps };
@@ -0,0 +1,7 @@
import { styled } from '../../Utilities';
import { DetailsListBase } from './DetailsList.base';
import { getDetailsListStyles } from './DetailsList.styles';
export var DetailsList = styled(DetailsListBase, getDetailsListStyles, undefined, {
scope: 'DetailsList',
});
//# sourceMappingURL=DetailsList.js.map
@@ -0,0 +1 @@
{"version":3,"file":"DetailsList.js","sourceRoot":"../src/","sources":["components/DetailsList/DetailsList.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAG5D,MAAM,CAAC,IAAM,WAAW,GAA+C,MAAM,CAI3E,eAAe,EAAE,oBAAoB,EAAE,SAAS,EAAE;IAClD,KAAK,EAAE,aAAa;CACrB,CAAC,CAAC","sourcesContent":["import * as React from 'react';\nimport { styled } from '../../Utilities';\nimport { DetailsListBase } from './DetailsList.base';\nimport { getDetailsListStyles } from './DetailsList.styles';\nimport type { IDetailsListProps, IDetailsListStyleProps, IDetailsListStyles } from './DetailsList.types';\n\nexport const DetailsList: React.FunctionComponent<IDetailsListProps> = styled<\n IDetailsListProps,\n IDetailsListStyleProps,\n IDetailsListStyles\n>(DetailsListBase, getDetailsListStyles, undefined, {\n scope: 'DetailsList',\n});\n\nexport type { IDetailsListProps };\n"]}
@@ -0,0 +1,2 @@
import type { IDetailsListStyleProps, IDetailsListStyles } from './DetailsList.types';
export declare const getDetailsListStyles: (props: IDetailsListStyleProps) => IDetailsListStyles;
@@ -0,0 +1,62 @@
import { getGlobalClassNames } from '../../Styling';
var GlobalClassNames = {
root: 'ms-DetailsList',
compact: 'ms-DetailsList--Compact',
contentWrapper: 'ms-DetailsList-contentWrapper',
headerWrapper: 'ms-DetailsList-headerWrapper',
isFixed: 'is-fixed',
isHorizontalConstrained: 'is-horizontalConstrained',
listCell: 'ms-List-cell',
};
export var getDetailsListStyles = function (props) {
var _a, _b;
var theme = props.theme, className = props.className, isHorizontalConstrained = props.isHorizontalConstrained, compact = props.compact, isFixed = props.isFixed;
var semanticColors = theme.semanticColors;
var classNames = getGlobalClassNames(GlobalClassNames, theme);
return {
root: [
classNames.root,
theme.fonts.small,
{
position: 'relative',
color: semanticColors.listText,
selectors: (_a = {},
_a["& .".concat(classNames.listCell)] = {
minHeight: 38,
wordBreak: 'break-word',
},
_a),
},
isFixed && classNames.isFixed,
compact && [
classNames.compact,
{
selectors: (_b = {},
_b[".".concat(classNames.listCell)] = {
minHeight: 32,
},
_b),
},
],
isHorizontalConstrained && [
classNames.isHorizontalConstrained,
{
overflowX: 'auto',
overflowY: 'visible',
WebkitOverflowScrolling: 'touch',
},
],
className,
],
focusZone: [
{
display: 'inline-block',
minWidth: '100%',
minHeight: 1,
},
],
headerWrapper: classNames.headerWrapper,
contentWrapper: classNames.contentWrapper,
};
};
//# sourceMappingURL=DetailsList.styles.js.map
@@ -0,0 +1 @@
{"version":3,"file":"DetailsList.styles.js","sourceRoot":"../src/","sources":["components/DetailsList/DetailsList.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAGpD,IAAM,gBAAgB,GAAG;IACvB,IAAI,EAAE,gBAAgB;IACtB,OAAO,EAAE,yBAAyB;IAClC,cAAc,EAAE,+BAA+B;IAC/C,aAAa,EAAE,8BAA8B;IAC7C,OAAO,EAAE,UAAU;IACnB,uBAAuB,EAAE,0BAA0B;IACnD,QAAQ,EAAE,cAAc;CACzB,CAAC;AAEF,MAAM,CAAC,IAAM,oBAAoB,GAAG,UAAC,KAA6B;;IACxD,IAAA,KAAK,GAA2D,KAAK,MAAhE,EAAE,SAAS,GAAgD,KAAK,UAArD,EAAE,uBAAuB,GAAuB,KAAK,wBAA5B,EAAE,OAAO,GAAc,KAAK,QAAnB,EAAE,OAAO,GAAK,KAAK,QAAV,CAAW;IACtE,IAAA,cAAc,GAAK,KAAK,eAAV,CAAW;IACjC,IAAM,UAAU,GAAG,mBAAmB,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;IAEhE,OAAO;QACL,IAAI,EAAE;YACJ,UAAU,CAAC,IAAI;YACf,KAAK,CAAC,KAAK,CAAC,KAAK;YACjB;gBACE,QAAQ,EAAE,UAAU;gBACpB,KAAK,EAAE,cAAc,CAAC,QAAQ;gBAC9B,SAAS;oBACP,GAAC,aAAM,UAAU,CAAC,QAAQ,CAAE,IAAG;wBAC7B,SAAS,EAAE,EAAE;wBACb,SAAS,EAAE,YAAY;qBACxB;uBACF;aACF;YAED,OAAO,IAAI,UAAU,CAAC,OAAO;YAE7B,OAAO,IAAI;gBACT,UAAU,CAAC,OAAO;gBAClB;oBACE,SAAS;wBACP,GAAC,WAAI,UAAU,CAAC,QAAQ,CAAE,IAAG;4BAC3B,SAAS,EAAE,EAAE;yBACd;2BACF;iBACF;aACF;YAED,uBAAuB,IAAI;gBACzB,UAAU,CAAC,uBAAuB;gBAClC;oBACE,SAAS,EAAE,MAAM;oBACjB,SAAS,EAAE,SAAS;oBACpB,uBAAuB,EAAE,OAAO;iBACjC;aACF;YAED,SAAS;SACV;QAED,SAAS,EAAE;YACT;gBACE,OAAO,EAAE,cAAc;gBACvB,QAAQ,EAAE,MAAM;gBAChB,SAAS,EAAE,CAAC;aACb;SACF;QACD,aAAa,EAAE,UAAU,CAAC,aAAa;QACvC,cAAc,EAAE,UAAU,CAAC,cAAc;KAC1C,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { getGlobalClassNames } from '../../Styling';\nimport type { IDetailsListStyleProps, IDetailsListStyles } from './DetailsList.types';\n\nconst GlobalClassNames = {\n root: 'ms-DetailsList',\n compact: 'ms-DetailsList--Compact',\n contentWrapper: 'ms-DetailsList-contentWrapper',\n headerWrapper: 'ms-DetailsList-headerWrapper',\n isFixed: 'is-fixed',\n isHorizontalConstrained: 'is-horizontalConstrained',\n listCell: 'ms-List-cell',\n};\n\nexport const getDetailsListStyles = (props: IDetailsListStyleProps): IDetailsListStyles => {\n const { theme, className, isHorizontalConstrained, compact, isFixed } = props;\n const { semanticColors } = theme;\n const classNames = getGlobalClassNames(GlobalClassNames, theme);\n\n return {\n root: [\n classNames.root,\n theme.fonts.small,\n {\n position: 'relative',\n color: semanticColors.listText,\n selectors: {\n [`& .${classNames.listCell}`]: {\n minHeight: 38,\n wordBreak: 'break-word',\n },\n },\n },\n\n isFixed && classNames.isFixed,\n\n compact && [\n classNames.compact,\n {\n selectors: {\n [`.${classNames.listCell}`]: {\n minHeight: 32,\n },\n },\n },\n ],\n\n isHorizontalConstrained && [\n classNames.isHorizontalConstrained,\n {\n overflowX: 'auto',\n overflowY: 'visible',\n WebkitOverflowScrolling: 'touch',\n },\n ],\n\n className,\n ],\n\n focusZone: [\n {\n display: 'inline-block',\n minWidth: '100%',\n minHeight: 1,\n },\n ],\n headerWrapper: classNames.headerWrapper,\n contentWrapper: classNames.contentWrapper,\n };\n};\n"]}
@@ -0,0 +1,565 @@
import * as React from 'react';
import { DetailsListBase } from './DetailsList.base';
import { SelectionMode } from '../../Selection';
import { ScrollToMode } from '../../List';
import type { ISelection, ISelectionZoneProps } from '../../Selection';
import type { IRefObject, IBaseProps, IRenderFunction, IStyleFunctionOrObject, IComponentAs } from '../../Utilities';
import type { IDragDropEvents, IDragDropContext, IDragDropHelper, IDragDropOptions } from '../../DragDrop';
import type { IGroup, IGroupRenderProps, IGroupDividerProps, IGroupedListProps } from '../GroupedList/index';
import type { IDetailsRowProps, IDetailsRowBaseProps } from '../DetailsList/DetailsRow';
import type { IDetailsHeaderProps, IDetailsHeaderBaseProps } from './DetailsHeader';
import type { IDetailsFooterProps, IDetailsFooterBaseProps } from './DetailsFooter.types';
import type { IWithViewportProps, IViewport } from '../../utilities/decorators/withViewport';
import type { IList, IListProps } from '../../List';
import type { ITheme, IStyle } from '../../Styling';
import type { ICellStyleProps, IDetailsItemProps } from './DetailsRow.types';
import type { IDetailsCheckboxProps } from './DetailsRowCheck.types';
import type { IDetailsColumnStyleProps, IDetailsColumnProps, IDetailsColumnStyles, IDetailsColumnFilterIconProps, IDetailsColumnFieldProps } from './DetailsColumn.types';
import { IFocusZoneProps } from '../../FocusZone';
/**
* {@docCategory DetailsList}
*/
export interface IDetailsList extends IList {
/**
* Ensures that the list content is updated. Call this in cases where the list prop updates don't change, but the list
* still needs to be re-evaluated. For example, if a sizer bar is adjusted and causes the list width to change,
* you can call this to force a re-evaluation. Be aware that this can be an expensive operation and should be
* done sparingly.
*/
forceUpdate: () => void;
/**
* Scroll to and focus the item at the given index. focusIndex will call scrollToIndex on the specified index.
*
* @param index - Index of item to scroll to
* @param forceIntoFirstElement - If true, focus will be set to the first focusable child element of the item rather
* than the item itself.
* @param measureItem - Optional callback to measure the height of an individual item
* @param scrollToMode - Optional setting to determine where in the window the item should be scrolled to
* when focused.
*/
focusIndex: (index: number, forceIntoFirstElement?: boolean, measureItem?: (itemIndex: number) => number, scrollToMode?: ScrollToMode) => void;
/**
* Get the start index of the page that is currently in view
*/
getStartItemIndexInView: () => number;
/**
* Use to programatically resize and/or reorder columns in the DetailsList.
* @param column - column to resize/reorder.
* @param options - includes width which is desired width in pixels the column should be resized
* to and newColumnIndex which is desired index position where the column should be moved to.
*/
updateColumn: (column: IColumn, options: {
width?: number;
newColumnIndex?: number;
}) => void;
}
/**
* {@docCategory DetailsList}
*/
export interface IDetailsListProps extends IBaseProps<IDetailsList>, IWithViewportProps {
/** Theme provided by a higher-order component. */
theme?: ITheme;
/** Custom overrides to the themed or default styles. */
styles?: IStyleFunctionOrObject<IDetailsListStyleProps, IDetailsListStyles>;
/**
* Callback to access the IDetailsList interface. Use this instead of ref for accessing
* the public methods and properties of the component.
*/
componentRef?: IRefObject<IDetailsList>;
/** A key that uniquely identifies the given items. If provided, the selection will be reset when the key changes. */
setKey?: string;
/** The items to render. */
items: any[];
/** Set this to true to indicate that the items being displayed are placeholder data. */
isPlaceholderData?: boolean;
/** Properties to pass through to the List components being rendered. */
listProps?: IListProps;
/** Default index to set focus to once the items have rendered and the index exists. */
initialFocusedIndex?: number;
/** Class name to add to the root element. */
className?: string;
/** Grouping instructions. */
groups?: IGroup[];
/** Override properties to render groups. */
groupProps?: IDetailsGroupRenderProps;
/** Override for the indent width used for group nesting. */
indentWidth?: number;
/** Selection model to track selection state. */
selection?: ISelection;
/** Controls how/if the details list manages selection. Options include none, single, multiple */
selectionMode?: SelectionMode;
/**
* By default, selection is cleared when clicking on an empty (non-focusable) section of the screen.
* Setting this value to true overrides that behavior and maintains selection.
* @defaultvalue false
**/
selectionPreservedOnEmptyClick?: boolean;
/**
* Additional props to pass through to the SelectionZone created by default.
*/
selectionZoneProps?: Partial<ISelectionZoneProps>;
/** Controls how the columns are adjusted. */
layoutMode?: DetailsListLayoutMode;
/**
* Controls the visibility of selection check box.
* @defaultvalue CheckboxVisibility.onHover
*/
checkboxVisibility?: CheckboxVisibility;
/**
* Controls the visibility of the header.
* @defaultvalue true
*/
isHeaderVisible?: boolean;
/** Column definitions. If none are provided, default columns will be created based on the items' properties. */
columns?: IColumn[];
/** Controls how the list constrains overflow. */
constrainMode?: ConstrainMode;
/** Event names and corresponding callbacks that will be registered to rendered row elements. */
rowElementEventMap?: {
eventName: string;
callback: (context: IDragDropContext, event?: any) => void;
}[];
/** Callback for when the list has been updated. Useful for telemetry tracking externally. */
onDidUpdate?: (detailsList?: DetailsListBase) => void;
/**
* Callback for when a given row has been mounted. Useful for identifying when a row has been rendered on the page.
*/
onRowDidMount?: (item?: any, index?: number) => void;
/**
* Callback for when a given row has been unmounted.
* Useful for identifying when a row has been removed from the page.
*/
onRowWillUnmount?: (item?: any, index?: number) => void;
/** Callback for when the user clicks on the column header. */
onColumnHeaderClick?: (ev?: React.MouseEvent<HTMLElement>, column?: IColumn) => void;
/** Callback for when the user asks for a contextual menu (usually via right click) from a column header. */
onColumnHeaderContextMenu?: (column?: IColumn, ev?: React.MouseEvent<HTMLElement>) => void;
/** Callback fired on column resize */
onColumnResize?: (column?: IColumn, newWidth?: number, columnIndex?: number) => void;
/** Callback for when a given row has been invoked (by pressing enter while it is selected.) */
onItemInvoked?: (item?: any, index?: number, ev?: Event) => void;
/**
* Callback for when the context menu of an item has been accessed.
* If undefined or false is returned, `ev.preventDefault()` will be called.
*/
onItemContextMenu?: (item?: any, index?: number, ev?: Event) => void | boolean;
/**
* Callback to override the default row rendering.
*/
onRenderRow?: IRenderFunction<IDetailsRowProps>;
/**
* If provided, will be the "default" item column renderer method.
* This affects cells within the rows, not the rows themselves.
* If a column definition provides its own `onRender` method, that will be used instead of this.
*/
onRenderItemColumn?: (item?: any, index?: number, column?: IColumn) => React.ReactNode;
/**
* Render function which is composed around rendering every cell.
*/
onRenderField?: IRenderFunction<IDetailsColumnFieldProps>;
/**
* If provided, will be the "default" item column cell value return.
* A column's `getValueKey` can override `getCellValueKey`.
*/
getCellValueKey?: (item?: any, index?: number, column?: IColumn) => string;
/** Map of callback functions related to row drag and drop functionality. */
dragDropEvents?: IDragDropEvents;
/** Callback for what to render when the item is missing. */
onRenderMissingItem?: (index?: number, rowProps?: IDetailsRowProps) => React.ReactNode;
/** An override to render the details header. */
onRenderDetailsHeader?: IRenderFunction<IDetailsHeaderProps>;
/** An override to render the details footer. */
onRenderDetailsFooter?: IRenderFunction<IDetailsFooterProps>;
/** If provided, can be used to render a custom checkbox. */
onRenderCheckbox?: IRenderFunction<IDetailsListCheckboxProps>;
/** Viewport info, provided by the `withViewport` decorator. */
viewport?: IViewport;
/**
* Callback for when an item in the list becomes active by clicking anywhere inside the row or navigating to it
* with the keyboard.
*/
onActiveItemChanged?: (item?: any, index?: number, ev?: React.FocusEvent<HTMLElement>) => void;
/** Accessible label for the list header. */
ariaLabelForListHeader?: string;
/** Accessible label for the select all checkbox. */
ariaLabelForSelectAllCheckbox?: string;
/** Accessible label for the name of the selection column. */
ariaLabelForSelectionColumn?: string;
/** Callback to get the aria-label string for a given item. */
getRowAriaLabel?: (item: any) => string;
/** Callback to get the aria-describedby IDs (space-separated strings) of elements that describe the item. */
getRowAriaDescribedBy?: (item: any) => string;
/**
* Callback to get the item key, to be used in the selection and on render.
* Must be provided if sorting or filtering is enabled.
*/
getKey?: (item: any, index?: number) => string;
/**
* Accessible label describing or summarizing the list.
* @deprecated use `ariaLabelForGrid`
*/
ariaLabel?: string;
/** Accessible label for the row check button, e.g. "select row". */
checkButtonAriaLabel?: string;
/** Accessible label for the group header check button, e.g. "select section". */
checkButtonGroupAriaLabel?: string;
/** Accessible label for the grid within the list. */
ariaLabelForGrid?: string;
/** An optional margin for proportional columns, to e.g. account for scrollbars when laying out width. */
flexMargin?: number;
/**
* Whether the role `application` should be applied to the list.
* @defaultvalue false
* @deprecated using the application role in this case is an antipattern, and heavily discouraged.
*/
shouldApplyApplicationRole?: boolean;
/**
* The minimum mouse move distance to interpret the action as drag event.
* @defaultvalue 5
*/
minimumPixelsForDrag?: number;
/**
* Whether to render in compact mode.
* @defaultvalue false
*/
compact?: boolean;
/**
* Whether to enable render page caching. This is an experimental performance optimization that is off by default.
* @defaultvalue false
*/
usePageCache?: boolean;
/**
* Callback to determine whether the list should be rendered in full, or virtualized.
*
* Virtualization will add and remove pages of items as the user scrolls them into the visible range.
* This benefits larger list scenarios by reducing the DOM on the screen, but can negatively affect performance
* for smaller lists.
*
* The default implementation will virtualize when this callback is not provided.
*/
onShouldVirtualize?: (props: IListProps) => boolean;
/** Class name to add to the cell of a checkbox. */
checkboxCellClassName?: string;
/** Whether the selection zone should enter modal state on touch. */
enterModalSelectionOnTouch?: boolean;
/** Options for column reordering using drag and drop. */
columnReorderOptions?: IColumnReorderOptions;
/** Callback to override default group height calculation used by list virtualization. */
getGroupHeight?: IGroupedListProps['getGroupHeight'];
/**
* Whether to re-render a row only when props changed. Might cause regression when depending on external updates.
* @defaultvalue 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;
/** Whether to disable the built-in SelectionZone, so the host component can provide its own. */
disableSelectionZone?: boolean;
/**
* Determines if an item is selected on focus.
*
* @defaultvalue true
*/
isSelectedOnFocus?: boolean;
/** Whether to animate updates */
enableUpdateAnimations?: boolean;
/**
* Whether to use fast icon and check components. The icons can't be targeted by customization
* but are still customizable via class names.
* @defaultvalue true
*/
useFastIcons?: boolean;
/** Role for the list. */
role?: string;
/**
* Properties to pass through to the FocusZone.
*/
focusZoneProps?: IFocusZoneProps;
}
/**
* {@docCategory DetailsList}
*/
export interface IColumn {
/** A unique key for identifying the column. */
key: string;
/** Name to render on the column header. */
name: string;
/**
* The field to pull the text value from for the column.
* Can be unset if a custom `onRender` method is provided.
*/
fieldName?: string;
/**
* If specified, the width of the column is a portion of the available space equal to this value divided by the sum
* of all proportional column widths in the list. For example, if there is a list with two proportional columns that
* have widths of 1 and 3, they will respectively occupy (1/4) = 25% and (3/4) = 75% of the remaining space. Note that
* this relies on viewport measures and will not work well with skipViewportMeasures.
*/
flexGrow?: number;
/** Class name to apply to the column cell within each row. */
className?: string;
/** Custom overrides to the themed or default styles. */
styles?: IStyleFunctionOrObject<IDetailsColumnStyleProps, IDetailsColumnStyles>;
/** Minimum width for the column. */
minWidth: number;
/**
* If specified, the width of the column is a portion of the available space equal to this value divided by the sum
* of all proportional column widths in the list. For example, if there is a list with two proportional columns that
* have widths of 1 and 3, they will respectively occupy (1/4) = 25% and (2/4) = 75% of the remaining space. Note that
* this relies on viewport measures and will not work well with skipViewportMeasures.
*/
targetWidthProportion?: number;
/**
* Accessible label for the column. The column name will still be used as the primary label,
* but this text (if specified) will be used as the column description.
* WARNING: grid column descriptions are often ignored by screen readers, so any necessary information
* should go directly in the column content
*/
ariaLabel?: string;
/** Whether the column is a header for the given row. There should be only one column with this set to true. */
isRowHeader?: boolean;
/** Maximum width for the column, if stretching is allowed in justified scenarios. */
maxWidth?: number;
/**
* Defines how the column's header should render.
* @defaultvalue ColumnActionsMode.clickable
*/
columnActionsMode?: ColumnActionsMode;
/** Custom icon to use in the column header. */
iconName?: string;
/**
* Whether only the icon should be displayed in the column header.
* If true, the column name and dropdown chevron will not be displayed.
*/
isIconOnly?: boolean;
/** Class name for the icon within the header. */
iconClassName?: string;
/**
* If true, allow the column to be collapsed when rendered in justified layout.
* @deprecated Use `isCollapsible`
*/
isCollapsable?: boolean;
/** If true, allow the column to be collapsed when rendered in justified layout. */
isCollapsible?: boolean;
/** If true, column header will render an icon indicating column is sortable while unsorted */
showSortIconWhenUnsorted?: boolean;
/** Determines if the column is currently sorted. Renders a sort arrow in the column header. */
isSorted?: boolean;
/** Determines if the sort arrow is pointed down (descending) or up. */
isSortedDescending?: boolean;
/** Determines if the column can be resized. */
isResizable?: boolean;
/** Determines if the column can render multi-line text. */
isMultiline?: boolean;
/** Custom renderer for cell content, instead of the default text rendering. */
onRender?: (item?: any, index?: number, column?: IColumn) => any;
/** Custom override for the parent list's `getCellValueKey`. */
getValueKey?: (item?: any, index?: number, column?: IColumn) => string;
onRenderField?: IRenderFunction<IDetailsColumnFieldProps>;
/** Custom renderer for column header divider. */
onRenderDivider?: IRenderFunction<IDetailsColumnProps>;
/** Custom renderer for filter icon. */
onRenderFilterIcon?: IRenderFunction<IDetailsColumnFilterIconProps>;
/** Custom renderer for column header content, instead of the default text rendering. */
onRenderHeader?: IRenderFunction<IDetailsColumnProps>;
/** Whether the list is filtered by this column. If true, shows a filter icon next to this column's name. */
isFiltered?: boolean;
/** Callback for when the user clicks on the column header. */
onColumnClick?: (ev: React.MouseEvent<HTMLElement>, column: IColumn) => void;
/** Callback for when the user opens the column header context menu. */
onColumnContextMenu?: (column?: IColumn, ev?: React.MouseEvent<HTMLElement>) => void;
/** Callback for when the user performs a keyboard action on the column header */
onColumnKeyDown?: (ev: React.KeyboardEvent, column: IColumn) => void;
/**
* Callback for when the column is resized (`width` is the current width).
*
* Prefer this over `DetailsList`'s `onColumnResize` if you require the `IColumn` to report its width
* after every resize event. Consider debouncing the callback if resize events occur frequently.
*/
onColumnResize?: (width?: number) => void;
/** Whether the list is grouped by this column. If true, shows a grouped icon next to this column's name. */
isGrouped?: boolean;
/** Arbitrary data passthrough which can be used by the caller. */
data?: any;
/** Internal only value. */
calculatedWidth?: number;
/**
* Internal only value.
* Remembers the actual width of the column in any case.
* `calculatedWidth` is only saved when it's defined by user, not for justified calculations.
*/
currentWidth?: number;
/** Class name to apply to the column header cell. */
headerClassName?: string;
/** If true, add additional LTR padding-right to column and cells. */
isPadded?: boolean;
/**
* Accessible label for indicating that the list is sorted by this column in ascending order.
* This will be read after the main column header label.
*/
sortAscendingAriaLabel?: string;
/**
* Accessible label for indicating that the list is sorted by this column in descending order.
* This will be read after the main column header label.
*/
sortDescendingAriaLabel?: string;
/**
* Accessible label for indicating that the list could be sorted by this column but isn't currently.
* This will be read after the main column header label.
*/
sortableAriaLabel?: string;
/** Accessible label for the status of this column when grouped. */
groupAriaLabel?: string;
/** Accessible label for the status of this column when filtered. */
filterAriaLabel?: string;
/** Whether a dropdown menu is open so that the appropriate ARIA attributes are rendered. */
isMenuOpen?: boolean;
}
/**
* Enum to describe how a particular column header behaves.
* This is used to to specify the property `IColumn.columnActionsMode`.
* If `IColumn.columnActionsMode` is undefined, it's equivalent to `ColumnActionsMode.clickable`.
* {@docCategory DetailsList}
*/
export declare enum ColumnActionsMode {
/** Renders the column header as disabled. */
disabled = 0,
/** Renders the column header as clickable. Default value. */
clickable = 1,
/** Renders the column header as clickable and displays the dropdown chevron. */
hasDropdown = 2
}
/**
* {@docCategory DetailsList}
*/
export declare enum ConstrainMode {
/** Lets the content grow which allows the page to manage scrolling. */
unconstrained = 0,
/** Constrains the list to the given layout space. */
horizontalConstrained = 1
}
/**
* {@docCategory DetailsList}
*/
export interface IColumnReorderOptions {
/**
* Specifies the number fixed columns from left
* @defaultvalue 0
*/
frozenColumnCountFromStart?: number;
/**
* Specifies the number fixed columns from right
* @defaultvalue 0
*/
frozenColumnCountFromEnd?: number;
/**
* Callback to handle when dragging on this column's DetailsHeader has started.
*/
onColumnDragStart?: (dragStarted: boolean) => void;
/**
* Callback to handle column reordering.
* `draggedIndex` is the source column index, which should be placed at `targetIndex`.
* @deprecated Use `onColumnDrop` instead.
*/
handleColumnReorder?: (draggedIndex: number, targetIndex: number) => void;
/**
* Callback to handle column reordering.
* `draggedIndex` is the source column index, which should be placed at `targetIndex`.
*/
onColumnDrop?: (dragDropDetails: IColumnDragDropDetails) => void;
/**
* Callback to handle when dragging on this column's DetailsHeader has finished.
*/
onDragEnd?: (columnDropLocationDetails: ColumnDragEndLocation) => void;
}
/**
* {@docCategory DetailsList}
*/
export interface IColumnDragDropDetails {
/**
* Specifies the source column index
* @defaultvalue -1
*/
draggedIndex: number;
/**
* Specifies the target column index
* @defaultvalue -1
*/
targetIndex: number;
}
/**
* Enum to describe where the column has been dropped, after starting the drag
* {@docCategory DetailsList}
*/
export declare enum ColumnDragEndLocation {
/** Drag ended outside of current list */
outside = 0,
/** Drag ended within current list */
surface = 1,
/** Drag ended on header */
header = 2
}
/**
* {@docCategory DetailsList}
*/
export declare enum DetailsListLayoutMode {
/**
* Lets the user resize columns and makes not attempt to fit them.
*/
fixedColumns = 0,
/**
* Manages which columns are visible, tries to size them according to their min/max rules and drops
* off columns that can't fit and have isCollapsible set.
*/
justified = 1
}
/**
* {@docCategory DetailsList}
*/
export declare enum CheckboxVisibility {
/** Visible on hover. */
onHover = 0,
/** Visible always. */
always = 1,
/** Hide checkboxes. */
hidden = 2
}
/**
* {@docCategory DetailsList}
*/
export type IDetailsListStyleProps = Required<Pick<IDetailsListProps, 'theme'>> & Pick<IDetailsListProps, 'className'> & {
/** Whether the list is horizontally constrained */
isHorizontalConstrained?: boolean;
/** Whether the list is in compact mode */
compact?: boolean;
/** Whether the list is fixed in size */
isFixed?: boolean;
};
/**
* {@docCategory DetailsList}
*/
export interface IDetailsListStyles {
root: IStyle;
focusZone: IStyle;
headerWrapper: IStyle;
contentWrapper: IStyle;
}
/**
* {@docCategory DetailsList}
*/
export interface IDetailsGroupRenderProps extends IGroupRenderProps {
onRenderFooter?: IRenderFunction<IDetailsGroupDividerProps>;
onRenderHeader?: IRenderFunction<IDetailsGroupDividerProps>;
groupedListAs?: IComponentAs<IGroupedListProps>;
}
/**
* {@docCategory DetailsList}
*/
export interface IDetailsGroupDividerProps extends IGroupDividerProps, IDetailsItemProps {
}
export interface IDetailsListCheckboxProps extends IDetailsCheckboxProps {
}
export type { IDetailsHeaderProps, IDetailsRowBaseProps, IDetailsHeaderBaseProps, IDetailsFooterBaseProps, IDragDropContext, IDragDropEvents, IDragDropHelper, IDragDropOptions, IViewport, IWithViewportProps, };
@@ -0,0 +1,66 @@
/**
* Enum to describe how a particular column header behaves.
* This is used to to specify the property `IColumn.columnActionsMode`.
* If `IColumn.columnActionsMode` is undefined, it's equivalent to `ColumnActionsMode.clickable`.
* {@docCategory DetailsList}
*/
export var ColumnActionsMode;
(function (ColumnActionsMode) {
/** Renders the column header as disabled. */
ColumnActionsMode[ColumnActionsMode["disabled"] = 0] = "disabled";
/** Renders the column header as clickable. Default value. */
ColumnActionsMode[ColumnActionsMode["clickable"] = 1] = "clickable";
/** Renders the column header as clickable and displays the dropdown chevron. */
ColumnActionsMode[ColumnActionsMode["hasDropdown"] = 2] = "hasDropdown";
})(ColumnActionsMode || (ColumnActionsMode = {}));
/**
* {@docCategory DetailsList}
*/
export var ConstrainMode;
(function (ConstrainMode) {
/** Lets the content grow which allows the page to manage scrolling. */
ConstrainMode[ConstrainMode["unconstrained"] = 0] = "unconstrained";
/** Constrains the list to the given layout space. */
ConstrainMode[ConstrainMode["horizontalConstrained"] = 1] = "horizontalConstrained";
})(ConstrainMode || (ConstrainMode = {}));
/**
* Enum to describe where the column has been dropped, after starting the drag
* {@docCategory DetailsList}
*/
export var ColumnDragEndLocation;
(function (ColumnDragEndLocation) {
/** Drag ended outside of current list */
ColumnDragEndLocation[ColumnDragEndLocation["outside"] = 0] = "outside";
/** Drag ended within current list */
ColumnDragEndLocation[ColumnDragEndLocation["surface"] = 1] = "surface";
/** Drag ended on header */
ColumnDragEndLocation[ColumnDragEndLocation["header"] = 2] = "header";
})(ColumnDragEndLocation || (ColumnDragEndLocation = {}));
/**
* {@docCategory DetailsList}
*/
export var DetailsListLayoutMode;
(function (DetailsListLayoutMode) {
/**
* Lets the user resize columns and makes not attempt to fit them.
*/
DetailsListLayoutMode[DetailsListLayoutMode["fixedColumns"] = 0] = "fixedColumns";
/**
* Manages which columns are visible, tries to size them according to their min/max rules and drops
* off columns that can't fit and have isCollapsible set.
*/
DetailsListLayoutMode[DetailsListLayoutMode["justified"] = 1] = "justified";
})(DetailsListLayoutMode || (DetailsListLayoutMode = {}));
/**
* {@docCategory DetailsList}
*/
export var CheckboxVisibility;
(function (CheckboxVisibility) {
/** Visible on hover. */
CheckboxVisibility[CheckboxVisibility["onHover"] = 0] = "onHover";
/** Visible always. */
CheckboxVisibility[CheckboxVisibility["always"] = 1] = "always";
/** Hide checkboxes. */
CheckboxVisibility[CheckboxVisibility["hidden"] = 2] = "hidden";
})(CheckboxVisibility || (CheckboxVisibility = {}));
//# sourceMappingURL=DetailsList.types.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,61 @@
import * as React from 'react';
import type { IColumn } from './DetailsList.types';
import type { IDetailsRowBaseProps } from './DetailsRow.types';
import type { IDetailsRowCheckProps } from './DetailsRowCheck.types';
import type { JSXElement } from '@fluentui/utilities';
export interface IDetailsRowSelectionState {
isSelected: boolean;
isSelectionModal: boolean;
}
export interface IDetailsRowState {
selectionState: IDetailsRowSelectionState;
columnMeasureInfo?: {
index: number;
column: IColumn;
onMeasureDone: (measuredWidth: number) => void;
};
isDropping?: boolean;
}
export declare class DetailsRowBase extends React.Component<IDetailsRowBaseProps, IDetailsRowState> {
private _events;
private _root;
private _cellMeasurer;
private _focusZone;
private _droppingClassNames;
/** Whether this.props.onDidMount has been called */
private _onDidMountCalled;
private _dragDropSubscription?;
private _classNames;
private _rowClassNames;
private _ariaRowDescriptionId;
static getDerivedStateFromProps(nextProps: IDetailsRowBaseProps, previousState: IDetailsRowState): IDetailsRowState;
constructor(props: IDetailsRowBaseProps);
componentDidMount(): void;
componentDidUpdate(previousProps: IDetailsRowBaseProps): void;
componentWillUnmount(): void;
shouldComponentUpdate(nextProps: IDetailsRowBaseProps, nextState: IDetailsRowState): boolean;
render(): JSXElement;
/**
* measure cell at index. and call the call back with the measured cell width when finish measure
*
* @param index - The cell index
* @param onMeasureDone - The call back function when finish measure
*/
measureCell(index: number, onMeasureDone: (width: number) => void): void;
focus(forceIntoFirstElement?: boolean): boolean;
protected _onRenderCheck(props: IDetailsRowCheckProps): JSXElement;
private _onSelectionChanged;
private _getRowDragDropOptions;
/**
* update isDropping state based on the input value, which is used to change style during drag and drop
*
* when change to true, that means drag enter. we will add default dropping class name
* or the custom dropping class name (return result from onDragEnter) to the root elemet.
*
* when change to false, that means drag leave. we will remove the dropping class name from root element.
*
* @param newValue - New isDropping state value
* @param event - The event trigger dropping state change which can be dragenter, dragleave etc
*/
private _updateDroppingState;
}
@@ -0,0 +1,284 @@
import { __assign, __extends } from "tslib";
import * as React from 'react';
import { initializeComponentRef, EventGroup, css, shallowCompare, getNativeProps, divProperties, composeComponentAs, } from '../../Utilities';
import { CheckboxVisibility } from './DetailsList.types';
import { DetailsRowCheck } from './DetailsRowCheck';
import { GroupSpacer } from '../GroupedList/GroupSpacer';
import { DetailsRowFields } from './DetailsRowFields';
import { FocusZone, FocusZoneDirection } from '../../FocusZone';
import { SelectionMode, SELECTION_CHANGE } from '../../Selection';
import { classNamesFunction } from '../../Utilities';
import { getId } from '../../Utilities';
var getClassNames = classNamesFunction();
var DEFAULT_DROPPING_CSS_CLASS = 'is-dropping';
var NO_COLUMNS = [];
var DetailsRowBase = /** @class */ (function (_super) {
__extends(DetailsRowBase, _super);
function DetailsRowBase(props) {
var _this = _super.call(this, props) || this;
_this._root = React.createRef();
_this._cellMeasurer = React.createRef();
_this._focusZone = React.createRef();
_this._onSelectionChanged = function () {
var selectionState = getSelectionState(_this.props);
if (!shallowCompare(selectionState, _this.state.selectionState)) {
_this.setState({ selectionState: selectionState });
}
};
/**
* update isDropping state based on the input value, which is used to change style during drag and drop
*
* when change to true, that means drag enter. we will add default dropping class name
* or the custom dropping class name (return result from onDragEnter) to the root elemet.
*
* when change to false, that means drag leave. we will remove the dropping class name from root element.
*
* @param newValue - New isDropping state value
* @param event - The event trigger dropping state change which can be dragenter, dragleave etc
*/
_this._updateDroppingState = function (newValue, event) {
var isDropping = _this.state.isDropping;
var _a = _this.props, dragDropEvents = _a.dragDropEvents, item = _a.item;
if (!newValue) {
if (dragDropEvents.onDragLeave) {
dragDropEvents.onDragLeave(item, event);
}
}
else if (dragDropEvents.onDragEnter) {
_this._droppingClassNames = dragDropEvents.onDragEnter(item, event);
}
if (isDropping !== newValue) {
_this.setState({ isDropping: newValue });
}
};
initializeComponentRef(_this);
_this._events = new EventGroup(_this);
_this.state = {
selectionState: getSelectionState(props),
columnMeasureInfo: undefined,
isDropping: false,
};
_this._droppingClassNames = '';
return _this;
}
DetailsRowBase.getDerivedStateFromProps = function (nextProps, previousState) {
return __assign(__assign({}, previousState), { selectionState: getSelectionState(nextProps) });
};
DetailsRowBase.prototype.componentDidMount = function () {
var _a = this.props, dragDropHelper = _a.dragDropHelper, selection = _a.selection, item = _a.item, onDidMount = _a.onDidMount;
if (dragDropHelper && this._root.current) {
this._dragDropSubscription = dragDropHelper.subscribe(this._root.current, this._events, this._getRowDragDropOptions());
}
if (selection) {
this._events.on(selection, SELECTION_CHANGE, this._onSelectionChanged);
}
if (onDidMount && item) {
// If the item appears later, we should wait for it before calling this method.
this._onDidMountCalled = true;
onDidMount(this);
}
};
DetailsRowBase.prototype.componentDidUpdate = function (previousProps) {
var state = this.state;
var _a = this.props, item = _a.item, onDidMount = _a.onDidMount;
var columnMeasureInfo = state.columnMeasureInfo;
if (this.props.itemIndex !== previousProps.itemIndex ||
this.props.item !== previousProps.item ||
this.props.dragDropHelper !== previousProps.dragDropHelper) {
if (this._dragDropSubscription) {
this._dragDropSubscription.dispose();
delete this._dragDropSubscription;
}
if (this.props.dragDropHelper && this._root.current) {
this._dragDropSubscription = this.props.dragDropHelper.subscribe(this._root.current, this._events, this._getRowDragDropOptions());
}
}
if (columnMeasureInfo && columnMeasureInfo.index >= 0 && this._cellMeasurer.current) {
var newWidth = this._cellMeasurer.current.getBoundingClientRect().width;
columnMeasureInfo.onMeasureDone(newWidth);
this.setState({
columnMeasureInfo: undefined,
});
}
if (item && onDidMount && !this._onDidMountCalled) {
this._onDidMountCalled = true;
onDidMount(this);
}
};
DetailsRowBase.prototype.componentWillUnmount = function () {
var _a = this.props, item = _a.item, onWillUnmount = _a.onWillUnmount;
// Only call the onWillUnmount callback if we have an item.
if (onWillUnmount && item) {
onWillUnmount(this);
}
if (this._dragDropSubscription) {
this._dragDropSubscription.dispose();
delete this._dragDropSubscription;
}
this._events.dispose();
};
DetailsRowBase.prototype.shouldComponentUpdate = function (nextProps, nextState) {
if (this.props.useReducedRowRenderer) {
var newSelectionState = getSelectionState(nextProps);
if (this.state.selectionState.isSelected !== newSelectionState.isSelected) {
return true;
}
return !shallowCompare(this.props, nextProps);
}
else {
return true;
}
};
DetailsRowBase.prototype.render = function () {
var _a, _b;
var _c = this.props, className = _c.className, _d = _c.columns, columns = _d === void 0 ? NO_COLUMNS : _d, dragDropEvents = _c.dragDropEvents, item = _c.item, itemIndex = _c.itemIndex, id = _c.id, _e = _c.flatIndexOffset, flatIndexOffset = _e === void 0 ? 2 : _e, _f = _c.onRenderCheck, onRenderCheck = _f === void 0 ? this._onRenderCheck : _f, onRenderDetailsCheckbox = _c.onRenderDetailsCheckbox, onRenderItemColumn = _c.onRenderItemColumn, onRenderField = _c.onRenderField, getCellValueKey = _c.getCellValueKey, selectionMode = _c.selectionMode, checkboxVisibility = _c.checkboxVisibility, getRowAriaLabel = _c.getRowAriaLabel, getRowAriaDescription = _c.getRowAriaDescription, getRowAriaDescribedBy = _c.getRowAriaDescribedBy, isGridRow = _c.isGridRow, checkButtonAriaLabel = _c.checkButtonAriaLabel, checkboxCellClassName = _c.checkboxCellClassName,
/** Alias rowFieldsAs as RowFields and default to DetailsRowFields if rowFieldsAs does not exist */
rowFieldsAs = _c.rowFieldsAs, selection = _c.selection, indentWidth = _c.indentWidth, enableUpdateAnimations = _c.enableUpdateAnimations, compact = _c.compact, theme = _c.theme, styles = _c.styles, cellsByColumn = _c.cellsByColumn, groupNestingDepth = _c.groupNestingDepth, _g = _c.useFastIcons, useFastIcons = _g === void 0 ? true : _g, cellStyleProps = _c.cellStyleProps, group = _c.group, focusZoneProps = _c.focusZoneProps, _h = _c.disabled, disabled = _h === void 0 ? false : _h;
var _j = this.state, columnMeasureInfo = _j.columnMeasureInfo, isDropping = _j.isDropping;
var _k = this.state.selectionState, _l = _k.isSelected, isSelected = _l === void 0 ? false : _l, _m = _k.isSelectionModal, isSelectionModal = _m === void 0 ? false : _m;
var isDraggable = dragDropEvents ? !!(dragDropEvents.canDrag && dragDropEvents.canDrag(item)) : undefined;
var droppingClassName = isDropping ? this._droppingClassNames || DEFAULT_DROPPING_CSS_CLASS : '';
var ariaLabel = getRowAriaLabel ? getRowAriaLabel(item) : undefined;
var ariaRowDescription = getRowAriaDescription ? getRowAriaDescription(item) : undefined;
var ariaDescribedBy = getRowAriaDescribedBy ? getRowAriaDescribedBy(item) : undefined;
var canSelect = !!selection && selection.canSelectItem(item, itemIndex) && !disabled;
var isContentUnselectable = selectionMode === SelectionMode.multiple;
var showCheckbox = selectionMode !== SelectionMode.none && checkboxVisibility !== CheckboxVisibility.hidden;
var ariaSelected = selectionMode === SelectionMode.none ? undefined : isSelected;
var ariaPositionInSet = group ? itemIndex - group.startIndex + 1 : undefined;
var ariaSetSize = group ? group.count : undefined;
var focusZoneDirection = (_a = focusZoneProps === null || focusZoneProps === void 0 ? void 0 : focusZoneProps.direction) !== null && _a !== void 0 ? _a : FocusZoneDirection.horizontal;
this._classNames = __assign(__assign({}, this._classNames), getClassNames(styles, {
theme: theme,
isSelected: isSelected,
canSelect: !isContentUnselectable,
anySelected: isSelectionModal,
checkboxCellClassName: checkboxCellClassName,
droppingClassName: droppingClassName,
className: className,
compact: compact,
enableUpdateAnimations: enableUpdateAnimations,
cellStyleProps: cellStyleProps,
disabled: disabled,
}));
var rowClassNames = {
isMultiline: this._classNames.isMultiline,
isRowHeader: this._classNames.isRowHeader,
cell: this._classNames.cell,
cellAnimation: this._classNames.cellAnimation,
cellPadded: this._classNames.cellPadded,
cellUnpadded: this._classNames.cellUnpadded,
fields: this._classNames.fields,
};
// Only re-assign rowClassNames when classNames have changed.
// Otherwise, they will cause DetailsRowFields to unnecessarily
// re-render, see https://github.com/microsoft/fluentui/pull/8799.
// Refactor DetailsRowFields to generate own styles to remove need for this.
if (!shallowCompare(this._rowClassNames || {}, rowClassNames)) {
this._rowClassNames = rowClassNames;
}
var RowFields = rowFieldsAs ? composeComponentAs(rowFieldsAs, DetailsRowFields) : DetailsRowFields;
var rowFields = (React.createElement(RowFields, { rowClassNames: this._rowClassNames, rowHeaderId: "".concat(id, "-header"), cellsByColumn: cellsByColumn, columns: columns, item: item, itemIndex: itemIndex, isSelected: isSelected, columnStartIndex: (showCheckbox ? 1 : 0) + (groupNestingDepth ? 1 : 0), onRenderItemColumn: onRenderItemColumn, onRenderField: onRenderField, getCellValueKey: getCellValueKey, enableUpdateAnimations: enableUpdateAnimations, cellStyleProps: cellStyleProps }));
var defaultRole = 'row';
var role = this.props.role ? this.props.role : defaultRole;
this._ariaRowDescriptionId = getId('DetailsRow-description');
// When the user does not specify any column is a row-header in the columns props,
// The aria-labelledby of the checkbox does not specify {id}-header.
var hasRowHeader = columns.some(function (column) {
return !!column.isRowHeader;
});
var ariaLabelledby = "".concat(id, "-checkbox") + (hasRowHeader ? " ".concat(id, "-header") : '');
// additional props for rows within a GroupedList
// these are needed for treegrid row semantics, but not grid row semantics
var groupedListRowProps = isGridRow
? {}
: {
'aria-level': (groupNestingDepth && groupNestingDepth + 1) || undefined,
'aria-posinset': ariaPositionInSet,
'aria-setsize': ariaSetSize,
};
return (React.createElement(FocusZone, __assign({ "data-is-focusable": true }, getNativeProps(this.props, divProperties), (typeof isDraggable === 'boolean'
? {
'data-is-draggable': isDraggable, // This data attribute is used by some host applications.
draggable: isDraggable,
}
: {}), focusZoneProps, groupedListRowProps, { direction: focusZoneDirection,
// eslint-disable-next-line @typescript-eslint/no-deprecated
elementRef: this._root, componentRef: this._focusZone, role: role, "aria-label": ariaLabel, "aria-disabled": disabled || undefined, "aria-describedby": ariaRowDescription ? this._ariaRowDescriptionId : ariaDescribedBy, className: this._classNames.root, "data-selection-index": itemIndex, "data-selection-touch-invoke": true, "data-selection-disabled": (_b = this.props['data-selection-disabled']) !== null && _b !== void 0 ? _b : (disabled || undefined), "data-item-index": itemIndex, "aria-rowindex": ariaPositionInSet === undefined ? itemIndex + flatIndexOffset : undefined, "data-automationid": "DetailsRow", "aria-selected": ariaSelected, allowFocusRoot: true }),
ariaRowDescription ? (React.createElement("span", { key: "description", role: "presentation", hidden: true, id: this._ariaRowDescriptionId }, ariaRowDescription)) : null,
showCheckbox && (React.createElement("div", { role: "gridcell", "data-selection-toggle": true, className: this._classNames.checkCell }, onRenderCheck({
id: id ? "".concat(id, "-checkbox") : undefined,
selected: isSelected,
selectionMode: selectionMode,
anySelected: isSelectionModal,
'aria-label': checkButtonAriaLabel,
'aria-labelledby': id ? ariaLabelledby : undefined,
canSelect: canSelect,
compact: compact,
className: this._classNames.check,
theme: theme,
isVisible: checkboxVisibility === CheckboxVisibility.always,
onRenderDetailsCheckbox: onRenderDetailsCheckbox,
useFastIcons: useFastIcons,
}))),
React.createElement(GroupSpacer, { indentWidth: indentWidth, role: "gridcell", count: groupNestingDepth === 0 ? -1 : groupNestingDepth }),
item && rowFields,
columnMeasureInfo && (React.createElement("span", { role: "presentation", className: css(this._classNames.cellMeasurer, this._classNames.cell), ref: this._cellMeasurer },
React.createElement(RowFields, { rowClassNames: this._rowClassNames, rowHeaderId: "".concat(id, "-header"), columns: [columnMeasureInfo.column], item: item, itemIndex: itemIndex, columnStartIndex: (showCheckbox ? 1 : 0) + (groupNestingDepth ? 1 : 0) + columns.length, onRenderItemColumn: onRenderItemColumn, getCellValueKey: getCellValueKey })))));
};
/**
* measure cell at index. and call the call back with the measured cell width when finish measure
*
* @param index - The cell index
* @param onMeasureDone - The call back function when finish measure
*/
DetailsRowBase.prototype.measureCell = function (index, onMeasureDone) {
var _a = this.props.columns, columns = _a === void 0 ? NO_COLUMNS : _a;
var column = __assign({}, columns[index]);
column.minWidth = 0;
column.maxWidth = 999999;
delete column.calculatedWidth;
this.setState({
columnMeasureInfo: {
index: index,
column: column,
onMeasureDone: onMeasureDone,
},
});
};
DetailsRowBase.prototype.focus = function (forceIntoFirstElement) {
var _a;
if (forceIntoFirstElement === void 0) { forceIntoFirstElement = false; }
return !!((_a = this._focusZone.current) === null || _a === void 0 ? void 0 : _a.focus(forceIntoFirstElement));
};
DetailsRowBase.prototype._onRenderCheck = function (props) {
return React.createElement(DetailsRowCheck, __assign({}, props));
};
DetailsRowBase.prototype._getRowDragDropOptions = function () {
var _a = this.props, item = _a.item, itemIndex = _a.itemIndex, dragDropEvents = _a.dragDropEvents, eventsToRegister = _a.eventsToRegister;
var options = {
eventMap: eventsToRegister,
selectionIndex: itemIndex,
context: { data: item, index: itemIndex },
canDrag: dragDropEvents.canDrag,
canDrop: dragDropEvents.canDrop,
onDragStart: dragDropEvents.onDragStart,
updateDropState: this._updateDroppingState,
onDrop: dragDropEvents.onDrop,
onDragEnd: dragDropEvents.onDragEnd,
onDragOver: dragDropEvents.onDragOver,
};
return options;
};
return DetailsRowBase;
}(React.Component));
export { DetailsRowBase };
function getSelectionState(props) {
var _a;
var itemIndex = props.itemIndex, selection = props.selection;
return {
isSelected: !!(selection === null || selection === void 0 ? void 0 : selection.isIndexSelected(itemIndex)),
isSelectionModal: !!((_a = selection === null || selection === void 0 ? void 0 : selection.isModal) === null || _a === void 0 ? void 0 : _a.call(selection)),
};
}
//# sourceMappingURL=DetailsRow.base.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
import * as React from 'react';
import type { IDetailsRowProps, IDetailsRowBaseProps } from './DetailsRow.types';
export declare const DetailsRow: React.FunctionComponent<IDetailsRowBaseProps>;
export type { IDetailsRowProps, IDetailsRowBaseProps };
@@ -0,0 +1,7 @@
import { styled } from '../../Utilities';
import { DetailsRowBase } from './DetailsRow.base';
import { getDetailsRowStyles } from './DetailsRow.styles';
export var DetailsRow = styled(DetailsRowBase, getDetailsRowStyles, undefined, {
scope: 'DetailsRow',
});
//# sourceMappingURL=DetailsRow.js.map
@@ -0,0 +1 @@
{"version":3,"file":"DetailsRow.js","sourceRoot":"../src/","sources":["components/DetailsList/DetailsRow.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAQ1D,MAAM,CAAC,IAAM,UAAU,GAAkD,MAAM,CAI7E,cAAc,EAAE,mBAAmB,EAAE,SAAS,EAAE;IAChD,KAAK,EAAE,YAAY;CACpB,CAAC,CAAC","sourcesContent":["import * as React from 'react';\nimport { styled } from '../../Utilities';\nimport { DetailsRowBase } from './DetailsRow.base';\nimport { getDetailsRowStyles } from './DetailsRow.styles';\nimport type {\n IDetailsRowProps,\n IDetailsRowBaseProps,\n IDetailsRowStyleProps,\n IDetailsRowStyles,\n} from './DetailsRow.types';\n\nexport const DetailsRow: React.FunctionComponent<IDetailsRowBaseProps> = styled<\n IDetailsRowBaseProps,\n IDetailsRowStyleProps,\n IDetailsRowStyles\n>(DetailsRowBase, getDetailsRowStyles, undefined, {\n scope: 'DetailsRow',\n});\n\nexport type { IDetailsRowProps, IDetailsRowBaseProps };\n"]}
@@ -0,0 +1,22 @@
import type { IDetailsRowStyleProps, IDetailsRowStyles, ICellStyleProps } from './DetailsRow.types';
export declare const DetailsRowGlobalClassNames: {
root: string;
compact: string;
cell: string;
cellAnimation: string;
cellCheck: string;
check: string;
cellMeasurer: string;
listCellFirstChild: string;
isContentUnselectable: string;
isSelected: string;
isCheckVisible: string;
isRowHeader: string;
fields: string;
};
export declare const DEFAULT_CELL_STYLE_PROPS: ICellStyleProps;
export declare const DEFAULT_ROW_HEIGHTS: {
rowHeight: number;
compactRowHeight: number;
};
export declare const getDetailsRowStyles: (props: IDetailsRowStyleProps) => IDetailsRowStyles;
@@ -0,0 +1,350 @@
import { __assign } from "tslib";
import { AnimationClassNames, AnimationStyles, HighContrastSelector, getFocusStyle, getGlobalClassNames, FontWeights, getHighContrastNoAdjustStyle, } from '../../Styling';
import { IsFocusVisibleClassName } from '../../Utilities';
import { GlobalClassNames as LinkGlobalClassNames } from '../../components/Link/Link.styles';
export var DetailsRowGlobalClassNames = {
root: 'ms-DetailsRow',
// TODO: in Fabric 7.0 lowercase the 'Compact' for consistency across other components.
compact: 'ms-DetailsList--Compact',
cell: 'ms-DetailsRow-cell',
cellAnimation: 'ms-DetailsRow-cellAnimation',
cellCheck: 'ms-DetailsRow-cellCheck',
check: 'ms-DetailsRow-check',
cellMeasurer: 'ms-DetailsRow-cellMeasurer',
listCellFirstChild: 'ms-List-cell:first-child',
isContentUnselectable: 'is-contentUnselectable',
isSelected: 'is-selected',
isCheckVisible: 'is-check-visible',
isRowHeader: 'is-row-header',
fields: 'ms-DetailsRow-fields',
};
var IsFocusableSelector = "[data-is-focusable='true']";
export var DEFAULT_CELL_STYLE_PROPS = {
cellLeftPadding: 12,
cellRightPadding: 8,
cellExtraRightPadding: 24,
};
// Source of default row heights to share.
export var DEFAULT_ROW_HEIGHTS = {
rowHeight: 42,
compactRowHeight: 32,
};
// Constant values
var values = __assign(__assign({}, DEFAULT_ROW_HEIGHTS), { rowVerticalPadding: 11, compactRowVerticalPadding: 6 });
export var getDetailsRowStyles = function (props) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
var theme = props.theme, isSelected = props.isSelected, canSelect = props.canSelect, droppingClassName = props.droppingClassName, isCheckVisible = props.isCheckVisible, checkboxCellClassName = props.checkboxCellClassName, compact = props.compact, className = props.className, _q = props.cellStyleProps, cellStyleProps = _q === void 0 ? DEFAULT_CELL_STYLE_PROPS : _q, enableUpdateAnimations = props.enableUpdateAnimations, disabled = props.disabled;
var palette = theme.palette, fonts = theme.fonts;
var neutralPrimary = palette.neutralPrimary, white = palette.white, neutralSecondary = palette.neutralSecondary, neutralLighter = palette.neutralLighter, neutralLight = palette.neutralLight, neutralDark = palette.neutralDark, neutralQuaternaryAlt = palette.neutralQuaternaryAlt;
var _r = theme.semanticColors, focusBorder = _r.focusBorder, focusedLinkColor = _r.linkHovered;
var classNames = getGlobalClassNames(DetailsRowGlobalClassNames, theme);
var colors = {
// Default
defaultHeaderText: neutralPrimary,
defaultMetaText: neutralSecondary,
defaultBackground: white,
// Default Hover
defaultHoverHeaderText: neutralDark,
defaultHoverMetaText: neutralPrimary,
defaultHoverBackground: neutralLighter,
// Selected
selectedHeaderText: neutralDark,
selectedMetaText: neutralPrimary,
selectedBackground: neutralLight,
// Selected Hover
selectedHoverHeaderText: neutralDark,
selectedHoverMetaText: neutralPrimary,
selectedHoverBackground: neutralQuaternaryAlt,
// Focus
focusHeaderText: neutralDark,
focusMetaText: neutralPrimary,
focusBackground: neutralLight,
focusHoverBackground: neutralQuaternaryAlt,
};
var rowHighContrastFocus = {
top: 2,
right: 2,
bottom: 2,
left: 2,
};
// Selected row styles
var selectedStyles = [
getFocusStyle(theme, {
inset: -1,
borderColor: focusBorder,
outlineColor: white,
highContrastStyle: rowHighContrastFocus,
pointerEvents: 'none',
}),
classNames.isSelected,
{
color: colors.selectedMetaText,
background: colors.selectedBackground,
borderBottom: "1px solid ".concat(white),
selectors: (_a = {
'&:before': {
position: 'absolute',
display: 'block',
top: -1,
height: 1,
bottom: 0,
left: 0,
right: 0,
content: '',
borderTop: "1px solid ".concat(white),
}
},
_a[".".concat(classNames.cell, " > .").concat(LinkGlobalClassNames.root)] = {
color: focusedLinkColor,
selectors: (_b = {},
_b[HighContrastSelector] = {
color: 'HighlightText',
},
_b),
},
// Selected State hover
_a['&:hover'] = {
background: colors.selectedHoverBackground,
color: colors.selectedHoverMetaText,
selectors: (_c = {},
// Selected State hover meta cell
_c[HighContrastSelector] = {
background: 'Highlight',
selectors: (_d = {},
_d[".".concat(classNames.cell)] = {
color: 'HighlightText',
},
_d[".".concat(classNames.cell, " > .").concat(LinkGlobalClassNames.root)] = {
forcedColorAdjust: 'none',
color: 'HighlightText',
},
_d),
},
// Selected State hover Header cell
_c[".".concat(classNames.isRowHeader)] = {
color: colors.selectedHoverHeaderText,
selectors: (_e = {},
_e[HighContrastSelector] = {
color: 'HighlightText',
},
_e),
},
_c),
},
// Focus state
_a['&:focus'] = {
background: colors.focusBackground,
selectors: (_f = {},
// Selected State hover meta cell
_f[".".concat(classNames.cell)] = {
color: colors.focusMetaText,
selectors: (_g = {},
_g[HighContrastSelector] = {
color: 'HighlightText',
selectors: {
'> a': {
color: 'HighlightText',
},
},
},
_g),
},
// Row header cell
_f[".".concat(classNames.isRowHeader)] = {
color: colors.focusHeaderText,
selectors: (_h = {},
_h[HighContrastSelector] = {
color: 'HighlightText',
},
_h),
},
// Ensure high-contrast mode overrides default focus background
_f[HighContrastSelector] = {
background: 'Highlight',
},
_f),
},
_a[HighContrastSelector] = __assign(__assign({ background: 'Highlight', color: 'HighlightText' }, getHighContrastNoAdjustStyle()), { selectors: {
a: {
color: 'HighlightText',
},
} }),
// Focus and hover state
_a['&:focus:hover'] = {
background: colors.focusHoverBackground,
},
_a),
},
];
var cannotSelectStyles = [
classNames.isContentUnselectable,
{
userSelect: 'none',
cursor: 'default',
},
];
var rootCompactStyles = {
minHeight: values.compactRowHeight,
border: 0,
};
var cellCompactStyles = {
minHeight: values.compactRowHeight,
paddingTop: values.compactRowVerticalPadding,
paddingBottom: values.compactRowVerticalPadding,
paddingLeft: "".concat(cellStyleProps.cellLeftPadding, "px"),
};
var defaultCellStyles = [
getFocusStyle(theme, { inset: -1 }),
classNames.cell,
{
display: 'inline-block',
position: 'relative',
boxSizing: 'border-box',
minHeight: values.rowHeight,
verticalAlign: 'top',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
paddingTop: values.rowVerticalPadding,
paddingBottom: values.rowVerticalPadding,
paddingLeft: "".concat(cellStyleProps.cellLeftPadding, "px"),
selectors: (_j = {
'& > button': {
maxWidth: '100%',
}
},
_j[IsFocusableSelector] = getFocusStyle(theme, { inset: -1, borderColor: neutralSecondary, outlineColor: white }),
_j),
},
isSelected && {
selectors: (_k = {},
_k[HighContrastSelector] = __assign({ background: 'Highlight', color: 'HighlightText' }, getHighContrastNoAdjustStyle()),
_k),
},
compact && cellCompactStyles,
disabled && { opacity: 0.5 },
];
return {
root: [
classNames.root,
AnimationClassNames.fadeIn400,
droppingClassName,
theme.fonts.small,
isCheckVisible && classNames.isCheckVisible,
getFocusStyle(theme, { borderColor: focusBorder, outlineColor: white }),
{
borderBottom: "1px solid ".concat(neutralLighter),
background: colors.defaultBackground,
color: colors.defaultMetaText,
// This ensures that the row always tries to consume is minimum width and does not compress.
display: 'inline-flex',
minWidth: '100%',
minHeight: values.rowHeight,
whiteSpace: 'nowrap',
padding: 0,
boxSizing: 'border-box',
verticalAlign: 'top',
textAlign: 'left',
selectors: (_l = {},
_l[".".concat(classNames.listCellFirstChild, " &:before")] = {
display: 'none',
},
_l['&:hover'] = {
background: colors.defaultHoverBackground,
color: colors.defaultHoverMetaText,
selectors: (_m = {},
_m[".".concat(classNames.isRowHeader)] = {
color: colors.defaultHoverHeaderText,
},
_m[".".concat(classNames.cell, " > .").concat(LinkGlobalClassNames.root)] = {
color: focusedLinkColor,
},
_m),
},
_l["&:hover .".concat(classNames.check)] = {
opacity: 1,
},
// eslint-disable-next-line @fluentui/max-len
_l[".".concat(IsFocusVisibleClassName, " &:focus .").concat(classNames.check, ", :host(.").concat(IsFocusVisibleClassName, ") &:focus .").concat(classNames.check)] = {
opacity: 1,
},
_l['.ms-GroupSpacer'] = {
flexShrink: 0,
flexGrow: 0,
},
_l),
},
isSelected && selectedStyles,
!canSelect && cannotSelectStyles,
compact && rootCompactStyles,
className,
],
cellUnpadded: {
paddingRight: "".concat(cellStyleProps.cellRightPadding, "px"),
},
cellPadded: {
paddingRight: "".concat(cellStyleProps.cellExtraRightPadding + cellStyleProps.cellRightPadding, "px"),
selectors: (_o = {},
_o["&.".concat(classNames.cellCheck)] = {
paddingRight: 0,
},
_o),
},
cell: defaultCellStyles,
cellAnimation: enableUpdateAnimations && AnimationStyles.slideLeftIn40,
cellMeasurer: [
classNames.cellMeasurer,
{
overflow: 'visible',
whiteSpace: 'nowrap',
},
],
checkCell: [
defaultCellStyles,
classNames.cellCheck,
checkboxCellClassName,
{
padding: 0,
// Ensure that the check cell covers the top border of the cell.
// This ensures the click target does not leave a spot which would
// cause other items to be deselected.
paddingTop: 1,
marginTop: -1,
flexShrink: 0,
},
],
fields: [
classNames.fields,
{
display: 'flex',
alignItems: 'stretch',
},
],
isRowHeader: [
classNames.isRowHeader,
{
color: colors.defaultHeaderText,
fontSize: fonts.medium.fontSize,
},
isSelected && {
color: colors.selectedHeaderText,
fontWeight: FontWeights.semibold,
selectors: (_p = {},
_p[HighContrastSelector] = {
color: 'HighlightText',
},
_p),
},
],
isMultiline: [
defaultCellStyles,
{
whiteSpace: 'normal',
wordBreak: 'break-word',
textOverflow: 'clip',
},
],
check: [classNames.check],
};
};
//# sourceMappingURL=DetailsRow.styles.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,276 @@
import * as React from 'react';
import { DetailsRowBase } from './DetailsRow.base';
import { CheckboxVisibility } from './DetailsList.types';
import { SelectionMode } from '../../Selection';
import { CollapseAllVisibility } from '../GroupedList/GroupedList.types';
import type { IStyle, ITheme } from '../../Styling';
import type { IColumn, IDetailsListProps } from './DetailsList.types';
import type { ISelection } from '../../Selection';
import type { IDragDropHelper, IDragDropEvents } from '../../DragDrop';
import type { IViewport } from '../../utilities/decorators/withViewport';
import type { IGroup } from '../GroupedList/GroupedList.types';
import type { IBaseProps, IRefObject, IStyleFunctionOrObject, IRenderFunction, IComponentAs } from '../../Utilities';
import type { IDetailsRowCheckProps, IDetailsCheckboxProps } from './DetailsRowCheck.types';
import type { IDetailsRowFieldsProps } from './DetailsRowFields.types';
import type { IFocusZoneProps } from '../../FocusZone';
import type { JSXElement } from '@fluentui/utilities';
/**
* {@docCategory DetailsList}
*/
export interface IDetailsRow {
}
/**
* {@docCategory DetailsList}
*/
export interface IDetailsItemProps {
/**
* Column metadata
*/
columns?: IColumn[];
/**
* Nesting depth of a grouping
*/
groupNestingDepth?: number;
/**
* How much to indent
*/
indentWidth?: number | undefined;
/**
* Selection from utilities
*/
selection?: ISelection | undefined;
/**
* Selection mode
*/
selectionMode?: SelectionMode | undefined;
/**
* Viewport of the virtualized list
*
* @deprecated Use `rowWidth` instead
*/
viewport?: IViewport | undefined;
/**
* Checkbox visibility
*/
checkboxVisibility?: CheckboxVisibility | undefined;
/**
* Rules for rendering column cells.
*/
cellStyleProps?: ICellStyleProps;
/**
* Minimum width of the row.
*
* @defaultvalue 0
*/
rowWidth?: number;
}
/**
* {@docCategory DetailsList}
*/
export interface IDetailsRowBaseProps extends Pick<IDetailsListProps, 'onRenderItemColumn' | 'getCellValueKey' | 'onRenderField'>, IBaseProps<IDetailsRow>, IDetailsItemProps {
/**
* Theme provided by styled() function
*/
theme?: ITheme;
/**
* Overriding styles to this row
*/
styles?: IStyleFunctionOrObject<IDetailsRowStyleProps, IDetailsRowStyles>;
/**
* Ref of the component
*/
componentRef?: IRefObject<IDetailsRow>;
/**
* Data source for this component
*/
item: any;
/**
* Index of the collection of items of the DetailsList
*/
itemIndex: number;
/**
* Offset used to calculate the aria-rowindex value based on itemIndex
* @defaultvalue 2
*/
flatIndexOffset?: number;
/**
* Whether to render in compact mode
*/
compact?: boolean;
/**
* A list of events to register
*/
eventsToRegister?: {
eventName: string;
callback: (item?: any, index?: number, event?: any) => void;
}[];
/**
* Callback for did mount for parent
*/
onDidMount?: (row?: DetailsRowBase) => void;
/**
* Callback for will mount for parent
*/
onWillUnmount?: (row?: DetailsRowBase) => void;
/**
* Callback for rendering a checkbox
*/
onRenderCheck?: (props: IDetailsRowCheckProps) => JSXElement;
/**
* If provided, can be used to render a custom checkbox
*/
onRenderDetailsCheckbox?: IRenderFunction<IDetailsCheckboxProps>;
/**
* Handling drag and drop events
*/
dragDropEvents?: IDragDropEvents;
/**
* Helper for the drag and drop
*/
dragDropHelper?: IDragDropHelper;
/**
* Collapse all visibility
*/
collapseAllVisibility?: CollapseAllVisibility;
/**
* Callback for getting the row aria label
*/
getRowAriaLabel?: (item: any) => string;
/**
* Callback for getting the row aria description
*/
getRowAriaDescription?: (item: any) => string;
/**
* Callback for getting the row aria-describedby
*/
getRowAriaDescribedBy?: (item: any) => string;
/**
* Check button's aria label
*/
checkButtonAriaLabel?: string;
/**
* Class name for the checkbox cell
*/
checkboxCellClassName?: string;
/**
* DOM element into which to render row field
*/
rowFieldsAs?: IComponentAs<IDetailsRowFieldsProps>;
/**
* Overriding class name
*/
className?: string;
/** Whether to animate updates */
enableUpdateAnimations?: boolean;
/**
* Rerender DetailsRow only when props changed. Might cause regression when depending on external updates.
* @defaultvalue false
*/
useReducedRowRenderer?: boolean;
/**
* Optional pre-rendered content per column. Preferred over onRender or onRenderItemColumn if provided.
*/
cellsByColumn?: {
[columnKey: string]: React.ReactNode;
};
/**
* Whether to use fast icon and check components. The icons can't be targeted by customization
* but are still customizable via class names.
* @defaultvalue true
*/
useFastIcons?: boolean;
/** Role for the row. */
role?: string;
/**
* Whether the row is rendered within a grid.
* In DetailsList this should be true, and in GroupedList this should be false.
*/
isGridRow?: boolean;
/**
* Id for row
*/
id?: string;
/**
* Group row item belongs to.
* When using GroupedList, this needs to be passed in order to calculate
* the correct aria-posinset and aria-setsize values.
*/
group?: IGroup;
/**
* Properties to pass to the rows' FocusZone.
*/
focusZoneProps?: IFocusZoneProps;
/** whether or not row should be rendered in disabled state */
disabled?: boolean;
}
/**
* {@docCategory DetailsList}
*/
export interface IDetailsRowProps extends IDetailsRowBaseProps {
/**
* Column metadata
*/
columns: IColumn[];
/**
* Selection from utilities
*/
selection: ISelection;
/**
* Selection mode
*/
selectionMode: SelectionMode;
}
/**
* {@docCategory DetailsList}
*/
export type IDetailsRowStyleProps = Required<Pick<IDetailsRowProps, 'theme'>> & Pick<IDetailsRowProps, 'disabled'> & {
/** Whether the row is selected */
isSelected?: boolean;
/** Whether there are any rows in the list selected */
anySelected?: boolean;
/** Whether this row can be selected */
canSelect?: boolean;
/** Class name of when this becomes a drop target. */
droppingClassName?: string;
/** Is the checkbox visible */
isCheckVisible?: boolean;
/** Is this a row header */
isRowHeader?: boolean;
/** A class name from the checkbox cell, so proper styling can be targeted */
checkboxCellClassName?: string;
/** CSS class name for the component */
className?: string;
/** Is list in compact mode */
compact?: boolean;
cellStyleProps?: ICellStyleProps;
/** Whether to animate updates */
enableUpdateAnimations?: boolean;
};
/**
* {@docCategory DetailsList}
*/
export interface ICellStyleProps {
cellLeftPadding: number;
cellRightPadding: number;
cellExtraRightPadding: number;
}
/**
* {@docCategory DetailsList}
*/
export interface IDetailsRowStyles {
root: IStyle;
cell: IStyle;
cellAnimation: IStyle;
cellUnpadded: IStyle;
cellPadded: IStyle;
checkCell: IStyle;
isRowHeader: IStyle;
isMultiline: IStyle;
fields: IStyle;
cellMeasurer: IStyle;
/**
* @deprecated Node removed, do not use
*/
checkCover?: IStyle;
check: IStyle;
}
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=DetailsRow.types.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
import * as React from 'react';
import type { IDetailsRowCheckProps } from './DetailsRowCheck.types';
export declare const DetailsRowCheck: React.FunctionComponent<React.PropsWithChildren<React.PropsWithChildren<IDetailsRowCheckProps>>>;
@@ -0,0 +1,47 @@
import { __assign, __rest } from "tslib";
import * as React from 'react';
import { css, styled, classNamesFunction, composeRenderFunction, getNativeElementProps } from '../../Utilities';
import { Check } from '../../Check';
import { getDetailsRowCheckStyles } from './DetailsRowCheck.styles';
import { SelectionMode } from '../../Selection';
var getClassNames = classNamesFunction();
var DetailsRowCheckBase = function (props) {
var _a = props.isVisible, isVisible = _a === void 0 ? false : _a, _b = props.canSelect, canSelect = _b === void 0 ? false : _b, _c = props.anySelected, anySelected = _c === void 0 ? false : _c, _d = props.selected, selected = _d === void 0 ? false : _d, selectionMode = props.selectionMode, _e = props.isHeader, isHeader = _e === void 0 ? false : _e, className = props.className, checkClassName = props.checkClassName, styles = props.styles, theme = props.theme, compact = props.compact, onRenderDetailsCheckbox = props.onRenderDetailsCheckbox, _f = props.useFastIcons, useFastIcons = _f === void 0 ? true : _f, // must be removed from buttonProps
buttonProps = __rest(props, ["isVisible", "canSelect", "anySelected", "selected", "selectionMode", "isHeader", "className", "checkClassName", "styles", "theme", "compact", "onRenderDetailsCheckbox", "useFastIcons"]);
var defaultCheckboxRender = useFastIcons ? _fastDefaultCheckboxRender : _defaultCheckboxRender;
var onRenderCheckbox = onRenderDetailsCheckbox
? composeRenderFunction(onRenderDetailsCheckbox, defaultCheckboxRender)
: defaultCheckboxRender;
var classNames = getClassNames(styles, {
theme: theme,
canSelect: canSelect,
selected: selected,
anySelected: anySelected,
className: className,
isHeader: isHeader,
isVisible: isVisible,
compact: compact,
});
var detailsCheckboxProps = {
checked: selected,
theme: theme,
};
var divProps = getNativeElementProps('div', buttonProps, ['aria-label', 'aria-labelledby', 'aria-describedby']);
var checkRole = selectionMode === SelectionMode.single ? 'radio' : 'checkbox';
return canSelect ? (React.createElement("div", __assign({}, buttonProps, { role: checkRole,
// eslint-disable-next-line @typescript-eslint/no-deprecated
className: css(classNames.root, classNames.check), "aria-checked": selected, "data-selection-toggle": true, "data-automationid": "DetailsRowCheck", tabIndex: -1 }), onRenderCheckbox(detailsCheckboxProps))) : (
// eslint-disable-next-line @typescript-eslint/no-deprecated
React.createElement("div", __assign({}, divProps, { className: css(classNames.root, classNames.check) })));
};
var FastCheck = React.memo(function (props) {
return React.createElement(Check, { theme: props.theme, checked: props.checked, className: props.className, useFastIcons: true });
});
function _defaultCheckboxRender(checkboxProps) {
return React.createElement(Check, { checked: checkboxProps.checked });
}
function _fastDefaultCheckboxRender(checkboxProps) {
return React.createElement(FastCheck, { theme: checkboxProps.theme, checked: checkboxProps.checked });
}
export var DetailsRowCheck = styled(DetailsRowCheckBase, getDetailsRowCheckStyles, undefined, { scope: 'DetailsRowCheck' }, true);
//# sourceMappingURL=DetailsRowCheck.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
import type { IDetailsRowCheckStyleProps, IDetailsRowCheckStyles } from './DetailsRowCheck.types';
export declare const CHECK_CELL_WIDTH = 48;
export declare const getDetailsRowCheckStyles: (props: IDetailsRowCheckStyleProps) => IDetailsRowCheckStyles;
@@ -0,0 +1,45 @@
import { getGlobalClassNames, getFocusStyle } from '../../Styling';
import { DEFAULT_ROW_HEIGHTS } from './DetailsRow.styles';
import { HEADER_HEIGHT } from './DetailsHeader.styles';
import { CheckGlobalClassNames } from '../../components/Check/Check.styles';
var GlobalClassNames = {
root: 'ms-DetailsRow-check',
isDisabled: 'ms-DetailsRow-check--isDisabled',
isHeader: 'ms-DetailsRow-check--isHeader',
};
export var CHECK_CELL_WIDTH = 48;
export var getDetailsRowCheckStyles = function (props) {
var theme = props.theme, className = props.className, isHeader = props.isHeader, selected = props.selected, anySelected = props.anySelected, canSelect = props.canSelect, compact = props.compact, isVisible = props.isVisible;
var classNames = getGlobalClassNames(GlobalClassNames, theme);
var rowHeight = DEFAULT_ROW_HEIGHTS.rowHeight, compactRowHeight = DEFAULT_ROW_HEIGHTS.compactRowHeight;
var height = isHeader ? HEADER_HEIGHT : compact ? compactRowHeight : rowHeight;
var isCheckVisible = isVisible || selected || anySelected;
return {
root: [classNames.root, className],
check: [
!canSelect && classNames.isDisabled,
isHeader && classNames.isHeader,
getFocusStyle(theme),
theme.fonts.small,
CheckGlobalClassNames.checkHost,
{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
cursor: 'default',
boxSizing: 'border-box',
verticalAlign: 'top',
background: 'none',
backgroundColor: 'transparent',
border: 'none',
opacity: isCheckVisible ? 1 : 0,
height: height,
width: CHECK_CELL_WIDTH,
padding: 0,
margin: 0,
},
],
isDisabled: [],
};
};
//# sourceMappingURL=DetailsRowCheck.styles.js.map
@@ -0,0 +1 @@
{"version":3,"file":"DetailsRowCheck.styles.js","sourceRoot":"../src/","sources":["components/DetailsList/DetailsRowCheck.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAG5E,IAAM,gBAAgB,GAAG;IACvB,IAAI,EAAE,qBAAqB;IAC3B,UAAU,EAAE,iCAAiC;IAC7C,QAAQ,EAAE,+BAA+B;CAC1C,CAAC;AAEF,MAAM,CAAC,IAAM,gBAAgB,GAAG,EAAE,CAAC;AAEnC,MAAM,CAAC,IAAM,wBAAwB,GAAG,UAAC,KAAiC;IAChE,IAAA,KAAK,GAAgF,KAAK,MAArF,EAAE,SAAS,GAAqE,KAAK,UAA1E,EAAE,QAAQ,GAA2D,KAAK,SAAhE,EAAE,QAAQ,GAAiD,KAAK,SAAtD,EAAE,WAAW,GAAoC,KAAK,YAAzC,EAAE,SAAS,GAAyB,KAAK,UAA9B,EAAE,OAAO,GAAgB,KAAK,QAArB,EAAE,SAAS,GAAK,KAAK,UAAV,CAAW;IACnG,IAAM,UAAU,GAAG,mBAAmB,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;IACxD,IAAA,SAAS,GAAuB,mBAAmB,UAA1C,EAAE,gBAAgB,GAAK,mBAAmB,iBAAxB,CAAyB;IAE5D,IAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC;IAEjF,IAAM,cAAc,GAAG,SAAS,IAAI,QAAQ,IAAI,WAAW,CAAC;IAE5D,OAAO;QACL,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC;QAElC,KAAK,EAAE;YACL,CAAC,SAAS,IAAI,UAAU,CAAC,UAAU;YACnC,QAAQ,IAAI,UAAU,CAAC,QAAQ;YAC/B,aAAa,CAAC,KAAK,CAAC;YACpB,KAAK,CAAC,KAAK,CAAC,KAAK;YACjB,qBAAqB,CAAC,SAAS;YAC/B;gBACE,OAAO,EAAE,MAAM;gBACf,UAAU,EAAE,QAAQ;gBACpB,cAAc,EAAE,QAAQ;gBACxB,MAAM,EAAE,SAAS;gBACjB,SAAS,EAAE,YAAY;gBACvB,aAAa,EAAE,KAAK;gBACpB,UAAU,EAAE,MAAM;gBAClB,eAAe,EAAE,aAAa;gBAC9B,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC/B,MAAM,QAAA;gBACN,KAAK,EAAE,gBAAgB;gBACvB,OAAO,EAAE,CAAC;gBACV,MAAM,EAAE,CAAC;aACV;SACF;QAED,UAAU,EAAE,EAAE;KACf,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { getGlobalClassNames, getFocusStyle } from '../../Styling';\nimport { DEFAULT_ROW_HEIGHTS } from './DetailsRow.styles';\nimport { HEADER_HEIGHT } from './DetailsHeader.styles';\nimport { CheckGlobalClassNames } from '../../components/Check/Check.styles';\nimport type { IDetailsRowCheckStyleProps, IDetailsRowCheckStyles } from './DetailsRowCheck.types';\n\nconst GlobalClassNames = {\n root: 'ms-DetailsRow-check',\n isDisabled: 'ms-DetailsRow-check--isDisabled',\n isHeader: 'ms-DetailsRow-check--isHeader',\n};\n\nexport const CHECK_CELL_WIDTH = 48;\n\nexport const getDetailsRowCheckStyles = (props: IDetailsRowCheckStyleProps): IDetailsRowCheckStyles => {\n const { theme, className, isHeader, selected, anySelected, canSelect, compact, isVisible } = props;\n const classNames = getGlobalClassNames(GlobalClassNames, theme);\n const { rowHeight, compactRowHeight } = DEFAULT_ROW_HEIGHTS;\n\n const height = isHeader ? HEADER_HEIGHT : compact ? compactRowHeight : rowHeight;\n\n const isCheckVisible = isVisible || selected || anySelected;\n\n return {\n root: [classNames.root, className],\n\n check: [\n !canSelect && classNames.isDisabled,\n isHeader && classNames.isHeader,\n getFocusStyle(theme),\n theme.fonts.small,\n CheckGlobalClassNames.checkHost,\n {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'default',\n boxSizing: 'border-box',\n verticalAlign: 'top',\n background: 'none',\n backgroundColor: 'transparent',\n border: 'none',\n opacity: isCheckVisible ? 1 : 0,\n height,\n width: CHECK_CELL_WIDTH,\n padding: 0,\n margin: 0,\n },\n ],\n\n isDisabled: [],\n };\n};\n"]}
@@ -0,0 +1,83 @@
import * as React from 'react';
import { SelectionMode } from '../../Selection';
import type { IStyle, ITheme } from '../../Styling';
import type { IStyleFunctionOrObject, IRenderFunction } from '../../Utilities';
/**
* {@docCategory DetailsList}
*/
export interface IDetailsRowCheckProps extends React.HTMLAttributes<HTMLElement> {
/**
* Theme provided by High-Order Component.
*/
theme?: ITheme;
/**
* Style override
*/
styles?: IStyleFunctionOrObject<IDetailsRowCheckStyleProps, IDetailsRowCheckStyles>;
/**
* Is the check part of the header in a DetailsList
*/
isHeader?: boolean;
/**
* Whether or not this check is selected
*/
selected?: boolean;
/**
* Is any selected - also true for isSelectionModal
*/
anySelected?: boolean;
/**
* Can this checkbox be selectable
*/
canSelect: boolean;
/**
* Selection mode
*/
selectionMode?: SelectionMode;
/**
* Is this in compact mode?
*/
compact?: boolean;
/**
* Optional className to attach to the slider root element.
*/
className?: string;
/**
* The classname to be passed down to Check component
*/
checkClassName?: string;
/**
* Whether or not this checkbox is visible
*/
isVisible?: boolean;
/**
* If provided, can be used to render a custom checkbox
*/
onRenderDetailsCheckbox?: IRenderFunction<IDetailsCheckboxProps>;
/**
* Whether to use fast icon and check components. The icons can't be targeted by customization
* but are still customizable via class names.
* @defaultvalue true
*/
useFastIcons?: boolean;
}
/**
* {@docCategory DetailsList}
*/
export type IDetailsRowCheckStyleProps = Required<Pick<IDetailsRowCheckProps, 'theme'>> & Pick<IDetailsRowCheckProps, 'compact' | 'isHeader' | 'selected' | 'anySelected' | 'canSelect' | 'className'> & {
/** Is checkbox visible */
isVisible?: boolean;
};
/**
* {@docCategory DetailsList}
*/
export interface IDetailsRowCheckStyles {
root: IStyle;
/** @deprecated Use `root` (they're applied to the same element) */
check: IStyle;
isDisabled: IStyle;
}
export interface IDetailsCheckboxProps {
checked: boolean;
theme?: ITheme;
}
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=DetailsRowCheck.types.js.map
@@ -0,0 +1 @@
{"version":3,"file":"DetailsRowCheck.types.js","sourceRoot":"../src/","sources":["components/DetailsList/DetailsRowCheck.types.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport { SelectionMode } from '../../Selection';\nimport type { IStyle, ITheme } from '../../Styling';\nimport type { IStyleFunctionOrObject, IRenderFunction } from '../../Utilities';\n\n/**\n * {@docCategory DetailsList}\n */\nexport interface IDetailsRowCheckProps extends React.HTMLAttributes<HTMLElement> {\n /**\n * Theme provided by High-Order Component.\n */\n theme?: ITheme;\n\n /**\n * Style override\n */\n styles?: IStyleFunctionOrObject<IDetailsRowCheckStyleProps, IDetailsRowCheckStyles>;\n\n /**\n * Is the check part of the header in a DetailsList\n */\n isHeader?: boolean;\n\n /**\n * Whether or not this check is selected\n */\n selected?: boolean;\n\n /**\n * Is any selected - also true for isSelectionModal\n */\n anySelected?: boolean;\n\n /**\n * Can this checkbox be selectable\n */\n canSelect: boolean;\n\n /**\n * Selection mode\n */\n selectionMode?: SelectionMode;\n\n /**\n * Is this in compact mode?\n */\n compact?: boolean;\n\n /**\n * Optional className to attach to the slider root element.\n */\n className?: string;\n\n /**\n * The classname to be passed down to Check component\n */\n checkClassName?: string;\n\n /**\n * Whether or not this checkbox is visible\n */\n isVisible?: boolean;\n\n /**\n * If provided, can be used to render a custom checkbox\n */\n onRenderDetailsCheckbox?: IRenderFunction<IDetailsCheckboxProps>;\n\n /**\n * Whether to use fast icon and check components. The icons can't be targeted by customization\n * but are still customizable via class names.\n * @defaultvalue true\n */\n useFastIcons?: boolean;\n}\n\n/**\n * {@docCategory DetailsList}\n */\nexport type IDetailsRowCheckStyleProps = Required<Pick<IDetailsRowCheckProps, 'theme'>> &\n Pick<IDetailsRowCheckProps, 'compact' | 'isHeader' | 'selected' | 'anySelected' | 'canSelect' | 'className'> & {\n /** Is checkbox visible */\n isVisible?: boolean;\n };\n\n/**\n * {@docCategory DetailsList}\n */\nexport interface IDetailsRowCheckStyles {\n root: IStyle;\n /** @deprecated Use `root` (they're applied to the same element) */\n check: IStyle;\n isDisabled: IStyle;\n}\n\nexport interface IDetailsCheckboxProps {\n checked: boolean;\n theme?: ITheme;\n}\n"]}
@@ -0,0 +1,8 @@
import * as React from 'react';
import type { IDetailsRowFieldsProps } from './DetailsRowFields.types';
/**
* Component for rendering a row's cells in a `DetailsList`.
*
* {@docCategory DetailsList}
*/
export declare const DetailsRowFields: React.FunctionComponent<IDetailsRowFieldsProps>;
@@ -0,0 +1,71 @@
import * as React from 'react';
import { composeRenderFunction, css } from '../../Utilities';
import { DEFAULT_CELL_STYLE_PROPS } from './DetailsRow.styles';
var getCellText = function (item, column) {
var value = item && column && column.fieldName ? item[column.fieldName] : '';
if (value === null || value === undefined) {
value = '';
}
if (typeof value === 'boolean') {
return value.toString();
}
return value;
};
/**
* Component for rendering a row's cells in a `DetailsList`.
*
* {@docCategory DetailsList}
*/
export var DetailsRowFields = function (props) {
var columns = props.columns, rowClassNames = props.rowClassNames, _a = props.cellStyleProps, cellStyleProps = _a === void 0 ? DEFAULT_CELL_STYLE_PROPS : _a, item = props.item, itemIndex = props.itemIndex, isSelected = props.isSelected, onRenderItemColumn = props.onRenderItemColumn, getCellValueKey = props.getCellValueKey, propsOnRenderField = props.onRenderField, cellsByColumn = props.cellsByColumn, enableUpdateAnimations = props.enableUpdateAnimations, rowHeaderId = props.rowHeaderId;
var cellValueKeysRef = React.useRef(undefined);
var cellValueKeys = cellValueKeysRef.current || (cellValueKeysRef.current = {});
var defaultOnRenderField = React.useCallback(function (fieldProps) {
var column = fieldProps.column, cellValueKey = fieldProps.cellValueKey, className = fieldProps.className, onRender = fieldProps.onRender, fieldItem = fieldProps.item, fieldItemIndex = fieldProps.itemIndex;
var width = typeof column.calculatedWidth === 'undefined'
? 'auto'
: column.calculatedWidth +
cellStyleProps.cellLeftPadding +
cellStyleProps.cellRightPadding +
(column.isPadded ? cellStyleProps.cellExtraRightPadding : 0);
var key = "".concat(column.key).concat(cellValueKey !== undefined ? "-".concat(cellValueKey) : '');
return (React.createElement("div", { key: key, id: column.isRowHeader ? rowHeaderId : undefined, role: column.isRowHeader ? 'rowheader' : 'gridcell', className: css(column.className, column.isMultiline && rowClassNames.isMultiline, column.isRowHeader && rowClassNames.isRowHeader, rowClassNames.cell, column.isPadded ? rowClassNames.cellPadded : rowClassNames.cellUnpadded, className), style: { width: width }, "data-automationid": "DetailsRowCell", "data-automation-key": column.key }, onRender(fieldItem, fieldItemIndex, column)));
}, [rowClassNames, cellStyleProps, rowHeaderId]);
return (React.createElement("div", { className: rowClassNames.fields, "data-automationid": "DetailsRowFields", role: "presentation" }, columns.map(function (column) {
var _a = column.getValueKey, getValueKey = _a === void 0 ? getCellValueKey : _a;
var onRender = (cellsByColumn && column.key in cellsByColumn && (function () { return cellsByColumn[column.key]; })) ||
column.onRender ||
onRenderItemColumn ||
defaultOnRender;
var onRenderField = defaultOnRenderField;
if (column.onRenderField) {
onRenderField = composeRenderFunction(column.onRenderField, onRenderField);
}
if (propsOnRenderField) {
onRenderField = composeRenderFunction(propsOnRenderField, onRenderField);
}
var previousValueKey = cellValueKeys[column.key];
var cellValueKey = enableUpdateAnimations && getValueKey ? getValueKey(item, itemIndex, column) : undefined;
var showAnimation = false;
if (cellValueKey !== undefined && previousValueKey !== undefined && cellValueKey !== previousValueKey) {
showAnimation = true;
}
cellValueKeys[column.key] = cellValueKey;
return onRenderField({
item: item,
itemIndex: itemIndex,
isSelected: isSelected,
column: column,
cellValueKey: cellValueKey,
className: showAnimation ? rowClassNames.cellAnimation : undefined,
onRender: onRender,
});
})));
};
function defaultOnRender(item, index, column) {
if (!item || !column) {
return null;
}
return getCellText(item, column);
}
//# sourceMappingURL=DetailsRowFields.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,56 @@
import type { IColumn } from './DetailsList.types';
import type { ICellStyleProps, IDetailsRowStyles } from './DetailsRow.types';
import type { IDetailsListProps } from './DetailsList';
import type { IDetailsRowProps } from './DetailsRow';
/**
* Extended column render props.
*
* {@docCategory DetailsList}
*/
export type IOverrideColumnRenderProps = Pick<IDetailsListProps, 'onRenderItemColumn' | 'getCellValueKey' | 'onRenderField'> & Pick<IDetailsRowProps, 'cellsByColumn'>;
/**
* Props interface for the DetailsRowFields component.
*
* {@docCategory DetailsList}
*/
export interface IDetailsRowFieldsProps extends IOverrideColumnRenderProps {
/**
* Data source for this component
*/
item: any;
/**
* The item index of the collection for the DetailsList
*/
itemIndex: number;
/**
* Index to start for the column
*/
columnStartIndex: number;
/**
* Columns metadata
*/
columns: IColumn[];
/**
* whether to render as a compact field
*/
compact?: boolean;
/**
* Subset of classnames currently generated in DetailsRow that are used within DetailsRowFields.
*/
rowClassNames: {
[k in keyof Pick<IDetailsRowStyles, 'isMultiline' | 'isRowHeader' | 'cell' | 'cellAnimation' | 'cellPadded' | 'cellUnpadded' | 'fields'>]: string;
};
/**
* Whether or not the details row is in a selected state.
*/
isSelected?: boolean;
/**
* Id for the current row's row-header
*/
rowHeaderId?: string;
/**
* Style properties to customize cell render output.
*/
cellStyleProps?: ICellStyleProps;
enableUpdateAnimations?: boolean;
}
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=DetailsRowFields.types.js.map
@@ -0,0 +1 @@
{"version":3,"file":"DetailsRowFields.types.js","sourceRoot":"../src/","sources":["components/DetailsList/DetailsRowFields.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { IColumn } from './DetailsList.types';\nimport type { ICellStyleProps, IDetailsRowStyles } from './DetailsRow.types';\nimport type { IDetailsListProps } from './DetailsList';\nimport type { IDetailsRowProps } from './DetailsRow';\n\n/**\n * Extended column render props.\n *\n * {@docCategory DetailsList}\n */\nexport type IOverrideColumnRenderProps = Pick<\n IDetailsListProps,\n 'onRenderItemColumn' | 'getCellValueKey' | 'onRenderField'\n> &\n Pick<IDetailsRowProps, 'cellsByColumn'>;\n\n/**\n * Props interface for the DetailsRowFields component.\n *\n * {@docCategory DetailsList}\n */\nexport interface IDetailsRowFieldsProps extends IOverrideColumnRenderProps {\n /**\n * Data source for this component\n */\n item: any;\n\n /**\n * The item index of the collection for the DetailsList\n */\n itemIndex: number;\n\n /**\n * Index to start for the column\n */\n columnStartIndex: number;\n\n /**\n * Columns metadata\n */\n columns: IColumn[];\n\n /**\n * whether to render as a compact field\n */\n compact?: boolean;\n\n /**\n * Subset of classnames currently generated in DetailsRow that are used within DetailsRowFields.\n */\n rowClassNames: {\n [k in keyof Pick<\n IDetailsRowStyles,\n 'isMultiline' | 'isRowHeader' | 'cell' | 'cellAnimation' | 'cellPadded' | 'cellUnpadded' | 'fields'\n >]: string;\n };\n\n /**\n * Whether or not the details row is in a selected state.\n */\n isSelected?: boolean;\n\n /**\n * Id for the current row's row-header\n */\n rowHeaderId?: string;\n\n /**\n * Style properties to customize cell render output.\n */\n cellStyleProps?: ICellStyleProps;\n\n enableUpdateAnimations?: boolean;\n}\n"]}
@@ -0,0 +1,11 @@
import * as React from 'react';
import type { IShimmeredDetailsListProps } from './ShimmeredDetailsList.types';
import type { JSXElement } from '@fluentui/utilities';
export declare class ShimmeredDetailsListBase extends React.Component<IShimmeredDetailsListProps, {}> {
private _shimmerItems;
private _classNames;
constructor(props: IShimmeredDetailsListProps);
render(): JSXElement;
private _onRenderShimmerPlaceholder;
private _renderDefaultShimmerPlaceholder;
}
@@ -0,0 +1,96 @@
import { __assign, __extends, __rest } from "tslib";
import * as React from 'react';
import { classNamesFunction, css } from '../../Utilities';
import { SelectionMode } from '../../Selection';
import { DetailsList } from './DetailsList';
import { Shimmer, ShimmerElementsGroup, ShimmerElementType } from '../../Shimmer';
import { CheckboxVisibility } from './DetailsList.types';
import { DEFAULT_CELL_STYLE_PROPS, DEFAULT_ROW_HEIGHTS } from './DetailsRow.styles';
var getClassNames = classNamesFunction();
var SHIMMER_INITIAL_ITEMS = 10;
var DEFAULT_SHIMMER_HEIGHT = 7;
var SHIMMER_LINE_VS_CELL_WIDTH_RATIO = 0.95;
var ShimmeredDetailsListBase = /** @class */ (function (_super) {
__extends(ShimmeredDetailsListBase, _super);
function ShimmeredDetailsListBase(props) {
var _this = _super.call(this, props) || this;
_this._onRenderShimmerPlaceholder = function (index, rowProps) {
var onRenderCustomPlaceholder = _this.props.onRenderCustomPlaceholder;
var placeholderElements = onRenderCustomPlaceholder
? onRenderCustomPlaceholder(rowProps, index, _this._renderDefaultShimmerPlaceholder)
: _this._renderDefaultShimmerPlaceholder(rowProps);
return React.createElement(Shimmer, { customElementsGroup: placeholderElements });
};
_this._renderDefaultShimmerPlaceholder = function (rowProps) {
var columns = rowProps.columns, compact = rowProps.compact, selectionMode = rowProps.selectionMode, checkboxVisibility = rowProps.checkboxVisibility, _a = rowProps.cellStyleProps, cellStyleProps = _a === void 0 ? DEFAULT_CELL_STYLE_PROPS : _a;
var rowHeight = DEFAULT_ROW_HEIGHTS.rowHeight, compactRowHeight = DEFAULT_ROW_HEIGHTS.compactRowHeight;
// 1px to take into account the border-bottom of DetailsRow.
var gapHeight = compact ? compactRowHeight : rowHeight + 1;
var shimmerElementsRow = [];
var showCheckbox = selectionMode !== SelectionMode.none && checkboxVisibility !== CheckboxVisibility.hidden;
if (showCheckbox) {
shimmerElementsRow.push(React.createElement(ShimmerElementsGroup, { key: 'checkboxGap', shimmerElements: [{ type: ShimmerElementType.gap, width: '40px', height: gapHeight }] }));
}
columns.forEach(function (column, columnIdx) {
var shimmerElements = [];
var groupWidth = cellStyleProps.cellLeftPadding +
cellStyleProps.cellRightPadding +
column.calculatedWidth +
(column.isPadded ? cellStyleProps.cellExtraRightPadding : 0);
shimmerElements.push({
type: ShimmerElementType.gap,
width: cellStyleProps.cellLeftPadding,
height: gapHeight,
});
if (column.isIconOnly) {
shimmerElements.push({
type: ShimmerElementType.line,
width: column.calculatedWidth,
height: column.calculatedWidth,
});
shimmerElements.push({
type: ShimmerElementType.gap,
width: cellStyleProps.cellRightPadding,
height: gapHeight,
});
}
else {
shimmerElements.push({
type: ShimmerElementType.line,
width: column.calculatedWidth * SHIMMER_LINE_VS_CELL_WIDTH_RATIO,
height: DEFAULT_SHIMMER_HEIGHT,
});
shimmerElements.push({
type: ShimmerElementType.gap,
width: cellStyleProps.cellRightPadding +
(column.calculatedWidth - column.calculatedWidth * SHIMMER_LINE_VS_CELL_WIDTH_RATIO) +
(column.isPadded ? cellStyleProps.cellExtraRightPadding : 0),
height: gapHeight,
});
}
shimmerElementsRow.push(React.createElement(ShimmerElementsGroup, { key: columnIdx, width: "".concat(groupWidth, "px"), shimmerElements: shimmerElements }));
});
// When resizing the window from narrow to wider, we need to cover the exposed Shimmer wave
// until the column resizing logic is done.
shimmerElementsRow.push(React.createElement(ShimmerElementsGroup, { key: 'endGap', width: '100%', shimmerElements: [{ type: ShimmerElementType.gap, width: '100%', height: gapHeight }] }));
return React.createElement("div", { style: { display: 'flex' } }, shimmerElementsRow);
};
_this._shimmerItems = props.shimmerLines ? new Array(props.shimmerLines) : new Array(SHIMMER_INITIAL_ITEMS);
return _this;
}
ShimmeredDetailsListBase.prototype.render = function () {
var _a = this.props, detailsListStyles = _a.detailsListStyles, enableShimmer = _a.enableShimmer, items = _a.items, listProps = _a.listProps, onRenderCustomPlaceholder = _a.onRenderCustomPlaceholder, removeFadingOverlay = _a.removeFadingOverlay, shimmerLines = _a.shimmerLines, styles = _a.styles, theme = _a.theme, ariaLabelForGrid = _a.ariaLabelForGrid, ariaLabelForShimmer = _a.ariaLabelForShimmer, restProps = __rest(_a, ["detailsListStyles", "enableShimmer", "items", "listProps", "onRenderCustomPlaceholder", "removeFadingOverlay", "shimmerLines", "styles", "theme", "ariaLabelForGrid", "ariaLabelForShimmer"]);
var listClassName = listProps && listProps.className;
this._classNames = getClassNames(styles, {
theme: theme,
});
var newListProps = __assign(__assign({}, listProps), {
// Adds to the optional listProp className a fading out overlay className only when `enableShimmer` toggled on
// and the overlay is not disabled by `removeFadingOverlay` prop.
className: enableShimmer && !removeFadingOverlay ? css(this._classNames.root, listClassName) : listClassName });
return (React.createElement(DetailsList, __assign({}, restProps, { styles: detailsListStyles, items: enableShimmer ? this._shimmerItems : items, isPlaceholderData: enableShimmer, ariaLabelForGrid: (enableShimmer && ariaLabelForShimmer) || ariaLabelForGrid, onRenderMissingItem: this._onRenderShimmerPlaceholder, listProps: newListProps })));
};
return ShimmeredDetailsListBase;
}(React.Component));
export { ShimmeredDetailsListBase };
//# sourceMappingURL=ShimmeredDetailsList.base.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
import * as React from 'react';
import type { IShimmeredDetailsListProps } from './ShimmeredDetailsList.types';
export declare const ShimmeredDetailsList: React.FunctionComponent<IShimmeredDetailsListProps>;
@@ -0,0 +1,5 @@
import { styled } from '../../Utilities';
import { ShimmeredDetailsListBase } from './ShimmeredDetailsList.base';
import { getShimmeredDetailsListStyles } from './ShimmeredDetailsList.styles';
export var ShimmeredDetailsList = styled(ShimmeredDetailsListBase, getShimmeredDetailsListStyles, undefined, { scope: 'ShimmeredDetailsList' });
//# sourceMappingURL=ShimmeredDetailsList.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ShimmeredDetailsList.js","sourceRoot":"../src/","sources":["components/DetailsList/ShimmeredDetailsList.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAC;AAO9E,MAAM,CAAC,IAAM,oBAAoB,GAAwD,MAAM,CAI7F,wBAAwB,EAAE,6BAA6B,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC,CAAC","sourcesContent":["import * as React from 'react';\nimport { styled } from '../../Utilities';\nimport { ShimmeredDetailsListBase } from './ShimmeredDetailsList.base';\nimport { getShimmeredDetailsListStyles } from './ShimmeredDetailsList.styles';\nimport type {\n IShimmeredDetailsListProps,\n IShimmeredDetailsListStyleProps,\n IShimmeredDetailsListStyles,\n} from './ShimmeredDetailsList.types';\n\nexport const ShimmeredDetailsList: React.FunctionComponent<IShimmeredDetailsListProps> = styled<\n IShimmeredDetailsListProps,\n IShimmeredDetailsListStyleProps,\n IShimmeredDetailsListStyles\n>(ShimmeredDetailsListBase, getShimmeredDetailsListStyles, undefined, { scope: 'ShimmeredDetailsList' });\n"]}
@@ -0,0 +1,2 @@
import type { IShimmeredDetailsListStyleProps, IShimmeredDetailsListStyles } from './ShimmeredDetailsList.types';
export declare const getShimmeredDetailsListStyles: (props: IShimmeredDetailsListStyleProps) => IShimmeredDetailsListStyles;
@@ -0,0 +1,22 @@
export var getShimmeredDetailsListStyles = function (props) {
var theme = props.theme;
var palette = theme.palette;
return {
root: {
position: 'relative',
selectors: {
':after': {
content: '""',
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
left: 0,
// eslint-disable-next-line @fluentui/max-len
backgroundImage: "linear-gradient(to bottom, transparent 30%, ".concat(palette.whiteTranslucent40, " 65%,").concat(palette.white, " 100%)"),
},
},
},
};
};
//# sourceMappingURL=ShimmeredDetailsList.styles.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ShimmeredDetailsList.styles.js","sourceRoot":"../src/","sources":["components/DetailsList/ShimmeredDetailsList.styles.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,IAAM,6BAA6B,GAAG,UAAC,KAAsC;IAC1E,IAAA,KAAK,GAAK,KAAK,MAAV,CAAW;IAChB,IAAA,OAAO,GAAK,KAAK,QAAV,CAAW;IAE1B,OAAO;QACL,IAAI,EAAE;YACJ,QAAQ,EAAE,UAAU;YACpB,SAAS,EAAE;gBACT,QAAQ,EAAE;oBACR,OAAO,EAAE,IAAI;oBACb,QAAQ,EAAE,UAAU;oBACpB,GAAG,EAAE,CAAC;oBACN,KAAK,EAAE,CAAC;oBACR,MAAM,EAAE,CAAC;oBACT,IAAI,EAAE,CAAC;oBACP,6CAA6C;oBAC7C,eAAe,EAAE,sDAA+C,OAAO,CAAC,kBAAkB,kBAAQ,OAAO,CAAC,KAAK,WAAQ;iBACxH;aACF;SACF;KACF,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import type { IShimmeredDetailsListStyleProps, IShimmeredDetailsListStyles } from './ShimmeredDetailsList.types';\n\nexport const getShimmeredDetailsListStyles = (props: IShimmeredDetailsListStyleProps): IShimmeredDetailsListStyles => {\n const { theme } = props;\n const { palette } = theme;\n\n return {\n root: {\n position: 'relative',\n selectors: {\n ':after': {\n content: '\"\"',\n position: 'absolute',\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n // eslint-disable-next-line @fluentui/max-len\n backgroundImage: `linear-gradient(to bottom, transparent 30%, ${palette.whiteTranslucent40} 65%,${palette.white} 100%)`,\n },\n },\n },\n };\n};\n"]}
@@ -0,0 +1,66 @@
import * as React from 'react';
import type { IDetailsListProps } from './DetailsList.types';
import type { IDetailsRowProps } from './DetailsRow.types';
import type { IStyle } from '../../Styling';
import type { IStyleFunctionOrObject } from '../../Utilities';
/**
* ShimmeredDetailsList props interface
* {@docCategory DetailsList}
*/
export interface IShimmeredDetailsListProps extends Omit<IDetailsListProps, 'styles'> {
/**
* DetailsList styles to pass through.
*/
detailsListStyles?: IDetailsListProps['styles'];
/**
* Boolean flag to control when to render placeholders vs real items.
* It's up to the consumer app to know when fetching of the data is done to toggle this prop.
*/
enableShimmer?: boolean;
/**
* Aria label for shimmer. Set on grid while shimmer is enabled.
*/
ariaLabelForShimmer?: string;
/**
* Determines whether to remove a fading out to bottom overlay over the shimmering items
* used to further emphasize the unknown number of items that will be fetched.
*/
removeFadingOverlay?: boolean;
/**
* Custom placeholder renderer to be used when in need to override the default placeholder of a DetailsRow.
* `rowProps` argument is passed to leverage the calculated column measurements done by DetailsList
* or you can use the optional arguments of item `index` and `defaultRender` to execute additional
* logic before rendering the default placeholder.
*/
onRenderCustomPlaceholder?: (rowProps: IDetailsRowProps, index?: number, defaultRender?: (props: IDetailsRowProps) => React.ReactNode) => React.ReactNode;
/**
* Custom styles to override the styles specific to the ShimmeredDetailsList root area.
* @deprecated Use `styles` prop instead. Any value provided will be ignored.
*/
shimmerOverlayStyles?: IStyleFunctionOrObject<IShimmeredDetailsListStyleProps, IShimmeredDetailsListStyles>;
/**
* Custom styles to override the styles specific to the ShimmeredDetailsList root area.
*/
styles?: IStyleFunctionOrObject<IShimmeredDetailsListStyleProps, IShimmeredDetailsListStyles>;
/**
* Number of shimmer placeholder lines to render.
* @defaultvalue 10
*/
shimmerLines?: number;
}
/**
* Defines props needed to construct styles.
* This represents the simplified set of immutable things which control the class names.
* {@docCategory DetailsList}
*/
export type IShimmeredDetailsListStyleProps = Required<Pick<IShimmeredDetailsListProps, 'theme'>>;
/**
* Represents the stylable areas of the control.
* {@docCategory DetailsList}
*/
export interface IShimmeredDetailsListStyles {
/**
* Represents styles passed to the `List` component for creating a fade-out to the bottom overlay.
*/
root: IStyle;
}
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=ShimmeredDetailsList.types.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ShimmeredDetailsList.types.js","sourceRoot":"../src/","sources":["components/DetailsList/ShimmeredDetailsList.types.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport type { IDetailsListProps } from './DetailsList.types';\nimport type { IDetailsRowProps } from './DetailsRow.types';\nimport type { IStyle } from '../../Styling';\nimport type { IStyleFunctionOrObject } from '../../Utilities';\n\n/**\n * ShimmeredDetailsList props interface\n * {@docCategory DetailsList}\n */\nexport interface IShimmeredDetailsListProps extends Omit<IDetailsListProps, 'styles'> {\n /**\n * DetailsList styles to pass through.\n */\n detailsListStyles?: IDetailsListProps['styles'];\n\n /**\n * Boolean flag to control when to render placeholders vs real items.\n * It's up to the consumer app to know when fetching of the data is done to toggle this prop.\n */\n enableShimmer?: boolean;\n\n /**\n * Aria label for shimmer. Set on grid while shimmer is enabled.\n */\n ariaLabelForShimmer?: string;\n\n /**\n * Determines whether to remove a fading out to bottom overlay over the shimmering items\n * used to further emphasize the unknown number of items that will be fetched.\n */\n removeFadingOverlay?: boolean;\n\n /**\n * Custom placeholder renderer to be used when in need to override the default placeholder of a DetailsRow.\n * `rowProps` argument is passed to leverage the calculated column measurements done by DetailsList\n * or you can use the optional arguments of item `index` and `defaultRender` to execute additional\n * logic before rendering the default placeholder.\n */\n onRenderCustomPlaceholder?: (\n rowProps: IDetailsRowProps,\n index?: number,\n defaultRender?: (props: IDetailsRowProps) => React.ReactNode,\n ) => React.ReactNode;\n\n /**\n * Custom styles to override the styles specific to the ShimmeredDetailsList root area.\n * @deprecated Use `styles` prop instead. Any value provided will be ignored.\n */\n shimmerOverlayStyles?: IStyleFunctionOrObject<IShimmeredDetailsListStyleProps, IShimmeredDetailsListStyles>;\n\n /**\n * Custom styles to override the styles specific to the ShimmeredDetailsList root area.\n */\n styles?: IStyleFunctionOrObject<IShimmeredDetailsListStyleProps, IShimmeredDetailsListStyles>;\n\n /**\n * Number of shimmer placeholder lines to render.\n * @defaultvalue 10\n */\n shimmerLines?: number;\n}\n\n/**\n * Defines props needed to construct styles.\n * This represents the simplified set of immutable things which control the class names.\n * {@docCategory DetailsList}\n */\nexport type IShimmeredDetailsListStyleProps = Required<Pick<IShimmeredDetailsListProps, 'theme'>>;\n\n/**\n * Represents the stylable areas of the control.\n * {@docCategory DetailsList}\n */\nexport interface IShimmeredDetailsListStyles {\n /**\n * Represents styles passed to the `List` component for creating a fade-out to the bottom overlay.\n */\n root: IStyle;\n}\n"]}
+24
View File
@@ -0,0 +1,24 @@
export * from '../../Selection';
export * from '../GroupedList/GroupedList.types';
export * from './DetailsHeader';
export * from './DetailsHeader.base';
export * from './DetailsHeader.styles';
export * from './DetailsHeader.types';
export * from './DetailsList';
export * from './DetailsList.base';
export * from './DetailsList.styles';
export * from './DetailsList.types';
export * from './DetailsRow';
export * from './DetailsRow.base';
export * from './DetailsRow.types';
export * from './DetailsRow.styles';
export * from './DetailsRowCheck';
export * from './DetailsRowCheck.styles';
export * from './DetailsRowCheck.types';
export * from './DetailsRowFields';
export * from './DetailsRowFields.types';
export * from './DetailsFooter.types';
export * from './DetailsColumn';
export * from './DetailsColumn.base';
export * from './DetailsColumn.styles';
export * from './DetailsColumn.types';
+26
View File
@@ -0,0 +1,26 @@
export * from '../../Selection';
export * from '../GroupedList/GroupedList.types';
export * from './DetailsHeader';
export * from './DetailsHeader.base';
export * from './DetailsHeader.styles';
export * from './DetailsHeader.types';
export * from './DetailsList';
export * from './DetailsList.base';
export * from './DetailsList.styles';
export * from './DetailsList.types';
export * from './DetailsRow';
export * from './DetailsRow.base';
export * from './DetailsRow.types';
export * from './DetailsRow.styles';
export * from './DetailsRowCheck';
export * from './DetailsRowCheck.styles';
export * from './DetailsRowCheck.types';
export * from './DetailsRowFields';
export * from './DetailsRowFields.types';
export * from './DetailsFooter.types';
export * from './DetailsColumn';
export * from './DetailsColumn.base';
export * from './DetailsColumn.styles';
export * from './DetailsColumn.types';
// ShimmeredDetailsList is not exported here as it is exported from ../ShimmeredDetailsList.ts
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"../src/","sources":["components/DetailsList/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,kCAAkC,CAAC;AACjD,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AAEtC,8FAA8F","sourcesContent":["export * from '../../Selection';\nexport * from '../GroupedList/GroupedList.types';\nexport * from './DetailsHeader';\nexport * from './DetailsHeader.base';\nexport * from './DetailsHeader.styles';\nexport * from './DetailsHeader.types';\nexport * from './DetailsList';\nexport * from './DetailsList.base';\nexport * from './DetailsList.styles';\nexport * from './DetailsList.types';\nexport * from './DetailsRow';\nexport * from './DetailsRow.base';\nexport * from './DetailsRow.types';\nexport * from './DetailsRow.styles';\nexport * from './DetailsRowCheck';\nexport * from './DetailsRowCheck.styles';\nexport * from './DetailsRowCheck.types';\nexport * from './DetailsRowFields';\nexport * from './DetailsRowFields.types';\nexport * from './DetailsFooter.types';\nexport * from './DetailsColumn';\nexport * from './DetailsColumn.base';\nexport * from './DetailsColumn.styles';\nexport * from './DetailsColumn.types';\n\n// ShimmeredDetailsList is not exported here as it is exported from ../ShimmeredDetailsList.ts\n"]}