Merged in fix(SW-1796)-issues-with-datepicker (pull request #1631)
Fix(SW-1796) issues with datepicker * feat(SW-1796) Refactor DatePicker for Range * feat(SW-1796) cleanup * feat(SW-1796) added const for dateClicked and now Approved-by: Michael Zetterberg Approved-by: Niclas Edenvin
This commit is contained in:
@@ -24,7 +24,7 @@ export default function DatePickerRangeDesktop({
|
|||||||
close,
|
close,
|
||||||
handleOnSelect,
|
handleOnSelect,
|
||||||
locales,
|
locales,
|
||||||
selectedDate,
|
selectedRange,
|
||||||
}: DatePickerRangeProps) {
|
}: DatePickerRangeProps) {
|
||||||
const lang = useLang()
|
const lang = useLang()
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
@@ -79,10 +79,10 @@ export default function DatePickerRangeDesktop({
|
|||||||
mode="range"
|
mode="range"
|
||||||
month={month}
|
month={month}
|
||||||
numberOfMonths={2}
|
numberOfMonths={2}
|
||||||
onDayClick={handleOnSelect}
|
onSelect={handleOnSelect}
|
||||||
onMonthChange={handleMonthChange}
|
onMonthChange={handleMonthChange}
|
||||||
required={false}
|
required={false}
|
||||||
selected={selectedDate}
|
selected={selectedRange}
|
||||||
startMonth={currentDate}
|
startMonth={currentDate}
|
||||||
endMonth={endDate}
|
endMonth={endDate}
|
||||||
weekStartsOn={1}
|
weekStartsOn={1}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export default function DatePickerRangeMobile({
|
|||||||
close,
|
close,
|
||||||
handleOnSelect,
|
handleOnSelect,
|
||||||
locales,
|
locales,
|
||||||
selectedDate,
|
selectedRange,
|
||||||
}: DatePickerRangeProps) {
|
}: DatePickerRangeProps) {
|
||||||
const lang = useLang()
|
const lang = useLang()
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
@@ -75,9 +75,9 @@ export default function DatePickerRangeMobile({
|
|||||||
mode="range"
|
mode="range"
|
||||||
/** Showing full year or what's left of it */
|
/** Showing full year or what's left of it */
|
||||||
numberOfMonths={13}
|
numberOfMonths={13}
|
||||||
onDayClick={handleOnSelect}
|
onSelect={handleOnSelect}
|
||||||
required
|
required
|
||||||
selected={selectedDate}
|
selected={selectedRange}
|
||||||
startMonth={currentDate}
|
startMonth={currentDate}
|
||||||
weekStartsOn={1}
|
weekStartsOn={1}
|
||||||
components={{
|
components={{
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import DatePickerRangeMobile from "./Range/Mobile"
|
|||||||
|
|
||||||
import styles from "./date-picker.module.css"
|
import styles from "./date-picker.module.css"
|
||||||
|
|
||||||
|
import type { DateRange } from "react-day-picker"
|
||||||
|
|
||||||
import type { DatePickerFormProps } from "@/types/components/datepicker"
|
import type { DatePickerFormProps } from "@/types/components/datepicker"
|
||||||
|
|
||||||
const locales = {
|
const locales = {
|
||||||
@@ -35,16 +37,12 @@ export default function DatePickerForm({ name = "date" }: DatePickerFormProps) {
|
|||||||
const { register, setValue } = useFormContext()
|
const { register, setValue } = useFormContext()
|
||||||
const ref = useRef<HTMLDivElement | null>(null)
|
const ref = useRef<HTMLDivElement | null>(null)
|
||||||
|
|
||||||
const [isSelectingFrom, setIsSelectingFrom] = useState(true)
|
|
||||||
|
|
||||||
const close = useCallback(() => {
|
const close = useCallback(() => {
|
||||||
if (!selectedDate.toDate) {
|
if (!selectedDate.toDate) {
|
||||||
setValue(name, {
|
setValue(name, {
|
||||||
fromDate: selectedDate.fromDate,
|
fromDate: selectedDate.fromDate,
|
||||||
toDate: dt(selectedDate.fromDate).add(1, "day").format("YYYY-MM-DD"),
|
toDate: dt(selectedDate.fromDate).add(1, "day").format("YYYY-MM-DD"),
|
||||||
})
|
})
|
||||||
|
|
||||||
setIsSelectingFrom(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsOpen(false)
|
setIsOpen(false)
|
||||||
@@ -54,34 +52,46 @@ export default function DatePickerForm({ name = "date" }: DatePickerFormProps) {
|
|||||||
setIsOpen(true)
|
setIsOpen(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSelectDate(selected: Date) {
|
function handleSelectDate(
|
||||||
|
_nextRange: DateRange | undefined,
|
||||||
|
selectedDay: Date
|
||||||
|
) {
|
||||||
|
const now = dt()
|
||||||
|
const dateClicked = dt(selectedDay)
|
||||||
|
const dateClickedFormatted = dateClicked.format("YYYY-MM-DD")
|
||||||
/* check if selected date is not before todays date,
|
/* check if selected date is not before todays date,
|
||||||
which happens when "Enter" key is pressed in any other input field of the form */
|
which happens when "Enter" key is pressed in any other input field of the form */
|
||||||
if (!dt(selected).isBefore(dt(), "day")) {
|
if (!dateClicked.isBefore(now, "day")) {
|
||||||
if (isSelectingFrom) {
|
// Handle form value updates based on the requirements
|
||||||
|
if (selectedDate.fromDate && selectedDate.toDate) {
|
||||||
|
// Both dates were previously selected, starting fresh with new date
|
||||||
setValue(name, {
|
setValue(name, {
|
||||||
fromDate: dt(selected).format("YYYY-MM-DD"),
|
fromDate: dateClickedFormatted,
|
||||||
toDate: undefined,
|
toDate: undefined,
|
||||||
})
|
})
|
||||||
setIsSelectingFrom(false)
|
} else if (selectedDate.fromDate && !selectedDate.toDate) {
|
||||||
} else if (!dt(selectedDate.fromDate).isSame(dt(selected))) {
|
// If the selected day is the same as the first date, we don't need to update the form value
|
||||||
const fromDate = dt(selectedDate.fromDate)
|
if (dateClicked.isSame(selectedDate.fromDate)) {
|
||||||
const toDate = dt(selected)
|
return
|
||||||
if (toDate.isAfter(fromDate)) {
|
}
|
||||||
|
// We're selecting the second date
|
||||||
|
if (dateClicked.isBefore(selectedDate.fromDate)) {
|
||||||
|
// If second selected date is before first date, swap them
|
||||||
setValue(name, {
|
setValue(name, {
|
||||||
fromDate: selectedDate.fromDate,
|
fromDate: dateClickedFormatted,
|
||||||
toDate: toDate.format("YYYY-MM-DD"),
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
setValue(name, {
|
|
||||||
fromDate: toDate.format("YYYY-MM-DD"),
|
|
||||||
toDate: selectedDate.fromDate,
|
toDate: selectedDate.fromDate,
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
// If second selected date is after first date, keep order
|
||||||
|
setValue(name, {
|
||||||
|
fromDate: selectedDate.fromDate,
|
||||||
|
toDate: dateClickedFormatted,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
setIsSelectingFrom(true)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const closeIfOutside = useCallback(
|
const closeIfOutside = useCallback(
|
||||||
(target: HTMLElement) => {
|
(target: HTMLElement) => {
|
||||||
if (ref.current && target && !ref.current.contains(target)) {
|
if (ref.current && target && !ref.current.contains(target)) {
|
||||||
@@ -153,9 +163,11 @@ export default function DatePickerForm({ name = "date" }: DatePickerFormProps) {
|
|||||||
handleOnSelect={handleSelectDate}
|
handleOnSelect={handleSelectDate}
|
||||||
locales={locales}
|
locales={locales}
|
||||||
// DayPicker lib needs Daterange in form as below to show appropriate UI
|
// DayPicker lib needs Daterange in form as below to show appropriate UI
|
||||||
selectedDate={{
|
selectedRange={{
|
||||||
from: selectedDate.fromDate,
|
from: dt(selectedDate.fromDate).toDate(),
|
||||||
to: selectedDate.toDate,
|
to: selectedDate.toDate
|
||||||
|
? dt(selectedDate.toDate).toDate()
|
||||||
|
: undefined,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<DatePickerRangeMobile
|
<DatePickerRangeMobile
|
||||||
@@ -163,9 +175,11 @@ export default function DatePickerForm({ name = "date" }: DatePickerFormProps) {
|
|||||||
handleOnSelect={handleSelectDate}
|
handleOnSelect={handleSelectDate}
|
||||||
locales={locales}
|
locales={locales}
|
||||||
// DayPicker lib needs Daterange in form as below to show appropriate UI
|
// DayPicker lib needs Daterange in form as below to show appropriate UI
|
||||||
selectedDate={{
|
selectedRange={{
|
||||||
from: selectedDate.fromDate,
|
from: dt(selectedDate.fromDate).toDate(),
|
||||||
to: selectedDate.toDate,
|
to: selectedDate.toDate
|
||||||
|
? dt(selectedDate.toDate).toDate()
|
||||||
|
: undefined,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,17 +11,17 @@ type LangWithoutEn = Lang.da | Lang.de | Lang.fi | Lang.no | Lang.sv
|
|||||||
|
|
||||||
interface DatePickerProps {
|
interface DatePickerProps {
|
||||||
close: () => void
|
close: () => void
|
||||||
handleOnSelect: (selected: Date) => void
|
|
||||||
locales: Record<LangWithoutEn, Locale>
|
locales: Record<LangWithoutEn, Locale>
|
||||||
selectedDate: DateRange | Date
|
|
||||||
startMonth?: Date
|
startMonth?: Date
|
||||||
hideHeader?: boolean
|
hideHeader?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DatePickerRangeProps extends DatePickerProps {
|
export interface DatePickerRangeProps extends DatePickerProps {
|
||||||
selectedDate: DateRange
|
selectedRange: DateRange | undefined
|
||||||
|
handleOnSelect: (nextRange: DateRange | undefined, selectedDay: Date) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DatePickerSingleProps extends DatePickerProps {
|
export interface DatePickerSingleProps extends DatePickerProps {
|
||||||
selectedDate: Date
|
selectedDate: Date
|
||||||
|
handleOnSelect: (selected: Date) => void
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user