From c511b9e1fae83d2d011ae98b4ca668df2c47457d Mon Sep 17 00:00:00 2001 From: Melloware Date: Sat, 2 Dec 2023 08:17:41 -0500 Subject: [PATCH] Fix #5493: Multiselect passthrough fixes (#5504) --- .../doc/multiselect/theming/tailwinddoc.js | 46 ++++++++++--------- .../lib/multiselect/MultiSelectHeader.js | 11 ++++- components/lib/multiselect/MultiSelectItem.js | 15 +++++- components/lib/multiselect/multiselect.d.ts | 4 ++ components/lib/passthrough/tailwind/index.js | 40 ++++++++-------- 5 files changed, 72 insertions(+), 44 deletions(-) diff --git a/components/doc/multiselect/theming/tailwinddoc.js b/components/doc/multiselect/theming/tailwinddoc.js index a50235bd1a..d9fb1d78aa 100644 --- a/components/doc/multiselect/theming/tailwinddoc.js +++ b/components/doc/multiselect/theming/tailwinddoc.js @@ -21,7 +21,7 @@ const Tailwind = { multiselect: { root: ({ props }) => ({ className: classNames('inline-flex cursor-pointer select-none', 'bg-white dark:bg-gray-900 border border-gray-400 dark:border-blue-900/40 transition-colors duration-200 ease-in-out rounded-md', 'w-full md:w-80', { - 'opacity-60 select-none pointer-events-none cursor-default': props?.disabled + 'opacity-60 select-none pointer-events-none cursor-default': props.disabled }) }), labelContainer: 'overflow-hidden flex flex-auto cursor-pointer', @@ -47,18 +47,20 @@ const Tailwind = { headerCheckboxContainer: { className: classNames('inline-flex cursor-pointer select-none align-bottom relative', 'mr-2', 'w-6 h-6') }, - headerCheckbox: ({ context }) => ({ - className: classNames( - 'flex items-center justify-center', - 'border-2 w-6 h-6 text-gray-600 dark:text-white/70 rounded-lg transition-colors duration-200', - 'hover:border-blue-500 focus:outline-none focus:outline-offset-0 focus:shadow-[0_0_0_0.2rem_rgba(191,219,254,1)] dark:focus:shadow-[0_0_0_0.2rem_rgba(147,197,253,0.5)]', - { - 'border-gray-300 dark:border-blue-900/40 bg-white dark:bg-gray-900': !context?.selected, - 'border-blue-500 bg-blue-500': context?.selected - } - ) - }), - headercheckboxicon: 'w-4 h-4 transition-all duration-200 text-white text-base', + headerCheckbox: { + root: ({ props }) => ({ + className: classNames( + 'flex items-center justify-center', + 'border-2 w-6 h-6 text-gray-600 dark:text-white/70 rounded-lg transition-colors duration-200', + 'hover:border-blue-500 focus:outline-none focus:outline-offset-0 focus:shadow-[0_0_0_0.2rem_rgba(191,219,254,1)] dark:focus:shadow-[0_0_0_0.2rem_rgba(147,197,253,0.5)]', + { + 'border-gray-300 dark:border-blue-900/40 bg-white dark:bg-gray-900': !props?.checked, + 'border-blue-500 bg-blue-500': props?.checked + } + ) + }) + }, + headerCheckboxIcon: 'w-4 h-4 transition-all duration-200 text-white text-base', closeButton: { className: classNames( 'flex items-center justify-center overflow-hidden relative', @@ -67,7 +69,7 @@ const Tailwind = { 'focus:outline-none focus:outline-offset-0 focus:shadow-[0_0_0_0.2rem_rgba(191,219,254,1)] dark:focus:shadow-[0_0_0_0.2rem_rgba(147,197,253,0.5)]' ) }, - closeButtonIcon: 'w-4 h-4 inline-block', + closeIcon: 'w-4 h-4 inline-block', wrapper: { className: classNames('max-h-[200px] overflow-auto', 'bg-white text-gray-700 border-0 rounded-md shadow-lg', 'dark:bg-gray-900 dark:text-white/80') }, @@ -89,17 +91,17 @@ const Tailwind = { 'border-2 w-6 h-6 text-gray-600 dark:text-white/80 rounded-lg transition-colors duration-200', 'hover:border-blue-500 focus:outline-none focus:outline-offset-0 focus:shadow-[0_0_0_0.2rem_rgba(191,219,254,1)] dark:focus:shadow-[0_0_0_0.2rem_rgba(147,197,253,0.5)]', { - 'border-gray-300 dark:border-blue-900/40 bg-white dark:bg-gray-900': !context?.selected, - 'border-blue-500 bg-blue-500': context?.selected + 'border-gray-300 dark:border-blue-900/40 bg-white dark:bg-gray-900': !context.selected, + 'border-blue-500 bg-blue-500': context.selected } ) }), - checkboxicon: 'w-4 h-4 transition-all duration-200 text-white text-base', - itemgroup: { + checkboxIcon: 'w-4 h-4 transition-all duration-200 text-white text-base', + itemGroup: { className: classNames('m-0 p-3 text-gray-800 bg-white font-bold', 'dark:bg-gray-900 dark:text-white/80', 'cursor-auto') }, - filtercontainer: 'relative', - filterinput: { + filterContainer: 'relative', + filterInput: { className: classNames( 'pr-7 -mr-7', 'w-full', @@ -108,8 +110,8 @@ const Tailwind = { 'hover:border-blue-500 focus:outline-none focus:outline-offset-0 focus:shadow-[0_0_0_0.2rem_rgba(191,219,254,1)] dark:focus:shadow-[0_0_0_0.2rem_rgba(147,197,253,0.5)]' ) }, - filtericon: '-mt-2 absolute top-1/2', - clearicon: 'text-gray-500 right-12 -mt-2 absolute top-1/2', + filterIcon: '-mt-2 absolute top-1/2', + clearIcon: 'text-gray-500 right-12 -mt-2 absolute top-1/2', transition: TRANSITIONS.overlay } } diff --git a/components/lib/multiselect/MultiSelectHeader.js b/components/lib/multiselect/MultiSelectHeader.js index 3921b27679..9145c7738f 100644 --- a/components/lib/multiselect/MultiSelectHeader.js +++ b/components/lib/multiselect/MultiSelectHeader.js @@ -116,12 +116,19 @@ export const MultiSelectHeader = React.memo((props) => { getPTOptions('headerCheckboxIcon') ); + const headerCheckboxContainerProps = mergeProps( + { + className: cx('headerCheckboxContainer') + }, + getPTOptions('headerCheckboxContainer') + ); + 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 9339c8694b..e2d8cedda9 100644 --- a/components/lib/multiselect/MultiSelectItem.js +++ b/components/lib/multiselect/MultiSelectItem.js @@ -4,13 +4,16 @@ import { Ripple } from '../ripple/Ripple'; import { IconUtils, ObjectUtils, classNames, mergeProps } from '../utils/Utils'; export const MultiSelectItem = React.memo((props) => { + const [focused, setFocused] = React.useState(false); const { ptm, cx } = props; const getPTOptions = (key) => { return ptm(key, { hostName: props.hostName, context: { - selected: props.selected + selected: props.selected, + disabled: props.disabled, + focused: focused } }); }; @@ -36,6 +39,14 @@ export const MultiSelectItem = React.memo((props) => { } }; + const onFocus = (event) => { + setFocused(true); + }; + + const onBlur = (event) => { + setFocused(false); + }; + const checkboxIconProps = mergeProps( { className: cx('checkboxIcon') @@ -71,6 +82,8 @@ export const MultiSelectItem = React.memo((props) => { onClick: onClick, tabIndex: tabIndex, onKeyDown: onKeyDown, + onFocus: onFocus, + onBlur: onBlur, role: 'option', 'aria-selected': props.selected, 'data-p-highlight': props.selected, diff --git a/components/lib/multiselect/multiselect.d.ts b/components/lib/multiselect/multiselect.d.ts index 273b31037e..6a75171cda 100644 --- a/components/lib/multiselect/multiselect.d.ts +++ b/components/lib/multiselect/multiselect.d.ts @@ -88,6 +88,10 @@ export interface MultiSelectPassThroughOptions { * Uses to pass attributes to the header's DOM element. */ header?: MultiSelectPassThroughType>; + /** + * Uses to pass attributes to the header checkbox's container DOM element. + */ + headerCheckboxContainer?: MultiSelectPassThroughType>; /** * 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 51d35499bb..428b66464b 100644 --- a/components/lib/passthrough/tailwind/index.js +++ b/components/lib/passthrough/tailwind/index.js @@ -1313,18 +1313,20 @@ const Tailwind = { headerCheckboxContainer: { className: classNames('inline-flex cursor-pointer select-none align-bottom relative', 'mr-2', 'w-6 h-6') }, - headerCheckbox: ({ context }) => ({ - className: classNames( - 'flex items-center justify-center', - 'border-2 w-6 h-6 text-gray-600 dark:text-white/70 rounded-lg transition-colors duration-200', - 'hover:border-blue-500 focus:outline-none focus:outline-offset-0 focus:shadow-[0_0_0_0.2rem_rgba(191,219,254,1)] dark:focus:shadow-[0_0_0_0.2rem_rgba(147,197,253,0.5)]', - { - 'border-gray-300 dark:border-blue-900/40 bg-white dark:bg-gray-900': !context.selected, - 'border-blue-500 bg-blue-500': context.selected - } - ) - }), - headercheckboxicon: 'w-4 h-4 transition-all duration-200 text-white text-base', + headerCheckbox: { + root: ({ props }) => ({ + className: classNames( + 'flex items-center justify-center', + 'border-2 w-6 h-6 text-gray-600 dark:text-white/70 rounded-lg transition-colors duration-200', + 'hover:border-blue-500 focus:outline-none focus:outline-offset-0 focus:shadow-[0_0_0_0.2rem_rgba(191,219,254,1)] dark:focus:shadow-[0_0_0_0.2rem_rgba(147,197,253,0.5)]', + { + 'border-gray-300 dark:border-blue-900/40 bg-white dark:bg-gray-900': !props?.checked, + 'border-blue-500 bg-blue-500': props?.checked + } + ) + }) + }, + headerCheckboxIcon: 'w-4 h-4 transition-all duration-200 text-white text-base', closeButton: { className: classNames( 'flex items-center justify-center overflow-hidden relative', @@ -1333,7 +1335,7 @@ const Tailwind = { 'focus:outline-none focus:outline-offset-0 focus:shadow-[0_0_0_0.2rem_rgba(191,219,254,1)] dark:focus:shadow-[0_0_0_0.2rem_rgba(147,197,253,0.5)]' ) }, - closeButtonIcon: 'w-4 h-4 inline-block', + closeIcon: 'w-4 h-4 inline-block', wrapper: { className: classNames('max-h-[200px] overflow-auto', 'bg-white text-gray-700 border-0 rounded-md shadow-lg', 'dark:bg-gray-900 dark:text-white/80') }, @@ -1360,12 +1362,12 @@ const Tailwind = { } ) }), - checkboxicon: 'w-4 h-4 transition-all duration-200 text-white text-base', - itemgroup: { + checkboxIcon: 'w-4 h-4 transition-all duration-200 text-white text-base', + itemGroup: { className: classNames('m-0 p-3 text-gray-800 bg-white font-bold', 'dark:bg-gray-900 dark:text-white/80', 'cursor-auto') }, - filtercontainer: 'relative', - filterinput: { + filterContainer: 'relative', + filterInput: { className: classNames( 'pr-7 -mr-7', 'w-full', @@ -1374,8 +1376,8 @@ const Tailwind = { 'hover:border-blue-500 focus:outline-none focus:outline-offset-0 focus:shadow-[0_0_0_0.2rem_rgba(191,219,254,1)] dark:focus:shadow-[0_0_0_0.2rem_rgba(147,197,253,0.5)]' ) }, - filtericon: '-mt-2 absolute top-1/2', - clearicon: 'text-gray-500 right-12 -mt-2 absolute top-1/2', + filterIcon: '-mt-2 absolute top-1/2', + clearIcon: 'text-gray-500 right-12 -mt-2 absolute top-1/2', transition: TRANSITIONS.overlay }, multistatecheckbox: {