Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# @gravity-ui/date-components · [![npm package](https://img.shields.io/npm/v/@gravity-ui/date-components)](https://www.npmjs.com/package/@gravity-ui/date-components) [![CI](https://img.shields.io/github/actions/workflow/status/gravity-ui/date-components/.github/workflows/ci.yml?label=CI&logo=github)](https://github.com/gravity-ui/date-components/actions/workflows/ci.yml?query=branch:main) [![storybook](https://img.shields.io/badge/Storybook-deployed-ff4685)](https://preview.gravity-ui.com/date-components/) [![coverage](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fstorage.yandexcloud.net%2Fplaywright-reports%2Fdate-components%2Fpulls%2Fmain%2Fcoverage%2Fcoverage-summary.json&query=%24.total.lines.pct&suffix=%25&label=Coverage)](https://storage.yandexcloud.net/playwright-reports/date-components/pulls/main/coverage/lcov-report/index.html) [![tests-report](https://img.shields.io/badge/Tests-report-ff4685)](https://storage.yandexcloud.net/playwright-reports/date-components/pulls/main/html/index.html)

## Install
Expand Down Expand Up @@ -109,6 +109,10 @@

React date and time controls for Gravity UI apps — date/time pickers, calendars, and absolute/relative range selectors built on `@gravity-ui/date-utils`.

### Migration notes

For migration guidance from 3.x to 4.x, see [docs/migration-3-to-4.md](docs/migration-3-to-4.md).

### When to use

- A single date or date-time input: `DatePicker`, `DateField`.
Expand Down
117 changes: 117 additions & 0 deletions docs/migration-3-to-4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Migration guide: 3.x → 4.x

This note summarizes the main behavior changes that are relevant for migration from version 3 to version 4.

## 1. RelativeDateField: `onUpdate` is now emitted only for valid input

### Before

The component could report intermediate values while the user was typing an incomplete or invalid relative expression.

```tsx
<RelativeDateField onUpdate={(value) => console.log(value)} />
```

Example flow:

- typing `now - 1` could already trigger `onUpdate('now - 1')`
- invalid draft text could still propagate while the input was being edited

### After

`onUpdate` is emitted only when the current input is valid.

```tsx
<RelativeDateField onUpdate={(value) => console.log(value)} />
```

Example flow:

- typing `now - 1` does not emit until the expression becomes valid
- invalid draft text is kept in the field, but the last committed value remains unchanged until the input becomes valid again

### What to change in your code

If your application relied on “live updates during typing”, move the logic to the moment when the value becomes valid.

```tsx
// Before
const handleUpdate = (value) => {
setState(value);
};

// After
const handleUpdate = (value) => {
if (value !== null) {
setState(value);
}
};
Comment on lines +44 to +48

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A strange proposal. This approach doesn't allow empty fields and doesn't rely on real-time updates. THe component doesn't support live updates any more.

```

## 2. DateField / RangeDateField: intermediate invalid dates are now preserved instead of immediately emitting

### Before

While the user was typing, an incomplete or invalid date could be forced through the update flow quickly, and the component could emit values before the input was finalized.

```tsx
<DateField onUpdate={(value) => console.log(value)} />
```

### After

The component temporarily preserves invalid or incomplete input internally and does not emit `onUpdate` until the value is finalized on blur.

```tsx
<DateField onUpdate={(value) => console.log(value)} />
```

Example flow:

- typing `31 April 2024` keeps the field in an intermediate state
- the value is normalized only when the field loses focus

### What to change in your code

If your consumer expects “instant updates on every keystroke”, switch to a blur-based or validation-based flow.

```tsx
// Before
const handleUpdate = (value) => {
saveValue(value);
};

// After
const handleBlur = () => {
if (currentValueRef.current) {
saveValue(currentValueRef.current);
}
};
Comment on lines +85 to +89

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

???

```

## 3. Calendar selection styling changed

### Before

The visual treatment of the selection end text color was different.

### After

The end of the selection uses updated text color styling.

### What to change in your code

If you use custom CSS overrides for calendar selection visuals, review those styles after upgrading.

## 4. Additional behavior changes worth checking

- Calendar now supports multi-selection.
- RelativeRangeDatePicker accepts `null` values in preset handling.
- DateField internals were refactored around incomplete/invalid state handling.

## Migration checklist

- Review handlers that depend on `onUpdate` during typing.
- Make sure your form logic handles “invalid/incomplete intermediate input” without assuming it is committed.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an incorrect statement. The user didn't receive an invalid/incomplete value, but rather a null value immediately after the input became invalid. Now, they receive the null value only after they finish editing the input.

- Check custom styles for calendar selection visuals.
- Re-test date entry flows for blur and validation behavior.
Loading