# SaveableInput

*Category:* Components
*Section:* Interaction
*Source:* https://uikit.developers.rio.cloud/#/components/saveableInput
*Captured:* 2026-04-27T14:57:25.988Z

## SaveableInput

### Example: SaveableInput

SaveableInput

SaveableInput with value

SaveableInput with previous value
Dolor sit amet

SaveableInput with fixed previous value
You shall not pass

SaveableInput with default button style

SaveableInput with unit and icon
Pcs

SaveableInput with feedback
Lab
This is an error message

Disabled SaveableInput

#### React (tsx)

```tsx
import SaveableInput from '@rio-cloud/rio-uikit/SaveableInput';
import FormLabel from '@rio-cloud/rio-uikit/FormLabel';

export default () => (
    <div>
        <div className='display-grid grid-cols-3-md grid-cols-2-xs gap-20'>
            <div>
                <FormLabel>SaveableInput</FormLabel>
                <SaveableInput placeholder='Some value comes here' />
            </div>

            <div>
                <FormLabel>SaveableInput with value</FormLabel>
                <SaveableInput value='Lorem ipsum' />
            </div>

            <div>
                <FormLabel>SaveableInput with previous value</FormLabel>
                <SaveableInput value='Lorem ipsum' previousValue='Dolor sit amet' />
            </div>

            <div>
                <FormLabel>SaveableInput with fixed previous value</FormLabel>
                <SaveableInput value='Lorem ipsum' fixedPreviousValue='You shall not pass' />
            </div>

            <div>
                <FormLabel>SaveableInput with default button style</FormLabel>
                <SaveableInput value='Lorem ipsum' buttonStyle='default' inputProps={{ id: 'some-id ' }} />
            </div>

            <div>
                <FormLabel>SaveableInput with unit and icon</FormLabel>
                <SaveableInput
                    value='145'
                    buttonStyle='default'
                    icon='rioglyph-parcel'
                    unit='Pcs'
                    className='max-width-150'
                />
            </div>

            <div>
                <FormLabel>SaveableInput with feedback</FormLabel>
                <div className='form-group'>
                    <SaveableInput
                        value='Lorem ipsum'
                        icon='rioglyph-factory'
                        unit='Lab'
                        className='margin-0'
                        isValid={false}
                        errorMessage='This is an error message'
                    />
                </div>
            </div>

            <div>
                <FormLabel>Disabled SaveableInput</FormLabel>
                <SaveableInput value='Lorem ipsum' disabled />
            </div>
        </div>
    </div>
);
```

#### HTML (html)

```html
<div>
    <div class="display-grid grid-cols-3-md grid-cols-2-xs gap-20">
        <div>
            <div class="text-color-dark max-width-100pct text-size-12 display-inline-block margin-bottom-5">SaveableInput</div>
            <div class="form-group">
                <div class="input-group">
                    <input type="text" placeholder="Some value comes here" class="form-control" disabled="" value="">
                    <div class="input-group-btn">
                        <button type="button" class="btn btn-primary btn-icon-only btn-component" tabindex="0">
                            <span class="rioglyph rioglyph-pencil">
                            </span>
                        </button>
                    </div>
                </div>
            </div>
        </div>
        <div>
            <div class="text-color-dark max-width-100pct text-size-12 display-inline-block margin-bottom-5">SaveableInput with value</div>
            <div class="form-group">
                <div class="input-group">
                    <input type="text" class="form-control" disabled="" value="Lorem ipsum">
                    <div class="input-group-btn">
                        <button type="button" class="btn btn-primary btn-icon-only btn-component" tabindex="0">
                            <span class="rioglyph rioglyph-pencil">
                            </span>
                        </button>
                    </div>
                </div>
            </div>
        </div>
        <div>
            <div class="text-color-dark max-width-100pct text-size-12 display-inline-block margin-bottom-5">SaveableInput with previous value</div>
            <div class="form-group">
                <div class="input-group">
                    <input type="text" class="form-control padding-bottom-0 padding-top-10 text-size-12" disabled="" value="Lorem ipsum">
                    <div class="position-absolute top-2 left-10 margin-left-3 text-size-10 text-decoration-line-through" aria-label="previous value">Dolor sit amet</div>
                    <div class="input-group-btn">
                        <button type="button" class="btn btn-primary btn-icon-only btn-component" tabindex="0">
                            <span class="rioglyph rioglyph-pencil">
                            </span>
                        </button>
                    </div>
                </div>
            </div>
        </div>
        <div>
            <div class="text-color-dark max-width-100pct text-size-12 display-inline-block margin-bottom-5">SaveableInput with fixed previous value</div>
            <div class="form-group">
                <div class="input-group">
                    <input type="text" class="form-control padding-bottom-0 padding-top-10 text-size-12" disabled="" value="Lorem ipsum">
                    <div class="position-absolute top-2 left-10 margin-left-3 text-size-10 text-decoration-line-through" aria-label="previous value">You shall not pass</div>
                    <div class="input-group-btn">
                        <button type="button" class="btn btn-primary btn-icon-only btn-component" tabindex="0">
                            <span class="rioglyph rioglyph-pencil">
                            </span>
                        </button>
                    </div>
                </div>
            </div>
        </div>
        <div>
            <div class="text-color-dark max-width-100pct text-size-12 display-inline-block margin-bottom-5">SaveableInput with default button style</div>
            <div class="form-group">
                <div class="input-group">
                    <input type="text" class="form-control" disabled="" id="some-id " value="Lorem ipsum">
                    <div class="input-group-btn">
                        <button type="button" class="btn btn-default btn-icon-only btn-component" tabindex="0">
                            <span class="rioglyph rioglyph-pencil">
                            </span>
                        </button>
                    </div>
                </div>
            </div>
        </div>
        <div>
            <div class="text-color-dark max-width-100pct text-size-12 display-inline-block margin-bottom-5">SaveableInput with unit and icon</div>
            <div class="form-group max-width-150">
                <div class="input-group">
                    <span class="input-group-addon">
                        <span class="rioglyph rioglyph-parcel" aria-hidden="true" aria-label="input icon">
                        </span>
                    </span>
                    <input type="text" class="form-control padding-right-50" disabled="" value="145">
                    <div class="position-absolute right-0 margin-right-50" aria-label="unit">Pcs</div>
                    <div class="input-group-btn">
                        <button type="button" class="btn btn-default btn-icon-only btn-component" tabindex="0">
                            <span class="rioglyph rioglyph-pencil">
                            </span>
                        </button>
                    </div>
                </div>
            </div>
        </div>
        <div>
            <div class="text-color-dark max-width-100pct text-size-12 display-inline-block margin-bottom-5">SaveableInput with feedback</div>
            <div class="form-group">
                <div class="form-group has-feedback has-error margin-0">
                    <div class="input-group">
                        <span class="input-group-addon">
                            <span class="rioglyph rioglyph-factory" aria-hidden="true" aria-label="input icon">
                            </span>
                        </span>
                        <input type="text" class="form-control padding-right-50" disabled="" value="Lorem ipsum">
                        <div class="position-absolute right-0 margin-right-50" aria-label="unit">Lab</div>
                        <div class="input-group-btn">
                            <button type="button" class="btn btn-primary btn-icon-only btn-component" tabindex="0">
                                <span class="rioglyph rioglyph-pencil">
                                </span>
                            </button>
                        </div>
                    </div>
                    <span class="help-block z-index-max">
                        <span>This is an error message</span>
                    </span>
                </div>
            </div>
        </div>
        <div>
            <div class="text-color-dark max-width-100pct text-size-12 display-inline-block margin-bottom-5">Disabled SaveableInput</div>
            <div class="form-group">
                <div class="input-group">
                    <input type="text" class="form-control" disabled="" value="Lorem ipsum">
                    <div class="input-group-btn">
                        <button type="button" class="btn btn-primary btn-icon-only btn-component" disabled="" tabindex="0">
                            <span class="rioglyph rioglyph-pencil">
                            </span>
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
```

#### Props: SaveableInput

### SaveableInput

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| placeholder | string | — | The input placeholder. |
| fixedPreviousValue | string | — | The previous or old value shown above the input value. This value will *not* be changed for new input values. |
| previousValue | string | — | The previous or old value shown above the input value. This value *changes* when a new input value is accepted. |
| value | string | — | The actual input value. |
| isValid | boolean | true | Used to control the save button from the outside to disable it in case the entered value is not valid. |
| errorMessage | string \| React.ReactNode | — | This is the error message that is shown below the input. It uses the built-in error handling, and will be shown when the "isValid" prop is set to false. |
| hideErrorIcon | boolean | false | Defines wether the error icon is shown or not. If enabled, it will be shown when the "isValid" prop is set to false. |
| onValueChanged | (value: string, previousValue: string) => void | — | Callback function triggered when the value changes. |
| onInputChange | (keyValue: string, inputValue: string) => void | — | Callback function that gets triggered on every input change. Use this to control the component or when implementing key validation. |
| onEsc | () => void | — | Callback function that gets triggered when the user aborts the edit mode. Use this to control the component and handle the resetting of previous value on the outside. |
| onEnterEdit | () => void | — | Callback function that gets triggered when the input is in edit mode. Use this to control the component dna to handle the previous value on the outside. |
| buttonStyle | 'primary' \| 'default' | 'primary' | Defines the button style: default or primary. |
| inputProps | HTMLAttributes<HTMLInputElement> | — | Additional HTML attributes to be set on the input element. |
| unit | string \| React.ReactNode | — | Adds a given unit to the input. |
| icon | string | — | Icon class name that shall be used. If defined, the input element is wrapped in an input-group and the icon will be set in an input-addon. Example: rioglyph-search. |
| disabled | boolean | false | Disables the component so the user cannot enter the edit mode. |
| inputClassName | string | — | Additional classes to be set on the input itself. |
| className | string | — | Additional classes to be set on the wrapper element. |

### Example: Example 2

With error feedback and disabled save button

#### React (tsx)

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

import SaveableInput from '@rio-cloud/rio-uikit/SaveableInput';

export default () => {
    const [previousValue, setPreviousValue] = useState('');
    const [backupValue, setBackupValue] = useState('');
    const [value, setValue] = useState('Remove this value');

    // When the user "saves" the entered value, we update the current and the previous value
    const handleValueChanged = (newValue: string, oldValue: string) => {
        setPreviousValue(oldValue);
        setValue(newValue);
    };

    // Used to do some custom validation here...
    const handleInputChange = (_keyValue: string, inputValue: string) => {
        setValue(inputValue);
    };

    // As we control the current and previous value outside the component, whe need to keep
    // the previous value around to restore it when the user aborts the edit with "esc", otherwise
    // the previous value is already overwritten and changed
    const handleEnterEditMode = () => {
        setBackupValue(previousValue);
        setPreviousValue(value);
    };

    // Restore the current and previous value when the user aborts the edit
    const handleEsc = () => {
        setValue(previousValue);
        setPreviousValue(backupValue);
    };

    const hasValidInput = !!value;

    return (
        <div className='max-width-300'>
            <label>With error feedback and disabled save button</label>
            <div className='form-group'>
                <SaveableInput
                    icon='rioglyph-factory'
                    value={value}
                    onValueChanged={handleValueChanged}
                    onInputChange={handleInputChange}
                    onEnterEdit={handleEnterEditMode}
                    onEsc={handleEsc}
                    isValid={hasValidInput}
                    className='margin-0'
                    errorMessage='Please enter something'
                    hideErrorIcon
                />
            </div>
        </div>
    );
};
```

#### HTML (html)

```html
<div class="max-width-300">
    <label>With error feedback and disabled save button</label>
    <div class="form-group">
        <div class="form-group margin-0">
            <div class="input-group">
                <span class="input-group-addon">
                    <span class="rioglyph rioglyph-factory" aria-hidden="true" aria-label="input icon">
                    </span>
                </span>
                <input type="text" class="form-control" disabled="" value="Remove this value">
                <div class="input-group-btn">
                    <button type="button" class="btn btn-primary btn-icon-only btn-component" tabindex="0">
                        <span class="rioglyph rioglyph-pencil">
                        </span>
                    </button>
                </div>
            </div>
        </div>
    </div>
</div>
```

#### Props: SaveableInput

### SaveableInput

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| placeholder | string | — | The input placeholder. |
| fixedPreviousValue | string | — | The previous or old value shown above the input value. This value will *not* be changed for new input values. |
| previousValue | string | — | The previous or old value shown above the input value. This value *changes* when a new input value is accepted. |
| value | string | — | The actual input value. |
| isValid | boolean | true | Used to control the save button from the outside to disable it in case the entered value is not valid. |
| errorMessage | string \| React.ReactNode | — | This is the error message that is shown below the input. It uses the built-in error handling, and will be shown when the "isValid" prop is set to false. |
| hideErrorIcon | boolean | false | Defines wether the error icon is shown or not. If enabled, it will be shown when the "isValid" prop is set to false. |
| onValueChanged | (value: string, previousValue: string) => void | — | Callback function triggered when the value changes. |
| onInputChange | (keyValue: string, inputValue: string) => void | — | Callback function that gets triggered on every input change. Use this to control the component or when implementing key validation. |
| onEsc | () => void | — | Callback function that gets triggered when the user aborts the edit mode. Use this to control the component and handle the resetting of previous value on the outside. |
| onEnterEdit | () => void | — | Callback function that gets triggered when the input is in edit mode. Use this to control the component dna to handle the previous value on the outside. |
| buttonStyle | 'primary' \| 'default' | 'primary' | Defines the button style: default or primary. |
| inputProps | HTMLAttributes<HTMLInputElement> | — | Additional HTML attributes to be set on the input element. |
| unit | string \| React.ReactNode | — | Adds a given unit to the input. |
| icon | string | — | Icon class name that shall be used. If defined, the input element is wrapped in an input-group and the icon will be set in an input-addon. Example: rioglyph-search. |
| disabled | boolean | false | Disables the component so the user cannot enter the edit mode. |
| inputClassName | string | — | Additional classes to be set on the input itself. |
| className | string | — | Additional classes to be set on the wrapper element. |

### Example: Controlled SaveableInput

Controlled SaveableInput

Randomize values Clear values

{
value: '',
previousValue: ''
}

#### React (tsx)

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

import SaveableInput from '@rio-cloud/rio-uikit/SaveableInput';
import Button from '@rio-cloud/rio-uikit/Button';
import FormLabel from '@rio-cloud/rio-uikit/FormLabel';

const getRandomString = () => (Math.random() + 1).toString(36).toUpperCase().substring(2);

export default () => {
    const [previousValue, setPreviousValue] = useState('');
    const [value, setValue] = useState('');

    const handleValueChanged = (newValue: string) => {
        setPreviousValue(value);
        setValue(newValue);
    };

    return (
        <div>
            <div className='display-grid grid-cols-3-md grid-cols-2-xs gap-20'>
                <div>
                    <FormLabel>Controlled SaveableInput</FormLabel>
                    <SaveableInput
                        placeholder='Some value comes here'
                        value={value}
                        previousValue={previousValue}
                        onValueChanged={handleValueChanged}
                    />
                </div>
                <div className='grid-colspan-2 margin-top-25 btn-toolbar'>
                    <Button
                        onClick={() => {
                            setPreviousValue(getRandomString());
                            setValue(getRandomString());
                        }}
                    >
                        Randomize values
                    </Button>

                    <Button
                        onClick={() => {
                            setPreviousValue('');
                            setValue('');
                        }}
                    >
                        Clear values
                    </Button>
                </div>
            </div>
            <div className='margin-top-10 text-italic text-size-11'>
                <pre>{`{
    value: '${value}',
    previousValue: '${previousValue}'
}`}</pre>
            </div>
        </div>
    );
};
```

#### HTML (html)

```html
<div>
    <div class="display-grid grid-cols-3-md grid-cols-2-xs gap-20">
        <div>
            <div class="text-color-dark max-width-100pct text-size-12 display-inline-block margin-bottom-5">Controlled SaveableInput</div>
            <div class="form-group">
                <div class="input-group">
                    <input type="text" placeholder="Some value comes here" class="form-control" disabled="" value="">
                    <div class="input-group-btn">
                        <button type="button" class="btn btn-primary btn-icon-only btn-component" tabindex="0">
                            <span class="rioglyph rioglyph-pencil">
                            </span>
                        </button>
                    </div>
                </div>
            </div>
        </div>
        <div class="grid-colspan-2 margin-top-25 btn-toolbar">
            <button type="button" class="btn btn-default btn-component" tabindex="0">Randomize values</button>
            <button type="button" class="btn btn-default btn-component" tabindex="0">Clear values</button>
        </div>
    </div>
    <div class="margin-top-10 text-italic text-size-11">
        <pre>{
    value: '',
    previousValue: ''
}</pre>
    </div>
</div>
```

#### Props: SaveableInput

### SaveableInput

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| placeholder | string | — | The input placeholder. |
| fixedPreviousValue | string | — | The previous or old value shown above the input value. This value will *not* be changed for new input values. |
| previousValue | string | — | The previous or old value shown above the input value. This value *changes* when a new input value is accepted. |
| value | string | — | The actual input value. |
| isValid | boolean | true | Used to control the save button from the outside to disable it in case the entered value is not valid. |
| errorMessage | string \| React.ReactNode | — | This is the error message that is shown below the input. It uses the built-in error handling, and will be shown when the "isValid" prop is set to false. |
| hideErrorIcon | boolean | false | Defines wether the error icon is shown or not. If enabled, it will be shown when the "isValid" prop is set to false. |
| onValueChanged | (value: string, previousValue: string) => void | — | Callback function triggered when the value changes. |
| onInputChange | (keyValue: string, inputValue: string) => void | — | Callback function that gets triggered on every input change. Use this to control the component or when implementing key validation. |
| onEsc | () => void | — | Callback function that gets triggered when the user aborts the edit mode. Use this to control the component and handle the resetting of previous value on the outside. |
| onEnterEdit | () => void | — | Callback function that gets triggered when the input is in edit mode. Use this to control the component dna to handle the previous value on the outside. |
| buttonStyle | 'primary' \| 'default' | 'primary' | Defines the button style: default or primary. |
| inputProps | HTMLAttributes<HTMLInputElement> | — | Additional HTML attributes to be set on the input element. |
| unit | string \| React.ReactNode | — | Adds a given unit to the input. |
| icon | string | — | Icon class name that shall be used. If defined, the input element is wrapped in an input-group and the icon will be set in an input-addon. Example: rioglyph-search. |
| disabled | boolean | false | Disables the component so the user cannot enter the edit mode. |
| inputClassName | string | — | Additional classes to be set on the input itself. |
| className | string | — | Additional classes to be set on the wrapper element. |

### Example: Controlled SaveableInput with key validation

Controlled SaveableInput with key validation
Pcs

{
value: '0',
previousValue: ''
}

#### React (tsx)

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

import SaveableInput from '@rio-cloud/rio-uikit/SaveableInput';
import FormLabel from '@rio-cloud/rio-uikit/FormLabel';

export default () => {
    const [previousValue, setPreviousValue] = useState('');
    const [backupValue, setBackupValue] = useState('');
    const [value, setValue] = useState('0');

    // When the user "saves" the entered value, we update the current and the previous value
    const handleValueChanged = (newValue: string, oldValue: string) => {
        setPreviousValue(oldValue);
        setValue(newValue);
    };

    // Used to do some custom validation here...
    const handleInputChange = (keyValue: string, inputValue: string) => {
        console.log({ keyValue, inputValue });

        const parsedValue = Number.parseFloat(keyValue);
        if (keyValue !== '' && Number.isNaN(parsedValue)) {
            console.log('Not a valid number: ', keyValue);
        } else {
            console.log('Valid number entered:', parsedValue);
            setValue(inputValue);
        }
    };

    // As we control the current and previous value outside the component, whe need to keep
    // the previous value around to restore it when the user aborts the edit with "esc", otherwise
    // the previous value is already overwritten and changed
    const handleEnterEditMode = () => {
        setBackupValue(previousValue);
        setPreviousValue(value);
    };

    // Restore the current and previous value when the user aborts the edit
    const handleEsc = () => {
        setValue(previousValue);
        setPreviousValue(backupValue);
    };

    return (
        <div>
            <div className='display-grid grid-cols-3-md grid-cols-2-xs gap-20'>
                <div>
                    <FormLabel>Controlled SaveableInput with key validation</FormLabel>
                    <SaveableInput
                        unit='Pcs'
                        value={value}
                        previousValue={previousValue}
                        onValueChanged={handleValueChanged}
                        onInputChange={handleInputChange}
                        onEsc={handleEsc}
                        onEnterEdit={handleEnterEditMode}
                        className='max-width-200'
                    />
                </div>
            </div>
            <div className='margin-top-10 text-italic text-size-11'>
                <pre>{`{
    value: '${value}',
    previousValue: '${previousValue}'
}`}</pre>
            </div>
        </div>
    );
};
```

#### HTML (html)

```html
<div>
    <div class="display-grid grid-cols-3-md grid-cols-2-xs gap-20">
        <div>
            <div class="text-color-dark max-width-100pct text-size-12 display-inline-block margin-bottom-5">Controlled SaveableInput with key validation</div>
            <div class="form-group max-width-200">
                <div class="input-group">
                    <input type="text" class="form-control padding-right-50" disabled="" value="0">
                    <div class="position-absolute right-0 margin-right-50" aria-label="unit">Pcs</div>
                    <div class="input-group-btn">
                        <button type="button" class="btn btn-primary btn-icon-only btn-component" tabindex="0">
                            <span class="rioglyph rioglyph-pencil">
                            </span>
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="margin-top-10 text-italic text-size-11">
        <pre>{
    value: '0',
    previousValue: ''
}</pre>
    </div>
</div>
```

#### Props: SaveableInput

### SaveableInput

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| placeholder | string | — | The input placeholder. |
| fixedPreviousValue | string | — | The previous or old value shown above the input value. This value will *not* be changed for new input values. |
| previousValue | string | — | The previous or old value shown above the input value. This value *changes* when a new input value is accepted. |
| value | string | — | The actual input value. |
| isValid | boolean | true | Used to control the save button from the outside to disable it in case the entered value is not valid. |
| errorMessage | string \| React.ReactNode | — | This is the error message that is shown below the input. It uses the built-in error handling, and will be shown when the "isValid" prop is set to false. |
| hideErrorIcon | boolean | false | Defines wether the error icon is shown or not. If enabled, it will be shown when the "isValid" prop is set to false. |
| onValueChanged | (value: string, previousValue: string) => void | — | Callback function triggered when the value changes. |
| onInputChange | (keyValue: string, inputValue: string) => void | — | Callback function that gets triggered on every input change. Use this to control the component or when implementing key validation. |
| onEsc | () => void | — | Callback function that gets triggered when the user aborts the edit mode. Use this to control the component and handle the resetting of previous value on the outside. |
| onEnterEdit | () => void | — | Callback function that gets triggered when the input is in edit mode. Use this to control the component dna to handle the previous value on the outside. |
| buttonStyle | 'primary' \| 'default' | 'primary' | Defines the button style: default or primary. |
| inputProps | HTMLAttributes<HTMLInputElement> | — | Additional HTML attributes to be set on the input element. |
| unit | string \| React.ReactNode | — | Adds a given unit to the input. |
| icon | string | — | Icon class name that shall be used. If defined, the input element is wrapped in an input-group and the icon will be set in an input-addon. Example: rioglyph-search. |
| disabled | boolean | false | Disables the component so the user cannot enter the edit mode. |
| inputClassName | string | — | Additional classes to be set on the input itself. |
| className | string | — | Additional classes to be set on the wrapper element. |

## SaveableDateInput

### Example: SaveableDateInput (uncontrolled)

SaveableDateInput (uncontrolled)

‹ April 2026 ›
Su Mo Tu We Th Fr Sa

29 30 31 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 1 2
3 4 5 6 7 8 9

Controlled - Stay open on invalid (default)

‹ April 2026 ›
Su Mo Tu We Th Fr Sa

29 30 31 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 1 2
3 4 5 6 7 8 9

04:57

Saved value:

Controlled - With error

‹ April 2026 ›
Su Mo Tu We Th Fr Sa

29 30 31 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 1 2
3 4 5 6 7 8 9

12:00

Required field

Saved value:

Controlled - Reset and close on invalid

‹ April 2026 ›
Su Mo Tu We Th Fr Sa

29 30 31 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 1 2
3 4 5 6 7 8 9

Saved value:

SaveableDateInput (only month)

‹ 2026 ›

Jan Feb Mar Apr
May Jun Jul Aug
Sep Oct Nov Dec

SaveableDateInput (disabled)

‹ April 2026 ›
Su Mo Tu We Th Fr Sa

29 30 31 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 1 2
3 4 5 6 7 8 9

4:57 PM

#### React (tsx)

```tsx
import SaveableDateInput from '@rio-cloud/rio-uikit/SaveableDateInput';
import FormLabel from '@rio-cloud/rio-uikit/FormLabel';
import { useState } from 'react';
import moment, { type Moment } from 'moment';

/**
 * The Datepicker returns either a Moment object if date is valid or the input as string
 * if it's not a valid date
 */
const isValidDate = (input: Moment | string) => typeof input !== 'string';

export default () => {
    // Controlled example with "stay-open" behavior (default)
    const [savedValue1, setSavedValue1] = useState<Moment | string>('');
    const [currentTransientInput1, setCurrentTransientInput1] = useState<Moment | string>(moment(new Date()));
    const [isValid1, setIsValid1] = useState<boolean>(true);

    const handleSaveValue1 = (newValue: string | Date | Moment, previousValue: string | Date | Moment) => {
        console.log('Saving value:', newValue, 'Previous:', previousValue);
        setSavedValue1(newValue as Moment);
        setCurrentTransientInput1(newValue as Moment | string);
    };

    const handleTransientInputChange1 = (input: Moment | string, isValid: boolean) => {
        console.log('Input changed:', input, 'Valid:', isValid);
        setCurrentTransientInput1(input);
        setIsValid1(isValid);
    };

    // Controlled example with "reset-and-close" behavior
    const [savedValue2, setSavedValue2] = useState<Moment | string>('');
    const [currentTransientInput2, setCurrentTransientInput2] = useState<Moment | string>();
    const [isValid2, setIsValid2] = useState<boolean>(true);

    const handleSaveValue2 = (newValue: string | Date | Moment, previousValue: string | Date | Moment) => {
        console.log('Saving value 2:', newValue, 'Previous:', previousValue);
        setSavedValue2(newValue as Moment);
        setCurrentTransientInput2(newValue as Moment | string);
    };

    const handleTransientInputChange2 = (input: Moment | string, isValid: boolean) => {
        console.log('Input changed 2:', input, 'Valid:', isValid);
        setCurrentTransientInput2(input);

        // Custom validation: date must be valid AND newer than last week
        let customIsValid = isValid;
        if (isValid && isValidDate(input)) {
            const lastWeek = moment().subtract(7, 'days').startOf('day');
            customIsValid = input.isAfter(lastWeek);
        }

        setIsValid2(customIsValid);
    };

    // Controlled example with "stay-open" behavior (default)
    const [savedValue3, setSavedValue3] = useState<Moment | string>('');
    const [currentTransientInput3, setCurrentTransientInput3] = useState<Moment | string>();
    const [isValid3, setIsValid3] = useState<boolean>(true);

    const handleSaveValue3 = (newValue: string | Date | Moment, previousValue: string | Date | Moment) => {
        console.log('Saving value:', newValue, 'Previous:', previousValue);
        setSavedValue3(newValue as Moment);
        setCurrentTransientInput3(newValue as Moment | string);
    };

    const handleTransientInputChange3 = (input: Moment | string, isValid: boolean) => {
        console.log('Input changed:', input, 'Valid:', isValid);
        setCurrentTransientInput3(input);
        setIsValid3(isValid);
    };

    const handleCancel1 = () => {
        console.log('Edit cancelled - resetting to saved value');
        setCurrentTransientInput1(savedValue1);
        setIsValid1(true);
    };

    const handleCancel2 = () => {
        console.log('Edit cancelled - resetting to saved value');
        setCurrentTransientInput2(savedValue2);
        setIsValid2(true);
    };

    const handleCancel3 = () => {
        console.log('Edit cancelled - resetting to saved value');
        setCurrentTransientInput3(savedValue2);
        setIsValid3(true);
    };

    const handleExitEdit = (wasSaved: boolean) => {
        console.log('Exited edit mode, was saved:', wasSaved);
    };

    return (
        <div className='margin-bottom-50 display-flex flex-wrap flex-direction-column gap-25'>
            <div className='width-300'>
                <FormLabel>SaveableDateInput (uncontrolled)</FormLabel>
                <SaveableDateInput
                    placeholder='Delivery date'
                    datePickerProps={{ dateFormat: 'YYYY-MM-DD', timeFormat: false }}
                    onValueChanged={(value, _) => console.log('Uncontrolled saved:', value)}
                />
            </div>

            <div className='width-300'>
                <div className='form-group'>
                    <FormLabel>Controlled - Stay open on invalid (default)</FormLabel>
                    <SaveableDateInput
                        value={currentTransientInput1}
                        isValid={isValid1}
                        onValueChanged={handleSaveValue1}
                        onInputChange={handleTransientInputChange1}
                        onCancel={handleCancel1}
                        onExitEdit={handleExitEdit}
                        className='margin-0'
                        placeholder='Enter valid date'
                        datePickerProps={{ dateFormat: 'YYYY-MM-DD', timeFormat: 'hh:mm' }}
                        invalidExitBehavior='stay-open'
                        inputProps={{ style: { padding: '0' } }}
                        errorMessage='Please enter a valid date'
                    />
                </div>
                <div className='margin-top-10'>
                    <small>
                        Saved value: {isValidDate(savedValue1) ? savedValue1.format('YYYY-MM-DD') : String(savedValue1)}
                    </small>
                </div>
            </div>

            <div className='width-300'>
                <div className='form-group'>
                    <FormLabel>Controlled - With error</FormLabel>
                    <SaveableDateInput
                        value={currentTransientInput3}
                        isValid={!!currentTransientInput3}
                        onValueChanged={handleSaveValue3}
                        onInputChange={handleTransientInputChange3}
                        onCancel={handleCancel3}
                        onExitEdit={handleExitEdit}
                        className='margin-0'
                        placeholder='Enter a date'
                        datePickerProps={{ dateFormat: 'YYYY-MM-DD', timeFormat: 'hh:mm' }}
                        invalidExitBehavior='stay-open'
                        inputProps={{ style: { padding: '0' } }}
                        errorMessage='Required field'
                        hideErrorIcon
                    />
                </div>
                <div className='margin-top-10'>
                    <small>
                        Saved value: {isValidDate(savedValue1) ? savedValue1.format('YYYY-MM-DD') : String(savedValue1)}
                    </small>
                </div>
            </div>

            <div className='width-300'>
                <div className='form-group'>
                    <FormLabel>Controlled - Reset and close on invalid</FormLabel>
                    <SaveableDateInput
                        value={currentTransientInput2}
                        isValid={isValid2}
                        onValueChanged={handleSaveValue2}
                        onInputChange={handleTransientInputChange2}
                        onCancel={handleCancel2}
                        onExitEdit={handleExitEdit}
                        className='margin-0'
                        placeholder='Enter date after last week'
                        datePickerProps={{ dateFormat: 'YYYY-MM-DD', timeFormat: false }}
                        invalidExitBehavior='reset-and-close'
                        data-testid='demo-testid'
                        errorMessage={
                            <span>
                                Please enter a valid date that is newer than{' '}
                                {moment().subtract(7, 'days').format('YYYY-MM-DD')}
                            </span>
                        }
                    />
                </div>
                <div className='margin-top-10'>
                    <small>
                        Saved value: {isValidDate(savedValue2) ? savedValue2.format('YYYY-MM-DD') : String(savedValue2)}
                    </small>
                </div>
            </div>

            <div className='width-300'>
                <FormLabel>SaveableDateInput (only month)</FormLabel>
                <SaveableDateInput
                    placeholder='Target month'
                    datePickerProps={{ dateFormat: 'YYYY-MM', timeFormat: false }}
                    onValueChanged={(value, _) => console.log('Month saved:', value)}
                />
            </div>

            <div className='width-300'>
                <FormLabel>SaveableDateInput (disabled)</FormLabel>
                <SaveableDateInput value={new Date()} disabled />
            </div>
        </div>
    );
};
```

#### HTML (html)

```html
<div class="margin-bottom-50 display-flex flex-wrap flex-direction-column gap-25">
    <div class="width-300">
        <div class="text-color-dark max-width-100pct text-size-12 display-inline-block margin-bottom-5">SaveableDateInput (uncontrolled)</div>
        <div class="form-group">
            <div class="input-group">
                <div class="rdt DatePicker form-group margin-0 width-100pct">
                    <div class="input-group">
                        <span class="input-group-addon">
                            <span class="rioglyph rioglyph-calendar" aria-hidden="true">
                            </span>
                        </span>
                        <div class="ClearableInput input-group">
                            <input type="text" class="form-control" placeholder="Delivery date" disabled="" value="" style="border-top-right-radius: 0px; border-bottom-right-radius: 0px;">
                        </div>
                    </div>
                    <div class="rdtPicker">
                        <div class="rdtDays">
                            <table>
                                <thead>
                                    <tr>
                                        <th class="rdtPrev">
                                            <span>‹</span>
                                        </th>
                                        <th class="rdtSwitch" colspan="5" data-value="3">April 2026</th>
                                        <th class="rdtNext">
                                            <span>›</span>
                                        </th>
                                    </tr>
                                    <tr>
                                        <th class="dow">Su</th>
                                        <th class="dow">Mo</th>
                                        <th class="dow">Tu</th>
                                        <th class="dow">We</th>
                                        <th class="dow">Th</th>
                                        <th class="dow">Fr</th>
                                        <th class="dow">Sa</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <tr>
                                        <td data-value="29" data-month="2" data-year="2026" class="rdtDay rdtOld">29</td>
                                        <td data-value="30" data-month="2" data-year="2026" class="rdtDay rdtOld">30</td>
                                        <td data-value="31" data-month="2" data-year="2026" class="rdtDay rdtOld">31</td>
                                        <td data-value="1" data-month="3" data-year="2026" class="rdtDay">1</td>
                                        <td data-value="2" data-month="3" data-year="2026" class="rdtDay">2</td>
                                        <td data-value="3" data-month="3" data-year="2026" class="rdtDay">3</td>
                                        <td data-value="4" data-month="3" data-year="2026" class="rdtDay">4</td>
                                    </tr>
                                    <tr>
                                        <td data-value="5" data-month="3" data-year="2026" class="rdtDay">5</td>
                                        <td data-value="6" data-month="3" data-year="2026" class="rdtDay">6</td>
                                        <td data-value="7" data-month="3" data-year="2026" class="rdtDay">7</td>
                                        <td data-value="8" data-month="3" data-year="2026" class="rdtDay">8</td>
                                        <td data-value="9" data-month="3" data-year="2026" class="rdtDay">9</td>
                                        <td data-value="10" data-month="3" data-year="2026" class="rdtDay">10</td>
                                        <td data-value="11" data-month="3" data-year="2026" class="rdtDay">11</td>
                                    </tr>
                                    <tr>
                                        <td data-value="12" data-month="3" data-year="2026" class="rdtDay">12</td>
                                        <td data-value="13" data-month="3" data-year="2026" class="rdtDay">13</td>
                                        <td data-value="14" data-month="3" data-year="2026" class="rdtDay">14</td>
                                        <td data-value="15" data-month="3" data-year="2026" class="rdtDay">15</td>
                                        <td data-value="16" data-month="3" data-year="2026" class="rdtDay">16</td>
                                        <td data-value="17" data-month="3" data-year="2026" class="rdtDay">17</td>
                                        <td data-value="18" data-month="3" data-year="2026" class="rdtDay">18</td>
                                    </tr>
                                    <tr>
                                        <td data-value="19" data-month="3" data-year="2026" class="rdtDay">19</td>
                                        <td data-value="20" data-month="3" data-year="2026" class="rdtDay">20</td>
                                        <td data-value="21" data-month="3" data-year="2026" class="rdtDay">21</td>
                                        <td data-value="22" data-month="3" data-year="2026" class="rdtDay">22</td>
                                        <td data-value="23" data-month="3" data-year="2026" class="rdtDay">23</td>
                                        <td data-value="24" data-month="3" data-year="2026" class="rdtDay">24</td>
                                        <td data-value="25" data-month="3" data-year="2026" class="rdtDay">25</td>
                                    </tr>
                                    <tr>
                                        <td data-value="26" data-month="3" data-year="2026" class="rdtDay">26</td>
                                        <td data-value="27" data-month="3" data-year="2026" class="rdtDay rdtToday">27</td>
                                        <td data-value="28" data-month="3" data-year="2026" class="rdtDay">28</td>
                                        <td data-value="29" data-month="3" data-year="2026" class="rdtDay">29</td>
                                        <td data-value="30" data-month="3" data-year="2026" class="rdtDay">30</td>
                                        <td data-value="1" data-month="4" data-year="2026" class="rdtDay rdtNew">1</td>
                                        <td data-value="2" data-month="4" data-year="2026" class="rdtDay rdtNew">2</td>
                                    </tr>
                                    <tr>
                                        <td data-value="3" data-month="4" data-year="2026" class="rdtDay rdtNew">3</td>
                                        <td data-value="4" data-month="4" data-year="2026" class="rdtDay rdtNew">4</td>
                                        <td data-value="5" data-month="4" data-year="2026" class="rdtDay rdtNew">5</td>
                                        <td data-value="6" data-month="4" data-year="2026" class="rdtDay rdtNew">6</td>
                                        <td data-value="7" data-month="4" data-year="2026" class="rdtDay rdtNew">7</td>
                                        <td data-value="8" data-month="4" data-year="2026" class="rdtDay rdtNew">8</td>
                                        <td data-value="9" data-month="4" data-year="2026" class="rdtDay rdtNew">9</td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
                <div class="input-group-btn">
                    <button type="button" class="btn btn-primary btn-icon-only btn-component" tabindex="0">
                        <span class="rioglyph rioglyph-pencil">
                        </span>
                    </button>
                </div>
            </div>
        </div>
    </div>
    <div class="width-300">
        <div class="form-group">
            <div class="text-color-dark max-width-100pct text-size-12 display-inline-block margin-bottom-5">Controlled - Stay open on invalid (default)</div>
            <div class="form-group margin-0">
                <div class="input-group">
                    <div class="rdt DatePicker form-group margin-0 width-100pct">
                        <div class="input-group">
                            <span class="input-group-addon">
                                <span class="rioglyph rioglyph-calendar" aria-hidden="true">
                                </span>
                            </span>
                            <div class="ClearableInput input-group">
                                <input type="text" class="form-control" placeholder="Enter valid date" disabled="" value="2026-04-27 04:57" style="border-top-right-radius: 0px; border-bottom-right-radius: 0px;">
                            </div>
                        </div>
                        <div class="rdtPicker">
                            <div class="rdtDays">
                                <table>
                                    <thead>
                                        <tr>
                                            <th class="rdtPrev">
                                                <span>‹</span>
                                            </th>
                                            <th class="rdtSwitch" colspan="5" data-value="3">April 2026</th>
                                            <th class="rdtNext">
                                                <span>›</span>
                                            </th>
                                        </tr>
                                        <tr>
                                            <th class="dow">Su</th>
                                            <th class="dow">Mo</th>
                                            <th class="dow">Tu</th>
                                            <th class="dow">We</th>
                                            <th class="dow">Th</th>
                                            <th class="dow">Fr</th>
                                            <th class="dow">Sa</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <tr>
                                            <td data-value="29" data-month="2" data-year="2026" class="rdtDay rdtOld">29</td>
                                            <td data-value="30" data-month="2" data-year="2026" class="rdtDay rdtOld">30</td>
                                            <td data-value="31" data-month="2" data-year="2026" class="rdtDay rdtOld">31</td>
                                            <td data-value="1" data-month="3" data-year="2026" class="rdtDay">1</td>
                                            <td data-value="2" data-month="3" data-year="2026" class="rdtDay">2</td>
                                            <td data-value="3" data-month="3" data-year="2026" class="rdtDay">3</td>
                                            <td data-value="4" data-month="3" data-year="2026" class="rdtDay">4</td>
                                        </tr>
                                        <tr>
                                            <td data-value="5" data-month="3" data-year="2026" class="rdtDay">5</td>
                                            <td data-value="6" data-month="3" data-year="2026" class="rdtDay">6</td>
                                            <td data-value="7" data-month="3" data-year="2026" class="rdtDay">7</td>
                                            <td data-value="8" data-month="3" data-year="2026" class="rdtDay">8</td>
                                            <td data-value="9" data-month="3" data-year="2026" class="rdtDay">9</td>
                                            <td data-value="10" data-month="3" data-year="2026" class="rdtDay">10</td>
                                            <td data-value="11" data-month="3" data-year="2026" class="rdtDay">11</td>
                                        </tr>
                                        <tr>
                                            <td data-value="12" data-month="3" data-year="2026" class="rdtDay">12</td>
                                            <td data-value="13" data-month="3" data-year="2026" class="rdtDay">13</td>
                                            <td data-value="14" data-month="3" data-year="2026" class="rdtDay">14</td>
                                            <td data-value="15" data-month="3" data-year="2026" class="rdtDay">15</td>
                                            <td data-value="16" data-month="3" data-year="2026" class="rdtDay">16</td>
                                            <td data-value="17" data-month="3" data-year="2026" class="rdtDay">17</td>
                                            <td data-value="18" data-month="3" data-year="2026" class="rdtDay">18</td>
                                        </tr>
                                        <tr>
                                            <td data-value="19" data-month="3" data-year="2026" class="rdtDay">19</td>
                                            <td data-value="20" data-month="3" data-year="2026" class="rdtDay">20</td>
                                            <td data-value="21" data-month="3" data-year="2026" class="rdtDay">21</td>
                                            <td data-value="22" data-month="3" data-year="2026" class="rdtDay">22</td>
                                            <td data-value="23" data-month="3" data-year="2026" class="rdtDay">23</td>
                                            <td data-value="24" data-month="3" data-year="2026" class="rdtDay">24</td>
                                            <td data-value="25" data-month="3" data-year="2026" class="rdtDay">25</td>
                                        </tr>
                                        <tr>
                                            <td data-value="26" data-month="3" data-year="2026" class="rdtDay">26</td>
                                            <td data-value="27" data-month="3" data-year="2026" class="rdtDay rdtActive rdtToday">27</td>
                                            <td data-value="28" data-month="3" data-year="2026" class="rdtDay">28</td>
                                            <td data-value="29" data-month="3" data-year="2026" class="rdtDay">29</td>
                                            <td data-value="30" data-month="3" data-year="2026" class="rdtDay">30</td>
                                            <td data-value="1" data-month="4" data-year="2026" class="rdtDay rdtNew">1</td>
                                            <td data-value="2" data-month="4" data-year="2026" class="rdtDay rdtNew">2</td>
                                        </tr>
                                        <tr>
                                            <td data-value="3" data-month="4" data-year="2026" class="rdtDay rdtNew">3</td>
                                            <td data-value="4" data-month="4" data-year="2026" class="rdtDay rdtNew">4</td>
                                            <td data-value="5" data-month="4" data-year="2026" class="rdtDay rdtNew">5</td>
                                            <td data-value="6" data-month="4" data-year="2026" class="rdtDay rdtNew">6</td>
                                            <td data-value="7" data-month="4" data-year="2026" class="rdtDay rdtNew">7</td>
                                            <td data-value="8" data-month="4" data-year="2026" class="rdtDay rdtNew">8</td>
                                            <td data-value="9" data-month="4" data-year="2026" class="rdtDay rdtNew">9</td>
                                        </tr>
                                    </tbody>
                                    <tfoot>
                                        <tr>
                                            <td colspan="7" class="rdtTimeToggle">04:57</td>
                                        </tr>
                                    </tfoot>
                                </table>
                            </div>
                        </div>
                    </div>
                    <div class="input-group-btn">
                        <button type="button" class="btn btn-primary btn-icon-only btn-component" tabindex="0">
                            <span class="rioglyph rioglyph-pencil">
                            </span>
                        </button>
                    </div>
                </div>
            </div>
        </div>
        <div class="margin-top-10">
            <small>Saved value: </small>
        </div>
    </div>
    <div class="width-300">
        <div class="form-group">
            <div class="text-color-dark max-width-100pct text-size-12 display-inline-block margin-bottom-5">Controlled - With error</div>
            <div class="form-group has-feedback has-error margin-0">
                <div class="input-group">
                    <div class="rdt DatePicker form-group margin-0 width-100pct">
                        <div class="input-group">
                            <span class="input-group-addon">
                                <span class="rioglyph rioglyph-calendar" aria-hidden="true">
                                </span>
                            </span>
                            <div class="ClearableInput input-group">
                                <input type="text" class="form-control" placeholder="Enter a date" disabled="" value="" style="border-top-right-radius: 0px; border-bottom-right-radius: 0px; padding-right: 10px;">
                            </div>
                        </div>
                        <div class="rdtPicker">
                            <div class="rdtDays">
                                <table>
                                    <thead>
                                        <tr>
                                            <th class="rdtPrev">
                                                <span>‹</span>
                                            </th>
                                            <th class="rdtSwitch" colspan="5" data-value="3">April 2026</th>
                                            <th class="rdtNext">
                                                <span>›</span>
                                            </th>
                                        </tr>
                                        <tr>
                                            <th class="dow">Su</th>
                                            <th class="dow">Mo</th>
                                            <th class="dow">Tu</th>
                                            <th class="dow">We</th>
                                            <th class="dow">Th</th>
                                            <th class="dow">Fr</th>
                                            <th class="dow">Sa</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <tr>
                                            <td data-value="29" data-month="2" data-year="2026" class="rdtDay rdtOld">29</td>
                                            <td data-value="30" data-month="2" data-year="2026" class="rdtDay rdtOld">30</td>
                                            <td data-value="31" data-month="2" data-year="2026" class="rdtDay rdtOld">31</td>
                                            <td data-value="1" data-month="3" data-year="2026" class="rdtDay">1</td>
                                            <td data-value="2" data-month="3" data-year="2026" class="rdtDay">2</td>
                                            <td data-value="3" data-month="3" data-year="2026" class="rdtDay">3</td>
                                            <td data-value="4" data-month="3" data-year="2026" class="rdtDay">4</td>
                                        </tr>
                                        <tr>
                                            <td data-value="5" data-month="3" data-year="2026" class="rdtDay">5</td>
                                            <td data-value="6" data-month="3" data-year="2026" class="rdtDay">6</td>
                                            <td data-value="7" data-month="3" data-year="2026" class="rdtDay">7</td>
                                            <td data-value="8" data-month="3" data-year="2026" class="rdtDay">8</td>
                                            <td data-value="9" data-month="3" data-year="2026" class="rdtDay">9</td>
                                            <td data-value="10" data-month="3" data-year="2026" class="rdtDay">10</td>
                                            <td data-value="11" data-month="3" data-year="2026" class="rdtDay">11</td>
                                        </tr>
                                        <tr>
                                            <td data-value="12" data-month="3" data-year="2026" class="rdtDay">12</td>
                                            <td data-value="13" data-month="3" data-year="2026" class="rdtDay">13</td>
                                            <td data-value="14" data-month="3" data-year="2026" class="rdtDay">14</td>
                                            <td data-value="15" data-month="3" data-year="2026" class="rdtDay">15</td>
                                            <td data-value="16" data-month="3" data-year="2026" class="rdtDay">16</td>
                                            <td data-value="17" data-month="3" data-year="2026" class="rdtDay">17</td>
                                            <td data-value="18" data-month="3" data-year="2026" class="rdtDay">18</td>
                                        </tr>
                                        <tr>
                                            <td data-value="19" data-month="3" data-year="2026" class="rdtDay">19</td>
                                            <td data-value="20" data-month="3" data-year="2026" class="rdtDay">20</td>
                                            <td data-value="21" data-month="3" data-year="2026" class="rdtDay">21</td>
                                            <td data-value="22" data-month="3" data-year="2026" class="rdtDay">22</td>
                                            <td data-value="23" data-month="3" data-year="2026" class="rdtDay">23</td>
                                            <td data-value="24" data-month="3" data-year="2026" class="rdtDay">24</td>
                                            <td data-value="25" data-month="3" data-year="2026" class="rdtDay">25</td>
                                        </tr>
                                        <tr>
                                            <td data-value="26" data-month="3" data-year="2026" class="rdtDay">26</td>
                                            <td data-value="27" data-month="3" data-year="2026" class="rdtDay rdtToday">27</td>
                                            <td data-value="28" data-month="3" data-year="2026" class="rdtDay">28</td>
                                            <td data-value="29" data-month="3" data-year="2026" class="rdtDay">29</td>
                                            <td data-value="30" data-month="3" data-year="2026" class="rdtDay">30</td>
                                            <td data-value="1" data-month="4" data-year="2026" class="rdtDay rdtNew">1</td>
                                            <td data-value="2" data-month="4" data-year="2026" class="rdtDay rdtNew">2</td>
                                        </tr>
                                        <tr>
                                            <td data-value="3" data-month="4" data-year="2026" class="rdtDay rdtNew">3</td>
                                            <td data-value="4" data-month="4" data-year="2026" class="rdtDay rdtNew">4</td>
                                            <td data-value="5" data-month="4" data-year="2026" class="rdtDay rdtNew">5</td>
                                            <td data-value="6" data-month="4" data-year="2026" class="rdtDay rdtNew">6</td>
                                            <td data-value="7" data-month="4" data-year="2026" class="rdtDay rdtNew">7</td>
                                            <td data-value="8" data-month="4" data-year="2026" class="rdtDay rdtNew">8</td>
                                            <td data-value="9" data-month="4" data-year="2026" class="rdtDay rdtNew">9</td>
                                        </tr>
                                    </tbody>
                                    <tfoot>
                                        <tr>
                                            <td colspan="7" class="rdtTimeToggle">12:00</td>
                                        </tr>
                                    </tfoot>
                                </table>
                            </div>
                        </div>
                    </div>
                    <div class="input-group-btn">
                        <button type="button" class="btn btn-primary btn-icon-only btn-component" tabindex="0">
                            <span class="rioglyph rioglyph-pencil">
                            </span>
                        </button>
                    </div>
                </div>
                <span class="help-block z-index-max">
                    <span>Required field</span>
                </span>
            </div>
        </div>
        <div class="margin-top-10">
            <small>Saved value: </small>
        </div>
    </div>
    <div class="width-300">
        <div class="form-group">
            <div class="text-color-dark max-width-100pct text-size-12 display-inline-block margin-bottom-5">Controlled - Reset and close on invalid</div>
            <div data-testid="demo-testid" class="form-group margin-0">
                <div class="input-group">
                    <div class="rdt DatePicker form-group margin-0 width-100pct">
                        <div class="input-group">
                            <span class="input-group-addon">
                                <span class="rioglyph rioglyph-calendar" aria-hidden="true">
                                </span>
                            </span>
                            <div class="ClearableInput input-group">
                                <input type="text" class="form-control" placeholder="Enter date after last week" disabled="" value="" style="border-top-right-radius: 0px; border-bottom-right-radius: 0px;">
                            </div>
                        </div>
                        <div class="rdtPicker">
                            <div class="rdtDays">
                                <table>
                                    <thead>
                                        <tr>
                                            <th class="rdtPrev">
                                                <span>‹</span>
                                            </th>
                                            <th class="rdtSwitch" colspan="5" data-value="3">April 2026</th>
                                            <th class="rdtNext">
                                                <span>›</span>
                                            </th>
                                        </tr>
                                        <tr>
                                            <th class="dow">Su</th>
                                            <th class="dow">Mo</th>
                                            <th class="dow">Tu</th>
                                            <th class="dow">We</th>
                                            <th class="dow">Th</th>
                                            <th class="dow">Fr</th>
                                            <th class="dow">Sa</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <tr>
                                            <td data-value="29" data-month="2" data-year="2026" class="rdtDay rdtOld">29</td>
                                            <td data-value="30" data-month="2" data-year="2026" class="rdtDay rdtOld">30</td>
                                            <td data-value="31" data-month="2" data-year="2026" class="rdtDay rdtOld">31</td>
                                            <td data-value="1" data-month="3" data-year="2026" class="rdtDay">1</td>
                                            <td data-value="2" data-month="3" data-year="2026" class="rdtDay">2</td>
                                            <td data-value="3" data-month="3" data-year="2026" class="rdtDay">3</td>
                                            <td data-value="4" data-month="3" data-year="2026" class="rdtDay">4</td>
                                        </tr>
                                        <tr>
                                            <td data-value="5" data-month="3" data-year="2026" class="rdtDay">5</td>
                                            <td data-value="6" data-month="3" data-year="2026" class="rdtDay">6</td>
                                            <td data-value="7" data-month="3" data-year="2026" class="rdtDay">7</td>
                                            <td data-value="8" data-month="3" data-year="2026" class="rdtDay">8</td>
                                            <td data-value="9" data-month="3" data-year="2026" class="rdtDay">9</td>
                                            <td data-value="10" data-month="3" data-year="2026" class="rdtDay">10</td>
                                            <td data-value="11" data-month="3" data-year="2026" class="rdtDay">11</td>
                                        </tr>
                                        <tr>
                                            <td data-value="12" data-month="3" data-year="2026" class="rdtDay">12</td>
                                            <td data-value="13" data-month="3" data-year="2026" class="rdtDay">13</td>
                                            <td data-value="14" data-month="3" data-year="2026" class="rdtDay">14</td>
                                            <td data-value="15" data-month="3" data-year="2026" class="rdtDay">15</td>
                                            <td data-value="16" data-month="3" data-year="2026" class="rdtDay">16</td>
                                            <td data-value="17" data-month="3" data-year="2026" class="rdtDay">17</td>
                                            <td data-value="18" data-month="3" data-year="2026" class="rdtDay">18</td>
                                        </tr>
                                        <tr>
                                            <td data-value="19" data-month="3" data-year="2026" class="rdtDay">19</td>
                                            <td data-value="20" data-month="3" data-year="2026" class="rdtDay">20</td>
                                            <td data-value="21" data-month="3" data-year="2026" class="rdtDay">21</td>
                                            <td data-value="22" data-month="3" data-year="2026" class="rdtDay">22</td>
                                            <td data-value="23" data-month="3" data-year="2026" class="rdtDay">23</td>
                                            <td data-value="24" data-month="3" data-year="2026" class="rdtDay">24</td>
                                            <td data-value="25" data-month="3" data-year="2026" class="rdtDay">25</td>
                                        </tr>
                                        <tr>
                                            <td data-value="26" data-month="3" data-year="2026" class="rdtDay">26</td>
                                            <td data-value="27" data-month="3" data-year="2026" class="rdtDay rdtToday">27</td>
                                            <td data-value="28" data-month="3" data-year="2026" class="rdtDay">28</td>
                                            <td data-value="29" data-month="3" data-year="2026" class="rdtDay">29</td>
                                            <td data-value="30" data-month="3" data-year="2026" class="rdtDay">30</td>
                                            <td data-value="1" data-month="4" data-year="2026" class="rdtDay rdtNew">1</td>
                                            <td data-value="2" data-month="4" data-year="2026" class="rdtDay rdtNew">2</td>
                                        </tr>
                                        <tr>
                                            <td data-value="3" data-month="4" data-year="2026" class="rdtDay rdtNew">3</td>
                                            <td data-value="4" data-month="4" data-year="2026" class="rdtDay rdtNew">4</td>
                                            <td data-value="5" data-month="4" data-year="2026" class="rdtDay rdtNew">5</td>
                                            <td data-value="6" data-month="4" data-year="2026" class="rdtDay rdtNew">6</td>
                                            <td data-value="7" data-month="4" data-year="2026" class="rdtDay rdtNew">7</td>
                                            <td data-value="8" data-month="4" data-year="2026" class="rdtDay rdtNew">8</td>
                                            <td data-value="9" data-month="4" data-year="2026" class="rdtDay rdtNew">9</td>
                                        </tr>
                                    </tbody>
                                </table>
                            </div>
                        </div>
                    </div>
                    <div class="input-group-btn">
                        <button type="button" class="btn btn-primary btn-icon-only btn-component" tabindex="0">
                            <span class="rioglyph rioglyph-pencil">
                            </span>
                        </button>
                    </div>
                </div>
            </div>
        </div>
        <div class="margin-top-10">
            <small>Saved value: </small>
        </div>
    </div>
    <div class="width-300">
        <div class="text-color-dark max-width-100pct text-size-12 display-inline-block margin-bottom-5">SaveableDateInput (only month)</div>
        <div class="form-group">
            <div class="input-group">
                <div class="rdt DatePicker form-group margin-0 width-100pct">
                    <div class="input-group">
                        <span class="input-group-addon">
                            <span class="rioglyph rioglyph-calendar" aria-hidden="true">
                            </span>
                        </span>
                        <div class="ClearableInput input-group">
                            <input type="text" class="form-control" placeholder="Target month" disabled="" value="" style="border-top-right-radius: 0px; border-bottom-right-radius: 0px;">
                        </div>
                    </div>
                    <div class="rdtPicker">
                        <div class="rdtMonths">
                            <table>
                                <thead>
                                    <tr>
                                        <th class="rdtPrev">
                                            <span>‹</span>
                                        </th>
                                        <th class="rdtSwitch" colspan="2">2026</th>
                                        <th class="rdtNext">
                                            <span>›</span>
                                        </th>
                                    </tr>
                                </thead>
                            </table>
                            <table>
                                <tbody>
                                    <tr>
                                        <td class="rdtMonth" data-value="0">Jan</td>
                                        <td class="rdtMonth" data-value="1">Feb</td>
                                        <td class="rdtMonth" data-value="2">Mar</td>
                                        <td class="rdtMonth" data-value="3">Apr</td>
                                    </tr>
                                    <tr>
                                        <td class="rdtMonth" data-value="4">May</td>
                                        <td class="rdtMonth" data-value="5">Jun</td>
                                        <td class="rdtMonth" data-value="6">Jul</td>
                                        <td class="rdtMonth" data-value="7">Aug</td>
                                    </tr>
                                    <tr>
                                        <td class="rdtMonth" data-value="8">Sep</td>
                                        <td class="rdtMonth" data-value="9">Oct</td>
                                        <td class="rdtMonth" data-value="10">Nov</td>
                                        <td class="rdtMonth" data-value="11">Dec</td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
                <div class="input-group-btn">
                    <button type="button" class="btn btn-primary btn-icon-only btn-component" tabindex="0">
                        <span class="rioglyph rioglyph-pencil">
                        </span>
                    </button>
                </div>
            </div>
        </div>
    </div>
    <div class="width-300">
        <div class="text-color-dark max-width-100pct text-size-12 display-inline-block margin-bottom-5">SaveableDateInput (disabled)</div>
        <div class="form-group">
            <div class="input-group">
                <div class="rdt DatePicker form-group margin-0 width-100pct">
                    <div class="input-group">
                        <span class="input-group-addon">
                            <span class="rioglyph rioglyph-calendar" aria-hidden="true">
                            </span>
                        </span>
                        <div class="ClearableInput input-group">
                            <input type="text" class="form-control" disabled="" value="04/27/2026 4:57 PM" style="border-top-right-radius: 0px; border-bottom-right-radius: 0px;">
                        </div>
                    </div>
                    <div class="rdtPicker">
                        <div class="rdtDays">
                            <table>
                                <thead>
                                    <tr>
                                        <th class="rdtPrev">
                                            <span>‹</span>
                                        </th>
                                        <th class="rdtSwitch" colspan="5" data-value="3">April 2026</th>
                                        <th class="rdtNext">
                                            <span>›</span>
                                        </th>
                                    </tr>
                                    <tr>
                                        <th class="dow">Su</th>
                                        <th class="dow">Mo</th>
                                        <th class="dow">Tu</th>
                                        <th class="dow">We</th>
                                        <th class="dow">Th</th>
                                        <th class="dow">Fr</th>
                                        <th class="dow">Sa</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <tr>
                                        <td data-value="29" data-month="2" data-year="2026" class="rdtDay rdtOld">29</td>
                                        <td data-value="30" data-month="2" data-year="2026" class="rdtDay rdtOld">30</td>
                                        <td data-value="31" data-month="2" data-year="2026" class="rdtDay rdtOld">31</td>
                                        <td data-value="1" data-month="3" data-year="2026" class="rdtDay">1</td>
                                        <td data-value="2" data-month="3" data-year="2026" class="rdtDay">2</td>
                                        <td data-value="3" data-month="3" data-year="2026" class="rdtDay">3</td>
                                        <td data-value="4" data-month="3" data-year="2026" class="rdtDay">4</td>
                                    </tr>
                                    <tr>
                                        <td data-value="5" data-month="3" data-year="2026" class="rdtDay">5</td>
                                        <td data-value="6" data-month="3" data-year="2026" class="rdtDay">6</td>
                                        <td data-value="7" data-month="3" data-year="2026" class="rdtDay">7</td>
                                        <td data-value="8" data-month="3" data-year="2026" class="rdtDay">8</td>
                                        <td data-value="9" data-month="3" data-year="2026" class="rdtDay">9</td>
                                        <td data-value="10" data-month="3" data-year="2026" class="rdtDay">10</td>
                                        <td data-value="11" data-month="3" data-year="2026" class="rdtDay">11</td>
                                    </tr>
                                    <tr>
                                        <td data-value="12" data-month="3" data-year="2026" class="rdtDay">12</td>
                                        <td data-value="13" data-month="3" data-year="2026" class="rdtDay">13</td>
                                        <td data-value="14" data-month="3" data-year="2026" class="rdtDay">14</td>
                                        <td data-value="15" data-month="3" data-year="2026" class="rdtDay">15</td>
                                        <td data-value="16" data-month="3" data-year="2026" class="rdtDay">16</td>
                                        <td data-value="17" data-month="3" data-year="2026" class="rdtDay">17</td>
                                        <td data-value="18" data-month="3" data-year="2026" class="rdtDay">18</td>
                                    </tr>
                                    <tr>
                                        <td data-value="19" data-month="3" data-year="2026" class="rdtDay">19</td>
                                        <td data-value="20" data-month="3" data-year="2026" class="rdtDay">20</td>
                                        <td data-value="21" data-month="3" data-year="2026" class="rdtDay">21</td>
                                        <td data-value="22" data-month="3" data-year="2026" class="rdtDay">22</td>
                                        <td data-value="23" data-month="3" data-year="2026" class="rdtDay">23</td>
                                        <td data-value="24" data-month="3" data-year="2026" class="rdtDay">24</td>
                                        <td data-value="25" data-month="3" data-year="2026" class="rdtDay">25</td>
                                    </tr>
                                    <tr>
                                        <td data-value="26" data-month="3" data-year="2026" class="rdtDay">26</td>
                                        <td data-value="27" data-month="3" data-year="2026" class="rdtDay rdtActive rdtToday">27</td>
                                        <td data-value="28" data-month="3" data-year="2026" class="rdtDay">28</td>
                                        <td data-value="29" data-month="3" data-year="2026" class="rdtDay">29</td>
                                        <td data-value="30" data-month="3" data-year="2026" class="rdtDay">30</td>
                                        <td data-value="1" data-month="4" data-year="2026" class="rdtDay rdtNew">1</td>
                                        <td data-value="2" data-month="4" data-year="2026" class="rdtDay rdtNew">2</td>
                                    </tr>
                                    <tr>
                                        <td data-value="3" data-month="4" data-year="2026" class="rdtDay rdtNew">3</td>
                                        <td data-value="4" data-month="4" data-year="2026" class="rdtDay rdtNew">4</td>
                                        <td data-value="5" data-month="4" data-year="2026" class="rdtDay rdtNew">5</td>
                                        <td data-value="6" data-month="4" data-year="2026" class="rdtDay rdtNew">6</td>
                                        <td data-value="7" data-month="4" data-year="2026" class="rdtDay rdtNew">7</td>
                                        <td data-value="8" data-month="4" data-year="2026" class="rdtDay rdtNew">8</td>
                                        <td data-value="9" data-month="4" data-year="2026" class="rdtDay rdtNew">9</td>
                                    </tr>
                                </tbody>
                                <tfoot>
                                    <tr>
                                        <td colspan="7" class="rdtTimeToggle">4:57 PM</td>
                                    </tr>
                                </tfoot>
                            </table>
                        </div>
                    </div>
                </div>
                <div class="input-group-btn">
                    <button type="button" class="btn btn-primary btn-icon-only btn-component" disabled="" tabindex="0">
                        <span class="rioglyph rioglyph-pencil">
                        </span>
                    </button>
                </div>
            </div>
        </div>
    </div>
</div>
```

#### Props: SaveableDateInput

### SaveableDateInput

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| placeholder | string | — | The input placeholder. |
| value | Date \| Moment \| string | — | The actual input value. |
| isValid | boolean | true | Used to control the save button from the outside to disable it in case the entered value is not valid. |
| errorMessage | string \| React.ReactNode | — | This is the error message that is shown below the input. It uses the built-in error handling, and will be shown when the "isValid" prop is set to false. |
| hideErrorIcon | boolean | false | Defines wether the error icon is shown or not. If enabled, it will be shown when the "isValid" prop is set to false. |
| onValueChanged | (value: Moment \| string, previousValue: Moment \| string \| Date) => void | — | Callback function triggered when the value changes and is saved. |
| onInputChange | (value: Moment \| string, isValid: boolean) => void | — | Callback function that gets triggered on every input change. Use this to control the component or when implementing key validation. |
| onEnterEdit | () => void | — | Callback function that gets triggered when the input is in edit mode. Use this to control the component and to handle the previous value on the outside. |
| onExitEdit | (wasSaved: boolean) => void | — | Callback function that gets triggered when edit mode is exited (either saved or cancelled). |
| onCancel | () => void | — | Callback function that gets triggered when the user aborts the edit mode. Use this to control the component and handle the resetting of previous value on the outside. |
| invalidExitBehavior | 'stay-open' \| 'reset-and-close' | 'stay-open' | Behavior when trying to exit edit mode with invalid input: - 'stay-open': Keep edit mode open until valid input is provided - 'reset-and-close': Close edit mode and reset to initial value |
| buttonStyle | 'primary' \| 'default' | 'primary' | Defines the button style: default or primary. |
| inputProps | HTMLAttributes<HTMLInputElement> | — | Additional HTML attributes to be set on the input element. |
| datePickerProps | DatePickerProps | {} | Additional props passed to the underlying DatePicker component. |
| disabled | boolean | false | Disables the component so the user cannot enter the edit mode. |
| inputClassName | string | — | Additional classes to be set on the input itself. |
| className | string | — | Additional classes to be set on the wrapper element. |