akveo / react-native-ui-kitten

:boom: React Native UI Library based on Eva Design System :new_moon_with_face::sparkles:Dark Mode
https://akveo.github.io/react-native-ui-kitten/
MIT License
10.3k stars 952 forks source link

No example usage for render custom day in Official React Native UI Kitten Page #1757

Open danya0365 opened 1 year ago

danya0365 commented 1 year ago

💬 Question

I have already check this site React Native UI Kitten

Then scroll to section. To render custom cells, renderDay, renderMonth and renderYear properties may be used.

but the example code is wrong, the site show how to render renderArrowLeft or renderArrowRight.

Can you update and fix it.

UI Kitten and Eva version

Screen Shot 2566-06-24 at 15 46 52
Package Version
@eva-design/eva 2.2.0
@ui-kitten/components 5.3.1
danya0365 commented 1 year ago

The date value from onVisibleDateChange is incorrect timezone

this cause my isSameMonth is wrong i cant get correct of current visibleDate to calculate in my renderDay Component

import {
  Button,
  Calendar,
  Layout,
  StyleService,
  StyleType,
  Text,
  useStyleSheet,
} from "@ui-kitten/components";
import {
  CalendarDateInfo,
  CalendarViewModeId,
} from "@ui-kitten/components/ui/calendar/type";
import moment from "moment";
import { TouchableOpacity, View } from "react-native";
import { WorkBooking } from "../../../model/work-booking.model";
import { MomentDateService } from "@ui-kitten/moment";

const dateService = new MomentDateService();

const CalendarComponent = ({
  initialDate,
  confirmWorkBookings,
  getConfirmWorkBookings,
}: {
  initialDate: moment.Moment;
  confirmWorkBookings: WorkBooking[];
  getConfirmWorkBookings: (date: moment.Moment) => void;
}): React.ReactElement => {
  const styles = useStyleSheet(themedStyles);
  const [selectedDate, setSelectedDate] =
    React.useState<moment.Moment>(initialDate);
  const [visibleDate, setVisibleDate] = React.useState<moment.Moment>(moment());

  const componentRef = React.createRef<Calendar<moment.Moment>>();

  const scrollToSelected = (): void => {
    if (componentRef.current && selectedDate) {
      componentRef.current.scrollToDate(selectedDate);
    }
  };

  const scrollToToday = (): void => {
    if (componentRef.current) {
      componentRef.current.scrollToToday();
    }
  };

  const onSelectDay = (nextDate: moment.Moment) => {
    console.log("onSelectDay", nextDate);
    setSelectedDate(nextDate);
  };

  const renderDay = (
    info: CalendarDateInfo<moment.Moment>,
    style: StyleType
  ): React.ReactElement => {
    const { date } = info;
    const dayLabel = date.format("D");
    const isToday = moment().isSame(date, "day");
    const isSameMonth = date.isSame(visibleDate, "month");
    const isSelectedDate = moment(selectedDate).isSame(date, "day");
    const isConfirmBookings = confirmWorkBookings.filter((data) =>
      moment(data.bookingDate).isSame(date, "day")
    );

    const isConfirmBooking = (): boolean => {
      return isConfirmBookings.length > 0;
    };

    return (
      <TouchableOpacity
        onPress={() => {
          onSelectDay(date);
        }}
        style={[
          styles.dayContainer,
          {
            backgroundColor: isConfirmBooking()
              ? "#B63601"
              : style.backgroundColor,
            borderColor: isSelectedDate ? "#FFFFF" : "transparent",
          },
        ]}
      >
        {isSameMonth ? (
          <Text appearance="default" status={isToday ? "danger" : "basic"}>
            {dayLabel}
          </Text>
        ) : (
          <Text appearance="hint">{dayLabel}</Text>
        )}
        {isConfirmBooking() && <Text>*</Text>}
      </TouchableOpacity>
    );
  };

  const onVisibleDateChange = (
    date: moment.Moment,
    viewModeId: CalendarViewModeId
  ) => {
    const dateEndMonth = moment(date).endOf("month");
    console.log("onVisibleDateChange", dateEndMonth);

    setVisibleDate(dateEndMonth);
    getConfirmWorkBookings(date);
  };

  return (
    <Layout style={styles.container} level="2">
      <View style={styles.buttonContainer}>
        <Button onPress={scrollToToday}>ไปยังวันที่ปัจจุบัน</Button>
        <Button onPress={scrollToSelected}>ไปยังวันที่เลือก</Button>
      </View>
      <View style={styles.calendarContainer}>
        <Text category="h6" style={styles.text}>
          {`${moment(selectedDate).format("L")}`}
        </Text>
        <Calendar
          ref={componentRef}
          dateService={dateService}
          date={selectedDate}
          renderDay={renderDay}
          onSelect={onSelectDay}
          onVisibleDateChange={onVisibleDateChange}
        />
      </View>
    </Layout>
  );
};
export default memo(CalendarComponent);

const themedStyles = StyleService.create({
  dayContainer: {
    flex: 1,
    alignItems: "center",
    justifyContent: "flex-start",
    borderRadius: 8,
  },
  container: {
    flex: 1,
    margin: 2,
    paddingVertical: 4,
    paddingHorizontal: 4,
    flexDirection: "column",
    justifyContent: "space-between",
  },
  buttonContainer: {
    justifyContent: "space-between",
    flexDirection: "row",
    alignItems: "center",
    alignContent: "flex-start",
  },
  calendarContainer: {
    justifyContent: "space-between",
    flexDirection: "column",
    alignItems: "center",
    alignContent: "flex-start",
  },
  text: {
    marginVertical: 8,
  },
});
danya0365 commented 1 year ago

ok finally i can figure it out

import React, { memo } from "react";
import {
  Button,
  Calendar,
  Layout,
  StyleService,
  StyleType,
  Text,
  useStyleSheet,
  useTheme,
} from "@ui-kitten/components";
import {
  CalendarDateInfo,
  CalendarViewModeId,
} from "@ui-kitten/components/ui/calendar/type";
import moment from "moment";
import { StyleProp, View, ViewStyle } from "react-native";
import { WorkBooking } from "../../../model/work-booking.model";
import { MomentDateService } from "@ui-kitten/moment";

const dateService = new MomentDateService();

const CalendarComponent = ({
  initialDate,
  confirmWorkBookings,
  getConfirmWorkBookings,
}: {
  initialDate: moment.Moment;
  confirmWorkBookings: WorkBooking[];
  getConfirmWorkBookings: (date: moment.Moment) => void;
}): React.ReactElement => {
  const styles = useStyleSheet(themedStyles);
  const theme = useTheme();
  const [selectedDate, setSelectedDate] =
    React.useState<moment.Moment>(initialDate);
  const [visibleDate, setVisibleDate] = React.useState<moment.Moment>(moment());

  const componentRef = React.createRef<Calendar<moment.Moment>>();

  const scrollToSelected = (): void => {
    if (componentRef.current && selectedDate) {
      componentRef.current.scrollToDate(selectedDate);
    }
  };

  const scrollToToday = (): void => {
    if (componentRef.current) {
      componentRef.current.scrollToToday();
    }
  };

  const onSelectDay = (nextDate: moment.Moment) => {
    setSelectedDate(nextDate);
  };

  const renderDay = (
    info: CalendarDateInfo<moment.Moment>,
    style: StyleType
  ): React.ReactElement => {
    const { date } = info;
    const dayLabel = date.format("D");
    const isConfirmBookings = confirmWorkBookings.filter((data) =>
      moment(data.bookingDate).isSame(date, "day")
    );

    const isConfirmBooking = (): boolean => {
      return isConfirmBookings.length > 0;
    };

    const containerStyle = (): StyleProp<ViewStyle> => {
      if (isConfirmBooking()) {
        return [
          styles.dayContainer,
          style.container,
          {
            backgroundColor: theme["color-primary-500"],
          },
        ];
      }
      return [styles.dayContainer, style.container];
    };

    return (
      <View style={containerStyle()}>
        <Text style={style.text}>{dayLabel}</Text>
        {isConfirmBooking() && <Text>*</Text>}
      </View>
    );
  };

  const onVisibleDateChange = (
    date: moment.Moment,
    viewModeId: CalendarViewModeId
  ) => {
    setVisibleDate(date);
    getConfirmWorkBookings(date);
  };

  return (
    <Layout style={styles.container} level="2">
      <View style={styles.buttonContainer}>
        <Button onPress={scrollToToday}>ไปยังวันที่ปัจจุบัน</Button>
        <Button onPress={scrollToSelected}>ไปยังวันที่เลือก</Button>
      </View>
      <View style={styles.calendarContainer}>
        <Text category="h6" style={styles.text}>
          {`${moment(selectedDate).format("L")}`}
        </Text>
        <Calendar
          ref={componentRef}
          dateService={dateService}
          date={selectedDate}
          renderDay={renderDay}
          onSelect={onSelectDay}
          onVisibleDateChange={onVisibleDateChange}
        />
      </View>
    </Layout>
  );
};
export default memo(CalendarComponent);

const themedStyles = StyleService.create({
  dayContainer: {
    flex: 1,
    alignItems: "center",
    justifyContent: "flex-start",
    borderRadius: 8,
  },
  container: {
    flex: 1,
    margin: 2,
    paddingVertical: 4,
    paddingHorizontal: 4,
    flexDirection: "column",
    justifyContent: "space-between",
  },
  buttonContainer: {
    justifyContent: "space-between",
    flexDirection: "row",
    alignItems: "center",
    alignContent: "flex-start",
  },
  calendarContainer: {
    justifyContent: "space-between",
    flexDirection: "column",
    alignItems: "center",
    alignContent: "flex-start",
  },
  text: {
    marginVertical: 8,
  },
});
Karsten-Larson commented 1 year ago

Why was this closed? The documentation site still displays example code for rendering custom left and right arrows in the section for rendering custom days, months, and years.

danya0365 commented 4 months ago

Why was this closed? The documentation site still displays example code for rendering custom left and right arrows in the section for rendering custom days, months, and years.

let talk about it again