Skip to content

Commit

Permalink
Refactor #4391 - For BreadCrumb
Browse files Browse the repository at this point in the history
  • Loading branch information
ulasturann committed May 15, 2023
1 parent a89c4ba commit 18b1d31
Show file tree
Hide file tree
Showing 7 changed files with 337 additions and 34 deletions.
82 changes: 82 additions & 0 deletions components/doc/breadcrumb/pt/ptdoc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { BreadCrumb } from '../../../lib/breadcrumb/BreadCrumb';
import { DocSectionCode } from '../../common/docsectioncode';
import { DocSectionText } from '../../common/docsectiontext';

export function PTDoc(props) {
const items = [{ label: 'Computer' }, { label: 'Notebook' }, { label: 'Accessories' }, { label: 'Backpacks' }, { label: 'Item' }];
const home = { icon: 'pi pi-home', url: 'https://primereact.org' };

const code = {
basic: `
<BreadCrumb model={items} home={home} />
`,
javascript: `
import React from 'react';
import { BreadCrumb } from 'primereact/breadcrumb';
export default function PTDemo() {
const items = [{ label: 'Computer' }, { label: 'Notebook' }, { label: 'Accessories' }, { label: 'Backpacks' }, { label: 'Item' }];
const home = { icon: 'pi pi-home', url: 'https://primereact.org' }
return (
<div className="card flex justify-content-center">
<BreadCrumb
pt={{
root: { className: 'surface-ground' },
label: ({ props }) => ({
className: props.index === items.length - 1 ? 'font-italic' : undefined
})
}}
model={items}
home={home}
/>
</div>
)
}
`,
typescript: `
import React from 'react';
import { BreadCrumb } from 'primereact/breadcrumb';
import { MenuItem } from 'primereact/menuitem';
export default function PTDemo() {
const items: MenuItem[] = [{ label: 'Computer' }, { label: 'Notebook' }, { label: 'Accessories' }, { label: 'Backpacks' }, { label: 'Item' }];
const home: MenuItem = { icon: 'pi pi-home', url: 'https://primereact.org' }
return (
<div className="card flex justify-content-center">
<BreadCrumb
pt={{
root: { className: 'surface-ground' },
label: ({ props }) => ({
className: props.index === items.length - 1 ? 'font-italic' : undefined
})
}}
model={items}
home={home}
/>
</div>
)
}
`
};

return (
<>
<DocSectionText {...props}></DocSectionText>
<div className="card flex justify-content-center">
<BreadCrumb
pt={{
root: { className: 'surface-ground' },
label: ({ props }) => ({
className: props.index === items.length - 1 ? 'font-italic' : undefined
})
}}
model={items}
home={home}
/>
</div>
<DocSectionCode code={code} />
</>
);
}
13 changes: 13 additions & 0 deletions components/doc/breadcrumb/pt/wireframe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';
import { DocSectionText } from '../../common/docsectiontext';

export const Wireframe = (props) => {
return (
<>
<DocSectionText {...props} />
<div>
<img className="w-full" src="https://primefaces.org/cdn/primereact/images/pt/wireframe-placeholder.jpg" alt="breadcrumb" />
</div>
</>
);
};
90 changes: 90 additions & 0 deletions components/doc/common/apidoc/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -3520,6 +3520,14 @@
"type": "ReactNode",
"default": "",
"description": "Used to get the child elements of the component."
},
{
"name": "pt",
"optional": true,
"readonly": false,
"type": "BreadCrumbPassThroughOptions",
"default": "",
"description": "Uses to pass attributes to DOM elements inside the component."
}
]
},
Expand All @@ -3528,6 +3536,88 @@
"values": []
}
}
},
"interfaces": {
"description": "Defines the custom interfaces used by the module.",
"values": {
"BreadCrumbPassThroughMethodOptions": {
"description": "Custom passthrough(pt) option method.",
"relatedProp": "",
"props": [
{
"name": "props",
"optional": false,
"readonly": false,
"type": "BreadCrumbProps"
}
],
"callbacks": []
},
"BreadCrumbPassThroughOptions": {
"description": "Custom passthrough(pt) options.",
"relatedProp": "pt",
"props": [
{
"name": "root",
"optional": true,
"readonly": false,
"type": "BreadCrumbPassThroughType<HTMLAttributes<HTMLElement>>",
"description": "Uses to pass attributes to the root's DOM element."
},
{
"name": "menu",
"optional": true,
"readonly": false,
"type": "BreadCrumbPassThroughType<HTMLAttributes<HTMLDivElement>>",
"description": "Uses to pass attributes to the list's DOM element."
},
{
"name": "menuitem",
"optional": true,
"readonly": false,
"type": "BreadCrumbPassThroughType<HTMLAttributes<HTMLDivElement>>",
"description": "Uses to pass attributes to the list item's DOM element."
},
{
"name": "action",
"optional": true,
"readonly": false,
"type": "BreadCrumbPassThroughType<HTMLAttributes<HTMLDivElement>>",
"description": "Uses to pass attributes to the action's DOM element."
},
{
"name": "icon",
"optional": true,
"readonly": false,
"type": "BreadCrumbPassThroughType<HTMLAttributes<HTMLSpanElement> | SVGProps<SVGSVGElement>>",
"description": "Uses to pass attributes to the icon's DOM element."
},
{
"name": "label",
"optional": true,
"readonly": false,
"type": "BreadCrumbPassThroughType<HTMLAttributes<HTMLDivElement>>",
"description": "Uses to pass attributes to the label's DOM element."
},
{
"name": "separatorIcon",
"optional": true,
"readonly": false,
"type": "BreadCrumbPassThroughType<HTMLAttributes<HTMLSpanElement> | SVGProps<SVGSVGElement>>",
"description": "Uses to pass attributes to the separator icon's DOM element."
}
],
"callbacks": []
}
}
},
"types": {
"description": "Defines the custom types used by the module.",
"values": {
"BreadCrumbPassThroughType": {
"values": "PassThroughType<T, BreadCrumbPassThroughMethodOptions>"
}
}
}
},
"button": {
Expand Down
103 changes: 77 additions & 26 deletions components/lib/breadcrumb/BreadCrumb.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import * as React from 'react';
import { classNames, IconUtils, ObjectUtils } from '../utils/Utils';
import { classNames, IconUtils, mergeProps, ObjectUtils } from '../utils/Utils';
import { BreadCrumbBase } from './BreadCrumbBase';
import { ChevronRightIcon } from '../icons/chevronright';

export const BreadCrumb = React.memo(
React.forwardRef((inProps, ref) => {
const props = BreadCrumbBase.getProps(inProps);

const { ptm } = BreadCrumbBase.setMetaData({
props
});
const elementRef = React.useRef(null);

const itemClick = (event, item) => {
Expand Down Expand Up @@ -38,14 +40,26 @@ export const BreadCrumb = React.memo(

const { icon: _icon, target, url, disabled, style, className: _className, template } = home;
const className = classNames('p-breadcrumb-home', { 'p-disabled': disabled }, _className);
const icon = IconUtils.getJSXIcon(_icon, { className: 'p-menuitem-icon' }, { props });

let content = (
<a href={url || '#'} className="p-menuitem-link" aria-disabled={disabled} target={target} onClick={(event) => itemClick(event, home)}>
{icon}
</a>
const iconProps = mergeProps(
{
className: 'p-menuitem-icon'
},
ptm('icon')
);
const icon = IconUtils.getJSXIcon(_icon, { ...iconProps }, { props });
const actionProps = mergeProps(
{
href: url || '#',
className: 'p-menuitem-link',
'aria-disabled': disabled,
target,
onClick: (event) => itemClick(event, home)
},
ptm('action')
);

let content = <a {...actionProps}>{icon}</a>;

if (template) {
const defaultContentOptions = {
onClick: (event) => itemClick(event, home),
Expand All @@ -58,20 +72,30 @@ export const BreadCrumb = React.memo(
content = ObjectUtils.getJSXElement(template, home, defaultContentOptions);
}

return (
<li className={className} style={style}>
{content}
</li>
const menuitemProps = mergeProps(
{
className,
style
},
ptm('menuitem')
);

return <li {...menuitemProps}>{content}</li>;
}

return null;
};

const createSeparator = () => {
const iconClassName = 'p-breadcrumb-chevron';
const icon = props.separatorIcon || <ChevronRightIcon className={iconClassName} />;
const separatorIcon = IconUtils.getJSXIcon(icon, { className: iconClassName }, { props });
const separatorIconProps = mergeProps(
{
className: iconClassName
},
ptm('separatorIcon')
);
const icon = props.separatorIcon || <ChevronRightIcon {...separatorIconProps} />;
const separatorIcon = IconUtils.getJSXIcon(icon, { ...separatorIconProps }, { props });

return separatorIcon;
};
Expand All @@ -82,12 +106,24 @@ export const BreadCrumb = React.memo(
}

const className = classNames(item.className, { 'p-disabled': item.disabled });
const label = item.label && <span className="p-menuitem-text">{item.label}</span>;
let content = (
<a href={item.url || '#'} className="p-menuitem-link" target={item.target} onClick={(event) => itemClick(event, item)} aria-disabled={item.disabled}>
{label}
</a>
const labelProps = mergeProps(
{
className: 'p-menuitem-text'
},
ptm('label')
);
const label = item.label && <span {...labelProps}>{item.label}</span>;
const actionProps = mergeProps(
{
href: item.url || '#',
className: 'p-menuitem-link',
target: item.target,
onClick: (event) => itemClick(event, item),
'aria-disabled': item.disabled
},
ptm('action')
);
let content = <a {...actionProps}>{label}</a>;

if (item.template) {
const defaultContentOptions = {
Expand All @@ -101,11 +137,15 @@ export const BreadCrumb = React.memo(
content = ObjectUtils.getJSXElement(item.template, item, defaultContentOptions);
}

return (
<li className={className} style={item.style}>
{content}
</li>
const menuitemProps = mergeProps(
{
className,
style: item.style
},
ptm('menuitem')
);

return <li {...menuitemProps}>{content}</li>;
};

const createMenuitems = () => {
Expand Down Expand Up @@ -138,15 +178,26 @@ export const BreadCrumb = React.memo(
getElement: () => elementRef.current
}));

const otherProps = BreadCrumbBase.getOtherProps(props);
const className = classNames('p-breadcrumb p-component', props.className);
const home = createHome();
const items = createMenuitems();
const separator = createSeparator();
const menuProps = mergeProps(ptm('menu'));
const rootProps = mergeProps(
{
id: props.id,
ref: elementRef,
className,
style: props.style,
'aria-label': 'Breadcrumb'
},
BreadCrumbBase.getOtherProps(props),
ptm('root')
);

return (
<nav id={props.id} ref={elementRef} className={className} style={props.style} aria-label="Breadcrumb" {...otherProps}>
<ul>
<nav {...rootProps}>
<ul {...menuProps}>
{home}
{separator}
{items}
Expand Down
10 changes: 4 additions & 6 deletions components/lib/breadcrumb/BreadCrumbBase.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ObjectUtils } from '../utils/Utils';
import { ComponentBase } from '../componentbase/ComponentBase';

export const BreadCrumbBase = {
export const BreadCrumbBase = ComponentBase.extend({
defaultProps: {
__TYPE: 'BreadCrumb',
id: null,
Expand All @@ -10,7 +10,5 @@ export const BreadCrumbBase = {
style: null,
className: null,
children: undefined
},
getProps: (props) => ObjectUtils.getMergedProps(props, BreadCrumbBase.defaultProps),
getOtherProps: (props) => ObjectUtils.getDiffProps(props, BreadCrumbBase.defaultProps)
};
}
});
Loading

0 comments on commit 18b1d31

Please sign in to comment.