Skip to content

Commit

Permalink
Related #4391, #4602 - For Menu components
Browse files Browse the repository at this point in the history
  • Loading branch information
ulasturann committed Sep 2, 2023
1 parent ffec750 commit f0c5e57
Show file tree
Hide file tree
Showing 16 changed files with 197 additions and 183 deletions.
6 changes: 3 additions & 3 deletions components/doc/menu/templatedoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function TemplateDoc(props) {
},
template: (item, options) => {
return (
<button onClick={(e) => options.onClick(e)} className={classNames(options.className, 'w-full p-link flex align-items-center')}>
<button onClick={(e) => options.onClick(e)} className={classNames(options.className, 'w-full p-link flex align-items-center p-2 pl-4 text-color hover:surface-200 border-noround')}>
<Avatar image="https://primefaces.org/cdn/primereact/images/avatar/amyelsner.png" className="mr-2" shape="circle" />
<div className="flex flex-column align">
<span className="font-bold">Amy Elsner</span>
Expand Down Expand Up @@ -50,7 +50,7 @@ export default function TemplateDemo() {
command: () => { toast.current.show({ severity: 'info', summary: 'Info', detail: 'Item Selected', life: 3000 }); },
template: (item, options) => {
return (
<button onClick={(e) => options.onClick(e)} className={classNames(options.className, 'w-full p-link flex align-items-center')}>
<button onClick={(e) => options.onClick(e)} className={classNames(options.className, 'w-full p-link flex align-items-center p-2 pl-4 text-color hover:surface-200 border-noround')}>
<Avatar image="https://primefaces.org/cdn/primereact/images/avatar/amyelsner.png" className="mr-2" shape="circle" />
<div className="flex flex-column align">
<span className="font-bold">Amy Elsner</span>
Expand Down Expand Up @@ -86,7 +86,7 @@ export default function TemplateDemo() {
command: () => { toast.current.show({ severity: 'info', summary: 'Info', detail: 'Item Selected', life: 3000 }); },
template: (item, options) => {
return (
<button onClick={(e) => options.onClick(e)} className={classNames(options.className, 'w-full p-link flex align-items-center')}>
<button onClick={(e) => options.onClick(e)} className={classNames(options.className, 'w-full p-link flex align-items-center p-2 pl-4 text-color hover:surface-200 border-noround')}>
<Avatar image="https://primefaces.org/cdn/primereact/images/avatar/amyelsner.png" className="mr-2" shape="circle" />
<div className="flex flex-column align">
<span className="font-bold">Amy Elsner</span>
Expand Down
6 changes: 2 additions & 4 deletions components/lib/dock/Dock.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,7 @@ export const Dock = React.memo(
const footer = createFooter();
const rootProps = mergeProps(
{
id: props.id,
ref: elementRef,
className: cx('root'),
className: classNames(props.className, cx('root')),
style: props.style
},
DockBase.getOtherProps(props),
Expand All @@ -182,7 +180,7 @@ export const Dock = React.memo(
);

return (
<div {...rootProps}>
<div id={props.id} ref={elementRef} {...rootProps}>
<div {...containerProps}>
{header}
{list}
Expand Down
10 changes: 3 additions & 7 deletions components/lib/dock/DockBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,9 @@ const classes = {
menu: 'p-dock-list',
footer: 'p-dock-footer',
root: ({ props }) =>
classNames(
`p-dock p-component p-dock-${props.position}`,
{
'p-dock-magnification': props.magnification
},
props.className
),
classNames(`p-dock p-component p-dock-${props.position}`, {
'p-dock-magnification': props.magnification
}),
container: 'p-dock-container'
};

Expand Down
106 changes: 51 additions & 55 deletions components/lib/megamenu/MegaMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ export const MegaMenu = React.memo(

useHandleStyle(MegaMenuBase.css.styles, isUnstyled, { name: 'megamenu' });

const getPTOptions = (item, key) => {
const getPTOptions = (item, key, index) => {
return ptm(key, {
context: {
active: activeItemState === item
active: activeItemState === item,
item,
index
}
});
};
Expand Down Expand Up @@ -174,13 +176,13 @@ export const MegaMenu = React.memo(
const findNextItem = (item) => {
const nextItem = item.nextElementSibling;

return nextItem ? (DomHandler.hasClass(nextItem, 'p-disabled') || !DomHandler.hasClass(nextItem, 'p-menuitem') ? findNextItem(nextItem) : nextItem) : null;
return nextItem ? (DomHandler.getAttribute(nextItem, '[data-p-disabled="true"]') || !DomHandler.getAttribute(nextItem, '[data-pc-section="menuitem"]') ? findNextItem(nextItem) : nextItem) : null;
};

const findPrevItem = (item) => {
const prevItem = item.previousElementSibling;

return prevItem ? (DomHandler.hasClass(prevItem, 'p-disabled') || !DomHandler.hasClass(prevItem, 'p-menuitem') ? findPrevItem(prevItem) : prevItem) : null;
return prevItem ? (DomHandler.getAttribute(prevItem, '[data-p-disabled="true"]') || !DomHandler.getAttribute(prevItem, '[data-pc-section="menuitem"]') ? findPrevItem(prevItem) : prevItem) : null;
};

const navigateToNextItem = (listItem) => {
Expand All @@ -199,35 +201,6 @@ export const MegaMenu = React.memo(
return elementRef.current && !(elementRef.current.isSameNode(event.target) || elementRef.current.contains(event.target) || (menuButtonRef.current && menuButtonRef.current.contains(event.target)));
};

const getColumnClassName = (category) => {
const length = category.items ? category.items.length : 0;
let columnClass;

switch (length) {
case 2:
columnClass = 'p-megamenu-col-6';
break;

case 3:
columnClass = 'p-megamenu-col-4';
break;

case 4:
columnClass = 'p-megamenu-col-3';
break;

case 6:
columnClass = 'p-megamenu-col-2';
break;

default:
columnClass = 'p-megamenu-col-12';
break;
}

return columnClass;
};

React.useImperativeHandle(ref, () => ({
props,
getElement: () => elementRef.current
Expand Down Expand Up @@ -264,7 +237,7 @@ export const MegaMenu = React.memo(
const separatorProps = mergeProps(
{
key,
className: cx('separatorProps'),
className: cx('separator'),
role: 'separator'
},
ptm('separator')
Expand Down Expand Up @@ -301,9 +274,21 @@ export const MegaMenu = React.memo(
} else {
const key = item.label + '_' + index;
const linkClassName = classNames('p-menuitem-link', { 'p-disabled': item.disabled });
const iconProps = mergeProps(
{
className: classNames(item.icon, cx('icon'))
},
ptm('icon')
);
const labelProps = mergeProps(
{
className: cx('label')
},
ptm('label')
);
const iconClassName = classNames(item.icon, 'p-menuitem-icon');
const icon = IconUtils.getJSXIcon(item.icon, { className: 'p-menuitem-icon' }, { props });
const label = item.label && <span className="p-menuitem-text">{item.label}</span>;
const icon = IconUtils.getJSXIcon(item.icon, { ...iconProps }, { props });
const label = item.label && <span {...labelProps}>{item.label}</span>;

const actionProps = mergeProps(
{
Expand All @@ -314,7 +299,7 @@ export const MegaMenu = React.memo(
role: 'menuitem',
'aria-disabled': item.disabled
},
getPTOptions(item, 'action')
getPTOptions(item, 'action', index)
);

const submenuItemProps = mergeProps(
Expand All @@ -325,7 +310,7 @@ export const MegaMenu = React.memo(
style: item.style,
role: 'none'
},
getPTOptions(item, 'submenuItem')
getPTOptions(item, 'submenuItem', index)
);

let content = (
Expand Down Expand Up @@ -382,21 +367,22 @@ export const MegaMenu = React.memo(
return column.map(createSubmenu);
};

const createColumn = (category, column, index, columnClassName) => {
const createColumn = (category, column, index) => {
const key = category.label + '_column_' + index;
const submenus = createSubmenus(column);

const columnProps = mergeProps(
{
key: key,
className: columnClassName
className: cx('column', { category })
},
ptm('column')
);

const submenuProps = mergeProps(
{
className: cx('submenu'),
style: { display: activeItemState === category ? 'block' : 'none' },
role: 'menu'
},
ptm('submenu')
Expand All @@ -411,10 +397,8 @@ export const MegaMenu = React.memo(

const createColumns = (category) => {
if (category.items) {
const columnClassName = getColumnClassName(category);

return category.items.map((column, index) => {
return createColumn(category, column, index, columnClassName);
return createColumn(category, column, index);
});
}

Expand Down Expand Up @@ -563,15 +547,15 @@ export const MegaMenu = React.memo(
{
className: cx('icon')
},
getPTOptions(category, 'icon')
getPTOptions(category, 'icon', index)
);
const icon = IconUtils.getJSXIcon(category.icon, { ...iconProps }, { props });

const labelProps = mergeProps(
{
className: cx('label')
},
getPTOptions(category, 'label')
getPTOptions(category, 'label', index)
);
const label = category.label && <span {...labelProps}>{category.label}</span>;
const itemContent = category.template ? ObjectUtils.getJSXElement(category.template, category) : null;
Expand All @@ -588,7 +572,7 @@ export const MegaMenu = React.memo(
role: 'menuitem',
'aria-haspopup': category.items != null
},
getPTOptions(category, 'headerAction')
getPTOptions(category, 'headerAction', index)
);

const menuItemProps = mergeProps(
Expand All @@ -598,9 +582,10 @@ export const MegaMenu = React.memo(
className: cx('menuitem', { category, activeItemState }),
style: category.style,
onMouseEnter: (e) => onCategoryMouseEnter(e, category),
role: 'none'
role: 'none',
'data-p-disabled': category.disabled || false
},
getPTOptions(category, 'menuitem')
getPTOptions(category, 'menuitem', index)
);

return (
Expand Down Expand Up @@ -678,11 +663,24 @@ export const MegaMenu = React.memo(
return null;
}

const icon = props.menuIcon || <BarsIcon />;
const menuIcon = IconUtils.getJSXIcon(icon, undefined, { props });
const menuButtonProps = mergeProps(
{
className: cx('menuButton'),
href: '#',
role: 'button',
tabIndex: 0,
onClick: (e) => toggle(e)
},
ptm('menuButton')
);

const menuButtonIconProps = mergeProps(ptm('menuButtonIcon'));

const icon = props.menuIcon || <BarsIcon {...menuButtonIconProps} />;
const menuIcon = IconUtils.getJSXIcon(icon, { ...menuButtonIconProps }, { props });
/* eslint-disable */
const button = (
<a ref={menuButtonRef} href={'#'} role="button" tabIndex={0} className="p-megamenu-button" onClick={toggle}>
<a ref={menuButtonRef} {...menuButtonProps}>
{menuIcon}
</a>
);
Expand All @@ -693,9 +691,7 @@ export const MegaMenu = React.memo(

const rootProps = mergeProps(
{
ref: elementRef,
id: props.id,
className: cx('root', { mobileActiveState }),
className: classNames(props.className, cx('root', { mobileActiveState })),
style: props.style
},
MegaMenuBase.getOtherProps(props),
Expand All @@ -708,7 +704,7 @@ export const MegaMenu = React.memo(
const menuButton = createMenuButton();

return (
<div {...rootProps}>
<div id={props.id} ref={elementRef} {...rootProps}>
{start}
{menuButton}
{menu}
Expand Down
49 changes: 37 additions & 12 deletions components/lib/megamenu/MegaMenuBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ import { ComponentBase } from '../componentbase/ComponentBase';
import { classNames } from '../utils/Utils';

const classes = {
separatorProps: 'p-menu-separator',
root: ({ props, mobileActiveState }) =>
classNames('p-megamenu p-component', {
'p-megamenu-horizontal': props.orientation === 'horizontal',
'p-megamenu-vertical': props.orientation === 'vertical',
'p-megamenu-mobile-active': mobileActiveState
}),
separator: 'p-menu-separator',
submenuIcon: 'p-submenu-icon',
action: ({ item }) => classNames('p-menuitem-link', { 'p-disabled': item.disabled }),
submenuItem: ({ item }) => classNames('p-menuitem', item.className),
Expand All @@ -19,22 +25,41 @@ const classes = {
grid: 'p-megamenu-grid',
icon: 'p-menuitem-icon',
label: 'p-menuitem-text',
column: ({ category }) => {
const length = category.items ? category.items.length : 0;
let columnClass;

switch (length) {
case 2:
columnClass = 'p-megamenu-col-6';
break;

case 3:
columnClass = 'p-megamenu-col-4';
break;

case 4:
columnClass = 'p-megamenu-col-3';
break;

case 6:
columnClass = 'p-megamenu-col-2';
break;

default:
columnClass = 'p-megamenu-col-12';
break;
}

return columnClass;
},
headerAction: ({ category }) => classNames('p-menuitem-link', { 'p-disabled': category.disabled }),
menuButton: 'p-megamenu-button',
menuitem: ({ category, activeItemState }) => classNames('p-menuitem', { 'p-menuitem-active': category === activeItemState }, category.className),
menubar: 'p-megamenu-root-list',
menu: 'p-megamenu-root-list',
start: 'p-megamenu-start',
end: 'p-megamenu-end',
root: ({ props, mobileActiveState }) =>
classNames(
'p-megamenu p-component',
{
'p-megamenu-horizontal': props.orientation === 'horizontal',
'p-megamenu-vertical': props.orientation === 'vertical',
'p-megamenu-mobile-active': mobileActiveState
},
props.className
)
end: 'p-megamenu-end'
};

const styles = `
Expand Down
8 changes: 8 additions & 0 deletions components/lib/megamenu/megamenu.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ export interface MegaMenuPassThroughOptions {
* Uses to pass attributes to the list's DOM element.
*/
menu?: MegaMenuPassThroughType<React.HTMLAttributes<HTMLUListElement>>;
/**
* Uses to pass attributes to the menu button's DOM element.
*/
menuButton?: MegaMenuPassThroughType<React.HTMLAttributes<HTMLAnchorElement>>;
/**
* Uses to pass attributes to the menu icon's DOM element.
*/
menuButtonIcon?: MegaMenuPassThroughType<React.SVGProps<SVGSVGElement> | React.HTMLAttributes<HTMLSpanElement>>;
/**
* Uses to pass attributes to the list item's DOM element.
*/
Expand Down
Loading

0 comments on commit f0c5e57

Please sign in to comment.