henripar / react-lite-month-picker

Simple, modern and customizable month picker component for ReactJS.
https://react-lite-month-picker.dev
MIT License
36 stars 10 forks source link

Error on nextjs #6

Open pjatupon opened 2 months ago

pjatupon commented 2 months ago

Could not find a declaration file for module 'react-lite-month-picker'. '/node_modules/react-lite-month-picker/src/index.js' implicitly has an 'any' type. Try npm i --save-dev @types/react-lite-month-picker if it exists or add a new declaration (.d.ts) file containing declare module 'react-lite-month-picker';

ElementaitaStopover commented 1 month ago

@pjatupon Have you found a solution for this?

As for me I meet with build error, I am a newbie in Nextjs, here is my issue,

Build Error Failed to compile

``Next.js (14.2.13) ./node_modules/react-lite-month-picker/src/components/MonthInput/MonthInput.jsx Module parse failed: Unexpected token (25:4) | | return (

<button

| className={styles.monthInputField} | onClick={() => props.setShowMonthPicker(!props.showMonthPicker)}``

pjatupon commented 1 month ago

@ElementaitaStopover I can't found any solution. But I create custom component base on this vendor. It work for me.

image

ElementaitaStopover commented 1 month ago

@ElementaitaStopover I can't found any solution. But I create custom component base on this vendor. It work for me.

image

Kindly share how you solved this.

pjatupon commented 1 month ago

my application develop by nextjs + nextui. first. install popover npm install @nextui-org/popover

second. create component file name "monthPicker.tsx"

import { Button, Popover, PopoverContent, PopoverTrigger } from '@nextui-org/react';
import moment from 'moment';
import React, { useEffect, useState } from 'react';
import { BsCalendar3 } from 'react-icons/bs';

export function MonthInput(props: any) {
    const [isOpen, setIsOpen] = useState(false);
    const [month, setMonth] = useState(
        props.selected.month ? props.selected.month - 1 : new Date().getMonth()
    );
    const [year, setYear] = useState(
        props.selected.year ?? new Date().getFullYear()
    );

    const changeYear = (year: any) => {
        setYear(year);
    };

    const getMonthNames = (locale = 'en', format = "short") => {
        const options: any = { month: format, timeZone: 'Asia/Bangkok' }
        const formatter = new Intl.DateTimeFormat(locale, options);
        const months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].map((month) => {
            const mm = month < 10 ? `0${month}` : month;
            return new Date(`2023-${mm}-01T00:00:00+00:00`);
        });
        return months.map((date) => formatter.format(date));
    };

    const changeMonth = (month: any) => {
        setMonth(month);
        props.onChange({
            month: month + 1,
            year: year,
            monthName: new Date(year, month).toLocaleString(
                props.lang ? props.lang : 'en',
                {
                    month: 'long',
                }
            ),
            monthShortName: new Date(year, month).toLocaleString(
                props.lang ? props.lang : 'en',
                {
                    month: 'short',
                }
            ),
        });
        setIsOpen(false);
    };

    return (
        <Popover placement="bottom" showArrow isOpen={isOpen} onOpenChange={(open) => setIsOpen(open)}>
            <PopoverTrigger>
                <Button variant="bordered" className='min-w-48 border-1' endContent={<BsCalendar3 />}>
                    {props.selected.month ? moment(`${parseInt(props.selected.year)}-${props.selected.month}`, "YYYY-MM").add(543, 'year').format('MMMM YYYY') : null}
                </Button>
            </PopoverTrigger>
            <PopoverContent>
                <div className="px-1 py-2" >
                    <div className="text-large font-bold flex justify-center">
                        <div className='flex flex-row items-center gap-3'>
                            <button
                                // className={styles.button}
                                aria-label='Previous Year'
                                onClick={(e) => changeYear(year - 1)}
                            >
                                <svg
                                    xmlns='http://www.w3.org/2000/svg'
                                    width='24'
                                    height='24'
                                    viewBox='0 0 24 24'
                                    fill='none'
                                    stroke={props.textColor ? props.textColor : '#000'}
                                    strokeWidth='2'
                                    strokeLinecap='round'
                                    strokeLinejoin='round'
                                    className='lucide lucide-chevron-left'
                                >
                                    <path d='m15 18-6-6 6-6' />
                                </svg>
                            </button>
                            <span aria-description='Year selected'>
                                {moment(`${parseInt(year)}-${props.selected.month}`, "YYYY-MM").add(543, 'year').format('YYYY')}
                            </span>
                            <button
                                // className={styles.button}
                                aria-label='Next Year'
                                onClick={(e) => changeYear(year + 1)}
                            >
                                <svg
                                    xmlns='http://www.w3.org/2000/svg'
                                    width='24'
                                    height='24'
                                    viewBox='0 0 24 24'
                                    fill='none'
                                    stroke={props.textColor ? props.textColor : '#000'}
                                    strokeWidth='2'
                                    strokeLinecap='round'
                                    strokeLinejoin='round'
                                    className='lucide lucide-chevron-right'
                                >
                                    <path d='m9 18 6-6-6-6' />
                                </svg>
                            </button>
                        </div>
                    </div>
                    <div className="mt-3 grid grid-cols-2 md:grid-cols-3 gap-1">
                        {getMonthNames(props.lang).map((monthName, index) => {
                            return (
                                <Button
                                    color="default" variant="light"
                                    key={index}
                                    className={`${index == month && props.selected.year == year
                                        ? 'bg-secondary text-white'
                                        : null
                                        }`}
                                    onClick={(e) => changeMonth(index)}
                                >
                                    {monthName}
                                </Button>
                            );
                        })}
                    </div>
                </div>
            </PopoverContent>
        </Popover>
    );
}

third. Used component

const [selectedMonthData, setSelectedMonthData] = useState({
        month: (new Date().getMonth() + 1),
        year: new Date().getFullYear(),
    });
    const [isPickerOpen, setIsPickerOpen] = useState(false);

<div className="flex gap-3">
      <MonthInput
          selected={selectedMonthData}
          showMonthPicker={isPickerOpen}
          onChange={setSelectedMonthData}
          lang='th-TH'
      />
  </div>