react-native-ui-kitten icon indicating copy to clipboard operation
react-native-ui-kitten copied to clipboard

DatePicker popover full width

Open ZoltanSzokodi opened this issue 1 year ago • 2 comments

Hi, I was trying to change the DayPicker's popover style to take the full width of the anchor component (the input filed). This is possible with the Popover component using the fullWidth property.
Screenshot 2023-03-13 at 09 44 51

ZoltanSzokodi avatar Mar 13 '23 08:03 ZoltanSzokodi

Hello there @ZoltanSzokodi !

Please provide code example, and i will try to help you with that!

bataevvlad avatar May 25 '23 13:05 bataevvlad

Hi @bataevvlad thanks for your reply! However I was expecting the Datepicker to have a property specifically for styling the popover not just the relative alignment. This is my component, but obviously you won't be able to fire it without the imports etc.

import {
  CalendarViewModes,
  Datepicker,
  DatepickerProps,
  I18nConfig,
  IconProps,
  TextProps,
} from '@ui-kitten/components'
import { RenderProp } from '@ui-kitten/components/devsupport'
import { DateFnsService } from '@ui-kitten/date-fns'
import getDate from 'date-fns/getDate'
import getMonth from 'date-fns/getMonth'
import isNil from 'lodash/isNil'
import React, { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { StyleProp, TextStyle } from 'react-native'

import { BaseTextProps } from './BaseText'
import { InputCaption } from './InputCaption'
import { InfoTooltipProps, InputLabel } from './InputLabel'
import { dateToUTC } from './helpers/dateToUTCDate'
import { CalendarIcon } from './svgs/CalendarIcon'

interface Props extends Omit<DatepickerProps, 'startView' | 'label'> {
  startView?: 'DATE' | 'MONTH' | 'YEAR'
  filteredDates?: {
    // years?: number[]
    months?: number[]
    days?: number[]
  }
  infoTooltip?: InfoTooltipProps
  label?: BaseTextProps['children']
  useUTC?: boolean
}

const DateSelectorImpl = ({
  style,
  initialVisibleDate,
  onSelect,
  autoDismiss,
  min,
  max,
  boundingMonth,
  startView = 'DATE', // can be CalendarViewModes.DATE | CalendarViewModes.MONTH | CalendarViewModes.YEAR
  status,
  size,
  placeholder,
  label,
  accessoryLeft,
  accessoryRight,
  caption,
  onFocus,
  onBlur,
  placement = 'bottom',
  backdropStyle,
  disabled,
  date,
  filteredDates = {
    months: [],
    days: [],
  },
  infoTooltip,
  useUTC,
}: Props) => {
  const [internalDate, setInternalDate] = useState<Date | undefined>()

  const formatDate = (d: Date | undefined) =>
    !isNil(d) ? new Date(d) : undefined

  // for setting initial value
  useEffect(() => {
    if (date) {
      setInternalDate(formatDate(date))
    }
  }, [])

  useEffect(() => {
    if (onSelect && internalDate) {
      if (useUTC) {
        onSelect(dateToUTC(internalDate))
      } else {
        onSelect(internalDate)
      }
    }
  }, [internalDate])

  // a function to determine whether particular date cells should be disabled
  const filterDates = (d: Date) => {
    const day = getDate(d)
    const month = getMonth(d) + 1 // months are 0 indexed

    if (filteredDates.days && filteredDates.days.length > 0) {
      if (filteredDates.months && filteredDates.months.length > 0) {
        return filteredDates.months.includes(month)
          ? !filteredDates.days.includes(day)
          : true
      } else {
        return !filteredDates.days.includes(day)
      }
    } else if (filteredDates.months && filteredDates.months.length > 0) {
      return filteredDates.months.includes(month) ? false : true
    } else {
      return true
    }
  }

  const renderAccessoryRight = accessoryRight
    ? accessoryRight
    : ({ style }: IconProps) => {
        return (
          <CalendarIcon
            style={style}
            size={style.width}
            color={style.tintColor}
          />
        )
      }

  const renderLabel = ({ style }: { style?: StyleProp<TextStyle> }) => {
    return label ? (
      <InputLabel style={style} label={label} infoTooltip={infoTooltip} />
    ) : undefined
  }

  const { i18n } = useTranslation()

  const dateService = new DateFnsService(i18n.language, {
    i18n: langConfig[i18n.language],
  })

  return (
    <Datepicker
      style={style}
      backdropStyle={backdropStyle}
      date={internalDate}
      dateService={dateService}
      onSelect={(nextDate) => setInternalDate(nextDate)}
      onFocus={onFocus}
      onBlur={onBlur}
      placeholder={placeholder}
      initialVisibleDate={formatDate(initialVisibleDate)}
      autoDismiss={autoDismiss}
      min={formatDate(min)}
      max={formatDate(max)}
      boundingMonth={boundingMonth}
      disabled={disabled}
      startView={CalendarViewModes[startView]}
      status={status}
      size={size}
      label={renderLabel as RenderProp<TextProps>}
      caption={(props: TextProps | undefined) => (
        <InputCaption caption={caption} {...props} />
      )}
      placement={placement}
      accessoryLeft={accessoryLeft}
      accessoryRight={renderAccessoryRight}
      filter={filterDates}
    />
  )
}

export const DateSelector = React.memo(DateSelectorImpl)

const langConfig: {
  [key: string]: I18nConfig
} = {
  de: {
    dayNames: {
      short: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
      long: [
        'Sonntag',
        'Montag',
        'Dienstag',
        'Mittwoch',
        'Donnerstag',
        'Freitag',
        'Samstag',
      ],
    },
    monthNames: {
      short: [
        'Jan',
        'Feb',
        'Mär',
        'Apr',
        'Mai',
        'Jun',
        'Jul',
        'Aug',
        'Sep',
        'Okt',
        'Nov',
        'Dez',
      ],
      long: [
        'Januar',
        'Februar',
        'März',
        'April',
        'Mai',
        'Juni',
        'Juli',
        'August',
        'September',
        'Oktober',
        'November',
        'Dezember',
      ],
    },
  },
  en: {
    dayNames: {
      short: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
      long: [
        'Sunday',
        'Monday',
        'Tuesday',
        'Wednesday',
        'Thursday',
        'Friday',
        'Saturday',
      ],
    },
    monthNames: {
      short: [
        'Jan',
        'Feb',
        'Mar',
        'Apr',
        'May',
        'Jun',
        'Jul',
        'Aug',
        'Sep',
        'Okt',
        'Nov',
        'Dec',
      ],
      long: [
        'January',
        'February',
        'March',
        'April',
        'May',
        'June',
        'July',
        'August',
        'September',
        'October',
        'November',
        'December',
      ],
    },
  },
}

ZoltanSzokodi avatar Jul 03 '23 12:07 ZoltanSzokodi