torch-glare 1.0.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.
Files changed (68) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +207 -0
  3. package/cli/bin/addComponent.js +278 -0
  4. package/cli/bin/addHooks.js +75 -0
  5. package/cli/bin/addLayout.js +71 -0
  6. package/cli/bin/addProvider.js +71 -0
  7. package/cli/bin/addUtils.js +74 -0
  8. package/cli/bin/cli.js +73 -0
  9. package/cli/bin/init/init.js +15 -0
  10. package/cli/bin/init/tailwindInit.js +174 -0
  11. package/cli/bin/update.js +147 -0
  12. package/lib/components/ActionButton.tsx +63 -0
  13. package/lib/components/ActionsGroup.tsx +34 -0
  14. package/lib/components/AlertDialog.tsx +211 -0
  15. package/lib/components/Badge.tsx +116 -0
  16. package/lib/components/BadgeField.tsx +192 -0
  17. package/lib/components/Button.tsx +277 -0
  18. package/lib/components/Card.tsx +63 -0
  19. package/lib/components/Checkbox.tsx +104 -0
  20. package/lib/components/CountBadge.tsx +54 -0
  21. package/lib/components/DatePicker.tsx +464 -0
  22. package/lib/components/Drawer.tsx +118 -0
  23. package/lib/components/DropdownMenu.tsx +399 -0
  24. package/lib/components/FieldHint.tsx +76 -0
  25. package/lib/components/ImageAttachment.tsx +171 -0
  26. package/lib/components/InnerLabelField.tsx +155 -0
  27. package/lib/components/Input.tsx +179 -0
  28. package/lib/components/InputField.tsx +147 -0
  29. package/lib/components/Label.tsx +107 -0
  30. package/lib/components/LabelField.tsx +75 -0
  31. package/lib/components/LabeledCheckBox.tsx +65 -0
  32. package/lib/components/LabeledRadio.tsx +45 -0
  33. package/lib/components/LinkButton.tsx +90 -0
  34. package/lib/components/LoginButton.tsx +56 -0
  35. package/lib/components/PasswordLevel.tsx +58 -0
  36. package/lib/components/Popover.tsx +274 -0
  37. package/lib/components/ProfileMenu.tsx +90 -0
  38. package/lib/components/Radio.tsx +69 -0
  39. package/lib/components/RadioCard.tsx +70 -0
  40. package/lib/components/RingLoading.tsx +190 -0
  41. package/lib/components/SearchField.tsx +49 -0
  42. package/lib/components/Select.tsx +417 -0
  43. package/lib/components/SlideDatePicker.tsx +120 -0
  44. package/lib/components/SpinLoading.tsx +190 -0
  45. package/lib/components/Switcher.tsx +56 -0
  46. package/lib/components/TabFormItem.tsx +158 -0
  47. package/lib/components/Table.tsx +395 -0
  48. package/lib/components/Textarea.tsx +108 -0
  49. package/lib/components/Tooltip.tsx +111 -0
  50. package/lib/components/TransparentLabel.tsx +72 -0
  51. package/lib/components/TreeDropDown.tsx +69 -0
  52. package/lib/hooks/MobileSlidePicker/components/Picker.tsx +218 -0
  53. package/lib/hooks/MobileSlidePicker/components/PickerColumn.tsx +238 -0
  54. package/lib/hooks/MobileSlidePicker/components/PickerItem.tsx +64 -0
  55. package/lib/hooks/MobileSlidePicker/index.ts +10 -0
  56. package/lib/hooks/useActiveTreeItem.tsx +61 -0
  57. package/lib/hooks/useClickOutside.tsx +20 -0
  58. package/lib/hooks/useResize.tsx +78 -0
  59. package/lib/layouts/CLayout.tsx +326 -0
  60. package/lib/layouts/FieldSection.tsx +64 -0
  61. package/lib/layouts/TreeSubLayout.tsx +187 -0
  62. package/lib/providers/ThemeProvider.tsx +99 -0
  63. package/lib/utils/cn.ts +6 -0
  64. package/lib/utils/convertImageFileToDataUrl.ts +17 -0
  65. package/lib/utils/resize.ts +35 -0
  66. package/lib/utils/types.ts +12 -0
  67. package/package.json +28 -0
  68. package/torch-glare.js +24 -0
@@ -0,0 +1,399 @@
1
+ import { cva, VariantProps } from "class-variance-authority";
2
+ import * as React from "react";
3
+ import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
4
+ import { cn } from "../utils/cn";
5
+ import { Themes } from "../utils/types";
6
+
7
+ export const MenuItemStyles = cva(
8
+ [
9
+ "text-content-presentation-action-light-primary",
10
+ "outline-none",
11
+ "border",
12
+ "border-transparent",
13
+ "flex",
14
+ "gap-[8px]",
15
+ "items-center",
16
+ "justify-start",
17
+ "text-overflow",
18
+ "overflow-hidden",
19
+ "px-[12px]",
20
+ "rounded-[4px]",
21
+ "transition-all",
22
+ "ease-in-out",
23
+ "duration-300",
24
+ ],
25
+ {
26
+ variants: {
27
+ variant: {
28
+ Default: [
29
+ "text-content-presentation-action-light-primary",
30
+ "bg-background-presentation-action-dropdown-primary",
31
+ "hover:bg-background-presentation-action-hover",
32
+ "hover:text-content-presentation-action-hover",
33
+ "focus:bg-background-presentation-action-selected",
34
+ "focus:text-content-presentation-action-light-primary",
35
+ "active:border-border-presentation-action-disabled",
36
+ "active:bg-background-presentation-action-selected",
37
+ "active:text-content-presentation-action-light-primary",
38
+ "active:border-border-presentation-action-disabled",
39
+ "disabled:text-content-presentation-state-disabled",
40
+ "disabled:bg-white-00",
41
+ ],
42
+ Warning: [
43
+ "bg-background-presentation-action-dropdown-primary",
44
+ "text-content-presentation-state-information",
45
+ "hover:bg-background-presentation-state-information-primary",
46
+ "hover:text-content-presentation-action-hover",
47
+ ],
48
+ Negative: [
49
+ "bg-background-presentation-action-dropdown-primary",
50
+ "text-content-presentation-state-negative",
51
+ "hover:bg-background-presentation-state-negative-primary",
52
+ "hover:!text-content-presentation-action-hover",
53
+ "focus:text-content-presentation-state-negative",
54
+ "active:text-content-presentation-state-negative",
55
+ ],
56
+ SystemStyle: [
57
+ "bg-background-system-body-primary",
58
+ "text-content-system-global-primary",
59
+ "hover:!bg-background-system-action-secondary-hover",
60
+ "hover:!text-content-system-action-primary-hover",
61
+ "hover:!border-border-system-action-primary-hover",
62
+ "focus:bg-background-System-Action-Primary-Selected",
63
+ "focus:border-transparent",
64
+ "active:border-transparent",
65
+ "active:bg-background-System-Action-Primary-Selected",
66
+ "disabled:bg-background-system-body-secondary",
67
+ "disabled:text-content-system-global-disabled",
68
+ ],
69
+ },
70
+ size: {
71
+ S: ["typography-body-small-regular", "h-[24px]"],
72
+ M: ["typography-body-medium-regular", "h-[32px]"],
73
+ },
74
+
75
+ disabled: {
76
+ true: [
77
+ "text-content-presentation-state-disabled",
78
+ "bg-white-00",
79
+ ],
80
+ },
81
+
82
+ active: {
83
+ true: [
84
+ "bg-background-presentation-action-selected",
85
+ "text-content-presentation-action-light-primary",
86
+ ],
87
+ },
88
+
89
+ defaultVariants: {
90
+ variant: "Default",
91
+ size: "M",
92
+ active: false,
93
+ disabled: false,
94
+ },
95
+ },
96
+ compoundVariants: [
97
+ {
98
+ active: true,
99
+ variant: "Warning",
100
+ className: ["text-content-presentation-state-negative"],
101
+ },
102
+ ],
103
+ }
104
+ );
105
+ export const dropdownMenuStyles = cva(
106
+ [
107
+ "p-1",
108
+ "rounded-[8px]",
109
+ "border",
110
+ "max-h-[200px]",
111
+ "min-w-[240px]",
112
+ "outline-none",
113
+ "overflow-scroll",
114
+ "data-[state=open]:animate-in",
115
+ "data-[state=closed]:animate-out",
116
+ "data-[state=closed]:fade-out-0",
117
+ "data-[state=open]:fade-in-0",
118
+ "overflow-x-hidden",
119
+ "scrollbar-hide",
120
+ ],
121
+ {
122
+ variants: {
123
+ variant: {
124
+ SystemStyle: [
125
+ "border-border-system-global-secondary",
126
+ "bg-background-system-body-primary",
127
+ "shadow-[0px_0px_18px_0px_rgba(0,0,0,0.75)]",
128
+ ],
129
+ PresentationStyle: [
130
+ "border-border-presentation-global-primary",
131
+ "bg-background-presentation-form-base",
132
+ "shadow-[0px_0px_10px_0px_rgba(0,0,0,0.4),0px_4px_4px_0px_rgba(0,0,0,0.2)]",
133
+ ],
134
+ },
135
+ defaultVariants: {
136
+ variant: "PresentationStyle",
137
+ },
138
+ },
139
+ }
140
+ );
141
+
142
+ interface DropdownMenuProps {
143
+ variant?: "SystemStyle" | "PresentationStyle";
144
+ className?: string;
145
+ theme?: Themes
146
+ }
147
+
148
+
149
+ const DropdownMenu = DropdownMenuPrimitive.Root;
150
+
151
+ const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
152
+
153
+ const DropdownMenuGroup = DropdownMenuPrimitive.Group;
154
+
155
+ const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
156
+
157
+ const DropdownMenuSub = DropdownMenuPrimitive.Sub;
158
+
159
+ const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
160
+
161
+ const DropdownMenuContent = React.forwardRef<
162
+ React.ElementRef<typeof DropdownMenuPrimitive.Content>,
163
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content> &
164
+ DropdownMenuProps
165
+ >(
166
+ (
167
+ { theme, className, sideOffset = 4, variant = "PresentationStyle", ...props },
168
+ ref
169
+ ) => (
170
+ <DropdownMenuPrimitive.Portal>
171
+ <DropdownMenuPrimitive.Content
172
+ data-theme={theme}
173
+ ref={ref}
174
+ sideOffset={sideOffset}
175
+ className={cn(dropdownMenuStyles({ variant }), className)}
176
+ {...props}
177
+ />
178
+ </DropdownMenuPrimitive.Portal>
179
+ )
180
+ );
181
+ DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
182
+
183
+ const DropdownMenuSubTrigger = React.forwardRef<
184
+ React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
185
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
186
+ inset?: boolean;
187
+ } & VariantProps<typeof MenuItemStyles>
188
+ >(
189
+ (
190
+ {
191
+ className,
192
+ inset,
193
+ children,
194
+ variant = "Default",
195
+ size = "M",
196
+ disabled,
197
+ ...props
198
+ },
199
+ ref
200
+ ) => (
201
+ <DropdownMenuPrimitive.SubTrigger
202
+ ref={ref}
203
+ className={cn(
204
+ MenuItemStyles({ variant, size, disabled }),
205
+ "justify-between",
206
+ className
207
+ )}
208
+ {...props}
209
+ >
210
+ {children}
211
+ <i className="ri-arrow-right-s-line text-[16px]"></i>
212
+ </DropdownMenuPrimitive.SubTrigger>
213
+ )
214
+ );
215
+ DropdownMenuSubTrigger.displayName =
216
+ DropdownMenuPrimitive.SubTrigger.displayName;
217
+
218
+ const DropdownMenuSubContent = React.forwardRef<
219
+ React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
220
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent> & {
221
+ variant?: "SystemStyle" | "PresentationStyle";
222
+ }
223
+ >(({ className, variant = "PresentationStyle", ...props }, ref) => (
224
+ <DropdownMenuPrimitive.SubContent
225
+ ref={ref}
226
+ className={cn(dropdownMenuStyles({ variant }), className)}
227
+ {...props}
228
+ />
229
+ ));
230
+ DropdownMenuSubContent.displayName =
231
+ DropdownMenuPrimitive.SubContent.displayName;
232
+
233
+ const DropdownMenuItem = React.forwardRef<
234
+ React.ElementRef<typeof DropdownMenuPrimitive.Item>,
235
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
236
+ inset?: boolean;
237
+ } & VariantProps<typeof MenuItemStyles>
238
+ >(
239
+ (
240
+ {
241
+ className,
242
+ inset,
243
+ variant = "Default",
244
+ size = "M",
245
+ disabled,
246
+ active,
247
+ ...props
248
+ },
249
+ ref
250
+ ) => (
251
+ <DropdownMenuPrimitive.Item
252
+ {...props}
253
+ ref={ref}
254
+ className={cn(
255
+ MenuItemStyles({ variant, size, disabled, active }),
256
+ className
257
+ )}
258
+ />
259
+ )
260
+ );
261
+ DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
262
+
263
+ const DropdownMenuCheckboxItem = React.forwardRef<
264
+ React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
265
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem> &
266
+ VariantProps<typeof MenuItemStyles>
267
+ >(
268
+ (
269
+ {
270
+ className,
271
+ children,
272
+ checked,
273
+ variant = "Default",
274
+ size = "M",
275
+ disabled,
276
+ ...props
277
+ },
278
+ ref
279
+ ) => (
280
+ <DropdownMenuPrimitive.CheckboxItem
281
+ ref={ref}
282
+ className={cn(
283
+ MenuItemStyles({ variant, size, disabled }),
284
+ "relative pl-8",
285
+ className
286
+ )}
287
+ checked={checked}
288
+ {...props}
289
+ >
290
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
291
+ <DropdownMenuPrimitive.ItemIndicator>
292
+ <i className="ri-radio-button-fill text-white text-[16px]"></i>
293
+ </DropdownMenuPrimitive.ItemIndicator>
294
+ </span>
295
+ {children}
296
+ </DropdownMenuPrimitive.CheckboxItem>
297
+ )
298
+ );
299
+ DropdownMenuCheckboxItem.displayName =
300
+ DropdownMenuPrimitive.CheckboxItem.displayName;
301
+
302
+ const DropdownMenuRadioItem = React.forwardRef<
303
+ React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
304
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem> &
305
+ VariantProps<typeof MenuItemStyles>
306
+ >(
307
+ (
308
+ {
309
+ className,
310
+ children,
311
+ variant = "Default",
312
+ size = "M",
313
+ disabled,
314
+ ...props
315
+ },
316
+ ref
317
+ ) => (
318
+ <DropdownMenuPrimitive.RadioItem
319
+ ref={ref}
320
+ className={cn(
321
+ MenuItemStyles({ variant, size, disabled }),
322
+ "relative pl-8",
323
+ className
324
+ )}
325
+ {...props}
326
+ >
327
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
328
+ <DropdownMenuPrimitive.ItemIndicator>
329
+ <i className="h-2 w-2 fill-current" />
330
+ </DropdownMenuPrimitive.ItemIndicator>
331
+ </span>
332
+ {children}
333
+ </DropdownMenuPrimitive.RadioItem>
334
+ )
335
+ );
336
+ DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
337
+
338
+ const DropdownMenuLabel = React.forwardRef<
339
+ React.ElementRef<typeof DropdownMenuPrimitive.Label>,
340
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
341
+ inset?: boolean;
342
+ }
343
+ >(({ className, inset, ...props }, ref) => (
344
+ <DropdownMenuPrimitive.Label
345
+ ref={ref}
346
+ className={cn(
347
+ "text-content-presentation-state-disabled typography-body-medium-regular px-[12px] h-[32px] flex justify-start items-center",
348
+ className
349
+ )}
350
+ {...props}
351
+ />
352
+ ));
353
+ DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
354
+
355
+ const DropdownMenuSeparator = React.forwardRef<
356
+ React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
357
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
358
+ >(({ className, ...props }, ref) => (
359
+ <DropdownMenuPrimitive.Separator
360
+ ref={ref}
361
+ className={cn(
362
+ "mx-[8px] my-[4px] border-b border-b-border-presentation-action-disabled flex-1",
363
+ className
364
+ )}
365
+ {...props}
366
+ />
367
+ ));
368
+ DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
369
+
370
+ const DropdownMenuShortcut = ({
371
+ className,
372
+ ...props
373
+ }: React.HTMLAttributes<HTMLSpanElement>) => {
374
+ return (
375
+ <span
376
+ className={cn("ml-auto text-xs tracking-widest opacity-60", className)}
377
+ {...props}
378
+ />
379
+ );
380
+ };
381
+ DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
382
+
383
+ export {
384
+ DropdownMenu,
385
+ DropdownMenuTrigger,
386
+ DropdownMenuContent,
387
+ DropdownMenuSubTrigger,
388
+ DropdownMenuGroup,
389
+ DropdownMenuPortal,
390
+ DropdownMenuSub,
391
+ DropdownMenuRadioGroup,
392
+ DropdownMenuSubContent,
393
+ DropdownMenuCheckboxItem,
394
+ DropdownMenuRadioItem,
395
+ DropdownMenuLabel,
396
+ DropdownMenuSeparator,
397
+ DropdownMenuShortcut,
398
+ DropdownMenuItem,
399
+ };
@@ -0,0 +1,76 @@
1
+ import { HTMLAttributes, ReactNode } from "react";
2
+ import { cva } from "class-variance-authority";
3
+ import { cn } from "../utils/cn";
4
+ import { Themes } from "../utils/types";
5
+
6
+ export const glareFieldAlert = cva(
7
+ "flex relative justify-start items-center rounded-[4px] min-h-26px w-fit pr-1 rtl:pl-1 rtl:pr-0 [&>section]:text-white",
8
+ {
9
+ variants: {
10
+ state: {
11
+ info: "bg-background-presentation-state-information-secondary [&>section]:bg-background-presentation-state-information-primary [&>section]:text-background-presentation-state-information-secondary",
12
+ warning:
13
+ "bg-background-presentation-state-warning-secondary [&>section]:bg-background-presentation-state-warning-primary [&>section]:text-background-presentation-state-warning-secondary",
14
+ error:
15
+ "bg-background-presentation-state-negative-secondary [&>section]:bg-background-presentation-state-negative-primary [&>section]:text-background-presentation-state-negative-secondary",
16
+ success:
17
+ "bg-background-presentation-state-success-secondary [&>section]:bg-background-presentation-state-success-primary [&>section]:text-background-presentation-state-success-secondary",
18
+ },
19
+ },
20
+ defaultVariants: {
21
+ state: "info",
22
+ },
23
+ }
24
+ );
25
+
26
+ type FieldAlertVariant = "success" | "error" | "warning" | "info";
27
+
28
+ interface Props extends HTMLAttributes<HTMLDivElement> {
29
+ label: ReactNode;
30
+ state?: FieldAlertVariant;
31
+ icon?: ReactNode;
32
+ theme?: Themes
33
+ }
34
+
35
+ export const FieldHint: React.FC<Props> = ({
36
+ label,
37
+ state,
38
+ theme,
39
+ icon,
40
+ className,
41
+ ...props
42
+ }) => {
43
+ return (
44
+ <section
45
+ {...props}
46
+ data-theme={theme}
47
+ className={cn(
48
+ glareFieldAlert({
49
+ state,
50
+ }),
51
+ className
52
+ )}
53
+ >
54
+ <section className="flex items-center justify-center min-w-[26px] min-h-[26px] h-full rounded-[4px] text-[18px]">
55
+ {icon ? (
56
+ icon
57
+ ) : state === "error" ? (
58
+ <i className="ri-alert-fill"></i>
59
+ ) : state === "success" ? (
60
+ <i className="ri-checkbox-circle-fill"></i>
61
+ ) : (
62
+ <i className="ri-error-warning-fill"></i>
63
+ )}
64
+ </section>
65
+ <p
66
+ className={
67
+ "p-1 word-break-all text-content-presentation-global-primary text-wrap text-start whitespace-pre-wrap text-sm"
68
+ }
69
+ >
70
+ {label}
71
+ </p>
72
+ </section>
73
+ );
74
+ };
75
+
76
+ export default FieldHint;
@@ -0,0 +1,171 @@
1
+ import { forwardRef, HTMLAttributes, InputHTMLAttributes, ReactNode } from "react";
2
+ import { Button } from "./Button";
3
+ import { cva } from "class-variance-authority";
4
+ import { cn } from "../utils/cn";
5
+ import { Themes } from "../utils/types";
6
+
7
+ const dropZoneStyles = cva(
8
+ [
9
+ "w-full min-w-[200px] h-[65px] flex flex-col rounded-lg border-dashed !border-2 transition-all duration-300 ease-in-out ",
10
+ "!border-border-presentation-action-borderstyle bg-background-presentation-badge-gray",
11
+ "hover:border-border-presentation-action-borderstyle hover:bg-background-presentation-badge-gray",
12
+ ],
13
+ {
14
+ variants: {
15
+ active: {
16
+ true: "bg-background-presentation-action-hovercontstyle border-border-presentation-badge-gray",
17
+ },
18
+ },
19
+ }
20
+ );
21
+
22
+ interface Props extends InputHTMLAttributes<HTMLInputElement> {
23
+ isDropAreaActive?: boolean;
24
+ mainLabel: string;
25
+ secondaryLabel: string;
26
+ theme?: Themes
27
+ expandLabel: ReactNode
28
+ uploadedImage: any
29
+ onExpand?: () => void
30
+ getRootProps?: () => any
31
+
32
+ }
33
+
34
+ export const ImageAttachment = forwardRef<HTMLInputElement, Props>(
35
+ (
36
+ {
37
+ isDropAreaActive,
38
+ mainLabel,
39
+ theme,
40
+ secondaryLabel,
41
+ expandLabel,
42
+ uploadedImage,
43
+ onExpand,
44
+ className,
45
+ getRootProps,
46
+ ...props
47
+ }: Props,
48
+ ref
49
+ ) => {
50
+ return (
51
+ <section className="flex items-center justify-center w-full gap-1">
52
+ <ExpandableImage
53
+ theme={theme}
54
+ selectedImg={uploadedImage}
55
+ expandLabel={expandLabel}
56
+ onExpand={onExpand}
57
+ />
58
+ <Button
59
+ {...getRootProps?.()}
60
+ theme={theme}
61
+ as="label"
62
+ id={props.id}
63
+ variant="PrimeContStyle"
64
+ className={cn(dropZoneStyles({ active: isDropAreaActive }), className)}
65
+ >
66
+ <h1 className="text-content-presentation-action-light-primary typography-body-large-medium">
67
+ {mainLabel}
68
+ </h1>
69
+ <p className="text-content-presentation-action-light-secondary typography-body-small-medium">
70
+ {secondaryLabel}
71
+ </p>
72
+ <input ref={ref} {...props} type="file" hidden />
73
+ </Button>
74
+ </section>
75
+
76
+ );
77
+ }
78
+ );
79
+
80
+ ImageAttachment.displayName = "ImageAttachment"
81
+
82
+
83
+
84
+
85
+
86
+ interface ExpandableImageProps extends HTMLAttributes<HTMLDivElement> {
87
+ selectedImg: any
88
+ onExpand?: () => void
89
+ expandLabel: ReactNode
90
+ theme?: Themes
91
+ }
92
+
93
+ const ExpandableImage = forwardRef<HTMLDivElement, ExpandableImageProps>(({ theme, id, selectedImg, onExpand, expandLabel, className, ...props }, ref) => {
94
+ return (
95
+ <section data-theme={theme} className={cn("flex items-center justify-center w-[65px] h-[65px] rounded-md relative overflow-hidden border-none group", className)}>
96
+ {selectedImg ? <SelectedImg imageSrc={selectedImg} /> : <ExpandableBaseComponent label="Upload Image" />}
97
+ {selectedImg && <ExpandImage onExpand={onExpand} expandLabel={expandLabel} />}
98
+ </section>
99
+ );
100
+ })
101
+
102
+
103
+ function ExpandableBaseComponent({ label }: any) {
104
+ return (
105
+ <section className={cn([
106
+ 'w-full h-full gap-[2px] flex flex-col justify-center items-center px-1',
107
+ ' rounded-lg border-2 border-dashed',
108
+ ' border-border-presentation-badge-blue-purple',
109
+ ' bg-background-presentation-badge-blue-purple',
110
+ ' transition-all duration-300 ease-in-out',
111
+ ' hover:bg-background-presentation-badge-gray hover:border-border-presentation-badge-gray']
112
+ )}>
113
+ <i className="ri-attachment-line text-content-presentation-badge-blue-purple group-hover:text-[#797C7F] text-[24px] h-[24px]"></i>
114
+ <p className='text-content-presentation-badge-blue-purple typography-labels-small-regular group-hover:text-[#797C7F] px-1 py-[2px] text-center'>{label}</p>
115
+ </section>
116
+ )
117
+ }
118
+ function ExpandImage({ onExpand, expandLabel = "Expand Pic" }: any) {
119
+ return (
120
+ <button onClick={onExpand} className='flex w-full h-full justify-center items-center flex-col absolute z-10 opacity-0 bg-black/50 transition-all duration-250 ease-in-out hover:opacity-100' >
121
+ <svg width="25" height="25" viewBox="0 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg">
122
+ <path d="M15.5 3.5L17.8 5.8L14.91 8.67L16.33 10.09L19.2 7.2L21.5 9.5V3.5H15.5ZM3.5 9.5L5.8 7.2L8.67 10.09L10.09 8.67L7.2 5.8L9.5 3.5H3.5V9.5ZM9.5 21.5L7.2 19.2L10.09 16.33L8.67 14.91L5.8 17.8L3.5 15.5V21.5H9.5ZM21.5 15.5L19.2 17.8L16.33 14.91L14.91 16.33L17.8 19.2L15.5 21.5H21.5V15.5Z" fill="#F9F9F9" />
123
+ </svg>
124
+ <p className='text-content-presentation-action-hover typography-labels-small-regular max-w-[50px] break-words m-0'>{expandLabel}</p>
125
+ </button>
126
+ )
127
+ }
128
+
129
+ function SelectedImg({ imageSrc }: any) {
130
+ return (
131
+ <section className='bg-white'>
132
+ <img src={imageSrc} className='w-full h-full object-cover object-center' />
133
+ </section>
134
+ )
135
+ }
136
+
137
+
138
+ interface AttachmentImagePreviewProps extends HTMLAttributes<HTMLDivElement> {
139
+ src: any;
140
+ header?: ReactNode;
141
+ onHide?: () => void;
142
+ theme?: Themes
143
+ }
144
+
145
+ export function AttachmentImagePreview({ theme, src, header, onHide, className, ...props }: AttachmentImagePreviewProps) {
146
+ return (
147
+ <section
148
+ {...props}
149
+ data-theme={theme}
150
+ className={cn(
151
+ " overflow-hidden flex flex-col items-center justify-center w-80 p-2 gap-2 rounded-md border shadow-md border-border-presentation-global-primary bg-background-presentation-form-base",
152
+ className
153
+ )}
154
+ >
155
+ <section className="flex items-center justify-between w-full m-0">
156
+ <p className="m-0 text-content-presentation-global-primary typography-display-medium-semibold">
157
+ {header}
158
+ </p>
159
+ <Button theme={theme} onClick={onHide} size="M" buttonType="icon">
160
+ <i className="ri-close-line text-[16px]"></i>
161
+ </Button>
162
+ </section>
163
+
164
+ <img className="w-full object-cover object-center rounded-md" src={src} />
165
+
166
+ <section className="flex items-center justify-end w-full gap-2">
167
+ {props.children}
168
+ </section>
169
+ </section>
170
+ );
171
+ }