From 9a9c16452b1d70a13fe43e3d845f8b668a28fd37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ula=C5=9F=20Turan?= Date: Tue, 16 May 2023 00:22:36 +0300 Subject: [PATCH] Refactor #4391 - For Dock --- components/doc/common/apidoc/index.json | 112 +++++++++++++++ components/doc/dock/pt/ptdoc.js | 182 ++++++++++++++++++++++++ components/doc/dock/pt/wireframe.js | 15 ++ components/lib/dock/Dock.js | 93 ++++++++++-- components/lib/dock/DockBase.js | 10 +- components/lib/dock/dock.d.ts | 66 +++++++++ pages/dock/index.js | 23 ++- 7 files changed, 482 insertions(+), 19 deletions(-) create mode 100644 components/doc/dock/pt/ptdoc.js create mode 100644 components/doc/dock/pt/wireframe.js diff --git a/components/doc/common/apidoc/index.json b/components/doc/common/apidoc/index.json index e2ca2c8408..636b7b2c00 100644 --- a/components/doc/common/apidoc/index.json +++ b/components/doc/common/apidoc/index.json @@ -14421,6 +14421,14 @@ "type": "ReactNode", "default": "", "description": "Used to get the child elements of the component." + }, + { + "name": "pt", + "optional": true, + "readonly": false, + "type": "DockPassThroughOptions", + "default": "", + "description": "Uses to pass attributes to DOM elements inside the component." } ] }, @@ -14433,6 +14441,102 @@ "interfaces": { "description": "Defines the custom interfaces used by the module.", "values": { + "DockPassThroughMethodOptions": { + "description": "Custom passthrough(pt) option method.", + "relatedProp": "", + "props": [ + { + "name": "props", + "optional": false, + "readonly": false, + "type": "DockProps" + }, + { + "name": "state", + "optional": false, + "readonly": false, + "type": "DockState" + } + ], + "callbacks": [] + }, + "DockPassThroughOptions": { + "description": "Custom passthrough(pt) options.", + "relatedProp": "pt", + "props": [ + { + "name": "root", + "optional": true, + "readonly": false, + "type": "DockPassThroughType>", + "description": "Uses to pass attributes to the root's DOM element." + }, + { + "name": "container", + "optional": true, + "readonly": false, + "type": "DockPassThroughType>", + "description": "Uses to pass attributes to the container's DOM element." + }, + { + "name": "header", + "optional": true, + "readonly": false, + "type": "DockPassThroughType>", + "description": "Uses to pass attributes to the header's DOM element." + }, + { + "name": "footer", + "optional": true, + "readonly": false, + "type": "DockPassThroughType>", + "description": "Uses to pass attributes to the footer's DOM element." + }, + { + "name": "menu", + "optional": true, + "readonly": false, + "type": "DockPassThroughType>", + "description": "Uses to pass attributes to the list's DOM element." + }, + { + "name": "menuitem", + "optional": true, + "readonly": false, + "type": "DockPassThroughType>", + "description": "Uses to pass attributes to the list item's DOM element." + }, + { + "name": "action", + "optional": true, + "readonly": false, + "type": "DockPassThroughType>", + "description": "Uses to pass attributes to the action's DOM element." + }, + { + "name": "icon", + "optional": true, + "readonly": false, + "type": "DockPassThroughType | SVGProps>", + "description": "Uses to pass attributes to the icon's DOM element." + } + ], + "callbacks": [] + }, + "DockState": { + "description": "Defines current inline state in Dock component.", + "relatedProp": "", + "props": [ + { + "name": "currentIndex", + "optional": false, + "readonly": false, + "type": "number", + "description": "Current index as a number." + } + ], + "callbacks": [] + }, "DockHeaderTemplateOptions": { "description": "Custom header template", "relatedProp": "header", @@ -14464,6 +14568,14 @@ "extendedTypes": "DockHeaderTemplateOptions" } } + }, + "types": { + "description": "Defines the custom types used by the module.", + "values": { + "DockPassThroughType": { + "values": "PassThroughType" + } + } } }, "dropdown": { diff --git a/components/doc/dock/pt/ptdoc.js b/components/doc/dock/pt/ptdoc.js new file mode 100644 index 0000000000..efadc294c1 --- /dev/null +++ b/components/doc/dock/pt/ptdoc.js @@ -0,0 +1,182 @@ +import { Dock } from '../../../lib/dock/Dock'; +import { DocSectionCode } from '../../common/docsectioncode'; +import { DocSectionText } from '../../common/docsectiontext'; + +export function PTDoc(props) { + const items = [ + { + label: 'Finder', + icon: () => Finder + }, + { + label: 'App Store', + icon: () => App Store + }, + { + label: 'Photos', + icon: () => Photos + }, + { + label: 'Trash', + icon: () => trash + } + ]; + + const positions = [ + { + label: 'Bottom', + value: 'bottom' + }, + { + label: 'Top', + value: 'top' + }, + { + label: 'Left', + value: 'left' + }, + { + label: 'Right', + value: 'right' + } + ]; + + const code = { + basic: ` + +`, + javascript: ` +import React from 'react'; +import { Dock } from 'primereact/dock'; +import './DockDemo.css'; + +export default function PTDemo() { + const items = [ + { + label: 'Finder', + icon: () => Finder, + }, + { + label: 'App Store', + icon: () => App Store, + }, + { + label: 'Photos', + icon: () => Photos, + }, + { + label: 'Trash', + icon: () => trash, + } + ]; + + return ( +
+
+ +
+
+ ) +} + `, + typescript: ` +import React from 'react'; +import { Dock } from 'primereact/dock'; +import { MenuItem } from 'primereact/menuitem'; +import './DockDemo.css'; + +export default function PTDemo() { + const items: MenuItem[] = [ + { + label: 'Finder', + icon: () => Finder, + }, + { + label: 'App Store', + icon: () => App Store, + }, + { + label: 'Photos', + icon: () => Photos, + }, + { + label: 'Trash', + icon: () => trash, + } + ]; + + return ( +
+
+ +
+
+ ) +} + `, + extFiles: { + 'DockDemo.css': ` +/* DockDemo.css */ +.dock-demo .dock-window { + width: 100%; + height: 450px; + position: relative; + background-image: url('https://primefaces.org/cdn/primereact/images/dock/window.jpg'); + background-repeat: no-repeat; + background-size: cover; +} +.dock-demo .p-dock { + z-index: 1000; +} + ` + } + }; + + return ( + <> + +

+ Menu requires a collection of menuitems as its model. Default location is bottom and other sides are also available when defined with the position property. +

+
+
+
+ +
+
+ + + ); +} diff --git a/components/doc/dock/pt/wireframe.js b/components/doc/dock/pt/wireframe.js new file mode 100644 index 0000000000..2fd759d892 --- /dev/null +++ b/components/doc/dock/pt/wireframe.js @@ -0,0 +1,15 @@ + +import React from 'react'; +import { DocSectionText } from '../../common/docsectiontext'; + +export const Wireframe = (props) => { + + return ( + <> + +
+ dock +
+ + ); +}; diff --git a/components/lib/dock/Dock.js b/components/lib/dock/Dock.js index b37b942fd0..c0f55d17c4 100644 --- a/components/lib/dock/Dock.js +++ b/components/lib/dock/Dock.js @@ -1,6 +1,6 @@ import * as React from 'react'; import { Ripple } from '../ripple/Ripple'; -import { classNames, IconUtils, ObjectUtils } from '../utils/Utils'; +import { classNames, IconUtils, mergeProps, ObjectUtils } from '../utils/Utils'; import { DockBase } from './DockBase'; export const Dock = React.memo( @@ -8,6 +8,12 @@ export const Dock = React.memo( const props = DockBase.getProps(inProps); const [currentIndexState, setCurrentIndexState] = React.useState(-3); + const { ptm } = DockBase.setMetaData({ + props, + state: { + currentIndex: currentIndexState + } + }); const elementRef = React.useRef(null); const onListMouseLeave = () => { @@ -41,10 +47,27 @@ export const Dock = React.memo( }); const contentClassName = classNames('p-dock-action', { 'p-disabled': disabled }); const iconClassName = classNames('p-dock-action-icon', _icon); - const icon = IconUtils.getJSXIcon(_icon, { className: 'p-dock-action-icon' }, { props }); + const iconProps = mergeProps( + { + className: 'p-dock-action-icon' + }, + ptm('icon') + ); + const icon = IconUtils.getJSXIcon(_icon, { ...iconProps }, { props }); + const actionProps = mergeProps( + { + href: url || '#', + role: "menuitem", + className: contentClassName, + target, + 'data-pr-tooltip': label, + onClick: (e) => onItemClick(e, item) + }, + ptm('action') + ); let content = ( - onItemClick(e, item)}> + {icon} @@ -63,8 +86,18 @@ export const Dock = React.memo( content = ObjectUtils.getJSXElement(template, item, defaultContentOptions); } + const menuitemProps = mergeProps( + { + key: index, + className, + role: "none", + onMouseEnter: () => onItemMouseEnter(index) + }, + ptm('menuitem') + ) + return ( -
  • onItemMouseEnter(index)}> +
  • {content}
  • ); @@ -77,8 +110,14 @@ export const Dock = React.memo( const createHeader = () => { if (props.header) { const header = ObjectUtils.getJSXElement(props.header, { props }); - - return
    {header}
    ; + const headerProps = mergeProps( + { + className: "p-dock-header" + }, + ptm('header') + ); + + return
    {header}
    ; } return null; @@ -86,9 +125,17 @@ export const Dock = React.memo( const createList = () => { const items = createItems(); + const menuProps = mergeProps( + { + className: "p-dock-list", + role: "menu", + onMouseLeave: onListMouseLeave + }, + ptm('menu') + ) return ( -
      +
        {items}
      ); @@ -97,8 +144,14 @@ export const Dock = React.memo( const createFooter = () => { if (props.footer) { const footer = ObjectUtils.getJSXElement(props.footer, { props }); - - return
      {footer}
      ; + const footerProps = mergeProps( + { + className: "p-dock-footer" + }, + ptm('footer') + ) + + return
      {footer}
      ; } return null; @@ -109,7 +162,6 @@ export const Dock = React.memo( getElement: () => elementRef.current })); - const otherProps = DockBase.getOtherProps(props); const className = classNames( `p-dock p-component p-dock-${props.position}`, { @@ -120,10 +172,27 @@ export const Dock = React.memo( const header = createHeader(); const list = createList(); const footer = createFooter(); + const rootProps = mergeProps( + { + id: props.id, + ref: elementRef, + className, + style: props.style + }, + DockBase.getOtherProps(props), + ptm('root') + ); + + const containerProps = mergeProps( + { + className: "p-dock-container" + }, + ptm('container') + ); return ( -
      -
      +
      +
      {header} {list} {footer} diff --git a/components/lib/dock/DockBase.js b/components/lib/dock/DockBase.js index d7912bec3b..8cd5abe28d 100644 --- a/components/lib/dock/DockBase.js +++ b/components/lib/dock/DockBase.js @@ -1,6 +1,6 @@ -import { ObjectUtils } from '../utils/Utils'; +import { ComponentBase } from '../componentbase/ComponentBase'; -export const DockBase = { +export const DockBase = ComponentBase.extend({ defaultProps: { __TYPE: 'Dock', id: null, @@ -12,7 +12,5 @@ export const DockBase = { header: null, footer: null, children: undefined - }, - getProps: (props) => ObjectUtils.getMergedProps(props, DockBase.defaultProps), - getOtherProps: (props) => ObjectUtils.getDiffProps(props, DockBase.defaultProps) -}; + } +}); diff --git a/components/lib/dock/dock.d.ts b/components/lib/dock/dock.d.ts index 2bcc6225ec..296816ebaa 100644 --- a/components/lib/dock/dock.d.ts +++ b/components/lib/dock/dock.d.ts @@ -9,6 +9,67 @@ */ import * as React from 'react'; import { MenuItem } from '../menuitem'; +import { PassThroughType } from '../utils/utils'; + +export declare type DockPassThroughType = PassThroughType; + +/** + * Custom passthrough(pt) option method. + */ +export interface DockPassThroughMethodOptions { + props: DockProps; + state: DockState; +} + +/** + * Custom passthrough(pt) options. + * @see {@link DockProps.pt} + */ +export interface DockPassThroughOptions { + /** + * Uses to pass attributes to the root's DOM element. + */ + root?: DockPassThroughType>; + /** + * Uses to pass attributes to the container's DOM element. + */ + container?: DockPassThroughType>; + /** + * Uses to pass attributes to the header's DOM element. + */ + header?: DockPassThroughType>; + /** + * Uses to pass attributes to the footer's DOM element. + */ + footer?: DockPassThroughType>; + /** + * Uses to pass attributes to the list's DOM element. + */ + menu?: DockPassThroughType>; + /** + * Uses to pass attributes to the list item's DOM element. + */ + menuitem?: DockPassThroughType>; + /** + * Uses to pass attributes to the action's DOM element. + */ + action?: DockPassThroughType>; + /** + * Uses to pass attributes to the icon's DOM element. + */ + icon?: DockPassThroughType | React.HTMLAttributes>; +} + +/** + * Defines current inline state in Dock component. + */ +export interface DockState { + /** + * Current index as a number. + * @defaultvalue -3 + */ + currentIndex: number; +} /** * Custom header template @@ -59,6 +120,11 @@ export interface DockProps extends Omit { component: AccessibilityDoc } ]; + const ptDocs = [ + { + id: 'pt.wireframe', + label: 'Wireframe', + component: Wireframe + }, + { + id: 'pt.dock.options', + label: 'Dock PT Options', + component: DocApiTable + }, + { + id: 'pt.demo', + label: 'Example', + component: PTDoc + } + ]; + - return ; + return ; }; export default DockDemo;