diff --git a/components/doc/common/apidoc/index.json b/components/doc/common/apidoc/index.json index 355b88ba57..a00df03f04 100644 --- a/components/doc/common/apidoc/index.json +++ b/components/doc/common/apidoc/index.json @@ -28908,6 +28908,14 @@ "type": "ReactNode", "default": "", "description": "Used to get the child elements of the component." + }, + { + "name": "pt", + "optional": true, + "readonly": false, + "type": "OrganizationChartPassThroughOptions", + "default": "", + "description": "Uses to pass attributes to DOM elements inside the component." } ] }, @@ -29038,6 +29046,143 @@ "interfaces": { "description": "Defines the custom interfaces used by the module.", "values": { + "OrganizationChartPassThroughMethodOptions": { + "description": "Custom passthrough(pt) option method.", + "relatedProp": "", + "props": [ + { + "name": "props", + "optional": false, + "readonly": false, + "type": "OrganizationChartProps" + }, + { + "name": "state", + "optional": false, + "readonly": false, + "type": "OrganizationChartState" + }, + { + "name": "context", + "optional": false, + "readonly": false, + "type": "OrganizationChartContext" + } + ], + "callbacks": [] + }, + "OrganizationChartPassThroughOptions": { + "description": "Custom passthrough(pt) options.", + "relatedProp": "pt", + "props": [ + { + "name": "root", + "optional": true, + "readonly": false, + "type": "OrganizationChartPassThroughType>", + "description": "Uses to pass attributes to the root's DOM element." + }, + { + "name": "table", + "optional": true, + "readonly": false, + "type": "OrganizationChartPassThroughType>", + "description": "Uses to pass attributes to the table's DOM element." + }, + { + "name": "cell", + "optional": true, + "readonly": false, + "type": "OrganizationChartPassThroughType>", + "description": "Uses to pass attributes to the cell's DOM element." + }, + { + "name": "node", + "optional": true, + "readonly": false, + "type": "OrganizationChartPassThroughType>", + "description": "Uses to pass attributes to the node's DOM element." + }, + { + "name": "nodeToggler", + "optional": true, + "readonly": false, + "type": "OrganizationChartPassThroughType>", + "description": "Uses to pass attributes to the nodeToggler's DOM element." + }, + { + "name": "nodeTogglerIcon", + "optional": true, + "readonly": false, + "type": "OrganizationChartPassThroughType | SVGProps>", + "description": "Uses to pass attributes to the nodeTogglerIcon's DOM element." + }, + { + "name": "lines", + "optional": true, + "readonly": false, + "type": "OrganizationChartPassThroughType>", + "description": "Uses to pass attributes to the lines's DOM element." + }, + { + "name": "lineCell", + "optional": true, + "readonly": false, + "type": "OrganizationChartPassThroughType>", + "description": "Uses to pass attributes to the lineCell's DOM element." + }, + { + "name": "lineDown", + "optional": true, + "readonly": false, + "type": "OrganizationChartPassThroughType>", + "description": "Uses to pass attributes to the lineDown's DOM element." + }, + { + "name": "nodes", + "optional": true, + "readonly": false, + "type": "OrganizationChartPassThroughType>", + "description": "Uses to pass attributes to the nodes's DOM element." + }, + { + "name": "nodeCell", + "optional": true, + "readonly": false, + "type": "OrganizationChartPassThroughType>", + "description": "Uses to pass attributes to the nodeCell's DOM element." + } + ], + "callbacks": [] + }, + "OrganizationChartState": { + "description": "Defines current inline state in OrganizationChart component.", + "relatedProp": "", + "props": [ + { + "name": "expanded", + "optional": false, + "readonly": false, + "type": "boolean", + "description": "Current focus expanded of the node as a boolean." + } + ], + "callbacks": [] + }, + "OrganizationChartContext": { + "description": "Defines current options in OrganizationChart component.", + "relatedProp": "", + "props": [ + { + "name": "selected", + "optional": false, + "readonly": false, + "type": "boolean", + "description": "Current selection state of the node as a boolean." + } + ], + "callbacks": [] + }, "OrganizationChartNodeData": { "description": "Custom organizationchart node data.", "relatedProp": "", @@ -29081,6 +29226,14 @@ "callbacks": [] } } + }, + "types": { + "description": "Defines the custom types used by the module.", + "values": { + "OrganizationChartPassThroughType": { + "values": "PassThroughType" + } + } } }, "overlaypanel": { diff --git a/components/doc/organizationchart/pt/ptdoc.js b/components/doc/organizationchart/pt/ptdoc.js new file mode 100644 index 0000000000..91553aa6bb --- /dev/null +++ b/components/doc/organizationchart/pt/ptdoc.js @@ -0,0 +1,189 @@ +import { useState } from 'react'; +import { OrganizationChart } from '../../../lib/organizationchart/OrganizationChart'; +import { DocSectionCode } from '../../common/docsectioncode'; +import { DocSectionText } from '../../common/docsectiontext'; + +export function PTDoc(props) { + const [selection, setSelection] = useState([]); + const [data] = useState([ + { + label: 'Argentina', + expanded: true, + children: [ + { + label: 'Argentina', + expanded: true, + children: [ + { + label: 'Argentina' + }, + { + label: 'Croatia' + } + ] + }, + { + label: 'France', + expanded: true, + children: [ + { + label: 'France' + }, + { + label: 'Morocco' + } + ] + } + ] + } + ]); + + const code = { + basic: ` + setSelection(e.data)} + pt={{ + node: ({ context }) => ({ + className: context.selected ? 'border-orange-400 border-round-sm' : 'border-primary-400 border-round-sm' + }) + }} +/> + `, + javascript: ` +import React, { useState } from 'react'; +import { OrganizationChart } from 'primereact/organizationchart'; + +export default function PTDemo() { + const [selection, setSelection] = useState([]); + const [data] = useState([ + { + label: 'Argentina', + expanded: true, + children: [ + { + label: 'Argentina', + expanded: true, + children: [ + { + label: 'Argentina' + }, + { + label: 'Croatia' + } + ] + }, + { + label: 'France', + expanded: true, + children: [ + { + label: 'France' + }, + { + label: 'Morocco' + } + ] + } + ] + } + ]); + + return ( +
+ setSelection(e.data)} + pt={{ + node: ({ context }) => ({ + className: context.selected ? 'border-orange-400 border-round-sm' : 'border-primary-400 border-round-sm' + }) + }} + /> +
+ ) +} + `, + typescript: ` +import React, { useState } from 'react'; +import { OrganizationChart } from 'primereact/organizationchart'; +import { TreeNode } from 'primereact/treenode'; + +export default function PTDemo() { + const [selection, setSelection] = useState([]); + const [data] = useState([ + { + label: 'Argentina', + expanded: true, + children: [ + { + label: 'Argentina', + expanded: true, + children: [ + { + label: 'Argentina' + }, + { + label: 'Croatia' + } + ] + }, + { + label: 'France', + expanded: true, + children: [ + { + label: 'France' + }, + { + label: 'Morocco' + } + ] + } + ] + } + ]); + + return ( +
+ setSelection(e.data)} + pt={{ + node: ({ context }) => ({ + className: context.selected ? 'border-orange-400 border-round-sm' : 'border-primary-400 border-round-sm' + }) + }} + /> +
+ ) +} + ` + }; + + return ( + <> + +
+ setSelection(e.data)} + pt={{ + node: ({ context }) => ({ + className: context.selected ? 'border-orange-400 border-round-sm' : 'border-primary-400 border-round-sm' + }) + }} + /> +
+ + + ); +} diff --git a/components/doc/organizationchart/pt/wireframe.js b/components/doc/organizationchart/pt/wireframe.js new file mode 100644 index 0000000000..2e0151087f --- /dev/null +++ b/components/doc/organizationchart/pt/wireframe.js @@ -0,0 +1,13 @@ +import React from 'react'; +import { DocSectionText } from '../../common/docsectiontext'; + +export const Wireframe = (props) => { + return ( + <> + +
+ organizationchart +
+ + ); +}; diff --git a/components/lib/organizationchart/OrganizationChart.js b/components/lib/organizationchart/OrganizationChart.js index e9a5fdb58a..8e357184e1 100644 --- a/components/lib/organizationchart/OrganizationChart.js +++ b/components/lib/organizationchart/OrganizationChart.js @@ -1,12 +1,14 @@ import * as React from 'react'; -import { classNames, DomHandler } from '../utils/Utils'; +import { classNames, DomHandler, mergeProps } from '../utils/Utils'; import { OrganizationChartBase } from './OrganizationChartBase'; import { OrganizationChartNode } from './OrganizationChartNode'; export const OrganizationChart = React.memo( React.forwardRef((inProps, ref) => { const props = OrganizationChartBase.getProps(inProps); - + const { ptm } = OrganizationChartBase.setMetaData({ + props + }); const elementRef = React.useRef(null); const root = props.value && props.value.length ? props.value[0] : null; @@ -67,12 +69,22 @@ export const OrganizationChart = React.memo( getElement: () => elementRef.current })); - const otherProps = OrganizationChartBase.getOtherProps(props); const className = classNames('p-organizationchart p-component', props.className); + const rootProps = mergeProps( + { + id: props.id, + ref: elementRef, + style: props.style, + className + }, + OrganizationChartBase.getOtherProps(props), + ptm('root') + ); + return ( -
- +
+
); }) diff --git a/components/lib/organizationchart/OrganizationChartBase.js b/components/lib/organizationchart/OrganizationChartBase.js index b0b9562c81..e4e178359c 100644 --- a/components/lib/organizationchart/OrganizationChartBase.js +++ b/components/lib/organizationchart/OrganizationChartBase.js @@ -1,6 +1,6 @@ -import { ObjectUtils } from '../utils/Utils'; +import { ComponentBase } from '../componentbase/ComponentBase'; -export const OrganizationChartBase = { +export const OrganizationChartBase = ComponentBase.extend({ defaultProps: { __TYPE: 'OrganizationChart', id: null, @@ -15,7 +15,5 @@ export const OrganizationChartBase = { onNodeUnselect: null, togglerIcon: null, children: undefined - }, - getProps: (props) => ObjectUtils.getMergedProps(props, OrganizationChartBase.defaultProps), - getOtherProps: (props) => ObjectUtils.getDiffProps(props, OrganizationChartBase.defaultProps) -}; + } +}); diff --git a/components/lib/organizationchart/OrganizationChartNode.js b/components/lib/organizationchart/OrganizationChartNode.js index 7beb551706..9b4ef8fd68 100644 --- a/components/lib/organizationchart/OrganizationChartNode.js +++ b/components/lib/organizationchart/OrganizationChartNode.js @@ -1,7 +1,7 @@ import * as React from 'react'; -import { classNames, ObjectUtils, IconUtils } from '../utils/Utils'; import { ChevronDownIcon } from '../icons/chevrondown'; import { ChevronUpIcon } from '../icons/chevronup'; +import { IconUtils, ObjectUtils, classNames, mergeProps } from '../utils/Utils'; export const OrganizationChartNode = React.memo((props) => { const node = props.node; @@ -11,6 +11,17 @@ export const OrganizationChartNode = React.memo((props) => { const selected = props.isSelected(node); const visibility = !leaf && expandedState ? 'inherit' : 'hidden'; + const getPTOptions = (key) => { + return props.ptm(key, { + state: { + expanded: expandedState + }, + context: { + selected: props.isSelected(node) + } + }); + }; + const onNodeClick = (event, node) => { props.onNodeClick(event, node); }; @@ -21,13 +32,27 @@ export const OrganizationChartNode = React.memo((props) => { }; const createChildNodes = () => { + const nodesProps = mergeProps( + { + className: 'p-organizationchart-nodes', + style: { visibility } + }, + props.ptm('nodes') + ); + const nodeCellProps = mergeProps( + { + colSpan: '2' + }, + props.ptm('nodeCell') + ); + return ( - + {node.children && node.children.map((child, index) => { return ( - - + + ); })} @@ -37,12 +62,31 @@ export const OrganizationChartNode = React.memo((props) => { const createLinesMiddle = () => { const nodeChildLength = node.children && node.children.length; + const linesProps = mergeProps( + { + className: 'p-organizationchart-lines', + style: { visibility } + }, + props.ptm('lines') + ); + const lineCellProps = mergeProps( + { + colSpan: colspan + }, + props.ptm('lineCell') + ); + const lineDownProps = mergeProps( + { + className: 'p-organizationchart-line-down' + }, + props.ptm('lineDown') + ); return ( - + {node.children && node.children.length === 1 && ( - -
+ +
)} {node.children && @@ -65,10 +109,32 @@ export const OrganizationChartNode = React.memo((props) => { }; const createLinesDown = () => { + const linesProps = mergeProps( + { + className: 'p-organizationchart-lines', + style: { visibility } + }, + props.ptm('lines') + ); + + const lineCellProps = mergeProps( + { + colSpan: colspan + }, + props.ptm('lineCell') + ); + + const lineDownProps = mergeProps( + { + className: 'p-organizationchart-line-down' + }, + props.ptm('lineDown') + ); + return ( - - -
+ + +
); @@ -78,19 +144,35 @@ export const OrganizationChartNode = React.memo((props) => { if (!leaf) { const iconClassName = 'p-node-toggler-icon'; + const nodeTogglerIconProps = mergeProps( + { + className: iconClassName + }, + props.ptm('nodeTogglerIcon') + ); + let icon; if (expandedState) { - icon = props.togglerIcon || ; + icon = props.togglerIcon || ; } else { - icon = props.togglerIcon || ; + icon = props.togglerIcon || ; } - const togglerIcon = IconUtils.getJSXIcon(icon, { className: iconClassName }, { props }); + const togglerIcon = IconUtils.getJSXIcon(icon, { ...nodeTogglerIconProps }, { props }); + + const nodeTogglerProps = mergeProps( + { + className: 'p-node-toggler', + onClick: (e) => toggleNode(e, node), + href: '#' + }, + getPTOptions('nodeToggler') + ); return ( /* eslint-disable */ - toggleNode(e, node)}> + {togglerIcon} /* eslint-enable */ @@ -118,10 +200,26 @@ export const OrganizationChartNode = React.memo((props) => { const label = createNodeLabel(); const toggler = createToggler(); + const cellProps = mergeProps( + { + colSpan: colspan + }, + props.ptm('cell') + ); + + const nodeProps = mergeProps( + { + className: nodeClassName, + style: node.style, + onClick: (e) => onNodeClick(e, node) + }, + getPTOptions('node') + ); + return ( - -
onNodeClick(e, node)}> + +
{label} {toggler}
@@ -135,8 +233,15 @@ export const OrganizationChartNode = React.memo((props) => { const linesMiddle = createLinesMiddle(); const childNodes = createChildNodes(); + const tableProps = mergeProps( + { + className: 'p-organizationchart-table' + }, + props.ptm('table') + ); + return ( - +
{nodeContent} {linesDown} diff --git a/components/lib/organizationchart/organizationchart.d.ts b/components/lib/organizationchart/organizationchart.d.ts index 0131f95a19..0a52d85927 100644 --- a/components/lib/organizationchart/organizationchart.d.ts +++ b/components/lib/organizationchart/organizationchart.d.ts @@ -8,7 +8,89 @@ * */ import * as React from 'react'; -import { IconType } from '../utils/utils'; +import { IconType, PassThroughType } from '../utils/utils'; + +export declare type OrganizationChartPassThroughType = PassThroughType; + +/** + * Custom passthrough(pt) option method. + */ +export interface OrganizationChartPassThroughMethodOptions { + props: OrganizationChartProps; + state: OrganizationChartState; + context: OrganizationChartContext; +} + +/** + * Custom passthrough(pt) options. + * @see {@link OrganizationChartProps.pt} + */ +export interface OrganizationChartPassThroughOptions { + /** + * Uses to pass attributes to the root's DOM element. + */ + root?: OrganizationChartPassThroughType>; + /** + * Uses to pass attributes to the table's DOM element. + */ + table?: OrganizationChartPassThroughType>; + /** + * Uses to pass attributes to the cell's DOM element. + */ + cell?: OrganizationChartPassThroughType>; + /** + * Uses to pass attributes to the node's DOM element. + */ + node?: OrganizationChartPassThroughType>; + /** + * Uses to pass attributes to the nodeToggler's DOM element. + */ + nodeToggler?: OrganizationChartPassThroughType>; + /** + * Uses to pass attributes to the nodeTogglerIcon's DOM element. + */ + nodeTogglerIcon?: OrganizationChartPassThroughType | React.HTMLAttributes>; + /** + * Uses to pass attributes to the lines's DOM element. + */ + lines?: OrganizationChartPassThroughType>; + /** + * Uses to pass attributes to the lineCell's DOM element. + */ + lineCell?: OrganizationChartPassThroughType>; + /** + * Uses to pass attributes to the lineDown's DOM element. + */ + lineDown?: OrganizationChartPassThroughType>; + /** + * Uses to pass attributes to the nodes's DOM element. + */ + nodes?: OrganizationChartPassThroughType>; + /** + * Uses to pass attributes to the nodeCell's DOM element. + */ + nodeCell?: OrganizationChartPassThroughType>; +} + +/** + * Defines current inline state in OrganizationChart component. + */ +export interface OrganizationChartState { + /** + * Current focus expanded of the node as a boolean. + */ + expanded: boolean; +} + +/** + * Defines current options in OrganizationChart component. + */ +export interface OrganizationChartContext { + /** + * Current selection state of the node as a boolean. + */ + selected: boolean; +} /** * Custom node select event. @@ -89,7 +171,7 @@ interface OrganizationChartNodeData { * Defines valid properties in OrganizationChart component. In addition to these, all properties of HTMLDivElement can be used in this component. * @group Properties */ -export interface OrganizationChartProps extends Omit, HTMLDivElement>, 'ref'> { +export interface OrganizationChartProps extends Omit, HTMLDivElement>, 'ref' | 'pt'> { /** * An array of nested TreeNodes. */ @@ -131,6 +213,11 @@ export interface OrganizationChartProps extends Omit { component: AccessibilityDoc } ]; + const ptDocs = [ + { + id: 'pt.wireframe', + label: 'Wireframe', + component: Wireframe + }, + { + id: 'pt.organizationchart.options', + label: 'OrganizationChart PT Options', + component: DocApiTable + }, + { + id: 'pt.demo', + label: 'Example', + component: PTDoc + } + ]; return ( { componentDocs={docs} apiDocs={['OrganizationChart']} className="organizationchart-demo" + ptDocs={ptDocs} /> ); };