torch-glare 1.1.5 → 1.1.7
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/src/shared/getDependenciesAndInstallNestedComponents.js +1 -1
- package/dist/src/shared/getDependenciesAndInstallNestedComponents.js.map +1 -1
- package/lib/components/BadgeField.tsx +51 -44
- package/lib/components/Calendar.tsx +2 -2
- package/lib/components/DatePicker.tsx +145 -99
- package/lib/components/Input.tsx +6 -5
- package/lib/components/InputField.tsx +6 -2
- package/lib/components/LinkButton.tsx +1 -1
- package/lib/components/RadioCard.tsx +1 -1
- package/lib/components/SimpleSelect.tsx +1 -1
- package/lib/components/SlideDatePicker.tsx +21 -15
- package/lib/components/Textarea.tsx +0 -1
- package/lib/components/Toast.tsx +87 -0
- package/package.json +1 -1
- /package/lib/hooks/{useActiveTreeItem.tsx → useActiveTreeItem.ts} +0 -0
- /package/lib/hooks/{useClickOutside.tsx → useClickOutside.ts} +0 -0
- /package/lib/hooks/{useResize.tsx → useResize.ts} +0 -0
- /package/lib/hooks/{useTagSelection.tsx → useTagSelection.ts} +0 -0
|
@@ -29,7 +29,7 @@ export function getDependenciesAndInstallNestedComponents(componentPath, install
|
|
|
29
29
|
else if (moduleName &&
|
|
30
30
|
moduleName.startsWith("../hooks") &&
|
|
31
31
|
!installedDependencies.has(moduleName)) {
|
|
32
|
-
addHook(moduleName.slice(9) + ".
|
|
32
|
+
addHook(moduleName.slice(9) + ".ts");
|
|
33
33
|
}
|
|
34
34
|
// install required nested components
|
|
35
35
|
else if (moduleName &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getDependenciesAndInstallNestedComponents.js","sourceRoot":"","sources":["../../../cli/src/shared/getDependenciesAndInstallNestedComponents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAEzC;;;;;GAKG;AAEH,MAAM,UAAU,yCAAyC,CACrD,aAAqB,EACrB,qBAAkC;IAElC,MAAM,gBAAgB,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACjE,MAAM,WAAW,GAAG,yCAAyC,CAAC;IAC9D,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAU,CAAC;IAEhD,IAAI,KAAK,CAAC;IACV,OAAO,CAAC,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC3D,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAE5B,sCAAsC;QACtC,IAAI,UAAU,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YACtF,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC1C,CAAC;QAED,oCAAoC;aAC/B,IACD,UAAU;YACV,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC;YACjC,CAAC,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,EACxC,CAAC;YACC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;QACzC,CAAC;QAED,oCAAoC;aAC/B,IACD,UAAU;YACV,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC;YACjC,CAAC,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,EACxC,CAAC;YACC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,
|
|
1
|
+
{"version":3,"file":"getDependenciesAndInstallNestedComponents.js","sourceRoot":"","sources":["../../../cli/src/shared/getDependenciesAndInstallNestedComponents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAEzC;;;;;GAKG;AAEH,MAAM,UAAU,yCAAyC,CACrD,aAAqB,EACrB,qBAAkC;IAElC,MAAM,gBAAgB,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACjE,MAAM,WAAW,GAAG,yCAAyC,CAAC;IAC9D,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAU,CAAC;IAEhD,IAAI,KAAK,CAAC;IACV,OAAO,CAAC,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC3D,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAE5B,sCAAsC;QACtC,IAAI,UAAU,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YACtF,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC1C,CAAC;QAED,oCAAoC;aAC/B,IACD,UAAU;YACV,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC;YACjC,CAAC,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,EACxC,CAAC;YACC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;QACzC,CAAC;QAED,oCAAoC;aAC/B,IACD,UAAU;YACV,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC;YACjC,CAAC,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,EACxC,CAAC;YACC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;QACzC,CAAC;QACD,qCAAqC;aAChC,IACD,UAAU;YACV,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC;gBACxB,CAAC,UAAU,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;YAC5C,CAAC,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,EACxC,CAAC;YACC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;QACtC,CAAC;QACD,0CAA0C;aACrC,IACD,UAAU;YACV,UAAU,CAAC,UAAU,CAAC,eAAe,CAAC;YACtC,CAAC,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,EACxC,CAAC;YACC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC;QACvC,CAAC;IACL,CAAC;IAED,OAAO,qBAAqB,CAAC;AACjC,CAAC"}
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
forwardRef,
|
|
4
4
|
InputHTMLAttributes,
|
|
5
5
|
ReactNode,
|
|
6
|
+
useEffect,
|
|
6
7
|
useRef,
|
|
7
8
|
useState,
|
|
8
9
|
} from "react";
|
|
@@ -15,7 +16,6 @@ import { useClickOutside } from "../hooks/useClickOutside";
|
|
|
15
16
|
import { Badge } from "./Badge";
|
|
16
17
|
import { Tag, useTagSelection } from "../hooks/useTagSelection";
|
|
17
18
|
|
|
18
|
-
|
|
19
19
|
interface Props
|
|
20
20
|
extends Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "variant"> {
|
|
21
21
|
size?: "XS" | "S" | "M"; // this is used to change the size style of the component
|
|
@@ -26,13 +26,12 @@ interface Props
|
|
|
26
26
|
toolTipSide?: ToolTipSide;
|
|
27
27
|
label?: string;
|
|
28
28
|
required?: boolean;
|
|
29
|
-
theme?: Themes
|
|
30
|
-
actionButton?: ReactNode
|
|
31
|
-
tags: Tag[]
|
|
32
|
-
onValueChange?: (tags: Tag[]) => void
|
|
29
|
+
theme?: Themes;
|
|
30
|
+
actionButton?: ReactNode;
|
|
31
|
+
tags: Tag[];
|
|
32
|
+
onValueChange?: (tags: Tag[]) => void;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
|
|
36
35
|
export const BadgeField = forwardRef<HTMLInputElement, Props>(
|
|
37
36
|
(
|
|
38
37
|
{
|
|
@@ -48,7 +47,6 @@ export const BadgeField = forwardRef<HTMLInputElement, Props>(
|
|
|
48
47
|
actionButton,
|
|
49
48
|
theme,
|
|
50
49
|
tags,
|
|
51
|
-
onValueChange,
|
|
52
50
|
children,
|
|
53
51
|
...props
|
|
54
52
|
},
|
|
@@ -62,7 +60,8 @@ export const BadgeField = forwardRef<HTMLInputElement, Props>(
|
|
|
62
60
|
if (
|
|
63
61
|
!inputGroupRef?.current?.contains(e?.target as Node) &&
|
|
64
62
|
!popoverContentRef?.current?.contains(e?.target as Node)
|
|
65
|
-
)
|
|
63
|
+
)
|
|
64
|
+
setIsPopoverOpen(false);
|
|
66
65
|
else setIsPopoverOpen(true);
|
|
67
66
|
});
|
|
68
67
|
|
|
@@ -79,7 +78,16 @@ export const BadgeField = forwardRef<HTMLInputElement, Props>(
|
|
|
79
78
|
focusedPopoverIndex,
|
|
80
79
|
isPopoverOpen,
|
|
81
80
|
setIsPopoverOpen,
|
|
82
|
-
|
|
81
|
+
searchTags
|
|
82
|
+
} = useTagSelection({
|
|
83
|
+
Tags: tags,
|
|
84
|
+
onTagsChange: (e) => props.onChange?.({
|
|
85
|
+
target: {
|
|
86
|
+
value: e
|
|
87
|
+
}
|
|
88
|
+
} as any),
|
|
89
|
+
inputRef
|
|
90
|
+
});
|
|
83
91
|
|
|
84
92
|
return (
|
|
85
93
|
<Popover open={isPopoverOpen}>
|
|
@@ -88,8 +96,7 @@ export const BadgeField = forwardRef<HTMLInputElement, Props>(
|
|
|
88
96
|
open={errorMessage !== undefined}
|
|
89
97
|
text={errorMessage}
|
|
90
98
|
>
|
|
91
|
-
<PopoverTrigger asChild
|
|
92
|
-
>
|
|
99
|
+
<PopoverTrigger asChild>
|
|
93
100
|
<Group
|
|
94
101
|
error={errorMessage !== undefined}
|
|
95
102
|
onTable={onTable}
|
|
@@ -102,44 +109,42 @@ export const BadgeField = forwardRef<HTMLInputElement, Props>(
|
|
|
102
109
|
onFocus={(e: any) => {
|
|
103
110
|
setDropDownListWidth(e.currentTarget.offsetWidth);
|
|
104
111
|
}}
|
|
105
|
-
className={cn(
|
|
112
|
+
className={cn(
|
|
113
|
+
"flex gap-1 flex-row w-full relative p-1 flex-nowrap overflow-hidden justify-end items-center",
|
|
106
114
|
{
|
|
107
115
|
"flex-wrap justify-start": isPopoverOpen,
|
|
116
|
+
"h-fit": isPopoverOpen,
|
|
108
117
|
},
|
|
109
118
|
className
|
|
110
119
|
)}
|
|
111
120
|
>
|
|
112
|
-
{icon &&
|
|
113
|
-
<Icon >
|
|
114
|
-
{icon}
|
|
115
|
-
</Icon>
|
|
116
|
-
)}
|
|
121
|
+
{icon && <Icon>{icon}</Icon>}
|
|
117
122
|
|
|
118
|
-
{
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
123
|
+
{selectedTagsStack.map((tag, index) => (
|
|
124
|
+
<Badge
|
|
125
|
+
key={tag.id}
|
|
126
|
+
size={size}
|
|
127
|
+
variant={tag.variant as any}
|
|
128
|
+
label={tag.name}
|
|
129
|
+
isSelected={true}
|
|
130
|
+
onUnselect={() => handleUnselectTag(tag.id)}
|
|
131
|
+
className={
|
|
132
|
+
focusedTagIndex === index ? "ring-2 ring-blue-500" : ""
|
|
133
|
+
}
|
|
134
|
+
tabIndex={focusedTagIndex === index ? 0 : -1}
|
|
135
|
+
/>
|
|
136
|
+
))}
|
|
132
137
|
|
|
133
138
|
<Input
|
|
134
139
|
{...props}
|
|
140
|
+
value={searchTags}
|
|
135
141
|
onChange={(e) => {
|
|
136
|
-
|
|
137
|
-
filterTagsBySearch(e.target.value)
|
|
142
|
+
filterTagsBySearch(e.target.value);
|
|
138
143
|
}}
|
|
139
144
|
onFocus={(e) => {
|
|
140
|
-
props.onFocus?.(e)
|
|
145
|
+
props.onFocus?.(e);
|
|
141
146
|
setFocusedTagIndex(null);
|
|
142
|
-
setIsPopoverOpen(true)
|
|
147
|
+
setIsPopoverOpen(true);
|
|
143
148
|
}}
|
|
144
149
|
ref={inputRef}
|
|
145
150
|
className={cn(
|
|
@@ -151,13 +156,12 @@ export const BadgeField = forwardRef<HTMLInputElement, Props>(
|
|
|
151
156
|
}
|
|
152
157
|
)}
|
|
153
158
|
/>
|
|
154
|
-
{
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
159
|
+
{actionButton && (
|
|
160
|
+
<Trilling className="py-0">
|
|
161
|
+
{/* Keep the ActionButton right aligned */}
|
|
162
|
+
{actionButton}
|
|
163
|
+
</Trilling>
|
|
164
|
+
)}
|
|
161
165
|
</Group>
|
|
162
166
|
</PopoverTrigger>
|
|
163
167
|
</Tooltip>
|
|
@@ -178,13 +182,16 @@ export const BadgeField = forwardRef<HTMLInputElement, Props>(
|
|
|
178
182
|
variant={tag.variant as any}
|
|
179
183
|
label={tag.name}
|
|
180
184
|
onClick={() => handleSelectTag(tag.id)}
|
|
181
|
-
className={`outline-none ${focusedPopoverIndex === index ? "ring-2 ring-blue-500" : ""
|
|
185
|
+
className={`outline-none ${focusedPopoverIndex === index ? "ring-2 ring-blue-500" : ""
|
|
186
|
+
} ${index !== 0 ? "mt-1" : ""}`}
|
|
182
187
|
tabIndex={focusedPopoverIndex === index ? 0 : -1}
|
|
183
188
|
/>
|
|
184
189
|
))
|
|
185
190
|
) : (
|
|
186
191
|
<div className="text-sm text-gray-500 py-1 px-2">
|
|
187
|
-
{tags.length === 0
|
|
192
|
+
{tags.length === 0
|
|
193
|
+
? "All tags selected"
|
|
194
|
+
: "No matching tags found"}
|
|
188
195
|
</div>
|
|
189
196
|
)}
|
|
190
197
|
</>
|
|
@@ -86,8 +86,8 @@ const Calendar = ({
|
|
|
86
86
|
range_start: `rounded-l-[8px] bg-background-system-action-secondary-hover`,
|
|
87
87
|
range_end: `rounded-r-[8px] bg-background-system-action-secondary-hover`,
|
|
88
88
|
range_middle: `bg-background-system-action-secondary-hover [&_button]:!border-none [&_button]:!bg-transparent`,
|
|
89
|
-
weekdays: `text-content-presentation-global-
|
|
90
|
-
week_number: `text-content-presentation-global-
|
|
89
|
+
weekdays: `text-content-presentation-global-primary text-[12px]`,
|
|
90
|
+
week_number: `text-content-presentation-global-primary text-[12px] px-1`,
|
|
91
91
|
month_caption: `flex items-center justify-center`,
|
|
92
92
|
caption_label: `text-content-presentation-global-primary text-[14px] pt-[2px]`,
|
|
93
93
|
months: `flex items-end justify-center gap-4 flex-wrap`,
|
|
@@ -1,14 +1,28 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import React, {
|
|
2
|
+
useState,
|
|
3
|
+
forwardRef,
|
|
4
|
+
ForwardedRef,
|
|
5
|
+
HTMLAttributes,
|
|
6
|
+
useEffect,
|
|
7
|
+
cloneElement,
|
|
8
|
+
isValidElement,
|
|
9
|
+
useRef,
|
|
10
|
+
Ref,
|
|
11
|
+
} from "react";
|
|
12
|
+
import { Popover, PopoverContent, PopoverTrigger } from "./Popover";
|
|
13
|
+
import { Calendar } from "./Calendar";
|
|
14
|
+
import { ActionButton } from "./ActionButton";
|
|
15
|
+
import { DateRange } from "react-day-picker";
|
|
16
|
+
import Picker from "torch-react-mobile-picker";
|
|
6
17
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
18
|
+
import {
|
|
19
|
+
applyTimeToDateValue,
|
|
20
|
+
formatDateValueToString,
|
|
21
|
+
TimePickerValue,
|
|
22
|
+
} from "../utils/dateFormat";
|
|
23
|
+
import { InputField } from "./InputField";
|
|
10
24
|
|
|
11
|
-
export type CalendarProps = React.ComponentProps<typeof Calendar
|
|
25
|
+
export type CalendarProps = React.ComponentProps<typeof Calendar>;
|
|
12
26
|
|
|
13
27
|
interface DatePickerProps extends HTMLAttributes<HTMLInputElement> {
|
|
14
28
|
mode?: "single" | "multiple" | "range";
|
|
@@ -21,75 +35,96 @@ interface DatePickerProps extends HTMLAttributes<HTMLInputElement> {
|
|
|
21
35
|
dateFormat?: string;
|
|
22
36
|
calendarProps?: CalendarProps;
|
|
23
37
|
timePicker?: boolean;
|
|
38
|
+
value?: any;
|
|
24
39
|
}
|
|
25
40
|
|
|
26
|
-
export const DatePicker = forwardRef(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
export const DatePicker = forwardRef(
|
|
42
|
+
(
|
|
43
|
+
{
|
|
44
|
+
size = "M",
|
|
45
|
+
min,
|
|
46
|
+
max,
|
|
47
|
+
mode = "single",
|
|
48
|
+
onChange,
|
|
49
|
+
showWeekNumber = false,
|
|
50
|
+
captionLayout = "dropdown",
|
|
51
|
+
dateFormat = "yyyy/MM/dd",
|
|
52
|
+
calendarProps,
|
|
53
|
+
timePicker = false,
|
|
54
|
+
children,
|
|
55
|
+
value = new Date(),
|
|
56
|
+
...props
|
|
57
|
+
}: DatePickerProps,
|
|
58
|
+
ref: ForwardedRef<HTMLInputElement>
|
|
59
|
+
) => {
|
|
60
|
+
const initialDate =
|
|
61
|
+
mode == "multiple"
|
|
62
|
+
? Array.isArray(value)
|
|
63
|
+
? value
|
|
64
|
+
: [value]
|
|
65
|
+
: mode == "range"
|
|
66
|
+
? { from: value, to: value }
|
|
67
|
+
: value;
|
|
68
|
+
const [date, setDate] = useState<Date[] | Date | DateRange | undefined>(initialDate);
|
|
69
|
+
const [pickerValue, setPickerValue] = useState<TimePickerValue>({
|
|
70
|
+
hour: (date instanceof Date ? date.getHours() : 12).toString(),
|
|
71
|
+
minute: (date instanceof Date ? date.getMinutes() : 0)
|
|
72
|
+
.toString()
|
|
73
|
+
.padStart(2, "0"),
|
|
74
|
+
time: date instanceof Date && date.getHours() < 12 ? "AM" : "PM",
|
|
75
|
+
});
|
|
76
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
77
|
+
const triggerRef = useRef<HTMLButtonElement>(null);
|
|
41
78
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
79
|
+
// Call the onChange function when the date or picker value changes
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
onChange?.({
|
|
82
|
+
target: {
|
|
83
|
+
value: date,
|
|
84
|
+
},
|
|
85
|
+
} as any);
|
|
86
|
+
}, [date, pickerValue]);
|
|
50
87
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
} as any);
|
|
58
|
-
}, [date, pickerValue]);
|
|
59
|
-
|
|
60
|
-
// Disable body scroll when popover is open
|
|
61
|
-
useEffect(() => {
|
|
62
|
-
if (isOpen) {
|
|
63
|
-
// Save the current overflow style
|
|
64
|
-
const originalOverflow = document.body.style.overflow;
|
|
65
|
-
document.body.style.overflow = 'hidden';
|
|
88
|
+
// Disable body scroll when popover is open
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
if (isOpen) {
|
|
91
|
+
// Save the current overflow style
|
|
92
|
+
const originalOverflow = document.body.style.overflow;
|
|
93
|
+
document.body.style.overflow = "hidden";
|
|
66
94
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
95
|
+
// Cleanup function to restore original overflow style
|
|
96
|
+
return () => {
|
|
97
|
+
document.body.style.overflow = originalOverflow;
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}, [isOpen]);
|
|
101
|
+
const formattedValue = formatDateValueToString(
|
|
102
|
+
date,
|
|
103
|
+
pickerValue,
|
|
104
|
+
dateFormat
|
|
105
|
+
);
|
|
74
106
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
isValidElement(children) ?
|
|
107
|
+
return (
|
|
108
|
+
<Popover onOpenChange={setIsOpen}>
|
|
109
|
+
<PopoverTrigger ref={triggerRef} asChild>
|
|
110
|
+
{/* Clone the children element and pass the formatted value to the input element */}
|
|
111
|
+
{isValidElement(children) ? (
|
|
81
112
|
cloneElement(children as React.ReactElement<HTMLInputElement>, {
|
|
82
|
-
value:
|
|
113
|
+
value:
|
|
114
|
+
(children as React.ReactElement<HTMLInputElement>).props
|
|
115
|
+
.value ?? formattedValue,
|
|
83
116
|
type: "input",
|
|
84
|
-
readOnly: true
|
|
117
|
+
readOnly: true,
|
|
85
118
|
})
|
|
86
|
-
|
|
119
|
+
) : (
|
|
87
120
|
/* If the children is not a valid element, Show the default input */
|
|
88
121
|
<InputField
|
|
89
122
|
readOnly
|
|
90
123
|
type="input"
|
|
91
124
|
childrenSide={
|
|
92
|
-
<ActionButton type=
|
|
125
|
+
<ActionButton type="button" size={"M"} onClick={() => {
|
|
126
|
+
triggerRef.current?.click();
|
|
127
|
+
}}>
|
|
93
128
|
<i className="ri-calendar-event-fill"></i>
|
|
94
129
|
</ActionButton>
|
|
95
130
|
}
|
|
@@ -97,39 +132,41 @@ export const DatePicker = forwardRef(({
|
|
|
97
132
|
value={formattedValue}
|
|
98
133
|
ref={ref}
|
|
99
134
|
/>
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
/>
|
|
115
|
-
{timePicker && (
|
|
116
|
-
<TimePicker
|
|
117
|
-
value={pickerValue}
|
|
118
|
-
onChange={(value: TimePickerValue) => {
|
|
119
|
-
setPickerValue(value);
|
|
120
|
-
setDate(applyTimeToDateValue(date, value));
|
|
135
|
+
)}
|
|
136
|
+
</PopoverTrigger>
|
|
137
|
+
<PopoverContent
|
|
138
|
+
data-theme="dark"
|
|
139
|
+
className="!h-fit max-h-[fit-content] p-0 border-none rounded-[12px] flex flex-col sm:flex-row "
|
|
140
|
+
>
|
|
141
|
+
<Calendar
|
|
142
|
+
{...calendarProps}
|
|
143
|
+
captionLayout={captionLayout}
|
|
144
|
+
showWeekNumber={showWeekNumber}
|
|
145
|
+
mode={mode as any}
|
|
146
|
+
selected={date as any}
|
|
147
|
+
onSelect={(e: any) => {
|
|
148
|
+
setDate(applyTimeToDateValue(e, pickerValue));
|
|
121
149
|
}}
|
|
150
|
+
min={mode != "single" ? min : undefined}
|
|
151
|
+
max={mode != "single" ? max : undefined}
|
|
122
152
|
/>
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
153
|
+
{timePicker && (
|
|
154
|
+
<TimePicker
|
|
155
|
+
value={pickerValue}
|
|
156
|
+
onChange={(value: TimePickerValue) => {
|
|
157
|
+
setPickerValue(value);
|
|
158
|
+
setDate(applyTimeToDateValue(date, value));
|
|
159
|
+
}}
|
|
160
|
+
/>
|
|
161
|
+
)}
|
|
162
|
+
</PopoverContent>
|
|
163
|
+
</Popover>
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
);
|
|
128
167
|
|
|
129
168
|
DatePicker.displayName = "DatePicker";
|
|
130
169
|
|
|
131
|
-
|
|
132
|
-
|
|
133
170
|
interface TimePickerProps {
|
|
134
171
|
value: TimePickerValue;
|
|
135
172
|
onChange: (value: TimePickerValue) => void;
|
|
@@ -137,7 +174,7 @@ interface TimePickerProps {
|
|
|
137
174
|
|
|
138
175
|
const TimePicker = ({ value, onChange }: TimePickerProps) => {
|
|
139
176
|
return (
|
|
140
|
-
<div className=
|
|
177
|
+
<div className="relative w-full sm:w-[189px]" data-theme="dark">
|
|
141
178
|
<Picker
|
|
142
179
|
className="flex-1"
|
|
143
180
|
selectContainerClassName="bg-background-system-body-tertiary z-[-1] rounded-[8px]"
|
|
@@ -147,11 +184,18 @@ const TimePicker = ({ value, onChange }: TimePickerProps) => {
|
|
|
147
184
|
}}
|
|
148
185
|
wheelMode="normal"
|
|
149
186
|
>
|
|
150
|
-
<span className=
|
|
187
|
+
<span className="absolute left-0 top-1/2 -translate-y-1/2 w-full h-[20px] flex justify-center items-center text-white text-[30px] pr-[55px] pb-[5px]">
|
|
188
|
+
:
|
|
189
|
+
</span>
|
|
151
190
|
<Picker.Column name="hour">
|
|
152
191
|
{Array.from({ length: 12 }, (_, i) => i + 1).map((hour) => (
|
|
153
192
|
<Picker.Item key={hour + "hour"} value={hour}>
|
|
154
|
-
<div className="typography-display-small-semibold flex gap-1 whitespace-nowrap text-content-presentation-global-primary pl-[25px]">
|
|
193
|
+
<div className="typography-display-small-semibold flex gap-1 whitespace-nowrap text-content-presentation-global-primary pl-[25px]">
|
|
194
|
+
{" "}
|
|
195
|
+
<p className="text-content-presentation-global-primary">
|
|
196
|
+
{hour}
|
|
197
|
+
</p>
|
|
198
|
+
</div>
|
|
155
199
|
</Picker.Item>
|
|
156
200
|
))}
|
|
157
201
|
</Picker.Column>
|
|
@@ -159,7 +203,7 @@ const TimePicker = ({ value, onChange }: TimePickerProps) => {
|
|
|
159
203
|
{Array.from({ length: 60 }, (_, i) => i).map((minute) => (
|
|
160
204
|
<Picker.Item key={minute + "minute"} value={minute}>
|
|
161
205
|
<div className="typography-display-small-semibold text-content-presentation-global-primary">
|
|
162
|
-
{minute.toString().padStart(2,
|
|
206
|
+
{minute.toString().padStart(2, "0")}
|
|
163
207
|
</div>
|
|
164
208
|
</Picker.Item>
|
|
165
209
|
))}
|
|
@@ -167,11 +211,13 @@ const TimePicker = ({ value, onChange }: TimePickerProps) => {
|
|
|
167
211
|
<Picker.Column name="time">
|
|
168
212
|
{["AM", "PM"].map((time) => (
|
|
169
213
|
<Picker.Item key={time + "time"} value={time}>
|
|
170
|
-
<div className="typography-display-small-semibold text-content-presentation-global-primary pr-[30px]">
|
|
214
|
+
<div className="typography-display-small-semibold text-content-presentation-global-primary pr-[30px]">
|
|
215
|
+
{time}
|
|
216
|
+
</div>
|
|
171
217
|
</Picker.Item>
|
|
172
218
|
))}
|
|
173
219
|
</Picker.Column>
|
|
174
220
|
</Picker>
|
|
175
221
|
</div>
|
|
176
|
-
)
|
|
177
|
-
}
|
|
222
|
+
);
|
|
223
|
+
};
|
package/lib/components/Input.tsx
CHANGED
|
@@ -45,13 +45,14 @@ export const Icon = ({ children, className }: IconProps) => {
|
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
interface TrillingProps {
|
|
48
|
+
interface TrillingProps extends HTMLAttributes<HTMLDivElement> {
|
|
49
49
|
children: React.ReactNode;
|
|
50
50
|
className?: string;
|
|
51
51
|
}
|
|
52
|
-
export const Trilling = ({ children, className }: TrillingProps) => {
|
|
52
|
+
export const Trilling = ({ children, className, ...props }: TrillingProps) => {
|
|
53
53
|
return (
|
|
54
54
|
<div
|
|
55
|
+
{...props}
|
|
55
56
|
className={cn(
|
|
56
57
|
"flex items-center justify-center h-full gap-1 py-1",
|
|
57
58
|
className
|
|
@@ -96,7 +97,7 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(
|
|
|
96
97
|
autoComplete="off"
|
|
97
98
|
className={cn(
|
|
98
99
|
// Base styles
|
|
99
|
-
"typography-body-large-regular
|
|
100
|
+
"typography-body-large-regular",
|
|
100
101
|
"text-content-presentation-action-light-primary",
|
|
101
102
|
"bg-transparent",
|
|
102
103
|
"h-full",
|
|
@@ -183,8 +184,8 @@ export const GroupStyles = cva(
|
|
|
183
184
|
],
|
|
184
185
|
},
|
|
185
186
|
size: {
|
|
186
|
-
S: ["h-[30px]", "rounded-[6px] [&_input]:h-[30px] [&_div[data-role='icon']]:text-[16px]"],
|
|
187
|
-
M: ["h-[40px]", "rounded-[8px] [&_input]:h-[40px] [&_div[data-role='icon']]:text-[18px] [&_div[data-role='icon']]:px-[2px]"],
|
|
187
|
+
S: ["h-[30px] min-h-[30px]", "rounded-[6px] [&_input]:h-[30px] [&_div[data-role='icon']]:text-[16px]"],
|
|
188
|
+
M: ["h-[40px] min-h-[40px]", "rounded-[8px] [&_input]:h-[40px] [&_div[data-role='icon']]:text-[18px] [&_div[data-role='icon']]:px-[2px]"],
|
|
188
189
|
},
|
|
189
190
|
error: {
|
|
190
191
|
true: [
|
|
@@ -48,6 +48,7 @@ export const InputField = forwardRef<HTMLInputElement, Props>(
|
|
|
48
48
|
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
|
|
49
49
|
const [PopoverWidth, setPopoverWidth] = useState(0);
|
|
50
50
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
51
|
+
const triggerRef = useRef<HTMLButtonElement>(null);
|
|
51
52
|
|
|
52
53
|
useEffect(() => {
|
|
53
54
|
if (!forwardedRef) return;
|
|
@@ -56,14 +57,14 @@ export const InputField = forwardRef<HTMLInputElement, Props>(
|
|
|
56
57
|
}, [forwardedRef]);
|
|
57
58
|
// TODO: make the user input visible when input is focused
|
|
58
59
|
return (
|
|
59
|
-
<Popover
|
|
60
|
+
<Popover onOpenChange={setIsPopoverOpen}>
|
|
60
61
|
<Tooltip
|
|
61
62
|
theme={theme}
|
|
62
63
|
toolTipSide={toolTipSide}
|
|
63
64
|
open={errorMessage !== undefined}
|
|
64
65
|
text={errorMessage}
|
|
65
66
|
>
|
|
66
|
-
<PopoverTrigger asChild>
|
|
67
|
+
<PopoverTrigger ref={triggerRef} asChild>
|
|
67
68
|
<Group
|
|
68
69
|
error={errorMessage !== undefined}
|
|
69
70
|
onTable={onTable}
|
|
@@ -113,6 +114,9 @@ export const InputField = forwardRef<HTMLInputElement, Props>(
|
|
|
113
114
|
variant={variant}
|
|
114
115
|
onOpenAutoFocus={(e: any) => e.preventDefault()}
|
|
115
116
|
style={{ width: PopoverWidth }}
|
|
117
|
+
onClick={(e) => {
|
|
118
|
+
triggerRef.current?.click();
|
|
119
|
+
}}
|
|
116
120
|
>
|
|
117
121
|
{popoverChildren}
|
|
118
122
|
</PopoverContent>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { cloneElement, ComponentProps, forwardRef, isValidElement, useState, useEffect } from 'react';
|
|
1
|
+
import { cloneElement, ComponentProps, forwardRef, isValidElement, useState, useEffect, useRef } from 'react';
|
|
2
2
|
import { getDaysInMonth } from 'date-fns';
|
|
3
3
|
import Picker from 'torch-react-mobile-picker';
|
|
4
4
|
import { Popover, PopoverContent, PopoverTrigger } from './Popover';
|
|
5
5
|
import { InputField } from './InputField';
|
|
6
6
|
import { ActionButton } from './ActionButton';
|
|
7
|
-
import { formatDateValueToString } from '
|
|
7
|
+
import { formatDateValueToString } from '../utils/dateFormat';
|
|
8
8
|
|
|
9
9
|
function getDayArray(year: number, month: number): string[] {
|
|
10
10
|
const dayCount = getDaysInMonth(new Date(year, month - 1));
|
|
@@ -15,9 +15,10 @@ interface SlideDatePickerProps extends Omit<ComponentProps<typeof InputField>, '
|
|
|
15
15
|
onChange?: (e: any) => void;
|
|
16
16
|
theme?: "dark" | "light" | "default";
|
|
17
17
|
dateFormat?: string;
|
|
18
|
+
value?: any;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
type
|
|
21
|
+
type SlideValues = {
|
|
21
22
|
year: string,
|
|
22
23
|
month: string,
|
|
23
24
|
day: string,
|
|
@@ -32,22 +33,25 @@ export const SlideDatePicker = forwardRef<HTMLInputElement, SlideDatePickerProps
|
|
|
32
33
|
onChange,
|
|
33
34
|
dateFormat = "yyyy/MM/dd",
|
|
34
35
|
children,
|
|
36
|
+
value = new Date(),
|
|
35
37
|
...props
|
|
36
38
|
}, forwardedRef) => {
|
|
37
39
|
|
|
38
|
-
const today =
|
|
40
|
+
const today = value
|
|
39
41
|
const defaultPickerValue = {
|
|
40
42
|
year: String(today.getFullYear()),
|
|
41
|
-
month: String(today.getMonth() + 1)
|
|
42
|
-
day: String(today.getDate())
|
|
43
|
-
hour:
|
|
44
|
-
minute:
|
|
45
|
-
time: "AM"
|
|
43
|
+
month: String(today.getMonth() + 1),
|
|
44
|
+
day: String(today.getDate()),
|
|
45
|
+
hour: String(today.getHours()),
|
|
46
|
+
minute: String(today.getMinutes()),
|
|
47
|
+
time: today.getHours() < 12 ? "AM" : "PM"
|
|
46
48
|
};
|
|
47
49
|
|
|
48
|
-
const [pickerValue, setPickerValue] = useState<
|
|
49
|
-
const [date, setDate] = useState<Date>(
|
|
50
|
+
const [pickerValue, setPickerValue] = useState<SlideValues>(defaultPickerValue);
|
|
51
|
+
const [date, setDate] = useState<Date>(value);
|
|
50
52
|
const [isOpen, setIsOpen] = useState(false);
|
|
53
|
+
const triggerRef = useRef<HTMLButtonElement>(null);
|
|
54
|
+
|
|
51
55
|
const currentYear = new Date().getFullYear();
|
|
52
56
|
const years = Array.from({ length: 200 }, (_, i) => `${currentYear - 100 + i}`);
|
|
53
57
|
const months = Array.from({ length: 12 }, (_, i) => String(i + 1).padStart(2, ''));
|
|
@@ -57,7 +61,7 @@ export const SlideDatePicker = forwardRef<HTMLInputElement, SlideDatePickerProps
|
|
|
57
61
|
"July", "August", "September", "October", "November", "December",
|
|
58
62
|
];
|
|
59
63
|
|
|
60
|
-
const handlePickerChange = (newValue:
|
|
64
|
+
const handlePickerChange = (newValue: SlideValues, key: string) => {
|
|
61
65
|
let { year, month, day, hour, minute, time } = newValue;
|
|
62
66
|
|
|
63
67
|
if (key === 'year' || key === 'month') {
|
|
@@ -118,7 +122,7 @@ export const SlideDatePicker = forwardRef<HTMLInputElement, SlideDatePickerProps
|
|
|
118
122
|
|
|
119
123
|
return (
|
|
120
124
|
<Popover onOpenChange={setIsOpen}>
|
|
121
|
-
<PopoverTrigger asChild data-theme={theme} className='w-full flex-1' >
|
|
125
|
+
<PopoverTrigger ref={triggerRef} asChild data-theme={theme} className='w-full flex-1' >
|
|
122
126
|
{
|
|
123
127
|
isValidElement(children) ?
|
|
124
128
|
cloneElement(children as React.ReactElement<HTMLInputElement>, {
|
|
@@ -131,12 +135,14 @@ export const SlideDatePicker = forwardRef<HTMLInputElement, SlideDatePickerProps
|
|
|
131
135
|
<InputField
|
|
132
136
|
readOnly
|
|
133
137
|
type="input"
|
|
138
|
+
{...props}
|
|
134
139
|
childrenSide={
|
|
135
|
-
<ActionButton type='button' size={"M"}
|
|
140
|
+
<ActionButton type='button' size={"M"} onClick={() => {
|
|
141
|
+
triggerRef.current?.click();
|
|
142
|
+
}}>
|
|
136
143
|
<i className="ri-calendar-event-fill"></i>
|
|
137
144
|
</ActionButton>
|
|
138
145
|
}
|
|
139
|
-
{...props}
|
|
140
146
|
value={formattedValue}
|
|
141
147
|
ref={forwardedRef}
|
|
142
148
|
/>
|
|
@@ -2,7 +2,6 @@ import * as React from "react";
|
|
|
2
2
|
import { cn } from "../utils/cn";
|
|
3
3
|
import { Label } from "./Label";
|
|
4
4
|
import { cva, VariantProps } from "class-variance-authority";
|
|
5
|
-
import { Input } from "./Input";
|
|
6
5
|
|
|
7
6
|
// Define the styles for the textarea using cva
|
|
8
7
|
const textareaStyles = cva(
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Toaster as ToasterComponent, toast } from 'react-hot-toast'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const Toaster = ({
|
|
6
|
+
position = 'top-left',
|
|
7
|
+
reverseOrder = false,
|
|
8
|
+
gutter = 8,
|
|
9
|
+
containerClassName = '',
|
|
10
|
+
containerStyle = {},
|
|
11
|
+
toastOptions = {},
|
|
12
|
+
...props }: React.ComponentPropsWithoutRef<typeof ToasterComponent>) => {
|
|
13
|
+
return (
|
|
14
|
+
<ToasterComponent
|
|
15
|
+
position={position}
|
|
16
|
+
reverseOrder={reverseOrder}
|
|
17
|
+
gutter={gutter}
|
|
18
|
+
containerClassName={containerClassName}
|
|
19
|
+
containerStyle={containerStyle}
|
|
20
|
+
{...props}
|
|
21
|
+
toastOptions={{
|
|
22
|
+
// Define default options
|
|
23
|
+
className: '',
|
|
24
|
+
duration: 8000,
|
|
25
|
+
removeDelay: 1000,
|
|
26
|
+
style: {
|
|
27
|
+
background: 'var(--background-presentation-state-information-secondary)',
|
|
28
|
+
color: 'var(--content-presentation-global-primary)',
|
|
29
|
+
borderRadius: '16px',
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
// Default options for specific types
|
|
33
|
+
success: {
|
|
34
|
+
duration: 3000,
|
|
35
|
+
style: {
|
|
36
|
+
background: 'var(--background-presentation-state-success-secondary)',
|
|
37
|
+
color: 'var(--content-presentation-global-primary)',
|
|
38
|
+
borderRadius: '16px',
|
|
39
|
+
},
|
|
40
|
+
iconTheme: {
|
|
41
|
+
primary: 'var(--background-presentation-state-success-primary)',
|
|
42
|
+
secondary: 'var(--background-presentation-state-success-secondary)',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
error: {
|
|
46
|
+
duration: 5000,
|
|
47
|
+
style: {
|
|
48
|
+
background: 'var(--background-presentation-state-negative-secondary)',
|
|
49
|
+
color: 'var(--content-presentation-global-primary)',
|
|
50
|
+
borderRadius: '16px',
|
|
51
|
+
},
|
|
52
|
+
iconTheme: {
|
|
53
|
+
primary: 'var(--background-presentation-state-negative-primary)',
|
|
54
|
+
secondary: 'var(--background-presentation-state-negative-secondary)',
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
loading: {
|
|
58
|
+
duration: 4000,
|
|
59
|
+
style: {
|
|
60
|
+
background: 'var(--background-presentation-state-warning-secondary)',
|
|
61
|
+
color: 'var(--content-presentation-global-primary)',
|
|
62
|
+
borderRadius: '16px',
|
|
63
|
+
},
|
|
64
|
+
iconTheme: {
|
|
65
|
+
primary: 'var(--background-presentation-state-warning-primary)',
|
|
66
|
+
secondary: 'var(--background-presentation-state-warning-secondary)',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
blank: {
|
|
70
|
+
duration: 4000,
|
|
71
|
+
style: {
|
|
72
|
+
background: 'var(--background-presentation-state-information-secondary)',
|
|
73
|
+
color: 'var(--content-presentation-global-primary)',
|
|
74
|
+
borderRadius: '16px',
|
|
75
|
+
},
|
|
76
|
+
iconTheme: {
|
|
77
|
+
primary: 'var(--background-presentation-state-information-primary)',
|
|
78
|
+
secondary: 'var(--background-presentation-state-information-secondary)',
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
...toastOptions,
|
|
82
|
+
}}
|
|
83
|
+
/>
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export { Toaster, toast }
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|