Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New DateInput component #2645

Merged
merged 31 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
0176f24
Implement initial DateInput
connor-baer Aug 9, 2024
daa5b98
Add missing doc comments
connor-baer Oct 8, 2024
388207e
Merge experimental DateInput into stable one
connor-baer Oct 8, 2024
1fc8bec
Silence polyfill warnings in JSDOM
connor-baer Oct 8, 2024
14cfb04
Remove input[date] fallback
connor-baer Oct 10, 2024
2d2a149
Extract Dialog component
connor-baer Oct 10, 2024
7b47ab7
Bump @sumup-oss/intl to v3
connor-baer Oct 19, 2024
fab403f
Split text input into segments
connor-baer Oct 12, 2024
4710d9a
Focus following segment after clearing the current one
connor-baer Oct 12, 2024
62085d7
Sync value between calendar and input
connor-baer Oct 12, 2024
07439a5
Support autocomplete attribute
connor-baer Oct 12, 2024
231bc39
Do not clamp values
connor-baer Oct 14, 2024
46824b6
Tweak segment styles
connor-baer Oct 14, 2024
478bbdf
Focus first segment when clicking date field
connor-baer Oct 14, 2024
de5d9db
Hide the clear button when the input is required
connor-baer Oct 14, 2024
45a2d76
Install mockdate package
connor-baer Oct 16, 2024
2225481
Fix opening and closing of Dialog
connor-baer Oct 16, 2024
cda94ee
Implement validation states
connor-baer Oct 18, 2024
413466a
WIP tests
connor-baer Oct 18, 2024
ca14e33
Align styles with other composite inputs
connor-baer Oct 19, 2024
9dfe7e6
Add basic documentation
connor-baer Oct 21, 2024
6988ea3
Disable ESLint rules covered by Biome
connor-baer Oct 21, 2024
7ed1c0b
Add more unit tests and improve validation hint
connor-baer Oct 21, 2024
29e5ef5
Don't reset internal state on value change
connor-baer Oct 24, 2024
a93db26
Add tests for the DateInputService
connor-baer Oct 22, 2024
8158aa3
Add changeset
connor-baer Oct 22, 2024
1bd13c1
Add shiftInRange helper
connor-baer Oct 25, 2024
a52c8c0
Refactor DateInput internals
connor-baer Oct 25, 2024
fd08d21
Address code review
connor-baer Oct 25, 2024
a075ae0
Add more unit tests
connor-baer Oct 25, 2024
804f19f
Throw error if shiftInRange args are invalid
connor-baer Oct 28, 2024
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: 2 additions & 2 deletions .changeset/chilly-dodos-end.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
"@sumup-oss/circuit-ui": major
'@sumup-oss/circuit-ui': major
---

Upgraded to `@sumup-oss/intl` v2. If your app also depends on `@sumup-oss/intl` (previously called `@sumup/intl`), you need to upgrade it as well.
Upgraded to `@sumup-oss/intl` v3. If your app also depends on `@sumup-oss/intl` (previously called `@sumup/intl`), you need to upgrade it as well.
5 changes: 5 additions & 0 deletions .changeset/tiny-jars-knock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@sumup-oss/circuit-ui": major
---

Rewrote the DateInput component and replaced the native date input with a custom implementation to improve its usability and accessibility. The component now requires additional localized label props.
3 changes: 3 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ module.exports = require('@sumup-oss/foundry/eslint')({
'@sumup-oss/circuit-ui/no-renamed-props': 'error',
'@sumup-oss/circuit-ui/prefer-custom-properties': 'warn',
'react/no-unknown-property': ['error', { ignore: ['css'] }],
// These rules are already covered by Biome
'jsx-a11y/click-events-have-key-events': 'off',
'jsx-a11y/no-static-element-interactions': 'off',
},
parserOptions: {
project: ['./packages/*/tsconfig.json', './tsconfig.eslint.json'],
Expand Down
31 changes: 23 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 7 additions & 4 deletions packages/circuit-ui/components/CurrencyInput/CurrencyInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { resolveCurrencyFormat } from '@sumup-oss/intl';
import { NumericFormat, type NumericFormatProps } from 'react-number-format';

import { clsx } from '../../styles/clsx.js';
import { getBrowserLocale, type Locale } from '../../util/i18n.js';
import { Input, type InputProps } from '../Input/index.js';

import { formatPlaceholder } from './CurrencyInputService.js';
Expand All @@ -37,10 +38,12 @@ export interface CurrencyInputProps
*/
currency: string;
/**
* One or more Unicode BCP 47 locale identifiers, such as 'de-DE' or
* ['GB', 'en-US'] (the first supported locale is used).
* One or more [IETF BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag)
* locale identifiers such as `'de-DE'` or `['GB', 'en-US']`.
* When passing an array, the first supported locale is used.
* Defaults to `navigator.language` in supported environments.
*/
locale?: string | string[];
locale?: Locale;
/**
* A short string that is shown inside the empty input.
* If the placeholder is a number, it is formatted in the local
Expand Down Expand Up @@ -76,7 +79,7 @@ const DUMMY_DELIMITER = '?';
export const CurrencyInput = forwardRef<HTMLInputElement, CurrencyInputProps>(
(
{
locale,
locale = getBrowserLocale(),
currency,
placeholder,
'aria-describedby': descriptionId,
Expand Down
55 changes: 55 additions & 0 deletions packages/circuit-ui/components/DateInput/DateInput.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Meta, Status, Props, Story } from '../../../../.storybook/components';
import * as Stories from './DateInput.stories';

<Meta of={Stories} />

# DateInput

<Status variant="stable" />

The DateInput component allows users to type or select a specific date. The input value is always a string in the format `YYYY-MM-DD`.

<Story of={Stories.Base} />
<Props />

## Usage

Use the component whenever asking for a specific individual date such as a birth date, expiry date, or appointment date. The date is in the [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) format (`YYYY-MM-DD`).

For selecting a range of dates, we expect to introduce an iteration of this component in the future. Until then, we recommend using a combination of two input fields (one for the start and the other for the end date).

## Validations

Use the `validationHint` prop to communicate the expected response to users. The DateInput component ensures that the entered date is a valid date, but does not validate whether it falls within the minimum or maximum date range.

### Invalid

The user needs to change the value to proceed. This could be because they entered a date outside of the allowed range.

### Warning

The user is recommended to change the value, but can proceed without doing so. Use it when the provided value could have unintended side-effects, such as a date in the far future.

### Valid

The user is reassured that the value is valid. Use sparingly.

<Story of={Stories.Validations} />

## Optional

Use the `optionalLabel` prop to indicate that the field is optional. This can help reduce the cognitive load for the user by clearly indicating which fields are required and which are not. This label is only displayed when the `required` prop is falsy.

<Story of={Stories.Optional} />

## Readonly

Use the `readOnly` prop to indicate that the field is not currently editable. This can be useful in situations where the user needs to view but not edit the date, such as in a summary or review screen.

<Story of={Stories.Readonly} />

## Internationalization

Pass one or more [IETF BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag) locale identifiers such as `'de-DE'` or `['GB', 'en-US']` to the `locale` prop to display the date in the local format. When passing an array, the first supported locale is used. Defaults to `navigator.language` in supported environments.

<Story of={Stories.Locales} />
Loading