نحوه اضافه کردن دکمه های سفارشی به انتخابگر تاریخ در Flatpickr
اگر تا به حال مجبور شده اید از یک انتخابگر تاریخ در یک پروژه ظاهری وب استفاده کنید، به احتمال زیاد از flatpickr استفاده کرده اید.
برای افراد ناآشنا، flatpickr یکی از محبوبترین کتابخانههای انتخابگر تاریخ در متن باز است. این چارچوب آگنوستیک، بسیار قابل تنظیم و سبک وزن است.
من اخیراً مجبور شدم از آن در یک پایگاه کد Next.js استفاده کنم و یک مورد استفاده عجیب و غریب داشتم. رفتار داخلی این است که تاریخ ها بلافاصله پس از انتخاب اعمال می شوند و پس از آن انتخابگر تاریخ ناپدید می شود.
با این حال، چیزی که واقعاً میخواستم این بود که بتوانم تاریخها را انتخاب کنم و در لحظهای که این کار را انجام دادم، مدال ناپدید نشود. میخواستم بتوانم تاریخها را انتخاب کنم و فقط زمانی اعمال شود که روی دکمه «اعمال» کلیک کردم. من همچنین یک دکمه "پاک کردن" برای پاک کردن تاریخ های اعمال شده می خواستم.
معمولاً، API flatpickr روشهایی دارد که میتوانید با آنها کار کنید تا این قابلیتها را دریافت کنید، اما دکمههایی در خود انتخابگر تاریخ دریافت نخواهید کرد.
حتی در حالی که افزونهای وجود دارد که دکمهای را به انتخابگر تاریخ اضافه میکند تا تاریخها را بهصورت دستی اعمال کند، اما برای محدودههای تاریخ کار نمیکند (که من به آن نیاز داشتم) و ظاهر دکمه واقعاً با موضوع کلی ترکیب نمیشود. برنامه ای که من می ساختم
من چاره دیگری نداشتم جز اینکه راه حل خودم را بیابم. اما چگونه میتوانید دکمههای خود را در انتخابگر تاریخ flatpickr ظاهر کنید؟
نحوه تنظیم flatpickr
npm install flatpickr
در مرحله بعد، به یک مؤلفه DatePicker
نیاز دارید که انتخابگر تاریخ سفارشی را کپسوله کند و آن را قابل استفاده مجدد کند. این کامپوننت باید دارای یک پایه onChange
باشد که هر زمان که تاریخ اعمال شود، یک callback ارسال می شود که فراخوانی می شود:
// DatePicker.tsx const DatePicker: React.FC<DatePickerProps> = ({ onChange }) => { return <div></div> } export default DatePicker interface DatePickerProps { onChange: (date: Date[]) => void }
بعد، باید خود flatpickr را راه اندازی کنید. شما قصد دارید مقداری صادرات را از بسته flatpickr وارد کنید. در نشانه گذاری، یک عنصر ورودی متن را اضافه می کنید، که ورودی انتخابگر تاریخ خواهد بود، و یک متغیر ref عنصر را به آن منتقل می کنید که برای نمونه سازی نمونه flatpickr با چند گزینه پیکربندی استفاده می شود:
// DatePicker.tsx import { ElementRef, useEffect, useRef, useState } from "react" import flatpickr from "flatpickr" import { Instance as Flatpickr } from "flatpickr/dist/types/instance" import "flatpickr/dist/flatpickr.min.css" const DatePicker: React.FC<DatePickerProps> = ({ onChange }) => { const [flatpickrInstance, setFlatpickrInstance] = useState<Flatpickr>() const datePickerRef = useRef<ElementRef<"input">>(null) useEffect(() => { if (datePickerRef.current) { const flatpickrInstance = flatpickr(datePickerRef.current, { static: true, closeOnSelect: false, }) setFlatpickrInstance(flatpickrInstance) } return () => flatpickrInstance?.destroy() }, []) return ( <div> <input ref={datePickerRef} type="text" placeholder="Select date..." /> </div> ) } ...
برای گزینههای پیکربندی، static
روی true تنظیم میشود، پس مدال انتخابگر تاریخ به ورودی انتخابگر تاریخ متصل میشود و closeOnSelect
نادرست است، پس وقتی تاریخ انتخاب میشود، حالت انتخابگر تاریخ ناپدید نمیشود.
انتخابگر تاریخ تا اینجا به این صورت است:
نحوه اضافه کردن دکمه ها
ما به جاذبه اصلی روز رسیدیم. از قطعه زیر، متوجه دو واردات جدید خواهید شد: createPortal
از react-dom و یک کامپوننت Button
از پیش استایل شده. همانطور که می بینید createPortal
نقش بسیار ویژه ای ایفا خواهد کرد.
// DatePicker.tsx import { ElementRef, useEffect, useRef, useState } from "react" import { createPortal } from "react-dom" import flatpickr from "flatpickr" import Button from "./Button" import { Instance as Flatpickr } from "flatpickr/dist/types/instance" import "flatpickr/dist/flatpickr.min.css" ...
با حرکت به بدنه مولفه DatePicker
، تغییراتی را نیز مشاهده خواهید کرد.
dates
وجود دارد که تاریخ(های) انتخاب شده را ذخیره می کند (یا یک آرایه خالی در صورت عدم انتخاب تاریخ) و applyDate
که با کلیک روی دکمه "اعمال"، تماس را برای تماس نگه می دارد.
در شیء پیکربندی، دو قلاب flatpickr پیدا خواهید کرد: onChange
که هر زمان که تاریخ انتخاب میشود فعال میشود و آرایهای از تاریخهای انتخابشده فعلی را دریافت میکند، و onClose
که با بسته شدن حالت انتخابگر تاریخ فعال میشود.
در بدنه این هوک ها پیاده سازی هایی وجود دارد که رفتار انتخابگر تاریخ را مشخص می کند.
// DatePicker.tsx ... const DatePicker: React.FC<DatePickerProps> = ({ onChange }) => { const [flatpickrInstance, setFlatpickrInstance] = useState<Flatpickr>() const datePickerRef = useRef<ElementRef<"input">>(null) const dates = useRef<Date[]>([]) const [applyDate, setApplyDate] = useState(() => () => {}) useEffect(() => { if (datePickerRef.current) { const flatpickrInstance = flatpickr(datePickerRef.current, { static: true, closeOnSelect: false, onChange: (selectedDates) => { if (selectedDates.length === 0) { onChange([]) dates.current = [] } setApplyDate(() => { return () => { dates.current = selectedDates onChange(selectedDates) flatpickrInstance.close() } }) }, onClose: () => { flatpickrInstance.setDate(dates.current) }, }) setFlatpickrInstance(flatpickrInstance) } return () => flatpickrInstance?.destroy() }, []) return ( <div> ...
ما به قسمتی رسیدیم که در نهایت دکمه های سفارشی را در انتخابگر تاریخ قرار دادید. اینجاست که createPortal
می درخشد.
flatpickrInstance
دارای ویژگی calendarContainer
است که ارجاعی به عنصر div
در انتخابگر تاریخ دارد. اینجاست که با استفاده از پرتال واکنش، دکمههای سفارشی را، درست در زیر قسمت تقویم انتخابگر تاریخ، نمایش میدهید.
// DatePicker.tsx ... return ( <div> <input ref={datePickerRef} type="text" placeholder="Select date..." /> {flatpickrInstance && createPortal( <div className="flex justify-center gap-3 py-2"> <Button text="Clear" bgColor="#F8F8F8" textColor="#292A2E" onClick={() => { flatpickrInstance.clear(true) flatpickrInstance.close() }} /> <Button text="Apply" bgColor="#569ff7" textColor="#FFF" onClick={applyDate} /> </div>, flatpickrInstance.calendarContainer )} </div> ) } export default DatePicker ...
با هم، این خروجی کد نهایی است:
// DatePicker.tsx import { ElementRef, useEffect, useRef, useState } from "react" import { createPortal } from "react-dom" import flatpickr from "flatpickr" import Button from "./Button" import { Instance as Flatpickr } from "flatpickr/dist/types/instance" import "flatpickr/dist/flatpickr.min.css" const DatePicker: React.FC<DatePickerProps> = ({ onChange }) => { const [flatpickrInstance, setFlatpickrInstance] = useState<Flatpickr>() const datePickerRef = useRef<ElementRef<"input">>(null) const dates = useRef<Date[]>([]) const [applyDate, setApplyDate] = useState(() => () => {}) useEffect(() => { if (datePickerRef.current) { const flatpickrInstance = flatpickr(datePickerRef.current, { static: true, closeOnSelect: false, onChange: (selectedDates) => { if (selectedDates.length === 0) { onChange([]) dates.current = [] } setApplyDate(() => { return () => { dates.current = selectedDates onChange(selectedDates) flatpickrInstance.close() } }) }, onClose: () => { flatpickrInstance.setDate(dates.current) }, }) setFlatpickrInstance(flatpickrInstance) } return () => flatpickrInstance?.destroy() }, []) return ( <div> <input ref={datePickerRef} type="text" placeholder="Select date..." /> {flatpickrInstance && createPortal( <div className="flex justify-center gap-3 py-2"> <Button text="Clear" bgColor="#F8F8F8" textColor="#292A2E" onClick={() => { flatpickrInstance.clear(true) flatpickrInstance.close() }} /> <Button text="Apply" bgColor="#569ff7" textColor="#FFF" onClick={applyDate} /> </div>, flatpickrInstance.calendarContainer )} </div> ) } export default DatePicker interface DatePickerProps { onChange: (date: Date[]) => void }
و اکنون انتخابگر تاریخ با دکمه های سفارشی اینگونه به نظر می رسد:
نتیجه
انتخابگر تاریخ اکنون کاملاً کاربردی است و می تواند برای همه گزینه های mode
کار کند. تعداد زیادی سفارشی سازی بالقوه وجود دارد که می توانید با استفاده از این تکنیک انجام دهید. امیدواریم این مقاله به خوبی نشان دهد که چگونه می توان به سفارشی سازی flatpickr دست یافت.
❤️از این مقاله لذت بردید؟
مطالب من را بیشتر ببینید! می توانید مقالات بیشتری را در وبلاگ من بیابید.
می خواهید وصل شوید؟ با من در توییتر یا لینکدین پیوند برقرار کنید.
ارسال نظر