Skip to content

Commit

Permalink
feat(input-date-picker, date-picker): improve date picking experience (
Browse files Browse the repository at this point in the history
…#8402)

**Related Issue:** #3455, #10113 

## Summary

Update `calcite-date-picker` & `calcite-input-date-picker` UI & UX.



![4D1CFC3C-8FF9-4493-9178-4DEDA0417031](https://github.com/user-attachments/assets/4b1f5a12-85df-4577-b1cd-812c22e41ef7)

### Key changes
- display two calendars for range irrespective of layout.
- No longer switches focus from day to end input when startDate is
selected initially.
- Month selection is possible via select menu
- No longer positions the date-picker component relative to endInput
when endInput is focused in range.
- Dates from previous months are not visible in range calendar.
- Divider indicator icons are removed in horizontal layout for range in
input-date-picker.
- No longer uses chevron icon which indicate the open status of
input-date-picker in startInput field.


Other issues resolved :
#6321
#6410
#10301
#10291
#10113
#10243
#10490

Blocked issues: #9167 

Wiki
https://github.com/Esri/calcite-design-system/wiki/date%E2%80%90picker-enhancement-%238402
  • Loading branch information
anveshmekala authored and benelan committed Feb 8, 2025
1 parent 989da02 commit d03bfa6
Show file tree
Hide file tree
Showing 24 changed files with 3,199 additions and 1,426 deletions.
227 changes: 209 additions & 18 deletions packages/calcite-components/src/components.d.ts

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions packages/calcite-components/src/components/action/action.scss
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,8 @@ button {

:host([scale="s"]) {
.button {
@apply text-n2h px-2 py-1 font-normal;
@apply text-n2h px-2 font-normal;
padding-block: var(--calcite-internal-action-padding-block, var(--calcite-size-xxs));
}
.button--text-visible .icon-container {
margin-inline-end: theme("spacing.2");
Expand All @@ -182,7 +183,8 @@ button {

:host([scale="m"]) {
.button {
@apply text-n1h px-4 py-3 font-normal;
@apply text-n1h px-4 font-normal;
padding-block: var(--calcite-internal-action-padding-block, var(--calcite-size-md));
}
.button--text-visible .icon-container {
margin-inline-end: theme("spacing.3");
Expand All @@ -191,7 +193,8 @@ button {

:host([scale="l"]) {
.button {
@apply text-0h p-5 font-normal;
@apply text-0h px-5 font-normal;
padding-block: var(--calcite-internal-action-padding-block, var(--calcite-size-xl));
}
.button--text-visible .icon-container {
margin-inline-end: theme("spacing.4");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,88 +1,33 @@
:host {
@apply cursor-pointer flex relative text-color-3;
outline: none;
}

@include disabled();

@mixin range-part-base() {
&::before,
&::after {
@apply absolute pointer-events-none;
inset-block: 0;
content: "";
block-size: var(--calcite-internal-day-size);
inline-size: var(--calcite-internal-day-size);
}
}

@mixin range-part-edge-end() {
&::before {
inset-inline-end: 50%;
}
&::after {
inset-inline-start: 50%;
border-start-end-radius: var(--calcite-internal-day-size);
border-end-end-radius: var(--calcite-internal-day-size);
inline-size: calc(var(--calcite-internal-day-size) / 2);
}
}

@mixin range-part-edge-start() {
&::before {
inset-inline-end: 50%;
border-start-start-radius: var(--calcite-internal-day-size);
border-end-start-radius: var(--calcite-internal-day-size);
inline-size: calc(var(--calcite-internal-day-size) / 2);
}
&::after {
inset-inline-start: 50%;
}
}

@mixin range-part-middle() {
&::before {
inset-inline-end: 50%;
border-radius: 0;
}
&::after {
inset-inline-start: 50%;
border-radius: 0;
}
}

.day-v-wrapper {
@apply flex-auto;
}

.day-wrapper {
@apply flex
flex-col
items-center
relative;
}

:host([range]),
:host([range-hover]) {
.day-wrapper {
@include range-part-base();
}
justify-center
relative
w-full;
}

.day {
@apply text-n2h
text-color-3
flex
focus-base
items-center
justify-center
rounded-full
leading-none
transition-default
z-default;
w-full
relative;
line-height: var(--calcite-font-line-height-fixed-base);
background: none;
box-shadow: 0 0 0 2px transparent;
block-size: var(--calcite-internal-day-size);
inline-size: var(--calcite-internal-day-size);
outline-color: var(--calcite-color-transparent);
}

.text {
Expand All @@ -91,42 +36,22 @@
}

:host([scale="s"]) {
--calcite-internal-day-size: 27px;

.day-v-wrapper {
@apply py-0.5;
}
.day-wrapper {
@apply p-0;
}
--calcite-internal-day-size: #{$calcite-size-32};
.day {
@apply text-n2;
}
}

:host([scale="m"]) {
--calcite-internal-day-size: 33px;

.day-v-wrapper {
@apply py-1;
}
.day-wrapper {
@apply p-0;
}
--calcite-internal-day-size: #{$calcite-size-40};
.day {
@apply text-n1;
}
}

:host([scale="l"]) {
--calcite-internal-day-size: 43px;
--calcite-internal-day-size: #{$calcite-size-44};

.day-v-wrapper {
@apply py-1;
}
.day-wrapper {
@apply px-1;
}
.day {
@apply text-0;
}
Expand All @@ -136,20 +61,26 @@
@apply opacity-disabled;
}

:host(:hover:not([disabled]):not([selected])),
:host([active]:not([range]):not([selected])) {
:host(:hover:not([disabled]):not([selected])) {
& .day {
@apply bg-foreground-2 text-color-1;
}
}

:host(:focus),
:host([active]) {
@apply outline-none;
:host(:not([range]):not([selected]).current-day) {
& .day {
color: var(--calcite-color-text-1);
font-weight: var(--calcite-font-weight-medium);
}
}

:host(:focus[selected]) .day {
@apply focus-outset z-default;
box-shadow: 0 0 0 2px var(--calcite-color-foreground-1);
}

:host(:focus:not([disabled])) .day {
@apply focus-outset;
:host(:focus:not([disabled]):not([selected])) .day {
@apply focus-inset;
}

:host([selected]) .day {
Expand All @@ -158,83 +89,31 @@
color: var(--calcite-color-foreground-1);
}

:host(:focus:not([disabled])),
:host([start-of-range]:not(:focus)),
:host([end-of-range]:not(:focus)) {
:host([range-hover]:not([selected])) {
.day {
box-shadow: 0 0 0 2px var(--calcite-color-foreground-1);
@apply bg-foreground-2;
@apply text-color-1;
}
}

:host([range-hover]:not([selected])),
:host([highlighted]:not([selected])) {
.day-wrapper {
@include range-part-middle();
}

.day {
@apply text-color-1;
color: var(--calcite-color-brand);
background-color: var(--calcite-color-foreground-current);
}
}

:host([highlighted]),
:host([selected]:not(.hover--outside-range)) {
.day-wrapper {
&::before,
&::after {
background-color: var(--calcite-color-foreground-current);
}
}
}

:host([range-hover]:not([selected])) {
.day-wrapper {
&::before,
&::after {
@apply bg-foreground-2;
}
}
}

:host(:hover[range-hover]:not([selected]).focused--end),
:host([highlighted][end-of-range]),
:host([highlighted][range-edge="end"]),
:host([range-hover][range-edge="end"]),
:host(:hover[range-hover].focused--end.hover--outside-range) {
.day-wrapper {
@include range-part-edge-end();
}
}

:host([highlighted][start-of-range]),
:host([highlighted][range-edge="start"]),
:host([range-hover][range-edge="start"]),
:host(:hover[range-hover]:not([selected]).focused--start),
:host([start-of-range].hover--inside-range),
:host(:hover[range-hover].focused--start.hover--outside-range) {
.day-wrapper {
@include range-part-edge-start();
}
}

:host([range-hover][start-of-range][range-edge="end"]),
:host([range-hover][end-of-range][range-edge="start"]),
:host([start-of-range][range-edge="end"].hover--inside-range),
:host([end-of-range]) {
.day-wrapper {
&::after,
&::before {
content: unset;
}
:host(:hover[highlighted]:not([selected]).inside-range--hover) {
.day {
background-color: var(--calcite-color-foreground-current);
color: var(--calcite-color-brand);
@apply focus-inset;
}
}

:host(:hover[range-hover]:not([selected]).focused--start),
:host(:hover[range-hover]:not([selected]).focused--end),
:host(:hover[range-hover]:not([selected]).focused--start.hover--outside-range),
:host(:hover[range-hover]:not([selected]).focused--end.hover--outside-range) {
:host(:hover:not([highlighted]):not([selected]).outside-range--hover) {
.day {
box-shadow: 0 0 0 2px var(--calcite-color-foreground-1);
@apply focus-inset;
}
}

Expand All @@ -256,22 +135,16 @@
:host([range][selected]),
:host([highlighted]),
:host([range-hover]:not([selected])) {
.day-wrapper {
&::before,
&::after {
background-color: highlight;
}
.day {
background-color: highlight;
}
}

:host([range-hover]),
:host([range][selected][start-of-range]),
:host([range][selected][end-of-range]) {
.day-wrapper {
&::before,
&::after {
background-color: canvas;
}
.day {
background-color: canvas;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,12 @@ export class DatePickerDay implements InteractiveComponent, LoadableComponent {
return;
}

this.calciteDaySelect.emit();
this.calciteInternalDaySelect.emit();
};

keyDownHandler = (event: KeyboardEvent): void => {
if (isActivationKey(event.key)) {
!this.disabled && this.calciteDaySelect.emit();
!this.disabled && this.calciteInternalDaySelect.emit();
event.preventDefault();
}
};
Expand All @@ -128,7 +128,7 @@ export class DatePickerDay implements InteractiveComponent, LoadableComponent {
/**
* Fires when user selects day.
*/
@Event({ cancelable: false }) calciteDaySelect: EventEmitter<void>;
@Event({ cancelable: false }) calciteInternalDaySelect: EventEmitter<void>;

/**
* Fires when user hovers over a day.
Expand Down Expand Up @@ -190,12 +190,10 @@ export class DatePickerDay implements InteractiveComponent, LoadableComponent {
tabIndex={this.active && !this.disabled ? 0 : -1}
>
<InteractiveContainer disabled={this.disabled}>
<div aria-hidden="true" class={{ "day-v-wrapper": true }}>
<div class="day-wrapper">
<span class="day">
<span class="text">{formattedDay}</span>
</span>
</div>
<div aria-hidden="true" class="day-wrapper">
<span class="day">
<span class="text">{formattedDay}</span>
</span>
</div>
</InteractiveContainer>
</Host>
Expand Down
Loading

0 comments on commit d03bfa6

Please sign in to comment.