# Dialog

*Category:* Components
*Section:* Content
*Source:* https://uikit.developers.rio.cloud/#/components/dialogs
*Captured:* 2026-04-27T14:58:06.852Z

This component allows the user to create a generic modal dialog.

## Dialog

You can create React nodes and pass those as title, body or footer props to the Dialog component.

### Example: Example 1

Dialog Subtitle dialog Long dialog Long dialog with overflow Dialog with overflow and light background Dialog sizes Size xs (320px) Size sm (480px) Size md (768px - default) Size lg (1280px) Size xl (1440px) Size fullwidth Size fullheight Size fullheight lg Size fullheight xl Size fullscreen

#### React (tsx)

```tsx
import { useState } from 'react';

import Button from '@rio-cloud/rio-uikit/Button';
import Dialog from '@rio-cloud/rio-uikit/Dialog';
import Tooltip from '@rio-cloud/rio-uikit/Tooltip';
import OverlayTrigger from '@rio-cloud/rio-uikit/OverlayTrigger';

import { dummyTextExtraLong } from '../../../utils/data';
import { exampleTitle, exampleSubtitle, ExampleBody, exampleFullScreenBody, exampleFooter } from './DialogData';

export default () => {
    const [showDialog, setShowDialog] = useState(false);
    const [showSubtitleDialog, setShowSubtitleDialog] = useState(false);
    const [showLongDialog, setShowLongDialog] = useState(false);
    const [showLongOverflowDialog, setShowLongOverflowDialog] = useState(false);
    const [showLongOverflow2Dialog, setShowLongOverflow2Dialog] = useState(false);
    const [showSizeXSDialog, setShowSizeXSDialog] = useState(false);
    const [showSizeSMDialog, setShowSizeSMDialog] = useState(false);
    const [showSizeLGDialog, setShowSizeLGDialog] = useState(false);
    const [showSizeXLDialog, setShowSizeXLDialog] = useState(false);
    const [showSizeFullWidthDialog, setShowSizeFullWidthDialog] = useState(false);
    const [showSizeFullHeightDialog, setShowSizeFullHeightDialog] = useState(false);
    const [showSizeFullHeightLGDialog, setShowSizeFullHeightLGDialog] = useState(false);
    const [showSizeFullHeightXLDialog, setShowSizeFullHeightXLDialog] = useState(false);
    const [showSizeFullScreenDialog, setShowSizeFullScreenDialog] = useState(false);

    const renderDialog = () => {
        const onClose = () => setShowDialog(false);

        const headerButtons = (
            <>
                <OverlayTrigger placement='bottom' overlay={<Tooltip width='auto'>Download</Tooltip>}>
                    <Button bsStyle='muted' iconOnly iconName='rioglyph-cloud-download' />
                </OverlayTrigger>
                <OverlayTrigger placement='bottom' overlay={<Tooltip width='auto'>More options</Tooltip>}>
                    <Button bsStyle='muted' iconOnly iconName='rioglyph-option-horizontal' />
                </OverlayTrigger>
            </>
        );

        return (
            <Dialog
                show={showDialog}
                title={exampleTitle}
                footer={exampleFooter(onClose)}
                body={<ExampleBody />}
                headerButtons={headerButtons}
                onClose={onClose}
                className='exampleDialog'
                showCloseButton
                bsSize='md'
            />
        );
    };

    const renderSubtitleDialog = () => (
        <Dialog
            show={showSubtitleDialog}
            title={exampleTitle}
            subtitle={exampleSubtitle}
            footer={exampleFooter(() => setShowSubtitleDialog(false))}
            body={<ExampleBody />}
            onClose={() => setShowSubtitleDialog(false)}
            bodyClassName='exampleDialog'
            showCloseButton
        />
    );

    const renderLongDialog = () => (
        <Dialog
            show={showLongDialog}
            title={exampleTitle}
            body={dummyTextExtraLong}
            footer={exampleFooter(() => setShowLongDialog(false))}
            onClose={() => setShowLongDialog(false)}
            className='longExampleDialog'
            showCloseButton
        />
    );

    const renderLongOverflowDialog = () => (
        <Dialog
            show={showLongOverflowDialog}
            title={exampleTitle}
            body={dummyTextExtraLong}
            footer={exampleFooter(() => setShowLongOverflowDialog(false))}
            onClose={() => setShowLongOverflowDialog(false)}
            className='longExampleDialog'
            showCloseButton
            useOverflow
        />
    );

    const renderLongOverflow2Dialog = () => (
        <Dialog
            show={showLongOverflow2Dialog}
            title={exampleTitle}
            body={dummyTextExtraLong}
            bodyClassName='no-overflow-gradient bg-lightest'
            footerClassName='shadow-smooth-up'
            footer={exampleFooter(() => setShowLongOverflow2Dialog(false))}
            onClose={() => setShowLongOverflow2Dialog(false)}
            className='longExample2Dialog'
            showCloseButton
            useOverflow
        />
    );

    const renderSizeXSDialog = () => (
        <Dialog
            show={showSizeXSDialog}
            title='The smallest dialog'
            footer={
                <div className='display-flex justify-content-end'>
                    <Button bsStyle='primary' onClick={() => setShowSizeXSDialog(false)}>
                        Ok
                    </Button>
                </div>
            }
            body="This is our smallest dialog. Please treat it lightly and don't scare him"
            bsSize={Dialog.SIZE_XS}
            onClose={() => setShowSizeXSDialog(false)}
        />
    );

    const renderSizeSMDialog = () => (
        <Dialog
            show={showSizeSMDialog}
            title={exampleTitle}
            footer={exampleFooter(() => setShowSizeSMDialog(false))}
            body={<ExampleBody />}
            bsSize={Dialog.SIZE_SM}
            onClose={() => setShowSizeSMDialog(false)}
            className='exampleDialog'
            showCloseButton
        />
    );

    const renderSizeLGDialog = () => (
        <Dialog
            show={showSizeLGDialog}
            title={exampleTitle}
            footer={exampleFooter(() => setShowSizeLGDialog(false))}
            body={<ExampleBody />}
            bsSize={Dialog.SIZE_LG}
            onClose={() => setShowSizeLGDialog(false)}
            className='exampleDialog'
            showCloseButton
        />
    );

    const renderSizeXLDialog = () => (
        <Dialog
            show={showSizeXLDialog}
            title={exampleTitle}
            footer={exampleFooter(() => setShowSizeXLDialog(false))}
            body={<ExampleBody />}
            bsSize={Dialog.SIZE_XL}
            onClose={() => setShowSizeXLDialog(false)}
            className='exampleDialog'
            showCloseButton
        />
    );

    const renderSizeFullWidthDialog = () => (
        <Dialog
            show={showSizeFullWidthDialog}
            title={exampleTitle}
            footer={exampleFooter(() => setShowSizeFullWidthDialog(false))}
            body={<ExampleBody />}
            bsSize={Dialog.SIZE_FULL_WIDTH}
            onClose={() => setShowSizeFullWidthDialog(false)}
            className='exampleDialog'
            showCloseButton
        />
    );

    const renderSizeFullHeightDialog = () => (
        <Dialog
            show={showSizeFullHeightDialog}
            title={exampleTitle}
            footer={exampleFooter(() => setShowSizeFullHeightDialog(false))}
            body={<ExampleBody />}
            bsSize={Dialog.SIZE_FULL_HEIGHT}
            onClose={() => setShowSizeFullHeightDialog(false)}
            className='exampleDialog'
            showCloseButton
        />
    );

    const renderSizeFullHeightLGDialog = () => (
        <Dialog
            show={showSizeFullHeightLGDialog}
            title={exampleTitle}
            footer={exampleFooter(() => setShowSizeFullHeightLGDialog(false))}
            body={<ExampleBody />}
            bsSize={Dialog.SIZE_FULL_HEIGHT_LG}
            onClose={() => setShowSizeFullHeightLGDialog(false)}
            className='foobar'
            showCloseButton
        />
    );

    const renderSizeFullHeightXLDialog = () => (
        <Dialog
            show={showSizeFullHeightXLDialog}
            title={exampleTitle}
            footer={exampleFooter(() => setShowSizeFullHeightXLDialog(false))}
            body={<ExampleBody />}
            bsSize={Dialog.SIZE_FULL_HEIGHT_XL}
            onClose={() => setShowSizeFullHeightXLDialog(false)}
            showCloseButton
        />
    );

    const renderSizeFullScreenDialog = () => (
        <Dialog
            show={showSizeFullScreenDialog}
            title={exampleTitle}
            body={exampleFullScreenBody}
            footer={exampleFooter(() => setShowSizeFullScreenDialog(false))}
            className='exampleDialog'
            bodyClassName='padding-0'
            bsSize={Dialog.SIZE_FULL_SCREEN}
            onClose={() => setShowSizeFullScreenDialog(false)}
            showCloseButton
        />
    );

    return (
        <div>
            <div className='btn-toolbar margin-bottom-20'>
                <Button bsStyle='primary' onClick={() => setShowDialog(true)}>
                    Dialog
                </Button>
                {renderDialog()}

                <Button bsStyle='primary' onClick={() => setShowSubtitleDialog(true)}>
                    Subtitle dialog
                </Button>
                {renderSubtitleDialog()}

                <Button bsStyle='primary' onClick={() => setShowLongDialog(true)}>
                    Long dialog
                </Button>
                {renderLongDialog()}

                <Button bsStyle='primary' onClick={() => setShowLongOverflowDialog(true)}>
                    Long dialog with overflow
                </Button>
                {renderLongOverflowDialog()}

                <Button bsStyle='primary' onClick={() => setShowLongOverflow2Dialog(true)}>
                    Dialog with overflow and light background
                </Button>
                {renderLongOverflow2Dialog()}
            </div>

            <label>Dialog sizes</label>
            <div className='btn-toolbar'>
                <Button bsStyle='primary' onClick={() => setShowSizeXSDialog(true)}>
                    Size xs (320px)
                </Button>
                {renderSizeXSDialog()}

                <Button bsStyle='primary' onClick={() => setShowSizeSMDialog(true)}>
                    Size sm (480px)
                </Button>
                {renderSizeSMDialog()}

                <Button bsStyle='primary' onClick={() => setShowDialog(true)}>
                    Size md (768px - default)
                </Button>
                <Button type='button' bsStyle='primary' onClick={() => setShowSizeLGDialog(true)}>
                    Size lg (1280px)
                </Button>
                {renderSizeLGDialog()}

                <Button bsStyle='primary' onClick={() => setShowSizeXLDialog(true)}>
                    Size xl (1440px)
                </Button>
                {renderSizeXLDialog()}

                <Button bsStyle='primary' onClick={() => setShowSizeFullWidthDialog(true)}>
                    Size fullwidth
                </Button>
                {renderSizeFullWidthDialog()}

                <Button bsStyle='primary' onClick={() => setShowSizeFullHeightDialog(true)}>
                    Size fullheight
                </Button>
                {renderSizeFullHeightDialog()}

                <Button bsStyle='primary' onClick={() => setShowSizeFullHeightLGDialog(true)}>
                    Size fullheight lg
                </Button>
                {renderSizeFullHeightLGDialog()}

                <Button bsStyle='primary' onClick={() => setShowSizeFullHeightXLDialog(true)}>
                    Size fullheight xl
                </Button>
                {renderSizeFullHeightXLDialog()}

                <Button bsStyle='primary' onClick={() => setShowSizeFullScreenDialog(true)}>
                    Size fullscreen
                </Button>
                {renderSizeFullScreenDialog()}
            </div>
        </div>
    );
};
```

#### HTML (html)

```html
<div class='modal show exampleDialog modal-enter-done' tabindex='1' role='dialog'>
<div class='modal-dialog' role='document'>
    <div class='modal-content'>
        <div class='modal-header'>
            <div class='modal-header-text'>
                <div class='modal-header-title'>Dialog title</div>
            </div>
            <div class='modal-header-buttons'>
                <button type='button' class='btn btn-muted btn-icon-only'>
                    <span class='rioglyph rioglyph-cloud-download'></span>
                </button>
                <button type='button' class='btn btn-muted btn-icon-only'>
                    <span class='rioglyph rioglyph-option-horizontal'></span>
                </button>
                <div class='modal-header-buttons-spacer'></div>
                <button
                    type='button'
                    class='btn btn-icon-only btn-muted modal-header-close close'
                    data-testid='close'
                >
                    <span class='rioglyph rioglyph-remove' aria-hidden='true'></span>
                </button>
            </div>
        </div>
        <div class='modal-body'>
            {/* Body Content */}
        </div>
        <div class='modal-footer'>
            {/* Footer Content */}
        </div>
    </div>
</div>
<div class='modal-backdrop'></div>
</div>
```

#### Props: Base dialog props

### Base dialog props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| show | boolean | false | Opens the dialog when set to true. |
| title | React.ReactNode | — | The dialog title (can also be a FormattedMessage component). |
| subtitle | React.ReactNode | — | The dialog header subtitle content. |
| showCloseButton | boolean | true | Shows a close button when set to true. |
| onClose | () => void | — | A callback function invoked when the dialog closes. |
| bsSize | DialogSize | 'md' | Defined how large the dialog will be rendered. By default, the dialog has a medium size, and thus it can be omitted. Possible values are: 'xs' 'sm' 'lg' 'xl' 'fullwidth' 'fullheight' 'fullheight-lg' 'fullheight-xl' 'fullscreen' |
| disableEsc | boolean | false | Enables or disabled closing the dialog via esc key. |
| useOverflow | boolean | false | Enables the modal body to overflow and use inline scrolling if needed. |
| showXsDialogBorders | boolean | false | Show Header and Footer Borders for the "xs" dialog |
| className | string | — | Additional classes for the modal element. |

#### Props: Dialog

### Dialog

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| body | React.ReactNode | — | The dialog body content. |
| footer | React.ReactNode | — | The dialog body content. |
| bodyClassName | string | — | Additional classes for the modal-body element. |
| footerClassName | string | — | Additional classes for the modal-footer element. |
| headerButtons | React.ReactNode | — | Allows to add additional buttons to the dialog header. |
| onEsc | VoidFunction | — | A callback fired when esc key is pressed and the dialog is about to close. |
| onCloseValidation | () => boolean | () => true | A callback function to be executed before closing the dialog. If the function returns false, the dialog will not be closed |

## Dialog compound components

To accommodate forms within the dialog body and have the submit button in the footer or wrapping individual parts of the dialog, a more flexible approach to rendering its individual components is needed. In this scenario, you can make use of the dialog compound components.

### Example: Example 2

Dialog with form

#### React (tsx)

```tsx
import { useState } from 'react';

import Button from '@rio-cloud/rio-uikit/Button';
import Dialog from '@rio-cloud/rio-uikit/Dialog';

import { exampleTitle } from './DialogData';

export default () => {
    const [showDialog, setShowDialog] = useState(false);
    const [enableSubmit, setEnableSubmit] = useState(false);
    const [submittedFormData, setSubmittedFormData] = useState<{ [k: string]: FormDataEntryValue } | undefined>();

    const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
        // Avoid page reload on form submit
        event.preventDefault();

        // Get form data of all input elements
        const formData = new FormData(event.target as HTMLFormElement);

        // Convert all form data into an object for further use
        const entries = Object.fromEntries(formData.entries());
        setSubmittedFormData(entries);

        // Individual debug output of the form inputs
        for (const [key, value] of formData) {
            console.log({ key, value });
        }
    };

    const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
        setEnableSubmit(Boolean(event.currentTarget.value));
    };

    const handleClose = () => {
        setShowDialog(false);
        setSubmittedFormData(undefined);
    };

    return (
        <div>
            <div className='btn-toolbar margin-bottom-20'>
                <Button bsStyle='primary' onClick={() => setShowDialog(true)}>
                    Dialog with form
                </Button>
                <Dialog show={showDialog} onClose={handleClose} showCloseButton bsSize='md'>
                    <form onSubmit={handleSubmit}>
                        <Dialog.Title
                            title={exampleTitle}
                            subtitle='This is a subtitle'
                            headerButtons={<Button bsStyle='muted' iconOnly iconName='rioglyph-cloud-download' />}
                        />
                        <Dialog.Body className='foo'>
                            <div>
                                <div className='form-group'>
                                    <label htmlFor='demoInput'>Some random input to submit (required)</label>
                                    <input
                                        className='form-control'
                                        name='demoInput'
                                        placeholder='Please add something to continue'
                                        onChange={handleInputChange}
                                        required
                                    />
                                </div>
                                <div className='text-italic margin-top-25'>{JSON.stringify(submittedFormData)}</div>
                            </div>
                        </Dialog.Body>
                        <Dialog.Footer className='foobar'>
                            <div>
                                <Button bsStyle='primary' type='submit' disabled={!enableSubmit}>
                                    Submit
                                </Button>
                            </div>
                        </Dialog.Footer>
                    </form>
                </Dialog>
            </div>
        </div>
    );
};
```

#### HTML (html)

```html
<div class='modal show exampleDialog modal-enter-done' tabindex='1' role='dialog'>
<div class='modal-dialog' role='document'>
    <div class='modal-content'>
        <div class='modal-header'>
            <div class='modal-header-text'>
                <div class='modal-header-title'>Dialog title</div>
            </div>
            <div class='modal-header-buttons'>
                <button type='button' class='btn btn-muted btn-icon-only'>
                    <span class='rioglyph rioglyph-cloud-download'></span>
                </button>
                <button type='button' class='btn btn-muted btn-icon-only'>
                    <span class='rioglyph rioglyph-option-horizontal'></span>
                </button>
                <div class='modal-header-buttons-spacer'></div>
                <button
                    type='button'
                    class='btn btn-icon-only btn-muted modal-header-close close'
                    data-testid='close'
                >
                    <span class='rioglyph rioglyph-remove' aria-hidden='true'></span>
                </button>
            </div>
        </div>
        <div class='modal-body'>
            {/* Body Content */}
        </div>
        <div class='modal-footer'>
            {/* Footer Content */}
        </div>
    </div>
</div>
<div class='modal-backdrop'></div>
</div>
```

#### Props: Dialog.Title

### Dialog.Title

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| title | string \| React.ReactNode | — | The dialog title (can also be a FormattedMessage component). |
| subtitle | string \| React.ReactNode | — | The dialog header subtitle content. |
| headerButtons | React.ReactNode | — | Allows to add additional buttons to the dialog header. |
| onCloseButtonClick | () => void | — | — |

#### Props: Dialog.Body

### Dialog.Body

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| className | string | — | Additional classes for the modal-body element. |

#### Props: Dialog.Footer

### Dialog.Footer

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| className | string | — | Additional classes for the modal-footer element. |

## Dialogs with validation

### Example: Example 3

Open dialog

#### React (tsx)

```tsx
import type React from 'react';
import { useEffect, useRef, useState } from 'react';

import Dialog from '@rio-cloud/rio-uikit/Dialog';
import Button from '@rio-cloud/rio-uikit/Button';

type DemoContentProps = {
    inputValue: string;
    showError: boolean;
    onInputChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
};

const DemoContent = (props: DemoContentProps) => {
    const { inputValue, showError, onInputChange } = props;

    // Set the focus on the input.
    // Note: the dialog body need to be in the component that re-renders,
    // otherwise the focus is not set initially.
    const inputRef = useRef<HTMLInputElement>(null);
    useEffect(() => {
        if (inputRef.current) {
            console.log('focus input');
            inputRef.current.focus();
        }
    }, [inputRef.current]);

    return (
        <div className={`form-group has-feedback ${showError ? 'has-error' : ''} margin-bottom-15`}>
            <label htmlFor='input'>Some input</label>
            <div className='input-group'>
                <input
                    className='form-control'
                    value={inputValue}
                    id='input'
                    type='text'
                    placeholder='Please type in something'
                    onChange={onInputChange}
                    ref={inputRef}
                />
            </div>
            {showError && (
                <span className='help-block'>
                    <span>Please enter something</span>
                </span>
            )}
        </div>
    );
};

export default () => {
    const [state, setState] = useState({
        showDialog: false,
        hasError: false,
        inputValue: '',
    });

    const handleValidation = () => {
        if (!state.inputValue) {
            setState({ ...state, hasError: true });
            return false;
        }
        return true;
    };

    const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
        const inputValue = event.currentTarget.value;
        setState({ ...state, inputValue, hasError: !inputValue });
    };

    return (
        <>
            <Button bsStyle='primary' onClick={() => setState({ ...state, showDialog: true })}>
                Open dialog
            </Button>
            <Dialog
                show={state.showDialog}
                title='Dialog with validation example'
                body={
                    <DemoContent
                        inputValue={state.inputValue}
                        showError={state.hasError}
                        onInputChange={handleInputChange}
                    />
                }
                onClose={() => setState({ ...state, showDialog: false, inputValue: '' })}
                onCloseValidation={handleValidation}
            />
        </>
    );
};
```

#### HTML (html)

```html
<button type="button" class="btn btn-primary btn-component" tabindex="0">Open dialog</button>
```

#### Props: Base dialog props

### Base dialog props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| show | boolean | false | Opens the dialog when set to true. |
| title | React.ReactNode | — | The dialog title (can also be a FormattedMessage component). |
| subtitle | React.ReactNode | — | The dialog header subtitle content. |
| showCloseButton | boolean | true | Shows a close button when set to true. |
| onClose | () => void | — | A callback function invoked when the dialog closes. |
| bsSize | DialogSize | 'md' | Defined how large the dialog will be rendered. By default, the dialog has a medium size, and thus it can be omitted. Possible values are: 'xs' 'sm' 'lg' 'xl' 'fullwidth' 'fullheight' 'fullheight-lg' 'fullheight-xl' 'fullscreen' |
| disableEsc | boolean | false | Enables or disabled closing the dialog via esc key. |
| useOverflow | boolean | false | Enables the modal body to overflow and use inline scrolling if needed. |
| showXsDialogBorders | boolean | false | Show Header and Footer Borders for the "xs" dialog |
| className | string | — | Additional classes for the modal element. |

#### Props: Dialog

### Dialog

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| body | React.ReactNode | — | The dialog body content. |
| footer | React.ReactNode | — | The dialog body content. |
| bodyClassName | string | — | Additional classes for the modal-body element. |
| footerClassName | string | — | Additional classes for the modal-footer element. |
| headerButtons | React.ReactNode | — | Allows to add additional buttons to the dialog header. |
| onEsc | VoidFunction | — | A callback fired when esc key is pressed and the dialog is about to close. |
| onCloseValidation | () => boolean | () => true | A callback function to be executed before closing the dialog. If the function returns false, the dialog will not be closed |

### Example: Example 4

Validation with separate validation error dialog Open dialog

#### React (tsx)

```tsx
import type React from 'react';
import { useState, useRef, useEffect } from 'react';

import Dialog from '@rio-cloud/rio-uikit/Dialog';
import SimpleDialog from '@rio-cloud/rio-uikit/SimpleDialog';
import Button from '@rio-cloud/rio-uikit/Button';

type DemoContentProps = {
    inputRef: React.MutableRefObject<HTMLInputElement>;
    inputValue: string;
    showError: boolean;
    onInputChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
};

const DemoContent = (props: DemoContentProps) => {
    const { inputRef, inputValue, showError, onInputChange } = props;

    // Set the focus on the input.
    // Note: the dialog body need to be in the component that re-renders,
    // otherwise the focus is not set initially.
    useEffect(() => {
        if (inputRef.current) {
            console.log('focus input');
            inputRef.current.focus();
        }
    }, [inputRef.current]);

    return (
        <div className={`form-group has-feedback ${showError ? 'has-error' : ''} margin-bottom-15`}>
            <label htmlFor='input'>Some input</label>
            <div className='input-group'>
                <input
                    className='form-control'
                    value={inputValue}
                    id='input'
                    type='text'
                    placeholder='Please type in something'
                    onChange={onInputChange}
                    ref={inputRef}
                />
            </div>
            {showError && (
                <span className='help-block'>
                    <span>Please enter something</span>
                </span>
            )}
        </div>
    );
};

export default () => {
    const [state, setState] = useState({
        showDialog: false,
        hasError: false,
        showErrorDialog: false,
        inputValue: '',
    });

    const inputRef = useRef<HTMLInputElement>(null);

    const handleValidation = () => {
        if (!state.inputValue) {
            setState({ ...state, hasError: true, showErrorDialog: true });
            return false;
        }
        return true;
    };

    const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
        const inputValue = event.currentTarget.value;
        setState({ ...state, inputValue, hasError: !inputValue });
    };

    const handleCloseErrorDialog = () => {
        setState({ ...state, showErrorDialog: false });
        inputRef?.current?.focus();
    };

    const handleClose = () => {
        handleValidation() && setState({ ...state, showDialog: false, inputValue: '' });
    };

    const showError = state.hasError && !state.showErrorDialog;

    return (
        <>
            <div>
                <label>Validation with separate validation error dialog</label>
            </div>
            <Button bsStyle='primary' onClick={() => setState({ ...state, showDialog: true })}>
                Open dialog
            </Button>

            <Dialog
                show={state.showDialog}
                title='Dialog with validation example'
                body={
                    <DemoContent
                        inputRef={inputRef}
                        inputValue={state.inputValue}
                        showError={showError}
                        onInputChange={handleInputChange}
                    />
                }
                footer={
                    <Button bsStyle='primary' onClick={handleClose}>
                        Close
                    </Button>
                }
                onClose={handleClose}
                onCloseValidation={handleValidation}
            />
            <SimpleDialog
                show={state.showErrorDialog}
                bsSize='xs'
                title='Validation failed'
                content='Input may not be empty. Please enter some value.'
                footer={
                    <Button bsStyle='primary' onClick={handleCloseErrorDialog}>
                        Got it
                    </Button>
                }
            />
        </>
    );
};
```

#### HTML (html)

```html
<div>
    <label>Validation with separate validation error dialog</label>
</div>
<button type="button" class="btn btn-primary btn-component" tabindex="0">Open dialog</button>
```

#### Props: Base dialog props

### Base dialog props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| show | boolean | false | Opens the dialog when set to true. |
| title | React.ReactNode | — | The dialog title (can also be a FormattedMessage component). |
| subtitle | React.ReactNode | — | The dialog header subtitle content. |
| showCloseButton | boolean | true | Shows a close button when set to true. |
| onClose | () => void | — | A callback function invoked when the dialog closes. |
| bsSize | DialogSize | 'md' | Defined how large the dialog will be rendered. By default, the dialog has a medium size, and thus it can be omitted. Possible values are: 'xs' 'sm' 'lg' 'xl' 'fullwidth' 'fullheight' 'fullheight-lg' 'fullheight-xl' 'fullscreen' |
| disableEsc | boolean | false | Enables or disabled closing the dialog via esc key. |
| useOverflow | boolean | false | Enables the modal body to overflow and use inline scrolling if needed. |
| showXsDialogBorders | boolean | false | Show Header and Footer Borders for the "xs" dialog |
| className | string | — | Additional classes for the modal element. |

#### Props: Dialog

### Dialog

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| body | React.ReactNode | — | The dialog body content. |
| footer | React.ReactNode | — | The dialog body content. |
| bodyClassName | string | — | Additional classes for the modal-body element. |
| footerClassName | string | — | Additional classes for the modal-footer element. |
| headerButtons | React.ReactNode | — | Allows to add additional buttons to the dialog header. |
| onEsc | VoidFunction | — | A callback fired when esc key is pressed and the dialog is about to close. |
| onCloseValidation | () => boolean | () => true | A callback function to be executed before closing the dialog. If the function returns false, the dialog will not be closed |

## SimpleDialog

This component allows the user to create a simple dialog. It uses the dialog component described above.

### Example: Example 5

Simple dialog button

#### React (tsx)

```tsx
import { useState } from 'react';

import Button from '@rio-cloud/rio-uikit/Button';
import SimpleDialog from '@rio-cloud/rio-uikit/SimpleDialog';

export default () => {
    const [show, setShow] = useState(false);

    return (
        <>
            <Button bsStyle='primary' onClick={() => setShow(true)}>
                Simple dialog button
            </Button>
            <SimpleDialog
                show={show}
                title='Simple dialog title'
                content='Simple dialog body content'
                bodyClassName='my-content'
                onClose={() => setShow(false)}
            />
        </>
    );
};
```

#### HTML (html)

```html
<div content='Save Dialog Body Content' class='modal show simple-dialog modal-enter-done' tabindex='1' role='dialog'>
<div class='modal-dialog' role='document'>
    <div class='modal-content'>
        <div class='modal-header'>
            <div class='modal-header-text'>
                <div class='modal-header-title'>Save Dialog Title</div>
            </div>
            <div class='modal-header-buttons'>
                <button
                    type='button'
                    class='btn btn-icon-only btn-muted modal-header-close close'
                    data-testid='close'
                >
                    <span class='rioglyph rioglyph-remove' aria-hidden='true'></span>
                </button>
            </div>
        </div>
        <div class='modal-body'>Save Dialog Body Content</div>
    </div>
</div>
<div class='modal-backdrop'></div>
</div>;
```

#### Props: Base dialog props

### Base dialog props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| show | boolean | false | Opens the dialog when set to true. |
| title | React.ReactNode | — | The dialog title (can also be a FormattedMessage component). |
| subtitle | React.ReactNode | — | The dialog header subtitle content. |
| showCloseButton | boolean | true | Shows a close button when set to true. |
| onClose | () => void | — | A callback function invoked when the dialog closes. |
| bsSize | DialogSize | 'md' | Defined how large the dialog will be rendered. By default, the dialog has a medium size, and thus it can be omitted. Possible values are: 'xs' 'sm' 'lg' 'xl' 'fullwidth' 'fullheight' 'fullheight-lg' 'fullheight-xl' 'fullscreen' |
| disableEsc | boolean | false | Enables or disabled closing the dialog via esc key. |
| useOverflow | boolean | false | Enables the modal body to overflow and use inline scrolling if needed. |
| showXsDialogBorders | boolean | false | Show Header and Footer Borders for the "xs" dialog |
| className | string | — | Additional classes for the modal element. |

#### Props: SimpleDialog

### SimpleDialog

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| content | string \| React.ReactNode | — | The content of the dialog body itself. |

## ConfirmationDialog

This component allows the user to create a confirmation dialog. It uses the dialog component described above.

### Example: Example 6

Confirmation dialog

#### React (tsx)

```tsx
import { useState } from 'react';

import Dialog from '@rio-cloud/rio-uikit/Dialog';
import ConfirmationDialog from '@rio-cloud/rio-uikit/ConfirmationDialog';

export default () => {
    const [show, setShow] = useState(false);

    return (
        <div>
            <button type='button' className='btn btn-primary' onClick={() => setShow(true)}>
                Confirmation dialog
            </button>
            <ConfirmationDialog
                show={show}
                title='ConfirmationDialog title'
                content='ConfirmationDialog body content'
                bsSize={Dialog.SIZE_SM}
                onClickConfirm={() => setShow(false)}
                onClickCancel={() => setShow(false)}
                cancelButtonText='Abort the action'
                confirmButtonText={
                    <>
                        <span className='rioglyph rioglyph-ok margin-right-5' />
                        <span>Confirm the action</span>
                    </>
                }
                useOverflow
            />
        </div>
    );
};
```

#### HTML (html)

```html
<div class='modal show confirmation-dialog modal-enter-done' tabindex='1' role='dialog'>
<div class='modal-dialog modal-overflow modal-sm' role='document'>
    <div class='modal-content'>
        <div class='modal-header'>
            <div class='modal-header-text'>
                <div class='modal-header-title'>Confirmation dialog title</div>
            </div>
            <div class='modal-header-buttons'></div>
        </div>
        <div class='modal-body'>Confirmation dialog body content</div>
        <div class='modal-footer'>
            <div class='btn-toolbar'>
                <button type='button' class='CancelButton btn btn-default'>
                    Abort the action
                </button>
                <button type='button' class='ConfirmationButton btn btn-primary'>
                    Confirm the action
                </button>
            </div>
        </div>
    </div>
</div>
<div class='modal-backdrop'></div>
</div>;
```

#### Props: Base dialog props

### Base dialog props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| show | boolean | false | Opens the dialog when set to true. |
| title | React.ReactNode | — | The dialog title (can also be a FormattedMessage component). |
| subtitle | React.ReactNode | — | The dialog header subtitle content. |
| showCloseButton | boolean | true | Shows a close button when set to true. |
| onClose | () => void | — | A callback function invoked when the dialog closes. |
| bsSize | DialogSize | 'md' | Defined how large the dialog will be rendered. By default, the dialog has a medium size, and thus it can be omitted. Possible values are: 'xs' 'sm' 'lg' 'xl' 'fullwidth' 'fullheight' 'fullheight-lg' 'fullheight-xl' 'fullscreen' |
| disableEsc | boolean | false | Enables or disabled closing the dialog via esc key. |
| useOverflow | boolean | false | Enables the modal body to overflow and use inline scrolling if needed. |
| showXsDialogBorders | boolean | false | Show Header and Footer Borders for the "xs" dialog |
| className | string | — | Additional classes for the modal element. |

#### Props: ConfirmationDialog

### ConfirmationDialog

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| content | string \| React.ReactNode | — | The content of the dialog body itself |
| onClickConfirm | VoidFunction | () => {} | A callback fired when the confirmation button is clicked. |
| onClickCancel | VoidFunction | () => {} | A callback fired when the cancel button is clicked or the dialog is closed. |
| cancelButtonText | string \| React.ReactNode | — | The content of the cancel button. (Usually a text, can also be a FormattedMessage component). |
| confirmButtonText | string \| React.ReactNode | — | The content of the confirmation button. Since it is a node, it can be a simple text or any JSX node like a div element with an icon and a text. |
| disableConfirm | boolean | — | When set to true the confirmation button will be disabled. |

## SaveDialog

This component allows the user to create a save dialog. It uses the dialog component described above.

### Example: Example 7

Save dialog

#### React (tsx)

```tsx
import { useState } from 'react';

import Button from '@rio-cloud/rio-uikit/Button';
import SaveDialog from '@rio-cloud/rio-uikit/SaveDialog';

export default () => {
    const [show, setShow] = useState(false);

    return (
        <>
            <Button bsStyle='primary' onClick={() => setShow(true)}>
                Save dialog
            </Button>
            <SaveDialog
                show={show}
                title='Save Dialog Title'
                content='Save Dialog Body Content'
                onClickConfirm={() => setShow(false)}
                onClickCancel={() => setShow(false)}
                onClickDiscard={() => setShow(false)}
                discardButtonText='Discard changes'
                cancelButtonText='Continue editing'
                confirmButtonText={
                    <>
                        <span className='rioglyph rioglyph-save margin-right-5' />
                        <span>Save changes</span>
                    </>
                }
            />
        </>
    );
};
```

#### HTML (html)

```html
<div class='modal show save-dialog modal-enter-done' tabindex='1' role='dialog'>
<div class='modal-dialog' role='document'>
    <div class='modal-content'>
        <div class='modal-header'>
            <div class='modal-header-text'>
                <div class='modal-header-title'>Save Dialog Title</div>
            </div>
            <div class='modal-header-buttons'>
                <button
                    type='button'
                    class='btn btn-icon-only btn-muted modal-header-close close'
                    data-testid='close'
                >
                    <span class='rioglyph rioglyph-remove' aria-hidden='true'></span>
                </button>
            </div>
        </div>
        <div class='modal-body'>Save Dialog Body Content</div>
        <div class='modal-footer'>
            <div class='btn-toolbar'>
                <button type='button' class='DiscardButton btn btn-default'>
                    Discard
                </button>
                <button type='button' class='CancelButton btn btn-default'>
                    Abort
                </button>
                <button type='button' class='ConfirmationButton btn btn-primary'>
                    <span> Save</span>
                </button>
            </div>
        </div>
    </div>
</div>
<div class='modal-backdrop'></div>
</div>;
```

#### Props: Base dialog props

### Base dialog props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| show | boolean | false | Opens the dialog when set to true. |
| title | React.ReactNode | — | The dialog title (can also be a FormattedMessage component). |
| subtitle | React.ReactNode | — | The dialog header subtitle content. |
| showCloseButton | boolean | true | Shows a close button when set to true. |
| onClose | () => void | — | A callback function invoked when the dialog closes. |
| bsSize | DialogSize | 'md' | Defined how large the dialog will be rendered. By default, the dialog has a medium size, and thus it can be omitted. Possible values are: 'xs' 'sm' 'lg' 'xl' 'fullwidth' 'fullheight' 'fullheight-lg' 'fullheight-xl' 'fullscreen' |
| disableEsc | boolean | false | Enables or disabled closing the dialog via esc key. |
| useOverflow | boolean | false | Enables the modal body to overflow and use inline scrolling if needed. |
| showXsDialogBorders | boolean | false | Show Header and Footer Borders for the "xs" dialog |
| className | string | — | Additional classes for the modal element. |

#### Props: SaveDialog

### SaveDialog

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| content | string \| React.ReactNode | — | The content of the dialog body itself. |
| onClickCancel | VoidFunction | — | A callback fired when the cancel button is clicked or the dialog is closed. |
| onClickDiscard | VoidFunction | — | A callback fired when the discard button is clicked. |
| onClickConfirm | VoidFunction | — | A callback fired when the confirmation button is clicked. |
| discardButtonText | string \| React.ReactNode | — | The content of the discard button. (Usually a text, can also be a FormattedMessage component). |
| cancelButtonText | string \| React.ReactNode | — | The content of the cancel button. (Usually a text, can also be a FormattedMessage component). |
| confirmButtonText | string \| React.ReactNode | — | The content of the confirmation button. Since it is a node, it can be a simple text or any JSX node like a div element with an icon and a text. |

## SplitDialog

This component allows the user to create a split dialog. It uses the dialog component described above.

### Example: Example 8

Split dialog Split dialog large

#### React (tsx)

```tsx
import { useState } from 'react';

import composition from '../../../assets/getting_started_composition.webp';
import Button from '@rio-cloud/rio-uikit/Button';
import SplitDialog from '@rio-cloud/rio-uikit/SplitDialog';
import ListMenu from '@rio-cloud/rio-uikit/ListMenu';
import Notification from '@rio-cloud/rio-uikit/Notification';
import { dummyTextLong, dummyTextShort } from '../../../utils/data';

export default () => {
    const [show, setShow] = useState(false);
    const [showLg, setShowLg] = useState(false);

    const handleClose = () => {
        setShow(false);
        console.log('dialog closed');
    };

    return (
        <div className='btn-toolbar'>
            <Button bsStyle='primary' onClick={() => setShow(true)}>
                Split dialog
            </Button>
            <SplitDialog
                show={show}
                title='Split dialog title'
                onClose={handleClose}
                leftContent={<ListMenu menuItems={menuItems} groupClassName='padding-left-0' />}
                rightContentClassName='bg-lightest'
                footer={<div>Sample footer</div>}
                rightContent={
                    <>
                        <div className='h4'>Dolor sit amet</div>
                        <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy</p>
                        <div className='padding-top-15'>
                            <div className='panel panel-default shadow-default'>
                                <div className='panel-heading text-color-darkest text-bold'>Admin</div>
                                <div className='panel-body'>
                                    <ul className='padding-left-20 margin-0'>
                                        <li>Permission to read all vehicles and their master data.</li>
                                        <li>Permission to change driver emails.</li>
                                    </ul>
                                </div>
                            </div>
                            <div className='panel panel-default shadow-default'>
                                <div className='panel-heading text-color-darkest text-bold'>Reader</div>
                                <div className='panel-body'>
                                    <ul className='padding-left-20 margin-0'>
                                        <li>Permission to read all reports</li>
                                    </ul>
                                </div>
                            </div>
                            <div className='panel panel-default shadow-default'>
                                <div className='panel-heading text-color-darkest text-bold'>Lorem ipsum</div>
                                <div className='panel-body' />
                            </div>
                            <div className='panel panel-default shadow-default'>
                                <div className='panel-heading text-color-darkest text-bold'>Lorem ipsum</div>
                                <div className='panel-body' />
                            </div>
                            <div className='panel panel-default shadow-default'>
                                <div className='panel-heading text-color-darkest text-bold'>Lorem ipsum</div>
                                <div className='panel-body' />
                            </div>
                            <div className='panel panel-default shadow-default'>
                                <div className='panel-heading text-color-darkest text-bold'>Lorem ipsum</div>
                                <div className='panel-body' />
                            </div>
                            <div className='panel panel-default shadow-default'>
                                <div className='panel-heading text-color-darkest text-bold'>Lorem ipsum</div>
                                <div className='panel-body' />
                            </div>
                            <div className='panel panel-default shadow-default'>
                                <div className='panel-heading text-color-darkest text-bold'>Lorem ipsum</div>
                                <div className='panel-body' />
                            </div>
                            <div className='panel panel-default shadow-default'>
                                <div className='panel-heading text-color-darkest text-bold'>Lorem ipsum</div>
                                <div className='panel-body' />
                            </div>
                            <div className='panel panel-default shadow-default'>
                                <div className='panel-heading text-color-darkest text-bold'>Lorem ipsum</div>
                                <div className='panel-body' />
                            </div>
                            <div className='panel panel-default shadow-default'>
                                <div className='panel-heading text-color-darkest text-bold'>Lorem ipsum</div>
                                <div className='panel-body' />
                            </div>
                            <div className='panel panel-default shadow-default'>
                                <div className='panel-heading text-color-darkest text-bold'>Lorem ipsum</div>
                                <div className='panel-body' />
                            </div>
                            <div className='panel panel-default shadow-default'>
                                <div className='panel-heading text-color-darkest text-bold'>Lorem ipsum</div>
                                <div className='panel-body' />
                            </div>
                            <div className='panel panel-default shadow-default'>
                                <div className='panel-heading text-color-darkest text-bold'>Lorem ipsum</div>
                                <div className='panel-body' />
                            </div>
                            <div className='panel panel-default shadow-default'>
                                <div className='panel-heading text-color-darkest text-bold'>Lorem ipsum</div>
                                <div className='panel-body' />
                            </div>
                            <div className='panel panel-default shadow-default'>
                                <div className='panel-heading text-color-darkest text-bold'>Lorem ipsum</div>
                                <div className='panel-body' />
                            </div>
                            <div className='panel panel-default shadow-default'>
                                <div className='panel-heading text-color-darkest text-bold'>Lorem ipsum</div>
                                <div className='panel-body' />
                            </div>
                            <div className='panel panel-default shadow-default'>
                                <div className='panel-heading text-color-darkest text-bold'>Lorem ipsum</div>
                                <div className='panel-body' />
                            </div>
                        </div>
                    </>
                }
            />

            <Button bsStyle='primary' onClick={() => setShowLg(true)}>
                Split dialog large
            </Button>
            <SplitDialog
                show={showLg}
                bsSize='lg'
                title='Split dialog title'
                onClose={() => setShowLg(false)}
                leftContent={
                    <ListMenu menuItems={menuItems2} groupClassName='padding-left-0' className='padding-top-5' />
                }
                leftContentClassName='padding-top-25'
                showDivider={false}
                rightContent={
                    <>
                        <div className='text-size-h2 text-medium margin-bottom-15'>Dolor sit amet</div>
                        <p>{dummyTextShort}</p>
                        <img className='img-responsive border rounded' alt='Intro' src={composition} />
                        <div className='display-flex gap-50 margin-top-25'>
                            <div className='flex-1-1'>
                                <p className='h4'>Lorem ipsum dolor sit amet</p>
                                <div>{dummyTextLong}</div>
                            </div>
                            <div className='flex-1-1'>
                                <p className='h4'>Lorem ipsum dolor sit amet</p>
                                <div>{dummyTextLong}</div>
                            </div>
                        </div>
                    </>
                }
            />
        </div>
    );
};

const menuItems = [
    {
        group: 'Rolls',
        navItems: [
            {
                key: '1',
                item: (
                    <span className='active' onClick={() => Notification.info('Fleetadmin clicked')}>
                        Fleetadmin
                    </span>
                ),
            },
            {
                key: '2',
                item: <span onClick={() => Notification.info('Fleetuser clicked')}>Fleetuser</span>,
            },
            {
                key: '3',
                item: <span onClick={() => Notification.info('Fleetdriver clicked')}>Fleetdriver</span>,
            },
        ],
    },
];

const menuItems2 = [
    {
        group: 'Service name',
        navItems: [
            {
                key: '1',
                item: <span className='active'>Welcome</span>,
            },
            {
                key: '2',
                item: <span>What's new</span>,
            },
        ],
    },
    {
        group: 'Features',
        navItems: [
            {
                key: '1',
                item: <span>Feature name one</span>,
            },
            {
                key: '2',
                item: <span>Another cool feature for this</span>,
            },
            {
                key: '2',
                item: <span>That is a nice feature</span>,
            },
        ],
    },
];
```

#### HTML (html)

```html
<div class='modal show split-dialog modal-enter-done' tabindex='1' role='dialog'>
<div class='modal-dialog modal-overflow' role='document'>
    <div class='modal-content'>
        <div class='modal-header'>
            <div class='modal-header-text'>
                <div class='modal-header-title'>Split Dialog Title</div>
            </div>
            <div class='modal-header-buttons'>
                <button
                    type='button'
                    class='btn btn-icon-only btn-muted modal-header-close close'
                    data-testid='close'
                >
                    <span class='rioglyph rioglyph-remove' aria-hidden='true'></span>
                </button>
            </div>
        </div>
        <div class='modal-body'>
            <div class='split-wrapper'>
                <div class='split-left '>
                    {/* <!-- Left Content --> */}
                    <div class='split-divider bg-lighter'></div>
                </div>
                <div class='split-right bg-lightest'>
                    {/* <!-- Right Content --> */}
                </div>
            </div>
        </div>
    </div>
</div>
<div class='modal-backdrop'></div>
</div>;
```

#### Props: Base dialog props

### Base dialog props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| show | boolean | false | Opens the dialog when set to true. |
| title | React.ReactNode | — | The dialog title (can also be a FormattedMessage component). |
| subtitle | React.ReactNode | — | The dialog header subtitle content. |
| showCloseButton | boolean | true | Shows a close button when set to true. |
| onClose | () => void | — | A callback function invoked when the dialog closes. |
| bsSize | DialogSize | 'md' | Defined how large the dialog will be rendered. By default, the dialog has a medium size, and thus it can be omitted. Possible values are: 'xs' 'sm' 'lg' 'xl' 'fullwidth' 'fullheight' 'fullheight-lg' 'fullheight-xl' 'fullscreen' |
| disableEsc | boolean | false | Enables or disabled closing the dialog via esc key. |
| useOverflow | boolean | false | Enables the modal body to overflow and use inline scrolling if needed. |
| showXsDialogBorders | boolean | false | Show Header and Footer Borders for the "xs" dialog |
| className | string | — | Additional classes for the modal element. |

#### Props: SplitDialog

### SplitDialog

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| leftContent | string \| React.ReactNode | — | The content to be shown on the left side. |
| leftContentClassName | string | — | Additional classes for the left content element. |
| rightContent | string \| React.ReactNode | — | The content to be shown on the right side. |
| rightContentClassName | string | — | Additional classes for the right content element. |
| footer | React.ReactNode | — | The dialog body content. |
| footerClassName | string | — | Additional classes for the modal-footer element. |
| onCloseValidation | () => boolean | — | A callback function to be executed before closing the dialog. If the function returns false, the dialog will not be closed |
| useOverflow | boolean | true | Enables the modal body to overflow and use inline scrolling if needed. |
| showDivider | boolean | true | Allows to disable the divider. |

## InfoDialog

This component allows the user to create a dialog without title and footer. It uses the dialog component described above.

### Example: Example 9

Info dialog

#### React (tsx)

```tsx
import { useState } from 'react';

import Button from '@rio-cloud/rio-uikit/Button';
import InfoDialog from '@rio-cloud/rio-uikit/InfoDialog';

const InfoDialogExample = () => {
    const [show, setShow] = useState(false);

    const handleShow = () => setShow(true);
    const handleHide = () => setShow(false);

    return (
        <div>
            <Button bsStyle='primary' onClick={handleShow}>
                Info dialog
            </Button>
            <InfoDialog
                show={show}
                onClose={handleHide}
                content={
                    <div className='text-center'>
                        <div className='margin-bottom-25'>
                            <h2>Lorem ipsum dolor sit amet</h2>
                            <p>
                                Lorem ipsum dolor sit amet, consectetur adipiscing elit.Aliquam laoreet nec neque ut
                                fermentum. Vestibulum erat enim.
                            </p>
                        </div>
                        <Button className='margin-bottom-20' onClick={handleHide}>
                            Got it
                        </Button>
                    </div>
                }
            />
        </div>
    );
};

export default InfoDialogExample;
```

#### HTML (html)

```html
<div class='modal show info-dialog modal-enter-done' tabindex='1' role='dialog'>
<div class='modal-dialog' role='document'>
    <div class='modal-content'>
        <div class='modal-body'>
            <div class='text-center'>
                <div class='margin-bottom-25'>
                    <h2>Lorem ipsum dolor sit amet</h2>
                    <p>
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam laoreet nec neque ut
                        fermentum. Vestibulum erat enim.
                    </p>
                </div>
                <button type='button' class='btn btn-primary margin-bottom-20'>
                    Understood, close me
                </button>
            </div>
        </div>
    </div>
</div>
<div class='modal-backdrop'></div>
</div>;
```

#### Props: Base dialog props

### Base dialog props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| show | boolean | false | Opens the dialog when set to true. |
| title | React.ReactNode | — | The dialog title (can also be a FormattedMessage component). |
| subtitle | React.ReactNode | — | The dialog header subtitle content. |
| showCloseButton | boolean | true | Shows a close button when set to true. |
| onClose | () => void | — | A callback function invoked when the dialog closes. |
| bsSize | DialogSize | 'md' | Defined how large the dialog will be rendered. By default, the dialog has a medium size, and thus it can be omitted. Possible values are: 'xs' 'sm' 'lg' 'xl' 'fullwidth' 'fullheight' 'fullheight-lg' 'fullheight-xl' 'fullscreen' |
| disableEsc | boolean | false | Enables or disabled closing the dialog via esc key. |
| useOverflow | boolean | false | Enables the modal body to overflow and use inline scrolling if needed. |
| showXsDialogBorders | boolean | false | Show Header and Footer Borders for the "xs" dialog |
| className | string | — | Additional classes for the modal element. |

#### Props: InfoDialog

### InfoDialog

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| content | string \| React.ReactNode | — | The content of the dialog body itself. |

### Example: Example 10

Feature info dialog

#### React (tsx)

```tsx
import { useState } from 'react';

import composition from '../../../assets/getting_started_composition.webp';
import InfoDialog from '@rio-cloud/rio-uikit/InfoDialog';
import SimpleTooltip from '@rio-cloud/rio-uikit/SimpleTooltip';
import Button from '@rio-cloud/rio-uikit/Button';
import { dummyText } from '../../../utils/data';

const InfoDialogFeatureExample = () => {
    const [show, setShow] = useState(false);

    const handleShow = () => setShow(true);
    const handleHide = () => setShow(false);

    return (
        <div>
            <Button bsStyle='primary' onClick={handleShow}>
                Feature info dialog
            </Button>
            <InfoDialog
                show={show}
                onClose={handleHide}
                bodyClassName='padding-0'
                content={
                    <div>
                        <div>
                            <img
                                className='img-responsive rounded-top-right-extra-large rounded-top-left-extra-large'
                                src={composition}
                            />
                        </div>
                        <div className='position-relative padding-20 margin-top-10 margin-x-20'>
                            <SimpleTooltip placement='bottom' content='Close'>
                                <div
                                    className='position-absolute top-20 right-20 text-color-gray cursor-pointer'
                                    onClick={handleHide}
                                >
                                    <span className='rioglyph rioglyph-remove' />
                                </div>
                            </SimpleTooltip>
                            <div className='text-size-h3 text-medium margin-bottom-15 margin-right-20'>
                                Feature Lorem Ipsum dolor sit amet (Beta)
                            </div>
                            <p>{dummyText}</p>
                        </div>
                        <div
                            className={
                                'display-flex flex-row-sm flex-column gap-10 justify-content-between ' +
                                'align-items-start align-items-center-sm width-100pct bg-lightest ' +
                                'padding-20 rounded-bottom-right-extra-large rounded-bottom-left-extra-large'
                            }
                        >
                            <div className='btn-toolbar text-transform-uppercase margin-x-20 text-medium'>
                                How important is this feature to you?
                            </div>
                            <div className='btn-toolbar text-transform-uppercase margin-x-20'>
                                <SimpleTooltip placement='top' content='This would be cool, convenient or useful'>
                                    <Button bsStyle={Button.INFO} onClick={handleHide}>
                                        Nice-to-have
                                    </Button>
                                </SimpleTooltip>
                                <SimpleTooltip placement='top' content='This would solve a major need'>
                                    <Button bsStyle={Button.INFO} onClick={handleHide}>
                                        Important
                                    </Button>
                                </SimpleTooltip>
                                <SimpleTooltip placement='top' content='Withou it, we cannot use the service'>
                                    <Button bsStyle={Button.INFO} onClick={handleHide}>
                                        Critical
                                    </Button>
                                </SimpleTooltip>
                            </div>
                        </div>
                    </div>
                }
            />
        </div>
    );
};

export default InfoDialogFeatureExample;
```

#### HTML (html)

```html
<div class='modal show info-dialog modal-enter-done' tabindex='1' role='dialog'>
<div class='modal-dialog' role='document'>
    <div class='modal-content'>
        <div class='modal-body'>
            <div class='text-center'>
                <div class='margin-bottom-25'>
                    <h2>Lorem ipsum dolor sit amet</h2>
                    <p>
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam laoreet nec neque ut
                        fermentum. Vestibulum erat enim.
                    </p>
                </div>
                <button type='button' class='btn btn-primary margin-bottom-20'>
                    Understood, close me
                </button>
            </div>
        </div>
    </div>
</div>
<div class='modal-backdrop'></div>
</div>;
```

#### Props: Base dialog props

### Base dialog props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| show | boolean | false | Opens the dialog when set to true. |
| title | React.ReactNode | — | The dialog title (can also be a FormattedMessage component). |
| subtitle | React.ReactNode | — | The dialog header subtitle content. |
| showCloseButton | boolean | true | Shows a close button when set to true. |
| onClose | () => void | — | A callback function invoked when the dialog closes. |
| bsSize | DialogSize | 'md' | Defined how large the dialog will be rendered. By default, the dialog has a medium size, and thus it can be omitted. Possible values are: 'xs' 'sm' 'lg' 'xl' 'fullwidth' 'fullheight' 'fullheight-lg' 'fullheight-xl' 'fullscreen' |
| disableEsc | boolean | false | Enables or disabled closing the dialog via esc key. |
| useOverflow | boolean | false | Enables the modal body to overflow and use inline scrolling if needed. |
| showXsDialogBorders | boolean | false | Show Header and Footer Borders for the "xs" dialog |
| className | string | — | Additional classes for the modal element. |

#### Props: InfoDialog

### InfoDialog

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| content | string \| React.ReactNode | — | The content of the dialog body itself. |

## OnboardingDialog

The OnboardingDialog component is a customizable dialog designed to guide users through the initial steps of an onboarding tour. It displays a welcome message, a brief description of the onboarding process, and action buttons to either start the tour or skip it.

### Example: Example 11

Onboarding dialog

#### React (tsx)

```tsx
import { useState } from 'react';

import composition from '../../../assets/getting_started_composition.webp';
import OnboardingDialog from '@rio-cloud/rio-uikit/OnboardingDialog';
import Button from '@rio-cloud/rio-uikit/Button';

export default () => {
    const [show, setShow] = useState(false);

    const handleShow = () => setShow(true);
    const handleHide = () => setShow(false);

    const handleTakeTour = () => {
        // Start onboarding tour - see useOnboardingTour() hook
        setShow(false);
    };

    return (
        <div>
            <Button bsStyle='primary' onClick={handleShow}>
                Onboarding dialog
            </Button>
            <OnboardingDialog
                show={show}
                imageSrc={composition}
                imageAlt='Onboarding hero'
                title='Welcome to the RIO UIKIT!'
                description={
                    <span>
                        <span className='text-medium'>Get started with a quick tour</span> to explore UIKIT and discover
                        its key features. It's the easiest way to get familiar with the service and make the most of
                        your experience.
                    </span>
                }
                onboardingRestartHint='Not ready to take the tour now?'
                onboardingRestartDescription='If you choose to skip the tour now, don’t worry — you can always start it later from the service info option in the application header.'
                skipButtonText='Skip it'
                tourButtonText='Take the tour'
                onClose={handleHide}
                onStartTour={handleTakeTour}
            />
        </div>
    );
};
```

#### HTML (html)

```html
<div>
    <button type="button" class="btn btn-primary btn-component" tabindex="0">Onboarding dialog</button>
</div>
```

#### Props: OnboardingDialog

### OnboardingDialog

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| imageSrc | string | — | The source URL of the image to be displayed in the dialog. |
| imageAlt | string | — | Alternative text for the image, used for accessibility. |
| title | string \| React.ReactNode | — | The title of the dialog. A welcome message. |
| description | string \| React.ReactNode | — | A short description of the service and it's onboarding. |
| onboardingRestartHint | string \| React.ReactNode | — | Hint text for restarting the onboarding process. |
| onboardingRestartDescription | string \| React.ReactNode | — | Detailed description for restarting the onboarding process. |
| skipButtonText | string \| React.ReactNode | — | Text for the skip button |
| tourButtonText | string \| React.ReactNode | — | Text for the button to start the tour |
| onStartTour | () => void | — | Callback function to be called when the tour starts. |
| show | boolean | false | Opens the dialog when set to true. |
| onClose | () => void | — | A callback function invoked when the dialog closes. |
| className | string | — | Additional classes for the modal element. |

## MediaDialog

This component allows the user to show media inside a dialog like a set of images or a video. It uses the dialog component described above.

### Example: Example 12

Media dialog with multiple images Media dialog with single image Media dialog with video

#### React (tsx)

```tsx
import { useState } from 'react';

import Button from '@rio-cloud/rio-uikit/Button';
import MediaDialog from '@rio-cloud/rio-uikit/MediaDialog';
import ResponsiveVideo from '@rio-cloud/rio-uikit/ResponsiveVideo';
import Notification from '@rio-cloud/rio-uikit/Notification';

export default () => {
    const [showMediaDialog, setShowMediaDialog] = useState(false);
    const [showSingleMediaDialog, setShowSingleMediaDialog] = useState(false);
    const [showVideoMediaDialog, setShowVideoMediaDialog] = useState(false);

    return (
        <div>
            <div className='btn-toolbar'>
                <Button bsStyle='primary' onClick={() => setShowMediaDialog(true)}>
                    Media dialog with multiple images
                </Button>
                <Button bsStyle='primary' onClick={() => setShowSingleMediaDialog(true)}>
                    Media dialog with single image
                </Button>
                <Button bsStyle='primary' onClick={() => setShowVideoMediaDialog(true)}>
                    Media dialog with video
                </Button>
            </div>

            {/* Multiple images */}
            <MediaDialog
                show={showMediaDialog}
                onClose={() => setShowMediaDialog(false)}
                previousButtonText='Previous'
                useOverflow={false}
                previousButtonCallback={(mediaIndex: number) => mediaIndex === 1 && Notification.info('Cycled through')}
                nextButtonText='Next'
                nextButtonCallback={(mediaIndex: number) => mediaIndex === 0 && Notification.info('Cycled through')}
                media={[
                    {
                        src: 'https://picsum.photos/1920/1080',
                        type: MediaDialog.MEDIA_TYPE_IMAGE,
                        title: 'Image 1',
                    },
                    {
                        src: 'https://picsum.photos/1080/1920',
                        type: MediaDialog.MEDIA_TYPE_IMAGE,
                        title: 'Image 2',
                        subtitle: 'Lorem ipsum dolor sit amet',
                    },
                ]}
            />

            {/* Single image */}
            <MediaDialog
                show={showSingleMediaDialog}
                previousButtonText='Previous'
                nextButtonText='Next'
                onClose={() => setShowSingleMediaDialog(false)}
                media={[
                    {
                        src: 'https://picsum.photos/1920/1080',
                        type: MediaDialog.MEDIA_TYPE_IMAGE,
                        title: 'Lonely Image',
                    },
                ]}
            />

            {/* Embedded video */}
            <MediaDialog
                show={showVideoMediaDialog}
                previousButtonText='Previous'
                nextButtonText='Next'
                onClose={() => setShowVideoMediaDialog(false)}
                media={[
                    {
                        title: 'Video',
                        src: 'https://www.youtube.com/embed/znckWdXTbTk',
                        type: MediaDialog.MEDIA_TYPE_VIDEO,
                        aspectRatio: ResponsiveVideo.ASPECT_RATIO_16_BY_9,
                        className: 'foobar',
                    },
                ]}
            />
        </div>
    );
};
```

#### HTML (html)

```html
<div class='modal show media-dialog' tabindex='1' role='dialog'>
    <div class='modal-dialog modal-lg' role='document'>
        <div class='modal-content'>
            <div class='modal-header'>
                <div class='modal-header-text'>
                    <div class='modal-header-title'>Image 1</div>
                </div>
                <div class='modal-header-buttons'>
                    <button
                        type='button'
                        class='btn btn-icon-only btn-muted modal-header-close close'
                        data-testid='close'>
                        <span class='rioglyph rioglyph-remove' aria-hidden='true'></span>
                    </button>
                </div>
            </div>
            <div class='modal-body padding-0'>
                <div class='media-content content-center'>
                    <img class='ani-fade-in' src='https://......' />
                </div>
            </div>
            <div class="modal-footer" aria-label="dialog footer"><button type="button" class="btn btn-primary btn-link pull-left"><span class="rioglyph rioglyph-chevron-left"></span>Previous</button>
                <div>1 / 2</div><button type="button" class="btn btn-primary btn-link btn-icon-right"><span class="rioglyph rioglyph-chevron-right"></span>Next</button>
            </div>
        </div>
    </div>
    <div class='modal-backdrop'></div>
</div>;
```

#### Props: Base dialog props

### Base dialog props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| show | boolean | false | Opens the dialog when set to true. |
| title | React.ReactNode | — | The dialog title (can also be a FormattedMessage component). |
| subtitle | React.ReactNode | — | The dialog header subtitle content. |
| showCloseButton | boolean | true | Shows a close button when set to true. |
| onClose | () => void | — | A callback function invoked when the dialog closes. |
| bsSize | DialogSize | 'md' | Defined how large the dialog will be rendered. By default, the dialog has a medium size, and thus it can be omitted. Possible values are: 'xs' 'sm' 'lg' 'xl' 'fullwidth' 'fullheight' 'fullheight-lg' 'fullheight-xl' 'fullscreen' |
| disableEsc | boolean | false | Enables or disabled closing the dialog via esc key. |
| useOverflow | boolean | false | Enables the modal body to overflow and use inline scrolling if needed. |
| showXsDialogBorders | boolean | false | Show Header and Footer Borders for the "xs" dialog |
| className | string | — | Additional classes for the modal element. |

#### Props: MediaDialog

### MediaDialog

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| media | MediaDialogMedia[] | — | List of media objects. |
| └type | 'image' \| 'video' | — | Defines the media type that is going to be displayed. Possible values are: image and video. |
| └src | string | — | The source location for the media data. |
| └title | string \| React.ReactNode | — | The name or title of the media used for the dialogs title. |
| └subtitle | string \| React.ReactNode | — | Additional media information used for the dialogs subtitle. |
| └aspectRatio | '4by3' \| '16by9' | '16by9' | Only relevant for videos where the aspect of the video is defined. Possible values are: 4by3 and 16by9. |
| └className | string | — | Additional classes for the image element. |
| previousButtonText | string \| React.ReactNode | — | The button text for switching to the previous media if there are multiple. |
| previousButtonCallback | (newIndex: number) => void | — | Callback function for when the previous button is clicked. |
| nextButtonText | string \| React.ReactNode | — | The button text for switching to the next media if there are multiple. |
| nextButtonCallback | (newIndex: number) => void | — | Callback function for when the next button is clicked. |

## FrameDialog

This component allows the user to create a dialog in a parent window triggered and controlled by a widget iframe.

For more details, please visit iframe guidelines

### Example: Example 13



#### React (tsx)

```tsx
import React from 'react';
import IframeResizer from 'iframe-resizer-react';

import FrameDialog from '@rio-cloud/rio-uikit/FrameDialog';
import { PREFIX } from '../../../widgets/WidgetDemo';

const IFrameWidgetExample = React.memo(() => (
    <>
        <div className='iframe-wrapper'>
            <IframeResizer
                id='widgetDialogFrame'
                src={`${window.location.origin}${window.location.pathname}#widgetDemo`}
                className='unstyled width-100pct'
                style={{ width: '1px', minWidth: '100%' }}
            />
        </div>
        <FrameDialog
            eventPrefix={PREFIX}
            getSourceFrame={() => document.getElementById('widgetDialogFrame') as HTMLIFrameElement}
        />
    </>
));

export default IFrameWidgetExample;

// ----------------------------------------------------------
import { useState } from 'react';

import Button from '@rio-cloud/rio-uikit/Button';
import { OPEN_DIALOG_EVENT, CLOSE_DIALOG_EVENT, type OPEN_DIALOG_EVENT_TYPE } from '@rio-cloud/rio-uikit/FrameDialog';
import usePostMessage, { type RemoteAction } from '@rio-cloud/rio-uikit/usePostMessage';

export const PREFIX = 'EVENT_UIKIT_WIDGET_DEMO';

const WidgetDemo = () => {
    const [messageFromDialog, setMessageFromDialog] = useState('-');

    const { sendMessageToParent } = usePostMessage(PREFIX, (remoteAction: RemoteAction) => {
        console.log(remoteAction);

        if (remoteAction.type === `${PREFIX}${CLOSE_DIALOG_EVENT}`) {
            setMessageFromDialog(remoteAction.payload);
        }
    });

    const handleOpenDialog = () => {
        const payload: OPEN_DIALOG_EVENT_TYPE = {
            src: `${window.location.origin}${window.location.pathname}#widgetDemoDialog`,
            dialogProps: {
                bsSize: 'sm',
            },
        };

        sendMessageToParent({
            type: `${PREFIX}${OPEN_DIALOG_EVENT}`,
            payload,
        });
    };

    return (
        <div className='bg-white border rounded padding-20 height-200'>
            <div className='text-medium'>This is a widget embedded via an iframe</div>
            <div className='btn-toolbar margin-top-20'>
                <Button onClick={handleOpenDialog}>Open dialog in parent frame</Button>
            </div>
            <div className='margin-top-20'>
                <label>Closing message from dialog:</label>
                <div>{messageFromDialog}</div>
            </div>
        </div>
    );
};

export default WidgetDemo;

// ----------------------------------------------------------
import Button from '@rio-cloud/rio-uikit/Button';
import Dialog from '@rio-cloud/rio-uikit/Dialog';
import usePostMessage from '@rio-cloud/rio-uikit/usePostMessage';
import { CLOSE_DIALOG_EVENT } from '@rio-cloud/rio-uikit/FrameDialog';

import { dummyText } from '../../utils/data';
import { PREFIX } from './WidgetDemo';

const WidgetDemo = () => {
    const { sendMessageToParent } = usePostMessage(PREFIX);

    const handleCloseDialog = () => {
        sendMessageToParent({
            type: `${PREFIX}${CLOSE_DIALOG_EVENT}`,
            payload: 'hello from the dialog view',
        });
    };

    return (
        <div className='bg-white min-height-200'>
            <Dialog.Title title='Widget dialog' onCloseButtonClick={handleCloseDialog} />

            <Dialog.Body className='padding-20'>
                <div className='text-medium'>This is the widget dialog content embedded via an iframe</div>
                <p>{dummyText}</p>
            </Dialog.Body>

            <Dialog.Footer>
                <div>
                    <Button onClick={handleCloseDialog}>Close dialog in parent frame</Button>
                </div>
            </Dialog.Footer>
        </div>
    );
};

export default WidgetDemo;
```

#### HTML (html)

```html
<div class="iframe-wrapper">
    <iframe title="iframe" id="widgetDialogFrame" src="https://uikit.developers.rio.cloud/#widgetDemo" class="unstyled width-100pct" style="width: 1px; min-width: 100%; overflow: hidden; height: 200px;" scrolling="no">
    </iframe>
</div>
```

#### Props: FrameDialog

### FrameDialog

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| eventPrefix | string | 'EVENT_FRAME_DIALOG' | A prefix for all event types. |
| getSourceFrame | () => HTMLIFrameElement \| null | — | A function to retrieve the iframe DOM element so a message can be sent to it. This is required when sending messages back to the origin widget iframe that triggered the dialog in the first place. |
| className | string | — | Additional classes for the modal element. |

## ReleaseNotesDialog

The ReleaseNotesDialog component is meant to be used for the release notes of a service.Note there exists also a separate ReleaseNotes component.

### Example: Example 14

Service

1

#### React (tsx)

```tsx
import { useState } from 'react';

import ReleaseNotesDialog from '@rio-cloud/rio-uikit/ReleaseNotesDialog';
import ApplicationLayout from '@rio-cloud/rio-uikit/ApplicationLayout';
import ActionBarItem from '@rio-cloud/rio-uikit/ActionBarItem';
import ApplicationHeader from '@rio-cloud/rio-uikit/ApplicationHeader';

import packageJson from '../../../../package.json';
const currentVersion = packageJson.version;

const RELEASE_NOTES_ITEM = 'TEAMNAME.RELEASENOTES';

const currentVersionNumbers = currentVersion.split('.');

const isNewVersion = (localVersion: string | null) => {
    if (!localVersion) {
        return true;
    }

    const localVersionNumbers = localVersion.split('.');

    return !(
        currentVersionNumbers[0] === localVersionNumbers[0] && currentVersionNumbers[1] === localVersionNumbers[1]
    );
};

const releaseNotes = {
    'en-GB': {
        '1.1.0': {
            date: '23.07.2018',
            content: (
                <div>{`Map view within the tour history table
• Modern map design as used in the Beta of the fleet monitor
• Works with all event types
• Event specific map marker
• Map size adjustable via slider`}</div>
            ),
        },
        '1.0.0': {
            date: '27.06.2018',
            content: [
                <div key='1'>New feature XYZ has been added ...</div>,
                <div key='2'>fixed bugs in ...</div>,
                <div key='3'>Another feature has been added</div>,
            ],
        },
    },
};

const translationKey = 'en-GB';

const translations = {
    whatsNew: 'What`s new?',
    close: 'Close',
    'module.name': 'Modulename',
};

const handleRemoveReleaseNotesItem = () => {
    window.localStorage.removeItem(RELEASE_NOTES_ITEM);
};

export default () => {
    const [show, setShow] = useState(false);

    const hasNewReleaseNotes = isNewVersion(window.localStorage.getItem(RELEASE_NOTES_ITEM));
    const actionBarItemTitle = `${translations['module.name']} v.${currentVersion}`;

    const actionBarItem = (
        <ActionBarItem id='serviceInfoReleaseNotes'>
            <ActionBarItem.Icon>
                <span className='icon rioglyph rioglyph-info-sign' />
                {hasNewReleaseNotes && <span className='badge bg-primary badge-indicator'>1</span>}
            </ActionBarItem.Icon>
            <ActionBarItem.Popover title={actionBarItemTitle}>
                <ActionBarItem.List>
                    <ActionBarItem.ListItem icon='rioglyph-exclamation-sign' onClick={() => setShow(true)}>
                        {translations.whatsNew ?? 'What`s new?'}
                        {hasNewReleaseNotes && <span className='badge badge-primary margin-left-5'>1</span>}
                    </ActionBarItem.ListItem>
                </ActionBarItem.List>
                <ActionBarItem.List>
                    <ActionBarItem.ListItem icon='rioglyph-erase' onClick={handleRemoveReleaseNotesItem}>
                        Remove Release Notes flag
                    </ActionBarItem.ListItem>
                </ActionBarItem.List>
            </ActionBarItem.Popover>
        </ActionBarItem>
    );

    return (
        <>
            <ApplicationLayout>
                <ApplicationLayout.Header>
                    <ApplicationHeader label='Service' actionBarItems={[actionBarItem]} />
                </ApplicationLayout.Header>
            </ApplicationLayout>

            <ReleaseNotesDialog
                showReleaseNotes={show}
                setShowReleaseNotes={setShow}
                moduleName={translations['module.name']}
                whatsNewTitle={translations.whatsNew}
                closeButtonText={translations.close}
                translatedReleaseNotes={releaseNotes[translationKey]}
                currentVersion={currentVersion}
                RELEASE_NOTES_ITEM={RELEASE_NOTES_ITEM}
            />
        </>
    );
};
```

#### HTML (html)

```html
<div class="ApplicationLayout">
    <div class="ApplicationLayoutHeader" id="ApplicationLayoutHeader">
        <nav class="ApplicationHeader user-select-none">
            <div class="navbar-header">
                <span class="navbar-brand home-icon">
                </span>
            </div>
            <ul class="ModuleNavigation AppMenu user-select-none pointer-events-none">
                <li class="dropdown">
                    <a class="ModuleNavigation-dropdown dropdown-toggle justify-content-between inactive" role="button" id="basic-nav-dropdown">
                        <span>Service</span>
                    </a>
                </li>
            </ul>
            <ul class="SubmoduleNavigation nav">
            </ul>
            <ul class="ApplicationActionBar nav navbar-nav navbar-right ">
                <li role="presentation" class="navigationItem">
                    <div class="ActionBarItem">
                        <div class="ActionBarItemIcon">
                            <span class="icon rioglyph rioglyph-info-sign">
                            </span>
                            <span class="badge bg-primary badge-indicator">1</span>
                        </div>
                    </div>
                </li>
            </ul>
        </nav>
    </div>
</div>
```

#### Props (json)

```json
{
    "0.1.2": {
        date: '20.10.2023',
        content: (
            <div className='padding-left-15'>
                Summary
                • Feature 1
                • Feature 2
            </div>
        ),
    }
}
```