Header & Footer Customization

The KendoReact Scheduler renders a navigation and viewSelector components inside the header and businessHoursToggle component inside footer. Those components provides quick access to the available views and allows for fast date navigation or business-hours toggle.

Currently, only the header and footer components are available for customization. We are actively working on exposing the navigation, viewSelector and businessHoursToggle components.

Importing the default components

The default header is contained in the @progress/kendo-react-scheduler package:

// ES2015 module syntax
import { SchedulerHeader, SchedulerFooter } from '@progress/kendo-react-scheduler';
// CommonJS format
const { SchedulerHeader, SchedulerFooter } = require('@progress/kendo-react-scheduler');

Customization

To customize the header or footer component, provide the corresponding header or footer property to the Scheduler.

The following example demonstrates how to conditionally render the header and footer components, based on user configuration and add additional tools to the footer.

import React from 'react';
import ReactDOM from 'react-dom';
import {
    Scheduler,
    TimelineView,
    DayView,
    WeekView,
    SchedulerHeader,
    SchedulerFooter
} from '@progress/kendo-react-scheduler';
import { ToolbarItem, ToolbarSpacer, ToolbarSeparator } from '@progress/kendo-react-buttons';
import { Switch } from '@progress/kendo-react-inputs';
import { sampleData, displayDate } from './events-utc.js';
import { ToolbarDropdown } from './toolbar-dropdown.jsx'

const SchedulerConfigContext = React.createContext({
    slotDuration: [60],
    slotDivision: [2]
})

const CustomFooter = (props) => {
    const [slotDivision, setSlotDivision] = React.useContext(SchedulerConfigContext).slotDivision;
    const [slotDuration, setSlotDuration] = React.useContext(SchedulerConfigContext).slotDuration;

    const handleDivisionChange = React.useCallback(
        (event) => { setSlotDivision(event.target.value); },
        [setSlotDivision]
    )

    const handleDurationChange = React.useCallback(
        (event) => { setSlotDuration(event.target.value); },
        [setSlotDuration]
    );

    return (
        <SchedulerFooter>
            {props.children}
            <ToolbarSpacer />
            <ToolbarItem>
                <ToolbarDropdown
                    text="Slot Division"
                    value={slotDivision}
                    data={[1, 2, 3, 4]}
                    onChange={handleDivisionChange}
                />
            </ToolbarItem>
            <ToolbarSeparator />
            <ToolbarItem>
                <ToolbarDropdown
                    text="Slot Duration"
                    value={slotDuration}
                    data={[15, 30, 45, 60]}
                    onChange={handleDurationChange}
                />
            </ToolbarItem>
        </SchedulerFooter>
    )
}

const App = () => {
    const [slotDuration, setSlotDuration] = React.useState(60);
    const [slotDivision, setSlotDivision] = React.useState(2);

    const [showHeader, setShowHeader] = React.useState(true);
    const [showFooter, setShowFooter] = React.useState(true);

    const handleHeaderChange = React.useCallback(
        () => { setShowHeader(!showHeader); },
        [setShowHeader, showHeader]
    )

    const handleFooterChange = React.useCallback(
        () => { setShowFooter(!showFooter); },
        [setShowFooter, showFooter]
    )

    return (
        <div>
            <div className="example-config">
                <div className="row">
                    <div className="col-">
                        Header: <Switch defaultChecked={true} onChange={handleHeaderChange} />
                    </div>
                    <div className="col">
                        Footer: <Switch defaultChecked={true} onChange={handleFooterChange} />
                    </div>
                </div>
            </div>
            <SchedulerConfigContext.Provider
                value={{
                    slotDuration: [slotDuration, setSlotDuration],
                    slotDivision: [slotDivision, setSlotDivision]
                }}
            >
                <Scheduler
                    data={sampleData}
                    defaultDate={displayDate}
                    defaultView="week"

                    header={(props) => showHeader ? <SchedulerHeader {...props} /> : <React.Fragment />}
                    footer={(props) => showFooter ? <CustomFooter {...props} /> : <React.Fragment />}
                >
                    <TimelineView slotDivisions={slotDivision} slotDuration={slotDuration} />
                    <DayView slotDivisions={slotDivision} slotDuration={slotDuration} />
                    <WeekView slotDivisions={slotDivision} slotDuration={slotDuration} />
                </Scheduler>
            </SchedulerConfigContext.Provider>
        </div>
    );
};

ReactDOM.render(<App />, document.querySelector('my-app'));