diff --git a/components/doc/button/theming/tailwinddoc.js b/components/doc/button/theming/tailwinddoc.js index 6f5669874d..380a729139 100644 --- a/components/doc/button/theming/tailwinddoc.js +++ b/components/doc/button/theming/tailwinddoc.js @@ -9,31 +9,53 @@ const Tailwind = { button: { root: ({ props, context }) => ({ className: classNames( - 'items-center cursor-pointer inline-flex overflow-hidden relative select-none text-center align-bottom h-full', + 'items-center cursor-pointer inline-flex overflow-hidden relative select-none text-center align-bottom', 'transition duration-200 ease-in-out', - 'focus:outline-none focus:outline-offset-0 focus:shadow-[0_0_0_2px_rgba(255,255,255,1),0_0_0_4px_rgba(157,193,251,1),0_1px_2px_0_rgba(0,0,0,1)] dark:focus:shadow-[0_0_0_2px_rgba(28,33,39,1),0_0_0_4px_rgba(147,197,253,0.7),0_1px_2px_0_rgba(0,0,0,0)]', // Primary button focus + 'focus:outline-none focus:outline-offset-0', { - 'text-white bg-blue-500 border border-blue-500 hover:bg-blue-600 hover:border-blue-600': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain, - 'text-blue-600 bg-transparent border-transparent': props.link + 'text-white dark:text-gray-900 bg-blue-500 dark:bg-blue-400 border border-blue-500 dark:border-blue-400 hover:bg-blue-600 dark:hover:bg-blue-500 hover:border-blue-600 dark:hover:border-blue-500 focus:shadow-[0_0_0_2px_rgba(255,255,255,1),0_0_0_4px_rgba(157,193,251,1),0_1px_2px_0_rgba(0,0,0,1)] dark:focus:shadow-[0_0_0_2px_rgba(28,33,39,1),0_0_0_4px_rgba(147,197,253,0.7),0_1px_2px_0_rgba(0,0,0,0)]': + !props.link && props.severity === null && !props.text && !props.outlined && !props.plain, + 'text-blue-600 bg-transparent border-transparent focus:shadow-[0_0_0_2px_rgba(255,255,255,1),0_0_0_4px_rgba(157,193,251,1),0_1px_2px_0_rgba(0,0,0,1)] dark:focus:shadow-[0_0_0_2px_rgba(28,33,39,1),0_0_0_4px_rgba(147,197,253,0.7),0_1px_2px_0_rgba(0,0,0,0)]': + props.link }, { - 'text-white bg-gray-500 border border-gray-500 hover:bg-gray-600 hover:border-gray-600': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain, - 'text-white bg-green-500 border border-green-500 hover:bg-green-600 hover:border-green-600': props.severity === 'success' && !props.text && !props.outlined && !props.plain, - 'text-white bg-blue-500 border border-blue-500 hover:bg-blue-600 hover:border-blue-600': props.severity === 'info' && !props.text && !props.outlined && !props.plain, - 'text-white bg-orange-500 border border-orange-500 hover:bg-orange-600 hover:border-orange-600': props.severity === 'warning' && !props.text && !props.outlined && !props.plain, - 'text-white bg-purple-500 border border-purple-500 hover:bg-purple-600 hover:border-purple-600': props.severity === 'help' && !props.text && !props.outlined && !props.plain, - 'text-white bg-red-500 border border-red-500 hover:bg-red-600 hover:border-red-600': props.severity === 'danger' && !props.text && !props.outlined && !props.plain + 'focus:shadow-[0_0_0_2px_rgba(255,255,255,1),0_0_0_4px_rgba(176,185,198,1),0_1px_2px_0_rgba(0,0,0,1)] dark:focus:shadow-[0_0_0_2px_rgba(28,33,39,1),0_0_0_4px_rgba(203,213,225,0.7),0_1px_2px_0_rgba(0,0,0,0)]': + props.severity === 'secondary', + 'focus:shadow-[0_0_0_2px_rgba(255,255,255,1),0_0_0_4px_rgba(136,234,172,1),0_1px_2px_0_rgba(0,0,0,1)] dark:focus:shadow-[0_0_0_2px_rgba(28,33,39,1),0_0_0_4px_rgba(134,239,172,0.7),0_1px_2px_0_rgba(0,0,0,0)]': + props.severity === 'success', + 'focus:shadow-[0_0_0_2px_rgba(255,255,255,1),0_0_0_4px_rgba(157,193,251,1),0_1px_2px_0_rgba(0,0,0,1)] dark:focus:shadow-[0_0_0_2px_rgba(28,33,39,1),0_0_0_4px_rgba(147,197,253,0.7),0_1px_2px_0_rgba(0,0,0,0)]': + props.severity === 'info', + 'focus:shadow-[0_0_0_2px_rgba(255,255,255,1),0_0_0_4px_rgba(250,207,133,1),0_1px_2px_0_rgba(0,0,0,1)] dark:focus:shadow-[0_0_0_2px_rgba(28,33,39,1),0_0_0_4px_rgba(252,211,77,0.7),0_1px_2px_0_rgba(0,0,0,0)]': + props.severity === 'warning', + 'focus:shadow-[0_0_0_2px_rgba(255,255,255,1),0_0_0_4px_rgba(212,170,251,1),0_1px_2px_0_rgba(0,0,0,1)] dark:focus:shadow-[0_0_0_2px_rgba(28,33,39,1),0_0_0_4px_rgba(216,180,254,0.7),0_1px_2px_0_rgba(0,0,0,0)]': + props.severity === 'help', + 'focus:shadow-[0_0_0_2px_rgba(255,255,255,1),0_0_0_4px_rgba(247,162,162,1),0_1px_2px_0_rgba(0,0,0,1)] dark:focus:shadow-[0_0_0_2px_rgba(28,33,39,1),0_0_0_4px_rgba(252,165,165,0.7),0_1px_2px_0_rgba(0,0,0,0)]': + props.severity === 'danger' + }, + { + 'text-white dark:text-gray-900 bg-gray-500 dark:bg-gray-400 border border-gray-500 dark:border-gray-400 hover:bg-gray-600 dark:hover:bg-gray-500 hover:border-gray-600 dark:hover:border-gray-500': + props.severity === 'secondary' && !props.text && !props.outlined && !props.plain, + 'text-white dark:text-gray-900 bg-green-500 dark:bg-green-400 border border-green-500 dark:border-green-400 hover:bg-green-600 dark:hover:bg-green-500 hover:border-green-600 dark:hover:border-green-500': + props.severity === 'success' && !props.text && !props.outlined && !props.plain, + 'text-white dark:text-gray-900 dark:bg-blue-400 bg-blue-500 dark:bg-blue-400 border border-blue-500 dark:border-blue-400 hover:bg-blue-600 hover:border-blue-600 dark:hover:bg-blue-500 dark:hover:border-blue-500': + props.severity === 'info' && !props.text && !props.outlined && !props.plain, + 'text-white dark:text-gray-900 bg-orange-500 dark:bg-orange-400 border border-orange-500 dark:border-orange-400 hover:bg-orange-600 dark:hover:bg-orange-500 hover:border-orange-600 dark:hover:border-orange-500': + props.severity === 'warning' && !props.text && !props.outlined && !props.plain, + 'text-white dark:text-gray-900 bg-purple-500 dark:bg-purple-400 border border-purple-500 dark:border-purple-400 hover:bg-purple-600 dark:hover:bg-purple-500 hover:border-purple-600 dark:hover:border-purple-500': + props.severity === 'help' && !props.text && !props.outlined && !props.plain, + 'text-white dark:text-gray-900 bg-red-500 dark:bg-red-400 border border-red-500 dark:border-red-400 hover:bg-red-600 dark:hover:bg-red-500 hover:border-red-600 dark:hover:border-red-500': + props.severity === 'danger' && !props.text && !props.outlined && !props.plain }, { 'shadow-lg': props.raised }, { 'rounded-md': !props.rounded, 'rounded-full': props.rounded }, { 'bg-transparent border-transparent': props.text && !props.plain, - 'text-blue-500 hover:bg-blue-300/20': props.text && (props.severity === null || props.severity === 'info') && !props.plain, - 'text-gray-500 hover:bg-gray-300/20': props.text && props.severity === 'secondary' && !props.plain, - 'text-green-500 hover:bg-green-300/20': props.text && props.severity === 'success' && !props.plain, - 'text-orange-500 hover:bg-orange-300/20': props.text && props.severity === 'warning' && !props.plain, - 'text-purple-500 hover:bg-purple-300/20': props.text && props.severity === 'help' && !props.plain, - 'text-red-500 hover:bg-red-300/20': props.text && props.severity === 'danger' && !props.plain + 'text-blue-500 dark:text-blue-400 hover:bg-blue-300/20': props.text && (props.severity === null || props.severity === 'info') && !props.plain, + 'text-gray-500 dark:text-grayy-400 hover:bg-gray-300/20': props.text && props.severity === 'secondary' && !props.plain, + 'text-green-500 dark:text-green-400 hover:bg-green-300/20': props.text && props.severity === 'success' && !props.plain, + 'text-orange-500 dark:text-orange-400 hover:bg-orange-300/20': props.text && props.severity === 'warning' && !props.plain, + 'text-purple-500 dark:text-purple-400 hover:bg-purple-300/20': props.text && props.severity === 'help' && !props.plain, + 'text-red-500 dark:text-red-400 hover:bg-red-300/20': props.text && props.severity === 'danger' && !props.plain }, { 'shadow-lg': props.raised && props.text }, { @@ -43,28 +65,43 @@ const Tailwind = { }, { 'bg-transparent border': props.outlined && !props.plain, - 'text-blue-500 border border-blue-500 hover:bg-blue-300/20': props.outlined && (props.severity === null || props.severity === 'info') && !props.plain, - 'text-gray-500 border border-gray-500 hover:bg-gray-300/20': props.outlined && props.severity === 'secondary' && !props.plain, - 'text-green-500 border border-green-500 hover:bg-green-300/20': props.outlined && props.severity === 'success' && !props.plain, - 'text-orange-500 border border-orange-500 hover:bg-orange-300/20': props.outlined && props.severity === 'warning' && !props.plain, - 'text-purple-500 border border-purple-500 hover:bg-purple-300/20': props.outlined && props.severity === 'help' && !props.plain, - 'text-red-500 border border-red-500 hover:bg-red-300/20': props.outlined && props.severity === 'danger' && !props.plain + 'text-blue-500 dark:text-blue-400 border border-blue-500 dark:border-blue-400 hover:bg-blue-300/20': props.outlined && (props.severity === null || props.severity === 'info') && !props.plain, + 'text-gray-500 dark:text-gray-400 border border-gray-500 dark:border-gray-400 hover:bg-gray-300/20': props.outlined && props.severity === 'secondary' && !props.plain, + 'text-green-500 dark:text-green-400 border border-green-500 dark:border-green-400 hover:bg-green-300/20': props.outlined && props.severity === 'success' && !props.plain, + 'text-orange-500 dark:text-orange-400 border border-orange-500 dark:border-orange-400 hover:bg-orange-300/20': props.outlined && props.severity === 'warning' && !props.plain, + 'text-purple-500 dark:text-purple-400 border border-purple-500 dark:border-purple-400 hover:bg-purple-300/20': props.outlined && props.severity === 'help' && !props.plain, + 'text-red-500 dark:text-red-400 border border-red-500 dark:border-red-400 hover:bg-red-300/20': props.outlined && props.severity === 'danger' && !props.plain }, { 'px-4 py-3 text-base': props.size === null, 'text-xs py-2 px-3': props.size === 'small', 'text-xl py-3 px-4': props.size === 'large' }, + { 'flex-column': props.iconPos == 'top' || props.iconPos == 'bottom' }, { 'opacity-60 pointer-events-none cursor-default': context.disabled } ) }), label: ({ props }) => ({ - className: classNames('flex-1', 'duration-200', 'font-bold', { - 'hover:underline': props.link - }) + className: classNames( + 'flex-1', + 'duration-200', + 'font-bold', + { + 'hover:underline': props.link + }, + { 'invisible w-0': props.label == null } + ) }), icon: ({ props }) => ({ className: classNames('mx-0', { 'mr-2': props.iconPos == 'left' && props.label != null, - 'ml-2': props.iconPos == 'right' && props.label != null, + 'ml-2 order-1': props.iconPos == 'right' && props.label != null, 'mb-2': props.iconPos == 'top' && props.label != null, - 'mt-2': props.iconPos == 'bottom' && props.label != null + 'mt-2 order-2': props.iconPos == 'bottom' && props.label != null + }) + }), + loadingIcon: ({ props }) => ({ + className: classNames('mx-0', { + 'mr-2': props.loading && props.iconPos == 'left' && props.label != null, + 'ml-2 order-1': props.loading && props.iconPos == 'right' && props.label != null, + 'mb-2': props.loading && props.iconPos == 'top' && props.label != null, + 'mt-2 order-2': props.loading && props.iconPos == 'bottom' && props.label != null }) }), badge: ({ props }) => ({ diff --git a/components/doc/calendar/theming/tailwinddoc.js b/components/doc/calendar/theming/tailwinddoc.js index 6054d24860..dbe344dbfb 100644 --- a/components/doc/calendar/theming/tailwinddoc.js +++ b/components/doc/calendar/theming/tailwinddoc.js @@ -7,10 +7,13 @@ export function TailwindDoc(props) { basic: ` const TRANSITIONS = { overlay: { - enterFromClass: 'opacity-0 scale-75', - enterActiveClass: 'transition-transform transition-opacity duration-150 ease-in', - leaveActiveClass: 'transition-opacity duration-150 ease-linear', - leaveToClass: 'opacity-0' + timeout: 150, + classNames: { + enter: 'opacity-0 scale-75', + enterActive: 'opacity-100 !scale-100 transition-transform transition-opacity duration-150 ease-in', + exit: 'opacity-100', + exitActive: '!opacity-0 transition-opacity duration-150 ease-linear' + } } }; @@ -22,10 +25,10 @@ const Tailwind = { }) }), input: { - root: ({ props }) => ({ + root: ({ parent }) => ({ className: classNames('font-sans text-base text-gray-600 dark:text-white/80 bg-white dark:bg-gray-900 p-3 border border-gray-300 dark:border-blue-900/40 transition-colors duration-200 appearance-none', 'hover:border-blue-500', { - 'rounded-lg': !props.showIcon, - 'border-r-0 rounded-l-lg': props.showIcon + 'rounded-lg': !parent.props.showIcon, + 'border-r-0 rounded-l-lg': parent.props.showIcon }) }) }, @@ -44,13 +47,11 @@ const Tailwind = { className: classNames('flex items-center justify-between', 'p-2 text-gray-700 dark:text-white/80 bg-white dark:bg-gray-900 font-semibold m-0 border-b border-gray-300 dark:border-blue-900/40 rounded-t-lg') }, previousButton: { - root: ({ props }) => ({ - className: classNames( - 'flex items-center justify-center cursor-pointer overflow-hidden relative', - 'w-8 h-8 text-gray-600 dark:text-white/70 border-0 bg-transparent rounded-full transition-colors duration-200 ease-in-out', - 'hover:text-gray-700 dark:hover:text-white/80 hover:border-transparent hover:bg-gray-200 dark:hover:bg-gray-800/80 ' - ) - }) + className: classNames( + 'flex items-center justify-center cursor-pointer overflow-hidden relative', + 'w-8 h-8 text-gray-600 dark:text-white/70 border-0 bg-transparent rounded-full transition-colors duration-200 ease-in-out', + 'hover:text-gray-700 dark:hover:text-white/80 hover:border-transparent hover:bg-gray-200 dark:hover:bg-gray-800/80 ' + ) }, title: 'leading-8 mx-auto', monthTitle: { @@ -60,13 +61,11 @@ const Tailwind = { className: classNames('text-gray-700 dark:text-white/80 transition duration-200 font-semibold p-2', 'hover:text-blue-500') }, nextButton: { - root: ({ props }) => ({ - className: classNames( - 'flex items-center justify-center cursor-pointer overflow-hidden relative', - 'w-8 h-8 text-gray-600 dark:text-white/70 border-0 bg-transparent rounded-full transition-colors duration-200 ease-in-out', - 'hover:text-gray-700 dark:hover:text-white/80 hover:border-transparent hover:bg-gray-200 dark:hover:bg-gray-800/80 ' - ) - }) + className: classNames( + 'flex items-center justify-center cursor-pointer overflow-hidden relative', + 'w-8 h-8 text-gray-600 dark:text-white/70 border-0 bg-transparent rounded-full transition-colors duration-200 ease-in-out', + 'hover:text-gray-700 dark:hover:text-white/80 hover:border-transparent hover:bg-gray-200 dark:hover:bg-gray-800/80 ' + ) }, table: { className: classNames('border-collapse w-full', 'my-2') @@ -139,41 +138,8 @@ const Tailwind = { className: classNames('flex-1', 'border-l border-gray-300 pr-0.5 pl-0.5 pt-0 pb-0', 'first:pl-0 first:border-l-0') }, transition: TRANSITIONS.overlay - }, - listbox: { - root: { - className: classNames('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-56') - }, - wrapper: 'overflow-auto', - list: 'py-3 list-none m-0', - item: ({ context }) => ({ - className: classNames('cursor-pointer font-normal overflow-hidden relative whitespace-nowrap', 'm-0 p-3 border-0 transition-shadow duration-200 rounded-none', { - 'text-gray-700 hover:text-gray-700 hover:bg-gray-200 dark:text-white/80 dark:hover:bg-gray-800': !context.focused && !context.selected, - 'bg-gray-300 text-gray-700 dark:text-white/80 dark:bg-gray-800/90 hover:text-gray-700 hover:bg-gray-200 dark:text-white/80 dark:hover:bg-gray-800': context.focused && !context.selected, - 'bg-blue-100 text-blue-700 dark:bg-blue-400 dark:text-white/80': context.focused && context.selected, - 'bg-blue-50 text-blue-700 dark:bg-blue-300 dark:text-white/80': !context.focused && context.selected - }) - }), - 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: { - root: { - className: classNames( - 'pr-7 -mr-7', - 'w-full', - 'font-sans text-base text-gray-700 bg-white py-3 px-3 border border-gray-300 transition duration-200 rounded-lg appearance-none', - 'dark:bg-gray-900 dark:border-blue-900/40 dark:hover:border-blue-300 dark:text-white/80', - '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' } +} ` }; diff --git a/components/doc/cascadeselect/theming/tailwinddoc.js b/components/doc/cascadeselect/theming/tailwinddoc.js index f3ddf9d0f8..994c1191b0 100644 --- a/components/doc/cascadeselect/theming/tailwinddoc.js +++ b/components/doc/cascadeselect/theming/tailwinddoc.js @@ -24,7 +24,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', @@ -32,17 +32,16 @@ const Tailwind = { sublist: { className: classNames('block absolute left-full top-0', 'min-w-full z-10', 'py-3 bg-white dark:bg-gray-900 border-0 shadow-md') }, - item: { - className: classNames( - 'cursor-pointer font-normal whitespace-nowrap', - 'm-0 border-0 bg-transparent transition-shadow rounded-none', - 'text-gray-700 dark:text-white/80 hover:text-gray-700 dark:hover:text-white/80 hover:bg-gray-200 dark:hover:bg-gray-800/80' - ) - }, + item: ({ state }) => ({ + className: classNames('cursor-pointer font-normal whitespace-nowrap', 'm-0 border-0 bg-transparent transition-shadow rounded-none', { + 'text-gray-700 hover:text-gray-700 hover:bg-gray-200 dark:text-white/80 dark:hover:text-white/80 dark:hover:bg-gray-800/80': !state.selected, + 'bg-blue-50 text-blue-700 dark:bg-blue-300 dark:text-white/80': state.selected + }) + }), content: { className: classNames('flex items-center overflow-hidden relative', 'py-3 px-5') }, - groupicon: 'ml-auto', + optionGroupIcon: 'ml-auto', transition: TRANSITIONS.overlay } } diff --git a/components/doc/common/apidoc/index.json b/components/doc/common/apidoc/index.json index 8c4028e016..c80ef64283 100644 --- a/components/doc/common/apidoc/index.json +++ b/components/doc/common/apidoc/index.json @@ -952,7 +952,8 @@ "returnType": "void", "description": "This method is used to change the theme dynamically." } - ] + ], + "extendedBy": "CascadeSelectContext" }, "PrimeReactPTOptions": { "description": "This option allows to direct implementation of all relevant attributes (e.g., style, classnames) within the respective HTML tag globally for all components.", @@ -3531,7 +3532,7 @@ "values": "\"outlined\" | \"filled\"" }, "AppendToType": { - "values": "\"self\" | HTMLElement | undefined | null" + "values": "\"self\" | HTMLElement | undefined | null | Function" } } } @@ -3617,7 +3618,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and \"self\". The \"self\" value is used to render a component where it is located." }, @@ -5853,7 +5854,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and \"self\". The \"self\" value is used to render a component where it is located." }, @@ -6984,7 +6985,7 @@ "name": "previousButton", "optional": true, "readonly": false, - "type": "ButtonPassThroughOptions", + "type": "CalendarPassThroughType>", "description": "Uses to pass attributes to the Button component." }, { @@ -7033,7 +7034,7 @@ "name": "nextButton", "optional": true, "readonly": false, - "type": "ButtonPassThroughOptions", + "type": "CalendarPassThroughType>", "description": "Uses to pass attributes to the Button component." }, { @@ -7502,7 +7503,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and \"self\". The \"self\" value is used to render a component where it is located." }, { @@ -8963,7 +8964,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and \"self\". The \"self\" value is used to render a component where it is located." }, @@ -9314,6 +9315,12 @@ "optional": false, "readonly": false, "type": "CascadeSelectState" + }, + { + "name": "context", + "optional": false, + "readonly": false, + "type": "CascadeSelectContext" } ], "callbacks": [] @@ -9324,28 +9331,271 @@ "props": [ { "name": "focused", - "optional": false, + "optional": true, "readonly": false, "type": "boolean", "description": "Current focused state as a boolean." }, { "name": "overlayVisible", - "optional": false, + "optional": true, "readonly": false, "type": "boolean", "description": "Current overlay visible state as a boolean." }, { "name": "attributeSelector", - "optional": false, + "optional": true, "readonly": false, "type": "string", "description": "Current overlay attributeSelector state as a string." + }, + { + "name": "selected", + "optional": true, + "readonly": false, + "type": "boolean", + "description": "For items, this is the state of the item." + }, + { + "name": "grouped", + "optional": true, + "readonly": false, + "type": "boolean", + "description": "For items, this is whether it is a group item or not." } ], "callbacks": [] }, + "CascadeSelectContext": { + "description": "Defines current inline context in CascadeSelect component.", + "relatedProp": "", + "props": [ + { + "name": "appendTo", + "optional": true, + "readonly": false, + "type": "AppendToType", + "description": "This option allows components with overlays like dropdowns or popups to be mounted into either the component or any DOM element, such as document body and self." + }, + { + "name": "autoZIndex", + "optional": true, + "readonly": false, + "type": "boolean", + "description": "ZIndexes are managed automatically to make sure layering of overlay components work seamlessly when combining multiple components. When autoZIndex is false, each group increments its zIndex within itself." + }, + { + "name": "cssTransition", + "optional": true, + "readonly": false, + "type": "boolean", + "description": "PrimeReact components utilize \"react-transition-group\" internally to implement animations. Setting \"cssTransition\" to \"false\" disables all animations." + }, + { + "name": "filterMatchModeOptions", + "optional": true, + "readonly": false, + "type": "FilterMatchModeOptions", + "description": "Default filter modes to display on DataTable filter menus." + }, + { + "name": "hideOverlaysOnDocumentScrolling", + "optional": true, + "readonly": false, + "type": "boolean", + "description": "Define behavior if the browser window is scrolled while displaying an overlay panel like a Dropdown or Calendar. Depending on your organization's accessibility needs some prefer panels to be closed on scrolling and some prefer the overlay follow the scroll." + }, + { + "name": "inputStyle", + "optional": true, + "readonly": false, + "type": "InputStyleType", + "description": "Input fields have two styles: default (outlined with borders) and filled (background-colored). Applying 'p-input-filled' to an input's ancestor enables the filled style." + }, + { + "name": "locale", + "optional": true, + "readonly": false, + "type": "string", + "description": "The locale configuration sets up the language and region specific preferences." + }, + { + "name": "nonce", + "optional": true, + "readonly": false, + "type": "string", + "description": "The nonce value to use on dynamically generated style elements." + }, + { + "name": "nullSortOrder", + "optional": true, + "readonly": false, + "type": "number", + "description": "Determines how null values are sorted." + }, + { + "name": "ripple", + "optional": true, + "readonly": false, + "type": "boolean", + "description": "Ripple is an optional animation for the supported components such as buttons." + }, + { + "name": "zIndex", + "optional": true, + "readonly": false, + "type": "ZIndexOptions", + "description": "ZIndexes are managed automatically to make sure layering of overlay components work seamlessly when combining multiple components. When autoZIndex is false, each group increments its zIndex within itself." + }, + { + "name": "pt", + "optional": true, + "readonly": false, + "type": "PrimeReactPTOptions", + "description": "This option allows to direct implementation of all relevant attributes (e.g., style, classnames) within the respective HTML tag." + }, + { + "name": "ptOptions", + "optional": true, + "readonly": false, + "type": "PassThroughOptions", + "description": "Used to configure passthrough(pt) options of the component." + }, + { + "name": "unstyled", + "optional": true, + "readonly": false, + "type": "boolean", + "description": "When enabled, it removes all of components styles in the core." + }, + { + "name": "setAppendTo", + "optional": true, + "readonly": false, + "type": "Dispatch>", + "description": "Sets the \"appendTo\" state of the context." + }, + { + "name": "setAutoZIndex", + "optional": true, + "readonly": false, + "type": "Dispatch>", + "description": "Sets the \"autoZIndex\" state of the context." + }, + { + "name": "setCssTransition", + "optional": true, + "readonly": false, + "type": "Dispatch>", + "description": "Sets the \"cssTransition\" state of the context." + }, + { + "name": "setFilterMatchModeOptions", + "optional": true, + "readonly": false, + "type": "Dispatch>", + "description": "Sets the \"filterMatchModeOptions\" state of the context." + }, + { + "name": "setHideOverlaysOnDocumentScrolling", + "optional": true, + "readonly": false, + "type": "Dispatch>", + "description": "Sets the \"hideOverlaysOnDocumentScrolling\" state of the context." + }, + { + "name": "setInputStyle", + "optional": true, + "readonly": false, + "type": "Dispatch>", + "description": "Sets the \"inputStyle\" state of the context." + }, + { + "name": "setLocale", + "optional": true, + "readonly": false, + "type": "Dispatch>", + "description": "Sets the \"locale\" state of the context." + }, + { + "name": "setNonce", + "optional": true, + "readonly": false, + "type": "Dispatch>", + "description": "Sets the \"nonce\" state of the context." + }, + { + "name": "setNullSortOrder", + "optional": true, + "readonly": false, + "type": "Dispatch>", + "description": "Sets the \"nullSortOrder\" state of the context." + }, + { + "name": "setRipple", + "optional": true, + "readonly": false, + "type": "Dispatch>", + "description": "Sets the \"ripple\" state of the context." + }, + { + "name": "setZIndex", + "optional": true, + "readonly": false, + "type": "Dispatch>", + "description": "Sets the \"zIndex\" state of the context." + }, + { + "name": "setPt", + "optional": true, + "readonly": false, + "type": "Dispatch>", + "description": "Sets the \"pt\" state of the context." + }, + { + "name": "label", + "optional": true, + "readonly": false, + "type": "string", + "description": "Label of the currently selected item" + } + ], + "callbacks": [ + { + "name": "changeTheme", + "parameters": [ + { + "name": "theme", + "optional": true, + "type": "string", + "description": "The name of the theme to be applied." + }, + { + "name": "newTheme", + "optional": true, + "type": "string", + "description": "The name of the new theme to be applied." + }, + { + "name": "linkElementId", + "optional": true, + "type": "string", + "description": "The id of the link element to be updated." + }, + { + "name": "callback", + "optional": true, + "type": "Function", + "description": "Callback to invoke when the theme change is completed." + } + ], + "returnType": "void", + "description": "This method is used to change the theme dynamically." + } + ], + "extendedTypes": "APIOptions" + }, "CascadeSelectPassThroughOptions": { "description": "Custom passthrough(pt) options.", "relatedProp": "pt", @@ -10297,8 +10547,8 @@ { "name": "event", "optional": false, - "type": "MouseEvent", - "description": "Browser event." + "type": "ChipRemoveEvent", + "description": "Custom remove event" } ], "returnType": "void", @@ -10308,6 +10558,31 @@ } } }, + "events": { + "description": "Defines the custom events used by the component's callbacks.", + "values": { + "ChipRemoveEvent": { + "description": "Custom remove event", + "relatedProp": "", + "props": [ + { + "name": "originalEvent", + "optional": false, + "readonly": false, + "type": "SyntheticEvent", + "description": "Browser event" + }, + { + "name": "value", + "optional": false, + "readonly": false, + "type": "string", + "description": "Removed item value" + } + ] + } + } + }, "interfaces": { "description": "Defines the custom interfaces used by the module.", "values": { @@ -10957,7 +11232,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and \"self\". The \"self\" value is used to render a component where it is located." }, @@ -13833,7 +14108,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and \"self\". The \"self\" value is used to render a component where it is located." }, @@ -14693,7 +14968,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located." }, @@ -15178,7 +15453,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located." }, @@ -15982,7 +16257,7 @@ "name": "columnResizeMode", "optional": true, "readonly": false, - "type": "\"fit\" | \"expand\"", + "type": "\"expand\" | \"fit\"", "default": "fit", "description": "Used to define the resize mode of the columns, valid values are \"fit\" and \"expand\"." }, @@ -16063,7 +16338,7 @@ "optional": true, "readonly": false, "type": "ReactNode | Function", - "default": "", + "default": "No results found", "description": "Text to display when there is no data." }, { @@ -16318,7 +16593,7 @@ "name": "paginatorDropdownAppendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located." }, @@ -18911,7 +19186,7 @@ "name": "columnResizeMode", "optional": true, "readonly": false, - "type": "\"fit\" | \"expand\"", + "type": "\"expand\" | \"fit\"", "description": "Used to define the resize mode of the columns, valid values are \"fit\" and \"expand\"." }, { @@ -19198,7 +19473,7 @@ "name": "paginatorDropdownAppendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located." }, { @@ -20447,7 +20722,7 @@ "name": "paginatorDropdownAppendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located." }, @@ -21107,7 +21382,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located." }, @@ -22244,7 +22519,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and \"self\". The \"self\" value is used to render a component where it is located." }, @@ -29650,6 +29925,14 @@ "default": "false", "description": "When present, it specifies that the element must be filled out before submitting the form." }, + { + "name": "roundingMode", + "optional": true, + "readonly": false, + "type": "RoundingMode", + "default": "", + "description": "How decimals should be rounded.\nThe default value is `\"halfExpand\"` , [further information](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#roundingmode)." + }, { "name": "showButtons", "optional": true, @@ -29977,6 +30260,9 @@ "types": { "description": "Defines the custom types used by the module.", "values": { + "RoundingMode": { + "values": "\"ceil\" | \"floor\" | \"expand\" | \"trunc\" | \"halfCeil\" | \"halfFloor\" | \"halfExpand\" | \"halfTrunc\" | \"halfEven\"" + }, "InputNumberPassThroughType": { "values": "PassThroughType" } @@ -32673,7 +32959,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located." }, @@ -33963,7 +34249,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located." }, @@ -36605,7 +36891,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located." }, @@ -36970,7 +37256,7 @@ "name": "dropdownAppendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located." }, @@ -37723,7 +38009,7 @@ "name": "appendTo", "optional": false, "readonly": false, - "type": "undefined | null | HTMLElement | \"self\"", + "type": "undefined | null | HTMLElement | \"self\" | Function", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and \"self\". The \"self\" value is used to render a component where it is located." }, { @@ -38935,7 +39221,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located." }, @@ -42220,7 +42506,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and self. The self value is used to render a component where it is located." }, @@ -42763,7 +43049,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located." }, @@ -43863,7 +44149,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located." }, @@ -46449,7 +46735,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located." }, @@ -47015,7 +47301,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "self", "description": "DOM element instance where the component should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located." }, @@ -48008,7 +48294,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located." }, @@ -48422,7 +48708,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located." }, @@ -50173,7 +50459,7 @@ "name": "appendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located." }, @@ -51242,7 +51528,7 @@ "name": "columnResizeMode", "optional": true, "readonly": false, - "type": "\"fit\" | \"expand\"", + "type": "\"expand\" | \"fit\"", "default": "fit", "description": "Defines whether the overall table width should change on column resize, valid values are \"fit\" and \"expand\"." }, @@ -51274,8 +51560,8 @@ "name": "emptyMessage", "optional": true, "readonly": false, - "type": "string", - "default": "No records found", + "type": "ReactNode | Function", + "default": "No results found", "description": "Text to display when there is no data." }, { @@ -51474,7 +51760,7 @@ "name": "paginatorDropdownAppendTo", "optional": true, "readonly": false, - "type": "null | HTMLElement | \"self\"", + "type": "null | HTMLElement | \"self\" | Function", "default": "document.body", "description": "DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located." }, diff --git a/components/doc/datatable/theming/tailwinddoc.js b/components/doc/datatable/theming/tailwinddoc.js index ddc02af684..1dd344d10c 100644 --- a/components/doc/datatable/theming/tailwinddoc.js +++ b/components/doc/datatable/theming/tailwinddoc.js @@ -90,7 +90,7 @@ const Tailwind = { context?.size === 'small' ? 'p-2' : context?.size === 'large' ? 'p-5' : 'p-4', // Size 'dark:text-white/80 dark:border-blue-900/40', // Dark Mode { - 'sticky bg-inherit': props?.frozen || props?.frozen === '', // Frozen Columns + 'sticky bg-inherit': props && (props.frozen || props.frozen === ''), // Frozen Columns 'border-x border-y': context.showGridlines } ) diff --git a/components/doc/fileupload/theming/tailwinddoc.js b/components/doc/fileupload/theming/tailwinddoc.js index 0ce828eb2e..0e5e4bfa42 100644 --- a/components/doc/fileupload/theming/tailwinddoc.js +++ b/components/doc/fileupload/theming/tailwinddoc.js @@ -11,15 +11,18 @@ const Tailwind = { buttonbar: { className: classNames('flex flex-wrap', 'bg-gray-50 dark:bg-gray-800 p-5 border border-solid border-gray-300 dark:border-blue-900/40 text-gray-700 dark:text-white/80 rounded-tr-lg rounded-tl-lg gap-2 border-b-0') }, + basicButton: { + className: classNames('text-white bg-blue-500 border border-blue-500 p-3 px-5 rounded-md text-base', 'overflow-hidden relative') + }, chooseButton: { className: classNames('text-white bg-blue-500 border border-blue-500 p-3 px-5 rounded-md text-base', 'overflow-hidden relative') }, chooseIcon: 'mr-2 inline-block', chooseButtonLabel: 'flex-1 font-bold', - uploadbutton: { + uploadButton: { icon: 'mr-2' }, - cancelbutton: { + cancelButton: { icon: 'mr-2' }, content: { @@ -31,7 +34,7 @@ const Tailwind = { thumbnail: 'shrink-0', fileName: 'mb-2', fileSize: 'mr-2', - uploadicon: 'mr-2' + uploadIcon: 'mr-2' } } ` diff --git a/components/doc/multiselect/theming/tailwinddoc.js b/components/doc/multiselect/theming/tailwinddoc.js index d9fb1d78aa..a9e2832c3f 100644 --- a/components/doc/multiselect/theming/tailwinddoc.js +++ b/components/doc/multiselect/theming/tailwinddoc.js @@ -102,13 +102,15 @@ const Tailwind = { }, filterContainer: 'relative', filterInput: { - className: classNames( - 'pr-7 -mr-7', - 'w-full', - 'font-sans text-base text-gray-700 bg-white py-3 px-3 border border-gray-300 transition duration-200 rounded-lg appearance-none', - 'dark:bg-gray-900 dark:border-blue-900/40 dark:hover:border-blue-300 dark:text-white/80', - '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)]' - ) + root: { + className: classNames( + 'pr-7 -mr-7', + 'w-full', + 'font-sans text-base text-gray-700 bg-white py-3 px-3 border border-gray-300 transition duration-200 rounded-lg appearance-none', + 'dark:bg-gray-900 dark:border-blue-900/40 dark:hover:border-blue-300 dark:text-white/80', + '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', diff --git a/components/doc/overlaypanel/theming/tailwinddoc.js b/components/doc/overlaypanel/theming/tailwinddoc.js index c40f5e72ad..ae802885b0 100644 --- a/components/doc/overlaypanel/theming/tailwinddoc.js +++ b/components/doc/overlaypanel/theming/tailwinddoc.js @@ -7,10 +7,12 @@ export function TailwindDoc(props) { basic: ` const TRANSITIONS = { overlay: { - enterFromClass: 'opacity-0 scale-75', - enterActiveClass: 'transition-transform transition-opacity duration-150 ease-in', - leaveActiveClass: 'transition-opacity duration-150 ease-linear', - leaveToClass: 'opacity-0' + classNames: { + enter: 'opacity-0 scale-75', + enterActive: 'opacity-100 !scale-100 transition-transform transition-opacity duration-150 ease-in', + exit: 'opacity-100', + exitActive: '!opacity-0 transition-opacity duration-150 ease-linear' + } } }; @@ -20,11 +22,12 @@ const Tailwind = { className: classNames( 'bg-white text-gray-700 border-0 rounded-md shadow-lg', 'z-40 transform origin-center', - 'absolute left-0 top-0', + 'absolute left-0 top-0 mt-3', 'before:absolute before:w-0 before:-top-3 before:h-0 before:border-transparent before:border-solid before:ml-6 before:border-x-[0.75rem] before:border-b-[0.75rem] before:border-t-0 before:border-b-white dark:before:border-b-gray-900', 'dark:border dark:border-blue-900/40 dark:bg-gray-900 dark:text-white/80' ) }, + closeButton: 'flex items-center justify-center overflow-hidden absolute top-0 right-0 w-6 h-6', content: 'p-5 items-center flex', transition: TRANSITIONS.overlay } diff --git a/components/doc/picklist/basicdoc.js b/components/doc/picklist/basicdoc.js index 79c7a4189c..5443f0184e 100644 --- a/components/doc/picklist/basicdoc.js +++ b/components/doc/picklist/basicdoc.js @@ -35,7 +35,7 @@ export function BasicDoc(props) { const code = { basic: ` - `, javascript: ` @@ -74,7 +74,7 @@ export default function BasicDemo() { return (
-
); @@ -129,7 +129,7 @@ export default function BasicDemo() { return (
-
); @@ -162,7 +162,7 @@ export default function BasicDemo() {

- +
diff --git a/components/doc/picklist/filterdoc.js b/components/doc/picklist/filterdoc.js index 6b4df140cc..0465abf2d3 100644 --- a/components/doc/picklist/filterdoc.js +++ b/components/doc/picklist/filterdoc.js @@ -35,7 +35,7 @@ export function FilterDoc(props) { const code = { basic: ` - `, @@ -75,7 +75,7 @@ export default function FilterDemo() { return (
-
@@ -131,7 +131,7 @@ export default function FilterDemo() { return (
-
@@ -174,7 +174,7 @@ export default function FilterDemo() { targetHeader="Selected" sourceStyle={{ height: '24rem' }} targetStyle={{ height: '24rem' }} - breakpoint="1400px" + breakpoint="1280px" filter filterBy="name" sourceFilterPlaceholder="Search by name" diff --git a/components/doc/picklist/pt/ptdoc.js b/components/doc/picklist/pt/ptdoc.js index 2c7fc0829d..fcdccfa04f 100644 --- a/components/doc/picklist/pt/ptdoc.js +++ b/components/doc/picklist/pt/ptdoc.js @@ -40,7 +40,7 @@ export function PTDoc(props) { target={target} onChange={onChange} itemTemplate={itemTemplate} - breakpoint="1400px" + breakpoint="1280px" sourceHeader="Available" targetHeader="Selected" sourceStyle={{ height: '24rem' }} @@ -98,7 +98,7 @@ export default function PTDemo() { target={target} onChange={onChange} itemTemplate={itemTemplate} - breakpoint="1400px" + breakpoint="1280px" sourceHeader="Available" targetHeader="Selected" sourceStyle={{ height: '24rem' }} @@ -172,7 +172,7 @@ export default function PTDemo() { target={target} onChange={onChange} itemTemplate={itemTemplate} - breakpoint="1400px" + breakpoint="1280px" sourceHeader="Available" targetHeader="Selected" sourceStyle={{ height: '24rem' }} @@ -219,7 +219,7 @@ export default function PTDemo() { target={target} onChange={onChange} itemTemplate={itemTemplate} - breakpoint="1400px" + breakpoint="1280px" sourceHeader="Available" targetHeader="Selected" sourceStyle={{ height: '24rem' }} diff --git a/components/doc/picklist/theming/tailwinddoc.js b/components/doc/picklist/theming/tailwinddoc.js index 2cee034290..9bfe5ab68a 100644 --- a/components/doc/picklist/theming/tailwinddoc.js +++ b/components/doc/picklist/theming/tailwinddoc.js @@ -7,8 +7,8 @@ export function TailwindDoc(props) { basic: ` const Tailwind = { picklist: { - root: 'flex', - controls: 'flex flex-col justify-center p-5', + root: 'flex flex-col xl:flex-row', + controls: 'flex flex-row xl:flex-col justify-center p-5', moveUpButton: { root: { className: classNames( @@ -16,7 +16,7 @@ const Tailwind = { 'text-white bg-blue-500 border border-blue-500 rounded-md', 'transition duration-200 ease-in-out', 'justify-center px-0 py-3', // icon only - 'mb-2', // orderlist button + 'mr-2 xl:mb-2', // orderlist button 'dark:bg-sky-300 dark:border-sky-300 dark:text-gray-900' //Dark Mode ) }, @@ -29,7 +29,7 @@ const Tailwind = { 'text-white bg-blue-500 border border-blue-500 rounded-md', 'transition duration-200 ease-in-out', 'justify-center px-0 py-3', // icon only - 'mb-2', // orderlist button + 'mr-2 xl:mb-2', // orderlist button 'dark:bg-sky-300 dark:border-sky-300 dark:text-gray-900' //Dark Mode ) }, @@ -42,7 +42,7 @@ const Tailwind = { 'text-white bg-blue-500 border border-blue-500 rounded-md', 'transition duration-200 ease-in-out', 'justify-center px-0 py-3', // icon only - 'mb-2', // orderlist button + 'mr-2 xl:mb-2', // orderlist button 'dark:bg-sky-300 dark:border-sky-300 dark:text-gray-900' //Dark Mode ) }, @@ -55,7 +55,7 @@ const Tailwind = { 'text-white bg-blue-500 border border-blue-500 rounded-md', 'transition duration-200 ease-in-out', 'justify-center px-0 py-3', // icon only - 'mb-2', // orderlist button + 'mr-2 xl:mb-2', // orderlist button 'dark:bg-sky-300 dark:border-sky-300 dark:text-gray-900' //Dark Mode ) }, @@ -81,7 +81,7 @@ const Tailwind = { 'text-gray-600 dark:bg-blue-900/40': !context.selected }) }), - buttons: 'flex flex-col justify-center p-5', + buttons: 'flex flex-row xl:flex-col justify-center p-5', movetotargetbutton: { root: { className: classNames( @@ -89,7 +89,7 @@ const Tailwind = { 'text-white bg-blue-500 border border-blue-500 rounded-md', 'transition duration-200 ease-in-out', 'justify-center px-0 py-3', // icon only - 'mb-2', // orderlist button + 'mr-2 xl:mb-2', // orderlist button 'dark:bg-sky-300 dark:border-sky-300 dark:text-gray-900' //Dark Mode ) }, @@ -102,7 +102,7 @@ const Tailwind = { 'text-white bg-blue-500 border border-blue-500 rounded-md', 'transition duration-200 ease-in-out', 'justify-center px-0 py-3', // icon only - 'mb-2', // orderlist button + 'mr-2 xl:mb-2', // orderlist button 'dark:bg-sky-300 dark:border-sky-300 dark:text-gray-900' //Dark Mode ) }, @@ -115,7 +115,7 @@ const Tailwind = { 'text-white bg-blue-500 border border-blue-500 rounded-md', 'transition duration-200 ease-in-out', 'justify-center px-0 py-3', // icon only - 'mb-2', // orderlist button + 'mr-2 xl:mb-2', // orderlist button 'dark:bg-sky-300 dark:border-sky-300 dark:text-gray-900' //Dark Mode ) }, @@ -128,7 +128,7 @@ const Tailwind = { 'text-white bg-blue-500 border border-blue-500 rounded-md', 'transition duration-200 ease-in-out', 'justify-center px-0 py-3', // icon only - 'mb-2', // orderlist button + 'mr-2 xl:mb-2', // orderlist button 'dark:bg-sky-300 dark:border-sky-300 dark:text-gray-900' //Dark Mode ) }, @@ -200,7 +200,7 @@ export default function UnstyledDemo() { return (
-
); diff --git a/components/doc/theming/customthemedoc.js b/components/doc/theming/customthemedoc.js index 4968bbee3e..7a8334a115 100644 --- a/components/doc/theming/customthemedoc.js +++ b/components/doc/theming/customthemedoc.js @@ -23,18 +23,8 @@ import './assets/theme.css'; SASS API documentation.

- There are 3 alternatives to create your own theme. First option is using the Visual Editor, second one is compiling a theme with command line sass and final alternative is embedding scss files within your project to let your build - environment do the compilation. In all cases, the generated theme file should be imported to your project. We've created a video tutorial that demonstrates all three options. -

-
- -
- -

Visual Editor

-

- Visual Editor is an easy way to quickly customize an existing theme without dealing with the details of the SASS API. The editor allows changing common settings like primary color for - built-in themes. Once you have completed the design, click the download button to access the generated theme.css file and import it to your project as an asset. In near future, an advanced UI Designer will be available with - the ability to edit all variables and components where you'll also be able to save your themes when accessed with an account. + There are 2 alternatives to create your own theme. First option is compiling a theme with command line sass and final alternative is embedding scss files within your project to let your build environment do the compilation. In all + cases, the generated theme file should be imported to your project. We've created a video tutorial that demonstrates all three options.

Theme SCSS

diff --git a/components/doc/tooltip/theming/tailwinddoc.js b/components/doc/tooltip/theming/tailwinddoc.js index 8d51a689c1..b3b1b540b5 100644 --- a/components/doc/tooltip/theming/tailwinddoc.js +++ b/components/doc/tooltip/theming/tailwinddoc.js @@ -17,10 +17,10 @@ const Tailwind = { }, arrow: ({ context }) => ({ className: classNames('absolute w-0 h-0 border-transparent border-solid', { - '-m-t-1 border-y-[0.25rem] border-r-[0.25rem] border-l-0 border-r-gray-600': context.right, - '-m-t-1 border-y-[0.25rem] border-l-[0.25rem] border-r-0 border-l-gray-600': context.left, - '-m-l-1 border-x-[0.25rem] border-t-[0.25rem] border-b-0 border-t-gray-600': context.top, - '-m-l-1 border-x-[0.25rem] border-b-[0.25rem] border-t-0 border-b-gray-600': context.bottom + '-mt-1 border-y-[0.25rem] border-r-[0.25rem] border-l-0 border-r-gray-600': context.right, + '-mt-1 border-y-[0.25rem] border-l-[0.25rem] border-r-0 border-l-gray-600': context.left, + '-ml-1 border-x-[0.25rem] border-t-[0.25rem] border-b-0 border-t-gray-600': context.top, + '-ml-1 border-x-[0.25rem] border-b-[0.25rem] border-t-0 border-b-gray-600': context.bottom }) }), text: { diff --git a/components/landing/themesection.js b/components/landing/themesection.js index ffb17f9e43..615d8ce74b 100644 --- a/components/landing/themesection.js +++ b/components/landing/themesection.js @@ -188,9 +188,6 @@ const ThemeSection = () => { - - more... -
{ } }; - return mergeProps(ptm(`accordiontab.${key}`, { accordiontab: tabMetaData }), ptm(`accordiontab.${key}`, tabMetaData), ptmo(tab.props, key, tabMetaData)); + return mergeProps(ptm(`accordion.${key}`, { tab: tabMetaData }), ptm(`accordiontab.${key}`, { accordiontab: tabMetaData }), ptm(`accordiontab.${key}`, tabMetaData), ptmo(getTabProp(tab, 'pt'), key, tabMetaData)); }; const getTabProp = (tab, name) => AccordionTabBase.getCProp(tab, name); @@ -84,7 +84,7 @@ export const Accordion = React.forwardRef((inProps, ref) => { }; const isSelected = (index) => { - return props.multiple ? activeIndex && activeIndex.some((i) => i === index) : activeIndex === index; + return props.multiple && Array.isArray(activeIndex) ? activeIndex && activeIndex.some((i) => i === index) : activeIndex === index; }; React.useImperativeHandle(ref, () => ({ @@ -109,7 +109,7 @@ export const Accordion = React.forwardRef((inProps, ref) => { const tabIndex = getTabProp(tab, 'disabled') ? -1 : getTabProp(tab, 'tabIndex'); const headerTitleProps = mergeProps( { - className: cx('tab.headertitle') + className: cx('accordiontab.headertitle') }, getTabPT(tab, 'headertitle', index) ); @@ -117,7 +117,7 @@ export const Accordion = React.forwardRef((inProps, ref) => { const header = getTabProp(tab, 'headerTemplate') ? ObjectUtils.getJSXElement(getTabProp(tab, 'headerTemplate'), tabCProps) : {ObjectUtils.getJSXElement(getTabProp(tab, 'header'), tabCProps)}; const headerIconProps = mergeProps( { - className: cx('tab.headericon') + className: cx('accordiontab.headericon') }, getTabPT(tab, 'headericon', index) ); @@ -126,7 +126,7 @@ export const Accordion = React.forwardRef((inProps, ref) => { const label = selected ? ariaLabel('collapseLabel') : ariaLabel('expandLabel'); const headerProps = mergeProps( { - className: classNames(getTabProp(tab, 'headerClassName'), getTabProp(tab, 'className'), cx('tab.header', { selected, getTabProp, tab })), + className: classNames(getTabProp(tab, 'headerClassName'), getTabProp(tab, 'className'), cx('accordiontab.header', { selected, getTabProp, tab })), style, 'data-p-highlight': selected, 'data-p-disabled': getTabProp(tab, 'disabled') @@ -138,7 +138,7 @@ export const Accordion = React.forwardRef((inProps, ref) => { { id: headerId, href: '#' + ariaControls, - className: cx('tab.headeraction'), + className: cx('accordiontab.headeraction'), role: 'tab', tabIndex, onClick: (e) => onTabHeaderClick(e, tab, index), @@ -168,7 +168,7 @@ export const Accordion = React.forwardRef((inProps, ref) => { { id: contentId, ref: contentRef, - className: classNames(getTabProp(tab, 'contentClassName'), getTabProp(tab, 'className'), cx('tab.toggleablecontent')), + className: classNames(getTabProp(tab, 'contentClassName'), getTabProp(tab, 'className'), cx('accordiontab.toggleablecontent')), style, role: 'region', 'aria-labelledby': ariaLabelledby @@ -178,14 +178,14 @@ export const Accordion = React.forwardRef((inProps, ref) => { const contentProps = mergeProps( { - className: cx('tab.content') + className: cx('accordiontab.content') }, getTabPT(tab, 'content', index) ); const transitionProps = mergeProps( { - classNames: cx('tab.transition'), + classNames: cx('accordiontab.transition'), timeout: { enter: 1000, exit: 450 }, in: selected, unmountOnExit: true, @@ -213,7 +213,7 @@ export const Accordion = React.forwardRef((inProps, ref) => { const rootProps = mergeProps( { key, - className: cx('tab.root', { selected }) + className: cx('accordiontab.root', { selected }) }, AccordionTabBase.getCOtherProps(tab), getTabPT(tab, 'root', index) diff --git a/components/lib/accordion/AccordionBase.js b/components/lib/accordion/AccordionBase.js index 868a6345e7..51a379bbe5 100644 --- a/components/lib/accordion/AccordionBase.js +++ b/components/lib/accordion/AccordionBase.js @@ -3,7 +3,7 @@ import { ObjectUtils, classNames } from '../utils/Utils'; const classes = { root: 'p-accordion p-component', - tab: { + accordiontab: { root: ({ selected }) => classNames('p-accordion-tab', { 'p-accordion-tab-active': selected diff --git a/components/lib/api/api.d.ts b/components/lib/api/api.d.ts index f16ed67bb5..5ab824d95a 100644 --- a/components/lib/api/api.d.ts +++ b/components/lib/api/api.d.ts @@ -129,7 +129,7 @@ export interface ZIndexOptions { export type InputStyleType = 'outlined' | 'filled'; -export type AppendToType = 'self' | HTMLElement | undefined | null; +export type AppendToType = 'self' | HTMLElement | undefined | null | (() => HTMLElement); /** * Filter match modes for DataTable filter menus. diff --git a/components/lib/autocomplete/autocomplete.d.ts b/components/lib/autocomplete/autocomplete.d.ts index 1e6502869d..da565f89f4 100755 --- a/components/lib/autocomplete/autocomplete.d.ts +++ b/components/lib/autocomplete/autocomplete.d.ts @@ -236,7 +236,7 @@ export interface AutoCompleteProps extends Omit HTMLElement); /** * When present, it specifies that the component should automatically get focus on load. * @defaultValue false diff --git a/components/lib/blockui/BlockUI.js b/components/lib/blockui/BlockUI.js index 0d4e5179b7..44e3786765 100644 --- a/components/lib/blockui/BlockUI.js +++ b/components/lib/blockui/BlockUI.js @@ -14,6 +14,7 @@ export const BlockUI = React.forwardRef((inProps, ref) => { const [visibleState, setVisibleState] = React.useState(props.blocked); const elementRef = React.useRef(null); const maskRef = React.useRef(null); + const activeElementRef = React.useRef(null); const { ptm, cx, isUnstyled } = BlockUIBase.setMetaData({ props @@ -23,13 +24,18 @@ export const BlockUI = React.forwardRef((inProps, ref) => { const block = () => { setVisibleState(true); + activeElementRef.current = document.activeElement; }; const unblock = () => { const callback = () => { setVisibleState(false); - props.fullScreen && DomHandler.unblockBodyScroll(); + if (props.fullScreen) { + DomHandler.unblockBodyScroll(); + activeElementRef.current && activeElementRef.current.focus(); + } + props.onUnblocked && props.onUnblocked(); }; @@ -47,7 +53,7 @@ export const BlockUI = React.forwardRef((inProps, ref) => { const onPortalMounted = () => { if (props.fullScreen) { DomHandler.blockBodyScroll(); - document.activeElement.blur(); + activeElementRef.current && activeElementRef.current.blur(); } if (props.autoZIndex) { @@ -68,9 +74,7 @@ export const BlockUI = React.forwardRef((inProps, ref) => { }, [props.blocked]); useUnmountEffect(() => { - if (props.fullScreen) { - DomHandler.unblockBodyScroll(); - } + props.fullScreen && DomHandler.unblockBodyScroll(); ZIndexUtils.clear(maskRef.current); }); diff --git a/components/lib/calendar/Calendar.js b/components/lib/calendar/Calendar.js index 730e52f8d8..14427004c6 100644 --- a/components/lib/calendar/Calendar.js +++ b/components/lib/calendar/Calendar.js @@ -945,7 +945,7 @@ export const Calendar = React.memo( const updateViewDate = (event, value) => { validateDate(value); - if (props.onViewDateChange) { + if (props.onViewDateChange && event) { props.onViewDateChange({ originalEvent: event, value @@ -1535,7 +1535,9 @@ export const Calendar = React.memo( }; const appendDisabled = () => { - return props.appendTo === 'self' || props.inline; + const appendTo = props.appendTo || (context && context.appendTo) || PrimeReact.appendTo; + + return appendTo === 'self' || props.inline; }; const alignOverlay = () => { @@ -1840,11 +1842,7 @@ export const Calendar = React.memo( } } - if (props.disabledDates || props.enabledDates) { - validDate = !isDateDisabled(day, month, year); - } - - if (props.disabledDays && currentView === 'date') { + if (props.disabledDates || props.enabledDates || props.disabledDays) { validDay = !isDayDisabled(day, month, year); } @@ -1994,24 +1992,24 @@ export const Calendar = React.memo( return today.getDate() === day && today.getMonth() === month && today.getFullYear() === year; }; - const isDateDisabled = (day, month, year) => { + const isDayDisabled = (day, month, year) => { if (props.disabledDates) { - return props.disabledDates.some((d) => d.getFullYear() === year && d.getMonth() === month && d.getDate() === day); - } - - if (props.enabledDates) { - return !props.enabledDates.some((d) => d.getFullYear() === year && d.getMonth() === month && d.getDate() === day); + if (props.disabledDates.some((d) => d.getFullYear() === year && d.getMonth() === month && d.getDate() === day)) { + return true; + } + } else if (props.enabledDates) { + if (!props.enabledDates.some((d) => d.getFullYear() === year && d.getMonth() === month && d.getDate() === day)) { + return true; + } } - return false; - }; - - const isDayDisabled = (day, month, year) => { - if (props.disabledDays) { + if (props.disabledDays && currentView === 'date') { let weekday = new Date(year, month, day); let weekdayNumber = weekday.getDay(); - return props.disabledDays.indexOf(weekdayNumber) !== -1; + if (props.disabledDays.indexOf(weekdayNumber) !== -1) { + return true; + } } return false; @@ -2571,11 +2569,21 @@ export const Calendar = React.memo( setCurrentView(props.view); }, [props.view]); + useUpdateEffect(() => { + if (overlayVisibleState || props.visible) { + alignOverlay(); + } + }, [currentView, overlayVisibleState, props.visible]); + useUpdateEffect(() => { if (!props.onViewDateChange && !viewStateChanged.current) { setValue(props.value); } - }, [props.onViewDateChange, props.value]); + + if (props.viewDate) { + updateViewDate(null, getViewDate(props.viewDate)); + } + }, [props.onViewDateChange, props.value, props.viewDate]); useUpdateEffect(() => { const newDate = props.value; @@ -2612,7 +2620,7 @@ export const Calendar = React.memo( useUpdateEffect(() => { updateInputfield(props.value); - }, [props.dateFormat, props.hourFormat, props.timeOnly, props.showSeconds, props.showMillisec, props.showTime]); + }, [props.dateFormat, props.hourFormat, props.timeOnly, props.showSeconds, props.showMillisec, props.showTime, props.locale]); useUpdateEffect(() => { if (overlayRef.current) { @@ -2683,7 +2691,12 @@ export const Calendar = React.memo( ptm('previousButton') ); - return + ); }; const createForwardNavigator = (isVisible) => { @@ -2705,7 +2718,12 @@ export const Calendar = React.memo( ptm('nextButton') ); - return + ); }; const renderMonthsNavigator = (index) => { @@ -3635,18 +3653,18 @@ export const Calendar = React.memo( {monthPickerValues().map((m, i) => { const monthProps = mergeProps( { - className: cx('month', { isMonthSelected, isSelectable, i, currentYear }), + className: cx('month', { isMonthSelected, isMonthYearDisabled, i, currentYear }), onClick: (event) => onMonthSelect(event, i), onKeyDown: (event) => onMonthCellKeydown(event, i), - 'data-p-disabled': !m.selectable, + 'data-p-disabled': isMonthYearDisabled(i, currentYear), 'data-p-highlight': isMonthSelected(i) }, ptm('month', { context: { month: m, monthIndex: i, - selected: isMonthSelected(i), - disabled: !m.selectable + disabled: isMonthYearDisabled(i, currentYear), + selected: isMonthSelected(i) } }) ); @@ -3664,6 +3682,25 @@ export const Calendar = React.memo( return null; }; + const isMonthYearDisabled = (month, year) => { + const daysCountInAllMonth = month === -1 ? new Array(12).fill(0).map((_, i) => getDaysCountInMonth(i, year)) : [getDaysCountInMonth(month, year)]; + + for (let i = 0; i < daysCountInAllMonth.length; i++) { + const monthDays = daysCountInAllMonth[i]; + const _month = month === -1 ? i : month; + + for (let day = 1; day <= monthDays; day++) { + let isDateSelectable = isSelectable(day, _month, year); + + if (isDateSelectable) { + return false; + } + } + } + + return true; + }; + const createYearPicker = () => { if (currentView === 'year') { const yearPickerProps = mergeProps( @@ -3678,17 +3715,17 @@ export const Calendar = React.memo( {yearPickerValues().map((y, i) => { const yearProps = mergeProps( { - className: cx('year', { isYearSelected, isSelectable, y }), + className: cx('year', { isYearSelected, isSelectable, y, isMonthYearDisabled }), onClick: (event) => onYearSelect(event, y), 'data-p-highlight': isYearSelected(y), - 'data-p-disabled': !isSelectable(0, -1, y) + 'data-p-disabled': isMonthYearDisabled(-1, y) }, ptm('year', { context: { year: y, yearIndex: i, - selected: isYearSelected(i), - disabled: !y.selectable + selected: isYearSelected(y), + disabled: isMonthYearDisabled(-1, y) } }) ); diff --git a/components/lib/calendar/Calendar.spec.js b/components/lib/calendar/Calendar.spec.js new file mode 100644 index 0000000000..e38ff1eef1 --- /dev/null +++ b/components/lib/calendar/Calendar.spec.js @@ -0,0 +1,93 @@ +import '@testing-library/jest-dom'; +import { render } from '@testing-library/react'; +import { PrimeReactProvider } from '../api/Api'; +import { Calendar } from './Calendar'; + +describe('Calendar', () => { + function getAllDatesOfYear(year) { + let startDate = new Date(year, 0, 1); + let endDate = new Date(year, 11, 31); + + let dates = []; + let currentDate = startDate; + + while (currentDate <= endDate) { + dates.push(new Date(currentDate)); + currentDate.setDate(currentDate.getDate() + 1); + } + + return dates; + } + + test('When the days of the year are disabled, then the years and month should be disabled', async () => { + const { container } = render( + + + + ); + + const years = container.querySelectorAll('.p-yearpicker-year'); + + for (const year of years) { + if (year.innerHTML === '2023') { + expect(year).toHaveAttribute('data-p-disabled', 'true'); + expect(year).toHaveClass('p-disabled'); + } else { + expect(year).toHaveAttribute('data-p-disabled', 'false'); + expect(year).not.toHaveClass('p-disabled'); + } + } + + const { container: monthContainer } = render( + + + + ); + + const months = monthContainer.querySelectorAll('.p-monthpicker-month'); + + for (const month of months) { + expect(month).toHaveAttribute('data-p-disabled', 'true'); + expect(month).toHaveClass('p-disabled'); + } + }); + + test('If any day of the month is not disabled, then both the year and month can be selected', async () => { + const disabledDates = getAllDatesOfYear(2023); + + // January and December are not disabled. + disabledDates.shift(); + disabledDates.pop(); + + const { container: yearContainer } = render( + + + + ); + const years = yearContainer.querySelectorAll('.p-yearpicker-year'); + + for (const year of years) { + expect(year).toHaveAttribute('data-p-disabled', 'false'); + expect(year).not.toHaveClass('p-disabled'); + } + + // month + const { container: monthContainer } = render( + + + + ); + + const months = monthContainer.querySelectorAll('.p-monthpicker-month'); + + Array.from(months).forEach((month, index) => { + if (index === 0 || index === 11) { + expect(month).toHaveAttribute('data-p-disabled', 'false'); + expect(month).not.toHaveClass('p-disabled'); + } else { + expect(month).toHaveAttribute('data-p-disabled', 'true'); + expect(month).toHaveClass('p-disabled'); + } + }); + }); +}); diff --git a/components/lib/calendar/CalendarBase.js b/components/lib/calendar/CalendarBase.js index 4dbcc117c5..f1ec418550 100644 --- a/components/lib/calendar/CalendarBase.js +++ b/components/lib/calendar/CalendarBase.js @@ -190,9 +190,9 @@ const classes = { clearButton: 'p-button-text', footer: 'p-datepicker-footer', yearPicker: 'p-yearpicker', - year: ({ isYearSelected, isSelectable, y }) => classNames('p-yearpicker-year', { 'p-highlight': isYearSelected(y), 'p-disabled': !isSelectable(0, -1, y) }), + year: ({ isYearSelected, y, isMonthYearDisabled }) => classNames('p-yearpicker-year', { 'p-highlight': isYearSelected(y), 'p-disabled': isMonthYearDisabled(-1, y) }), monthPicker: 'p-monthpicker', - month: ({ isMonthSelected, isSelectable, i, currentYear }) => classNames('p-monthpicker-month', { 'p-highlight': isMonthSelected(i), 'p-disabled': !isSelectable(0, i, currentYear) }), + month: ({ isMonthSelected, isMonthYearDisabled, i, currentYear }) => classNames('p-monthpicker-month', { 'p-highlight': isMonthSelected(i), 'p-disabled': isMonthYearDisabled(i, currentYear) }), hourPicker: 'p-hour-picker', secondPicker: 'p-second-picker', minutePicker: 'p-minute-picker', diff --git a/components/lib/calendar/calendar.d.ts b/components/lib/calendar/calendar.d.ts index ddd7d04bac..4a6c7de88c 100644 --- a/components/lib/calendar/calendar.d.ts +++ b/components/lib/calendar/calendar.d.ts @@ -67,9 +67,8 @@ export interface CalendarPassThroughOptions { header?: CalendarPassThroughType>; /** * Uses to pass attributes to the Button component. - * @see {@link ButtonPassThroughOptions} */ - previousButton?: ButtonPassThroughOptions; + previousButton?: CalendarPassThroughType>; /** * Uses to pass attributes to the previous icon's DOM element. */ @@ -96,9 +95,8 @@ export interface CalendarPassThroughOptions { decadeTitleText?: CalendarPassThroughType>; /** * Uses to pass attributes to the Button component. - * @see {@link ButtonPassThroughOptions} */ - nextButton?: ButtonPassThroughOptions; + nextButton?: CalendarPassThroughType>; /** * Uses to pass attributes to the next icon's DOM element. */ @@ -525,7 +523,7 @@ interface CalendarBaseProps { * DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and "self". The "self" value is used to render a component where it is located. * @defaultValue document.body */ - appendTo?: 'self' | HTMLElement | undefined | null; + appendTo?: 'self' | HTMLElement | undefined | null | (() => HTMLElement); /** * When present, it specifies that the component should automatically get focus on load. * @defaultValue false diff --git a/components/lib/cascadeselect/CascadeSelect.js b/components/lib/cascadeselect/CascadeSelect.js index 95304cb96a..8696bb62dc 100644 --- a/components/lib/cascadeselect/CascadeSelect.js +++ b/components/lib/cascadeselect/CascadeSelect.js @@ -24,6 +24,9 @@ export const CascadeSelect = React.memo( focused: focusedState, overlayVisible: overlayVisibleState, attributeSelector: attributeSelectorState + }, + context: { + ...context } }); @@ -339,7 +342,7 @@ export const CascadeSelect = React.memo( ref: labelRef, className: cx('label', { label }) }, - ptm('label') + ptm('label', { context: { label, ...context } }) ); return {label}; diff --git a/components/lib/cascadeselect/CascadeSelectBase.js b/components/lib/cascadeselect/CascadeSelectBase.js index a188991825..917bd5ece7 100644 --- a/components/lib/cascadeselect/CascadeSelectBase.js +++ b/components/lib/cascadeselect/CascadeSelectBase.js @@ -25,10 +25,10 @@ const classes = { 'p-ripple-disabled': (context && context.ripple === false) || PrimeReact.ripple === false }), sublist: 'p-cascadeselect-panel p-cascadeselect-items p-cascadeselect-sublist', - item: ({ option, isOptionGroup, activeOptionState }) => + item: ({ option, isGroup, isSelected }) => classNames('p-cascadeselect-item', { - 'p-cascadeselect-item-group': isOptionGroup(option), - 'p-cascadeselect-item-active p-highlight': activeOptionState === option + 'p-cascadeselect-item-group': isGroup, + 'p-cascadeselect-item-active p-highlight': isSelected }), dropdownIcon: 'p-cascadeselect-trigger-icon', dropdownButton: 'p-cascadeselect-trigger', diff --git a/components/lib/cascadeselect/CascadeSelectSub.js b/components/lib/cascadeselect/CascadeSelectSub.js index 38135b2889..8c24e1c579 100644 --- a/components/lib/cascadeselect/CascadeSelectSub.js +++ b/components/lib/cascadeselect/CascadeSelectSub.js @@ -11,9 +11,10 @@ export const CascadeSelectSub = React.memo((props) => { const context = React.useContext(PrimeReactContext); const { ptm, cx } = props; - const getPTOptions = (key) => { + const getPTOptions = (key, options) => { return ptm(key, { - hostName: props.hostName + hostName: props.hostName, + state: { ...options } }); }; @@ -239,15 +240,17 @@ export const CascadeSelectSub = React.memo((props) => { getPTOptions('content') ); + const isSelected = activeOptionState === option; + const isGroup = isOptionGroup(option); const itemProps = mergeProps( { - className: classNames(option.className, cx('item', { option, isOptionGroup, activeOptionState })), + className: classNames(option.className, cx('item', { option, isGroup, isSelected })), style: option.style, role: 'none', - 'data-p-item-group': isOptionGroup(option), - 'data-p-highlight': activeOptionState === option + 'data-p-item-group': isGroup, + 'data-p-highlight': isSelected }, - getPTOptions('item') + getPTOptions('item', { selected: isSelected, group: isGroup }) ); return ( diff --git a/components/lib/cascadeselect/cascadeselect.d.ts b/components/lib/cascadeselect/cascadeselect.d.ts index 53c9c0eaec..78750f21fb 100644 --- a/components/lib/cascadeselect/cascadeselect.d.ts +++ b/components/lib/cascadeselect/cascadeselect.d.ts @@ -9,6 +9,7 @@ */ import * as React from 'react'; import { CSSTransitionProps as ReactCSSTransitionProps } from 'react-transition-group/CSSTransition'; +import { APIOptions } from '../api/api'; import { ComponentHooks } from '../componentbase/componentbase'; import { CSSTransitionProps } from '../csstransition'; import { PassThroughOptions } from '../passthrough'; @@ -24,6 +25,7 @@ export declare type CascadeSelectPassThroughTransitionType = ReactCSSTransitionP export interface CascadeSelectPassThroughMethodOptions { props: CascadeSelectProps; state: CascadeSelectState; + context: CascadeSelectContext; } /** @@ -34,16 +36,34 @@ export interface CascadeSelectState { * Current focused state as a boolean. * @defaultValue false */ - focused: boolean; + focused?: boolean; /** * Current overlay visible state as a boolean. * @defaultValue false */ - overlayVisible: boolean; + overlayVisible?: boolean; /** * Current overlay attributeSelector state as a string. */ - attributeSelector: string; + attributeSelector?: string; + /** + * For items, this is the state of the item. + */ + selected?: boolean; + /** + * For items, this is whether it is a group item or not. + */ + grouped?: boolean; +} + +/** + * Defines current inline context in CascadeSelect component. + */ +export interface CascadeSelectContext extends APIOptions { + /** + * Label of the currently selected item + */ + label?: string; } /** @@ -237,7 +257,7 @@ export interface CascadeSelectProps extends Omit HTMLElement); /** * The properties of CSSTransition can be customized, except for "nodeRef" and "in" properties. * @type {CSSTransitionProps} diff --git a/components/lib/chip/Chip.js b/components/lib/chip/Chip.js index d4d663852e..c96a8ccbeb 100644 --- a/components/lib/chip/Chip.js +++ b/components/lib/chip/Chip.js @@ -28,7 +28,10 @@ export const Chip = React.memo( setVisibleState(false); if (props.onRemove) { - props.onRemove(event); + props.onRemove({ + originalEvent: event, + value: props.label || props.image || props.icon + }); } }; diff --git a/components/lib/chip/chip.d.ts b/components/lib/chip/chip.d.ts index f541f42b31..10814f13bc 100644 --- a/components/lib/chip/chip.d.ts +++ b/components/lib/chip/chip.d.ts @@ -65,6 +65,21 @@ export interface ChipState { visible: boolean; } +/** + * Custom remove event + * @event + */ +interface ChipRemoveEvent { + /** + * Browser event + */ + originalEvent: React.SyntheticEvent; + /** + * Removed item value + */ + value: string; +} + /** * Defines valid properties in Chip component. In addition to these, all properties of HTMLDivElement can be used in this component. * @group Properties @@ -106,9 +121,9 @@ export interface ChipProps extends Omit): void; + onRemove?(event: ChipRemoveEvent): void; /** * Used to get the child elements of the component. * @readonly diff --git a/components/lib/colorpicker/colorpicker.d.ts b/components/lib/colorpicker/colorpicker.d.ts index ae1aa799dc..666639db18 100644 --- a/components/lib/colorpicker/colorpicker.d.ts +++ b/components/lib/colorpicker/colorpicker.d.ts @@ -149,7 +149,7 @@ export interface ColorPickerProps extends Omit HTMLElement); /** * When present, it specifies that the component should automatically get focus on load. * @defaultValue false diff --git a/components/lib/confirmdialog/confirmdialog.d.ts b/components/lib/confirmdialog/confirmdialog.d.ts index 39d8344e3d..dc816566f8 100644 --- a/components/lib/confirmdialog/confirmdialog.d.ts +++ b/components/lib/confirmdialog/confirmdialog.d.ts @@ -214,7 +214,7 @@ export interface ConfirmDialogProps extends Omit HTMLElement); /** * Style class of the element. */ diff --git a/components/lib/confirmpopup/ConfirmPopup.js b/components/lib/confirmpopup/ConfirmPopup.js index 769f9e82ea..397e552d69 100644 --- a/components/lib/confirmpopup/ConfirmPopup.js +++ b/components/lib/confirmpopup/ConfirmPopup.js @@ -1,5 +1,4 @@ import * as React from 'react'; -import { useOnEscapeKey } from '../../lib/hooks/Hooks'; import PrimeReact, { PrimeReactContext, localeOption } from '../api/Api'; import { Button } from '../button/Button'; import { useHandleStyle } from '../componentbase/ComponentBase'; diff --git a/components/lib/confirmpopup/confirmpopup.d.ts b/components/lib/confirmpopup/confirmpopup.d.ts index 01fbf21c04..1947442832 100644 --- a/components/lib/confirmpopup/confirmpopup.d.ts +++ b/components/lib/confirmpopup/confirmpopup.d.ts @@ -211,7 +211,7 @@ export interface ConfirmPopupProps { * DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located. * @defaultValue document.body */ - appendTo?: 'self' | HTMLElement | undefined | null; + appendTo?: 'self' | HTMLElement | undefined | null | (() => HTMLElement); /** * Enables to hide the popup when outside is clicked. * @defaultValue true diff --git a/components/lib/contextmenu/contextmenu.d.ts b/components/lib/contextmenu/contextmenu.d.ts index 42c213aef5..c0529b511c 100644 --- a/components/lib/contextmenu/contextmenu.d.ts +++ b/components/lib/contextmenu/contextmenu.d.ts @@ -147,7 +147,7 @@ export interface ContextMenuProps extends Omit HTMLElement); /** * The properties of CSSTransition can be customized, except for "nodeRef" and "in" properties. */ diff --git a/components/lib/datatable/BodyCell.js b/components/lib/datatable/BodyCell.js index 35797c9bf5..1545020311 100644 --- a/components/lib/datatable/BodyCell.js +++ b/components/lib/datatable/BodyCell.js @@ -28,11 +28,10 @@ export const BodyCell = React.memo((props) => { const { ptm, ptmo, cx } = props.ptCallbacks; const getColumnProp = (name) => ColumnBase.getCProp(props.column, name); - const getColumnProps = (column) => ColumnBase.getCProps(column); + const getColumnProps = () => ColumnBase.getCProps(props.column); const getColumnPTOptions = (key) => { - const cProps = getColumnProps(props.column); - + const cProps = getColumnProps(); const columnMetaData = { props: cProps, parent: props.metaData, @@ -70,10 +69,6 @@ export const BodyCell = React.memo((props) => { options: true }); - if (props.editMode === 'row' && props.editing !== editingState) { - setEditingState(props.editing); - } - const isEditable = () => { return getColumnProp('editor'); }; @@ -233,7 +228,7 @@ export const BodyCell = React.memo((props) => { clearTimeout(tabindexTimeout.current); tabindexTimeout.current = setTimeout(() => { if (editingState) { - const focusableEl = props.editMode === 'cell' ? DomHandler.getFirstFocusableElement(elementRef.current, ':not(.p-cell-editor-key-helper)') : DomHandler.findSingle(elementRef.current, '[data-p-row-editor-save="true"]'); + const focusableEl = props.editMode === 'cell' ? DomHandler.getFirstFocusableElement(elementRef.current, ':not([data-pc-section="editorkeyhelperlabel"])') : DomHandler.findSingle(elementRef.current, '[data-p-row-editor-save="true"]'); focusableEl && focusableEl.focus(); } @@ -518,6 +513,12 @@ export const BodyCell = React.memo((props) => { } }); + React.useEffect(() => { + if (props.editMode === 'row' && props.editing !== editingState) { + setEditingState(props.editing); + } + }, [props.editMode, props.editing, editingState]); + useUpdateEffect(() => { if (props.editMode === 'cell' || props.editMode === 'row') { setEditingRowDataState(getEditingRowData()); diff --git a/components/lib/datatable/DataTable.js b/components/lib/datatable/DataTable.js index 7ac23a83e6..88b2c2c73c 100644 --- a/components/lib/datatable/DataTable.js +++ b/components/lib/datatable/DataTable.js @@ -372,7 +372,7 @@ export const DataTable = React.forwardRef((inProps, ref) => { const saveColumnWidths = (state) => { let widths = []; - let headers = DomHandler.find(elementRef.current, '.p-datatable-thead > tr > th'); + let headers = DomHandler.find(elementRef.current, '[data-pc-section="thead"] > tr > th'); headers.forEach((header) => widths.push(DomHandler.getOuterWidth(header))); state.columnWidths = widths.join(','); @@ -385,15 +385,15 @@ export const DataTable = React.forwardRef((inProps, ref) => { const addColumnWidthStyles = (widths) => { createStyleElement(); let innerHTML = ''; - let selector = `.p-datatable[${attributeSelector.current}] > .p-datatable-wrapper ${isVirtualScrollerDisabled() ? '' : '> .p-virtualscroller'} > .p-datatable-table`; + let selector = `[data-pc-name="datatable"][${attributeSelector.current}] > [data-pc-section="wrapper"] ${isVirtualScrollerDisabled() ? '' : '> [data-pc-name="virtualscroller"]'} > [data-pc-section="table"]`; widths.forEach((width, index) => { let style = `width: ${width}px !important; max-width: ${width}px !important`; innerHTML += ` - ${selector} > .p-datatable-thead > tr > th:nth-child(${index + 1}), - ${selector} > .p-datatable-tbody > tr > td:nth-child(${index + 1}), - ${selector} > .p-datatable-tfoot > tr > td:nth-child(${index + 1}) { + ${selector} > [data-pc-section="thead"] > tr > th:nth-child(${index + 1}), + ${selector} > [data-pc-section="tbody"] > tr > td:nth-child(${index + 1}), + ${selector} > [data-pc-section="tfoot"] > tr > td:nth-child(${index + 1}) { ${style} } `; @@ -558,7 +558,7 @@ export const DataTable = React.forwardRef((inProps, ref) => { updateTableWidth(frozenBodyRef.current); if (wrapperRef.current) { - updateTableWidth(DomHandler.findSingle(wrapperRef.current, '.p-virtualscroller-content')); + updateTableWidth(DomHandler.findSingle(wrapperRef.current, '[data-pc-name="virtualscroller"] > table > tbody')); } } } @@ -588,7 +588,7 @@ export const DataTable = React.forwardRef((inProps, ref) => { const resizeTableCells = (newColumnWidth, nextColumnWidth) => { let widths = []; let colIndex = DomHandler.index(resizeColumnElement.current); - let headers = DomHandler.find(tableRef.current, '.p-datatable-thead > tr > th'); + let headers = DomHandler.find(tableRef.current, '[data-pc-section="thead"] > tr > th'); headers.forEach((header) => widths.push(DomHandler.getOuterWidth(header))); @@ -596,16 +596,16 @@ export const DataTable = React.forwardRef((inProps, ref) => { createStyleElement(); let innerHTML = ''; - let selector = `.p-datatable[${attributeSelector.current}] > .p-datatable-wrapper ${isVirtualScrollerDisabled() ? '' : '> .p-virtualscroller'} > .p-datatable-table`; + let selector = `[data-pc-name="datatable"][${attributeSelector.current}] > [data-pc-section="wrapper"] ${isVirtualScrollerDisabled() ? '' : '> [data-pc-name="virtualscroller"]'} > [data-pc-section="table"]`; widths.forEach((width, index) => { let colWidth = index === colIndex ? newColumnWidth : nextColumnWidth && index === colIndex + 1 ? nextColumnWidth : width; let style = `width: ${colWidth}px !important; max-width: ${colWidth}px !important`; innerHTML += ` - ${selector} > .p-datatable-thead > tr > th:nth-child(${index + 1}), - ${selector} > .p-datatable-tbody > tr > td:nth-child(${index + 1}), - ${selector} > .p-datatable-tfoot > tr > td:nth-child(${index + 1}) { + ${selector} > [data-pc-section="thead"] > tr > th:nth-child(${index + 1}), + ${selector} > [data-pc-section="tbody"] > tr > td:nth-child(${index + 1}), + ${selector} > [data-pc-section="tfoot"] > tr > td:nth-child(${index + 1}) { ${style} } `; @@ -745,9 +745,10 @@ export const DataTable = React.forwardRef((inProps, ref) => { let dragColIndex = columns.findIndex((child) => isSameColumn(child, draggedColumn.current)); let dropColIndex = columns.findIndex((child) => isSameColumn(child, column)); let widths = []; - let headers = DomHandler.find(tableRef.current, '.p-datatable-thead > tr > th'); + let headers = DomHandler.find(tableRef.current, '[data-pc-section="thead"] > tr > th'); headers.forEach((header) => widths.push(DomHandler.getOuterWidth(header))); + const movedItem = widths.find((items, index) => index === dragColIndex); const remainingItems = widths.filter((items, index) => index !== dragColIndex); const reorderedWidths = [...remainingItems.slice(0, dropColIndex), movedItem, ...remainingItems.slice(dropColIndex)]; @@ -799,34 +800,35 @@ export const DataTable = React.forwardRef((inProps, ref) => { if (!responsiveStyleElement.current) { responsiveStyleElement.current = DomHandler.createInlineStyle((context && context.nonce) || PrimeReact.nonce); - let tableSelector = `.p-datatable-wrapper ${isVirtualScrollerDisabled() ? '' : '> .p-virtualscroller'} > .p-datatable-table`; - let selector = `.p-datatable[${attributeSelector.current}] > ${tableSelector}`; - let gridLinesSelector = `.p-datatable[${attributeSelector.current}].p-datatable-gridlines > ${tableSelector}`; + let tableSelector = `[data-pc-section="wrapper"] ${isVirtualScrollerDisabled() ? '' : '> [data-pc-name="virtualscroller"]'} > [data-pc-section="table"]`; + let selector = `[data-pc-name="datatable"][${attributeSelector.current}] > ${tableSelector}`; + let gridLinesSelector = `[data-pc-name="datatable"][${attributeSelector.current}][data-showgridlines="true"] > ${tableSelector}`; + let innerHTML = ` @media screen and (max-width: ${props.breakpoint}) { - ${selector} > .p-datatable-thead > tr > th, - ${selector} > .p-datatable-tfoot > tr > td { + ${selector} > [data-pc-section="thead"] > tr > th, + ${selector} > [data-pc-section="tfoot"] > tr > td { display: none; } - ${selector} > .p-datatable-tbody > tr > td { + ${selector} > [data-pc-section="tbody"] > tr > td { display: flex; width: 100%; align-items: center; justify-content: space-between; } - ${selector} > .p-datatable-tbody > tr > td:not(:last-child) { + ${selector} > [data-pc-section="tbody"] > tr > td:not(:last-child) { border: 0 none; } - ${gridLinesSelector} > .p-datatable-tbody > tr > td:last-child { + ${gridLinesSelector} > [data-pc-section="tbody"] > tr > td:last-child { border-top: 0; border-right: 0; border-left: 0; } - ${selector} > .p-datatable-tbody > tr > td > .p-column-title { + ${selector} > [data-pc-section="tbody"] > tr > td > [data-pc-section="columntitle"] { display: block; } } @@ -1253,7 +1255,7 @@ export const DataTable = React.forwardRef((inProps, ref) => { const resetScroll = () => { if (wrapperRef.current) { - const scrollableContainer = !isVirtualScrollerDisabled() ? DomHandler.findSingle(wrapperRef.current, '.p-virtualscroller') : wrapperRef.current; + const scrollableContainer = !isVirtualScrollerDisabled() ? DomHandler.findSingle(wrapperRef.current, '[data-pc-name="virtualscroller"]') : wrapperRef.current; scrollableContainer.scrollTo(0, 0); } @@ -1343,7 +1345,7 @@ export const DataTable = React.forwardRef((inProps, ref) => { }; const closeEditingRows = () => { - DomHandler.find(document.body, '.p-row-editor-cancel').forEach((button, index) => { + DomHandler.find(document.body, '[data-pc-section="roweditorcancelbuttonprops"]').forEach((button, index) => { setTimeout(() => { button.click(); }, index * 5); @@ -1967,7 +1969,8 @@ export const DataTable = React.forwardRef((inProps, ref) => { id: props.id, className: classNames(props.className, ptCallbacks.cx('root', { selectable })), style: props.style, - 'data-scrollselectors': '.p-datatable-wrapper' + 'data-scrollselectors': '.p-datatable-wrapper', + 'data-showgridlines': props.showGridlines }, DataTableBase.getOtherProps(props), ptCallbacks.ptm('root') diff --git a/components/lib/datatable/TableBody.js b/components/lib/datatable/TableBody.js index 0f5daa2d3f..20e9d796ac 100644 --- a/components/lib/datatable/TableBody.js +++ b/components/lib/datatable/TableBody.js @@ -443,11 +443,11 @@ export const TableBody = React.memo( if (!allowCellSelection() && props.selectionAutoFocus) { if (isCheckboxSelectionModeInColumn) { - const checkbox = DomHandler.findSingle(target, 'td.p-selection-column .p-checkbox-box'); + const checkbox = DomHandler.findSingle(target, 'td[data-p-selection-column="true"] [data-pc-section="checkbox"]'); checkbox && checkbox.focus(); } else if (isRadioSelectionModeInColumn) { - const radio = DomHandler.findSingle(target, 'td.p-selection-column input[type="radio"]'); + const radio = DomHandler.findSingle(target, 'td[data-p-selection-column="true"] input[type="radio"]'); radio && radio.focus(); } diff --git a/components/lib/datatable/datatable.d.ts b/components/lib/datatable/datatable.d.ts index 4c7191c8e5..944bfe99bd 100644 --- a/components/lib/datatable/datatable.d.ts +++ b/components/lib/datatable/datatable.d.ts @@ -1082,8 +1082,9 @@ interface DataTableBaseProps extends Omit React.ReactNode); + emptyMessage?: string | React.ReactNode | ((frozen: boolean) => React.ReactNode) | undefined; /** * Makes row groups toggleable, default is false. * @defaultValue false @@ -1221,7 +1222,7 @@ interface DataTableBaseProps extends Omit HTMLElement); /** * Content for the left side of the paginator. */ diff --git a/components/lib/dataview/dataview.d.ts b/components/lib/dataview/dataview.d.ts index e64fff6399..5bd3465f2a 100755 --- a/components/lib/dataview/dataview.d.ts +++ b/components/lib/dataview/dataview.d.ts @@ -285,7 +285,7 @@ export interface DataViewProps extends Omit HTMLElement); /** * Array of integer values to display inside rows per page dropdown. */ diff --git a/components/lib/dialog/Dialog.js b/components/lib/dialog/Dialog.js index cd0b11ed52..12933a6927 100644 --- a/components/lib/dialog/Dialog.js +++ b/components/lib/dialog/Dialog.js @@ -384,6 +384,10 @@ export const Dialog = React.forwardRef((inProps, ref) => { unbindDocumentKeyDownListener(); }; + const destroyStyle = () => { + styleElement.current = DomHandler.removeInlineStyle(styleElement.current); + }; + const createStyle = () => { styleElement.current = DomHandler.createInlineStyle((context && context.nonce) || PrimeReact.nonce); @@ -392,8 +396,8 @@ export const Dialog = React.forwardRef((inProps, ref) => { for (let breakpoint in props.breakpoints) { innerHTML += ` @media screen and (max-width: ${breakpoint}) { - .p-dialog[${attributeSelector.current}] { - width: ${props.breakpoints[breakpoint]}; + [data-pc-name="dialog"][${attributeSelector.current}] { + width: ${props.breakpoints[breakpoint]} !important; } } `; @@ -402,16 +406,22 @@ export const Dialog = React.forwardRef((inProps, ref) => { styleElement.current.innerHTML = innerHTML; }; + useUpdateEffect(() => { + if (props.breakpoints) { + createStyle(); + } + + return () => { + destroyStyle(); + }; + }, [props.breakpoints]); + useMountEffect(() => { updateGlobalDialogsRegistry(true); if (props.visible) { setMaskVisibleState(true); } - - if (props.breakpoints) { - createStyle(); - } }); useUpdateEffect(() => { diff --git a/components/lib/dialog/dialog.d.ts b/components/lib/dialog/dialog.d.ts index 333fa492cd..8fda2692a4 100644 --- a/components/lib/dialog/dialog.d.ts +++ b/components/lib/dialog/dialog.d.ts @@ -137,7 +137,7 @@ export interface DialogProps { * DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located. * @defaultValue document.body */ - appendTo?: 'self' | HTMLElement | undefined | null; + appendTo?: 'self' | HTMLElement | undefined | null | (() => HTMLElement); /** * Defines a string that labels the close icon. */ diff --git a/components/lib/dropdown/Dropdown.js b/components/lib/dropdown/Dropdown.js index ed8b03109b..d57b9c1fe8 100644 --- a/components/lib/dropdown/Dropdown.js +++ b/components/lib/dropdown/Dropdown.js @@ -741,7 +741,7 @@ export const Dropdown = React.memo( onBlur: onInputBlur, onKeyDown: onInputKeyDown, disabled: props.disabled, - tabIndex: props.tabIndex, + tabIndex: props.tabIndex || 0, ...ariaProps }, ptm('input') @@ -772,6 +772,7 @@ export const Dropdown = React.memo( onFocus: onEditableInputFocus, onBlur: onInputBlur, 'aria-haspopup': 'listbox', + tabIndex: props.tabIndex || 0, ...ariaProps }, ptm('input') @@ -783,7 +784,8 @@ export const Dropdown = React.memo( const inputProps = mergeProps( { ref: inputRef, - className: cx('input', { label }) + className: cx('input', { label }), + tabIndex: '-1' }, ptm('input') ); diff --git a/components/lib/dropdown/dropdown.d.ts b/components/lib/dropdown/dropdown.d.ts index 701ef07e77..dcc710b444 100644 --- a/components/lib/dropdown/dropdown.d.ts +++ b/components/lib/dropdown/dropdown.d.ts @@ -220,7 +220,7 @@ export interface DropdownProps extends Omit HTMLElement); /** * Used to define a string that labels the component. */ diff --git a/components/lib/inplace/Inplace.js b/components/lib/inplace/Inplace.js index 00891430c5..d0232cbbd4 100644 --- a/components/lib/inplace/Inplace.js +++ b/components/lib/inplace/Inplace.js @@ -2,6 +2,7 @@ import * as React from 'react'; import { localeOption, PrimeReactContext } from '../api/Api'; import { Button } from '../button/Button'; import { useHandleStyle } from '../componentbase/ComponentBase'; +import { useUpdateEffect } from '../hooks/Hooks'; import { TimesIcon } from '../icons/times'; import { classNames, IconUtils, useMergeProps, ObjectUtils } from '../utils/Utils'; import { InplaceBase } from './InplaceBase'; @@ -45,6 +46,10 @@ export const Inplace = React.forwardRef((inProps, ref) => { }; const close = (event) => { + if (props.disabled) { + return; + } + props.onClose && props.onClose(event); if (props.onToggle) { @@ -134,6 +139,10 @@ export const Inplace = React.forwardRef((inProps, ref) => { }); }; + useUpdateEffect(() => { + props.active ? open(null) : close(null); + }, [props.active]); + React.useImperativeHandle(ref, () => ({ props, getElement: () => elementRef.current diff --git a/components/lib/inputnumber/InputNumber.js b/components/lib/inputnumber/InputNumber.js index 7e853e8098..42d9f337c6 100644 --- a/components/lib/inputnumber/InputNumber.js +++ b/components/lib/inputnumber/InputNumber.js @@ -45,6 +45,8 @@ export const InputNumber = React.memo( const _prefix = React.useRef(null); const _index = React.useRef(null); + const isFocusedByClick = React.useRef(false); + const _locale = props.locale || (context && context.locale) || PrimeReact.locale; const stacked = props.showButtons && props.buttonLayout === 'stacked'; const horizontal = props.showButtons && props.buttonLayout === 'horizontal'; @@ -59,7 +61,8 @@ export const InputNumber = React.memo( currencyDisplay: props.currencyDisplay, useGrouping: props.useGrouping, minimumFractionDigits: props.minFractionDigits, - maximumFractionDigits: props.maxFractionDigits + maximumFractionDigits: props.maxFractionDigits, + roundingMode: props.roundingMode }; }; @@ -109,7 +112,8 @@ export const InputNumber = React.memo( currency: props.currency, currencyDisplay: props.currencyDisplay, minimumFractionDigits: 0, - maximumFractionDigits: 0 + maximumFractionDigits: 0, + roundingMode: props.roundingMode }); return new RegExp(`[${formatter.format(1).replace(/\s/g, '').replace(_numeral.current, '').replace(_group.current, '')}]`, 'g'); @@ -139,7 +143,8 @@ export const InputNumber = React.memo( currency: props.currency, currencyDisplay: props.currencyDisplay, minimumFractionDigits: 0, - maximumFractionDigits: 0 + maximumFractionDigits: 0, + roundingMode: props.roundingMode }); suffixChar.current = formatter.format(1).split('1')[1]; @@ -724,6 +729,10 @@ export const InputNumber = React.memo( return index || 0; }; + const onInputPointerDown = () => { + isFocusedByClick.current = true; + }; + const onInputClick = () => { initCursor(); }; @@ -957,17 +966,22 @@ export const InputNumber = React.memo( setFocusedState(true); props.onFocus && props.onFocus(event); - if ((props.suffix || props.currency || props.prefix) && inputRef.current) { - // GitHub #1866 Cursor must be placed before/after symbol or arrow keys don't work - const selectionEnd = initCursor(); + if ((props.suffix || props.currency || props.prefix) && inputRef.current && !isFocusedByClick.current) { + // GitHub #1866,#5537 + let inputValue = inputRef.current.value; + let prefixLength = (prefixChar.current || '').length; + let suffixLength = (suffixChar.current || '').length; + let end = inputValue.length === 0 ? 0 : inputValue.length - suffixLength; - inputRef.current.setSelectionRange(selectionEnd, selectionEnd); + inputRef.current.setSelectionRange(prefixLength, end); } }; const onInputBlur = (event) => { setFocusedState(false); + isFocusedByClick.current = false; + if (inputRef.current) { let currentValue = inputRef.current.value; @@ -1068,6 +1082,7 @@ export const InputNumber = React.memo( onKeyPress={onInputKeyUp} onInput={onInput} onClick={onInputClick} + onPointerDown={onInputPointerDown} onBlur={onInputBlur} onFocus={onInputFocus} onPaste={onPaste} diff --git a/components/lib/inputnumber/InputNumberBase.js b/components/lib/inputnumber/InputNumberBase.js index c4e17d0dbc..b2d50d3b28 100644 --- a/components/lib/inputnumber/InputNumberBase.js +++ b/components/lib/inputnumber/InputNumberBase.js @@ -171,6 +171,7 @@ export const InputNumberBase = ComponentBase.extend({ prefix: null, readOnly: false, required: false, + roundingMode: undefined, showButtons: false, size: null, step: 1, diff --git a/components/lib/inputnumber/inputnumber.d.ts b/components/lib/inputnumber/inputnumber.d.ts index 4497b2c80f..23a1ad3e07 100644 --- a/components/lib/inputnumber/inputnumber.d.ts +++ b/components/lib/inputnumber/inputnumber.d.ts @@ -16,6 +16,8 @@ import { TooltipOptions } from '../tooltip/tooltipoptions'; import { FormEvent } from '../ts-helpers'; import { IconType, PassThroughType } from '../utils/utils'; +export declare type RoundingMode = 'ceil' | 'floor' | 'expand' | 'trunc' | 'halfCeil' | 'halfFloor' | 'halfExpand' | 'halfTrunc' | 'halfEven'; + export declare type InputNumberPassThroughType = PassThroughType; /** @@ -190,6 +192,11 @@ export interface InputNumberProps extends Omit HTMLElement); /** * The properties of CSSTransition can be customized, except for "nodeRef" and "in" properties. * @type {CSSTransitionProps} diff --git a/components/lib/multiselect/MultiSelectBase.js b/components/lib/multiselect/MultiSelectBase.js index d26c8fe404..021a0b94e5 100644 --- a/components/lib/multiselect/MultiSelectBase.js +++ b/components/lib/multiselect/MultiSelectBase.js @@ -260,6 +260,7 @@ export const MultiSelectBase = ComponentBase.extend({ resetFilterOnHide: false, scrollHeight: '200px', selectAll: false, + selectAllLabel: null, selectedItemTemplate: null, selectedItemsLabel: '{0} items selected', selectionLimit: null, diff --git a/components/lib/multiselect/multiselect.d.ts b/components/lib/multiselect/multiselect.d.ts index 6a75171cda..34c27d0bba 100644 --- a/components/lib/multiselect/multiselect.d.ts +++ b/components/lib/multiselect/multiselect.d.ts @@ -421,7 +421,7 @@ export interface MultiSelectProps extends Omit HTMLElement); /** * Establishes relationships between the component and label(s) where its value should be one or more element IDs. */ diff --git a/components/lib/overlaypanel/overlaypanel.d.ts b/components/lib/overlaypanel/overlaypanel.d.ts index cbd9330f27..527d3006f9 100644 --- a/components/lib/overlaypanel/overlaypanel.d.ts +++ b/components/lib/overlaypanel/overlaypanel.d.ts @@ -106,7 +106,7 @@ export interface OverlayPanelProps extends Omit HTMLElement); /** * Aria label of the close icon. * @defaultValue close diff --git a/components/lib/paginator/paginator.d.ts b/components/lib/paginator/paginator.d.ts index 83220e3a40..fae1178f1b 100644 --- a/components/lib/paginator/paginator.d.ts +++ b/components/lib/paginator/paginator.d.ts @@ -391,7 +391,7 @@ interface PaginatorRowsPerPageDropdownOptions { /** * DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and "self". The "self" value is used to render a component where it is located. */ - appendTo: 'self' | HTMLElement | null | undefined; + appendTo: 'self' | HTMLElement | null | undefined | (() => HTMLElement); /** * The current page number. */ @@ -610,7 +610,7 @@ export interface PaginatorProps extends Omit HTMLElement); /** * Callback to invoke when page changes, the event object contains information about the new state. * @param {PaginatorPageChangeEvent} event - Custom page change event. diff --git a/components/lib/passthrough/tailwind/index.js b/components/lib/passthrough/tailwind/index.js index 0a488e9804..d24daac5b4 100644 --- a/components/lib/passthrough/tailwind/index.js +++ b/components/lib/passthrough/tailwind/index.js @@ -396,6 +396,7 @@ const Tailwind = { 'dark:border dark:border-blue-900/40 dark:bg-gray-900 dark:text-white/80' ) }, + closeButton: 'flex items-center justify-center overflow-hidden absolute top-0 right-0 w-6 h-6', content: 'p-5 items-center flex', transition: TRANSITIONS.overlay }, @@ -492,10 +493,10 @@ const Tailwind = { }, arrow: ({ context }) => ({ className: classNames('absolute w-0 h-0 border-transparent border-solid', { - '-m-t-1 border-y-[0.25rem] border-r-[0.25rem] border-l-0 border-r-gray-600': context.right, - '-m-t-1 border-y-[0.25rem] border-l-[0.25rem] border-r-0 border-l-gray-600': context.left, - '-m-l-1 border-x-[0.25rem] border-t-[0.25rem] border-b-0 border-t-gray-600': context.top, - '-m-l-1 border-x-[0.25rem] border-b-[0.25rem] border-t-0 border-b-gray-600': context.bottom + '-mt-1 border-y-[0.25rem] border-r-[0.25rem] border-l-0 border-r-gray-600': context.right, + '-mt-1 border-y-[0.25rem] border-l-[0.25rem] border-r-0 border-l-gray-600': context.left, + '-ml-1 border-x-[0.25rem] border-t-[0.25rem] border-b-0 border-t-gray-600': context.top, + '-ml-1 border-x-[0.25rem] border-b-[0.25rem] border-t-0 border-b-gray-600': context.bottom }) }), text: { @@ -697,6 +698,14 @@ const Tailwind = { 'mt-2 order-2': props.iconPos == 'bottom' && props.label != null }) }), + loadingIcon: ({ props }) => ({ + className: classNames('mx-0', { + 'mr-2': props.loading && props.iconPos == 'left' && props.label != null, + 'ml-2 order-1': props.loading && props.iconPos == 'right' && props.label != null, + 'mb-2': props.loading && props.iconPos == 'top' && props.label != null, + 'mt-2 order-2': props.loading && props.iconPos == 'bottom' && props.label != null + }) + }), badge: ({ props }) => ({ className: classNames({ 'ml-2 w-4 h-4 leading-none flex items-center justify-center': props.badge }) }) @@ -845,13 +854,12 @@ const Tailwind = { sublist: { className: classNames('block absolute left-full top-0', 'min-w-full z-10', 'py-3 bg-white dark:bg-gray-900 border-0 shadow-md') }, - item: { - className: classNames( - 'cursor-pointer font-normal whitespace-nowrap', - 'm-0 border-0 bg-transparent transition-shadow rounded-none', - 'text-gray-700 dark:text-white/80 hover:text-gray-700 dark:hover:text-white/80 hover:bg-gray-200 dark:hover:bg-gray-800/80' - ) - }, + item: ({ state }) => ({ + className: classNames('cursor-pointer font-normal whitespace-nowrap', 'm-0 border-0 bg-transparent transition-shadow rounded-none', { + 'text-gray-700 hover:text-gray-700 hover:bg-gray-200 dark:text-white/80 dark:hover:text-white/80 dark:hover:bg-gray-800/80': !state.selected, + 'bg-blue-50 text-blue-700 dark:bg-blue-300 dark:text-white/80': state.selected + }) + }), content: { className: classNames('flex items-center overflow-hidden relative', 'py-3 px-5') }, @@ -1125,10 +1133,10 @@ const Tailwind = { }) }), input: { - root: ({ props }) => ({ + root: ({ parent }) => ({ className: classNames('font-sans text-base text-gray-600 dark:text-white/80 bg-white dark:bg-gray-900 p-3 border border-gray-300 dark:border-blue-900/40 transition-colors duration-200 appearance-none', 'hover:border-blue-500', { - 'rounded-lg': !props.showIcon, - 'border-r-0 rounded-l-lg': props.showIcon + 'rounded-lg': !parent.props.showIcon, + 'border-r-0 rounded-l-lg': parent.props.showIcon }) }) }, @@ -1147,13 +1155,11 @@ const Tailwind = { className: classNames('flex items-center justify-between', 'p-2 text-gray-700 dark:text-white/80 bg-white dark:bg-gray-900 font-semibold m-0 border-b border-gray-300 dark:border-blue-900/40 rounded-t-lg') }, previousButton: { - root: ({ props }) => ({ - className: classNames( - 'flex items-center justify-center cursor-pointer overflow-hidden relative', - 'w-8 h-8 text-gray-600 dark:text-white/70 border-0 bg-transparent rounded-full transition-colors duration-200 ease-in-out', - 'hover:text-gray-700 dark:hover:text-white/80 hover:border-transparent hover:bg-gray-200 dark:hover:bg-gray-800/80 ' - ) - }) + className: classNames( + 'flex items-center justify-center cursor-pointer overflow-hidden relative', + 'w-8 h-8 text-gray-600 dark:text-white/70 border-0 bg-transparent rounded-full transition-colors duration-200 ease-in-out', + 'hover:text-gray-700 dark:hover:text-white/80 hover:border-transparent hover:bg-gray-200 dark:hover:bg-gray-800/80 ' + ) }, title: 'leading-8 mx-auto', monthTitle: { @@ -1163,13 +1169,11 @@ const Tailwind = { className: classNames('text-gray-700 dark:text-white/80 transition duration-200 font-semibold p-2', 'hover:text-blue-500') }, nextButton: { - root: ({ props }) => ({ - className: classNames( - 'flex items-center justify-center cursor-pointer overflow-hidden relative', - 'w-8 h-8 text-gray-600 dark:text-white/70 border-0 bg-transparent rounded-full transition-colors duration-200 ease-in-out', - 'hover:text-gray-700 dark:hover:text-white/80 hover:border-transparent hover:bg-gray-200 dark:hover:bg-gray-800/80 ' - ) - }) + className: classNames( + 'flex items-center justify-center cursor-pointer overflow-hidden relative', + 'w-8 h-8 text-gray-600 dark:text-white/70 border-0 bg-transparent rounded-full transition-colors duration-200 ease-in-out', + 'hover:text-gray-700 dark:hover:text-white/80 hover:border-transparent hover:bg-gray-200 dark:hover:bg-gray-800/80 ' + ) }, table: { className: classNames('border-collapse w-full', 'my-2') @@ -1368,13 +1372,15 @@ const Tailwind = { }, filterContainer: 'relative', filterInput: { - className: classNames( - 'pr-7 -mr-7', - 'w-full', - 'font-sans text-base text-gray-700 bg-white py-3 px-3 border border-gray-300 transition duration-200 rounded-lg appearance-none', - 'dark:bg-gray-900 dark:border-blue-900/40 dark:hover:border-blue-300 dark:text-white/80', - '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)]' - ) + root: { + className: classNames( + 'pr-7 -mr-7', + 'w-full', + 'font-sans text-base text-gray-700 bg-white py-3 px-3 border border-gray-300 transition duration-200 rounded-lg appearance-none', + 'dark:bg-gray-900 dark:border-blue-900/40 dark:hover:border-blue-300 dark:text-white/80', + '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', @@ -2615,8 +2621,8 @@ const Tailwind = { }) }, picklist: { - root: 'flex', - controls: 'flex flex-col justify-center p-5', + root: 'flex flex-col xl:flex-row', + controls: 'flex flex-row xl:flex-col justify-center p-5', moveUpButton: { root: { className: classNames( @@ -2624,7 +2630,7 @@ const Tailwind = { 'text-white bg-blue-500 border border-blue-500 rounded-md', 'transition duration-200 ease-in-out', 'justify-center px-0 py-3', // icon only - 'mb-2', // orderlist button + 'mr-2 xl:mb-2', // orderlist button 'dark:bg-sky-300 dark:border-sky-300 dark:text-gray-900' //Dark Mode ) }, @@ -2637,7 +2643,7 @@ const Tailwind = { 'text-white bg-blue-500 border border-blue-500 rounded-md', 'transition duration-200 ease-in-out', 'justify-center px-0 py-3', // icon only - 'mb-2', // orderlist button + 'mr-2 xl:mb-2', // orderlist button 'dark:bg-sky-300 dark:border-sky-300 dark:text-gray-900' //Dark Mode ) }, @@ -2650,7 +2656,7 @@ const Tailwind = { 'text-white bg-blue-500 border border-blue-500 rounded-md', 'transition duration-200 ease-in-out', 'justify-center px-0 py-3', // icon only - 'mb-2', // orderlist button + 'mr-2 xl:mb-2', // orderlist button 'dark:bg-sky-300 dark:border-sky-300 dark:text-gray-900' //Dark Mode ) }, @@ -2663,7 +2669,7 @@ const Tailwind = { 'text-white bg-blue-500 border border-blue-500 rounded-md', 'transition duration-200 ease-in-out', 'justify-center px-0 py-3', // icon only - 'mb-2', // orderlist button + 'mr-2 xl:mb-2', // orderlist button 'dark:bg-sky-300 dark:border-sky-300 dark:text-gray-900' //Dark Mode ) }, @@ -2689,7 +2695,7 @@ const Tailwind = { 'text-gray-600 dark:bg-blue-900/40': !context.selected }) }), - buttons: 'flex flex-col justify-center p-5', + buttons: 'flex flex-row xl:flex-col justify-center p-5', movetotargetbutton: { root: { className: classNames( @@ -2697,7 +2703,7 @@ const Tailwind = { 'text-white bg-blue-500 border border-blue-500 rounded-md', 'transition duration-200 ease-in-out', 'justify-center px-0 py-3', // icon only - 'mb-2', // orderlist button + 'mr-2 xl:mb-2', // orderlist button 'dark:bg-sky-300 dark:border-sky-300 dark:text-gray-900' //Dark Mode ) }, @@ -2710,7 +2716,7 @@ const Tailwind = { 'text-white bg-blue-500 border border-blue-500 rounded-md', 'transition duration-200 ease-in-out', 'justify-center px-0 py-3', // icon only - 'mb-2', // orderlist button + 'mr-2 xl:mb-2', // orderlist button 'dark:bg-sky-300 dark:border-sky-300 dark:text-gray-900' //Dark Mode ) }, @@ -2723,7 +2729,7 @@ const Tailwind = { 'text-white bg-blue-500 border border-blue-500 rounded-md', 'transition duration-200 ease-in-out', 'justify-center px-0 py-3', // icon only - 'mb-2', // orderlist button + 'mr-2 xl:mb-2', // orderlist button 'dark:bg-sky-300 dark:border-sky-300 dark:text-gray-900' //Dark Mode ) }, @@ -2736,7 +2742,7 @@ const Tailwind = { 'text-white bg-blue-500 border border-blue-500 rounded-md', 'transition duration-200 ease-in-out', 'justify-center px-0 py-3', // icon only - 'mb-2', // orderlist button + 'mr-2 xl:mb-2', // orderlist button 'dark:bg-sky-300 dark:border-sky-300 dark:text-gray-900' //Dark Mode ) }, @@ -3169,7 +3175,7 @@ const Tailwind = { context.size === 'small' ? 'p-2' : context.size === 'large' ? 'p-5' : 'p-4', // Size 'dark:text-white/80 dark:border-blue-900/40', // Dark Mode { - 'sticky bg-inherit': props.frozen || props.frozen === '', // Frozen Columns + 'sticky bg-inherit': props && (props.frozen || props.frozen === ''), // Frozen Columns 'border-x border-y': context.showGridlines } ) diff --git a/components/lib/password/password.d.ts b/components/lib/password/password.d.ts index 8a221c443b..b9e43f7f34 100644 --- a/components/lib/password/password.d.ts +++ b/components/lib/password/password.d.ts @@ -215,7 +215,7 @@ export interface PasswordProps extends Omit HTMLElement); /** * Template of panel header if "feedback" is enabled. */ diff --git a/components/lib/portal/Portal.js b/components/lib/portal/Portal.js index 09bb7959a9..1959c3436c 100644 --- a/components/lib/portal/Portal.js +++ b/components/lib/portal/Portal.js @@ -2,7 +2,7 @@ import * as React from 'react'; import ReactDOM from 'react-dom'; import PrimeReact, { PrimeReactContext } from '../api/Api'; import { useMountEffect, useUnmountEffect, useUpdateEffect } from '../hooks/Hooks'; -import { DomHandler } from '../utils/Utils'; +import { DomHandler, ObjectUtils } from '../utils/Utils'; import { PortalBase } from './PortalBase'; export const Portal = React.memo((inProps) => { @@ -29,7 +29,15 @@ export const Portal = React.memo((inProps) => { const element = props.element || props.children; if (element && mountedState) { - const appendTo = props.appendTo || (context && context.appendTo) || PrimeReact.appendTo || document.body; + let appendTo = props.appendTo || (context && context.appendTo) || PrimeReact.appendTo; + + if (ObjectUtils.isFunction(appendTo)) { + appendTo = appendTo(); + } + + if (!appendTo) { + appendTo = document.body; + } return appendTo === 'self' ? element : ReactDOM.createPortal(element, appendTo); } diff --git a/components/lib/sidebar/sidebar.d.ts b/components/lib/sidebar/sidebar.d.ts index 7fca1a1014..5627c6ab98 100644 --- a/components/lib/sidebar/sidebar.d.ts +++ b/components/lib/sidebar/sidebar.d.ts @@ -161,7 +161,7 @@ export interface SidebarProps extends Omit HTMLElement); /** * The properties of CSSTransition can be customized, except for "nodeRef" and "in" properties. * @type {CSSTransitionProps} diff --git a/components/lib/slidemenu/slidemenu.d.ts b/components/lib/slidemenu/slidemenu.d.ts index 1accdf4847..b5eba8e670 100644 --- a/components/lib/slidemenu/slidemenu.d.ts +++ b/components/lib/slidemenu/slidemenu.d.ts @@ -143,7 +143,7 @@ export interface SlideMenuProps extends Omit HTMLElement); /** * Whether to automatically manage layering. * @defaultValue true diff --git a/components/lib/splitbutton/splitbutton.d.ts b/components/lib/splitbutton/splitbutton.d.ts index 1d5f76137a..7afe012d5b 100644 --- a/components/lib/splitbutton/splitbutton.d.ts +++ b/components/lib/splitbutton/splitbutton.d.ts @@ -185,7 +185,7 @@ export interface SplitButtonProps extends Omit HTMLElement); /** * Content of the tooltip. */ diff --git a/components/lib/tieredmenu/tieredmenu.d.ts b/components/lib/tieredmenu/tieredmenu.d.ts index 38ad92e03f..2210eaa125 100644 --- a/components/lib/tieredmenu/tieredmenu.d.ts +++ b/components/lib/tieredmenu/tieredmenu.d.ts @@ -142,7 +142,7 @@ export interface TieredMenuProps extends Omit HTMLElement); /** * The properties of CSSTransition can be customized, except for "nodeRef" and "in" properties. * @type {CSSTransitionProps} diff --git a/components/lib/toast/toast.d.ts b/components/lib/toast/toast.d.ts index 44a215704c..ec70aec268 100644 --- a/components/lib/toast/toast.d.ts +++ b/components/lib/toast/toast.d.ts @@ -239,7 +239,7 @@ export interface ToastProps extends Omit HTMLElement); /** * Callback to invoke when an active tab is collapsed by clicking on the header. * @param {ToastMessage} message - Clicked message diff --git a/components/lib/tooltip/tooltipoptions.d.ts b/components/lib/tooltip/tooltipoptions.d.ts index f614f464a3..ce7db5af53 100644 --- a/components/lib/tooltip/tooltipoptions.d.ts +++ b/components/lib/tooltip/tooltipoptions.d.ts @@ -34,7 +34,7 @@ export interface TooltipOptions { * DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located. * @defaultValue document.body */ - appendTo?: 'self' | HTMLElement | null | undefined; + appendTo?: 'self' | HTMLElement | null | undefined | (() => HTMLElement); /** * Defines which position on the target element to align the positioned tooltip. */ diff --git a/components/lib/treeselect/treeselect.d.ts b/components/lib/treeselect/treeselect.d.ts index 10a30ec2c4..df26a40f7e 100644 --- a/components/lib/treeselect/treeselect.d.ts +++ b/components/lib/treeselect/treeselect.d.ts @@ -351,7 +351,7 @@ export interface TreeSelectProps extends Omit HTMLElement); /** * Used to define a string that labels the component. */ diff --git a/components/lib/treetable/TreeTable.js b/components/lib/treetable/TreeTable.js index 43b90b9c02..c9130478e9 100644 --- a/components/lib/treetable/TreeTable.js +++ b/components/lib/treetable/TreeTable.js @@ -214,7 +214,7 @@ export const TreeTable = React.forwardRef((inProps, ref) => { const sortNodes = (data) => { let value = [...data]; - if (columnSortable.current && columnSortable.current === 'custom' && columnSortFunction.current) { + if (columnSortable.current && columnSortFunction.current) { value = columnSortFunction.current({ data, field: getSortField(), @@ -370,9 +370,9 @@ export const TreeTable = React.forwardRef((inProps, ref) => { if (newColumnWidth > 15 && nextColumnWidth > 15) { if (props.scrollable) { let scrollableView = findParentScrollableView(resizeColumn.current); - let scrollableBodyTable = DomHandler.findSingle(scrollableView, 'table.p-treetable-scrollable-body-table'); - let scrollableHeaderTable = DomHandler.findSingle(scrollableView, 'table.p-treetable-scrollable-header-table'); - let scrollableFooterTable = DomHandler.findSingle(scrollableView, 'table.p-treetable-scrollable-footer-table'); + let scrollableBodyTable = DomHandler.findSingle(scrollableView, 'table[data-pc-section="scrollablebodytable"]'); + let scrollableHeaderTable = DomHandler.findSingle(scrollableView, 'table[data-pc-section="scrollableheadertable"]'); + let scrollableFooterTable = DomHandler.findSingle(scrollableView, 'table[data-pc-section="scrollablefootertable"]'); let resizeColumnIndex = DomHandler.index(resizeColumn.current); resizeColGroup(scrollableHeaderTable, resizeColumnIndex, newColumnWidth, nextColumnWidth); @@ -389,9 +389,9 @@ export const TreeTable = React.forwardRef((inProps, ref) => { } else if (props.columnResizeMode === 'expand') { if (props.scrollable) { let scrollableView = findParentScrollableView(resizeColumn.current); - let scrollableBodyTable = DomHandler.findSingle(scrollableView, 'table.p-treetable-scrollable-body-table'); - let scrollableHeaderTable = DomHandler.findSingle(scrollableView, 'table.p-treetable-scrollable-header-table'); - let scrollableFooterTable = DomHandler.findSingle(scrollableView, 'table.p-treetable-scrollable-footer-table'); + let scrollableBodyTable = DomHandler.findSingle(scrollableView, 'table[data-pc-section="scrollablebodytable"]'); + let scrollableHeaderTable = DomHandler.findSingle(scrollableView, 'table[data-pc-section="scrollableheadertable"]'); + let scrollableFooterTable = DomHandler.findSingle(scrollableView, 'table[data-pc-section="scrollablefootertable"]'); scrollableBodyTable.style.width = scrollableBodyTable.offsetWidth + delta + 'px'; scrollableHeaderTable.style.width = scrollableHeaderTable.offsetWidth + delta + 'px'; @@ -913,39 +913,40 @@ export const TreeTable = React.forwardRef((inProps, ref) => { return ( ); }; diff --git a/components/lib/treetable/TreeTableBase.js b/components/lib/treetable/TreeTableBase.js index f8353c6e5c..a027d1a5bc 100644 --- a/components/lib/treetable/TreeTableBase.js +++ b/components/lib/treetable/TreeTableBase.js @@ -187,10 +187,11 @@ const classes = { tbody: 'p-treetable-tbody', tfoot: 'p-treetable-tfoot', emptyMessage: 'p-treetable-emptymessage', - bodyCell: ({ bodyProps: props, editingState }) => + bodyCell: ({ bodyProps: props, editingState, align }) => classNames({ 'p-editable-column': props.editor, - 'p-cell-editing': props.editor ? editingState : false + 'p-cell-editing': props.editor ? editingState : false, + [`p-align-${align}`]: !!align }), sortBadge: 'p-sortable-column-badge', headerTitle: 'p-column-title', diff --git a/components/lib/treetable/TreeTableBody.js b/components/lib/treetable/TreeTableBody.js index 15a424ac24..c36f4a5082 100644 --- a/components/lib/treetable/TreeTableBody.js +++ b/components/lib/treetable/TreeTableBody.js @@ -1,6 +1,6 @@ import * as React from 'react'; import { localeOption } from '../api/Api'; -import { DomHandler, useMergeProps } from '../utils/Utils'; +import { DomHandler, useMergeProps, ObjectUtils } from '../utils/Utils'; import { TreeTableRow } from './TreeTableRow'; export const TreeTableBody = React.memo((props) => { @@ -231,7 +231,7 @@ export const TreeTableBody = React.memo((props) => { return null; } else { const colSpan = props.columns ? props.columns.length : null; - const content = props.emptyMessage || localeOption('emptyMessage'); + const content = ObjectUtils.getJSXElement(props.emptyMessage, { props: props.tableProps }) || localeOption('emptyMessage'); const emptyMessageProps = mergeProps( { className: cx('emptyMessage') diff --git a/components/lib/treetable/TreeTableBodyCell.js b/components/lib/treetable/TreeTableBodyCell.js index 3de729516a..fc741f6c0f 100644 --- a/components/lib/treetable/TreeTableBodyCell.js +++ b/components/lib/treetable/TreeTableBodyCell.js @@ -227,10 +227,11 @@ export const TreeTableBodyCell = (props) => { ); + const align = getColumnProp('align'); /* eslint-enable */ const bodyCellProps = mergeProps( { - className: classNames(bodyClassName || props.className, cx('bodyCell', { bodyProps: props, editingState })), + className: classNames(bodyClassName || props.className, cx('bodyCell', { bodyProps: props, editingState, align })), style, onClick: (e) => onClick(e), onKeyDown: (e) => onKeyDown(e) diff --git a/components/lib/treetable/TreeTableHeader.js b/components/lib/treetable/TreeTableHeader.js index 6ef6bda3b1..da2bbc7278 100644 --- a/components/lib/treetable/TreeTableHeader.js +++ b/components/lib/treetable/TreeTableHeader.js @@ -40,7 +40,8 @@ export const TreeTableHeader = React.memo((props) => { 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' + DomHandler.getAttribute(targetNode.parentElement, 'data-pc-section') === 'sorticon' || + (targetNode.closest('[data-p-sortable-column="true"]') && !targetNode.closest('[data-pc-section="filtermenubutton"]')) ) { props.onSort({ originalEvent: event, @@ -284,7 +285,7 @@ export const TreeTableHeader = React.memo((props) => { const multipleSorted = multiSortMetaData !== null; const sorted = getColumnProp(column, 'sortable') && (singleSorted || multipleSorted); const frozen = getColumnProp(column, 'frozen'); - const align = getColumnProp(column, 'alignHeader') || getColumnProp(column, 'align'); + const align = getColumnProp(column, 'alignHeader'); let sortOrder = 0; if (singleSorted) sortOrder = props.sortOrder; diff --git a/components/lib/treetable/TreeTableScrollableView.js b/components/lib/treetable/TreeTableScrollableView.js index 87f4d148ea..6edd2a337b 100644 --- a/components/lib/treetable/TreeTableScrollableView.js +++ b/components/lib/treetable/TreeTableScrollableView.js @@ -64,13 +64,13 @@ export const TreeTableScrollableView = React.memo((props) => { let frozenScrollBody; if (frozenView) { - frozenScrollBody = DomHandler.findSingle(frozenView, '.p-treetable-scrollable-body'); + frozenScrollBody = DomHandler.findSingle(frozenView, '[data-pc-section="scrollablebody"]'); } - scrollHeaderBoxRef.current.style.marginLeft = -1 * scrollBodyRef.current.scrollLeft + 'px'; + scrollHeaderBoxRef.current.style.transform = `translateX(-${scrollBodyRef.current.scrollLeft}px)`; if (scrollFooterBoxRef.current) { - scrollFooterBoxRef.current.style.marginLeft = -1 * scrollBodyRef.current.scrollLeft + 'px'; + scrollFooterBoxRef.current.style.transform = `translateX(-${scrollBodyRef.current.scrollLeft}px)`; } if (frozenScrollBody) { @@ -79,16 +79,20 @@ export const TreeTableScrollableView = React.memo((props) => { }; useMountEffect(() => { - if (!props.frozen) { - const scrollBarWidth = DomHandler.calculateScrollbarWidth(); + let el = DomHandler.find(findDataTableContainer(elementRef.current), '[data-pc-section="scrollablebody"]'); + + el = el.length > 1 ? el[1] : el[0]; + const scrollBarWidth = DomHandler.calculateScrollbarWidth(el); + + if (!props.frozen) { scrollHeaderBoxRef.current.style.marginRight = scrollBarWidth + 'px'; if (scrollFooterBoxRef.current) { scrollFooterBoxRef.current.style.marginRight = scrollBarWidth + 'px'; } } else { - scrollBodyRef.current.style.paddingBottom = DomHandler.calculateScrollbarWidth() + 'px'; + scrollBodyRef.current.style.paddingBottom = scrollBarWidth + 'px'; } }); diff --git a/components/lib/treetable/treetable.d.ts b/components/lib/treetable/treetable.d.ts index 46466297a4..4583df72f4 100644 --- a/components/lib/treetable/treetable.d.ts +++ b/components/lib/treetable/treetable.d.ts @@ -620,9 +620,9 @@ export interface TreeTableProps extends Omit React.ReactNode) | undefined; /** * An array of keys to represent the state of the tree expansion state in controlled mode. */ @@ -733,7 +733,7 @@ export interface TreeTableProps extends Omit HTMLElement); /** * Content for the left side of the paginator. */ diff --git a/data/news.json b/data/news.json index 806c9bb319..d496617e78 100644 --- a/data/news.json +++ b/data/news.json @@ -1,6 +1,6 @@ { - "id": 43, - "content": "🎉 Black Friday Sale! Up to 50% Off", - "linkText": "Buy Now", - "linkHref": "https://www.primefaces.org/store" + "id": 44, + "content": "Sakai Free Admin Template", + "linkText": "View Demo", + "linkHref": "https://sakai.primereact.org" } diff --git a/pages/support/index.js b/pages/support/index.js index e44359bc1a..f8bddad0ab 100644 --- a/pages/support/index.js +++ b/pages/support/index.js @@ -101,8 +101,9 @@ const SupportPage = () => {
Enhancement Credits

- New features and enhancement requests are not available in core services and provided via a credit based model instead named PrimeCredit. When you have a feature request, we offer an initial estimate in terms of credits and once - this estimate is confirmed by you then implementation will be delivered by our team within an estimated timeframe. + New features and enhancement requests are not available in core services and provided via a credit based model instead named PrimeCredit. When you have an enhancement request, initially our team will review your requirement to + verify if it is suitable to be included in the open source core library. We cannot guarantee that all requests can be accepted depending on the project roadmap, workload at the time and type of the requirement. After successful + verification, we prepare an initial estimate in terms of credits and once this estimate is confirmed by you, implementation will be delivered by our team within an estimated timeframe.

@@ -125,30 +126,30 @@ const SupportPage = () => {
Frequently Asked Questions
-
What is the duration of the service?
+
What is the duration of the service?

Support service is for one year.

-
How many JIRA accounts do we get?
+
How many JIRA accounts do we get?

We provide one shared account per organization that any number of members in your organization can use it.

-
What happens if we extend after 1 year and we have unused tickets?
+
What happens if we extend after 1 year and we have unused tickets?

Unused tickets expire and cannot be transferred to the new subscription.

-
When can we purchase PrimeCredits for feature development?
+
When can we purchase PrimeCredits for feature development?

PrimeCredits can be purchased anytime during an active subscription.

-
Are all of our requests guaranteed to be implemented with PrimeCredits?
+
Are all of our requests guaranteed to be implemented with PrimeCredits?

No, PrimeTek does not guarantee the implementation so it is suggested to confirm with us before purchasing credits.

-
Can we get PrimeCredits without PRO support?
+
Can we get PrimeCredits without PRO support?

No, feature development is exclusive to PRO members.

-
Is there a limit on developers in our organization who can use the service?
+
Is there a limit on developers in our organization who can use the service?

PRO is per organization so there is no limit on the number of developers.

-
What is not covered by PRO?
+
What is not covered by PRO?

As PRO support focuses on the library, application consulting and code reviews are out of scope.

diff --git a/pages/team/index.js b/pages/team/index.js index a716cc7952..c567f12599 100644 --- a/pages/team/index.js +++ b/pages/team/index.js @@ -104,6 +104,11 @@ const TemplatesPage = () => { Burak SaÄŸlam Front-End Developer
+
+ Taner Engin + Taner Engin + Front-End Developer +
diff --git a/pages/uikit/index.js b/pages/uikit/index.js index 94d5078f7d..913b687284 100644 --- a/pages/uikit/index.js +++ b/pages/uikit/index.js @@ -132,7 +132,7 @@ const UIKitPage = (props) => {