Quellcode durchsuchen

Feature: Date Time Picker date-range system added.

lfabl vor 4 Wochen
Ursprung
Commit
bc4dfa30f3

+ 1 - 1
example/src/pages/home/index.tsx

@@ -371,7 +371,7 @@ const Home = () => {
             maxDate={moment().add(1, "months").toDate()}
             isWorkWithRealtime={false}
             isCleanEnabled={true}
-            variant="single"
+            variant="range"
             initialDateRange={{
                 start: moment().subtract(2, "days").startOf("day").toDate(),
                 end: moment().add(6, "days").endOf("day").toDate()

+ 81 - 37
src/components/dateSelector/index.tsx

@@ -4,11 +4,13 @@ import {
     forwardRef,
     useEffect,
     useState,
-    type Ref
+    type Ref,
+    useRef
 } from "react";
 import {
     TouchableOpacity,
-    View
+    View,
+    type ViewStyle
 } from "react-native";
 import type {
     CalendarDay,
@@ -24,6 +26,9 @@ import {
 import {
     NCoreUIKitTheme
 } from "../../core/hooks";
+import type {
+    Mutable
+} from "../../types";
 import {
     ChevronRight as ChevronRightIcon,
     ChevronLeft as ChevronLeftIcon
@@ -37,6 +42,7 @@ const DateSelector = ({
     dayOfWeekLength = "long",
     viewDate: viewDateProp,
     setIsSheetContentReady,
+    selectMultipleObject,
     selectObject,
     dateRange,
     dateRule,
@@ -69,6 +75,8 @@ const DateSelector = ({
         setMonthDays
     ] = useState<Array<CalendarDay>>([]);
 
+    const allSelectedDays = useRef<Array<Date>>([]);
+
     const {
         nextPrevToolChevronButton: nextPrevToolChevronButtonDynamicStyle,
         nextPrevToolContainer: nextPrevToolContainerDynamicStyle,
@@ -122,6 +130,8 @@ const DateSelector = ({
     }: {
         tDate: Date
     }): Array<CalendarDay> => {
+        allSelectedDays.current = [];
+
         const targetDate = moment(new Date(tDate));
 
         const startOfCalendar = targetDate.clone().startOf("month").startOf("week");
@@ -137,9 +147,23 @@ const DateSelector = ({
             let isSelected = false;
 
             if(variant === "single" && date) {
+                allSelectedDays.current = [date];
+
                 if(moment(currentDay).isSame(date, "day")) isSelected = true;
             } else if(variant === "range" && dateRange && dateRange.start) {
-                if(moment(currentDay).isBetween(dateRange.start, dateRange.end, "day", "[]")) isSelected = true;
+                if(dateRange.end) {
+                    allSelectedDays.current = Array.from({
+                        length: moment(dateRange.end).diff(dateRange.start, "days") + 1
+                    }, (_, i) =>
+                        moment(dateRange.start).clone().add(i, "days").toDate()
+                    );
+
+                    if(moment(currentDay).isBetween(dateRange.start, dateRange.end, "day", "[]")) isSelected = true;
+                } else if(moment(currentDay).isSame(dateRange.start)) {
+                    allSelectedDays.current = [dateRange.start];
+
+                    isSelected = true;
+                }
             }
 
             let isDisabled = false;
@@ -153,6 +177,7 @@ const DateSelector = ({
             }
 
             return {
+                originalIndex: allSelectedDays.current.findIndex((day) => moment(currentDay).isSame(day, "day")),
                 isCurrentMonth: currentDay.isSame(targetDate, "month"),
                 isToday: currentDay.isSame(moment(), "day"),
                 dayOfWeek: currentDay.weekday(),
@@ -163,56 +188,43 @@ const DateSelector = ({
             };
         });
 
-        const weeks: CalendarDay[][] = [];
-
-        allDays.forEach((day, index) => {
-            const weekIndex = Math.floor(index / 7);
-            if (!weeks[weekIndex]) {
-                weeks[weekIndex] = [];
-            }
-            weeks[weekIndex].push(day);
-        });
-
         return allDays;
     };
 
     const renderDay = ({
         weekIndex,
-        nextItem,
-        prevItem,
         dayIndex,
         dayItem
     }: {
-        nextItem?: CalendarDay;
-        prevItem?: CalendarDay;
         dayItem: CalendarDay;
         weekIndex: number;
         dayIndex: number;
     }) => {
-        const isNextItemSelected = nextItem && nextItem.isSelected && dayItem.isSelected;
-        const isPrevItemSelected = prevItem && prevItem.isSelected && dayItem.isSelected;
+        const isLastItemSelected = dayItem.isSelected && dayItem.originalIndex === allSelectedDays.current.length - 1;
+        const isFirstItemSelected = dayItem.isSelected && dayItem.originalIndex === 0;
 
-        const selectionStyle = [
-            isNextItemSelected ? {
+        const selectionStyle: Array<Mutable<ViewStyle> | null> = [
+            isFirstItemSelected && allSelectedDays.current.length > 1 ? {
                 borderBottomRightRadius: 0,
                 borderTopRightRadius: 0
             } : null,
-            isPrevItemSelected ? {
+            isLastItemSelected && allSelectedDays.current.length > 1 ? {
                 borderBottomLeftRadius: 0,
                 borderTopLeftRadius: 0
-            } : null,
-            isNextItemSelected && isPrevItemSelected ? {
-                borderBottomRightRadius: 0,
-                borderBottomLeftRadius: 0,
-                borderTopRightRadius: 0,
-                borderTopLeftRadius: 0
             } : null
         ];
 
         let dayTitleColor: keyof NCoreUIKit.TextContentColors = "mid";
 
-        if(isPrevItemSelected && isNextItemSelected) {
+        if(dayItem.isSelected && !isLastItemSelected && !isFirstItemSelected) {
             dayTitleColor = "emphasized";
+
+            selectionStyle.push({
+                borderBottomRightRadius: 0,
+                borderBottomLeftRadius: 0,
+                borderTopRightRadius: 0,
+                borderTopLeftRadius: 0
+            });
         } else if(dayItem.isSelected) {
             dayTitleColor = "onPrimary";
         }
@@ -232,7 +244,41 @@ const DateSelector = ({
                 if(variant === "single") {
                     selectObject(dayItem.date.toDate());
                 } else if(variant === "range") {
-                    console.log("range");
+                    if(!dateRange || !dateRange.start) {
+                        selectMultipleObject({
+                            start: new Date(dayItem.date.toDate().setHours(0, 0, 0)),
+                            end: undefined
+                        });
+                        return;
+                    }
+
+                    if(dateRange && moment(dateRange.start).isSame(dayItem.date, "day")) {
+                        selectMultipleObject({
+                            start: undefined,
+                            end: undefined
+                        });
+                        return;
+                    }
+
+                    if(dateRange && !dateRange.end) {
+                        if(moment(dayItem.date).isBefore(dateRange.start)) {
+                            selectMultipleObject({
+                                start: new Date(dayItem.date.toDate().setHours(0, 0, 0)),
+                                end: undefined
+                            });
+                        } else {
+                            selectMultipleObject({
+                                end: new Date(dayItem.date.toDate().setHours(23, 59, 59)),
+                                start: dateRange?.start
+                            });
+                        }
+                        return;
+                    }
+
+                    selectMultipleObject({
+                        start: dayItem.date.toDate(),
+                        end: undefined
+                    });
                 } else {
                     console.log("rrule");
                 }
@@ -244,10 +290,13 @@ const DateSelector = ({
                     backgroundColor: colors.content.container.primary,
                     borderColor: colors.content.container.primary
                 } : null,
-                isNextItemSelected && isPrevItemSelected ? {
+                dayItem.isSelected && !isLastItemSelected && !isFirstItemSelected ? {
                     backgroundColor: colors.content.container.emphasized,
                     borderColor: colors.content.container.emphasized
                 } : null,
+                dayItem.isSelected && (dayItem.isDisabled || !dayItem.isCurrentMonth) ? {
+                    opacity: 0.33
+                } : null,
                 ...selectionStyle
             ]}
         >
@@ -336,10 +385,7 @@ const DateSelector = ({
             ]}
         >
             {weekDays.map((weekItem, weekIndex) => {
-                const days = monthDays.map((day, dayI) => ({
-                    ...day,
-                    originalIndex: dayI
-                })).filter((dayItem) => dayItem.dayOfWeek === weekIndex);
+                const days = monthDays.filter((dayItem) => dayItem.dayOfWeek === weekIndex);
 
                 return <View
                     key={`day-column-${weekIndex}`}
@@ -358,8 +404,6 @@ const DateSelector = ({
                     </Text>
                     {days.map((dayItem, dayIndex) => {
                         return renderDay({
-                            nextItem: monthDays[dayItem.originalIndex + 1] ?? undefined,
-                            prevItem: monthDays[dayItem.originalIndex - 1] ?? undefined,
                             weekIndex,
                             dayIndex,
                             dayItem

+ 3 - 2
src/components/dateSelector/type.ts

@@ -24,6 +24,7 @@ export type DateSelectorDynamicStyle = {
 
 export interface CalendarDay {
     isCurrentMonth: boolean;
+    originalIndex: number;
     isDisabled: boolean;
     isSelected: boolean;
     date: moment.Moment;
@@ -42,9 +43,9 @@ export type DateSelectInitialGeneratorType = {
 export type DayOfWeekLengthType = "short" | "very-short" | "long";
 
 interface IDateSelectorProps {
-    selectMultipleObject?: (dateRange?: DateTimePickerDateRange) => void;
+    selectMultipleObject: (dateRange?: DateTimePickerDateRange) => void;
     setIsSheetContentReady: Dispatch<SetStateAction<boolean>>;
-    selectDateRule?: (dateRule: RRule) => void;
+    selectDateRule: (dateRule: RRule) => void;
     dayOfWeekLength?: DayOfWeekLengthType;
     selectObject: (date?: Date) => void;
     localeBasedFirstDayOfWeek?: boolean;

+ 20 - 22
src/components/dateTimePicker/index.tsx

@@ -75,9 +75,7 @@ const DateTimePicker = ({
     isWorkWithRealtime = true,
     dayOfWeekLength = "short",
     customDateTimeSheetTheme,
-    isMultipleSelect = false,
     pickerType = "date-time",
-    isWorkWithRRule = false,
     icon: IconComponentProp,
     hintTextContainerStyle,
     removeSelectValidation,
@@ -370,7 +368,7 @@ const DateTimePicker = ({
     };
 
     const selectDateRule = (selectedDateRule?: RRule) => {
-        if(isWorkWithRRule) {
+        if(variant === "rrule") {
             if(selectedDateRule && selectedDateRule !== dateRule) {
                 if(selectValidation) {
                     if(selectValidation({
@@ -409,7 +407,7 @@ const DateTimePicker = ({
         start?: Date;
         end?: Date;
     }) => {
-        if(!isWorkWithRRule && isMultipleSelect) {
+        if(variant === "range") {
             if(selectedDateRange) {
                 if(selectValidation) {
                     if(selectValidation({
@@ -457,7 +455,7 @@ const DateTimePicker = ({
     };
 
     const selectObject = (selectedDate?: Date) => {
-        if(!isWorkWithRRule && !isMultipleSelect) {
+        if(variant === "single") {
             if(selectedDate === date) {
                 if(removeSelectValidation) {
                     if(removeSelectValidation({
@@ -515,14 +513,12 @@ const DateTimePicker = ({
             return null;
         }
 
-        if(isWorkWithRRule) {
+        if(variant === "rrule") {
             if(!mainDateRule) return null;
+        } else if(variant === "range") {
+            if(!dateRange) return null;
         } else {
-            if(isMultipleSelect) {
-                if(!dateRange) return null;
-            } else {
-                if(!date) return null;
-            }
+            if(!date) return null;
         }
 
         return <TouchableOpacity
@@ -576,14 +572,12 @@ const DateTimePicker = ({
             return null;
         }
 
-        if(isWorkWithRRule) {
+        if(variant === "rrule") {
             if(!mainDateRule) return null;
+        } else if(variant === "range") {
+            if(!mainDateRange) return null;
         } else {
-            if(isMultipleSelect) {
-                if(!mainDateRange) return null;
-            } else {
-                if(!mainDate) return null;
-            }
+            if(!mainDate) return null;
         }
 
         return <View
@@ -721,6 +715,7 @@ const DateTimePicker = ({
         if(!date) {
             return <Text
                 variant="labelLargeSize"
+                numberOfLines={1}
                 style={[
                     stylesheet.contentText,
                     contentTextDynamicStyle
@@ -732,6 +727,7 @@ const DateTimePicker = ({
 
         return <Text
             variant="labelLargeSize"
+            numberOfLines={1}
             style={[
                 stylesheet.contentText,
                 contentTextDynamicStyle
@@ -745,6 +741,7 @@ const DateTimePicker = ({
         if(!dateRange) {
             return <Text
                 variant="labelLargeSize"
+                numberOfLines={1}
                 style={[
                     stylesheet.contentText,
                     contentTextDynamicStyle
@@ -760,6 +757,7 @@ const DateTimePicker = ({
 
         return <Text
             variant="labelLargeSize"
+            numberOfLines={1}
             style={[
                 stylesheet.contentText,
                 contentTextDynamicStyle
@@ -773,6 +771,7 @@ const DateTimePicker = ({
         if(!dateRule) {
             return <Text
                 variant="labelLargeSize"
+                numberOfLines={1}
                 style={[
                     stylesheet.contentText,
                     contentTextDynamicStyle
@@ -784,6 +783,7 @@ const DateTimePicker = ({
 
         return <Text
             variant="labelLargeSize"
+            numberOfLines={1}
             style={[
                 stylesheet.contentText,
                 contentTextDynamicStyle
@@ -794,11 +794,11 @@ const DateTimePicker = ({
     };
 
     const renderValue = () => {
-        if(isWorkWithRRule) {
+        if(variant === "rrule") {
             return renderDateRuleValue();
         }
 
-        if(isMultipleSelect) {
+        if(variant === "range") {
             return renderDateRangeValue();
         }
 
@@ -869,10 +869,8 @@ const DateTimePicker = ({
             isShowTodayIndicator={isShowTodayIndicator}
             isWorkWithRealtime={isWorkWithRealtime}
             customTheme={customDateTimeSheetTheme}
-            isMultipleSelect={isMultipleSelect}
             isShowTools={isShowDateTimeTools}
             dayOfWeekLength={dayOfWeekLength}
-            isWorkWithRRule={isWorkWithRRule}
             selectDateRule={selectDateRule}
             bottomSheetRef={bottomSheetRef}
             selectObject={selectObject}
@@ -884,11 +882,11 @@ const DateTimePicker = ({
                 isAutoHeight: true,
                 ...dateTimeSheetProps
             }}
+            dateRange={mainDateRange}
             pickerType={pickerType}
             maxChoice={maxChoice}
             minChoice={minChoice}
             isLoading={isLoading}
-            dateRange={dateRange}
             dateRule={dateRule}
             isActive={isActive}
             variant={variant}

+ 0 - 2
src/components/dateTimePicker/type.ts

@@ -157,11 +157,9 @@ interface IDateTimePickerProps {
     titleFormat?: ValidTitleFormat;
     isShowDateTimeTools?: boolean;
     isWorkWithRealtime?: boolean;
-    isMultipleSelect?: boolean;
     cleanIconStyle?: ViewStyle;
     rightIconStyle?: ViewStyle;
     rightIcon?: NCoreUIKitIcon;
-    isWorkWithRRule?: boolean;
     type?: DateTimePickerType;
     isShowSubTitle?: boolean;
     isCleanEnabled?: boolean;

+ 1 - 1
src/components/dateTimeSheet/index.tsx

@@ -145,7 +145,7 @@ const DateTimeSheet = ({
         >
             {!minChoice ? <CheckBox
                 isChecked={isAnySelected ? "checked" : null}
-                title={localize("clean-all")}
+                title={localize("clean-selection")}
                 spreadBehaviour="free"
                 onPress={() => {
                     clean();

+ 0 - 2
src/components/dateTimeSheet/type.ts

@@ -54,9 +54,7 @@ interface IDateTimeSheetProps {
     isShowTodayIndicator?: boolean;
     variant: DateTimePickerVariant;
     isWorkWithRealtime: boolean;
-    isMultipleSelect?: boolean;
     dateTimePickerKey: string;
-    isWorkWithRRule: boolean;
     bottomSheetProps?: Omit<
         IBottomSheetProps,
         "key" |

+ 6 - 0
src/variants/locales/default.json

@@ -3,10 +3,13 @@
         "locale": "tr-TR",
         "isRTL": false,
         "translations": {
+            "selected-end-date-cannot-before-from-start-date": "Seçilen başlangıç tarihi, bitiş tarihinden sonra olamaz.",
+            "selected-start-date-cannot-after-then-end-date": "Seçilen bitiş tarihi, başlangıç tarihinden önce olamaz.",
             "maximum-selection-limit-has-been-reached": "Maksimum seçim limitine ulaşıldı.",
             "minimum-a-item-selection-required": "Minimum 1 öğe seçimi gereklidir.",
             "selected-options-with-count": "{{0}} seçim yapıldı",
             "select-any-date": "Bir tarih seçin",
+            "clean-selection": "Seçimi Temizle",
             "select-an-option": "Seçim yapın",
             "clean-all": "Tümünü Temizle",
             "select-all": "Tümünü Seç",
@@ -89,10 +92,13 @@
         "locale": "en-US",
         "isRTL": false,
         "translations": {
+            "selected-end-date-cannot-before-from-start-date": "Selected end date cannot before from start date.",
+            "selected-start-date-cannot-after-then-end-date": "Selected start date cannot after then end date.",
             "maximum-selection-limit-has-been-reached": "Maximum selection limit has been reached.",
             "minimum-a-item-selection-required": "Minimum 1 item selection required.",
             "selected-options-with-count": "{{0}} items selected",
             "select-an-option": "Select an option",
+            "clean-selection": "Clean Selection",
             "select-any-date": "Select any date",
             "select-all": "Select All",
             "is-optional": "Optional",