
Средство выбора даты без заголовка для приложений React
24 декабря 2022 г.С каждым годом сообщество ⚛️ React становится все больше и больше.
И с этим ростом мы получаем все больше и больше инструментов для достижения наших целей и потребностей. Несмотря на это невероятное разнообразие, трудно получить то, что вы хотите.
Проблема
Давайте углубимся в проблему:
- 🙅 в вашей библиотеке компонентов нет нужного компонента;
- ⚙️ вам необходимо внести изменения в процесс сборки;
- 💅 ваша система укладки отличается от самого популярного решения;
- 🦹 сложно настроить компонент, соответствующий вашему дизайну;
- 💰 получение необходимых компонентов может стоить денег (привет MUI 😉)
- 🏋️ библиотека тяжёлая и не имеет tree-shaking;
- 📚 ужасная документация;
- ⛔️ без тестов, без поддержки TypeScript, без примеров...
И это всего лишь выбор даты 🗓.
Решение
Решением всех этих 👆 проблем может быть компонент безголового пользовательского интерфейса, такой как @rehookify/datepicker
Основные функции и преимущества:
- маленький размер
- ноль зависимостей;
- модульный дизайн позволяет использовать как можно меньше кода;
- одиночный, множественный выбор и диапазон даты;
- поддержка нескольких календарей;
- поддерживать нативную локализацию с помощью
.toLocaleDateString
; - prop-getters, чтобы предоставить все необходимые реквизиты для ваших компонентов;
Главный недостаток в том, что вам нужно стилизовать все самостоятельно. Но с современными методами компоновки CSS
, такими как grid
и flex
, это сделать легко и весело. Значит недостатков нет вообще 😅
Используя @rehookify/datepicker, вы можете выбрать модульный или комплексный подход.
Код
Модульные крючки
В приведенном ниже примере показан календарь с несколькими вариантами дат 👇
import {
useDatePickerState,
useDaysPropGetters,
} from '@rehookify/datepicker';
const DatePicker = () => {
const config = { dates: { toggle: true, mode: 'multiple' }}
const [state, dispatch] = useDatePickerState(config);
const { calendars, weekDays } = useCalendars(state);
const { dayButton } = useDaysPropGetters(state, dispatch);
const { month, year, days } = calendars[0];
return (
<section>
<header>
<div>
<p>{month} {year}</p>
</div>
<ul>
{weekDays.map((day) => (
<li key={`${month}-${day}`}}>{day}</li>
))}
</ul>
</header>
<ul>
{days.map((dpDay) => (
<li
key={`${month}-${dpDay.date}`}
>
<button {...dayButton(dpDay)}>{dpDay.day}</button>
</li>
))}
</ul>
</section>
);
}
Модульный контекст
Если вы не хотите передавать какие-либо параметры 💆♂️ или хотите разделить компоненты, вы можете использовать реализацию контекста.
В приведенном ниже примере показан календарь с выбором диапазона дат 👇
import {
DatePickerStateProvider,
useContextCalendars,
useContextDaysPropGetters,
} from '@rehookify/datepicker';
const DatePicker = () => {
const { calendars, weekDays } = useContextCalendars();
const { dayButtons } = useContextDaysPropGetters();
const { year, month, days } = calendars[0];
return (
<section>
<header>
<div>
<p>{month} {year}</p>
</div>
<ul>
{weekDays.map((day) => (
<li key={`${month}-${day}`}>{day}</li>
))}
</ul>
</header>
<ul>
{days.map((dpDay) => (
<li
key={`${month}-${dpDay.date}`}
>
<button
{...dayButton(dpDay)}
disabled={dpDay.disabled}
>{dpDay.day}</button>
</li>
))}
</ul>
</section>
)
}
const App = () => {
<DatePickerStateProvider
config={{ dates: { mode: 'range' }}}
>
<DatePicker />
</DatePickerStateProvider>
}
Универсальные решения
использовать средство выбора даты
Календарь с выбором даты и разбивкой по месяцам 👇
import React, { MouseEvent } from 'react';
import { useDatePicker } from '@rehookify/datepicker';
const DatePicker = () => {
const {
data: { weekDays, calendars, formattedDates },
propGetters: {
dayButton,
previousMonthButton,
nextMonthButton,
},
} = useDatePicker();
// calendars[0] is always present, this is an initial calendar
const { year, month, days } = calendars[0];
const onDayClick = (evt: MouseEvent<HTMLElement>, date: Date) => {
// In case you need any action with the event
evt.stopPropagation();
// In case you need any additional action with date
console.log(date);
}
// formattedDates is an array of dates formatted with
// `.toLocaleDateString(locale, options)`
return (
<section>
{selectedDates.length > 0 && <h1>{formattedDates[0]}</h1>}
<header>
<div>
<button {...previousMonthButton()}><</button>
<p>{month} {year}</p>
<button {...nextMonthButton()}>></button>
</div>
<ul>
{weekDays.map((day) => (
<li key={`${month}-${day}`}>{day}</li>
))}
</ul>
</header>
<ul>
{days.map((dpDay) => (
<li key={dpDay.date}>
<button {...dayButton(dpDay)}>{dpDay.day}</button>
</li>
))}
</ul>
</section>
)
}
Провайдер выбора даты
import {
DatePickerProvider,
useDatePickerContext,
} from '@rehookify/datepicker';
const DatePicker = () => {
const {
data: { weekDays, calendars, years, months }
} = useDatePickerContext();
const { year, month, days } = calendars[0];
return (
<section>
<header>{month} {year}</header>
...
</section>
)
}
const App = () => {
<DatePickerProvider config={{ dates: { mode: 'range' }}}>
<DatePicker />
</DatePickerProvider>
}
Заключение
@rehookify/datepicker поможет вам создать средство выбора даты, которое соответствует вашим потребностям и техническому стеку. Его модульная конструкция позволит сохранить как можно больше байтов для вашего приложения.
Изображение Антона Лапко
Оригинал