diff --git a/.claude/skills/ui4-review/SKILL.md b/.claude/skills/ui4-review/SKILL.md index 62819816cfc..31feb934dd2 100644 --- a/.claude/skills/ui4-review/SKILL.md +++ b/.claude/skills/ui4-review/SKILL.md @@ -185,6 +185,65 @@ These must be replaced with new tokens. --- +### SCSS Patterns in Native CSS (CRITICAL) + +Native CSS nesting does NOT support all SCSS patterns. Flag these: + +**Bad — `&--modifier` for BEM modifiers:** + +```css +.react-datepicker { + /* This does NOT work in native CSS */ + &--time-only { + border: none; + } +} +``` + +In SCSS, `&--time-only` expands to `.react-datepicker--time-only`. In native CSS, `&` represents the _entire selector list_, not a string to concatenate. + +**Good — Use flat selectors outside the block:** + +```css +.react-datepicker { + /* base styles */ +} + +.react-datepicker--time-only { + border: none; +} +``` + +**Also bad — `&__element` for BEM elements:** + +```css +.block { + &__element { + /* Does NOT work */ + } +} +``` + +**Detection pattern:** Look for `&--` or `&__` inside CSS blocks. These are SCSS-only patterns. + +**Exception:** `&:pseudo` and `& .child` work fine in native CSS: + +```css +.button { + &:hover { + /* OK */ + } + &:focus { + /* OK */ + } + & .icon { + /* OK */ + } +} +``` + +--- + ## Behavior: AUTO-FIX **Do NOT just report violations. FIX THEM.** diff --git a/packages/ui/src/elements/DatePicker/DatePicker.tsx b/packages/ui/src/elements/DatePicker/DatePicker.tsx index 75801da3096..47f357865cf 100644 --- a/packages/ui/src/elements/DatePicker/DatePicker.tsx +++ b/packages/ui/src/elements/DatePicker/DatePicker.tsx @@ -11,9 +11,8 @@ const ReactDatePicker = import type { Props } from './types.js' import { CalendarIcon } from '../../icons/Calendar/index.js' -import { XIcon } from '../../icons/X/index.js' import { useTranslation } from '../../providers/Translation/index.js' -import './index.scss' +import './index.css' import { getFormattedLocale } from './getFormattedLocale.js' const baseClass = 'date-time-picker' @@ -97,6 +96,7 @@ const DatePicker: React.FC = (props) => { showMonthYearPicker: pickerAppearance === 'monthOnly', showPopperArrow: false, showTimeSelect: pickerAppearance === 'dayAndTime' || pickerAppearance === 'timeOnly', + showTimeSelectOnly: pickerAppearance === 'timeOnly', timeFormat, timeIntervals, ...(overrides as Extract< @@ -124,18 +124,6 @@ const DatePicker: React.FC = (props) => { return (
-
- {dateTimePickerProps.selected && ( - - )} - -
= (props) => { showMonthDropdown showYearDropdown /> + {/* TODO: update icon */} +
) diff --git a/packages/ui/src/elements/DatePicker/index.css b/packages/ui/src/elements/DatePicker/index.css new file mode 100644 index 00000000000..d95531c13f3 --- /dev/null +++ b/packages/ui/src/elements/DatePicker/index.css @@ -0,0 +1,934 @@ +@layer payload-default { + /* —————————————————————————————————————————————— + react-datepicker library base styles + ————————————————————————————————————————————— */ + + .react-datepicker-wrapper { + display: block; + padding: 0; + border: 0; + } + + .react-datepicker { + --time-column-width: 120px; + + font-family: var(--text-body-medium-font-family); + font-size: var(--text-body-medium-font-size); + font-weight: var(--text-body-medium-font-weight); + line-height: var(--text-body-medium-line-height); + letter-spacing: var(--text-letter-spacing); + background-color: var(--bg-elevated-default); + color: var(--text-default); + border: none; + border-radius: var(--radius-large); + display: inline-flex; + position: relative; + box-shadow: + 0 0 0.25px rgba(0, 0, 0, 0.08), + 0 2px 2.5px rgba(0, 0, 0, 0.15), + 0 10px 12px rgba(0, 0, 0, 0.18); + } + + .react-datepicker--time-only .react-datepicker__time, + .react-datepicker--time-only .react-datepicker__time-box { + border-bottom-left-radius: var(--radius-large); + border-bottom-right-radius: var(--radius-large); + } + + .react-datepicker--time-only .react-datepicker__time-container { + border-left: none; + } + + .react-datepicker-popper { + z-index: 10; + line-height: 0; + } + + .react-datepicker-popper .react-datepicker__triangle { + display: none; + } + + /* —————————————————————————————————————————————— + Header + ————————————————————————————————————————————— */ + + .react-datepicker__header { + display: flex; + flex-wrap: wrap; + align-items: center; + text-align: center; + text-transform: none; + background-color: transparent; + border-bottom: none; + border-radius: 0; + padding: 0; + position: relative; + width: min-content; + + & h2 { + display: none; + } + + &:not(.react-datepicker__header--has-time-select) { + border-top-right-radius: var(--radius-large); + } + } + + .react-datepicker__header--time { + display: flex; + align-items: center; + justify-content: center; + padding: var(--spacer-2); + border-top-left-radius: 0; + border-top-right-radius: var(--radius-large); + font-weight: var(--text-body-medium-strong-font-weight); + min-height: calc(var(--spacer-4) + var(--spacer-2) * 2); + width: 100%; + } + + .react-datepicker__current-month { + display: none; + } + + .react-datepicker-time__header { + margin-top: 0; + color: var(--text-default); + font-family: var(--text-body-medium-strong-font-family); + font-size: var(--text-body-medium-strong-font-size); + font-weight: var(--text-body-medium-strong-font-weight); + line-height: var(--text-body-medium-strong-line-height); + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + } + + .react-datepicker__header__dropdown { + display: flex; + flex: 1 1 auto; + min-width: min-content; + gap: var(--spacer-2); + align-items: center; + order: 1; + padding: var(--spacer-2); + margin: 0 var(--spacer-5); + } + + .react-datepicker-year-header { + padding: var(--spacer-2-5) 0; + font-weight: var(--text-body-medium-strong-font-weight); + color: var(--text-default); + width: 100%; + display: flex; + justify-content: center; + } + + .react-datepicker__month-select, + .react-datepicker__year-select { + width: 100%; + margin: 0; + height: var(--spacer-4); + border: 1px solid var(--border-default); + background: var(--bg-default); + border-radius: var(--radius-medium); + outline: none; + cursor: pointer; + padding: 0 var(--spacer-2); + color: var(--text-default); + font-family: var(--text-body-medium-font-family); + font-size: var(--text-body-medium-font-size); + font-weight: var(--text-body-medium-font-weight); + -webkit-appearance: none; + appearance: none; + background-image: none; + padding-right: var(--spacer-4); + + option { + background-color: var(--bg-elevated-default); + color: var(--text-default); + } + } + + /* —————————————————————————————————————————————— + Navigation arrows + ————————————————————————————————————————————— */ + + .react-datepicker__navigation { + position: absolute; + align-items: center; + background: none; + display: flex; + justify-content: center; + text-align: center; + cursor: pointer; + top: 0; + margin: var(--spacer-2); + border: none; + z-index: 1; + height: var(--spacer-4); + width: var(--spacer-4); + text-indent: -999em; + overflow: hidden; + color: var(--icon-secondary); + border-radius: var(--radius-medium); + flex-shrink: 0; + + &:hover { + background-color: var(--bg-hover); + } + } + + .react-datepicker__navigation--years { + position: relative; + top: 0; + display: block; + margin-left: auto; + margin-right: auto; + } + + .react-datepicker__navigation--years-previous { + top: var(--spacer-1); + } + + .react-datepicker__navigation--years-upcoming { + top: calc(-1 * var(--spacer-1)); + } + + .react-datepicker__navigation--previous { + left: 0; + } + + .react-datepicker__navigation--previous span { + rotate: -135deg; + margin-left: 3px; + } + + .react-datepicker__navigation--next { + right: 0; + } + + .react-datepicker__navigation--next--with-time:not( + .react-datepicker__navigation--next--with-today-button + ) { + right: var(--time-column-width); + } + + .react-datepicker__navigation--next span { + rotate: 45deg; + margin-right: 3px; + } + + .react-datepicker__navigation-icon { + width: 7px; + height: 7px; + border-color: var(--icon-default); + border-style: solid; + border-width: 1px 1px 0 0; + font-size: 0; + line-height: 0; + text-indent: -999em; + overflow: hidden; + } + + .react-datepicker__navigation:hover .react-datepicker__navigation-icon { + border-color: var(--icon-default); + } + + /* —————————————————————————————————————————————— + Dropdowns (month, year) + ————————————————————————————————————————————— */ + + .react-datepicker__year-dropdown-container--select, + .react-datepicker__month-dropdown-container--select, + .react-datepicker__month-year-dropdown-container--select { + display: inline-block; + flex: 1 1 auto; + min-width: min-content; + margin: 0; + position: relative; + + &::after { + content: ''; + position: absolute; + right: var(--spacer-2); + top: 50%; + transform: translateY(-50%); + width: 8px; + height: 5px; + background-color: var(--icon-default); + mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='4' viewBox='0 0 6 4' fill='none'%3E%3Cpath d='M4.38935 0.146345C4.58463 -0.0487137 4.90119 -0.048849 5.09638 0.146345C5.29132 0.34156 5.29136 0.658183 5.09638 0.853376L2.97529 2.97447C2.78011 3.16965 2.46354 3.16947 2.26826 2.97447L0.146188 0.853376C-0.0487296 0.65818 -0.0487291 0.341541 0.146188 0.146345C0.341468 -0.0487138 0.659001 -0.0488494 0.854196 0.146345L2.62177 1.91392L4.38935 0.146345Z' fill='black'/%3E%3C/svg%3E"); + mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='4' viewBox='0 0 6 4' fill='none'%3E%3Cpath d='M4.38935 0.146345C4.58463 -0.0487137 4.90119 -0.048849 5.09638 0.146345C5.29132 0.34156 5.29136 0.658183 5.09638 0.853376L2.97529 2.97447C2.78011 3.16965 2.46354 3.16947 2.26826 2.97447L0.146188 0.853376C-0.0487296 0.65818 -0.0487291 0.341541 0.146188 0.146345C0.341468 -0.0487138 0.659001 -0.0488494 0.854196 0.146345L2.62177 1.91392L4.38935 0.146345Z' fill='black'/%3E%3C/svg%3E"); + -webkit-mask-repeat: no-repeat; + -webkit-mask-size: contain; + pointer-events: none; + } + } + + .react-datepicker__year-dropdown-container--scroll, + .react-datepicker__month-dropdown-container--scroll, + .react-datepicker__month-year-dropdown-container--scroll { + display: inline-block; + margin: 0 var(--spacer-1); + } + + .react-datepicker__year-read-view, + .react-datepicker__month-read-view, + .react-datepicker__month-year-read-view { + border: 1px solid transparent; + border-radius: var(--radius-medium); + position: relative; + + &:hover { + cursor: pointer; + } + } + + .react-datepicker__year-read-view--down-arrow, + .react-datepicker__month-read-view--down-arrow, + .react-datepicker__month-year-read-view--down-arrow { + border-color: var(--icon-secondary); + border-style: solid; + border-width: 2px 2px 0 0; + content: ''; + display: block; + height: 6px; + position: absolute; + top: 4px; + width: 6px; + transform: rotate(135deg); + right: -1rem; + } + + .react-datepicker__year-dropdown, + .react-datepicker__month-dropdown, + .react-datepicker__month-year-dropdown { + background-color: var(--bg-elevated-default); + position: absolute; + width: 50%; + left: 25%; + top: 30px; + z-index: 1; + text-align: center; + border-radius: var(--radius-medium); + border: 1px solid var(--border-default); + box-shadow: + 0 2px 5px rgba(0, 0, 0, 0.15), + 0 10px 24px rgba(0, 0, 0, 0.18); + + &:hover { + cursor: pointer; + } + } + + .react-datepicker__year-dropdown--scrollable, + .react-datepicker__month-dropdown--scrollable, + .react-datepicker__month-year-dropdown--scrollable { + height: 150px; + overflow-y: scroll; + } + + .react-datepicker__year-option, + .react-datepicker__month-option, + .react-datepicker__month-year-option { + line-height: 1.25rem; + width: 100%; + display: block; + margin-left: auto; + margin-right: auto; + color: var(--text-default); + + &:first-of-type { + border-top-left-radius: var(--radius-medium); + border-top-right-radius: var(--radius-medium); + } + + &:last-of-type { + user-select: none; + border-bottom-left-radius: var(--radius-medium); + border-bottom-right-radius: var(--radius-medium); + } + + &:hover { + background-color: var(--bg-hover); + } + } + + .react-datepicker__year-option--selected, + .react-datepicker__month-option--selected, + .react-datepicker__month-year-option--selected { + position: absolute; + left: 15px; + } + + /* —————————————————————————————————————————————— + Month container + ————————————————————————————————————————————— */ + + .react-datepicker__month-container { + position: relative; + } + + .react-datepicker__month { + margin: 0; + padding: var(--spacer-1); + text-align: center; + + .react-datepicker__month-text, + .react-datepicker__quarter-text { + display: inline-block; + width: 52px; + margin: var(--spacer-1); + height: var(--spacer-4); + padding: var(--spacer-1, 0.3rem) var(--spacer-2-5, 0.75rem); + } + } + + .react-datepicker__monthPicker { + border-top: 1px solid var(--border-default); + } + + .react-datepicker__month-text { + padding: var(--spacer-1); + font-size: var(--text-body-medium-font-size); + border-radius: var(--radius-medium); + } + + /* —————————————————————————————————————————————— + Year view + ————————————————————————————————————————————— */ + + .react-datepicker__year { + margin: var(--spacer-1); + text-align: center; + } + + .react-datepicker__year-wrapper { + display: flex; + flex-wrap: wrap; + max-width: 180px; + } + + .react-datepicker__year .react-datepicker__year-text { + display: inline-block; + width: 4rem; + margin: 2px; + } + + /* —————————————————————————————————————————————— + Day names & days + ————————————————————————————————————————————— */ + + .react-datepicker__day-names { + white-space: nowrap; + margin-bottom: 0; + background-color: transparent; + padding: var(--spacer-2); + padding-bottom: 0; + border-top: 1px solid var(--border-default); + width: 100%; + order: 3; + } + + .react-datepicker__week { + white-space: nowrap; + } + + .react-datepicker__day-name, + .react-datepicker__day, + .react-datepicker__time-name { + color: var(--text-default); + display: inline-flex; + align-items: center; + justify-content: center; + width: 2rem; + height: 2rem; + line-height: var(--text-body-medium-line-height); + text-align: center; + margin: 0; + font-family: var(--text-body-medium-font-family); + font-size: var(--text-body-medium-font-size); + font-weight: var(--text-body-medium-font-weight); + position: relative; + } + + .react-datepicker__day-name { + color: var(--text-secondary); + width: 1.5rem; + height: 2rem; + margin: 0 var(--spacer-1); + line-height: 2rem; + } + + .react-datepicker__day { + width: 1.5rem; + height: 1.5rem; + margin: var(--spacer-1); + line-height: 1.5rem; + + &:focus { + outline: 0; + } + } + + .react-datepicker__day, + .react-datepicker__month-text, + .react-datepicker__quarter-text, + .react-datepicker__year-text { + cursor: pointer; + border-radius: var(--radius-medium); + + &:hover { + background-color: var(--bg-hover); + } + + &:active { + background-color: var(--bg-default-pressed); + } + } + + .react-datepicker__day--today { + font-weight: var(--text-body-medium-font-weight); + position: relative; + + &::after { + content: ''; + position: absolute; + bottom: var(--spacer-1); + left: 50%; + transform: translate3D(-50%, 50%, 0); + width: 3px; + height: 3px; + border-radius: var(--radius-full); + background-color: var(--bg-brand); + } + } + + /* Outside month days (prev/next month) */ + .react-datepicker__day--outside-month { + visibility: hidden; + } + + /* Selected day */ + .react-datepicker__day--selected, + .react-datepicker__day--in-selecting-range, + .react-datepicker__day--in-range, + .react-datepicker__month-text--selected, + .react-datepicker__month-text--in-selecting-range, + .react-datepicker__month-text--in-range, + .react-datepicker__quarter-text--selected, + .react-datepicker__quarter-text--in-selecting-range, + .react-datepicker__quarter-text--in-range, + .react-datepicker__year-text--selected, + .react-datepicker__year-text--in-selecting-range, + .react-datepicker__year-text--in-range { + background-color: var(--bg-selected-strong); + color: var(--text-selected-onselected-strong); + font-weight: var(--text-body-medium-font-weight); + + &:hover { + background-color: var(--bg-selected-strong-hover); + } + } + + .react-datepicker__day--selected:focus { + background-color: var(--bg-selected-strong); + } + + .react-datepicker__day--keyboard-selected, + .react-datepicker__month-text--keyboard-selected, + .react-datepicker__quarter-text--keyboard-selected, + .react-datepicker__year-text--keyboard-selected { + background-color: var(--bg-selected); + color: var(--text-default); + + &:hover { + background-color: var(--bg-selected-hover); + } + } + + .react-datepicker__day--keyboard-selected:focus { + background-color: var(--bg-selected); + outline: 2px solid var(--border-selected); + outline-offset: -2px; + } + + /* In-range selecting (partial selection) */ + .react-datepicker__day--in-selecting-range:not( + .react-datepicker__day--in-range, + .react-datepicker__month-text--in-range, + .react-datepicker__quarter-text--in-range, + .react-datepicker__year-text--in-range + ), + .react-datepicker__month-text--in-selecting-range:not( + .react-datepicker__day--in-range, + .react-datepicker__month-text--in-range, + .react-datepicker__quarter-text--in-range, + .react-datepicker__year-text--in-range + ), + .react-datepicker__quarter-text--in-selecting-range:not( + .react-datepicker__day--in-range, + .react-datepicker__month-text--in-range, + .react-datepicker__quarter-text--in-range, + .react-datepicker__year-text--in-range + ), + .react-datepicker__year-text--in-selecting-range:not( + .react-datepicker__day--in-range, + .react-datepicker__month-text--in-range, + .react-datepicker__quarter-text--in-range, + .react-datepicker__year-text--in-range + ) { + background-color: var(--bg-selected); + } + + /* Disabled days */ + .react-datepicker__day--disabled, + .react-datepicker__month-text--disabled, + .react-datepicker__quarter-text--disabled, + .react-datepicker__year-text--disabled { + cursor: default; + color: var(--text-disabled-default); + + &:hover { + background-color: transparent; + } + } + + /* —————————————————————————————————————————————— + Week number + ————————————————————————————————————————————— */ + + .react-datepicker__week-number { + color: var(--text-tertiary); + display: inline-block; + width: 2rem; + line-height: 2rem; + text-align: center; + margin: 0; + } + + /* —————————————————————————————————————————————— + Input container + ————————————————————————————————————————————— */ + + .react-datepicker__input-container { + position: relative; + display: inline-block; + width: 100%; + } + + /* —————————————————————————————————————————————— + Time picker + ————————————————————————————————————————————— */ + + .react-datepicker__time-container { + float: right; + border-left: 1px solid var(--border-default); + width: var(--time-column-width); + + .react-datepicker__time { + position: relative; + background: transparent; + border-top: 1px solid var(--border-default); + border-bottom-right-radius: var(--radius-large); + + .react-datepicker__time-box { + width: var(--time-column-width); + overflow-x: hidden; + margin: 0 auto; + text-align: center; + border-bottom-right-radius: var(--radius-large); + + ul.react-datepicker__time-list { + list-style: none; + margin: 0; + height: calc(195px + 0.85rem); + max-height: 100%; + overflow-y: scroll; + scrollbar-width: none; + padding: var(--spacer-1) 0; + padding-right: 0; + padding-left: 0; + width: 100%; + box-sizing: content-box; + + &::-webkit-scrollbar { + display: none; + } + + li.react-datepicker__time-list-item { + height: auto; + padding: var(--spacer-1) var(--spacer-2); + white-space: nowrap; + font-family: var(--text-body-medium-font-family); + font-size: var(--text-body-medium-font-size); + font-weight: var(--text-body-medium-font-weight); + line-height: var(--text-body-medium-line-height); + color: var(--text-default); + margin: 0 var(--spacer-2); + border-radius: var(--radius-medium); + + &:hover { + cursor: pointer; + background-color: var(--bg-hover); + } + + &:active { + background-color: var(--bg-default-pressed); + } + + &:focus { + background-color: var(--bg-selected); + outline: none; + } + } + + li.react-datepicker__time-list-item--selected { + background-color: var(--bg-brand-default); + color: var(--text-onbrand); + + &:hover { + background-color: var(--bg-brand-hover); + } + + &:focus { + background-color: var(--bg-brand-default); + } + } + + li.react-datepicker__time-list-item--disabled { + color: var(--text-disabled-default); + + &:hover { + cursor: default; + background-color: transparent; + } + } + } + } + } + } + + .react-datepicker__input-time-container { + clear: both; + width: 100%; + float: left; + margin: var(--spacer-1) 0 var(--spacer-2) var(--spacer-3); + text-align: left; + } + + /* —————————————————————————————————————————————— + Close icon + ————————————————————————————————————————————— */ + + .react-datepicker__close-icon { + display: none; + } + + /* —————————————————————————————————————————————— + Today button + ————————————————————————————————————————————— */ + + .react-datepicker__today-button { + background: var(--bg-secondary); + border-top: 1px solid var(--border-default); + cursor: pointer; + text-align: center; + font-weight: var(--text-body-medium-strong-font-weight); + padding: var(--spacer-1) 0; + clear: left; + border-bottom-left-radius: var(--radius-large); + border-bottom-right-radius: var(--radius-large); + } + + /* —————————————————————————————————————————————— + Portal + ————————————————————————————————————————————— */ + + .react-datepicker__portal { + position: fixed; + width: 100vw; + height: 100vh; + background-color: rgba(0, 0, 0, 0.8); + left: 0; + top: 0; + justify-content: center; + align-items: center; + display: flex; + z-index: 2147483647; + } + + .react-datepicker__aria-live { + position: absolute; + clip-path: circle(0); + border: 0; + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + width: 1px; + white-space: nowrap; + } + + .react-datepicker__children-container { + width: 13.8rem; + margin: var(--spacer-1); + padding-right: 0.2rem; + padding-left: 0.2rem; + height: auto; + } + + /* —————————————————————————————————————————————— + DatePicker component styles + ————————————————————————————————————————————— */ + + [dir='rtl'] { + .date-time-picker { + .react-datepicker__input-container input { + padding-right: var(--spacer-5); + } + } + } + + .date-time-picker__icon-wrap { + position: relative; + z-index: 1; + } + + .date-time-picker .icon--calendar, + .date-time-picker__clear-button { + position: absolute; + } + + .date-time-picker .icon--calendar, + .date-time-picker .icon--x { + color: var(--icon-secondary); + height: auto; + } + + .date-time-picker__clear-button { + top: var(--spacer-2); + right: var(--spacer-5); + appearance: none; + background-color: transparent; + border: none; + outline: none; + padding: 0; + display: flex; + cursor: pointer; + } + + .date-time-picker .icon--calendar { + top: 50%; + right: var(--spacer-2-5); + width: 1.125rem; + pointer-events: none; + transform: translateY(-50%); + } + + .date-time-picker .icon--x { + width: 1rem; + } + + /* ——— Input field ——— */ + .date-time-picker .react-datepicker__input-container input { + font-family: var(--text-body-medium-font-family); + font-size: var(--text-body-medium-font-size); + font-weight: var(--text-body-medium-font-weight); + line-height: var(--text-body-medium-line-height); + letter-spacing: var(--text-letter-spacing); + width: 100%; + border: 1px solid var(--border-default); + border-radius: var(--radius-medium); + background: var(--bg-default); + color: var(--text-default); + height: 2rem; + padding: var(--spacer-2); + padding-right: 2.25rem; + -webkit-appearance: none; + outline: none; + + &::placeholder { + color: var(--text-tertiary); + font-weight: var(--text-body-medium-font-weight); + } + + &:hover { + border-color: var(--border-default-strong); + } + + &:focus, + &:focus-within, + &:active { + border-color: var(--border-selected); + border-width: 1px; + outline: 0; + } + + &:disabled { + background: var(--bg-secondary); + color: var(--text-disabled-default); + cursor: not-allowed; + border-color: var(--border-disabled-default); + } + } + + /* ——— Error state ——— */ + .date-time-picker--has-error .react-datepicker__input-container input { + border-color: var(--border-danger-strong); + border-width: 2px; + padding: calc(var(--spacer-1) - 1px) calc(var(--spacer-2-5) - 1px); + padding-right: calc(2.25rem - 1px); + } + + /* ——— Appearance variants ——— */ + .date-time-picker__appearance--dayOnly .react-datepicker__month-container, + .date-time-picker__appearance--monthOnly .react-datepicker__month-container { + border-right: none; + } + + @media (max-width: 768px) { + .date-time-picker .react-datepicker { + flex-direction: column; + } + + .date-time-picker .react-datepicker__month-container { + border-right: 0; + } + + .date-time-picker .react-datepicker__time-container { + width: auto; + border-top: 1px solid var(--border-default); + } + + .date-time-picker .react-datepicker__header--time { + background-color: transparent; + padding: var(--spacer-2) 0; + border-bottom: none; + } + + .date-time-picker + .react-datepicker__time-container + .react-datepicker__time + .react-datepicker__time-box { + height: var(--time-column-width); + width: unset; + + > ul { + height: var(--time-column-width); + } + } + + .date-time-picker + .react-datepicker__navigation--next--with-time:not( + .react-datepicker__navigation--next--with-today-button + ) { + right: 0; + } + + .date-time-picker__input-wrapper .icon { + top: 50%; + transform: translateY(-50%); + } + } +} diff --git a/packages/ui/src/elements/DatePicker/index.scss b/packages/ui/src/elements/DatePicker/index.scss deleted file mode 100644 index e08911b1a43..00000000000 --- a/packages/ui/src/elements/DatePicker/index.scss +++ /dev/null @@ -1,409 +0,0 @@ -@import '../../scss/styles'; -@import './library.scss'; - -$cal-icon-width: 18px; - -@layer payload-default { - [dir='rtl'] { - .date-time-picker { - .react-datepicker__input-container input { - padding-right: base(3.4); - } - } - } - - .date-time-picker { - .react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box, - .react-datepicker__time-container { - width: 120px; - } - - &__icon-wrap { - position: relative; - z-index: 1; - } - - .icon--calendar, - &__clear-button { - position: absolute; - } - - .icon--calendar, - .icon--x { - @include color-svg(var(--theme-elevation-800)); - height: auto; - } - - &__clear-button { - top: base(0.5); - right: base(2); - } - - .icon--calendar { - top: base(0.5); - right: base(0.75); - width: $cal-icon-width; - pointer-events: none; - } - - .icon--x { - width: base(1); - } - - &__clear-button { - appearance: none; - background-color: transparent; - border: none; - outline: none; - padding: 0; - display: flex; - cursor: pointer; - } - - &__appearance--timeOnly { - .react-datepicker { - width: 100%; - - &__month-container, - &__navigation--previous, - &__navigation--next { - display: none; - visibility: hidden; - } - - &-popper, - &__time-container, - &__time-box { - width: base(6); - } - - &__time-container { - .react-datepicker__time { - .react-datepicker__time-box { - width: 100%; - } - } - } - } - } - - .react-datepicker-wrapper { - display: block; - } - - .react-datepicker-wrapper, - .react-datepicker__input-container { - width: 100%; - } - - .react-datepicker__input-container input { - @include formInput; - padding-right: calc(#{base(0.75)} + #{$cal-icon-width}); - } - - &--has-error { - .react-datepicker__input-container input { - background-color: var(--theme-error-200); - } - } - - .react-datepicker { - @include shadow-lg; - border: 1px solid var(--theme-elevation-100); - background: var(--theme-input-bg); - display: inline-flex; - font-family: var(--font-body); - font-weight: 100; - border-radius: 0; - color: var(--theme-elevation-800); - - &__header { - padding-top: 0; - text-transform: none; - text-align: center; - border-radius: 0; - border: none; - background-color: var(--theme-input-bg); - - &--time { - padding: 10px 0; - border-bottom: 1px solid var(--theme-elevation-150); - font-weight: 600; - } - } - - &__navigation { - background: none; - line-height: 1.7rem; - text-align: center; - cursor: pointer; - position: absolute; - top: 10px; - width: 0; - padding: 0; - border: 0.45rem solid transparent; - z-index: 1; - height: 10px; - width: 10px; - text-indent: -999em; - overflow: hidden; - top: 15px; - - &--next { - border-left-color: var(--theme-elevation-400); - - &:focus { - border-left-color: var(--theme-elevation-500); - outline: none; - } - } - - &--previous { - border-right-color: var(--theme-elevation-400); - - &:focus { - border-right-color: var(--theme-elevation-500); - outline: none; - } - } - } - - &__current-month, - &__header, - &-year-header, - &__day-name, - &__day, - &__time-name, - &-time__header { - color: var(--theme-elevation-1000); - } - - &__current-month { - display: none; - } - - &__header__dropdown, - &-year-header { - padding: 10px 0; - font-weight: bold; - } - - &__month-container { - border-right: 1px solid var(--theme-elevation-150); - } - - &__time, - &__time-container, - .react-datepicker__time-container .react-datepicker__time { - background: none; - } - - &__time-container { - border-left: none; - } - - &__month-text { - padding: base(0.3); - margin: base(0.15); - font-size: base(0.55); - &:hover { - background: var(--theme-elevation-100); - } - } - - &__month-select, - &__year-select { - min-width: 70px; - border: none; - background: none; - outline: none; - cursor: pointer; - - option { - background-color: var(--theme-elevation-50); - } - } - - &__day-names { - background-color: var(--theme-elevation-100); - } - - &__day { - box-shadow: inset 0px 0px 0px 1px var(--theme-elevation-150); - font-size: base(0.55); - - &:hover { - background: var(--theme-elevation-100); - } - - &:focus { - outline: 0; - background: var(--theme-elevation-400); - } - - &--selected { - font-weight: bold; - - &:focus { - background-color: var(--theme-elevation-150); - } - } - - &--keyboard-selected { - color: var(--theme-elevation-0); - font-weight: bold; - - &:focus { - background-color: var(--theme-elevation-150); - box-shadow: - inset 0px 0px 0px 1px var(--theme-elevation-800), - 0px 0px 0px 1px var(--theme-elevation-800); - } - } - - &--today { - font-weight: bold; - } - } - - &__day, - &__day-name { - width: base(1.5); - margin: base(0.15); - line-height: base(1.25); - } - } - - .react-datepicker-popper { - z-index: 10; - border: none; - } - - .react-datepicker__time-container - .react-datepicker__time - .react-datepicker__time-box - ul.react-datepicker__time-list { - max-height: 100%; - } - - .react-datepicker__day--keyboard-selected, - .react-datepicker__month-text--keyboard-selected, - .react-datepicker__time-container - .react-datepicker__time - .react-datepicker__time-box - ul.react-datepicker__time-list - li.react-datepicker__time-list-item--selected { - box-shadow: none; - background-color: var(--theme-elevation-150); - font-weight: bold; - color: var(--theme-elevation-800); - border-radius: 0; - } - - .react-datepicker__time-container - .react-datepicker__time - .react-datepicker__time-box - ul.react-datepicker__time-list - li.react-datepicker__time-list-item--selected, - .react-datepicker__day--selected, - .react-datepicker__day--in-selecting-range, - .react-datepicker__day--in-range, - .react-datepicker__month-text--selected, - .react-datepicker__month-text--in-selecting-range, - .react-datepicker__month-text--in-range { - box-shadow: none; - background-color: var(--theme-elevation-150); - color: var(--theme-elevation-800); - font-weight: bold; - border-radius: 0; - } - - .react-datepicker__time-container - .react-datepicker__time - .react-datepicker__time-box - ul.react-datepicker__time-list - li.react-datepicker__time-list-item:hover { - background: var(--theme-elevation-100); - } - - .react-datepicker__day:hover, - .react-datepicker__month-text:hover { - border-radius: 0; - } - - .react-datepicker__month .react-datepicker__day { - &.react-datepicker__day--disabled { - color: var(--theme-elevation-200); - - &:hover { - background: none; - } - } - } - - .react-datepicker__navigation--next--with-time:not( - .react-datepicker__navigation--next--with-today-button - ) { - right: 130px; - } - - .react-datepicker__time-container - .react-datepicker__time - .react-datepicker__time-box - ul.react-datepicker__time-list - li.react-datepicker__time-list-item { - line-height: 20px; - font-size: base(0.5); - - &.react-datepicker__time-list-item--disabled { - color: var(--theme-elevation-200); - &:hover { - background: none; - } - } - } - - &__appearance--dayOnly, - &__appearance--monthOnly { - .react-datepicker { - &__month-container { - border-right: none; - } - } - } - - @include small-break { - .react-datepicker { - flex-direction: column; - } - .react-datepicker__month-container { - border-right: 0; - } - .react-datepicker__time-container { - width: auto; - } - .react-datepicker__header--time { - background-color: var(--theme-elevation-100); - padding: 8px 0; - border-bottom: none; - } - .react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box { - height: 120px; - width: unset; - > ul { - height: 120px; - } - } - .react-datepicker__navigation--next--with-time:not( - .react-datepicker__navigation--next--with-today-button - ) { - right: 0px; - } - &__input-wrapper { - .icon { - top: calc(50% - #{base(0.25)}); - } - } - } - } -} diff --git a/packages/ui/src/elements/DatePicker/library.scss b/packages/ui/src/elements/DatePicker/library.scss deleted file mode 100644 index 7bedf4e1d9a..00000000000 --- a/packages/ui/src/elements/DatePicker/library.scss +++ /dev/null @@ -1,859 +0,0 @@ -// CSS manually copied into the payload-default layer from the react-datepicker library -// see: /node_modules/react-datepicker/dist/react-datepicker.css - -@layer payload-default { - .react-datepicker__year-read-view--down-arrow, - .react-datepicker__month-read-view--down-arrow, - .react-datepicker__month-year-read-view--down-arrow, - .react-datepicker__navigation-icon::before { - border-color: #ccc; - border-style: solid; - border-width: 3px 3px 0 0; - content: ''; - display: block; - height: 9px; - position: absolute; - top: 6px; - width: 9px; - } - .react-datepicker-wrapper { - display: inline-block; - padding: 0; - border: 0; - } - - .react-datepicker { - font-family: 'Helvetica Neue', helvetica, arial, sans-serif; - font-size: 0.8rem; - background-color: #fff; - color: #000; - border: 1px solid #aeaeae; - border-radius: 0.3rem; - display: inline-block; - position: relative; - line-height: initial; - } - - .react-datepicker--time-only .react-datepicker__time-container { - border-left: 0; - } - .react-datepicker--time-only .react-datepicker__time, - .react-datepicker--time-only .react-datepicker__time-box { - border-bottom-left-radius: 0.3rem; - border-bottom-right-radius: 0.3rem; - } - - .react-datepicker-popper { - z-index: 1; - line-height: 0; - } - .react-datepicker-popper .react-datepicker__triangle { - stroke: #aeaeae; - } - .react-datepicker-popper[data-placement^='bottom'] .react-datepicker__triangle { - fill: #f0f0f0; - color: #f0f0f0; - } - .react-datepicker-popper[data-placement^='top'] .react-datepicker__triangle { - fill: #fff; - color: #fff; - } - - .react-datepicker__header { - text-align: center; - background-color: #f0f0f0; - border-bottom: 1px solid #aeaeae; - border-top-left-radius: 0.3rem; - padding: 8px 0; - position: relative; - } - .react-datepicker__header--time { - padding-bottom: 8px; - padding-left: 5px; - padding-right: 5px; - } - .react-datepicker__header--time:not(.react-datepicker__header--time--only) { - border-top-left-radius: 0; - } - .react-datepicker__header:not(.react-datepicker__header--has-time-select) { - border-top-right-radius: 0.3rem; - } - - .react-datepicker__year-dropdown-container--select, - .react-datepicker__month-dropdown-container--select, - .react-datepicker__month-year-dropdown-container--select, - .react-datepicker__year-dropdown-container--scroll, - .react-datepicker__month-dropdown-container--scroll, - .react-datepicker__month-year-dropdown-container--scroll { - display: inline-block; - margin: 0 15px; - } - - .react-datepicker__current-month, - .react-datepicker-time__header, - .react-datepicker-year-header { - margin-top: 0; - color: #000; - font-weight: bold; - font-size: 0.944rem; - } - - .react-datepicker-time__header { - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - } - - .react-datepicker__navigation { - align-items: center; - background: none; - display: flex; - justify-content: center; - text-align: center; - cursor: pointer; - position: absolute; - top: 2px; - padding: 0; - border: none; - z-index: 1; - height: 32px; - width: 32px; - text-indent: -999em; - overflow: hidden; - } - .react-datepicker__navigation--previous { - left: 2px; - } - .react-datepicker__navigation--next { - right: 2px; - } - .react-datepicker__navigation--next--with-time:not( - .react-datepicker__navigation--next--with-today-button - ) { - right: 85px; - } - .react-datepicker__navigation--years { - position: relative; - top: 0; - display: block; - margin-left: auto; - margin-right: auto; - } - .react-datepicker__navigation--years-previous { - top: 4px; - } - .react-datepicker__navigation--years-upcoming { - top: -4px; - } - .react-datepicker__navigation:hover *::before { - border-color: #a6a6a6; - } - - .react-datepicker__navigation-icon { - position: relative; - top: -1px; - font-size: 20px; - width: 0; - } - .react-datepicker__navigation-icon--next { - left: -2px; - } - .react-datepicker__navigation-icon--next::before { - transform: rotate(45deg); - left: -7px; - } - .react-datepicker__navigation-icon--previous { - right: -2px; - } - .react-datepicker__navigation-icon--previous::before { - transform: rotate(225deg); - right: -7px; - } - - .react-datepicker__month-container { - float: left; - } - - .react-datepicker__year { - margin: 0.4rem; - text-align: center; - } - .react-datepicker__year-wrapper { - display: flex; - flex-wrap: wrap; - max-width: 180px; - } - .react-datepicker__year .react-datepicker__year-text { - display: inline-block; - width: 4rem; - margin: 2px; - } - - .react-datepicker__month { - margin: 0.4rem; - text-align: center; - } - .react-datepicker__month .react-datepicker__month-text, - .react-datepicker__month .react-datepicker__quarter-text { - display: inline-block; - width: 4rem; - margin: 2px; - } - - .react-datepicker__input-time-container { - clear: both; - width: 100%; - float: left; - margin: 5px 0 10px 15px; - text-align: left; - } - .react-datepicker__input-time-container .react-datepicker-time__caption { - display: inline-block; - } - .react-datepicker__input-time-container .react-datepicker-time__input-container { - display: inline-block; - } - .react-datepicker__input-time-container - .react-datepicker-time__input-container - .react-datepicker-time__input { - display: inline-block; - margin-left: 10px; - } - .react-datepicker__input-time-container - .react-datepicker-time__input-container - .react-datepicker-time__input - input { - width: auto; - } - .react-datepicker__input-time-container - .react-datepicker-time__input-container - .react-datepicker-time__input - input[type='time']::-webkit-inner-spin-button, - .react-datepicker__input-time-container - .react-datepicker-time__input-container - .react-datepicker-time__input - input[type='time']::-webkit-outer-spin-button { - -webkit-appearance: none; - margin: 0; - } - .react-datepicker__input-time-container - .react-datepicker-time__input-container - .react-datepicker-time__input - input[type='time'] { - -moz-appearance: textfield; - } - .react-datepicker__input-time-container - .react-datepicker-time__input-container - .react-datepicker-time__delimiter { - margin-left: 5px; - display: inline-block; - } - - .react-datepicker__time-container { - float: right; - border-left: 1px solid #aeaeae; - width: 85px; - } - .react-datepicker__time-container--with-today-button { - display: inline; - border: 1px solid #aeaeae; - border-radius: 0.3rem; - position: absolute; - right: -87px; - top: 0; - } - .react-datepicker__time-container .react-datepicker__time { - position: relative; - background: white; - border-bottom-right-radius: 0.3rem; - } - .react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box { - width: 85px; - overflow-x: hidden; - margin: 0 auto; - text-align: center; - border-bottom-right-radius: 0.3rem; - } - .react-datepicker__time-container - .react-datepicker__time - .react-datepicker__time-box - ul.react-datepicker__time-list { - list-style: none; - margin: 0; - height: calc(195px + 1.7rem / 2); - overflow-y: scroll; - padding-right: 0; - padding-left: 0; - width: 100%; - box-sizing: content-box; - } - .react-datepicker__time-container - .react-datepicker__time - .react-datepicker__time-box - ul.react-datepicker__time-list - li.react-datepicker__time-list-item { - height: 30px; - padding: 5px 10px; - white-space: nowrap; - } - .react-datepicker__time-container - .react-datepicker__time - .react-datepicker__time-box - ul.react-datepicker__time-list - li.react-datepicker__time-list-item:hover { - cursor: pointer; - background-color: #f0f0f0; - } - .react-datepicker__time-container - .react-datepicker__time - .react-datepicker__time-box - ul.react-datepicker__time-list - li.react-datepicker__time-list-item--selected { - background-color: #216ba5; - color: white; - font-weight: bold; - } - .react-datepicker__time-container - .react-datepicker__time - .react-datepicker__time-box - ul.react-datepicker__time-list - li.react-datepicker__time-list-item--selected:hover { - background-color: #216ba5; - } - .react-datepicker__time-container - .react-datepicker__time - .react-datepicker__time-box - ul.react-datepicker__time-list - li.react-datepicker__time-list-item--disabled { - color: #ccc; - } - .react-datepicker__time-container - .react-datepicker__time - .react-datepicker__time-box - ul.react-datepicker__time-list - li.react-datepicker__time-list-item--disabled:hover { - cursor: default; - background-color: transparent; - } - - .react-datepicker__week-number { - color: #ccc; - display: inline-block; - width: 1.7rem; - line-height: 1.7rem; - text-align: center; - margin: 0.166rem; - } - .react-datepicker__week-number.react-datepicker__week-number--clickable { - cursor: pointer; - } - .react-datepicker__week-number.react-datepicker__week-number--clickable:not( - .react-datepicker__week-number--selected, - .react-datepicker__week-number--keyboard-selected - ):hover { - border-radius: 0.3rem; - background-color: #f0f0f0; - } - .react-datepicker__week-number--selected { - border-radius: 0.3rem; - background-color: #216ba5; - color: #fff; - } - .react-datepicker__week-number--selected:hover { - background-color: #1d5d90; - } - .react-datepicker__week-number--keyboard-selected { - border-radius: 0.3rem; - background-color: #2a87d0; - color: #fff; - } - .react-datepicker__week-number--keyboard-selected:hover { - background-color: #1d5d90; - } - - .react-datepicker__day-names { - white-space: nowrap; - margin-bottom: -8px; - } - - .react-datepicker__week { - white-space: nowrap; - } - - .react-datepicker__day-name, - .react-datepicker__day, - .react-datepicker__time-name { - color: #000; - display: inline-block; - width: 1.7rem; - line-height: 1.7rem; - text-align: center; - margin: 0.166rem; - } - - .react-datepicker__day, - .react-datepicker__month-text, - .react-datepicker__quarter-text, - .react-datepicker__year-text { - cursor: pointer; - } - .react-datepicker__day:hover, - .react-datepicker__month-text:hover, - .react-datepicker__quarter-text:hover, - .react-datepicker__year-text:hover { - border-radius: 0.3rem; - background-color: #f0f0f0; - } - .react-datepicker__day--today, - .react-datepicker__month-text--today, - .react-datepicker__quarter-text--today, - .react-datepicker__year-text--today { - font-weight: bold; - } - .react-datepicker__day--highlighted, - .react-datepicker__month-text--highlighted, - .react-datepicker__quarter-text--highlighted, - .react-datepicker__year-text--highlighted { - border-radius: 0.3rem; - background-color: #3dcc4a; - color: #fff; - } - .react-datepicker__day--highlighted:hover, - .react-datepicker__month-text--highlighted:hover, - .react-datepicker__quarter-text--highlighted:hover, - .react-datepicker__year-text--highlighted:hover { - background-color: #32be3f; - } - .react-datepicker__day--highlighted-custom-1, - .react-datepicker__month-text--highlighted-custom-1, - .react-datepicker__quarter-text--highlighted-custom-1, - .react-datepicker__year-text--highlighted-custom-1 { - color: magenta; - } - .react-datepicker__day--highlighted-custom-2, - .react-datepicker__month-text--highlighted-custom-2, - .react-datepicker__quarter-text--highlighted-custom-2, - .react-datepicker__year-text--highlighted-custom-2 { - color: green; - } - .react-datepicker__day--holidays, - .react-datepicker__month-text--holidays, - .react-datepicker__quarter-text--holidays, - .react-datepicker__year-text--holidays { - position: relative; - border-radius: 0.3rem; - background-color: #ff6803; - color: #fff; - } - .react-datepicker__day--holidays .overlay, - .react-datepicker__month-text--holidays .overlay, - .react-datepicker__quarter-text--holidays .overlay, - .react-datepicker__year-text--holidays .overlay { - position: absolute; - bottom: 100%; - left: 50%; - transform: translateX(-50%); - background-color: #333; - color: #fff; - padding: 4px; - border-radius: 4px; - white-space: nowrap; - visibility: hidden; - opacity: 0; - transition: - visibility 0s, - opacity 0.3s ease-in-out; - } - .react-datepicker__day--holidays:hover, - .react-datepicker__month-text--holidays:hover, - .react-datepicker__quarter-text--holidays:hover, - .react-datepicker__year-text--holidays:hover { - background-color: #cf5300; - } - .react-datepicker__day--holidays:hover .overlay, - .react-datepicker__month-text--holidays:hover .overlay, - .react-datepicker__quarter-text--holidays:hover .overlay, - .react-datepicker__year-text--holidays:hover .overlay { - visibility: visible; - opacity: 1; - } - .react-datepicker__day--selected, - .react-datepicker__day--in-selecting-range, - .react-datepicker__day--in-range, - .react-datepicker__month-text--selected, - .react-datepicker__month-text--in-selecting-range, - .react-datepicker__month-text--in-range, - .react-datepicker__quarter-text--selected, - .react-datepicker__quarter-text--in-selecting-range, - .react-datepicker__quarter-text--in-range, - .react-datepicker__year-text--selected, - .react-datepicker__year-text--in-selecting-range, - .react-datepicker__year-text--in-range { - border-radius: 0.3rem; - background-color: #216ba5; - color: #fff; - } - .react-datepicker__day--selected:hover, - .react-datepicker__day--in-selecting-range:hover, - .react-datepicker__day--in-range:hover, - .react-datepicker__month-text--selected:hover, - .react-datepicker__month-text--in-selecting-range:hover, - .react-datepicker__month-text--in-range:hover, - .react-datepicker__quarter-text--selected:hover, - .react-datepicker__quarter-text--in-selecting-range:hover, - .react-datepicker__quarter-text--in-range:hover, - .react-datepicker__year-text--selected:hover, - .react-datepicker__year-text--in-selecting-range:hover, - .react-datepicker__year-text--in-range:hover { - background-color: #1d5d90; - } - .react-datepicker__day--keyboard-selected, - .react-datepicker__month-text--keyboard-selected, - .react-datepicker__quarter-text--keyboard-selected, - .react-datepicker__year-text--keyboard-selected { - border-radius: 0.3rem; - background-color: #bad9f1; - color: rgb(0, 0, 0); - } - .react-datepicker__day--keyboard-selected:hover, - .react-datepicker__month-text--keyboard-selected:hover, - .react-datepicker__quarter-text--keyboard-selected:hover, - .react-datepicker__year-text--keyboard-selected:hover { - background-color: #1d5d90; - } - .react-datepicker__day--in-selecting-range:not( - .react-datepicker__day--in-range, - .react-datepicker__month-text--in-range, - .react-datepicker__quarter-text--in-range, - .react-datepicker__year-text--in-range - ), - .react-datepicker__month-text--in-selecting-range:not( - .react-datepicker__day--in-range, - .react-datepicker__month-text--in-range, - .react-datepicker__quarter-text--in-range, - .react-datepicker__year-text--in-range - ), - .react-datepicker__quarter-text--in-selecting-range:not( - .react-datepicker__day--in-range, - .react-datepicker__month-text--in-range, - .react-datepicker__quarter-text--in-range, - .react-datepicker__year-text--in-range - ), - .react-datepicker__year-text--in-selecting-range:not( - .react-datepicker__day--in-range, - .react-datepicker__month-text--in-range, - .react-datepicker__quarter-text--in-range, - .react-datepicker__year-text--in-range - ) { - background-color: rgba(33, 107, 165, 0.5); - } - .react-datepicker__month--selecting-range - .react-datepicker__day--in-range:not( - .react-datepicker__day--in-selecting-range, - .react-datepicker__month-text--in-selecting-range, - .react-datepicker__quarter-text--in-selecting-range, - .react-datepicker__year-text--in-selecting-range - ), - .react-datepicker__year--selecting-range - .react-datepicker__day--in-range:not( - .react-datepicker__day--in-selecting-range, - .react-datepicker__month-text--in-selecting-range, - .react-datepicker__quarter-text--in-selecting-range, - .react-datepicker__year-text--in-selecting-range - ), - .react-datepicker__month--selecting-range - .react-datepicker__month-text--in-range:not( - .react-datepicker__day--in-selecting-range, - .react-datepicker__month-text--in-selecting-range, - .react-datepicker__quarter-text--in-selecting-range, - .react-datepicker__year-text--in-selecting-range - ), - .react-datepicker__year--selecting-range - .react-datepicker__month-text--in-range:not( - .react-datepicker__day--in-selecting-range, - .react-datepicker__month-text--in-selecting-range, - .react-datepicker__quarter-text--in-selecting-range, - .react-datepicker__year-text--in-selecting-range - ), - .react-datepicker__month--selecting-range - .react-datepicker__quarter-text--in-range:not( - .react-datepicker__day--in-selecting-range, - .react-datepicker__month-text--in-selecting-range, - .react-datepicker__quarter-text--in-selecting-range, - .react-datepicker__year-text--in-selecting-range - ), - .react-datepicker__year--selecting-range - .react-datepicker__quarter-text--in-range:not( - .react-datepicker__day--in-selecting-range, - .react-datepicker__month-text--in-selecting-range, - .react-datepicker__quarter-text--in-selecting-range, - .react-datepicker__year-text--in-selecting-range - ), - .react-datepicker__month--selecting-range - .react-datepicker__year-text--in-range:not( - .react-datepicker__day--in-selecting-range, - .react-datepicker__month-text--in-selecting-range, - .react-datepicker__quarter-text--in-selecting-range, - .react-datepicker__year-text--in-selecting-range - ), - .react-datepicker__year--selecting-range - .react-datepicker__year-text--in-range:not( - .react-datepicker__day--in-selecting-range, - .react-datepicker__month-text--in-selecting-range, - .react-datepicker__quarter-text--in-selecting-range, - .react-datepicker__year-text--in-selecting-range - ) { - background-color: #f0f0f0; - color: #000; - } - .react-datepicker__day--disabled, - .react-datepicker__month-text--disabled, - .react-datepicker__quarter-text--disabled, - .react-datepicker__year-text--disabled { - cursor: default; - color: #ccc; - } - .react-datepicker__day--disabled:hover, - .react-datepicker__month-text--disabled:hover, - .react-datepicker__quarter-text--disabled:hover, - .react-datepicker__year-text--disabled:hover { - background-color: transparent; - } - .react-datepicker__day--disabled .overlay, - .react-datepicker__month-text--disabled .overlay, - .react-datepicker__quarter-text--disabled .overlay, - .react-datepicker__year-text--disabled .overlay { - position: absolute; - bottom: 70%; - left: 50%; - transform: translateX(-50%); - background-color: #333; - color: #fff; - padding: 4px; - border-radius: 4px; - white-space: nowrap; - visibility: hidden; - opacity: 0; - transition: - visibility 0s, - opacity 0.3s ease-in-out; - } - - .react-datepicker__input-container { - position: relative; - display: inline-block; - width: 100%; - } - .react-datepicker__input-container .react-datepicker__calendar-icon { - position: absolute; - padding: 0.5rem; - box-sizing: content-box; - } - - .react-datepicker__view-calendar-icon input { - padding: 6px 10px 5px 25px; - } - - .react-datepicker__year-read-view, - .react-datepicker__month-read-view, - .react-datepicker__month-year-read-view { - border: 1px solid transparent; - border-radius: 0.3rem; - position: relative; - } - .react-datepicker__year-read-view:hover, - .react-datepicker__month-read-view:hover, - .react-datepicker__month-year-read-view:hover { - cursor: pointer; - } - .react-datepicker__year-read-view:hover .react-datepicker__year-read-view--down-arrow, - .react-datepicker__year-read-view:hover .react-datepicker__month-read-view--down-arrow, - .react-datepicker__month-read-view:hover .react-datepicker__year-read-view--down-arrow, - .react-datepicker__month-read-view:hover .react-datepicker__month-read-view--down-arrow, - .react-datepicker__month-year-read-view:hover .react-datepicker__year-read-view--down-arrow, - .react-datepicker__month-year-read-view:hover .react-datepicker__month-read-view--down-arrow { - border-top-color: #b3b3b3; - } - .react-datepicker__year-read-view--down-arrow, - .react-datepicker__month-read-view--down-arrow, - .react-datepicker__month-year-read-view--down-arrow { - transform: rotate(135deg); - right: -16px; - top: 0; - } - - .react-datepicker__year-dropdown, - .react-datepicker__month-dropdown, - .react-datepicker__month-year-dropdown { - background-color: #f0f0f0; - position: absolute; - width: 50%; - left: 25%; - top: 30px; - z-index: 1; - text-align: center; - border-radius: 0.3rem; - border: 1px solid #aeaeae; - } - .react-datepicker__year-dropdown:hover, - .react-datepicker__month-dropdown:hover, - .react-datepicker__month-year-dropdown:hover { - cursor: pointer; - } - .react-datepicker__year-dropdown--scrollable, - .react-datepicker__month-dropdown--scrollable, - .react-datepicker__month-year-dropdown--scrollable { - height: 150px; - overflow-y: scroll; - } - - .react-datepicker__year-option, - .react-datepicker__month-option, - .react-datepicker__month-year-option { - line-height: 20px; - width: 100%; - display: block; - margin-left: auto; - margin-right: auto; - } - .react-datepicker__year-option:first-of-type, - .react-datepicker__month-option:first-of-type, - .react-datepicker__month-year-option:first-of-type { - border-top-left-radius: 0.3rem; - border-top-right-radius: 0.3rem; - } - .react-datepicker__year-option:last-of-type, - .react-datepicker__month-option:last-of-type, - .react-datepicker__month-year-option:last-of-type { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - border-bottom-left-radius: 0.3rem; - border-bottom-right-radius: 0.3rem; - } - .react-datepicker__year-option:hover, - .react-datepicker__month-option:hover, - .react-datepicker__month-year-option:hover { - background-color: #ccc; - } - .react-datepicker__year-option:hover .react-datepicker__navigation--years-upcoming, - .react-datepicker__month-option:hover .react-datepicker__navigation--years-upcoming, - .react-datepicker__month-year-option:hover .react-datepicker__navigation--years-upcoming { - border-bottom-color: #b3b3b3; - } - .react-datepicker__year-option:hover .react-datepicker__navigation--years-previous, - .react-datepicker__month-option:hover .react-datepicker__navigation--years-previous, - .react-datepicker__month-year-option:hover .react-datepicker__navigation--years-previous { - border-top-color: #b3b3b3; - } - .react-datepicker__year-option--selected, - .react-datepicker__month-option--selected, - .react-datepicker__month-year-option--selected { - position: absolute; - left: 15px; - } - - .react-datepicker__close-icon { - cursor: pointer; - background-color: transparent; - border: 0; - outline: 0; - padding: 0 6px 0 0; - position: absolute; - top: 0; - right: 0; - height: 100%; - display: table-cell; - vertical-align: middle; - } - .react-datepicker__close-icon::after { - cursor: pointer; - background-color: #216ba5; - color: #fff; - border-radius: 50%; - height: 16px; - width: 16px; - padding: 2px; - font-size: 12px; - line-height: 1; - text-align: center; - display: table-cell; - vertical-align: middle; - content: '×'; - } - .react-datepicker__close-icon--disabled { - cursor: default; - } - .react-datepicker__close-icon--disabled::after { - cursor: default; - background-color: #ccc; - } - - .react-datepicker__today-button { - background: #f0f0f0; - border-top: 1px solid #aeaeae; - cursor: pointer; - text-align: center; - font-weight: bold; - padding: 5px 0; - clear: left; - } - - .react-datepicker__portal { - position: fixed; - width: 100vw; - height: 100vh; - background-color: rgba(0, 0, 0, 0.8); - left: 0; - top: 0; - justify-content: center; - align-items: center; - display: flex; - z-index: 2147483647; - } - .react-datepicker__portal .react-datepicker__day-name, - .react-datepicker__portal .react-datepicker__day, - .react-datepicker__portal .react-datepicker__time-name { - width: 3rem; - line-height: 3rem; - } - @media (max-width: 400px), (max-height: 550px) { - .react-datepicker__portal .react-datepicker__day-name, - .react-datepicker__portal .react-datepicker__day, - .react-datepicker__portal .react-datepicker__time-name { - width: 2rem; - line-height: 2rem; - } - } - .react-datepicker__portal .react-datepicker__current-month, - .react-datepicker__portal .react-datepicker-time__header { - font-size: 1.44rem; - } - - .react-datepicker__children-container { - width: 13.8rem; - margin: 0.4rem; - padding-right: 0.2rem; - padding-left: 0.2rem; - height: auto; - } - - .react-datepicker__aria-live { - position: absolute; - clip-path: circle(0); - border: 0; - height: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - width: 1px; - white-space: nowrap; - } - - .react-datepicker__calendar-icon { - width: 1em; - height: 1em; - vertical-align: -0.125em; - } -} diff --git a/packages/ui/src/fields/DateTime/index.css b/packages/ui/src/fields/DateTime/index.css index 708313231a1..8bcae245c5a 100644 --- a/packages/ui/src/fields/DateTime/index.css +++ b/packages/ui/src/fields/DateTime/index.css @@ -1,7 +1,5 @@ @layer payload-default { - .date-time-field--has-error { - .react-datepicker__input-container input { - border-color: var(--border-danger-strong); - } + .date-time-field--has-error .date-time-picker .react-datepicker__input-container input { + border-color: var(--border-danger-strong); } } diff --git a/packages/ui/src/icons/Calendar/index.tsx b/packages/ui/src/icons/Calendar/index.tsx index f4284159189..34f64424908 100644 --- a/packages/ui/src/icons/Calendar/index.tsx +++ b/packages/ui/src/icons/Calendar/index.tsx @@ -3,7 +3,12 @@ import React from 'react' import './index.scss' export const CalendarIcon: React.FC = () => ( - + { await expect(page.locator('.doc-header__title.render-title')).toContainText('February') }) - test('should clear date', async () => { - await page.goto(url.create) - const dateField = page.locator('#field-default input') - await expect(dateField).toBeVisible() - await dateField.fill('02/07/2023') - await expect(dateField).toHaveValue('02/07/2023') - - // Fill in remaining required fields, this is just to make sure saving is possible - const dateWithTz = page.locator('#field-dayAndTimeWithTimezone .react-datepicker-wrapper input') - - await dateWithTz.fill('08/12/2027 10:00 AM') - - const dropdownControlSelector = `#field-dayAndTimeWithTimezone .rs__control` - - const timezoneOptionSelector = `#field-dayAndTimeWithTimezone .rs__menu .rs__option:has-text("London")` - await page.click(dropdownControlSelector) - await page.click(timezoneOptionSelector) - - await saveDocAndAssert(page) - - const clearButton = page.locator('#field-default .date-time-picker__clear-button') - await expect(clearButton).toBeVisible() - await clearButton.click() - await expect(dateField).toHaveValue('') - }) - test('should clear miliseconds from dates with time', async () => { await page.goto(url.create) const dateField = page.locator('#field-default input') diff --git a/test/v4/collections/Date/index.ts b/test/v4/collections/Date/index.ts index 0375fe0e776..f6a4505f495 100644 --- a/test/v4/collections/Date/index.ts +++ b/test/v4/collections/Date/index.ts @@ -8,12 +8,34 @@ const DateFields: CollectionConfig = { { name: 'default', type: 'date', - label: 'Date', + }, + { + name: 'required', + type: 'date', + required: true, + admin: { + description: 'Select a date from the calendar', + }, + }, + { + name: 'disabled', + type: 'date', + admin: { + disabled: true, + }, + defaultValue: '2026-01-15T12:00:00.000Z', + }, + { + name: 'readOnly', + type: 'date', + admin: { + readOnly: true, + }, + defaultValue: '2026-01-15T12:00:00.000Z', }, { name: 'dayOnly', type: 'date', - label: 'Date', admin: { date: { pickerAppearance: 'dayOnly', @@ -23,7 +45,6 @@ const DateFields: CollectionConfig = { { name: 'timeOnly', type: 'date', - label: 'Time', admin: { date: { pickerAppearance: 'timeOnly', @@ -33,13 +54,21 @@ const DateFields: CollectionConfig = { { name: 'dayAndTime', type: 'date', - label: 'Date & Time', admin: { date: { pickerAppearance: 'dayAndTime', }, }, }, + { + name: 'monthOnly', + type: 'date', + admin: { + date: { + pickerAppearance: 'monthOnly', + }, + }, + }, ], } diff --git a/test/v4/payload-types.ts b/test/v4/payload-types.ts index 87e555a8d13..a7155e8c387 100644 --- a/test/v4/payload-types.ts +++ b/test/v4/payload-types.ts @@ -262,7 +262,7 @@ export interface CodeField { /** * Write JavaScript code */ - javascript?: string | null; + javascript: string; /** * Write HTML markup */ @@ -275,6 +275,14 @@ export interface CodeField { * Write TypeScript code */ typescript?: string | null; + /** + * This field is read only + */ + readOnly?: string | null; + /** + * This field is disabled + */ + disabled?: string | null; updatedAt: string; createdAt: string; } @@ -296,9 +304,16 @@ export interface CollapsibleField { export interface DateField { id: string; default?: string | null; + /** + * Select a date from the calendar + */ + required: string; + disabled?: string | null; + readOnly?: string | null; dayOnly?: string | null; timeOnly?: string | null; dayAndTime?: string | null; + monthOnly?: string | null; updatedAt: string; createdAt: string; } @@ -361,7 +376,7 @@ export interface JsonField { | boolean | null; /** - * Enter valid JSON data + * This field is required */ jsonRequired: | { @@ -372,6 +387,30 @@ export interface JsonField { | number | boolean | null; + /** + * This field is read only + */ + jsonReadOnly?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + /** + * This field is disabled + */ + jsonDisabled?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; updatedAt: string; createdAt: string; } @@ -877,6 +916,8 @@ export interface CodeFieldsSelect { html?: T; css?: T; typescript?: T; + readOnly?: T; + disabled?: T; updatedAt?: T; createdAt?: T; } @@ -896,9 +937,13 @@ export interface CollapsibleFieldsSelect { */ export interface DateFieldsSelect { default?: T; + required?: T; + disabled?: T; + readOnly?: T; dayOnly?: T; timeOnly?: T; dayAndTime?: T; + monthOnly?: T; updatedAt?: T; createdAt?: T; } @@ -939,6 +984,8 @@ export interface GroupFieldsSelect { export interface JsonFieldsSelect { json?: T; jsonRequired?: T; + jsonReadOnly?: T; + jsonDisabled?: T; updatedAt?: T; createdAt?: T; }