@homecode/ui 4.16.0 → 4.17.1
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.
- package/dist/esm/index.js +3 -0
- package/dist/esm/src/components/Calendar/Calendar.js +1 -1
- package/dist/esm/src/components/DatePicker/DatePicker.helpers.js +12 -1
- package/dist/esm/src/components/DatePicker/DatePicker.js +13 -9
- package/dist/esm/src/components/DatePickerInput/DatePickerInput.js +18 -0
- package/dist/esm/src/components/DatePickerInput/DatePickerInput.styl.js +7 -0
- package/dist/esm/src/components/Input/Input.js +2 -1
- package/dist/esm/src/components/InputFile/InputFile.js +1 -0
- package/dist/esm/src/components/Popup/Popup.js +3 -2
- package/dist/esm/src/tools/date.js +11 -0
- package/dist/esm/types/src/components/Calendar/Calendar.types.d.ts +4 -4
- package/dist/esm/types/src/components/DatePicker/DatePicker.helpers.d.ts +6 -0
- package/dist/esm/types/src/components/DatePicker/DatePicker.types.d.ts +3 -3
- package/dist/esm/types/src/components/DatePickerInput/DatePickerInput.d.ts +3 -0
- package/dist/esm/types/src/components/DatePickerInput/DatePickerInput.types.d.ts +12 -0
- package/dist/esm/types/src/components/Icon/Icon.example.d.ts +0 -1
- package/dist/esm/types/src/components/index.d.ts +1 -0
- package/dist/esm/types/src/tools/date.d.ts +6 -0
- package/dist/esm/types/src/tools/index.d.ts +1 -0
- package/dist/esm/types/src/types.d.ts +1 -0
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export { Calendar } from './src/components/Calendar/Calendar.js';
|
|
|
5
5
|
export { Checkbox } from './src/components/Checkbox/Checkbox.js';
|
|
6
6
|
export { Container } from './src/components/Container/Container.js';
|
|
7
7
|
export { DatePicker } from './src/components/DatePicker/DatePicker.js';
|
|
8
|
+
export { DatePickerInput } from './src/components/DatePickerInput/DatePickerInput.js';
|
|
8
9
|
export { DateTime, formatDate } from './src/components/DateTime/DateTime.js';
|
|
9
10
|
export { Draggable } from './src/components/Draggable/Draggable.js';
|
|
10
11
|
export { Expand } from './src/components/Expand/Expand.js';
|
|
@@ -44,6 +45,8 @@ export { env };
|
|
|
44
45
|
export { config } from './src/tools/config.js';
|
|
45
46
|
import * as array from './src/tools/array.js';
|
|
46
47
|
export { array };
|
|
48
|
+
import * as date from './src/tools/date.js';
|
|
49
|
+
export { date };
|
|
47
50
|
import * as string from './src/tools/string.js';
|
|
48
51
|
export { string };
|
|
49
52
|
import * as number from './src/tools/number.js';
|
|
@@ -50,7 +50,7 @@ function Calendar({ className, value, onDayPointerDown, onDayPointerUp, renderDa
|
|
|
50
50
|
// @ts-ignore
|
|
51
51
|
size: size, label: renderYearLabel?.(year) ?? 'Year', value: year,
|
|
52
52
|
// @ts-ignore
|
|
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
|
+
onChange: onYearChange, onBlur: onYearBlur }), jsx(Select, { className: S.month, size: size, label: renderMonthesLabel?.(month) ?? 'Month', options: monthOptions, value: month, onChange: val => setMonth(val), required: true, hideRequiredStar: true })] }), 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) => {
|
|
54
54
|
const className = cn(S.day, day.currentMonth && S.currMonth, isWeekend(weekdayIndex) && weekendClassName, isSameDay(day, value) && S.selected);
|
|
55
55
|
const dayProps = { className };
|
|
56
56
|
if (onDayPointerDown) {
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
function dateToString(date) {
|
|
2
|
+
return `${date.year}-${date.month}-${date.day}`;
|
|
3
|
+
}
|
|
4
|
+
function strigToDate(dateString) {
|
|
5
|
+
const [year, month, day] = dateString.split('-');
|
|
6
|
+
return {
|
|
7
|
+
year: Number(year),
|
|
8
|
+
month: Number(month),
|
|
9
|
+
day: Number(day),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
1
12
|
function isDateEqual(date1, date2) {
|
|
2
13
|
return (date1.year === date2.year &&
|
|
3
14
|
date1.month === date2.month &&
|
|
@@ -17,4 +28,4 @@ function isDateBetween(date, startDate, endDate) {
|
|
|
17
28
|
return isDateAfter(date, startDate) && isDateBefore(date, endDate);
|
|
18
29
|
}
|
|
19
30
|
|
|
20
|
-
export { isDateAfter, isDateBefore, isDateBetween, isDateEqual };
|
|
31
|
+
export { dateToString, isDateAfter, isDateBefore, isDateBetween, isDateEqual, strigToDate };
|
|
@@ -3,7 +3,7 @@ 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
|
+
import { dateToString, isDateAfter, strigToDate, isDateBetween, isDateEqual } from './DatePicker.helpers.js';
|
|
7
7
|
import S from './DatePicker.styl.js';
|
|
8
8
|
|
|
9
9
|
function DatePicker(props) {
|
|
@@ -11,32 +11,36 @@ function DatePicker(props) {
|
|
|
11
11
|
const isRange = Array.isArray(value);
|
|
12
12
|
const [isPicking, setIsPicking] = useState(false);
|
|
13
13
|
const onFirstDateChange = useCallback((val) => {
|
|
14
|
-
|
|
14
|
+
const valStr = dateToString(val);
|
|
15
|
+
onChange(isRange ? [valStr, value[1]] : valStr);
|
|
15
16
|
}, [value, onChange, isRange]);
|
|
16
17
|
const onPointerDown = () => setIsPicking(true);
|
|
17
18
|
const onPointerUp = () => setIsPicking(false);
|
|
18
19
|
const renderDay = useCallback((val, { className, ...props }) => {
|
|
19
20
|
const { day, year, month } = val;
|
|
21
|
+
const valStr = dateToString(val);
|
|
20
22
|
if (isRange && isPicking) {
|
|
21
23
|
props.onPointerOver = () => {
|
|
22
|
-
const newVal = isDateAfter(value[0], val)
|
|
23
|
-
? [
|
|
24
|
-
: [value[0],
|
|
24
|
+
const newVal = isDateAfter(strigToDate(value[0]), val)
|
|
25
|
+
? [valStr, value[0]]
|
|
26
|
+
: [value[0], valStr];
|
|
25
27
|
onChange(newVal);
|
|
26
28
|
};
|
|
27
29
|
}
|
|
28
30
|
const classes = [className, S.day];
|
|
29
31
|
if (isRange) {
|
|
30
|
-
|
|
32
|
+
const from = strigToDate(value[0]);
|
|
33
|
+
const to = strigToDate(value[1]);
|
|
34
|
+
if (isDateBetween(val, from, to))
|
|
31
35
|
classes.push(S.between);
|
|
32
|
-
if (isDateEqual(val,
|
|
36
|
+
if (isDateEqual(val, from))
|
|
33
37
|
classes.push(S.start);
|
|
34
|
-
if (isDateEqual(val,
|
|
38
|
+
if (isDateEqual(val, to))
|
|
35
39
|
classes.push(S.end);
|
|
36
40
|
}
|
|
37
41
|
return (createElement(Button, { ...props, variant: "clear", className: cn(classes), size: size, key: `${year}-${month}-${day}` }, day));
|
|
38
42
|
}, [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:
|
|
43
|
+
return (jsxs("div", { className: cn(S.root, props.className), onPointerDown: onPointerDown, onPointerUp: onPointerUp, children: [jsx(Calendar, { size: size, hideOtherMonthDays: isRange, ...calendarProps, renderDay: renderDay, value: strigToDate(isRange ? value[0] : value), onDayPointerDown: onFirstDateChange, onDayPointerUp: undefined }), isRange && (jsx(Calendar, { size: size, hideOtherMonthDays: isRange, ...calendarProps, renderDay: renderDay, value: strigToDate(value[1]), onDayPointerDown: val => onChange([value[0], dateToString(val)]), onDayPointerUp: val => onChange([value[0], dateToString(val)]) }))] }));
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
export { DatePicker };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import cn from 'classnames';
|
|
3
|
+
import { strToDate } from '../../tools/date.js';
|
|
4
|
+
import { DateTime } from '../DateTime/DateTime.js';
|
|
5
|
+
import { DatePicker } from '../DatePicker/DatePicker.js';
|
|
6
|
+
import { Button } from '../Button/Button.js';
|
|
7
|
+
import { Popup } from '../Popup/Popup.js';
|
|
8
|
+
import S from './DatePickerInput.styl.js';
|
|
9
|
+
|
|
10
|
+
function DatePickerInput(props) {
|
|
11
|
+
const { value, variant = 'default', size = 'm', popupProps, displayFormat = 'MMM Do YYYY', } = props;
|
|
12
|
+
const isRange = Array.isArray(value);
|
|
13
|
+
return (jsx(Popup, { size: size, focusControl: true, direction: "bottom-right", ...popupProps, trigger: jsx(Button, { variant: variant, size: size, children: isRange ? (jsxs(Fragment, { children: [jsx(DateTime, { value: strToDate(value[0]), format: displayFormat }), ' - ', jsx(DateTime, { value: strToDate(value[1]), format: displayFormat })] })) : (jsx(DateTime, { value: strToDate(value), format: displayFormat })) }), contentProps: {
|
|
14
|
+
className: cn(S.popupContent, isRange && S.range, S[`size-${size}`]),
|
|
15
|
+
}, content: jsx(DatePicker, { ...props, className: S.content, calendarProps: { className: S.calendar } }) }));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { DatePickerInput };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
|
|
2
|
+
|
|
3
|
+
var css_248z = ".DatePickerInput_popupContent__rcVHH{min-width:-moz-fit-content;min-width:fit-content}.DatePickerInput_content__yll-b{padding:.5em}.DatePickerInput_range__xWj9K .DatePickerInput_content__yll-b{display:flex;flex-direction:row;flex-wrap:nowrap;gap:1em}.DatePickerInput_range__xWj9K .DatePickerInput_calendar__vf0za{width:50%}.DatePickerInput_size-s__5t05o{border-radius:6px!important}.DatePickerInput_size-s__5t05o .DatePickerInput_content__yll-b{min-width:12em;padding:8px}.DatePickerInput_range__xWj9K.DatePickerInput_size-s__5t05o .DatePickerInput_content__yll-b{min-width:25em}.DatePickerInput_size-m__TTkHV{border-radius:9px!important}.DatePickerInput_size-m__TTkHV .DatePickerInput_content__yll-b{min-width:16em;padding:12px}.DatePickerInput_range__xWj9K.DatePickerInput_size-m__TTkHV .DatePickerInput_content__yll-b{min-width:33em}.DatePickerInput_size-l__-fWkE{border-radius:12px!important}.DatePickerInput_size-l__-fWkE .DatePickerInput_content__yll-b{min-width:20em;padding:14px}.DatePickerInput_range__xWj9K.DatePickerInput_size-l__-fWkE .DatePickerInput_content__yll-b{min-width:41em}";
|
|
4
|
+
var S = {"popupContent":"DatePickerInput_popupContent__rcVHH","content":"DatePickerInput_content__yll-b","range":"DatePickerInput_range__xWj9K","calendar":"DatePickerInput_calendar__vf0za","size-s":"DatePickerInput_size-s__5t05o","size-m":"DatePickerInput_size-m__TTkHV","size-l":"DatePickerInput_size-l__-fWkE"};
|
|
5
|
+
styleInject(css_248z);
|
|
6
|
+
|
|
7
|
+
export { S as default };
|
|
@@ -28,6 +28,7 @@ import '../Checkbox/Checkbox.styl.js';
|
|
|
28
28
|
import '../Container/Container.styl.js';
|
|
29
29
|
import '../DatePicker/DatePicker.styl.js';
|
|
30
30
|
import 'moment';
|
|
31
|
+
import '../DatePickerInput/DatePickerInput.styl.js';
|
|
31
32
|
import '../Draggable/Draggable.styl.js';
|
|
32
33
|
import '../Expand/Expand.styl.js';
|
|
33
34
|
import '../Form/Form.styl.js';
|
|
@@ -334,7 +335,7 @@ class Input extends Component {
|
|
|
334
335
|
const classes = cn(S.root, isTextArea && S.isTextArea, S[`size-${size}`], S[`variant-${variant}`], isFocused && S.isFocused, error && S.hasError, hasClear && S.hasClear, disabled && S.isDisabled, className);
|
|
335
336
|
return (
|
|
336
337
|
// @ts-ignore
|
|
337
|
-
jsxs("div", { className: classes, title: value, children: [jsxs("label", { className: S.main, children: [jsx("div", { className: S.border, suppressHydrationWarning: true, style: { clipPath: labelClipPath } }, "border"), this.renderAddon('left'), this.wrapControll(createElement(Control, { ...controlProps, className: cn(S.control, controlProps?.className), ref: this.inputRef, key: "control" })), isNumber && (jsxs("div", { className: S.numberArrows, children: [jsx(Button, { variant: "clear", onClick: () => this.onNumberWheel(1), children: jsx(Icon, { type: "chevronUp", size: size }) }), jsx(Button, { variant: "clear", onClick: () => this.onNumberWheel(-1), children: jsx(Icon, { type: "chevronDown", size: size }) })] })), isTextArea && controlProps.placeholder && (jsx("span", { className: S.placeholder, spellCheck: false, children: controlProps.placeholder })), jsx(Label, { className: S.label, size: size, isOnTop: isLabelOnTop, isError: Boolean(error), onClipPathChange: this.onLabelClipPathChange, children: label }, "label"), this.renderAddon('right'), required && jsx(RequiredStar, { size: size }, "required-star")] }, "main"), hasClear && !disabled && hasValue && (jsx(Button, { className: S.clearButton, variant: "clear", size: size, square: true, onClick: this.onClearPress, title: "", children: jsx(Icon, { className: S.clearIcon, size: size, type: "close" }) }, "clear")), !disabled && typeof error === 'string' && (jsx(AssistiveText, { variant: "danger", size: size, children: error }, "assistive-text"))] }));
|
|
338
|
+
jsxs("div", { className: classes, title: value, children: [jsxs("label", { className: S.main, children: [jsx("div", { className: S.border, suppressHydrationWarning: true, style: { clipPath: labelClipPath } }, "border"), this.renderAddon('left'), this.wrapControll(createElement(Control, { ...controlProps, className: cn(S.control, controlProps?.className), ref: this.inputRef, key: "control" })), isNumber && (jsxs("div", { className: S.numberArrows, children: [jsx(Button, { variant: "clear", onClick: () => this.onNumberWheel(1), tabIndex: -1, children: jsx(Icon, { type: "chevronUp", size: size }) }), jsx(Button, { variant: "clear", onClick: () => this.onNumberWheel(-1), tabIndex: -1, children: jsx(Icon, { type: "chevronDown", size: size }) })] })), isTextArea && controlProps.placeholder && (jsx("span", { className: S.placeholder, spellCheck: false, children: controlProps.placeholder })), jsx(Label, { className: S.label, size: size, isOnTop: isLabelOnTop, isError: Boolean(error), onClipPathChange: this.onLabelClipPathChange, children: label }, "label"), this.renderAddon('right'), required && jsx(RequiredStar, { size: size }, "required-star")] }, "main"), hasClear && !disabled && hasValue && (jsx(Button, { className: S.clearButton, variant: "clear", size: size, square: true, onClick: this.onClearPress, title: "", children: jsx(Icon, { className: S.clearIcon, size: size, type: "close" }) }, "clear")), !disabled && typeof error === 'string' && (jsx(AssistiveText, { variant: "danger", size: size, children: error }, "assistive-text"))] }));
|
|
338
339
|
}
|
|
339
340
|
}
|
|
340
341
|
|
|
@@ -31,6 +31,7 @@ import '../Checkbox/Checkbox.styl.js';
|
|
|
31
31
|
import '../Container/Container.styl.js';
|
|
32
32
|
import '../DatePicker/DatePicker.styl.js';
|
|
33
33
|
import 'moment';
|
|
34
|
+
import '../DatePickerInput/DatePickerInput.styl.js';
|
|
34
35
|
import { Draggable } from '../Draggable/Draggable.js';
|
|
35
36
|
import '../Expand/Expand.styl.js';
|
|
36
37
|
import '../Form/Form.styl.js';
|
|
@@ -242,7 +242,8 @@ class Popup extends Component {
|
|
|
242
242
|
return;
|
|
243
243
|
}
|
|
244
244
|
// if scrolling outside this popup - close it
|
|
245
|
-
if (!this.isPointerOver(e.target, S.content)
|
|
245
|
+
if (!this.isPointerOver(e.target, S.content) &&
|
|
246
|
+
!childs[this.id]?.length) {
|
|
246
247
|
this.needDropOffset = true;
|
|
247
248
|
this.close();
|
|
248
249
|
}
|
|
@@ -280,7 +281,7 @@ class Popup extends Component {
|
|
|
280
281
|
this.focused = false;
|
|
281
282
|
this.props.triggerProps?.onBlur?.(e);
|
|
282
283
|
// give time to fire clicks inside popup
|
|
283
|
-
this.timers.after(
|
|
284
|
+
this.timers.after(60, () => {
|
|
284
285
|
if (!this.isLastClickInside())
|
|
285
286
|
this.close();
|
|
286
287
|
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert ISO 8601 format ("YYYY-MM-DD") to Date object
|
|
3
|
+
* @param str
|
|
4
|
+
* @returns Date
|
|
5
|
+
*/
|
|
6
|
+
const strToDate = (str) => {
|
|
7
|
+
const [year, month, day] = str.split('-').map(Number);
|
|
8
|
+
return new Date(year, month - 1, day);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export { strToDate };
|
|
@@ -5,14 +5,14 @@ export type Day = Date & {
|
|
|
5
5
|
};
|
|
6
6
|
export type DayProps = {
|
|
7
7
|
className: string;
|
|
8
|
-
onPointerDown
|
|
9
|
-
onPointerUp
|
|
8
|
+
onPointerDown?: () => void;
|
|
9
|
+
onPointerUp?: () => void;
|
|
10
10
|
};
|
|
11
11
|
export type Props = {
|
|
12
12
|
className?: string;
|
|
13
13
|
value: Date;
|
|
14
|
-
onDayPointerDown
|
|
15
|
-
onDayPointerUp
|
|
14
|
+
onDayPointerDown?: (value: Date) => void;
|
|
15
|
+
onDayPointerUp?: (value: Date) => void;
|
|
16
16
|
startOfWeek?: number;
|
|
17
17
|
size?: Size;
|
|
18
18
|
renderDay?: (day: Day, dayProps: DayProps) => ReactNode;
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import type { Date } from 'uilib/types';
|
|
2
|
+
export declare function dateToString(date: Date): string;
|
|
3
|
+
export declare function strigToDate(dateString: string): {
|
|
4
|
+
year: number;
|
|
5
|
+
month: number;
|
|
6
|
+
day: number;
|
|
7
|
+
};
|
|
2
8
|
export declare function isDateEqual(date1: Date, date2: Date): boolean;
|
|
3
9
|
export declare function isDateBefore(date1: Date, date2: Date): boolean;
|
|
4
10
|
export declare function isDateAfter(date1: Date, date2: Date): boolean;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { Size
|
|
1
|
+
import type { Size } from 'uilib/types';
|
|
2
2
|
import type { Props as CalendarProps } from 'uilib/components/Calendar/Calendar.types';
|
|
3
|
-
export type Value =
|
|
3
|
+
export type Value = string | [string, string];
|
|
4
4
|
export type Props = {
|
|
5
5
|
className?: string;
|
|
6
6
|
value: Value;
|
|
7
7
|
onChange: (value: Value) => void;
|
|
8
8
|
size?: Size;
|
|
9
|
-
calendarProps?: CalendarProps
|
|
9
|
+
calendarProps?: Partial<CalendarProps>;
|
|
10
10
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Size, Variant } from 'uilib/types';
|
|
2
|
+
import type { Props as PopupProps } from 'uilib/components/Popup/Popup.types';
|
|
3
|
+
export type Value = string | [string, string];
|
|
4
|
+
export type Props = {
|
|
5
|
+
className?: string;
|
|
6
|
+
size?: Size;
|
|
7
|
+
displayFormat?: string;
|
|
8
|
+
value: Value;
|
|
9
|
+
onChange: (value: Value) => void;
|
|
10
|
+
variant?: Variant;
|
|
11
|
+
popupProps?: PopupProps;
|
|
12
|
+
};
|
|
@@ -5,6 +5,7 @@ export * from './Calendar/Calendar';
|
|
|
5
5
|
export * from './Checkbox/Checkbox';
|
|
6
6
|
export * from './Container/Container';
|
|
7
7
|
export * from './DatePicker/DatePicker';
|
|
8
|
+
export * from './DatePickerInput/DatePickerInput';
|
|
8
9
|
export * from './DateTime/DateTime';
|
|
9
10
|
export * from './Draggable/Draggable';
|
|
10
11
|
export * from './Expand/Expand';
|