Skip to content

Commit

Permalink
Related #4431, #4432, #4602 - For MultiSelect & TreeTable
Browse files Browse the repository at this point in the history
  • Loading branch information
ulasturann committed Sep 7, 2023
1 parent 8e47174 commit e997277
Show file tree
Hide file tree
Showing 16 changed files with 197 additions and 135 deletions.
11 changes: 6 additions & 5 deletions components/lib/multiselect/MultiSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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) => {
Expand Down Expand Up @@ -769,6 +769,7 @@ export const MultiSelect = React.memo(
ptm={ptm}
cx={cx}
sx={sx}
isUnstyled={isUnstyled}
/>
</div>
{hasTooltip && <Tooltip target={elementRef} content={props.tooltip} {...props.tooltipOptions} pt={ptm('tooltip')} />}
Expand Down
16 changes: 6 additions & 10 deletions components/lib/multiselect/MultiSelectBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 }) =>
Expand Down
14 changes: 7 additions & 7 deletions components/lib/multiselect/MultiSelectHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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 || <CheckIcon {...headerCheckboxProps} />;
const itemCheckboxIcon = IconUtils.getJSXIcon(checkedIcon, { ...headerCheckboxProps }, { selected: props.selected });
const checkedIcon = props.itemCheckboxIcon || <CheckIcon {...headerCheckboxIconProps} />;
const itemCheckboxIcon = IconUtils.getJSXIcon(checkedIcon, { ...headerCheckboxIconProps }, { selected: props.selected });

const checkboxElement = props.showSelectAll && (
<div className="p-multiselect-select-all">
<Checkbox id={selectAllId} checked={props.selectAll} onChange={onSelectAll} role="checkbox" aria-checked={props.selectAll} icon={itemCheckboxIcon} />
<Checkbox id={selectAllId} checked={props.selectAll} onChange={onSelectAll} role="checkbox" aria-checked={props.selectAll} icon={itemCheckboxIcon} pt={ptm('headercheckbox')} unstyled={isUnstyled()} />
{!props.filter && <label {...headerSelectAllLabelProps}>{props.selectAllLabel}</label>}
</div>
);
Expand Down
7 changes: 4 additions & 3 deletions components/lib/multiselect/MultiSelectItem.js
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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')
);
Expand Down
3 changes: 2 additions & 1 deletion components/lib/multiselect/MultiSelectPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => {
Expand Down Expand Up @@ -68,6 +68,7 @@ export const MultiSelectPanel = React.memo(
itemCheckboxIcon={props.itemCheckboxIcon}
ptm={ptm}
cx={cx}
isUnstyled={isUnstyled}
/>
);
};
Expand Down
7 changes: 6 additions & 1 deletion components/lib/multiselect/multiselect.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> = PassThroughType<T, MultiSelectPassThroughMethodOptions>;

Expand Down Expand Up @@ -86,7 +87,11 @@ export interface MultiSelectPassThroughOptions {
/**
* Uses to pass attributes to the header checkbox's DOM element.
*/
headerCheckbox?: MultiSelectPassThroughType<React.SVGProps<SVGSVGElement> | React.HTMLAttributes<HTMLSpanElement>>;
headerCheckbox?: CheckboxPassThroughOptions;
/**
* Uses to pass attributes to the header checkbox icon's DOM element.
*/
headerCheckboxIcon?: MultiSelectPassThroughType<React.SVGProps<SVGSVGElement> | React.HTMLAttributes<HTMLSpanElement>>;
/**
* Uses to pass attributes to the header checkbox's DOM element.
*/
Expand Down
76 changes: 48 additions & 28 deletions components/lib/passthrough/tailwind/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down Expand Up @@ -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')
},
Expand Down Expand Up @@ -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: {
Expand All @@ -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,
Expand Down Expand Up @@ -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
}
)
Expand All @@ -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(
Expand All @@ -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
}
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
Loading

0 comments on commit e997277

Please sign in to comment.