sea-react-components 1.0.3 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/components/accordion/index.d.ts +19 -0
  2. package/dist/components/accordion/index.d.ts.map +1 -0
  3. package/dist/components/accordion/index.js +30 -0
  4. package/dist/components/alert/index.js +1 -1
  5. package/dist/components/calendar/index.d.ts +12 -0
  6. package/dist/components/calendar/index.d.ts.map +1 -0
  7. package/dist/components/calendar/index.js +116 -0
  8. package/dist/components/color-picker/index.d.ts +1 -1
  9. package/dist/components/color-picker/index.d.ts.map +1 -1
  10. package/dist/components/color-picker/index.js +4 -3
  11. package/dist/components/day-calendar/index.d.ts +19 -0
  12. package/dist/components/day-calendar/index.d.ts.map +1 -0
  13. package/dist/components/day-calendar/index.js +60 -0
  14. package/dist/components/drawer/index.js +5 -5
  15. package/dist/components/file-input/components/file-item/index.d.ts +3 -3
  16. package/dist/components/file-input/components/file-item/index.d.ts.map +1 -1
  17. package/dist/components/file-input/components/file-item/index.js +29 -4
  18. package/dist/components/file-input/index.d.ts +24 -7
  19. package/dist/components/file-input/index.d.ts.map +1 -1
  20. package/dist/components/file-input/index.js +53 -31
  21. package/dist/components/file-input-v2/file-input/index.d.ts +14 -0
  22. package/dist/components/file-input-v2/file-input/index.d.ts.map +1 -0
  23. package/dist/components/file-input-v2/file-input/index.js +6 -0
  24. package/dist/components/file-input-v2/file-input-container/index.d.ts +59 -0
  25. package/dist/components/file-input-v2/file-input-container/index.d.ts.map +1 -0
  26. package/dist/components/file-input-v2/file-input-container/index.js +99 -0
  27. package/dist/components/file-input-v2/index.d.ts +3 -0
  28. package/dist/components/file-input-v2/index.d.ts.map +1 -0
  29. package/dist/components/file-input-v2/index.js +2 -0
  30. package/dist/components/modal/index.d.ts +2 -1
  31. package/dist/components/modal/index.d.ts.map +1 -1
  32. package/dist/components/modal/index.js +7 -7
  33. package/dist/components/month-calendar/index.d.ts +14 -0
  34. package/dist/components/month-calendar/index.d.ts.map +1 -0
  35. package/dist/components/month-calendar/index.js +55 -0
  36. package/dist/components/select/index.d.ts +5 -4
  37. package/dist/components/select/index.d.ts.map +1 -1
  38. package/dist/components/select/index.js +37 -26
  39. package/dist/components/skeleton/index.d.ts +1 -1
  40. package/dist/components/skeleton/index.d.ts.map +1 -1
  41. package/dist/components/skeleton/index.js +14 -2
  42. package/dist/components/table/index.d.ts.map +1 -1
  43. package/dist/components/table/index.js +1 -1
  44. package/dist/components/tree-checkbox/components/tree-checkbox-item/index.js +1 -1
  45. package/dist/components/tree-checkbox/index.d.ts +2 -1
  46. package/dist/components/tree-checkbox/index.d.ts.map +1 -1
  47. package/dist/components/week-calendar/index.d.ts +20 -0
  48. package/dist/components/week-calendar/index.d.ts.map +1 -0
  49. package/dist/components/week-calendar/index.js +78 -0
  50. package/dist/hooks/list-items-hook/usePagination.js +1 -1
  51. package/dist/index.d.ts +6 -0
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +6 -0
  54. package/dist/tsconfig.tsbuildinfo +1 -1
  55. package/dist/utils/color/index.d.ts.map +1 -1
  56. package/dist/utils/color/index.js +3 -14
  57. package/package.json +2 -2
@@ -0,0 +1,19 @@
1
+ import React, { ReactNode } from "react";
2
+ type ContextType = {
3
+ openItem: string | null;
4
+ toggleItem: (id: string) => void;
5
+ };
6
+ type AccordionProps = {
7
+ children: ReactNode;
8
+ defaultOpenId?: string;
9
+ };
10
+ export declare const Accordion: React.FC<AccordionProps>;
11
+ export declare const useAccordion: () => ContextType;
12
+ export type AccordionItemProps = {
13
+ title: ReactNode;
14
+ children: ReactNode;
15
+ id?: string;
16
+ };
17
+ export declare const AccordionItem: React.FC<AccordionItemProps>;
18
+ export {};
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/accordion/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAIZ,SAAS,EAEV,MAAM,OAAO,CAAC;AAIf,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC,CAAC;AAIF,KAAK,cAAc,GAAG;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAe9C,CAAC;AAEF,eAAO,MAAM,YAAY,mBAMxB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;IACpB,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAkCtD,CAAC"}
@@ -0,0 +1,30 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { createContext, useState, useContext, useId, } from "react";
4
+ import Icon from "../icon";
5
+ import clsx from "clsx";
6
+ const AccordionContext = createContext(undefined);
7
+ export const Accordion = ({ children, defaultOpenId = null, }) => {
8
+ const [openItem, setOpenItem] = useState(defaultOpenId);
9
+ const toggleItem = (id) => {
10
+ setOpenItem((prev) => (prev === id ? null : id));
11
+ };
12
+ return (_jsx(AccordionContext.Provider, { value: { openItem, toggleItem }, children: _jsx("div", { className: "w-full divide-y divide-gray-300", children: children }) }));
13
+ };
14
+ export const useAccordion = () => {
15
+ const context = useContext(AccordionContext);
16
+ if (!context) {
17
+ throw new Error("useAccordion must be used within an Accordion");
18
+ }
19
+ return context;
20
+ };
21
+ export const AccordionItem = ({ title, children, id, }) => {
22
+ const generatedId = useId();
23
+ const itemId = id || generatedId;
24
+ const { openItem, toggleItem } = useAccordion();
25
+ const isOpen = openItem === itemId;
26
+ return (_jsxs("div", { className: "group", children: [_jsxs("button", { onClick: () => toggleItem(itemId), className: "w-full flex justify-between items-center px-4 py-3 bg-white hover:bg-gray-50 transition text-left", children: [_jsx("span", { className: "font-medium text-gray-800", children: title }), _jsx(Icon, { icon: "weui:arrow-filled", className: clsx("h-5 w-5 custom-animation", {
27
+ "-rotate-90": isOpen,
28
+ "rotate-90": !isOpen,
29
+ }) })] }), _jsx("div", { className: `px-4 pb-4 overflow-hidden transition-all duration-300 ease-in-out ${isOpen ? "max-h-screen opacity-100" : "max-h-0 opacity-0"}`, children: isOpen && _jsx("div", { className: "pt-2 text-gray-700", children: children }) })] }));
30
+ };
@@ -42,7 +42,7 @@ export default function Alert({ message, type, closeButton = true, showIcon = tr
42
42
  let className = colors[type].bg;
43
43
  className = clsx(className, theme === "default" ? "text-white" : `${colors[type].text} bg-opacity-20`);
44
44
  if (open)
45
- return (_jsxs("div", { className: clsx("flex items-center gap-3 rounded-lg p-2", className), children: [showIcon && _jsx(Icon, { icon: icons[type], className: "h-5 w-5" }), _jsx("p", { className: "flex-1", children: message }), closeButton && (_jsx("button", { onClick: () => {
45
+ return (_jsxs("div", { className: clsx("flex items-center gap-3 rounded-lg p-2", className), children: [showIcon && _jsx(Icon, { icon: icons[type], className: "h-5 w-5" }), _jsx("p", { className: "flex-1 text-sm md:text-base", children: message }), closeButton && (_jsx("button", { onClick: () => {
46
46
  setOpen(false);
47
47
  if (handleClickCloseButton) {
48
48
  handleClickCloseButton();
@@ -0,0 +1,12 @@
1
+ export type Props = {
2
+ value?: string | Date;
3
+ onChange?: (date: Date | Date[] | {
4
+ start: Date;
5
+ end: Date;
6
+ }) => void;
7
+ disabledDates?: (string | Date)[];
8
+ allowedDates?: (string | Date)[];
9
+ selectMode?: "single" | "multi" | "range";
10
+ };
11
+ export default function Calendar({ value, onChange, disabledDates, allowedDates, selectMode, }: Props): import("react/jsx-runtime").JSX.Element;
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/calendar/index.tsx"],"names":[],"mappings":"AAOA,MAAM,MAAM,KAAK,GAAG;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG;QAAE,KAAK,EAAE,IAAI,CAAC;QAAC,GAAG,EAAE,IAAI,CAAA;KAAE,KAAK,IAAI,CAAC;IACtE,aAAa,CAAC,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IAClC,YAAY,CAAC,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IACjC,UAAU,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;CAC3C,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAC/B,KAAK,EACL,QAAQ,EACR,aAAkB,EAClB,YAAY,EACZ,UAAqB,GACtB,EAAE,KAAK,2CA2LP"}
@@ -0,0 +1,116 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useMemo, useState } from "react";
4
+ import clsx from "clsx";
5
+ import { Utils } from "sea-platform-helpers";
6
+ import Icon from "../icon";
7
+ export default function Calendar({ value, onChange, disabledDates = [], allowedDates, selectMode = "single", }) {
8
+ const moment = Utils.Moment.default;
9
+ const initialDate = useMemo(() => (value ? moment(value) : moment()), [value]);
10
+ const [currentMonth, setCurrentMonth] = useState(moment(initialDate));
11
+ const [selectedDate, setSelectedDate] = useState(moment(initialDate));
12
+ const [selectedDates, setSelectedDates] = useState([]);
13
+ const [range, setRange] = useState({ start: null, end: null });
14
+ const isDateDisabled = useMemo(() => {
15
+ const disabledSet = new Set(disabledDates.map((d) => moment(d).format("YYYY-MM-DD")));
16
+ const allowedSet = allowedDates
17
+ ? new Set(allowedDates.map((d) => moment(d).format("YYYY-MM-DD")))
18
+ : null;
19
+ return (date) => {
20
+ const formatted = date.format("YYYY-MM-DD");
21
+ if (allowedSet)
22
+ return !allowedSet.has(formatted);
23
+ return disabledSet.has(formatted);
24
+ };
25
+ }, [allowedDates, disabledDates]);
26
+ const startDay = currentMonth.clone().startOf("month").startOf("week");
27
+ const endDay = currentMonth.clone().endOf("month").endOf("week");
28
+ const day = startDay.clone().subtract(1, "day");
29
+ const calendar = [];
30
+ while (day.isBefore(endDay, "day")) {
31
+ calendar.push(Array(7)
32
+ .fill(0)
33
+ .map(() => day.add(1, "day").clone()));
34
+ }
35
+ const isToday = (d) => d.isSame(moment(), "day");
36
+ const isSelected = (d) => selectMode === "single"
37
+ ? selectedDate.isSame(d, "day")
38
+ : selectMode === "multi"
39
+ ? selectedDates.some((sel) => sel.isSame(d, "day"))
40
+ : false;
41
+ const isCurrentMonth = (d) => d.isSame(currentMonth, "month");
42
+ const isInRange = (d) => range.start &&
43
+ range.end &&
44
+ d.isBetween(range.start, range.end, "day", "[]");
45
+ const handlePrevMonth = () => setCurrentMonth((prev) => prev.clone().subtract(1, "month"));
46
+ const handleNextMonth = () => setCurrentMonth((prev) => prev.clone().add(1, "month"));
47
+ const handleDateClick = (day) => {
48
+ if (isDateDisabled(day))
49
+ return;
50
+ if (!isCurrentMonth(day)) {
51
+ setCurrentMonth(day.clone().startOf("month"));
52
+ }
53
+ if (selectMode === "range") {
54
+ if (!range.start || (range.start && range.end)) {
55
+ setRange({ start: day, end: null });
56
+ }
57
+ else {
58
+ const end = day.isBefore(range.start) ? range.start : day;
59
+ const start = day.isBefore(range.start) ? day : range.start;
60
+ setRange({ start, end });
61
+ onChange === null || onChange === void 0 ? void 0 : onChange({ start: start.toDate(), end: end.toDate() });
62
+ }
63
+ }
64
+ else if (selectMode === "multi") {
65
+ const exists = selectedDates.some((d) => d.isSame(day, "day"));
66
+ const updated = exists
67
+ ? selectedDates.filter((d) => !d.isSame(day, "day"))
68
+ : [...selectedDates, day];
69
+ setSelectedDates(updated);
70
+ onChange === null || onChange === void 0 ? void 0 : onChange(updated.map((d) => d.toDate()));
71
+ }
72
+ else {
73
+ setSelectedDate(day);
74
+ onChange === null || onChange === void 0 ? void 0 : onChange(day.toDate());
75
+ }
76
+ };
77
+ useEffect(() => {
78
+ if (!value)
79
+ return;
80
+ let newDate;
81
+ if (selectMode === "single" && value instanceof Date) {
82
+ newDate = moment(value);
83
+ setSelectedDate(newDate);
84
+ setCurrentMonth(newDate.clone().startOf("month"));
85
+ }
86
+ if (selectMode === "multi" && Array.isArray(value)) {
87
+ const dates = value.map((d) => moment(d));
88
+ setSelectedDates(dates);
89
+ if (dates.length > 0) {
90
+ setCurrentMonth(dates[0].clone().startOf("month"));
91
+ }
92
+ }
93
+ if (selectMode === "range" &&
94
+ typeof value === "object" &&
95
+ "start" in value &&
96
+ "end" in value) {
97
+ const start = moment(value.start);
98
+ const end = moment(value.end);
99
+ setRange({ start, end });
100
+ setCurrentMonth(start.clone().startOf("month"));
101
+ }
102
+ }, [value, selectMode]);
103
+ return (_jsxs("div", { className: "p-4 max-w-sm mx-auto rounded-xl", children: [_jsxs("div", { className: "flex justify-between items-center mb-4", children: [_jsx("button", { onClick: handlePrevMonth, className: "custom-animation", children: _jsx(Icon, { icon: "weui:arrow-filled", className: "rotate-180 h-6 w-6 hover:text-primary hover:text-opacity-70 hover:-translate-x-1 custom-animation" }) }), _jsx("h2", { className: "text-lg font-semibold text-primary", children: currentMonth.format("MMMM YYYY") }), _jsx("button", { onClick: handleNextMonth, className: "custom-animation", children: _jsx(Icon, { icon: "weui:arrow-filled", className: "h-6 w-6 hover:text-primary hover:text-opacity-70 hover:translate-x-1 custom-animation" }) })] }), _jsx("div", { className: "grid grid-cols-7 text-center text-text text-sm mb-2", children: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => (_jsx("div", { children: day }, day))) }), _jsx("div", { className: "grid grid-cols-7 gap-1 animate-fade-in", children: calendar.flat().map((dayItem, i) => {
104
+ const disabled = isDateDisabled(dayItem);
105
+ const outOfMonth = !isCurrentMonth(dayItem);
106
+ return (_jsx("button", { onClick: () => handleDateClick(dayItem), disabled: disabled, className: clsx("w-8 h-8 rounded-lg text-sm flex items-center justify-center custom-animation", {
107
+ "bg-primary text-white": isSelected(dayItem),
108
+ "bg-primary/30 text-white": isInRange(dayItem),
109
+ "bg-primary bg-opacity-10": isToday(dayItem) && !isSelected(dayItem),
110
+ "text-text": isCurrentMonth(dayItem),
111
+ "text-text-light": outOfMonth,
112
+ "hover:bg-primary hover:text-white": !disabled,
113
+ "opacity-50 cursor-not-allowed": disabled,
114
+ }), children: dayItem.date() }, i));
115
+ }) }, currentMonth.format("YYYY-MM"))] }));
116
+ }
@@ -4,5 +4,5 @@ export type Props = {
4
4
  setColor: (newColor: string) => void;
5
5
  showDisplay?: boolean;
6
6
  } & React.InputHTMLAttributes<HTMLInputElement>;
7
- export default function ColorPicker({ color, setColor, showDisplay, ...props }: Props): import("react/jsx-runtime").JSX.Element;
7
+ export default function ColorPicker({ color, setColor, showDisplay, className, style, ...props }: Props): import("react/jsx-runtime").JSX.Element;
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/color-picker/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,MAAM,KAAK,GAAG;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;AAChD,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,KAAK,EACL,QAAQ,EACR,WAAkB,EAClB,GAAG,KAAK,EACT,EAAE,KAAK,2CAyBP"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/color-picker/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,MAAM,KAAK,GAAG;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;AAEhD,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,KAAK,EACL,QAAQ,EACR,WAAkB,EAClB,SAAc,EACd,KAAK,EACL,GAAG,KAAK,EACT,EAAE,KAAK,2CA8BP"}
@@ -13,9 +13,10 @@ var __rest = (this && this.__rest) || function (s, e) {
13
13
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
14
  import { isColorLight } from "../../utils/color";
15
15
  export default function ColorPicker(_a) {
16
- var { color, setColor, showDisplay = true } = _a, props = __rest(_a, ["color", "setColor", "showDisplay"]);
17
- return (_jsxs("div", { className: "relative flex items-center rounded-lg", children: [showDisplay && (_jsx("div", { className: "w-full h-10 rounded-lg flex items-center justify-center", style: {
16
+ var { color, setColor, showDisplay = true, className = "", style } = _a, props = __rest(_a, ["color", "setColor", "showDisplay", "className", "style"]);
17
+ return (_jsxs("label", { className: `relative inline-block overflow-hidden ${className}`, style: style, children: [showDisplay && (_jsx("div", { className: "w-full h-full flex items-center justify-center", style: {
18
18
  backgroundColor: color,
19
19
  color: isColorLight(color) ? "#000000" : "#FFFFFF",
20
- }, children: _jsx("p", { children: color }) })), _jsx("input", Object.assign({ type: "color", className: "absolute inset-0 w-full h-full opacity-0 cursor-pointer", value: color, onChange: (e) => setColor(e.target.value) }, props))] }));
20
+ borderRadius: "inherit",
21
+ }, children: _jsx("p", { className: "text-xs", children: color }) })), _jsx("input", Object.assign({ type: "color", className: "absolute inset-0 w-full h-full opacity-0 appearance-none cursor-pointer", value: color, onChange: (e) => setColor(e.target.value) }, props))] }));
21
22
  }
@@ -0,0 +1,19 @@
1
+ export type Props<T extends {
2
+ start: string;
3
+ end: string;
4
+ isAllDay?: boolean;
5
+ }> = {
6
+ day?: string | Date;
7
+ events: T[];
8
+ EventItem: (props: {
9
+ event: T;
10
+ }) => JSX.Element;
11
+ loading?: boolean;
12
+ setDay?: (day: Date) => void;
13
+ };
14
+ export default function DayCalendar<T extends {
15
+ start: string;
16
+ end: string;
17
+ isAllDay?: boolean;
18
+ }>({ day, events, EventItem, loading, setDay }: Props<T>): import("react/jsx-runtime").JSX.Element;
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/day-calendar/index.tsx"],"names":[],"mappings":"AAgBA,MAAM,MAAM,KAAK,CACf,CAAC,SAAS;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,IAC1D;IACF,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,CAAC,EAAE,CAAC;IACZ,SAAS,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,CAAC,CAAA;KAAE,KAAK,GAAG,CAAC,OAAO,CAAC;IAChD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,IAAI,CAAC;CAC9B,CAAC;AACF,MAAM,CAAC,OAAO,UAAU,WAAW,CACjC,CAAC,SAAS;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,EAC5D,EAAE,GAAgB,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,2CAuKnE"}
@@ -0,0 +1,60 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useMemo } from "react";
4
+ import { Utils } from "sea-platform-helpers";
5
+ import Skeleton from "../skeleton";
6
+ const moment = Utils.Moment.default;
7
+ const HOURS = Array.from({ length: 24 }, (_, i) => `${i}:00`);
8
+ export default function DayCalendar({ day = new Date(), events, EventItem, loading, setDay }) {
9
+ const today = moment().format("YYYY-MM-DD");
10
+ const selectedDay = moment(day).format("YYYY-MM-DD");
11
+ const dayMoment = useMemo(() => moment(day).startOf("day"), [day]);
12
+ const allDayEvents = useMemo(() => events.filter((e) => e.isAllDay), [events]);
13
+ const timedEvents = useMemo(() => events.filter((e) => !e.isAllDay), [events]);
14
+ const getPositionedEvents = (dayEvents) => {
15
+ const positioned = [];
16
+ const sorted = [...dayEvents].sort((a, b) => moment(a.start).diff(moment(b.start)));
17
+ const columns = [];
18
+ sorted.forEach((event) => {
19
+ const start = moment(event.start);
20
+ let placed = false;
21
+ for (const col of columns) {
22
+ if (!col.some((e) => moment(e.end).isAfter(start))) {
23
+ col.push(event);
24
+ placed = true;
25
+ break;
26
+ }
27
+ }
28
+ if (!placed) {
29
+ columns.push([event]);
30
+ }
31
+ });
32
+ columns.forEach((col, colIndex) => {
33
+ col.forEach((event) => {
34
+ const start = moment(event.start);
35
+ const end = moment(event.end);
36
+ const duration = end.diff(start, "minutes");
37
+ const startMinutes = start.hours() * 60 + start.minutes();
38
+ positioned.push({
39
+ event,
40
+ top: (startMinutes / 60) * 64,
41
+ height: (duration / 60) * 64,
42
+ leftPercent: (colIndex / columns.length) * 100,
43
+ widthPercent: 100 / columns.length,
44
+ zIndex: colIndex,
45
+ });
46
+ });
47
+ });
48
+ return positioned;
49
+ };
50
+ const positionedEvents = getPositionedEvents(timedEvents);
51
+ return (_jsxs("div", { className: "flex overflow-x-auto", children: [_jsxs("div", { className: "w-14 shrink-0", children: [_jsx("div", { className: "h-20 border-b border-gray-200" }), _jsx("div", { className: "h-[74px] text-sm text-text border-b border-gray-200 flex items-center justify-center", children: "All-Day" }), HOURS.map((hour) => (_jsx("div", { className: "h-16 text-xs text-text text-right pr-1 border-b border-gray-200", children: moment(`${today} ${hour}`).format("hh:mm a") }, hour)))] }), _jsxs("div", { className: "flex-1 border-l border-t border-gray-200 relative", children: [_jsx("div", { className: "h-20 flex items-center justify-center border-b border-gray-200 sticky top-0 z-10", children: _jsx("p", { className: "text-2xl font-semibold text-primary", children: dayMoment.format("dddd, MMM DD, YYYY") }) }), _jsx("div", { className: "h-[74px] border-b border-gray-200 px-1 py-1", children: allDayEvents.map((event, idx) => (_jsx("div", { className: "mb-1", children: _jsx(EventItem, { event: event }) }, idx))) }), _jsxs("div", { className: "relative h-[1536px] pt-0", children: [HOURS.map((_, j) => (_jsx("div", { className: "absolute left-0 right-0 h-16 border-t border-dashed border-gray-200", style: { top: j * 64 } }, j))), !loading
52
+ ? positionedEvents.map(({ event, top, height, leftPercent, widthPercent, zIndex }, j) => (_jsx("div", { className: "absolute px-1", style: {
53
+ top,
54
+ height,
55
+ left: `${leftPercent}%`,
56
+ width: `${widthPercent}%`,
57
+ zIndex,
58
+ }, children: _jsx(EventItem, { event: event }) }, j)))
59
+ : Array.from({ length: Utils.Number.getRandomInt(0, 5) }).map((_, j) => (_jsx(Skeleton, { className: "absolute left-1 right-1 top-[100px] h-16", style: { top: Utils.Number.getRandomInt(60, 1200) } }, j)))] })] })] }));
60
+ }
@@ -2,13 +2,13 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import clsx from "clsx";
3
3
  import { Icon } from "@iconify/react";
4
4
  export default function Drawer({ isOpen, onClose, placement = "right", overlay = true, className, children, }) {
5
- return (_jsxs(_Fragment, { children: [overlay && isOpen && (_jsx("div", { className: clsx("fixed z-50 inset-0 bg-black bg-opacity-50 transition-opacity duration-300", { "opacity-0 pointer-events-none": !isOpen }), onClick: onClose })), _jsxs("div", { className: clsx("fixed bg-white shadow-lg z-50 transition-transform duration-300 py-7 px-2", {
5
+ return (_jsxs(_Fragment, { children: [overlay && isOpen && (_jsx("div", { className: clsx("fixed z-50 inset-0 bg-black bg-opacity-50 transition-opacity duration-300", { "opacity-0 pointer-events-none": !isOpen }), onClick: onClose })), _jsxs("div", { className: clsx("fixed bg-white shadow-lg z-50 transition-transform duration-300 py-7 px-2 max-h-screen overflow-y-auto", {
6
6
  "top-0 left-0 w-full h-auto transform -translate-y-full": placement === "top" && !isOpen,
7
7
  "top-0 left-0 w-full h-auto translate-y-0": placement === "top" && isOpen,
8
- "top-0 right-0 h-full transform translate-x-full w-[85%] md:w-[40%]": placement === "right" && !isOpen,
9
- "top-0 right-0 h-full translate-x-0 w-[85%] md:w-[40%]": placement === "right" && isOpen,
10
- "top-0 left-0 h-full transform -translate-x-full w-[85%] md:w-[40%]": placement === "left" && !isOpen,
11
- "top-0 left-0 h-full translate-x-0 w-[85%] md:w-[40%]": placement === "left" && isOpen,
8
+ "top-0 right-0 max-h-screen h-full transform translate-x-full w-[85%] md:w-[40%]": placement === "right" && !isOpen,
9
+ "top-0 right-0 max-h-screen h-full translate-x-0 w-[85%] md:w-[40%]": placement === "right" && isOpen,
10
+ "top-0 left-0 max-h-screen h-full transform -translate-x-full w-[85%] md:w-[40%]": placement === "left" && !isOpen,
11
+ "top-0 left-0 max-h-screen h-full translate-x-0 w-[85%] md:w-[40%]": placement === "left" && isOpen,
12
12
  "bottom-0 left-0 w-full h-auto transform translate-y-full": placement === "bottom" && !isOpen,
13
13
  "bottom-0 left-0 w-full h-auto translate-y-0": placement === "bottom" && isOpen,
14
14
  }, className), children: [_jsx("button", { onClick: onClose, className: "absolute top-2 right-2 text-secondary-dark", children: _jsx(Icon, { icon: "line-md:close-small", className: "h-5 w-5 hover:scale-110 transition-all duration-300 ease-in-out" }) }), children] })] }));
@@ -1,9 +1,9 @@
1
1
  import { FileState } from "../..";
2
- type Props = {
2
+ export type Props = {
3
3
  file: FileState;
4
4
  handleUploadFile?: (file: FileState) => Promise<void>;
5
5
  handleDeleteFile?: (file: FileState) => Promise<void>;
6
+ displayMode?: boolean;
6
7
  };
7
- export default function FileItem({ file, handleUploadFile, handleDeleteFile, }: Props): import("react/jsx-runtime").JSX.Element;
8
- export {};
8
+ export default function FileItem({ file, handleUploadFile, handleDeleteFile, displayMode, }: Props): import("react/jsx-runtime").JSX.Element;
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/file-input/components/file-item/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAkB,MAAM,OAAO,CAAC;AAKlD,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,SAAS,CAAC;IAChB,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvD,CAAC;AACF,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAC/B,IAAI,EACJ,gBAAgB,EAChB,gBAAgB,GACjB,EAAE,KAAK,2CAuEP"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/file-input/components/file-item/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAkB,MAAM,OAAO,CAAC;AAKlD,MAAM,MAAM,KAAK,GAAG;IAClB,IAAI,EAAE,SAAS,CAAC;IAChB,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAC/B,IAAI,EACJ,gBAAgB,EAChB,gBAAgB,EAChB,WAAmB,GACpB,EAAE,KAAK,2CA4HP"}
@@ -1,10 +1,35 @@
1
+ "use client";
1
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useEffect, useState } from "react";
2
4
  import { UploadStatuses } from "../..";
3
5
  import Icon from "../../../icon";
4
6
  import { Utils } from "sea-platform-helpers";
5
7
  import Button from "../../../button";
6
- export default function FileItem({ file, handleUploadFile, handleDeleteFile, }) {
7
- return (_jsx("div", { className: "px-2 py-1 rounded-lg bg-info bg-opacity-20 max-w-52", children: _jsxs("div", { className: "grid grid-cols-4 gap-2 items-center", children: [_jsx("div", { className: "col-span-3", children: _jsxs("div", { children: [_jsx("p", { className: "text-sm text-text font-semibold truncate", children: file.name }), _jsx("p", { className: "text-sm text-info", children: Utils.Number.default(file.size).format("0.0 b") })] }) }), _jsx("div", { className: "col-span-1", children: _jsxs("div", { className: "flex items-center justify-end gap-1", children: [file.status === UploadStatuses.Failed && (_jsxs(_Fragment, { children: [_jsx(Icon, { icon: "mdi:cloud-remove-outline", className: "w-5 h-5 text-error" }), _jsx(Button, { type: "button", className: "bg-transparent", onClick: () => handleUploadFile(file), children: _jsx(Icon, { icon: "pajamas:retry", className: "w-5 h-5 text-primary hover:text-opacity-50 transition-all duration-300 ease-in-out" }) })] })), [UploadStatuses.Pending, UploadStatuses.Uploading].includes(file.status) && (_jsx(Icon, { icon: "line-md:uploading-loop", className: "w-5 h-5 text-info" })), file.status === UploadStatuses.Uploaded && (_jsxs(_Fragment, { children: [_jsx(Icon, { icon: "ic:outline-cloud-done", className: "w-5 h-5 text-primary" }), _jsx(Button, { type: "button", className: "bg-transparent", onClick: () => {
8
- handleDeleteFile(file);
9
- }, children: _jsx(Icon, { icon: "famicons:close", className: "w-5 h-5 text-error transition-all duration-300 ease-in-out" }) })] }))] }) })] }) }));
8
+ export default function FileItem({ file, handleUploadFile, handleDeleteFile, displayMode = false, }) {
9
+ const [previewUrl, setPreviewUrl] = useState(null);
10
+ useEffect(() => {
11
+ if (file.file) {
12
+ const url = URL.createObjectURL(file.file);
13
+ setPreviewUrl(url);
14
+ return () => URL.revokeObjectURL(url);
15
+ }
16
+ else if (file.URL) {
17
+ setPreviewUrl(file.URL);
18
+ }
19
+ }, [file.file, file.URL]);
20
+ const renderPreview = () => {
21
+ if (!previewUrl)
22
+ return null;
23
+ if (file.type.startsWith("image/")) {
24
+ return (_jsx("a", { href: previewUrl, target: "_blank", children: _jsx("img", { src: previewUrl, alt: file.name, className: "w-full h-28 object-cover rounded-md mb-1" }) }));
25
+ }
26
+ if (file.type.startsWith("video/")) {
27
+ return (_jsx("a", { href: previewUrl, target: "_blank", children: _jsx("video", { src: previewUrl, autoPlay: false, controls: false, className: "w-full h-28 object-cover rounded-md mb-1" }) }));
28
+ }
29
+ if (file.type === "application/pdf") {
30
+ return (_jsx("div", { className: "w-full h-28 flex items-center justify-center bg-white rounded-md mb-1", children: _jsx(Icon, { icon: "mdi:file-pdf-box", className: "w-12 h-12 text-red-600" }) }));
31
+ }
32
+ return (_jsx("div", { className: "w-full h-28 flex items-center justify-center bg-white rounded-md mb-1", children: _jsx(Icon, { icon: "mdi:file-outline", className: "w-10 h-10 text-gray-400" }) }));
33
+ };
34
+ return (_jsxs("div", { className: "px-2 py-1 rounded-lg max-w-52", children: [renderPreview(), _jsxs("div", { className: "grid grid-cols-4 gap-2 items-center", children: [_jsx("div", { className: "col-span-3", children: _jsxs("div", { children: [_jsx("p", { className: "text-sm text-text font-semibold truncate", children: file.name }), _jsx("p", { className: "text-sm text-info", children: Utils.Number.numeralUtils(file.size).format("0.0 b") })] }) }), _jsx("div", { className: "col-span-1", children: _jsxs("div", { className: "flex items-center justify-end gap-1", children: [file.status === UploadStatuses.Failed && (_jsxs(_Fragment, { children: [_jsx(Icon, { icon: "mdi:cloud-remove-outline", className: "w-5 h-5 text-error" }), _jsx(Button, { type: "button", className: "bg-transparent", onClick: () => handleUploadFile === null || handleUploadFile === void 0 ? void 0 : handleUploadFile(file), children: _jsx(Icon, { icon: "pajamas:retry", className: "w-5 h-5 text-primary hover:text-opacity-50 transition-all duration-300 ease-in-out" }) })] })), [UploadStatuses.Pending, UploadStatuses.Uploading].includes(file.status) && (_jsx(Icon, { icon: "line-md:uploading-loop", className: "w-5 h-5 text-info" })), file.status === UploadStatuses.Uploaded && !displayMode && (_jsxs(_Fragment, { children: [_jsx(Icon, { icon: "ic:outline-cloud-done", className: "w-5 h-5 text-primary" }), _jsx(Button, { type: "button", className: "bg-transparent", onClick: () => handleDeleteFile === null || handleDeleteFile === void 0 ? void 0 : handleDeleteFile(file), children: _jsx(Icon, { icon: "famicons:close", className: "w-5 h-5 text-error hover:text-opacity-70 custom-animation" }) })] }))] }) })] })] }));
10
35
  }
@@ -15,8 +15,9 @@ export declare enum UploadStatuses {
15
15
  }
16
16
  export type FileState = {
17
17
  id: string;
18
- serverId: string | undefined;
19
- file?: File | undefined;
18
+ serverId?: string;
19
+ file?: File;
20
+ URL?: string;
20
21
  name: string;
21
22
  size: number;
22
23
  type: string;
@@ -25,11 +26,9 @@ export type FileState = {
25
26
  };
26
27
  export type Props<T> = {
27
28
  name: string;
28
- files: FileState[];
29
- setFiles: React.Dispatch<React.SetStateAction<FileState[]>>;
30
29
  acceptedTypes?: AcceptedValuesArray;
31
- multiple: boolean;
32
- errorMessage?: string | boolean;
30
+ multiple?: boolean;
31
+ initialFiles?: FileState[];
33
32
  onUpload: (file: FileState) => Promise<{
34
33
  id: string;
35
34
  } & T>;
@@ -38,7 +37,25 @@ export type Props<T> = {
38
37
  } & T>;
39
38
  onUploadSuccess?: (file: T) => void;
40
39
  onDeleteSuccess?: (file: T) => void;
40
+ errorMessage?: string;
41
+ children: (props: {
42
+ inputRef: React.RefObject<HTMLInputElement>;
43
+ inputProps: {
44
+ id: string;
45
+ name: string;
46
+ type: string;
47
+ accept: string;
48
+ multiple: boolean;
49
+ onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
50
+ };
51
+ isDragging: boolean;
52
+ files: FileState[];
53
+ handleDeleteFile: (file: FileState) => void;
54
+ handleUploadFile: (file: FileState) => void;
55
+ setFiles: React.Dispatch<React.SetStateAction<FileState[]>>;
56
+ errorMessage?: string;
57
+ }) => React.ReactNode;
41
58
  };
42
- export default function FileInput<T>({ name, files, setFiles, acceptedTypes, multiple, errorMessage, onUpload, onDelete, onUploadSuccess, onDeleteSuccess, }: Props<T>): import("react/jsx-runtime").JSX.Element;
59
+ export default function FileInput<T>({ name, acceptedTypes, initialFiles, multiple, onUpload, onDelete, onUploadSuccess, onDeleteSuccess, children, errorMessage, }: Props<T>): import("react/jsx-runtime").JSX.Element;
43
60
  export {};
44
61
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/file-input/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAOhD,oBAAY,aAAa;IACvB,KAAK,YAAY;IACjB,KAAK,YAAY;IACjB,KAAK,YAAY;IACjB,GAAG,oBAAoB;IACvB,IAAI,eAAe;CACpB;AAED,KAAK,mBAAmB,GAAG,CAAC,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC;AAEtD,oBAAY,cAAc;IACxB,OAAO,YAAY;IACnB,SAAS,cAAc;IACvB,QAAQ,aAAa;IACrB,MAAM,WAAW;CAClB;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,IAAI,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,cAAc,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IAC5D,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,CAAC,CAAC,CAAC;IAC3D,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,CAAC,CAAC,CAAC;IAC3D,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IACpC,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,CAAC,EAAE,EACnC,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,aAAkB,EAClB,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,eAAe,GAChB,EAAE,KAAK,CAAC,CAAC,CAAC,2CAkIV"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/file-input/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAE3D,oBAAY,aAAa;IACvB,KAAK,YAAY;IACjB,KAAK,YAAY;IACjB,KAAK,YAAY;IACjB,GAAG,oBAAoB;IACvB,IAAI,eAAe;CACpB;AAED,KAAK,mBAAmB,GAAG,CAAC,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC;AAEtD,oBAAY,cAAc;IACxB,OAAO,YAAY;IACnB,SAAS,cAAc;IACvB,QAAQ,aAAa;IACrB,MAAM,WAAW;CAClB;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,cAAc,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,SAAS,EAAE,CAAC;IAC3B,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,CAAC,CAAC,CAAC;IAC3D,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,CAAC,CAAC,CAAC;IAC3D,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IACpC,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,QAAQ,EAAE,CAAC,KAAK,EAAE;QAChB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAC5C,UAAU,EAAE;YACV,EAAE,EAAE,MAAM,CAAC;YACX,IAAI,EAAE,MAAM,CAAC;YACb,IAAI,EAAE,MAAM,CAAC;YACb,MAAM,EAAE,MAAM,CAAC;YACf,QAAQ,EAAE,OAAO,CAAC;YAClB,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;SAC5D,CAAC;QACF,UAAU,EAAE,OAAO,CAAC;QACpB,KAAK,EAAE,SAAS,EAAE,CAAC;QACnB,gBAAgB,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;QAC5C,gBAAgB,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;QAC5C,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QAC5D,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,KAAK,KAAK,CAAC,SAAS,CAAC;CACvB,CAAC;AAKF,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,CAAC,EAAE,EACnC,IAAI,EACJ,aAAkB,EAClB,YAAiB,EACjB,QAAgB,EAChB,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,eAAe,EACf,QAAQ,EACR,YAAY,GACb,EAAE,KAAK,CAAC,CAAC,CAAC,2CA0HV"}
@@ -8,11 +8,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
12
- import { useState, useRef } from "react";
13
- import clsx from "clsx";
14
- import FileItem from "./components/file-item";
15
- const generateTempFileId = (type, size, name) => `(${type})-${size}-${name}`;
11
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
12
+ import { useEffect, useRef, useState } from "react";
16
13
  export var AcceptedTypes;
17
14
  (function (AcceptedTypes) {
18
15
  AcceptedTypes["Image"] = "image/*";
@@ -28,15 +25,17 @@ export var UploadStatuses;
28
25
  UploadStatuses["Uploaded"] = "Uploaded";
29
26
  UploadStatuses["Failed"] = "Failed";
30
27
  })(UploadStatuses || (UploadStatuses = {}));
31
- export default function FileInput({ name, files, setFiles, acceptedTypes = [], multiple, errorMessage, onUpload, onDelete, onUploadSuccess, onDeleteSuccess, }) {
32
- const currentFileIds = files.map((file) => generateTempFileId(file.type, file.size, file.name));
33
- const [isDragging, setIsDragging] = useState(false);
28
+ const generateTempFileId = (type, size, name) => `(${type})-${size}-${name}`;
29
+ export default function FileInput({ name, acceptedTypes = [], initialFiles = [], multiple = false, onUpload, onDelete, onUploadSuccess, onDeleteSuccess, children, errorMessage, }) {
34
30
  const inputRef = useRef(null);
31
+ const [isDragging, setIsDragging] = useState(false);
32
+ const [files, setFiles] = useState(initialFiles);
33
+ const currentFileIds = files.map((file) => generateTempFileId(file.type, file.size, file.name));
35
34
  const handleFiles = (selectedFiles) => {
36
35
  if (!selectedFiles)
37
36
  return;
38
- const selectedFilesArray = Array.from(selectedFiles);
39
- const filesToUpload = selectedFilesArray.filter((f) => !currentFileIds.includes(generateTempFileId(f.type, f.size, f.name)));
37
+ const selectedArray = Array.from(selectedFiles);
38
+ const filesToUpload = selectedArray.filter((f) => !currentFileIds.includes(generateTempFileId(f.type, f.size, f.name)));
40
39
  const newFiles = filesToUpload.map((f) => ({
41
40
  id: generateTempFileId(f.type, f.size, f.name),
42
41
  serverId: undefined,
@@ -48,38 +47,61 @@ export default function FileInput({ name, files, setFiles, acceptedTypes = [], m
48
47
  status: UploadStatuses.Pending,
49
48
  }));
50
49
  setFiles((prev) => [...prev, ...newFiles]);
51
- for (let i = 0; i < newFiles.length; i++) {
52
- handleUploadFile(newFiles[i]);
53
- }
50
+ newFiles.forEach(handleUploadFile);
54
51
  };
55
52
  const handleUploadFile = (file) => __awaiter(this, void 0, void 0, function* () {
53
+ setFiles((prev) => prev.map((f) => f.id === file.id ? Object.assign(Object.assign({}, f), { status: UploadStatuses.Uploading }) : f));
56
54
  try {
57
- setFiles((prev) => prev.map((f) => f.id === file.id ? Object.assign(Object.assign({}, f), { status: UploadStatuses.Uploading }) : f));
58
55
  const result = yield onUpload(file);
59
- onUploadSuccess(result);
60
- setFiles((prev) => prev.map((f) => f.id === file.id
61
- ? Object.assign(Object.assign({}, f), { serverId: result.id, status: UploadStatuses.Uploaded, progress: 100 }) : f));
56
+ onUploadSuccess === null || onUploadSuccess === void 0 ? void 0 : onUploadSuccess(result); // This allows parent to set `iconFileId`
57
+ // For single-file mode: remove old uploaded file if any
58
+ if (!multiple) {
59
+ const uploadedFile = Object.assign(Object.assign({}, file), { serverId: result.id, status: UploadStatuses.Uploaded, progress: 100 });
60
+ const oldUploaded = files.find((f) => f.status === UploadStatuses.Uploaded);
61
+ // Delete old uploaded file
62
+ if (oldUploaded && oldUploaded.serverId) {
63
+ yield onDelete(oldUploaded);
64
+ onDeleteSuccess === null || onDeleteSuccess === void 0 ? void 0 : onDeleteSuccess(oldUploaded);
65
+ }
66
+ setFiles([uploadedFile]); // Keep only the new one
67
+ }
68
+ else {
69
+ setFiles((prev) => prev.map((f) => f.id === file.id
70
+ ? Object.assign(Object.assign({}, f), { serverId: result.id, status: UploadStatuses.Uploaded, progress: 100 }) : f));
71
+ }
62
72
  }
63
- catch (error) {
73
+ catch (_a) {
64
74
  setFiles((prev) => prev.map((f) => f.id === file.id ? Object.assign(Object.assign({}, f), { status: UploadStatuses.Failed }) : f));
65
75
  }
66
76
  });
67
- const handleDrop = (event) => {
68
- event.preventDefault();
69
- event.stopPropagation();
70
- setIsDragging(false);
71
- handleFiles(event.dataTransfer.files);
72
- };
73
77
  const handleDeleteFile = (file) => __awaiter(this, void 0, void 0, function* () {
74
78
  try {
75
79
  const result = yield onDelete(file);
76
- onDeleteSuccess(result);
77
- setFiles((prev) => prev.filter((file) => file.serverId !== result.id));
80
+ onDeleteSuccess === null || onDeleteSuccess === void 0 ? void 0 : onDeleteSuccess(result);
81
+ setFiles((prev) => prev.filter((f) => f.serverId !== result.id));
78
82
  }
79
- catch (error) { }
83
+ catch (_a) { }
80
84
  });
81
- return (_jsxs("div", { className: "w-full flex flex-col gap-1", children: [(!files.length || multiple) && (_jsxs("div", { className: clsx("border-0.5 px-3 py-2 rounded-xl text-center", "cursor-pointer transition-all duration-200 ease-in-out", "hover:border-primary", errorMessage ? "border-error" : isDragging && "border-primary"), onDragOver: (e) => {
82
- e.preventDefault();
83
- setIsDragging(true);
84
- }, onDragLeave: () => setIsDragging(false), onDrop: handleDrop, onClick: () => { var _a; return (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, children: [_jsx("p", { className: "text-text-light", children: "Drag & Drop files here or click to select files" }), _jsx("input", { id: name, name: name, ref: inputRef, type: "file", className: "hidden", accept: acceptedTypes.join(","), multiple: multiple, onChange: (e) => handleFiles(e.target.files) })] })), _jsx("div", { className: "flex flex-nowrap gap-2 overflow-y-auto", children: files.map((f, i) => (_jsx(FileItem, { file: f, handleUploadFile: handleUploadFile, handleDeleteFile: handleDeleteFile }, `file-${name}-${i}`))) }), errorMessage && (_jsx("p", { className: "pl-1 text-sm text-error", children: errorMessage }))] }));
85
+ useEffect(() => {
86
+ if (initialFiles && initialFiles.length > 0) {
87
+ setFiles(initialFiles);
88
+ }
89
+ }, [initialFiles]);
90
+ return (_jsx(_Fragment, { children: children({
91
+ inputRef,
92
+ inputProps: {
93
+ id: name,
94
+ name,
95
+ type: "file",
96
+ accept: acceptedTypes.join(","),
97
+ multiple,
98
+ onChange: (e) => handleFiles(e.target.files),
99
+ },
100
+ isDragging,
101
+ files,
102
+ handleDeleteFile,
103
+ handleUploadFile,
104
+ setFiles,
105
+ errorMessage,
106
+ }) }));
85
107
  }
@@ -0,0 +1,14 @@
1
+ import React from "react";
2
+ export type Props = {
3
+ inputRef: React.RefObject<HTMLInputElement>;
4
+ inputProps: React.InputHTMLAttributes<HTMLInputElement>;
5
+ handleClick: () => void;
6
+ handleDrop: (e: React.DragEvent<HTMLDivElement>) => void;
7
+ handleDragOver: (e: React.DragEvent<HTMLDivElement>) => void;
8
+ handleDragLeave: () => void;
9
+ isDragging: boolean;
10
+ errorMessage?: string | boolean;
11
+ children?: React.ReactNode;
12
+ };
13
+ export default function FileInputV2({ inputRef, inputProps, handleClick, handleDrop, handleDragOver, handleDragLeave, isDragging, errorMessage, children, }: Props): import("react/jsx-runtime").JSX.Element;
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/file-input-v2/file-input/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAC5C,UAAU,EAAE,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;IACxD,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,UAAU,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;IACzD,cAAc,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;IAC7D,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,QAAQ,EACR,UAAU,EACV,WAAW,EACX,UAAU,EACV,cAAc,EACd,eAAe,EACf,UAAU,EACV,YAAY,EACZ,QAAQ,GACT,EAAE,KAAK,2CAuBP"}