torch-glare 1.1.4 → 1.1.5
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.
|
@@ -9,7 +9,7 @@ import { SimpleSelectValue, SimpleSelectItem } from "./SimpleSelect";
|
|
|
9
9
|
|
|
10
10
|
export type CalendarProps = React.ComponentProps<typeof DayPicker>
|
|
11
11
|
|
|
12
|
-
const
|
|
12
|
+
const Calendar = ({
|
|
13
13
|
className,
|
|
14
14
|
classNames,
|
|
15
15
|
captionLayout = "dropdown",
|
|
@@ -97,6 +97,6 @@ const Calender = ({
|
|
|
97
97
|
/>
|
|
98
98
|
)
|
|
99
99
|
}
|
|
100
|
-
|
|
100
|
+
Calendar.displayName = "Calendar"
|
|
101
101
|
|
|
102
|
-
export {
|
|
102
|
+
export { Calendar }
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import React, { useState, forwardRef, ForwardedRef, HTMLAttributes, useEffect, cloneElement, isValidElement } from 'react';
|
|
2
2
|
import { Popover, PopoverContent, PopoverTrigger } from './Popover';
|
|
3
|
-
import {
|
|
4
|
-
import { Input, Trilling } from './Input';
|
|
3
|
+
import { Calendar } from './Calendar';
|
|
5
4
|
import { ActionButton } from './ActionButton';
|
|
6
|
-
import { Group } from './Input'; import { DateRange } from 'react-day-picker';
|
|
7
5
|
import Picker, { PickerValue } from 'torch-react-mobile-picker';
|
|
8
6
|
|
|
9
7
|
import { applyTimeToDateValue, formatDateValueToString, TimePickerValue } from '../utils/dateFormat';
|
|
10
8
|
import { InputField } from './InputField';
|
|
9
|
+
import { DateRange } from 'react-day-picker';
|
|
11
10
|
|
|
12
|
-
export type CalendarProps = React.ComponentProps<typeof
|
|
11
|
+
export type CalendarProps = React.ComponentProps<typeof Calendar>
|
|
13
12
|
|
|
14
13
|
interface DatePickerProps extends HTMLAttributes<HTMLInputElement> {
|
|
15
14
|
mode?: "single" | "multiple" | "range";
|
|
@@ -101,7 +100,7 @@ export const DatePicker = forwardRef(({
|
|
|
101
100
|
}
|
|
102
101
|
</PopoverTrigger >
|
|
103
102
|
<PopoverContent data-theme="dark" className='!h-fit max-h-[fit-content] p-0 border-none rounded-[12px] flex flex-col sm:flex-row'>
|
|
104
|
-
<
|
|
103
|
+
<Calendar
|
|
105
104
|
{...calendarProps}
|
|
106
105
|
captionLayout={captionLayout}
|
|
107
106
|
showWeekNumber={showWeekNumber}
|
|
@@ -1,187 +1,187 @@
|
|
|
1
|
-
import { cloneElement, ComponentProps, forwardRef, isValidElement, useState, useEffect } from 'react';
|
|
2
|
-
import { getDaysInMonth } from 'date-fns';
|
|
3
|
-
import Picker from 'torch-react-mobile-picker';
|
|
4
|
-
import { Popover, PopoverContent, PopoverTrigger } from './Popover';
|
|
5
|
-
import { InputField } from './InputField';
|
|
6
|
-
import { ActionButton } from './ActionButton';
|
|
7
|
-
import { formatDateValueToString } from '@/utils/dateFormat';
|
|
8
|
-
|
|
9
|
-
function getDayArray(year: number, month: number): string[] {
|
|
10
|
-
const dayCount = getDaysInMonth(new Date(year, month - 1));
|
|
11
|
-
return Array.from({ length: dayCount }, (_, i) => String(i + 1).padStart(2, '0'));
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
interface SlideDatePickerProps extends Omit<ComponentProps<typeof InputField>, 'onChange'> {
|
|
15
|
-
onChange?: (e: any) => void;
|
|
16
|
-
theme?: "dark" | "light" | "default";
|
|
17
|
-
dateFormat?: string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
type SlideVlaues = {
|
|
21
|
-
year: string,
|
|
22
|
-
month: string,
|
|
23
|
-
day: string,
|
|
24
|
-
hour?: string,
|
|
25
|
-
minute?: string,
|
|
26
|
-
time?: string
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export const SlideDatePicker = forwardRef<HTMLInputElement, SlideDatePickerProps>((
|
|
30
|
-
{
|
|
31
|
-
theme = "dark",
|
|
32
|
-
onChange,
|
|
33
|
-
dateFormat = "yyyy/MM/dd",
|
|
34
|
-
children,
|
|
35
|
-
...props
|
|
36
|
-
}, forwardedRef) => {
|
|
37
|
-
|
|
38
|
-
const today = new Date();
|
|
39
|
-
const defaultPickerValue = {
|
|
40
|
-
year: String(today.getFullYear()),
|
|
41
|
-
month: String(today.getMonth() + 1).padStart(2, '0'),
|
|
42
|
-
day: String(today.getDate()).padStart(2, '0'),
|
|
43
|
-
hour: "00",
|
|
44
|
-
minute: "00",
|
|
45
|
-
time: "AM"
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const [pickerValue, setPickerValue] = useState<SlideVlaues>(defaultPickerValue);
|
|
49
|
-
const [date, setDate] = useState<Date>(new Date());
|
|
50
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
51
|
-
const currentYear = new Date().getFullYear();
|
|
52
|
-
const years = Array.from({ length: 200 }, (_, i) => `${currentYear - 100 + i}`);
|
|
53
|
-
const months = Array.from({ length: 12 }, (_, i) => String(i + 1).padStart(2, ''));
|
|
54
|
-
const days = getDayArray(Number(pickerValue.year), Number(pickerValue.month));
|
|
55
|
-
const monthsNames = [
|
|
56
|
-
"January", "February", "March", "April", "May", "June",
|
|
57
|
-
"July", "August", "September", "October", "November", "December",
|
|
58
|
-
];
|
|
59
|
-
|
|
60
|
-
const handlePickerChange = (newValue: SlideVlaues, key: string) => {
|
|
61
|
-
let { year, month, day, hour, minute, time } = newValue;
|
|
62
|
-
|
|
63
|
-
if (key === 'year' || key === 'month') {
|
|
64
|
-
const newDayArray = getDayArray(Number(year), Number(month));
|
|
65
|
-
day = newDayArray.includes(day as string) ? day : newDayArray[newDayArray.length - 1];
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const updatedValue = { year, month, day, hour, minute, time };
|
|
69
|
-
setPickerValue(updatedValue);
|
|
70
|
-
|
|
71
|
-
// Create a Date object from the updated value
|
|
72
|
-
const newDate = new Date(
|
|
73
|
-
Number(updatedValue.year),
|
|
74
|
-
Number(updatedValue.month) - 1, // Month is 0-indexed in JavaScript Date
|
|
75
|
-
Number(updatedValue.day)
|
|
76
|
-
);
|
|
77
|
-
setDate(newDate);
|
|
78
|
-
|
|
79
|
-
// Call the onChange callback with the Date object
|
|
80
|
-
if (onChange) {
|
|
81
|
-
onChange({
|
|
82
|
-
target: {
|
|
83
|
-
value: newDate
|
|
84
|
-
}
|
|
85
|
-
} as any);
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const formattedValue = formatDateValueToString(date, {
|
|
90
|
-
hour: pickerValue.hour ?? defaultPickerValue.hour,
|
|
91
|
-
minute: pickerValue.minute ?? defaultPickerValue.minute,
|
|
92
|
-
time: pickerValue.time ?? defaultPickerValue.time
|
|
93
|
-
}, dateFormat);
|
|
94
|
-
|
|
95
|
-
// Disable body scroll when popover is open
|
|
96
|
-
useEffect(() => {
|
|
97
|
-
if (isOpen) {
|
|
98
|
-
// Save the current overflow style
|
|
99
|
-
const originalOverflow = document.body.style.overflow;
|
|
100
|
-
document.body.style.overflow = 'hidden';
|
|
101
|
-
|
|
102
|
-
// Cleanup function to restore original overflow style
|
|
103
|
-
return () => {
|
|
104
|
-
document.body.style.overflow = originalOverflow;
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
}, [isOpen]);
|
|
108
|
-
|
|
109
|
-
useEffect(() => {
|
|
110
|
-
if (onChange) {
|
|
111
|
-
onChange({
|
|
112
|
-
target: {
|
|
113
|
-
value: date
|
|
114
|
-
}
|
|
115
|
-
} as any);
|
|
116
|
-
}
|
|
117
|
-
}, [formattedValue]);
|
|
118
|
-
|
|
119
|
-
return (
|
|
120
|
-
<Popover onOpenChange={setIsOpen}>
|
|
121
|
-
<PopoverTrigger asChild data-theme={theme} className='w-full flex-1' >
|
|
122
|
-
{
|
|
123
|
-
isValidElement(children) ?
|
|
124
|
-
cloneElement(children as React.ReactElement<HTMLInputElement>, {
|
|
125
|
-
value: (children as React.ReactElement<HTMLInputElement>).props.value ?? formattedValue,
|
|
126
|
-
type: "input",
|
|
127
|
-
readOnly: true
|
|
128
|
-
})
|
|
129
|
-
:
|
|
130
|
-
/* If the children is not a valid element, Show the default input */
|
|
131
|
-
<InputField
|
|
132
|
-
readOnly
|
|
133
|
-
type="input"
|
|
134
|
-
childrenSide={
|
|
135
|
-
<ActionButton type='button' size={"M"}>
|
|
136
|
-
<i className="ri-calendar-event-fill"></i>
|
|
137
|
-
</ActionButton>
|
|
138
|
-
}
|
|
139
|
-
{...props}
|
|
140
|
-
value={formattedValue}
|
|
141
|
-
ref={forwardedRef}
|
|
142
|
-
/>
|
|
143
|
-
}
|
|
144
|
-
</PopoverTrigger>
|
|
145
|
-
<PopoverContent data-theme={theme} dir="ltr" variant={props.variant} className="overflow-hidden w-[285px] flex justify-center items-center p-[6px] pt-[30px]">
|
|
146
|
-
<div className="flex justify-evenly items-center w-full absolute top-0 py-[6px]">
|
|
147
|
-
<p className="text-content-system-global-secondary typography-headers-medium-regular">Year</p>
|
|
148
|
-
<div className="flex justify-center items-center self-center">
|
|
149
|
-
<span className="h-[13px] w-[1px] bg-border-system-global-secondary rounded-[3px]"></span>
|
|
150
|
-
<p className="text-content-system-global-secondary typography-headers-medium-regular px-[18px]">Month</p>
|
|
151
|
-
<span className="h-[13px] w-[1px] bg-border-system-global-secondary rounded-[3px]"></span>
|
|
152
|
-
</div>
|
|
153
|
-
<p className="text-content-system-global-secondary typography-headers-medium-regular">Day</p>
|
|
154
|
-
</div>
|
|
155
|
-
<Picker
|
|
156
|
-
className="flex-1"
|
|
157
|
-
selectContainerClassName="bg-background-system-body-tertiary z-[-1] rounded-[8px]"
|
|
158
|
-
value={pickerValue}
|
|
159
|
-
onChange={handlePickerChange}
|
|
160
|
-
wheelMode="natural"
|
|
161
|
-
>
|
|
162
|
-
<Picker.Column name="year" >
|
|
163
|
-
{years.map((year) => (
|
|
164
|
-
<Picker.Item key={year} value={year}>
|
|
165
|
-
<div className="typography-display-small-semibold text-content-presentation-action-light-primary">{year}</div>
|
|
166
|
-
</Picker.Item>
|
|
167
|
-
))}
|
|
168
|
-
</Picker.Column>
|
|
169
|
-
<Picker.Column name="month">
|
|
170
|
-
{months.map((month, i) => (
|
|
171
|
-
<Picker.Item key={month} value={month}>
|
|
172
|
-
<div className="typography-display-small-semibold flex gap-1 whitespace-nowrap text-content-presentation-action-light-primary"> <p className='text-content-presentation-action-light-secondary'>{monthsNames[i].substring(0, 3)} - </p>{month}</div>
|
|
173
|
-
</Picker.Item>
|
|
174
|
-
))}
|
|
175
|
-
</Picker.Column>
|
|
176
|
-
<Picker.Column name="day">
|
|
177
|
-
{days.map((day) => (
|
|
178
|
-
<Picker.Item key={day} value={day}>
|
|
179
|
-
<div className="typography-display-small-semibold text-content-presentation-action-light-primary">{day}</div>
|
|
180
|
-
</Picker.Item>
|
|
181
|
-
))}
|
|
182
|
-
</Picker.Column>
|
|
183
|
-
</Picker>
|
|
184
|
-
</PopoverContent>
|
|
185
|
-
</Popover>
|
|
186
|
-
);
|
|
187
|
-
});
|
|
1
|
+
import { cloneElement, ComponentProps, forwardRef, isValidElement, useState, useEffect } from 'react';
|
|
2
|
+
import { getDaysInMonth } from 'date-fns';
|
|
3
|
+
import Picker from 'torch-react-mobile-picker';
|
|
4
|
+
import { Popover, PopoverContent, PopoverTrigger } from './Popover';
|
|
5
|
+
import { InputField } from './InputField';
|
|
6
|
+
import { ActionButton } from './ActionButton';
|
|
7
|
+
import { formatDateValueToString } from '@/utils/dateFormat';
|
|
8
|
+
|
|
9
|
+
function getDayArray(year: number, month: number): string[] {
|
|
10
|
+
const dayCount = getDaysInMonth(new Date(year, month - 1));
|
|
11
|
+
return Array.from({ length: dayCount }, (_, i) => String(i + 1).padStart(2, '0'));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface SlideDatePickerProps extends Omit<ComponentProps<typeof InputField>, 'onChange'> {
|
|
15
|
+
onChange?: (e: any) => void;
|
|
16
|
+
theme?: "dark" | "light" | "default";
|
|
17
|
+
dateFormat?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type SlideVlaues = {
|
|
21
|
+
year: string,
|
|
22
|
+
month: string,
|
|
23
|
+
day: string,
|
|
24
|
+
hour?: string,
|
|
25
|
+
minute?: string,
|
|
26
|
+
time?: string
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const SlideDatePicker = forwardRef<HTMLInputElement, SlideDatePickerProps>((
|
|
30
|
+
{
|
|
31
|
+
theme = "dark",
|
|
32
|
+
onChange,
|
|
33
|
+
dateFormat = "yyyy/MM/dd",
|
|
34
|
+
children,
|
|
35
|
+
...props
|
|
36
|
+
}, forwardedRef) => {
|
|
37
|
+
|
|
38
|
+
const today = new Date();
|
|
39
|
+
const defaultPickerValue = {
|
|
40
|
+
year: String(today.getFullYear()),
|
|
41
|
+
month: String(today.getMonth() + 1).padStart(2, '0'),
|
|
42
|
+
day: String(today.getDate()).padStart(2, '0'),
|
|
43
|
+
hour: "00",
|
|
44
|
+
minute: "00",
|
|
45
|
+
time: "AM"
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const [pickerValue, setPickerValue] = useState<SlideVlaues>(defaultPickerValue);
|
|
49
|
+
const [date, setDate] = useState<Date>(new Date());
|
|
50
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
51
|
+
const currentYear = new Date().getFullYear();
|
|
52
|
+
const years = Array.from({ length: 200 }, (_, i) => `${currentYear - 100 + i}`);
|
|
53
|
+
const months = Array.from({ length: 12 }, (_, i) => String(i + 1).padStart(2, ''));
|
|
54
|
+
const days = getDayArray(Number(pickerValue.year), Number(pickerValue.month));
|
|
55
|
+
const monthsNames = [
|
|
56
|
+
"January", "February", "March", "April", "May", "June",
|
|
57
|
+
"July", "August", "September", "October", "November", "December",
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
const handlePickerChange = (newValue: SlideVlaues, key: string) => {
|
|
61
|
+
let { year, month, day, hour, minute, time } = newValue;
|
|
62
|
+
|
|
63
|
+
if (key === 'year' || key === 'month') {
|
|
64
|
+
const newDayArray = getDayArray(Number(year), Number(month));
|
|
65
|
+
day = newDayArray.includes(day as string) ? day : newDayArray[newDayArray.length - 1];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const updatedValue = { year, month, day, hour, minute, time };
|
|
69
|
+
setPickerValue(updatedValue);
|
|
70
|
+
|
|
71
|
+
// Create a Date object from the updated value
|
|
72
|
+
const newDate = new Date(
|
|
73
|
+
Number(updatedValue.year),
|
|
74
|
+
Number(updatedValue.month) - 1, // Month is 0-indexed in JavaScript Date
|
|
75
|
+
Number(updatedValue.day)
|
|
76
|
+
);
|
|
77
|
+
setDate(newDate);
|
|
78
|
+
|
|
79
|
+
// Call the onChange callback with the Date object
|
|
80
|
+
if (onChange) {
|
|
81
|
+
onChange({
|
|
82
|
+
target: {
|
|
83
|
+
value: newDate
|
|
84
|
+
}
|
|
85
|
+
} as any);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const formattedValue = formatDateValueToString(date, {
|
|
90
|
+
hour: pickerValue.hour ?? defaultPickerValue.hour,
|
|
91
|
+
minute: pickerValue.minute ?? defaultPickerValue.minute,
|
|
92
|
+
time: pickerValue.time ?? defaultPickerValue.time
|
|
93
|
+
}, dateFormat);
|
|
94
|
+
|
|
95
|
+
// Disable body scroll when popover is open
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
if (isOpen) {
|
|
98
|
+
// Save the current overflow style
|
|
99
|
+
const originalOverflow = document.body.style.overflow;
|
|
100
|
+
document.body.style.overflow = 'hidden';
|
|
101
|
+
|
|
102
|
+
// Cleanup function to restore original overflow style
|
|
103
|
+
return () => {
|
|
104
|
+
document.body.style.overflow = originalOverflow;
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}, [isOpen]);
|
|
108
|
+
|
|
109
|
+
useEffect(() => {
|
|
110
|
+
if (onChange) {
|
|
111
|
+
onChange({
|
|
112
|
+
target: {
|
|
113
|
+
value: date
|
|
114
|
+
}
|
|
115
|
+
} as any);
|
|
116
|
+
}
|
|
117
|
+
}, [formattedValue]);
|
|
118
|
+
|
|
119
|
+
return (
|
|
120
|
+
<Popover onOpenChange={setIsOpen}>
|
|
121
|
+
<PopoverTrigger asChild data-theme={theme} className='w-full flex-1' >
|
|
122
|
+
{
|
|
123
|
+
isValidElement(children) ?
|
|
124
|
+
cloneElement(children as React.ReactElement<HTMLInputElement>, {
|
|
125
|
+
value: (children as React.ReactElement<HTMLInputElement>).props.value ?? formattedValue,
|
|
126
|
+
type: "input",
|
|
127
|
+
readOnly: true
|
|
128
|
+
})
|
|
129
|
+
:
|
|
130
|
+
/* If the children is not a valid element, Show the default input */
|
|
131
|
+
<InputField
|
|
132
|
+
readOnly
|
|
133
|
+
type="input"
|
|
134
|
+
childrenSide={
|
|
135
|
+
<ActionButton type='button' size={"M"}>
|
|
136
|
+
<i className="ri-calendar-event-fill"></i>
|
|
137
|
+
</ActionButton>
|
|
138
|
+
}
|
|
139
|
+
{...props}
|
|
140
|
+
value={formattedValue}
|
|
141
|
+
ref={forwardedRef}
|
|
142
|
+
/>
|
|
143
|
+
}
|
|
144
|
+
</PopoverTrigger>
|
|
145
|
+
<PopoverContent data-theme={theme} dir="ltr" variant={props.variant} className="overflow-hidden w-[285px] flex justify-center items-center p-[6px] pt-[30px]">
|
|
146
|
+
<div className="flex justify-evenly items-center w-full absolute top-0 py-[6px]">
|
|
147
|
+
<p className="text-content-system-global-secondary typography-headers-medium-regular">Year</p>
|
|
148
|
+
<div className="flex justify-center items-center self-center">
|
|
149
|
+
<span className="h-[13px] w-[1px] bg-border-system-global-secondary rounded-[3px]"></span>
|
|
150
|
+
<p className="text-content-system-global-secondary typography-headers-medium-regular px-[18px]">Month</p>
|
|
151
|
+
<span className="h-[13px] w-[1px] bg-border-system-global-secondary rounded-[3px]"></span>
|
|
152
|
+
</div>
|
|
153
|
+
<p className="text-content-system-global-secondary typography-headers-medium-regular">Day</p>
|
|
154
|
+
</div>
|
|
155
|
+
<Picker
|
|
156
|
+
className="flex-1"
|
|
157
|
+
selectContainerClassName="bg-background-system-body-tertiary z-[-1] rounded-[8px]"
|
|
158
|
+
value={pickerValue}
|
|
159
|
+
onChange={handlePickerChange}
|
|
160
|
+
wheelMode="natural"
|
|
161
|
+
>
|
|
162
|
+
<Picker.Column name="year" >
|
|
163
|
+
{years.map((year) => (
|
|
164
|
+
<Picker.Item key={year} value={year}>
|
|
165
|
+
<div className="typography-display-small-semibold text-content-presentation-action-light-primary">{year}</div>
|
|
166
|
+
</Picker.Item>
|
|
167
|
+
))}
|
|
168
|
+
</Picker.Column>
|
|
169
|
+
<Picker.Column name="month">
|
|
170
|
+
{months.map((month, i) => (
|
|
171
|
+
<Picker.Item key={month} value={month}>
|
|
172
|
+
<div className="typography-display-small-semibold flex gap-1 whitespace-nowrap text-content-presentation-action-light-primary"> <p className='text-content-presentation-action-light-secondary'>{monthsNames[i].substring(0, 3)} - </p>{month}</div>
|
|
173
|
+
</Picker.Item>
|
|
174
|
+
))}
|
|
175
|
+
</Picker.Column>
|
|
176
|
+
<Picker.Column name="day">
|
|
177
|
+
{days.map((day) => (
|
|
178
|
+
<Picker.Item key={day} value={day}>
|
|
179
|
+
<div className="typography-display-small-semibold text-content-presentation-action-light-primary">{day}</div>
|
|
180
|
+
</Picker.Item>
|
|
181
|
+
))}
|
|
182
|
+
</Picker.Column>
|
|
183
|
+
</Picker>
|
|
184
|
+
</PopoverContent>
|
|
185
|
+
</Popover>
|
|
186
|
+
);
|
|
187
|
+
});
|