diff --git a/tedi/components/form/date-picker/date-picker.component.html b/tedi/components/form/date-picker/date-picker.component.html new file mode 100644 index 000000000..a7e5a7959 --- /dev/null +++ b/tedi/components/form/date-picker/date-picker.component.html @@ -0,0 +1,344 @@ + +
diff --git a/tedi/components/form/date-picker/date-picker.component.scss b/tedi/components/form/date-picker/date-picker.component.scss new file mode 100644 index 000000000..ce60198fe --- /dev/null +++ b/tedi/components/form/date-picker/date-picker.component.scss @@ -0,0 +1,353 @@ +tedi-date-picker { + display: flex; + min-height: var(--form-field-height); + gap: var(--form-field-inner-spacing); + align-self: stretch; + border-radius: var(--form-field-radius); + border: var(--borders-01) solid var(--form-input-border-default); + background: var(--form-input-background-default); + padding-right: var(--form-field-padding-x-md-default); + + &:has(.tedi-date-picker__input:hover):not( + :has(.tedi-date-picker__input:disabled) + ) { + border-color: var(--form-input-border-hover); + } + + &:has(.tedi-date-picker__input:active):not( + :has(.tedi-date-picker__input:disabled) + ), + &:has(.tedi-date-picker__input:focus):not( + :has(.tedi-date-picker__input:disabled) + ) { + border-color: var(--form-input-border-active); + box-shadow: 0 0 0 1px var(--form-input-border-active); + } + + &:has(.tedi-date-picker__input:disabled) { + border-color: var(--form-input-border-disabled); + background: var(--form-input-background-disabled); + cursor: not-allowed; + } + + &:has(.tedi-date-picker__input--valid) { + border-color: var(--form-general-feedback-success-border); + } + + &:has(.tedi-date-picker__input--error) { + border-color: var(--form-general-feedback-error-border); + } + + &:has(.tedi-date-picker__input--small) { + min-height: var(--form-field-height-sm); + } +} + +.tedi-date-picker { + &__input { + flex: 1; + padding-left: var(--form-field-padding-x-md-default); + color: var(--form-input-text-filled); + font-size: var(--body-regular-size); + border: 0; + border-radius: var(--form-field-radius); + + &::placeholder { + color: var(--form-input-text-placeholder); + } + + &:disabled { + cursor: not-allowed; + } + } + + &__input-buttons { + align-self: center; + display: flex; + align-items: center; + justify-content: center; + gap: var(--layout-grid-gutters-04); + } + + &__clear { + &:disabled { + cursor: not-allowed; + } + } + + &__toggle { + width: var(--button-xs-icon-size) !important; + height: var(--form-field-button-height-sm) !important; + border-radius: var(--button-radius-sm) !important; + font-size: 1.125rem !important; + + &:disabled { + cursor: not-allowed; + } + } + + &__calendar { + width: fit-content; + display: block; + border-radius: var(--card-radius-rounded); + background: var(--card-background-primary); + user-select: none; + } + + &__header { + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--layout-grid-gutters-08); + padding: var(--card-padding-md-default) var(--card-padding-md-default) + var(--card-padding-xs) var(--card-padding-md-default); + } + + &__controls { + display: flex; + align-items: center; + gap: var(--layout-grid-gutters-08); + margin: 0 auto; + } + + &__dropdown-trigger { + display: inline-flex; + align-items: center; + gap: var(--layout-grid-gutters-02); + padding: 0; + padding-left: var(--layout-grid-gutters-04); + font-size: 1rem; + font-weight: 500; + color: var(--general-text-primary); + background: transparent; + border: 0; + border-radius: var(--button-radius-sm); + cursor: pointer; + + &:hover { + color: var(--button-main-neutral-text-hover); + background: var(--button-main-neutral-icon-only-background-hover); + + tedi-icon { + color: var(--button-main-neutral-text-hover); + } + } + + &:active { + color: var(--button-main-neutral-text-active); + background: var(--button-main-neutral-icon-only-background-active); + + tedi-icon { + color: var(--button-main-neutral-text-active); + } + } + + &:focus-visible { + outline: var(--borders-02) solid var(--primary-500); + outline-offset: var(--borders-01); + } + + tedi-icon { + font-size: 2rem; + color: var(--general-icon-tertiary); + } + } + + &__dropdown-content { + max-height: 15rem; + + &--month { + width: 10rem; + } + + &--year { + width: 8.75rem; + } + } + + &__label { + color: var(--general-text-primary); + font-weight: 500; + } + + &__nav { + font-size: var(--button-icon-inner-icon-only-size) !important; + } + + &__weekdays { + display: grid; + grid-template-columns: repeat(7, 1fr); + padding: 0 var(--card-padding-md-default); + + &--numbered { + grid-template-columns: repeat(8, 1fr); + } + } + + &__weekday { + width: var(--form-calendar-date-width); + height: var(--form-calendar-date-width); + display: flex; + justify-content: center; + align-items: center; + font-size: var(--body-small-regular-size); + color: var(--general-text-tertiary); + text-align: center; + text-transform: uppercase; + border-bottom: var(--borders-01) solid var(--general-border-primary); + } + + &__grid { + display: flex; + flex-direction: column; + padding: 0 var(--card-padding-md-default) var(--card-padding-md-default) + var(--card-padding-md-default); + } + + &__row { + display: grid; + grid-template-columns: repeat(7, 1fr); + + &--numbered { + grid-template-columns: repeat(8, 1fr); + } + } + + &__weeknumber { + width: var(--form-calendar-date-width); + height: var(--form-calendar-date-width); + display: flex; + justify-content: center; + align-items: center; + flex-shrink: 0; + color: var(--general-text-tertiary); + font-size: var(--body-small-regular-size); + border-right: var(--borders-01) solid var(--general-border-primary); + } + + &__day { + width: var(--form-calendar-date-width); + height: var(--form-calendar-date-width); + display: flex; + justify-content: center; + align-items: center; + flex-shrink: 0; + border: none; + background: none; + cursor: pointer; + color: var(--general-text-primary); + font-size: var(--body-regular-size); + border-radius: var(--button-radius-sm); + + &:hover { + background: var(--form-datepicker-date-hover); + } + + &:active { + background: var(--form-datepicker-date-active); + } + + &:disabled { + cursor: not-allowed; + opacity: 0.3; + } + + &:focus-visible { + outline: var(--borders-02) solid var(--primary-500); + outline-offset: var(--borders-01); + } + + &--other-month { + color: var(--form-datepicker-date-text-muted); + } + + &--selected { + color: var(--form-datepicker-date-text-selected); + border-radius: var(--button-radius-sm); + background: var(--form-datepicker-date-selected); + + &:hover { + background: var(--form-datepicker-date-selected); + } + + .tedi-date-picker__today { + border-color: var(--form-datepicker-today-border-secondary); + } + } + } + + &__today { + display: flex; + width: var(--form-calendar-date-width); + height: var(--form-calendar-date-width); + justify-content: center; + align-items: center; + border-radius: var(--button-radius-default); + border: var(--borders-01) solid var(--form-datepicker-today-border); + flex-shrink: 0; + } + + &__month-year-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: var(--layout-grid-gutters-08); + padding: var(--card-padding-md-default); + } + + &__month-year-button { + display: flex; + justify-content: center; + align-items: center; + padding: var(--form-checkbox-radio-card-radio-padding-y) + var(--form-checkbox-radio-card-radio-padding-x); + border-radius: var(--form-checkbox-radio-card-radius); + border: var(--borders-01) solid + var(--form-checkbox-radio-card-secondary-default-border); + background: var(--form-checkbox-radio-card-secondary-default-background); + color: var(--form-checkbox-radio-card-primary-default-text); + font-size: var(--body-regular-size); + + &:hover { + color: var(--form-checkbox-radio-card-secondary-hover-text); + border-color: var(--form-checkbox-radio-card-secondary-hover-border); + background: var(--form-checkbox-radio-card-secondary-hover-background); + } + + &:focus-visible { + outline: var(--borders-02) solid var(--primary-500); + outline-offset: var(--borders-01); + } + + &:disabled { + color: var(--form-checkbox-radio-card-secondary-disabled-default-text); + border-color: var( + --form-checkbox-radio-card-secondary-disabled-default-border + ); + background: var( + --form-checkbox-radio-card-secondary-disabled-default-background + ); + cursor: not-allowed; + } + + &--selected { + color: var(--form-checkbox-radio-card-secondary-selected-text); + border-color: var(--form-checkbox-radio-card-secondary-selected-border); + box-shadow: 0 0 0 1px + var(--form-checkbox-radio-card-secondary-selected-border); + background: var(--form-checkbox-radio-card-secondary-selected-background); + + &:disabled { + color: var(--form-checkbox-radio-card-secondary-disabled-selected-text); + border-color: var( + --form-checkbox-radio-card-secondary-disabled-selected-border + ); + box-shadow: 0 0 0 1px + var(--form-checkbox-radio-card-secondary-disabled-selected-border); + background: var( + --form-checkbox-radio-card-secondary-disabled-selected-background + ); + cursor: not-allowed; + } + } + } +} diff --git a/tedi/components/form/date-picker/date-picker.component.spec.ts b/tedi/components/form/date-picker/date-picker.component.spec.ts new file mode 100644 index 000000000..6151aa990 --- /dev/null +++ b/tedi/components/form/date-picker/date-picker.component.spec.ts @@ -0,0 +1,651 @@ +import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { DatePickerComponent } from "./date-picker.component"; +import { TediTranslationService } from "../../../services/translation/translation.service"; +import { NgxFloatUiContentComponent } from "ngx-float-ui"; +import { ElementRef } from "@angular/core"; + +class TranslationMock { + track(key: string) { + return () => key; + } +} + +describe("DatePickerComponent", () => { + let fixture: ComponentFixture