@homecode/ui 4.14.0 → 4.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -46,14 +46,16 @@ const getDaysArray = (year, month, startOfWeek) => {
46
46
  }
47
47
  let nextMonthDay = 1;
48
48
  const nextMonthStartDay = result.length % 7;
49
- for (let i = nextMonthStartDay; i < 7; i++) {
50
- result.push({
51
- day: nextMonthDay,
52
- month: monthIndex + 2 > 12 ? 1 : monthIndex + 2,
53
- year: monthIndex === 11 ? year + 1 : year,
54
- currentMonth: false,
55
- });
56
- nextMonthDay++;
49
+ if (nextMonthStartDay > 0) {
50
+ for (let i = nextMonthStartDay; i < 7; i++) {
51
+ result.push({
52
+ day: nextMonthDay,
53
+ month: monthIndex + 2 > 12 ? 1 : monthIndex + 2,
54
+ year: monthIndex === 11 ? year + 1 : year,
55
+ currentMonth: false,
56
+ });
57
+ nextMonthDay++;
58
+ }
57
59
  }
58
60
  CACHE[key] = result;
59
61
  return result;
@@ -25,7 +25,7 @@ const renderDayDefault = (val, props) => {
25
25
  const { day, year, month } = val;
26
26
  return (jsx("div", { ...props, children: day }, `${year}-${month}-${day}`));
27
27
  };
28
- function Calendar({ value, onDayClick, renderDay, renderWeekDayLabel, renderMonthLabel, renderMonthesLabel, renderYearLabel, startOfWeek = 1, weekendClassName, size, }) {
28
+ function Calendar({ className, value, onDayPointerDown, onDayPointerUp, renderDay, renderWeekDayLabel, renderMonthLabel, renderMonthesLabel, renderYearLabel, startOfWeek = 1, weekendClassName, hideOtherMonthDays, size, }) {
29
29
  const date = useMemo(() => valueToDate(value), [value]);
30
30
  const [month, setMonth] = useState(date.getMonth() + 1);
31
31
  const [year, setYear] = useState(date.getFullYear());
@@ -45,16 +45,20 @@ function Calendar({ value, onDayClick, renderDay, renderWeekDayLabel, renderMont
45
45
  if (year < MIN_YEAR)
46
46
  setYear(MIN_YEAR);
47
47
  };
48
- return (jsxs("div", { className: cn(S.root, S[`size-${size}`]), children: [jsxs("div", { className: S.header, children: [jsx(Input, { className: S.year, type: "number", min: MIN_YEAR,
48
+ const classes = cn(S.root, S[`size-${size}`], className, hideOtherMonthDays && S.hideOtherMonthDays);
49
+ return (jsxs("div", { className: classes, children: [jsxs("div", { className: S.header, children: [jsx(Input, { className: S.year, type: "number", min: MIN_YEAR,
49
50
  // @ts-ignore
50
51
  size: size, label: renderYearLabel?.(year) ?? 'Year', value: year,
51
52
  // @ts-ignore
52
53
  onChange: onYearChange, onBlur: onYearBlur }), jsx(Select, { className: S.month, size: size, label: renderMonthesLabel?.(month) ?? 'Month', options: monthOptions, value: month, onChange: val => setMonth(val) })] }), jsx("div", { className: S.weekDays, children: weekDaysArray.map((day, weekdayIndex) => (jsx("div", { className: cn(S.day, isWeekend(weekdayIndex) && weekendClassName), children: renderWeekDayLabel?.(day) ?? weekDays[day] }, `weekday-${day}`))) }), jsx("div", { className: S.days, children: daysArray.map((day, weekdayIndex) => {
53
- const classes = cn(S.day, day.currentMonth && S.currMonth, isWeekend(weekdayIndex) && weekendClassName, isSameDay(day, value) && S.selected);
54
- const dayProps = {
55
- className: classes,
56
- onClick: () => onDayClick?.(day),
57
- };
54
+ const className = cn(S.day, day.currentMonth && S.currMonth, isWeekend(weekdayIndex) && weekendClassName, isSameDay(day, value) && S.selected);
55
+ const dayProps = { className };
56
+ if (onDayPointerDown) {
57
+ dayProps.onPointerDown = () => onDayPointerDown(day);
58
+ }
59
+ if (onDayPointerUp) {
60
+ dayProps.onPointerUp = () => onDayPointerUp(day);
61
+ }
58
62
  return renderDay?.(day, dayProps) ?? renderDayDefault(day, dayProps);
59
63
  }) })] }));
60
64
  }
@@ -1,7 +1,7 @@
1
1
  import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
2
2
 
3
- var css_248z = ".Calendar_size-s__MFLPb{font-size:.5em}.Calendar_size-m__IGeoI{font-size:.75em}.Calendar_size-l__a2zct{font-size:1em}.Calendar_root__v8Jg6{display:flex;flex-direction:column}.Calendar_header__IHzS-{align-items:center;display:flex;justify-content:space-between}.Calendar_month__gi10Q{width:100%!important}.Calendar_year__UlmLM{min-width:5em}.Calendar_year__UlmLM input{min-width:0;min-width:auto}.Calendar_month__gi10Q{margin-left:var(--indent-s)}.Calendar_weekDays__Pglyw{align-items:center;color:var(--accent-color-alpha-500);display:flex;font-size:.75em;margin-top:var(--indent-s);width:100%}.Calendar_weekDays__Pglyw .Calendar_day__A3NG-{padding:1.5em 0}.Calendar_size-s__MFLPb .Calendar_weekDays__Pglyw .Calendar_day__A3NG-:first-child{border-top-left-radius:4px}.Calendar_size-s__MFLPb .Calendar_weekDays__Pglyw .Calendar_day__A3NG-:last-child{border-top-right-radius:4px}.Calendar_size-m__IGeoI .Calendar_weekDays__Pglyw .Calendar_day__A3NG-:first-child{border-top-left-radius:6px}.Calendar_size-m__IGeoI .Calendar_weekDays__Pglyw .Calendar_day__A3NG-:last-child{border-top-right-radius:6px}.Calendar_size-l__a2zct .Calendar_weekDays__Pglyw .Calendar_day__A3NG-:first-child{border-top-left-radius:8px}.Calendar_size-l__a2zct .Calendar_weekDays__Pglyw .Calendar_day__A3NG-:last-child{border-top-right-radius:8px}.Calendar_days__64U-y{display:flex;flex-wrap:wrap;justify-content:space-between;-webkit-user-select:none;-moz-user-select:none;user-select:none}.Calendar_days__64U-y .Calendar_day__A3NG-:not(.Calendar_currMonth__oL4nl){color:var(--accent-color-alpha-500)}.Calendar_size-s__MFLPb .Calendar_days__64U-y .Calendar_day__A3NG-:last-child{border-bottom-right-radius:4px}.Calendar_size-m__IGeoI .Calendar_days__64U-y .Calendar_day__A3NG-:last-child{border-bottom-right-radius:6px}.Calendar_size-l__a2zct .Calendar_days__64U-y .Calendar_day__A3NG-:last-child{border-bottom-right-radius:8px}.Calendar_day__A3NG-{align-items:center;display:flex;height:2em;justify-content:center;width:14.28571%}.Calendar_day__A3NG-.Calendar_selected__ffB6-{background-color:var(--active-color-alpha-100)!important}.Calendar_day__A3NG-.Calendar_currMonth__oL4nl{font-weight:700}";
4
- var S = {"size-s":"Calendar_size-s__MFLPb","size-m":"Calendar_size-m__IGeoI","size-l":"Calendar_size-l__a2zct","root":"Calendar_root__v8Jg6","header":"Calendar_header__IHzS-","month":"Calendar_month__gi10Q","year":"Calendar_year__UlmLM","weekDays":"Calendar_weekDays__Pglyw","day":"Calendar_day__A3NG-","days":"Calendar_days__64U-y","currMonth":"Calendar_currMonth__oL4nl","selected":"Calendar_selected__ffB6-"};
3
+ var css_248z = ".Calendar_size-s__MFLPb{font-size:.5em}.Calendar_size-m__IGeoI{font-size:.75em}.Calendar_size-l__a2zct{font-size:1em}.Calendar_root__v8Jg6{display:flex;flex-direction:column}.Calendar_header__IHzS-{align-items:center;display:flex;justify-content:space-between}.Calendar_month__gi10Q{width:100%!important}.Calendar_year__UlmLM{min-width:5em}.Calendar_year__UlmLM input{min-width:0;min-width:auto}.Calendar_month__gi10Q{margin-left:var(--indent-s)}.Calendar_weekDays__Pglyw{align-items:center;color:var(--accent-color-alpha-500);display:flex;font-size:.75em;margin-top:var(--indent-s);width:100%}.Calendar_weekDays__Pglyw .Calendar_day__A3NG-{padding:1.5em 0}.Calendar_size-s__MFLPb .Calendar_weekDays__Pglyw .Calendar_day__A3NG-:first-child{border-top-left-radius:4px}.Calendar_size-s__MFLPb .Calendar_weekDays__Pglyw .Calendar_day__A3NG-:last-child{border-top-right-radius:4px}.Calendar_size-m__IGeoI .Calendar_weekDays__Pglyw .Calendar_day__A3NG-:first-child{border-top-left-radius:6px}.Calendar_size-m__IGeoI .Calendar_weekDays__Pglyw .Calendar_day__A3NG-:last-child{border-top-right-radius:6px}.Calendar_size-l__a2zct .Calendar_weekDays__Pglyw .Calendar_day__A3NG-:first-child{border-top-left-radius:8px}.Calendar_size-l__a2zct .Calendar_weekDays__Pglyw .Calendar_day__A3NG-:last-child{border-top-right-radius:8px}.Calendar_days__64U-y{display:flex;flex-wrap:wrap;justify-content:space-between;-webkit-user-select:none;-moz-user-select:none;user-select:none}.Calendar_days__64U-y .Calendar_day__A3NG-:not(.Calendar_currMonth__oL4nl){color:var(--accent-color-alpha-500)}.Calendar_hideOtherMonthDays__DydjR .Calendar_days__64U-y .Calendar_day__A3NG-:not(.Calendar_currMonth__oL4nl){opacity:0;pointer-events:none}.Calendar_size-s__MFLPb .Calendar_days__64U-y .Calendar_day__A3NG-:last-child{border-bottom-right-radius:4px}.Calendar_size-m__IGeoI .Calendar_days__64U-y .Calendar_day__A3NG-:last-child{border-bottom-right-radius:6px}.Calendar_size-l__a2zct .Calendar_days__64U-y .Calendar_day__A3NG-:last-child{border-bottom-right-radius:8px}.Calendar_day__A3NG-{align-items:center;display:flex;height:2em;justify-content:center;min-width:0;min-width:auto;padding:0;width:14.28571%}.Calendar_day__A3NG-.Calendar_selected__ffB6-{background-color:var(--active-color-alpha-500)!important}.Calendar_day__A3NG-.Calendar_currMonth__oL4nl{font-weight:700}";
4
+ var S = {"size-s":"Calendar_size-s__MFLPb","size-m":"Calendar_size-m__IGeoI","size-l":"Calendar_size-l__a2zct","root":"Calendar_root__v8Jg6","header":"Calendar_header__IHzS-","month":"Calendar_month__gi10Q","year":"Calendar_year__UlmLM","weekDays":"Calendar_weekDays__Pglyw","day":"Calendar_day__A3NG-","days":"Calendar_days__64U-y","currMonth":"Calendar_currMonth__oL4nl","hideOtherMonthDays":"Calendar_hideOtherMonthDays__DydjR","selected":"Calendar_selected__ffB6-"};
5
5
  styleInject(css_248z);
6
6
 
7
7
  export { S as default };
@@ -0,0 +1,20 @@
1
+ function isDateEqual(date1, date2) {
2
+ return (date1.year === date2.year &&
3
+ date1.month === date2.month &&
4
+ date1.day === date2.day);
5
+ }
6
+ function isDateBefore(date1, date2) {
7
+ return (date1.year < date2.year ||
8
+ (date1.year === date2.year && date1.month < date2.month) ||
9
+ (date1.year === date2.year &&
10
+ date1.month === date2.month &&
11
+ date1.day < date2.day));
12
+ }
13
+ function isDateAfter(date1, date2) {
14
+ return isDateBefore(date2, date1);
15
+ }
16
+ function isDateBetween(date, startDate, endDate) {
17
+ return isDateAfter(date, startDate) && isDateBefore(date, endDate);
18
+ }
19
+
20
+ export { isDateAfter, isDateBefore, isDateBetween, isDateEqual };
@@ -1,21 +1,42 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
- import { useCallback, createElement } from 'react';
2
+ import { useState, useCallback, createElement } from 'react';
3
3
  import cn from 'classnames';
4
4
  import { Calendar } from '../Calendar/Calendar.js';
5
5
  import { Button } from '../Button/Button.js';
6
+ import { isDateAfter, isDateBetween, isDateEqual } from './DatePicker.helpers.js';
6
7
  import S from './DatePicker.styl.js';
7
8
 
8
9
  function DatePicker(props) {
9
10
  const { value, onChange, size, calendarProps } = props;
10
11
  const isRange = Array.isArray(value);
12
+ const [isPicking, setIsPicking] = useState(false);
11
13
  const onFirstDateChange = useCallback((val) => {
12
14
  onChange(isRange ? [val, value[1]] : val);
13
15
  }, [value, onChange, isRange]);
16
+ const onPointerDown = () => setIsPicking(true);
17
+ const onPointerUp = () => setIsPicking(false);
14
18
  const renderDay = useCallback((val, { className, ...props }) => {
15
19
  const { day, year, month } = val;
16
- return (createElement(Button, { ...props, variant: "clear", className: cn(className, S.day), size: size, key: `${year}-${month}-${day}` }, day));
17
- }, [size]);
18
- return (jsxs("div", { className: S.root, children: [jsx(Calendar, { size: size, ...calendarProps, value: isRange ? value[0] : value, onDayClick: onFirstDateChange, renderDay: renderDay }), isRange && (jsx(Calendar, { size: size, ...calendarProps, value: value[1], onDayClick: val => onChange([value[0], val]), renderDay: renderDay }))] }));
20
+ if (isRange && isPicking) {
21
+ props.onPointerOver = () => {
22
+ const newVal = isDateAfter(value[0], val)
23
+ ? [val, value[0]]
24
+ : [value[0], val];
25
+ onChange(newVal);
26
+ };
27
+ }
28
+ const classes = [className, S.day];
29
+ if (isRange) {
30
+ if (isDateBetween(val, ...value))
31
+ classes.push(S.between);
32
+ if (isDateEqual(val, value[0]))
33
+ classes.push(S.start);
34
+ if (isDateEqual(val, value[1]))
35
+ classes.push(S.end);
36
+ }
37
+ return (createElement(Button, { ...props, variant: "clear", className: cn(classes), size: size, key: `${year}-${month}-${day}` }, day));
38
+ }, [size, isPicking, isRange, value, onChange]);
39
+ return (jsxs("div", { className: cn(S.root, props.className), onPointerDown: onPointerDown, onPointerUp: onPointerUp, children: [jsx(Calendar, { size: size, hideOtherMonthDays: true, ...calendarProps, renderDay: renderDay, value: isRange ? value[0] : value, onDayPointerDown: onFirstDateChange }), isRange && (jsx(Calendar, { size: size, hideOtherMonthDays: true, ...calendarProps, renderDay: renderDay, value: value[1], onDayPointerDown: val => onChange([value[0], val]), onDayPointerUp: val => onChange([value[0], val]) }))] }));
19
40
  }
20
41
 
21
42
  export { DatePicker };
@@ -1,7 +1,7 @@
1
1
  import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
2
2
 
3
- var css_248z = ".DatePicker_root__hh-PP{display:flex;flex-direction:column}.DatePicker_day__kGD0i:hover{background-color:var(--accent-color-alpha-100)}";
4
- var S = {"root":"DatePicker_root__hh-PP","day":"DatePicker_day__kGD0i"};
3
+ var css_248z = ".DatePicker_root__hh-PP{display:flex;flex-direction:column}.DatePicker_day__kGD0i.DatePicker_end__KYPnO,.DatePicker_day__kGD0i.DatePicker_start__qd0rW{background-color:var(--active-color-alpha-500)!important}.DatePicker_day__kGD0i.DatePicker_start__qd0rW{border-bottom-right-radius:0;border-top-right-radius:0}.DatePicker_day__kGD0i.DatePicker_end__KYPnO{border-bottom-left-radius:0;border-top-left-radius:0}.DatePicker_day__kGD0i.DatePicker_between__1Bifb{background-color:var(--active-color-alpha-100);border-radius:0}.DatePicker_day__kGD0i:hover{background-color:var(--accent-color-alpha-100)}";
4
+ var S = {"root":"DatePicker_root__hh-PP","day":"DatePicker_day__kGD0i","start":"DatePicker_start__qd0rW","end":"DatePicker_end__KYPnO","between":"DatePicker_between__1Bifb"};
5
5
  styleInject(css_248z);
6
6
 
7
7
  export { S as default };
@@ -1,3 +1,3 @@
1
1
  /// <reference types="react" />
2
2
  import * as T from './Calendar.types';
3
- export declare function Calendar({ value, onDayClick, renderDay, renderWeekDayLabel, renderMonthLabel, renderMonthesLabel, renderYearLabel, startOfWeek, weekendClassName, size, }: T.Props): JSX.Element;
3
+ export declare function Calendar({ className, value, onDayPointerDown, onDayPointerUp, renderDay, renderWeekDayLabel, renderMonthLabel, renderMonthesLabel, renderYearLabel, startOfWeek, weekendClassName, hideOtherMonthDays, size, }: T.Props): JSX.Element;
@@ -5,11 +5,14 @@ export type Day = Date & {
5
5
  };
6
6
  export type DayProps = {
7
7
  className: string;
8
- onClick: () => void;
8
+ onPointerDown: () => void;
9
+ onPointerUp: () => void;
9
10
  };
10
11
  export type Props = {
12
+ className?: string;
11
13
  value: Date;
12
- onDayClick: (value: Date) => void;
14
+ onDayPointerDown: (value: Date) => void;
15
+ onDayPointerUp: (value: Date) => void;
13
16
  startOfWeek?: number;
14
17
  size?: Size;
15
18
  renderDay?: (day: Day, dayProps: DayProps) => ReactNode;
@@ -18,4 +21,5 @@ export type Props = {
18
21
  renderMonthesLabel?: (month: number) => string;
19
22
  renderMonthLabel?: (month: number) => string;
20
23
  weekendClassName?: string;
24
+ hideOtherMonthDays?: boolean;
21
25
  };
@@ -0,0 +1,5 @@
1
+ import type { Date } from 'uilib/types';
2
+ export declare function isDateEqual(date1: Date, date2: Date): boolean;
3
+ export declare function isDateBefore(date1: Date, date2: Date): boolean;
4
+ export declare function isDateAfter(date1: Date, date2: Date): boolean;
5
+ export declare function isDateBetween(date: Date, startDate: Date, endDate: Date): boolean;
@@ -2,6 +2,7 @@ import type { Size, Date } from 'uilib/types';
2
2
  import type { Props as CalendarProps } from 'uilib/components/Calendar/Calendar.types';
3
3
  export type Value = Date | [Date, Date];
4
4
  export type Props = {
5
+ className?: string;
5
6
  value: Value;
6
7
  onChange: (value: Value) => void;
7
8
  size?: Size;
@@ -1,2 +1,3 @@
1
+ /// <reference types="react" />
1
2
  declare const _default: () => JSX.Element;
2
3
  export default _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homecode/ui",
3
- "version": "4.14.0",
3
+ "version": "4.16.0",
4
4
  "description": "React UI components library",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",