Pass Through

The Pass Through props is an API to access the internal DOM Structure of the components.

Each component has a special pt property to define an object with keys corresponding to the available DOM elements. Each value is also an object to define the arbitrary properties to apply to the element such as styling, aria, data-* or custom attributes. Every component documentation has a dedicated section to document the available section names exposed via PT.

Most common usage of pt is styling and customization. The className and style properties support the exact syntax of the corresponding classNames like objects and conditionals. Example below styles a Panel component with PrimeFlex CSS library.

Header

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.


<Panel
    header="Header"
    toggleable
    pt={{
        header: ({ state }) => ({
            id: 'myPanelHeader',
            style: {
                'user-select': 'none'
            },
            className: classNames('border-primary', {
                'bg-primary': state.collapsed,
                'bg-primary-reverse': !state.collapsed
            })
        }),
        content: { className: 'border-primary text-lg text-primary-700' },
        title: 'text-xl', // OR { className: 'text-xl' }
        toggler: 'bg-primary hover:bg-primary-reverse' // OR { className: 'bg-primary hover:bg-primary-reverse' }
    }}
>
    <p className="m-0">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
        consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
</Panel>
         

Lifecycle hooks of components are exposed as pass through using the hooks property so that callback functions can be registered. Available callbacks are useMountEffect, useUpdateEffect, useUnmountEffect. Refer to the React.js documentation for detailed information about lifecycle hooks.


<Panel header="Header" pt={panelPT}>
    Content
</Panel>
         

Defines the shared pass through properties per component type. For example, with the configuration below all panel headers have the bg-primary style class and the all autocomplete components have a fixed width. These settings can be overriden by a particular component as components pt property has higher precedence over global pt.


// _app.js        
import { PrimeReactProvider } from "primereact/api";

export default function GlobalPTDemo() {

    const pt = {
        panel: {
            header: { className: 'bg-primary' }
        },
        autocomplete: {
            input: { root: { className: 'w-16rem' } }
        }
    };

    return(
        <PrimeReactProvider value={{ pt }}>
            <App />
        </PrimeReactProvider>
    )
}
         

The global property has a css option to define custom css that belongs to a global pt configuration. Common use case of this feature is defining global styles and animations related to the pass through props configuration.


// _app.js        
import { PrimeReactProvider } from "primereact/api";

export default function CustomCSSDemo() {

    const pt = {
        global: {
            css: `
                button {
                    padding: 2rem;
                }

                .p-ink {
                    display: block;
                    position: absolute;
                    background: rgba(255, 255, 255, 0.5);
                    border-radius: 100%;
                    transform: scale(0);
                    pointer-events: none;
                }

                .p-ink-active {
                    animation: ripple 0.4s linear;
                }

                @keyframes ripple {
                    100% {
                        opacity: 0;
                        transform: scale(2.5);
                    }
                }
            `
        }
    };

    return(
        <PrimeReactProvider value={{ pt }}>
            <App />
        </PrimeReactProvider>
    )
}
         

An existing pass through configuration is customized with the usePassThrough utility. The first parameter is the object to customize, the second parameter is the customizations and the final parameter is the behavior of merging. One of the example use cases is customizing existing unstyled themes like Tailwind.


import React from 'react'; 
import { PrimeReactProvider } from "primereact/api";
import { usePassThrough } from "primereact/passthrough";
import Tailwind from "primereact/passthrough/tailwind";

export default function UsePassThroughDemo() {

    const CustomTailwind = usePassThrough(
        Tailwind,
        {
            panel: {
                title: {
                    className: 'leading-none font-light text-2xl'
                }
            }
        },
        {
            mergeSections: true,
            mergeProps: false
        }
    );

    return(
        <PrimeReactProvider value={{ unstyled: true, pt: CustomTailwind }}>
            <App />
        </PrimeReactProvider>
    )
}
     

The mergeSections defines whether the sections from the main configuration gets added and the mergeProps controls whether to override or merge the defined props. Defaults are true for mergeSections andfalse for mergeProps.

Some CSS libraries, such as Tailwind, require that class names be merged in a non-conflicting manner. In order to support them a classNameMergeFunction may be passed as part of the ptOptions object to manually define how class names will be merged.


const CustomTailwind = usePassThrough(
    Tailwind,
    {
        panel: {
            header: 'my_panel_header'
        }
    },
    { mergeSections: true, mergeProps: false }
);

// Output: 
// panel.header.className => 'my_panel_header'
// panel.title.className => Tailwind.panel.title.className 

const CustomTailwind = usePassThrough(
    Tailwind,
    {
        panel: {
            header: 'my_panel_header'
        }
    },
    { mergeSections: true, mergeProps: true }
);

// Output: 
// panel.header.className => classNames(Tailwind.panel.header.className, 'my_panel_header')
// panel.title.className => Tailwind.panel.title.className
 

const CustomTailwind = usePassThrough(
    Tailwind,
    {
        panel: {
            header: 'my_panel_header'
        }
    },
    { mergeSections: false, mergeProps: true }
);

// Output: 
// panel.header.className => classNames(Tailwind.panel.header.className, 'my_panel_header')
// panel.title.className => undefined
 

const CustomTailwind = usePassThrough(
    Tailwind,
    {
        panel: {
            header: 'my_panel_header'
        }
    },
    { mergeSections: false, mergeProps: false }
);

// Output: 
// panel.header.className => 'my_panel_header'
// panel.title.className => undefined