Skip to content

feat(date): align with fusion ds - #8085

Draft
ibutakova wants to merge 1 commit into
masterfrom
FE-7142-align-date-with-fusion-ds
Draft

feat(date): align with fusion ds#8085
ibutakova wants to merge 1 commit into
masterfrom
FE-7142-align-date-with-fusion-ds

Conversation

@ibutakova

@ibutakova ibutakova commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Proposed behaviour

Aligns DatePicker component component with fusion DS designs and accessibility requirements:

  • aligns typical date picker with accessibility requirements;
  • uses semantic HTML structure, keyboard/navigation/focus behaviour;

Current behaviour

Currently, the Profile component is not aligned with fusion DS.

Checklist

  • Commits follow our style guide
  • Related issues linked in commit messages if required
  • Screenshots are included in the PR if useful
  • All themes are supported if required
  • Unit tests added or updated if required
  • Playwright automation tests added or updated if required
  • Storybook added or updated if required
  • Translations added or updated (including creating or amending translation keys table in storybook) if required
  • Typescript d.ts file added or updated if required
  • Related docs have been updated if required

QA

  • Tested in provided StackBlitz sandbox/Storybook
  • Add new Playwright test coverage if required
  • Carbon implementation matches Design System/designs
  • UI Tests GitHub check reviewed if required

Additional context

Testing instructions

Screenshot 2026-08-07 at 15 01 02 Screenshot 2026-08-07 at 15 01 57 Screenshot 2026-08-07 at 15 02 25 Screenshot 2026-08-07 at 15 04 07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Warning

  • Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.

Pull request overview

Aligns the DateInput/DateRange experience with Fusion DS by introducing a new default “typical” date input variant and a rebuilt, accessibility-focused calendar popover, while retaining the legacy variant for backward compatibility.

Changes:

  • Introduces variant="typical" | "legacy" (defaulting to typical) and updates DateInput rendering/behavior accordingly, including a dedicated trigger control.
  • Replaces legacy DayPicker navbar/weekday custom components with a new calendar + navigation/selectors architecture and supporting hooks/utilities.
  • Updates locales, docs, Storybook stories, and Jest/Playwright coverage to reflect new accessibility labels and interactions.

Reviewed changes

Copilot reviewed 93 out of 93 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/style/utils/add-scrollbar-styling.ts Adds reusable scrollbar styling helper for new select/calendar UI.
src/style/utils/add-inner-focus-styling.ts Adds reusable inner-focus styling helper used by new select UI.
src/locales/pt-pt.ts Adds new date-picker aria labels (month/year/close).
src/locales/locale.ts Extends Locale date ariaLabels contract for new controls.
src/locales/fr-fr.ts Adds new date-picker aria labels (month/year/close).
src/locales/fr-ca.ts Adds new date-picker aria labels (month/year/close).
src/locales/es-es.ts Adds new date-picker aria labels (month/year/close).
src/locales/en-us.ts Adds new date-picker aria labels (month/year/close).
src/locales/en-gb.ts Adds new date-picker aria labels (month/year/close).
src/locales/en-ca.ts Adds new date-picker aria labels (month/year/close).
src/locales/de-de.ts Adds new date-picker aria labels (month/year/close).
src/components/textbox/textbox.test.tsx Adds test coverage for ReactNode inputIcon.
src/components/textbox/textbox.component.tsx Allows rendering custom ReactNode as inputIcon.
src/components/flat-table/flat-table.test.tsx Updates FlatTable/date-picker interaction test to use keydown dispatch semantics.
src/components/date/date.style.ts Updates sizing tokens and inline-label spacing for redesigned DateInput.
src/components/date/date.stories.tsx Reworks stories to show typical vs legacy variants and expanded scenarios.
src/components/date/date.pw.tsx Updates Playwright tests to new UI structure (selectors, close button, sizing).
src/components/date/date.mdx Documents typical/legacy compatibility, new behaviors, and updated examples.
src/components/date/date.component.tsx Adds variant support; refactors state, trigger, and picker integration.
src/components/date/date-interaction.stories.tsx Updates interaction stories to cover both variants and new navigation model.
src/components/date/components.test-pw.tsx Adds typical test component and pins legacy where required for existing tests.
src/components/date/internal/weekday/weekday.test.tsx Removes legacy weekday renderer tests.
src/components/date/internal/weekday/weekday.style.ts Removes legacy weekday styling.
src/components/date/internal/weekday/weekday.component.tsx Removes legacy weekday component.
src/components/date/internal/weekday/index.ts Removes legacy weekday exports.
src/components/date/internal/weekday/abbr.style.ts Removes legacy abbr styling for weekdays.
src/components/date/internal/utils/utils.ts Adjusts internal date-fns/fp import wiring for shared utils.
src/components/date/internal/utils/utils.test.ts Minor test tidy (unused param naming).
src/components/date/internal/utils/date-input-value.utils.ts Extracts/centralizes DateInput value parsing/normalization/event building.
src/components/date/internal/utils/date-input-value.utils.test.ts Adds tests for extracted DateInput value utilities.
src/components/date/internal/utils/date-input-value.invalid.test.ts Adds invalid-date regression test for matched-but-invalid parsed dates.
src/components/date/internal/navbar/navbar.test.tsx Removes legacy navbar tests.
src/components/date/internal/navbar/navbar.style.ts Removes legacy navbar styling.
src/components/date/internal/navbar/navbar.component.tsx Removes legacy navbar component.
src/components/date/internal/navbar/index.ts Removes legacy navbar exports.
src/components/date/internal/navbar/button.style.ts Removes legacy navbar button styling.
src/components/date/internal/hooks/useDatePickerState.ts New hook for open/close/toggle picker state with lifecycle callbacks.
src/components/date/internal/hooks/useDatePickerState.test.ts Tests for picker state hook behavior.
src/components/date/internal/hooks/useDatePickerMonthYearSelection.ts New hook for month/year selector logic and bounds handling.
src/components/date/internal/hooks/useDatePickerMonthYearSelection.test.ts Tests for month/year selection behavior and bounds edge cases.
src/components/date/internal/hooks/useDatePickerMonthSync.ts Syncs focused month with selected date on open/close/updates.
src/components/date/internal/hooks/useDatePickerMonthSync.test.ts Tests focused-month synchronization logic.
src/components/date/internal/hooks/useDatePickerLocale.ts Centralizes locale-derived weekday labels and close label.
src/components/date/internal/hooks/useDatePickerLocale.test.ts Tests locale hook output for multiple locales.
src/components/date/internal/hooks/useDatePickerKeyboardNavigation.ts New keyboard/tab-cycle management for picker controls and custom focusables.
src/components/date/internal/hooks/useDatePickerInFlatTable.ts Integrates picker open state with FlatTable to avoid interaction conflicts.
src/components/date/internal/hooks/useDatePickerInFlatTable.test.tsx Tests FlatTable integration hook behavior.
src/components/date/internal/hooks/useDatePickerFocus.ts Ensures initial day focus and resets selector-change state.
src/components/date/internal/hooks/useDatePickerFocus.test.ts Tests focus behavior using timers.
src/components/date/internal/hooks/useDatePickerAccessibility.ts Applies aria-labelledby to calendar grids when open/month changes.
src/components/date/internal/hooks/useDatePickerAccessibility.test.ts Tests aria-labelledby application to all grids.
src/components/date/internal/hooks/useDateInputState.ts New hook for “pristine vs edited” formatting + event creation.
src/components/date/internal/hooks/useDateInputState.test.ts Tests DateInput state normalization and event behavior.
src/components/date/internal/date-picker/index.ts Updates public exports/types for the new date picker internals.
src/components/date/internal/date-picker/day-picker.style.ts Removes legacy DayPicker styling wrapper.
src/components/date/internal/date-picker/date-picker.utils.ts New utilities for date bounds parsing, year ranges, and transitions.
src/components/date/internal/date-picker/date-picker.utils.test.ts Tests new date-picker utility functions.
src/components/date/internal/date-picker/date-picker.types.ts Introduces typed DatePickerProps/PickerProps and size typing.
src/components/date/internal/date-picker/date-picker.style.ts New popover/dialog styling aligned to DS tokens.
src/components/date/internal/date-picker/date-picker.component.tsx Rewrites picker to use new calendar/navigation components and hooks.
src/components/date/internal/date-picker/date-picker-guard.test.tsx Regression test for undefined day clicks not closing picker.
src/components/date/internal/date-picker-trigger/date-picker-trigger.style.ts Adds styles for typical variant trigger button/divider.
src/components/date/internal/date-picker-trigger/date-picker-trigger.component.tsx Adds the typical variant calendar trigger button with a11y attributes.
src/components/date/internal/calendar/calendar.test.tsx Adds unit tests for calendar subcomponents/helpers.
src/components/date/internal/calendar/calendar.component.tsx Introduces calendar wrapper with default renderers and className merging.
src/components/date/internal/calendar/calendar-weekday.style.ts Adds weekday header styling aligned to DS tokens.
src/components/date/internal/calendar/calendar-weekday.component.tsx Adds accessible weekday header markup (visible short + SR long).
src/components/date/internal/calendar/calendar-select/useCustomizableSelectMarkup.ts Adds hook to inject standardized customizable-select markup in React 18.
src/components/date/internal/calendar/calendar-select/useCustomizableSelectMarkup.server.test.ts Ensures hook can be imported in SSR environments.
src/components/date/internal/calendar/calendar-select/index.ts Exports calendar select component/types.
src/components/date/internal/calendar/calendar-select/calendar-select.test.tsx Adds comprehensive tests for calendar select behavior and markup injection.
src/components/date/internal/calendar/calendar-select/calendar-select.style.ts Styles the month/year selects including base-select and scrollbar/focus styling.
src/components/date/internal/calendar/calendar-select/calendar-select.config.ts Adds size-based configuration for calendar selects.
src/components/date/internal/calendar/calendar-select/calendar-select.component.tsx Implements the month/year select component with tagging and icon.
src/components/date/internal/calendar/calendar-navigation.style.ts Styles container for month/year selectors.
src/components/date/internal/calendar/calendar-navigation.component.tsx Implements month/year navigation selectors with bounds disabling and locale labels.
src/components/date/internal/calendar/calendar-day-button.component.tsx Adds accessible day button renderer with SR label and “today” indicator.
src/components/date/internal/calendar/calendar-close-button.style.ts Styles the picker close button, including mobile behavior.
src/components/date/internal/calendar/calendar-close-button.component.tsx Adds close button component with data-role for focus management.
src/components/date-range/date-range.test.tsx Updates DateRange tests for new trigger, dialog role, and aria-labelledby expectations.
src/components/date-range/date-range.stories.tsx Updates locale override stories to include new aria label keys.
src/components/date-range/date-range.component.tsx Adjusts internal date utils import path for refactor.
src/components/date-range/date-range-interaction.stories.tsx Updates interaction stories to use new trigger and revised navigation behaviors.
src/internal/label/label.test.tsx Adds test ensuring small label font applies to required indicator.
src/internal/label/label.style.ts Adjusts required indicator styling for better inline behavior and logical properties.
src/internal/input/input-style-overrides.style.ts Updates Date input overrides for typical/legacy icon and focus-within behavior.
skills/carbon-react/components/date-range.md Documentation update (content excluded from diff).
skills/carbon-react/components/date-input.md Documentation update (content excluded from diff).
Files excluded by content exclusion policy (2)
  • skills/carbon-react/components/date-input.md
  • skills/carbon-react/components/date-range.md
Comments suppressed due to low confidence (1)

src/components/date/date.component.tsx:490

  • The MDX compatibility table says tooltipPosition and helpAriaLabel are not supported by the typical variant, but they are still passed through to Textbox unconditionally. This can re-enable legacy tooltip/help behavior in the typical variant. Only pass these props for variant="legacy".

Comment thread src/components/date/date.component.tsx Outdated
Comment on lines +494 to +496
inputWidth={inputWidth}
labelWidth={labelWidth}
maxWidth={maxWidth ?? datePickerWidth[actualSize]}
maxWidth={maxWidth ?? dateInputWidthBySize[actualSize]}

@edleeks87 edleeks87 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I notice when using the dropdowns in the calendar the input value is changing, it should only update if the user selects a new date.

It looks like typical also doesn't have the vertical divider

I don't mind the separation of concerns you've implemented with all the hooks etc but I think it might be useful to add a top level comment to them to help maintainability

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

comment: we shouldn't be overriding the scrollbar styling, accessibility have steered that using the browser default is preferred

Comment thread src/components/date/date.component.tsx Outdated
className="date"
className={`date date-${variant}`}
>
<Textbox

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

comment: we should be using TextInput as once all the inputs using Textbox have been updated we will be removing it

);
expect(select.querySelector("selectedcontent")).toBeInTheDocument();
});
/* eslint-enable testing-library/no-node-access */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

question: Is this es-lint comment required here? It looks like it's the end of the file.

test("renders a day without an accessible label", () => {
render(
<CalendarDayButton
day={{} as never}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion: Instead of casting this as never, you might be able to do something like this:

  const mockDay = new CalendarDay(new Date(2025, 0, 15), new Date(2025, 0, 1));

and use mockDay like this:

Suggested change
day={{} as never}
day={mockDay}

I'm not too precious about this though, I just try to avoid using the type never where possible.

min-width: var(--date-picker-trigger-size);
height: var(--date-picker-trigger-size);
min-height: var(--date-picker-trigger-size);
padding: 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion: There are a selection of ...-none tokens we could use here.

Suggested change
padding: 0;
padding: var(--global-space-none);

height: var(--date-picker-trigger-size);
min-height: var(--date-picker-trigger-size);
padding: 0;
border-radius: 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same here too.

Suggested change
border-radius: 0;
border-radius: var(--global-size-none);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

if tokens then border-radius: var(--global-radius-none); fits better)


.rdp-root {
width: 100%;
padding: 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

**suggestion: ** You could probably the same ...-none tokens here too.

Comment thread src/components/date/date.stories.tsx Outdated
const detailLabel = labelDetail ? ` - ${labelDetail}` : "";

return (
<Box display="flex" flexDirection="column" gap="var(--spacing300)">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nitpick: The var(--spacing300) is an old design-token. If this is a new example, we should probably use the equivalent Fusion DS token.

Comment thread src/components/date/date.stories.tsx Outdated
value={state}
onChange={setValue}
/>
<Box display="flex" flexDirection="column" gap="var(--spacing300)">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same thing here too with var(--spacing300).

/>
) : null;
) : (
inputIcon || null

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

question: Do we need this change if the new date input will use the new Text Input component?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Forget to remove while resolving the comment about using TextInput, not Textbox

Comment thread src/components/date/date.component.tsx Outdated
warning={warning}
/>
) : (
<Textbox

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Comment: both variants should use TextInput. We need to remove the uses of Textbox so we can deprecate it and replace it with the internal TextInput

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Things like the help, tooltip and legacy validation should not be supported etc

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

TextInput is now used for both legacy and typical


/* Legacy Date renders its calendar as an Input icon. Typical Date owns its
* trigger colors in date-picker-trigger.style.ts. */
.date-legacy & {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

comment: if we remove the use of TextInput we should be able to remove most of (if not all) of these overrides as we won't have a InputIconToggle. It also looks like the legacy variant doesn't have a divider so I don't think we need the pseudo selector anyway

Image

@ibutakova ibutakova Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I left legacy without divider, removed extra styles

Comment thread src/locales/de-de.ts Outdated
ariaLabels: {
previousMonthButton: () => "Vorheriger Monat",
nextMonthButton: () => "Nächster Monat",
chooseMonth: () => "Monat wählen",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

question: can I just clarify, have these come from the translation team? If not we should only include the en-GB translation file

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I fell back to en-gb

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

comment: we don't need this, there is already a util that supports the inset styling.

Comment thread src/components/date/date.component.tsx Outdated
@@ -122,11 +128,21 @@ export const DateInput = React.forwardRef<HTMLInputElement, DateInputProps>(
adaptiveLabelBreakpoint,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

comment: support for adaptiveBreakpoint should be removed but left on the interface to avoid a breaking change. If the TextInput doesn't support it then anything rendering it should drop it as well. The intention is that implementation teams will handle this themselves rather than baking the behaviour into the component library

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

question: is there any code coverage being missed without these tests? This feels like an implementation test that we can just remove if we aren't needing it for coverage

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

removed them

Comment thread src/components/date/date.mdx Outdated
| `validationIconId` | Not supported | Inline validation message ids are generated automatically |
| `validationOnLabel` | Not supported | Inline `warning` or `error` messages |

### Custom calendar renderers

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Comment: whilst we do support the pickerProps I'd prefer to not explicitly document the overriding of the internals. I suspect in the long run the DS will want us to remove support and we may be creating a larger migration hurdle if we do

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Unsupported props now distructured and discarded

ariaLabels: {
previousMonthButton: () => "Mois précédent",
nextMonthButton: () => "Mois prochain",
chooseMonth: () => "Choisir le mois",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

comment: if these haven't come from the translation teams I think we should leave them to fall back to en-GB

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I did fallback

@ibutakova
ibutakova force-pushed the FE-7142-align-date-with-fusion-ds branch 3 times, most recently from 225a9f8 to 11b0a63 Compare August 7, 2026 12:28

@edleeks87 edleeks87 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Happy with the changes, think we've lost the click away behaviour but going to approve for now and we can confirm next week with DS as it's trivial to add in

@ibutakova
ibutakova force-pushed the FE-7142-align-date-with-fusion-ds branch from 11b0a63 to bc47784 Compare August 7, 2026 15:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

4 participants