Merged in feat/SW-1509-new-select-usage-in-forms (pull request #1787)

feat(SW-1509): simplified date of birth component to work with new select

Approved-by: Chuma Mcphoy (We Ahead)
This commit is contained in:
Christian Andolf
2025-04-15 14:18:04 +00:00
4 changed files with 87 additions and 130 deletions

View File

@@ -1,35 +1,15 @@
.container {
display: grid;
display: flex;
gap: var(--Spacing-x2);
grid-template-areas: "year month day";
grid-template-columns: 1fr 1fr 1fr;
width: var(--width);
user-select: none;
}
@media (max-width: 350px) {
@media screen and (width < 400px) {
.container {
display: flex;
flex-direction: column;
}
}
.day {
grid-area: day;
}
.month {
grid-area: month;
}
.year {
grid-area: year;
}
/* TODO: Handle this in Select component.
- out of scope for now.
*/
.day.invalid > div > div,
.month.invalid > div > div,
.year.invalid > div > div {
border-color: var(--Scandic-Red-60);
.segment {
flex: 1;
}

View File

@@ -1,13 +1,13 @@
"use client"
import { parseDate } from "@internationalized/date"
import { useEffect } from "react"
import { DateInput, DatePicker, Group, type Key } from "react-aria-components"
import { useController, useFormContext, useWatch } from "react-hook-form"
import { useIntl } from "react-intl"
import { Select } from "@scandic-hotels/design-system/Select"
import { dt } from "@/lib/dt"
import Select from "@/components/TempDesignSystem/Select"
import useLang from "@/hooks/useLang"
import { getLocalizedMonthName } from "@/utils/dateFormatting"
import { rangeArray } from "@/utils/rangeArray"
@@ -22,13 +22,13 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
const lang = useLang()
const { control, setValue, formState, watch } = useFormContext()
const { field, fieldState } = useController({
const { field } = useController({
control,
name,
rules: registerOptions,
})
const currentDateValue = useWatch({ name })
const currentDateValue: string = useWatch({ name })
const year = watch(DateName.year)
const month = watch(DateName.month)
const day = watch(DateName.day)
@@ -61,16 +61,6 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
label: `${day}`,
}))
const dayLabel = intl.formatMessage({
defaultMessage: "Day",
})
const monthLabel = intl.formatMessage({
defaultMessage: "Month",
})
const yearLabel = intl.formatMessage({
defaultMessage: "Year",
})
useEffect(() => {
if (formState.isSubmitting) return
@@ -125,87 +115,50 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
}, [setValue, formState.isSubmitting, dateValue, day, month, year])
return (
<DatePicker
aria-label={intl.formatMessage({
defaultMessage: "Select date of birth",
})}
isRequired={!!registerOptions.required}
isInvalid={!formState.isValid}
name={name}
ref={field.ref}
value={dateValue}
data-testid={name}
>
<Group>
<DateInput className={styles.container}>
{(segment) => {
switch (segment.type) {
case "day":
return (
<div
className={`${styles.day} ${fieldState.invalid ? styles.invalid : ""}`}
>
<Select
aria-label={dayLabel}
items={days}
label={dayLabel}
name={DateName.day}
onSelect={(key: Key) =>
setValue(DateName.day, Number(key))
}
required
tabIndex={3}
value={segment.isPlaceholder ? undefined : segment.value}
/>
</div>
)
case "month":
return (
<div
className={`${styles.month} ${fieldState.invalid ? styles.invalid : ""}`}
>
<Select
aria-label={monthLabel}
items={months}
label={monthLabel}
name={DateName.month}
onSelect={(key: Key) =>
setValue(DateName.month, Number(key))
}
required
tabIndex={2}
value={segment.isPlaceholder ? undefined : segment.value}
/>
</div>
)
case "year":
return (
<div
className={`${styles.year} ${fieldState.invalid ? styles.invalid : ""}`}
>
<Select
aria-label={yearLabel}
items={years}
label={yearLabel}
name={DateName.year}
onSelect={(key: Key) =>
setValue(DateName.year, Number(key))
}
required
tabIndex={1}
value={segment.isPlaceholder ? undefined : segment.value}
/>
</div>
)
default:
/** DateInput forces return of ReactElement */
return <></>
}
}}
</DateInput>
</Group>
<>
<div className={styles.container}>
<div className={styles.segment}>
<Select
items={days}
label={intl.formatMessage({
defaultMessage: "Day",
})}
name={DateName.day}
onSelectionChange={(key) => setValue(DateName.day, Number(key))}
isRequired
enableFiltering
defaultSelectedKey={dateValue?.day}
/>
</div>
<div className={styles.segment}>
<Select
items={months}
label={intl.formatMessage({
defaultMessage: "Month",
})}
name={DateName.month}
onSelectionChange={(key) => setValue(DateName.month, Number(key))}
isRequired
enableFiltering
defaultSelectedKey={dateValue?.month}
/>
</div>
<div className={styles.segment}>
<Select
items={years}
label={intl.formatMessage({
defaultMessage: "Year",
})}
name={DateName.year}
onSelectionChange={(key) => setValue(DateName.year, Number(key))}
isRequired
enableFiltering
defaultSelectedKey={dateValue?.year}
/>
</div>
</div>
<ErrorMessage errors={formState.errors} name={field.name} />
</DatePicker>
</>
)
}