diff --git a/components/lib/multiselect/MultiSelect.js b/components/lib/multiselect/MultiSelect.js index 018b1dd927..d5d53b3583 100644 --- a/components/lib/multiselect/MultiSelect.js +++ b/components/lib/multiselect/MultiSelect.js @@ -128,17 +128,17 @@ export const MultiSelect = React.memo( const findNextItem = (item) => { const nextItem = item.nextElementSibling; - return nextItem ? (DomHandler.hasClass(nextItem, 'p-disabled') || DomHandler.hasClass(nextItem, 'p-multiselect-item-group') ? findNextItem(nextItem) : nextItem) : null; + return nextItem ? (DomHandler.getAttribute(nextItem, 'data-p-disabled') === true || DomHandler.getAttribute(nextItem, 'data-pc-section') === 'itemgroup' ? findNextItem(nextItem) : nextItem) : null; }; const findPrevItem = (item) => { const prevItem = item.previousElementSibling; - return prevItem ? (DomHandler.hasClass(prevItem, 'p-disabled') || DomHandler.hasClass(prevItem, 'p-multiselect-item-group') ? findPrevItem(prevItem) : prevItem) : null; + return prevItem ? (DomHandler.getAttribute(prevItem, 'data-p-disabled') === true || DomHandler.getAttribute(prevItem, 'data-pc-section') === 'itemgroup' ? findPrevItem(prevItem) : prevItem) : null; }; const onClick = (event) => { - if (!props.inline && !props.disabled && !isPanelClicked(event) && !DomHandler.hasClass(event.target, 'p-multiselect-token-icon') && !isClearClicked(event)) { + if (!props.inline && !props.disabled && !isPanelClicked(event) && DomHandler.getAttribute(event.target, 'data-pc-section') !== 'removetokenicon' && !isClearClicked(event)) { overlayVisibleState ? hide() : show(); DomHandler.focus(inputRef.current); event.preventDefault(); @@ -314,11 +314,11 @@ export const MultiSelect = React.memo( }; const isClearClicked = (event) => { - return DomHandler.hasClass(event.target, 'p-multiselect-clear-icon'); + return DomHandler.getAttribute(event.target, 'data-pc-section') === 'clearicon'; }; const isSelectAllClicked = (event) => { - return DomHandler.hasClass(event.target, 'p-multiselect-select-all'); + return DomHandler.getAttribute(event.target, 'data-pc-section') === 'headercheckboxcontainer'; }; const isPanelClicked = (event) => { @@ -769,6 +769,7 @@ export const MultiSelect = React.memo( ptm={ptm} cx={cx} sx={sx} + isUnstyled={isUnstyled} /> {hasTooltip && } diff --git a/components/lib/multiselect/MultiSelectBase.js b/components/lib/multiselect/MultiSelectBase.js index 1dfc9ca728..eb72583b78 100644 --- a/components/lib/multiselect/MultiSelectBase.js +++ b/components/lib/multiselect/MultiSelectBase.js @@ -48,20 +48,16 @@ const classes = { closeButton: 'p-multiselect-close p-link', header: 'p-multiselect-header', closeIcon: 'p-multiselect-close-icon', - headerCheckbox: 'p-multiselect-select-all p-checkbox-icon p-c', + headerCheckboxContainer: 'p-multiselect-select-all', + headerCheckboxIcon: 'p-multiselect-select-all p-checkbox-icon p-c', headerSelectAllLabel: 'p-multiselect-select-all-label', filterContainer: 'p-multiselect-filter-container', filterIcon: 'p-multiselect-filter-icon', item: ({ itemProps: props }) => - classNames( - 'p-multiselect-item', - { - 'p-highlight': props.selected, - 'p-disabled': props.disabled - }, - props.className, - props.option.className - ), + classNames('p-multiselect-item', { + 'p-highlight': props.selected, + 'p-disabled': props.disabled + }), checkboxContainer: 'p-checkbox p-component', checkboxIcon: 'p-checkbox-icon p-c', checkbox: ({ itemProps: props }) => diff --git a/components/lib/multiselect/MultiSelectHeader.js b/components/lib/multiselect/MultiSelectHeader.js index 6cd36d3b32..453e6ef44a 100644 --- a/components/lib/multiselect/MultiSelectHeader.js +++ b/components/lib/multiselect/MultiSelectHeader.js @@ -9,7 +9,7 @@ import { Ripple } from '../ripple/Ripple'; import { IconUtils, ObjectUtils, UniqueComponentId, classNames, mergeProps } from '../utils/Utils'; export const MultiSelectHeader = React.memo((props) => { - const { ptm, cx } = props; + const { ptm, cx, isUnstyled } = props; const filterOptions = { filter: (e) => onFilter(e), reset: () => props.resetFilter() @@ -91,19 +91,19 @@ export const MultiSelectHeader = React.memo((props) => { ptm('headerSelectAllLabel') ); - const headerCheckboxProps = mergeProps( + const headerCheckboxIconProps = mergeProps( { - className: cx('headerCheckbox') + className: cx('headerCheckboxIcon') }, - ptm('headerCheckbox') + ptm('headerCheckboxIcon') ); - const checkedIcon = props.itemCheckboxIcon || ; - const itemCheckboxIcon = IconUtils.getJSXIcon(checkedIcon, { ...headerCheckboxProps }, { selected: props.selected }); + const checkedIcon = props.itemCheckboxIcon || ; + const itemCheckboxIcon = IconUtils.getJSXIcon(checkedIcon, { ...headerCheckboxIconProps }, { selected: props.selected }); const checkboxElement = props.showSelectAll && (
- + {!props.filter && }
); diff --git a/components/lib/multiselect/MultiSelectItem.js b/components/lib/multiselect/MultiSelectItem.js index 1e19410ae3..88bcfa6ec5 100644 --- a/components/lib/multiselect/MultiSelectItem.js +++ b/components/lib/multiselect/MultiSelectItem.js @@ -1,7 +1,7 @@ import * as React from 'react'; import { CheckIcon } from '../icons/check'; import { Ripple } from '../ripple/Ripple'; -import { IconUtils, ObjectUtils, mergeProps } from '../utils/Utils'; +import { IconUtils, ObjectUtils, classNames, mergeProps } from '../utils/Utils'; export const MultiSelectItem = React.memo((props) => { const { ptm, cx } = props; @@ -63,13 +63,14 @@ export const MultiSelectItem = React.memo((props) => { const itemProps = mergeProps( { - className: cx('item', { itemProps: props }), + className: classNames(props.className, props.option.className, cx('item', { itemProps: props })), style: props.style, onClick: onClick, tabIndex: tabIndex, onKeyDown: onKeyDown, role: 'option', - 'aria-selected': props.selected + 'aria-selected': props.selected, + 'data-p-disabled': props.disabled }, getPTOptions('item') ); diff --git a/components/lib/multiselect/MultiSelectPanel.js b/components/lib/multiselect/MultiSelectPanel.js index 5ac439515d..57ef77f475 100644 --- a/components/lib/multiselect/MultiSelectPanel.js +++ b/components/lib/multiselect/MultiSelectPanel.js @@ -12,7 +12,7 @@ export const MultiSelectPanel = React.memo( const virtualScrollerRef = React.useRef(null); const filterInputRef = React.useRef(null); const context = React.useContext(PrimeReactContext); - const { ptm, cx, sx } = props; + const { ptm, cx, sx, isUnstyled } = props; const onEnter = () => { props.onEnter(() => { @@ -68,6 +68,7 @@ export const MultiSelectPanel = React.memo( itemCheckboxIcon={props.itemCheckboxIcon} ptm={ptm} cx={cx} + isUnstyled={isUnstyled} /> ); }; diff --git a/components/lib/multiselect/multiselect.d.ts b/components/lib/multiselect/multiselect.d.ts index 097652c3ca..539d75e313 100644 --- a/components/lib/multiselect/multiselect.d.ts +++ b/components/lib/multiselect/multiselect.d.ts @@ -14,6 +14,7 @@ import { TooltipPassThroughOptions } from '../tooltip/tooltip'; import { TooltipOptions } from '../tooltip/tooltipoptions'; import { IconType, PassThroughType } from '../utils'; import { VirtualScrollerPassThroughOptions, VirtualScrollerProps } from '../virtualscroller'; +import { CheckboxPassThroughOptions } from '../checkbox/checkbox'; export declare type MultiSelectPassThroughType = PassThroughType; @@ -86,7 +87,11 @@ export interface MultiSelectPassThroughOptions { /** * Uses to pass attributes to the header checkbox's DOM element. */ - headerCheckbox?: MultiSelectPassThroughType | React.HTMLAttributes>; + headerCheckbox?: CheckboxPassThroughOptions; + /** + * Uses to pass attributes to the header checkbox icon's DOM element. + */ + headerCheckboxIcon?: MultiSelectPassThroughType | React.HTMLAttributes>; /** * Uses to pass attributes to the header checkbox's DOM element. */ diff --git a/components/lib/passthrough/tailwind/index.js b/components/lib/passthrough/tailwind/index.js index 79647b4a35..6d4c41e2a3 100644 --- a/components/lib/passthrough/tailwind/index.js +++ b/components/lib/passthrough/tailwind/index.js @@ -774,7 +774,7 @@ const Tailwind = { content: { className: classNames('flex items-center overflow-hidden relative', 'py-3 px-5') }, - groupicon: 'ml-auto', + optiongroupicon: 'ml-auto', transition: TRANSITIONS.overlay }, inputmask: { @@ -1887,17 +1887,15 @@ const Tailwind = { menu: { className: classNames('outline-none', 'm-0 p-0 list-none') }, - menuitem: ({ context }) => { - return { - className: classNames( - 'text-gray-700 dark:text-white/80 transition-shadow duration-200 border-none rounded-none', - 'hover:bg-gray-200 dark:hover:bg-gray-800/80 hover:text-gray-700 dark:hover:text-white/80', // Hover - { - 'bg-gray-300 text-gray-700 dark:text-white/80 dark:bg-gray-800/90': context.focused - } - ) - }; - }, + menuitem: ({ context }) => ({ + className: classNames( + 'text-gray-700 dark:text-white/80 transition-shadow duration-200 border-none rounded-none', + 'hover:bg-gray-200 dark:hover:bg-gray-800/80 hover:text-gray-700 dark:hover:text-white/80', // Hover + { + 'bg-gray-300 text-gray-700 dark:text-white/80 dark:bg-gray-800/90': context.focused + } + ) + }), action: { className: classNames('text-gray-700 dark:text-white/80 py-3 px-5 select-none', 'flex items-center cursor-pointer no-underline relative overflow-hidden') }, @@ -2831,7 +2829,7 @@ const Tailwind = { treetable: { root: ({ props }) => ({ className: classNames('relative', { - 'flex flex-col h-full': props.scrollHeight === 'flex' + 'flex flex-col h-full': props.scrollHeight }) }), loadingoverlay: { @@ -2849,6 +2847,12 @@ const Tailwind = { 'dark:bg-gray-900 dark:text-white/70 dark:border-blue-900/40' // Dark Mode ) }, + scrollablewrapper: ({ props }) => ({ + className: classNames({ + 'relative overflow-auto': props.scrollable, + 'overflow-x-auto': props.resizableColumns + }) + }), wrapper: ({ props }) => ({ className: classNames({ 'relative overflow-auto': props.scrollable, @@ -2897,30 +2901,29 @@ const Tailwind = { headercell: ({ context }) => ({ className: classNames( 'text-left border-gray-300 border font-bold', - 'transition duration-200', - context.sorted ? 'bg-blue-50 text-blue-700' : 'bg-slate-50', - context?.size === 'small' ? 'p-2' : context?.size === 'large' ? 'p-5' : 'p-4', // Size + 'transition duration-200 p-4', 'dark:border-blue-900/40 dark:text-white/80 dark:bg-gray-900', //Dark Mode { + 'bg-blue-50 text-blue-700': context.sorted, + 'bg-slate-50': !context.sorted, 'flex flex-1 items-center': context.scrollable, - 'flex-initial shrink-0': context.scrollable && context.scrollDirection === 'both' && !context.frozen, - 'sticky z-[1]': context.scrollable && context.scrollDirection === 'both' && context.frozen, + 'flex-initial shrink-0': context.scrollable && !context.frozen, + 'sticky z-[1]': context.scrollable && context.frozen, 'border-x-0 border-l-0 border-t-0': !context.showGridlines, - 'overflow-hidden relative bg-clip-padding': context.resizable && !context.frozen + 'overflow-hidden relative bg-clip-padding': !context.frozen } ) }), bodycell: ({ context }) => ({ className: classNames( 'text-left border-gray-300 border', - 'transition duration-200', - context?.size === 'small' ? 'p-2' : context?.size === 'large' ? 'p-5' : 'p-4', // Size + 'transition duration-200 p-4', 'dark:border-blue-900/40', //Dark Mode { 'cursor-pointer': context.selectable, 'flex flex-1 items-center': context.scrollable, - 'flex-initial shrink-0': context.scrollable && context.scrollDirection === 'both' && !context.frozen, - sticky: context.scrollable && context.scrollDirection === 'both' && context.frozen, + 'flex-initial shrink-0': context.scrollable && !context.frozen, + sticky: context.scrollable && context.frozen, 'border-x-0 border-l-0': !context.showGridlines } ) @@ -2929,12 +2932,18 @@ const Tailwind = { className: classNames( 'relative inline-flex items-center justify-center align-center cursor-pointer select-none overflow-hidden bg-transparent', 'w-8 h-8 border-0 rounded mr-0.5', - context.selected ? 'text-blue-700' : 'text-gray-500', + { + 'text-blue-700': context.selected, + 'text-gray-500': !context.selected + }, 'dark:text-white/70' //Dark Mode ) }), sorticon: ({ context }) => ({ - className: classNames('ml-2', context.sorted ? 'text-blue-700 dark:text-white/80' : 'text-slate-700 dark:text-white/70') + className: classNames('ml-2', { + 'text-blue-700 dark:text-white/80': context.sorted, + 'text-slate-700 dark:text-white/70': !context.sorted + }) }), sortbadge: { className: classNames( @@ -2950,7 +2959,10 @@ const Tailwind = { className: classNames( 'flex items-center justify-center', 'border-2 w-6 h-6 text-gray-600 rounded-lg transition-colors duration-200', - context.checked ? 'border-blue-500 bg-blue-500 dark:border-blue-400 dark:bg-blue-400' : 'border-gray-300 bg-white dark:border-blue-900/40 dark:bg-gray-900', + { + 'border-blue-500 bg-blue-500 dark:border-blue-400 dark:bg-blue-400': context.checked, + 'border-gray-300 bg-white dark:border-blue-900/40 dark:bg-gray-900': !context.checked + }, { 'hover:border-blue-500 dark:hover:border-blue-400 focus:outline-none focus:outline-offset-0 focus:shadow-[0_0_0_0.2rem_rgba(191,219,254,1)] dark:focus:shadow-[inset_0_0_0_0.2rem_rgba(147,197,253,0.5)]': !context.disabled } @@ -3033,7 +3045,11 @@ const Tailwind = { bodycell: ({ props, context }) => ({ className: classNames( 'text-left border-0 border-b border-solid border-gray-300', - context?.size === 'small' ? 'p-2' : context?.size === 'large' ? 'p-5' : 'p-4', // Size + { + 'p-2': context?.size === 'small', + 'p-5': context?.size === 'large', + 'p-4': !context.size + }, 'dark:text-white/80 dark:border-blue-900/40', // Dark Mode { 'sticky bg-inherit': props.frozen || props.frozen === '', // Frozen Columns @@ -3046,7 +3062,11 @@ const Tailwind = { 'text-left border-0 border-b border-solid border-gray-300 font-bold', 'bg-slate-50 text-slate-700', 'transition duration-200', - context?.size === 'small' ? 'p-2' : context?.size === 'large' ? 'p-5' : 'p-4', // Size + { + 'p-2': context?.size === 'small', + 'p-5': context?.size === 'large', + 'p-4': !context.size + }, 'dark:text-white/80 dark:bg-gray-900 dark:border-blue-900/40', // Dark Mode { 'border-x border-y': context?.showGridlines diff --git a/components/lib/treetable/TreeTable.js b/components/lib/treetable/TreeTable.js index b7bec84970..2300b6603b 100644 --- a/components/lib/treetable/TreeTable.js +++ b/components/lib/treetable/TreeTable.js @@ -36,6 +36,9 @@ export const TreeTable = React.forwardRef((inProps, ref) => { multiSortMeta: multiSortMetaState, filters: filtersState, columnOrder: columnOrderState + }, + context: { + scrollable: props.scrollable } }; const ptCallbacks = TreeTableBase.setMetaData(metaData); @@ -344,7 +347,7 @@ export const TreeTable = React.forwardRef((inProps, ref) => { const onColumnResize = (event) => { let containerLeft = DomHandler.getOffset(elementRef.current).left; - !isUnstyled() && DomHandler.addClass(elementRef.current, 'p-unselectable-text'); + !ptCallbacks.isUnstyled() && DomHandler.addClass(elementRef.current, 'p-unselectable-text'); resizerHelperRef.current.style.height = elementRef.current.offsetHeight + 'px'; resizerHelperRef.current.style.top = 0 + 'px'; resizerHelperRef.current.style.left = event.pageX - containerLeft + elementRef.current.scrollLeft + 'px'; @@ -428,7 +431,7 @@ export const TreeTable = React.forwardRef((inProps, ref) => { if (column) { let parent = column.parentElement; - while (parent && !DomHandler.hasClass(parent, 'p-treetable-scrollable-view')) { + while (parent && DomHandler.getAttribute(parent, 'data-pc-section') !== 'scrollable') { parent = parent.parentElement; } @@ -987,7 +990,7 @@ export const TreeTable = React.forwardRef((inProps, ref) => { } scrollableView = createScrollableView(value, scrollableColumns, false, props.headerColumnGroup, props.footerColumnGroup); - const scrollableWrapper = mergeProps( + const scrollableWrapperProps = mergeProps( { className: ptCallbacks.cx('scrollableWrapper') }, @@ -995,7 +998,7 @@ export const TreeTable = React.forwardRef((inProps, ref) => { ); return ( -
+
{frozenView} {scrollableView}
@@ -1091,7 +1094,7 @@ export const TreeTable = React.forwardRef((inProps, ref) => { const resizeHelperProps = mergeProps( { className: ptCallbacks.cx('resizeHelper'), - style: ptCallbacks.sx('resizeHelper') + style: { display: 'none' } }, ptCallbacks.ptm('resizeHelper') ); @@ -1105,7 +1108,7 @@ export const TreeTable = React.forwardRef((inProps, ref) => { const reorderIndicatorUpProps = mergeProps( { className: ptCallbacks.cx('reorderIndicatorUp'), - style: ptCallbacks.sx('reorderIndicatorUp') + style: { position: 'absolute', display: 'none' } }, ptCallbacks.ptm('reorderIndicatorUp') ); @@ -1116,7 +1119,7 @@ export const TreeTable = React.forwardRef((inProps, ref) => { {reorderIndicatorUpIcon} ); - const reorderIndicatorDownProps = { className: ptCallbacks.sx('reorderIndicatorDown'), style: ptCallbacks.sx('reorderIndicatorDown') }; + const reorderIndicatorDownProps = { className: ptCallbacks.sx('reorderIndicatorDown'), style: { position: 'absolute', display: 'none' } }; const reorderIndicatorDownIconProps = mergeProps(ptCallbacks.ptm('reorderIndicatorDownIcon')); const reorderIndicatorDownIcon = IconUtils.getJSXIcon(props.reorderIndicatorDownIcon || , { ...reorderIndicatorDownIconProps }, { props }); const reorderIndicatorDown = props.reorderableColumns && ( diff --git a/components/lib/treetable/TreeTableBase.js b/components/lib/treetable/TreeTableBase.js index 7e6f2e7631..85023b7421 100644 --- a/components/lib/treetable/TreeTableBase.js +++ b/components/lib/treetable/TreeTableBase.js @@ -204,16 +204,6 @@ const classes = { scrollableColgroup: 'p-treetable-scrollable-colgroup' }; -const inlineStyles = { - resizeHelper: { display: 'none' }, - reorderIndicatorUp: { position: 'absolute', display: 'none' }, - reorderIndicatorDown: { position: 'absolute', display: 'none' }, - rowToggler: ({ rowProps: props }) => ({ marginLeft: props.level * 16 + 'px', visibility: props.node.leaf === false || (props.node.children && props.node.children.length) ? 'visible' : 'hidden' }), - scrollableBody: ({ scrolaableProps: props }) => (!props.frozen && props.scrollHeight ? { overflowY: 'scroll' } : undefined), - scrollableBodyTable: { top: '0' }, - scrollable: ({ width, left }) => ({ width: width, left: left }) -}; - export const TreeTableBase = ComponentBase.extend({ defaultProps: { __TYPE: 'TreeTable', @@ -303,7 +293,6 @@ export const TreeTableBase = ComponentBase.extend({ }, css: { classes, - styles, - inlineStyles + styles } }); diff --git a/components/lib/treetable/TreeTableBody.js b/components/lib/treetable/TreeTableBody.js index dc9409ad3c..3cddcbbab7 100644 --- a/components/lib/treetable/TreeTableBody.js +++ b/components/lib/treetable/TreeTableBody.js @@ -38,7 +38,7 @@ export const TreeTableBody = React.memo((props) => { const targetNode = event.target.nodeName; - if (targetNode === 'INPUT' || targetNode === 'BUTTON' || targetNode === 'A' || DomHandler.hasClass(event.target, 'p-clickable')) { + if (targetNode === 'INPUT' || targetNode === 'BUTTON' || targetNode === 'A' || DomHandler.getAttribute(event.target, 'data-pc-section') === 'columnresizer') { return; } @@ -229,16 +229,16 @@ export const TreeTableBody = React.memo((props) => { }, ptm('emptyMessage') ); - const bodyCellProps = mergeProps( + const emptyMessageCellProps = mergeProps( { colSpan }, - ptm('bodyCell') + ptm('emptyMessageCell') ); return ( - {content} + {content} ); } diff --git a/components/lib/treetable/TreeTableBodyCell.js b/components/lib/treetable/TreeTableBodyCell.js index 4896360da4..93862456bf 100644 --- a/components/lib/treetable/TreeTableBodyCell.js +++ b/components/lib/treetable/TreeTableBodyCell.js @@ -13,18 +13,29 @@ export const TreeTableBodyCell = (props) => { const tabIndexTimeout = React.useRef(null); const getColumnProp = (name) => ColumnBase.getCProp(props.column, name); const getColumnProps = (column) => ColumnBase.getCProps(column); - const { ptmo, cx } = props.ptCallbacks; + const { ptm, ptmo, cx } = props.ptCallbacks; const getColumnPTOptions = (key) => { + const isSingleSelectionMode = props.metaData.props.selectionMode === 'single'; + const isMultipleSelectionMode = props.metaData.props.selectionMode === 'multiple'; const cProps = getColumnProps(props.column); - - return ptmo(getColumnProp('pt'), key, { + const columnMetadata = { props: cProps, parent: props.metaData, state: { editing: editingState + }, + context: { + index: props.index, + selectable: isSingleSelectionMode || isMultipleSelectionMode, + selected: props.selected, + scrollable: props.metaData.props.scrollable, + frozen: getColumnProp('frozen'), + showGridlines: props.metaData.props.showGridlines } - }); + }; + + return mergeProps(ptm(`column.${key}`, { column: columnMetadata }), ptm(`column.${key}`, columnMetadata), ptmo(cProps, key, columnMetadata)); }; const field = getColumnProp('field') || `field_${props.index}`; @@ -222,8 +233,8 @@ export const TreeTableBodyCell = (props) => { onClick: (e) => onClick(e), onKeyDown: (e) => onKeyDown(e) }, - getColumnPTOptions('bodyCell'), - getColumnPTOptions('root') + getColumnPTOptions('root'), + getColumnPTOptions('bodyCell') ); return ( diff --git a/components/lib/treetable/TreeTableFooter.js b/components/lib/treetable/TreeTableFooter.js index fc056db7e3..a253c16418 100644 --- a/components/lib/treetable/TreeTableFooter.js +++ b/components/lib/treetable/TreeTableFooter.js @@ -16,10 +16,12 @@ export const TreeTableFooter = React.memo((props) => { }; const getColumnPTOptions = (column, key) => { - return ptmo(getColumnProp(column, 'pt'), key, { + const columnMetadata = { props: getColumnProps(column), parent: props.metaData - }); + }; + + return mergeProps(ptm(`column.${key}`, { column: columnMetadata }), ptm(`column.${key}`, columnMetadata), ptmo(getColumnProps(column), key, columnMetadata)); }; const createFooterCell = (column, index) => { diff --git a/components/lib/treetable/TreeTableHeader.js b/components/lib/treetable/TreeTableHeader.js index 6d7bdea7f1..45eb5053b6 100644 --- a/components/lib/treetable/TreeTableHeader.js +++ b/components/lib/treetable/TreeTableHeader.js @@ -13,24 +13,20 @@ export const TreeTableHeader = React.memo((props) => { const { ptm, ptmo, cx } = props.ptCallbacks; const filterTimeout = React.useRef(null); - const getColumnProps = (column) => { - return ptmo(ColumnBase.getCProps(column)); + const getColumnProp = (column, ...args) => { + return column ? (typeof args[0] === 'string' ? ColumnBase.getCProp(column, args[0]) : ColumnBase.getCProp(args[0] || column, args[1])) : null; }; + const getColumnProps = (column) => ColumnBase.getCProps(column); + const getColumnPTOptions = (column, key, params) => { - return ptmo(ColumnBase.getCProp(column, 'pt'), key, { + const columnMetadata = { props: getColumnProps(column), parent: props.metaData, ...params - }); - }; - - const ptHeaderCellOptions = (column) => { - return { - context: { - frozen: getColumnProp(column, 'frozen') - } }; + + return mergeProps(ptm(`column.${key}`, { column: columnMetadata }), ptm(`column.${key}`, columnMetadata), ptmo(getColumnProps(column), key, columnMetadata)); }; const onHeaderClick = (event, column) => { @@ -38,10 +34,10 @@ export const TreeTableHeader = React.memo((props) => { const targetNode = event.target; if ( - DomHandler.hasClass(targetNode, 'p-sortable-column') || - DomHandler.hasClass(targetNode, 'p-column-title') || - DomHandler.hasClass(targetNode, 'p-sortable-column-icon') || - DomHandler.hasClass(targetNode.parentElement, 'p-sortable-column-icon') + DomHandler.getAttribute(targetNode, 'data-p-sortable-column') === true || + DomHandler.getAttribute(targetNode, 'data-pc-section') === 'headertitle' || + DomHandler.getAttribute(targetNode, 'data-pc-section') === 'sorticon' || + DomHandler.getAttribute(targetNode.parentElement, 'data-pc-section') === 'sorticon' ) { props.onSort({ originalEvent: event, @@ -168,17 +164,17 @@ export const TreeTableHeader = React.memo((props) => { } }; - const getColumnProp = (column, ...args) => { - return column ? (typeof args[0] === 'string' ? ColumnBase.getCProp(column, args[0]) : ColumnBase.getCProp(args[0] || column, args[1])) : null; - }; - const createSortIcon = (column, sorted, sortOrder) => { if (getColumnProp(column, 'sortable')) { const sortIconProps = mergeProps( { className: cx('sortIcon') }, - getColumnPTOptions(column, 'sortIcon') + getColumnPTOptions(column, 'sortIcon', { + context: { + sorted + } + }) ); let icon = sorted ? sortOrder < 0 ? : : ; let sortIcon = IconUtils.getJSXIcon(props.sortIcon || icon, { ...sortIconProps }, { props, sorted, sortOrder }); @@ -257,10 +253,17 @@ export const TreeTableHeader = React.memo((props) => { className: classNames(cx('headerCell', { options }), getColumnProp(column, 'filterHeaderClassName')), style: getColumnProp(column, 'filterHeaderStyle') || getColumnProp(column, 'style'), rowSpan: getColumnProp(column, 'rowSpan'), - colSpan: getColumnProp(column, 'colSpan') + colSpan: getColumnProp(column, 'colSpan'), + 'data-p-sortable-column': getColumnProp(column, 'sortable'), + 'data-p-resizable-column': props.resizableColumns, + 'data-p-frozen-column': getColumnProp(column, 'frozen') }, - getColumnPTOptions(column, 'headerCell', ptHeaderCellOptions(column)), - getColumnPTOptions(column, 'root') + getColumnPTOptions(column, 'root'), + getColumnPTOptions(column, 'headerCell', { + context: { + frozen: getColumnProp(column, 'frozen') + } + }) ); return {filterElement}; @@ -299,10 +302,20 @@ export const TreeTableHeader = React.memo((props) => { onDragStart: (e) => onDragStart(e, column), onDragOver: (e) => onDragOver(e, column), onDragLeave: (e) => onDragLeave(e, column), - onDrop: (e) => onDrop(e, column) + onDrop: (e) => onDrop(e, column), + 'data-p-sortable-column': getColumnProp(column, 'sortable'), + 'data-p-resizable-column': props.resizableColumns, + 'data-p-highlight': sorted, + 'data-p-frozen-column': getColumnProp(column, 'frozen') }, - getColumnPTOptions(column, 'headerCell'), - getColumnPTOptions(column, 'root') + getColumnPTOptions(column, 'root'), + getColumnPTOptions(column, 'headerCell', { + context: { + sorted, + frozen, + resizable: props.resizableColumns + } + }) ); return ( diff --git a/components/lib/treetable/TreeTableRow.js b/components/lib/treetable/TreeTableRow.js index 0c302551fe..879eecb2a4 100644 --- a/components/lib/treetable/TreeTableRow.js +++ b/components/lib/treetable/TreeTableRow.js @@ -15,50 +15,65 @@ export const TreeTableRow = React.memo((props) => { const checkboxBoxRef = React.useRef(null); const nodeTouched = React.useRef(false); const expanded = props.expandedKeys ? props.expandedKeys[props.node.key] !== undefined : false; + + const getColumnProp = (column, name) => { + return ColumnBase.getCProp(column, name); + }; + const getColumnProps = (column) => ColumnBase.getCProps(column); const { ptm, ptmo, cx, sx, isUnstyled } = props.ptCallbacks; const getColumnPTOptions = (column, key) => { - return ptmo(ColumnBase.getCProp(column, 'pt'), key, { - props: getColumnProps(column), - parent: props.metaData - }); + const cProps = getColumnProps(column); + const columnMetadata = { + props: cProps, + parent: props.metaData, + context: { + index: props.rowIndex, + selectable: props.node.selectable !== false, + selected: isSelected(), + frozen: getColumnProp(column, 'frozen'), + scrollable: props.metaData.props.scrollable + } + }; + + return mergeProps(ptm(`column.${key}`, { column: columnMetadata }), ptm(`column.${key}`, columnMetadata), ptmo(cProps, key, columnMetadata)); }; const getColumnCheckboxPTOptions = (column, key) => { - return ptmo(ColumnBase.getCProp(column, 'pt'), key, { - props: getColumnProps(column), + const cProps = getColumnProps(column); + + const columnMetadata = { + props: cProps, parent: props.metaData, context: { checked: isChecked(), partialChecked: isPartialChecked() } - }); + }; + + return mergeProps(ptm(`column.${key}`, { column: columnMetadata }), ptm(`column.${key}`, columnMetadata), ptmo(cProps, key, columnMetadata)); }; const getRowPTOptions = (key) => { - return ptmo(props.pt, key, { - props: props, - parent: props.metaData, + const rowMetadata = { context: { index: props.index, - selected: props.selected, - selectable: props.metaData.props.rowHover, + selected: isSelected(), + selectable: props.node.selectable !== false, frozen: getColumnProp('frozen'), scrollable: props.metaData.props.scrollable, showGridlines: props.metaData.props.showGridlines } - }); + }; + + return ptm(key, rowMetadata); }; const isLeaf = () => { return props.node.leaf === false ? false : !(props.node.children && props.node.children.length); }; - const getColumnProp = (column, name) => { - return ColumnBase.getCProp(column, name); - }; - const onTogglerClick = (event) => { expanded ? collapse(event) : expand(event); @@ -343,7 +358,7 @@ export const TreeTableRow = React.memo((props) => { className: cx('rowToggler'), onClick: (e) => onTogglerClick(e), tabIndex: -1, - style: sx('rowToggler', { rowProps: props }), + style: { marginLeft: props.level * 16 + 'px', visibility: props.node.leaf === false || (props.node.children && props.node.children.length) ? 'visible' : 'hidden' }, 'aria-label': label }, getColumnPTOptions(column, 'rowToggler') @@ -525,7 +540,8 @@ export const TreeTableRow = React.memo((props) => { onContextMenu: (e) => onRightClick(e), onKeyDown: (e) => onKeyDown(e), onMouseEnter: (e) => onMouseEnter(e), - onMouseLeave: (e) => onMouseLeave(e) + onMouseLeave: (e) => onMouseLeave(e), + 'data-p-highlight': isSelected() }, getRowPTOptions('row') ); diff --git a/components/lib/treetable/TreeTableScrollableView.js b/components/lib/treetable/TreeTableScrollableView.js index d701dfcd94..6fd92069c7 100644 --- a/components/lib/treetable/TreeTableScrollableView.js +++ b/components/lib/treetable/TreeTableScrollableView.js @@ -37,7 +37,7 @@ export const TreeTableScrollableView = React.memo((props) => { if (element) { let el = element; - while (el && !DomHandler.hasClass(el, 'p-treetable')) { + while (el && !(DomHandler.getAttribute(el, 'data-pc-section') === 'root' || DomHandler.getAttribute(el, 'data-pc-name') === 'treetable')) { el = el.parentElement; } @@ -110,7 +110,7 @@ export const TreeTableScrollableView = React.memo((props) => { const scrollableProps = mergeProps( { className: cx('scrollable', { scrolaableProps: props }), - style: sx('scrollable', { width, left }) + style: { width, left } }, ptm('scrollable') ); @@ -140,7 +140,7 @@ export const TreeTableScrollableView = React.memo((props) => { const scrollableBodyProps = mergeProps( { className: cx('scrollableBody'), - style: sx('scrollableBody', { scrolaableProps: props }), + style: !props.frozen && props.scrollHeight ? { overflowY: 'scroll' } : undefined, onScroll: (e) => onBodyScroll(e) }, ptm('scrollableBody') @@ -148,7 +148,7 @@ export const TreeTableScrollableView = React.memo((props) => { const scrollableBodyTableProps = mergeProps( { - style: sx('scrollableBodyTable'), + style: { top: '0' }, className: cx('scrollableBodyTable') }, ptm('scrollableBodyTable') diff --git a/components/lib/treetable/treetable.d.ts b/components/lib/treetable/treetable.d.ts index d57c8b713b..3ddf208b01 100644 --- a/components/lib/treetable/treetable.d.ts +++ b/components/lib/treetable/treetable.d.ts @@ -84,6 +84,10 @@ export interface TreeTablePassThroughOptions { * Uses to pass attributes to the empty message's DOM element. */ emptyMessage?: TreeTablePassThroughType>; + /** + * Uses to pass attributes to the empty message cell's DOM element. + */ + emptyMessageCell?: TreeTablePassThroughType>; /** * Uses to pass attributes to the body cell's DOM element. */