From 017ad3466cff20fc16f9693578ad81a5d13df632 Mon Sep 17 00:00:00 2001 From: Melloware Date: Tue, 9 Jan 2024 13:32:52 -0500 Subject: [PATCH] Port fixes4 (#5712) * Fix #5444/#5443: Tailwind fixes * Fix #5447: TreeSelect don't close panel on unselect * Fix #5445: Tabview passthrough fixes * Fix #5452: Datatable onRowEditChange typescript def * Fix #5461: Passthrough case insensitve props * Fix #5465: Sidebar passthrough fix * Fix #5466: Slider remove handlers * Fix #5464: Tailwind fixes * Fix #5477: ComponentBase fkey refactor * Fix #5461: Passthrough TS and casing issues --- components/lib/accordion/accordion.d.ts | 35 ++++++ .../lib/cascadeselect/cascadeselect.d.ts | 4 + components/lib/componentbase/ComponentBase.js | 12 +- .../lib/confirmdialog/confirmdialog.d.ts | 9 +- components/lib/datatable/datatable.d.ts | 2 +- components/lib/passthrough/tailwind/index.js | 103 +++++++----------- components/lib/sidebar/sidebar.d.ts | 2 +- components/lib/tabview/TabView.js | 31 ++++-- components/lib/tabview/tabview.d.ts | 35 ++++++ components/lib/tooltip/tooltip.d.ts | 27 +++++ components/lib/treeselect/TreeSelect.js | 1 + 11 files changed, 178 insertions(+), 83 deletions(-) diff --git a/components/lib/accordion/accordion.d.ts b/components/lib/accordion/accordion.d.ts index dbb78feb8b..df90a79c48 100644 --- a/components/lib/accordion/accordion.d.ts +++ b/components/lib/accordion/accordion.d.ts @@ -28,6 +28,7 @@ export declare type AccordionPassThroughTransitionType = ReactCSSTransitionProps export interface AccordionTabPassThroughMethodOptions { props: AccordionTabProps; parent: AccordionPassThroughMethodOptions; + context: AccordionContext; } /** @@ -74,6 +75,40 @@ export interface AccordionTabPassThroughOptions { transition?: AccordionPassThroughTransitionType; } +/** + * Defines current inline context in Accordion component. + */ +export interface AccordionContext { + /** + * Opened tab index. + */ + index: number; + /** + * Total number of tabs + */ + count: number; + /** + * Is this the first tab? + * @defaultValue false + */ + first: boolean; + /** + * Is this the last tab? + * @defaultValue false + */ + last: boolean; + /** + * Is this tab currently selected. + * @defaultValue false + */ + selected: boolean; + /** + * Is this tab currently disabled. + * @defaultValue false + */ + disabled: boolean; +} + /** * Defines valid properties in AccordionTab component. * @group Properties diff --git a/components/lib/cascadeselect/cascadeselect.d.ts b/components/lib/cascadeselect/cascadeselect.d.ts index b0e97bc18e..a935b82688 100644 --- a/components/lib/cascadeselect/cascadeselect.d.ts +++ b/components/lib/cascadeselect/cascadeselect.d.ts @@ -87,6 +87,10 @@ export interface CascadeSelectPassThroughOptions { * Uses to pass attributes to the item's DOM element. */ item?: CascadeSelectPassThroughType>; + /** + * Uses to pass attributes to the sub-list's DOM element. + */ + sublist?: CascadeSelectPassThroughType>; /** * Uses to pass attributes to the content's DOM element. */ diff --git a/components/lib/componentbase/ComponentBase.js b/components/lib/componentbase/ComponentBase.js index 8960da8bcd..6c1d309154 100644 --- a/components/lib/componentbase/ComponentBase.js +++ b/components/lib/componentbase/ComponentBase.js @@ -497,13 +497,13 @@ export const ComponentBase = { obj = obj.pt; } + const originalkey = key; + const isNestedParam = /./g.test(originalkey) && !!params[originalkey.split('.')[0]]; + const fkey = isNestedParam ? ObjectUtils.toFlatCase(originalkey.split('.')[1]) : ObjectUtils.toFlatCase(originalkey); const hostName = params.hostName && ObjectUtils.toFlatCase(params.hostName); const componentName = hostName || (params.props && params.props.__TYPE && ObjectUtils.toFlatCase(params.props.__TYPE)) || ''; - const isNestedParam = /./g.test(key) && !!params[key.split('.')[0]]; - const isTransition = key === 'transition' || (/./g.test(key) && !!(key.split('.')[1] === 'transition')); - + const isTransition = fkey === 'transition'; const datasetPrefix = 'data-pc-'; - const fkey = isNestedParam ? ObjectUtils.toFlatCase(key.split('.')[1]) : ObjectUtils.toFlatCase(key); const getHostInstance = (params) => { return params?.props ? (params.hostName ? (params.props.__TYPE === params.hostName ? params.props : getHostInstance(params.parent)) : params.parent) : undefined; @@ -523,8 +523,8 @@ export const ComponentBase = { return ObjectUtils.isString(value) ? { className: value } : value; }; - const globalPT = searchInDefaultPT ? (isNestedParam ? _useGlobalPT(getPTClassValue, key, params) : _useDefaultPT(getPTClassValue, key, params)) : undefined; - const self = isNestedParam ? undefined : _usePT(_getPT(obj, componentName), getPTClassValue, key, params, componentName); + const globalPT = searchInDefaultPT ? (isNestedParam ? _useGlobalPT(getPTClassValue, originalkey, params) : _useDefaultPT(getPTClassValue, originalkey, params)) : undefined; + const self = isNestedParam ? undefined : _usePT(_getPT(obj, componentName), getPTClassValue, originalkey, params, componentName); const datasetProps = !isTransition && { ...(fkey === 'root' && { [`${datasetPrefix}name`]: params.props && params.props.__parentMetadata ? ObjectUtils.toFlatCase(params.props.__TYPE) : componentName }), diff --git a/components/lib/confirmdialog/confirmdialog.d.ts b/components/lib/confirmdialog/confirmdialog.d.ts index 6bcc869966..a10e6ef8f6 100644 --- a/components/lib/confirmdialog/confirmdialog.d.ts +++ b/components/lib/confirmdialog/confirmdialog.d.ts @@ -14,12 +14,13 @@ import { DialogProps } from '../dialog'; import { PassThroughOptions } from '../passthrough'; import { IconType, PassThroughType } from '../utils'; -export declare type ConfirmDialogPassThroughType = PassThroughType; +export declare type ConfirmDialogPassThroughType = PassThroughType; +export declare type ConfirmDialogPassThroughTransitionType = ReactCSSTransitionProps | ((options: ConfirmDialogPassThroughMethodOptions) => ReactCSSTransitionProps) | undefined; /** * Custom passthrough(pt) option method. */ -export interface ConfirmDialogThroughMethodOptions { +export interface ConfirmDialogPassThroughMethodOptions { props: ConfirmDialogProps; state: ConfirmDialogState; } @@ -84,6 +85,10 @@ export interface ConfirmDialogPassThroughOptions { * @see {@link ComponentHooks} */ hooks?: ComponentHooks; + /** + * Used to control React Transition API. + */ + transition?: ConfirmDialogPassThroughTransitionType; } /** diff --git a/components/lib/datatable/datatable.d.ts b/components/lib/datatable/datatable.d.ts index ffb149f1da..02a2c3fab1 100644 --- a/components/lib/datatable/datatable.d.ts +++ b/components/lib/datatable/datatable.d.ts @@ -1538,7 +1538,7 @@ interface DataTableBaseProps extends Omit ({ + root: ({ state }) => ({ className: classNames('w-16 !h-16 !rounded-full justify-center z-10', { - 'rotate-45': parent.state.visible + 'rotate-45': state.visible }) }), label: { @@ -750,8 +750,8 @@ const Tailwind = { menu: { className: classNames('outline-none', 'py-1 px-0 rounded-md list-none bg-white border-none shadow-lg') }, - menulist: 'm-0 p-0 border-none outline-none no-underline list-none', - menubutton: { + menuList: 'm-0 p-0 border-none outline-none no-underline list-none', + menuButton: { root: ({ parent }) => ({ className: classNames('rounded-l-none', { 'rounded-r-full': parent.props.rounded }) }), @@ -780,19 +780,20 @@ const Tailwind = { }, inputnumber: { root: 'w-full inline-flex', - input: ({ props }) => ({ - className: classNames({ 'rounded-tr-none rounded-br-none': props.showButtons && props.buttonLayout == 'stacked' }) - }), - buttongroup: ({ props }) => ({ + input: { + root: ({ props }) => ({ + className: classNames({ 'rounded-tr-none rounded-br-none': props.showButtons && props.buttonLayout == 'stacked' }) + }) + }, + buttonGroup: ({ props }) => ({ className: classNames({ 'flex flex-col': props.showButtons && props.buttonLayout == 'stacked' }) }), - incrementbutton: ({ props }) => ({ + incrementButton: ({ props }) => ({ className: classNames('flex !items-center !justify-center', { 'rounded-br-none rounded-bl-none rounded-bl-none !p-0 flex-1 w-[3rem]': props.showButtons && props.buttonLayout == 'stacked' }) }), - label: 'hidden', - decrementbutton: ({ props }) => ({ + decrementButton: ({ props }) => ({ className: classNames('flex !items-center !justify-center', { 'rounded-tr-none rounded-tl-none rounded-tl-none !p-0 flex-1 w-[3rem]': props.showButtons && props.buttonLayout == 'stacked' }) @@ -836,7 +837,7 @@ const Tailwind = { label: { className: classNames('block whitespace-nowrap overflow-hidden flex flex-1 w-1 text-overflow-ellipsis cursor-pointer', 'bg-transparent border-0 p-3 text-gray-700 dark:text-white/80', 'appearance-none rounded-md') }, - dropdownbutton: { + dropdownButton: { className: classNames('flex items-center justify-center shrink-0', 'bg-transparent text-gray-600 dark:text-white/80 w-[3rem] rounded-tr-6 rounded-br-6') }, panel: 'absolute py-3 bg-white dark:bg-gray-900 border-0 shadow-md', @@ -854,7 +855,7 @@ const Tailwind = { content: { className: classNames('flex items-center overflow-hidden relative', 'py-3 px-5') }, - optiongroupicon: 'ml-auto', + optionGroupIcon: 'ml-auto', transition: TRANSITIONS.overlay }, inputmask: { @@ -866,7 +867,7 @@ const Tailwind = { 'opacity-60 select-none pointer-events-none cursor-default': props.disabled }) }), - cancelitem: ({ context }) => ({ + cancelItem: ({ context }) => ({ className: classNames( 'inline-flex items-center cursor-pointer' @@ -875,25 +876,25 @@ const Tailwind = { // } ) }), - cancelicon: { + cancelIcon: { className: classNames('text-red-500', 'w-5 h-5', 'transition duration-200 ease-in') }, item: ({ props, context }) => ({ className: classNames( 'inline-flex items-center', { - 'cursor-pointer': !props.readonly, - 'cursor-default': props.readonly + 'cursor-pointer': !props.readOnly, + 'cursor-default': props.readOnly }, { - 'outline-none outline-offset-0 shadow-[0_0_0_0.2rem_rgba(191,219,254,1)] dark:shadow-[0_0_0_0.2rem_rgba(147,197,253,0.5)]': context.focused + 'outline-none outline-offset-0 shadow-[0_0_0_0.2rem_rgba(191,219,254,1)] dark:shadow-[0_0_0_0.2rem_rgba(147,197,253,0.5)]': context.active } ) }), - officon: { + offIcon: { className: classNames('text-gray-700 hover:text-blue-400', 'w-5 h-5', 'transition duration-200 ease-in') }, - onicon: { + onIcon: { className: classNames('text-blue-500', 'w-5 h-5', 'transition duration-200 ease-in') } }, @@ -943,30 +944,6 @@ const Tailwind = { 'left-[50%] mb-[-0.5715rem] ml-[-0.4715rem]': props.orientation == 'vertical' } ) - }), - starthandler: ({ props }) => ({ - className: classNames( - 'h-4 w-4 bg-white dark:bg-gray-600 border-2 border-blue-500 rounded-full transition duration-200', - 'cursor-grab touch-action-none block', - '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)]', - 'hover:bg-blue-500 hover:border hover:border-blue-500', - { - 'top-[50%] mt-[-0.5715rem] ml-[-0.5715rem]': props.orientation == 'horizontal', - 'left-[50%] mb-[-0.5715rem] ml-[-0.4715rem]': props.orientation == 'vertical' - } - ) - }), - endhandler: ({ props }) => ({ - className: classNames( - 'h-4 w-4 bg-white dark:bg-gray-600 border-2 border-blue-500 rounded-full transition duration-200', - 'cursor-grab touch-action-none block', - '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)]', - 'hover:bg-blue-500 hover:border hover:border-blue-500', - { - 'top-[50%] mt-[-0.5715rem] ml-[-0.5715rem]': props.orientation == 'horizontal', - 'left-[50%] mb-[-0.5715rem] ml-[-0.4715rem]': props.orientation == 'vertical' - } - ) }) }, password: { @@ -977,7 +954,7 @@ const Tailwind = { }), panel: 'p-5 bg-white dark:bg-gray-900 text-gray-700 dark:text-white/80 shadow-md rounded-md', meter: 'mb-2 bg-gray-300 dark:bg-gray-700 h-3', - meterlabel: ({ state, props }) => ({ + meterLabel: ({ state, props }) => ({ className: classNames( 'transition-width duration-1000 ease-in-out h-full', { @@ -988,10 +965,10 @@ const Tailwind = { { 'pr-[2.5rem] ': props.toggleMask } ) }), - showicon: { + showIcon: { className: classNames('absolute top-1/2 -mt-2', 'right-3 text-gray-600 dark:text-white/70') }, - hideicon: { + hideIcon: { className: classNames('absolute top-1/2 -mt-2', 'right-3 text-gray-600 dark:text-white/70') }, transition: TRANSITIONS.overlay @@ -1016,7 +993,7 @@ const Tailwind = { label: 'font-bold text-center w-full', icon: ({ props }) => ({ className: classNames(' mr-2', { - 'text-gray-600 dark:text-white/70': !props.modelValue, + 'text-gray-600 dark:text-white/70': !props.checked, 'text-white': props.checked }) }) @@ -1122,14 +1099,14 @@ const Tailwind = { 'opacity-60 select-none pointer-events-none cursor-default': context.disabled }) }), - itemgroup: { + itemGroup: { className: classNames('m-0 p-3 text-gray-800 bg-white font-bold', 'dark:bg-gray-900 dark:text-white/80', 'cursor-auto') }, header: { className: classNames('p-3 border-b border-gray-300 text-gray-700 bg-gray-100 mt-0 rounded-tl-lg rounded-tr-lg', 'dark:bg-gray-800 dark:text-white/80 dark:border-blue-900/40') }, - filtercontainer: 'relative', - filterinput: { + filterContainer: 'relative', + filterInput: { className: classNames( 'pr-7 -mr-7', 'w-full', @@ -1138,8 +1115,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 }, calendar: { @@ -1156,7 +1133,7 @@ const Tailwind = { }) }) }, - dropdownbutton: ({ props }) => ({ + dropdownButton: ({ props }) => ({ root: { className: classNames({ 'rounded-l-none': props.showIcon }) } @@ -1313,8 +1290,8 @@ const Tailwind = { labelContainer: 'overflow-hidden flex flex-auto cursor-pointer', label: ({ props }) => ({ className: classNames('block overflow-hidden whitespace-nowrap cursor-pointer overflow-ellipsis', 'text-gray-800 dark:text-white/80', 'p-3 transition duration-200', { - '!p-3': props.display !== 'chip' && (props?.modelValue == null || props?.modelValue == undefined), - '!py-1.5 px-3': props.display === 'chip' && props?.modelValue !== null + '!p-3': props.display !== 'chip' && (props.value == null || props.value == undefined), + '!py-1.5 px-3': props.display === 'chip' && props.value !== null }) }), token: { @@ -1494,7 +1471,7 @@ const Tailwind = { token: { className: classNames('py-1 px-2 mr-2 bg-gray-300 dark:bg-gray-700 text-gray-700 dark:text-white/80 rounded-full', 'cursor-default inline-flex items-center') }, - dropdownbutton: { + dropdownButton: { root: 'rounded-tl-none rounded-bl-none' }, panel: { diff --git a/components/lib/sidebar/sidebar.d.ts b/components/lib/sidebar/sidebar.d.ts index 82ff6b0e5a..0f91ab0211 100644 --- a/components/lib/sidebar/sidebar.d.ts +++ b/components/lib/sidebar/sidebar.d.ts @@ -41,7 +41,7 @@ export interface SidebarPassThroughOptions { /** * Uses to pass attributes to the close button's DOM element. */ - closeButton?: SidebarPassThroughType>; + closeButtonIcon?: SidebarPassThroughType>; /** * Uses to pass attributes to the close icon's DOM element. */ diff --git a/components/lib/tabview/TabView.js b/components/lib/tabview/TabView.js index 3113b46454..5e870f8371 100644 --- a/components/lib/tabview/TabView.js +++ b/components/lib/tabview/TabView.js @@ -28,6 +28,7 @@ export const TabView = React.forwardRef((inProps, ref) => { const nextBtnRef = React.useRef(null); const tabsRef = React.useRef({}); const activeIndex = props.onTabChange ? props.activeIndex : activeIndexState; + const count = React.Children.count(props.children); const metaData = { props, @@ -46,11 +47,21 @@ export const TabView = React.forwardRef((inProps, ref) => { useHandleStyle(TabViewBase.css.styles, isUnstyled, { name: 'tabview' }); - const getTabPT = (tab, key) => { - return ptmo(getTabProp(tab, 'pt'), key, { + const getTabPT = (tab, key, index) => { + const tabMetaData = { props: tab.props, - parent: metaData - }); + parent: metaData, + context: { + index, + count, + first: index === 0, + last: index === count - 1, + active: index == activeIndexState, + disabled: getTabProp(tab, 'disabled') + } + }; + + return mergeProps(ptm(`tab.${key}`, { tab: tabMetaData }), ptm(`tabpanel.${key}`, { tabpanel: tabMetaData }), ptm(`tabpanel.${key}`, tabMetaData), ptmo(getTabProp(tab, 'pt'), key, tabMetaData)); }; const isSelected = (index) => index === activeIndex; @@ -321,7 +332,7 @@ export const TabView = React.forwardRef((inProps, ref) => { { className: cx('tab.headertitle') }, - getTabPT(tab, 'headertitle') + getTabPT(tab, 'headertitle', index) ); const titleElement = {header}; const rightIconElement = rightIcon && IconUtils.getJSXIcon(rightIcon, undefined, { props }); @@ -341,7 +352,7 @@ export const TabView = React.forwardRef((inProps, ref) => { onClick: (e) => onTabHeaderClick(e, tab, index), onKeyDown: (e) => onKeyDown(e, tab, index) }, - getTabPT(tab, 'headeraction') + getTabPT(tab, 'headeraction', index) ); let content = ( @@ -382,8 +393,8 @@ export const TabView = React.forwardRef((inProps, ref) => { style: sx('tab.header', { headerStyle, _style }), role: 'presentation' }, - getTabPT(tab, 'root'), - getTabPT(tab, 'header') + getTabPT(tab, 'root', index), + getTabPT(tab, 'header', index) ); return
  • {content}
  • ; @@ -462,8 +473,8 @@ export const TabView = React.forwardRef((inProps, ref) => { 'aria-labelledby': ariaLabelledBy }, TabPanelBase.getCOtherProps(tab), - getTabPT(tab, 'root'), - getTabPT(tab, 'content') + getTabPT(tab, 'root', index), + getTabPT(tab, 'content', index) ); return
    {!props.renderActiveOnly ? getTabProp(tab, 'children') : selected && getTabProp(tab, 'children')}
    ; diff --git a/components/lib/tabview/tabview.d.ts b/components/lib/tabview/tabview.d.ts index 5298d7ffed..592bde95d6 100644 --- a/components/lib/tabview/tabview.d.ts +++ b/components/lib/tabview/tabview.d.ts @@ -81,6 +81,41 @@ interface TabPanelHeaderTemplateOptions { export interface TabPanelPassThroughMethodOptions { props: TabPanelProps; parent: TabViewPassThroughMethodOptions; + context: TabViewContext; +} + +/** + * Defines current inline context in Tabview component. + */ +export interface TabViewContext { + /** + * Opened tab index. + */ + index: number; + /** + * Total number of tabs + */ + count: number; + /** + * Is this the first tab? + * @defaultValue false + */ + first: boolean; + /** + * Is this the last tab? + * @defaultValue false + */ + last: boolean; + /** + * Is this tab currently selected. + * @defaultValue false + */ + selected: boolean; + /** + * Is this tab currently disabled. + * @defaultValue false + */ + disabled: boolean; } /** diff --git a/components/lib/tooltip/tooltip.d.ts b/components/lib/tooltip/tooltip.d.ts index 066287feac..8514e92cfc 100644 --- a/components/lib/tooltip/tooltip.d.ts +++ b/components/lib/tooltip/tooltip.d.ts @@ -21,6 +21,7 @@ export declare type TooltipPassThroughType = PassThroughType { props.onNodeUnselect && props.onNodeUnselect(node); + isCheckboxSelectionMode && node.originalEvent.stopPropagation(); }; const onNodeToggle = (e) => {