All Components

This website hosts native Kendo UI components, built from the ground up with the ultimate performance in mind, intended to be used in the React ecosystem.

Configuration

To perform CSS transitions and animations when a React component enters or exits the DOM, the Animations use the ReactTransitionGroup add-on.

The Animations wrap all components which will be animated and enclose every child element in an AnimationChild component. The AnimationChild component implements the required special life-cycle hooks and each child component is wrapped in an additional div element.

The TransitionGroup component automatically detects the enter and exit state of the children. This means that to animate a child, you only need to add or remove it.

Default Setup

The following example demonstrates how to animate a CONTENT element which is added to the Slide Animation with an entering effect. When CONTENT is removed, the element acquires a special animation effect.

<style>
 .content {
   width: 100px;
   padding: 10px;
   color: #787878;
   background-color: #fcf7f8;
   font-size: 13px;
   font-family: Helvetica, Arial, sans-serif;
   letter-spacing: 1px;
   text-align: center;
   border: 1px solid rgba(0,0,0,.05);
 }
 </style>
class App extends React.Component {
    constructor(props) {
        super(props);

        this.state = { show: true };
    }

    onClick = () => {
        this.setState({
            show: !this.state.show
        });
    }

    render() {
        const { show } = this.state;

        const children = show ? (<div className="content">CONTENT</div>) : null;

        return (
            <div>
                <dl>
                    <dt>
                        Animate:
                    </dt>
                    <dd>
                        <button className="k-button" onClick={this.onClick}>Animate</button>
                    </dd>
                </dl>

                <Slide>
                    {children}
                </Slide>
            </div>
        );
    }
}

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

Animating Elements and Components

The Animations provide options for animating:

Entering Components

To the child component which enters the animation, the Animations set a {transitionName}-enter CSS class. Then, to start the animation, they add a {transitionName}-enter-active CSS class to the child.

The naming convention of the CSS class names is inherited from the TransitionGroup component. For example, the Slide adds a k-slide-down-enter CSS class on enter and, in the next tick, adds a k-slide-down-enter-active to activate the transition.

Exiting Components

To the child component which exits the animation, the Animations set a {transitionName}-exit CSS class. Then, to start the animation, they add a {transitionName}-exit-active CSS class to the child.

The naming convention of the CSS class names is inherited from the TransitionGroup component. For example, the Slide adds a k-slide-down-exit CSS class on exit and, in the next tick, adds a k-slide-down-exit-active to activate the transition.

Exiting components are not available in the DOM. To apply reactive updates to a child which is exiting, use the childFactory function.

Multiple Elements

The enter and exit animation state of multiple elements is automatically controlled by TransitionGroup. This means that whenever you add or remove an item, TransitionGroup detects through its key property which item is updated and then animates it.

const Task = ({ dataItem, onRemove }) => {
    const click = function () {
        onRemove(dataItem);
    };

    const iconProps = {
        className: 'k-i-x k-icon'
    };

    return (
        <div className="k-item k-header">
            <span {...iconProps} onClick={click} />
            {dataItem.name}
        </div>
    );
};

class App extends React.Component {
    itemNameInput = null;

    constructor(props) {
        super(props);

        this.state = {
            tasks: [
                { name: 'John' },
                { name: 'Carrey' },
                { name: 'Joe' },
                { name: 'Doe' },
                { name: 'Chan' },
                { name: 'Chani' },
                { name: 'Bush' }
            ],
            action: ''
        };
    }

    add = () => {
        let tasks = this.state.tasks.slice();

        tasks.push({
            name: this.itemNameInput.value
        });

        this.itemNameInput.value = '';

        this.setState({
            action: 'add',
            tasks: tasks
        });
    }

    remove = (item) => {
        let predicate = function (current) {
            return current !== item;
        };

        this.setState({
            action: 'remove',
            tasks: this.state.tasks.filter(predicate)
        });
    }

    renderTasks() {
        return this.state.tasks.map((task, idx) => (
            <Task key={task.name} dataItem={task} onRemove={this.remove} />
        ));
    }

    render() {
        const tasks = this.renderTasks();

        return (
            <div>
                <fieldset>
                    <input placeholder="Item name..." ref={(input) => this.itemNameInput = input} />
                    <button className="k-button" onClick={this.add}>Add</button>
                </fieldset>
                <Slide direction="right" className="k-list-scroller">
                    {tasks}
                </Slide>
            </div>
        );
    }
}

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