@ikatec/nebula-react 1.0.24 → 1.0.26

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/index.mjs CHANGED
@@ -7,7 +7,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
7
  import * as PopoverPrimitive from '@radix-ui/react-popover';
8
8
  import * as LabelPrimitive from '@radix-ui/react-label';
9
9
  import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
10
- import { ChevronRight, Check, Circle, CircleX, Eye, EyeOff, X, Minus, ClockIcon, ChevronsLeft, ChevronLeft, ChevronsRight, MoreHorizontal, ChevronDown, ChevronLeftIcon, ChevronDownIcon, ChevronRightIcon, CalendarIcon, ImageUpIcon, XIcon, PhoneIcon, FileTextIcon, FileAudioIcon, FileVideoIcon, Info, CircleCheckBig } from 'lucide-react';
10
+ import { ChevronRight, Check, Circle, CircleX, Eye, EyeOff, X, Minus, ClockIcon, ChevronsLeft, ChevronLeft, ChevronsRight, MoreHorizontal, ChevronDown, ChevronLeftIcon, ChevronDownIcon, ChevronRightIcon, CalendarIcon, ImageUpIcon, XIcon, UserIcon, PhoneIcon, FileTextIcon, FileAudioIcon, FileVideoIcon, Info, CircleCheckBig } from 'lucide-react';
11
11
  import * as SeparatorPrimitive from '@radix-ui/react-separator';
12
12
  import Select, { components } from 'react-select';
13
13
  import Creatable from 'react-select/creatable';
@@ -2202,15 +2202,9 @@ var StyledAsyncCreatable = createStyledSelect(
2202
2202
  "AsyncCreatable"
2203
2203
  );
2204
2204
  var InputText = React8.forwardRef(
2205
- ({
2206
- className,
2207
- icon,
2208
- isError = false,
2209
- onClean,
2210
- iconPlacement = "start",
2211
- disabled,
2212
- ...props
2213
- }, ref) => {
2205
+ ({ className, isError = false, onClean, disabled, suffix, ...props }, ref) => {
2206
+ const icon = "icon" in props ? props.icon : null;
2207
+ const iconPlacement = "iconPlacement" in props || props.type !== "password" ? props.iconPlacement || "start" : null;
2214
2208
  const initialInputType = props.type || "text";
2215
2209
  const [type, setType] = React8.useState(initialInputType);
2216
2210
  const iconClass = {
@@ -2221,71 +2215,92 @@ var InputText = React8.forwardRef(
2221
2215
  return /* @__PURE__ */ jsxs(
2222
2216
  "div",
2223
2217
  {
2224
- className: cn("relative w-full", {
2225
- "pointer-events-none": disabled
2226
- }),
2218
+ className: cn(
2219
+ "w-full flex outline-none",
2220
+ "rounded-input",
2221
+ "border border-inputText-border-default focus-within:ring-[3px] focus-within:ring-inputText-border-focus focus-within:border-inputText-border-focus",
2222
+ "focus-within:text-inputText-text-focus placeholder:text-inputText-text-default disabled:text-inputText-text-disabled",
2223
+ isError && "border-inputText-border-danger focus-within:border-inputText-border-danger focus-within:ring-button-danger-border-focus",
2224
+ disabled && "pointer-events-none"
2225
+ ),
2227
2226
  children: [
2228
- /* @__PURE__ */ jsx(
2229
- "input",
2227
+ /* @__PURE__ */ jsxs("div", { className: "nebula-ds relative w-full", children: [
2228
+ /* @__PURE__ */ jsx(
2229
+ "input",
2230
+ {
2231
+ ref,
2232
+ className: cn(
2233
+ "w-full h-10 outline-none text-sm leading-none font-medium",
2234
+ "bg-inputText-background-default disabled:bg-inputText-background-disabled",
2235
+ "text-inputText-text-filled",
2236
+ "disabled:cursor-not-allowed",
2237
+ "rounded-input",
2238
+ "pl-4",
2239
+ !!suffix && "rounded-r-none",
2240
+ {
2241
+ "pl-10 pr-4": !!icon && iconPlacement === "start",
2242
+ "pr-10": initialInputType === "password",
2243
+ "pr-10 pl-4": !!icon && iconPlacement === "end" && initialInputType !== "password"
2244
+ },
2245
+ className
2246
+ ),
2247
+ ...{ ...props, icon: void 0, iconPlacement: void 0 },
2248
+ disabled,
2249
+ type
2250
+ }
2251
+ ),
2252
+ onClean && props.value && /* @__PURE__ */ jsx(
2253
+ "button",
2254
+ {
2255
+ type: "button",
2256
+ className: cn("absolute top-1/2 transform -translate-y-1/2", {
2257
+ "right-10": initialInputType === "password" || iconPlacement === "end",
2258
+ "right-4": initialInputType === "text" && iconPlacement === "start"
2259
+ }),
2260
+ onClick: onClean,
2261
+ children: /* @__PURE__ */ jsx(CircleX, { className: cn("w-4 h-4", iconClass) })
2262
+ }
2263
+ ),
2264
+ initialInputType === "password" && /* @__PURE__ */ jsx(
2265
+ "button",
2266
+ {
2267
+ type: "button",
2268
+ className: "nebula-ds absolute right-4 top-1/2 transform -translate-y-1/2",
2269
+ onClick: () => setType((prev) => prev === "text" ? "password" : "text"),
2270
+ children: type === "text" ? /* @__PURE__ */ jsx(Eye, { className: cn("w-4 h-4", iconClass) }) : /* @__PURE__ */ jsx(EyeOff, { className: cn("w-4 h-4", iconClass) })
2271
+ }
2272
+ ),
2273
+ icon && initialInputType !== "password" && /* @__PURE__ */ jsx(
2274
+ "span",
2275
+ {
2276
+ className: cn("absolute top-1/2 transform -translate-y-1/2", {
2277
+ "left-4": iconPlacement === "start",
2278
+ "right-4": iconPlacement === "end"
2279
+ }),
2280
+ children: /* @__PURE__ */ jsx(
2281
+ "span",
2282
+ {
2283
+ className: cn(
2284
+ "w-4 h-4 flex items-center justify-center disabled:text-inputText-icon-disabled",
2285
+ iconClass
2286
+ ),
2287
+ children: icon
2288
+ }
2289
+ )
2290
+ }
2291
+ )
2292
+ ] }),
2293
+ !!suffix && /* @__PURE__ */ jsx(
2294
+ "div",
2230
2295
  {
2231
- ref,
2232
2296
  className: cn(
2233
- "w-full h-10 outline-none rounded-input text-sm leading-none font-medium",
2234
- "bg-inputText-background-default disabled:bg-inputText-background-disabled",
2235
- "border border-inputText-border-default focus:ring-[3px] focus:ring-inputText-border-focus focus:border-inputText-border-focus",
2236
- "text-inputText-text-filled focus:text-inputText-text-focus placeholder:text-inputText-text-default disabled:text-inputText-text-disabled",
2237
- "disabled:cursor-not-allowed",
2238
- {
2239
- "pl-10 pr-4": !!icon && iconPlacement === "start",
2240
- "pr-10 pl-4": !!icon && iconPlacement === "end" && initialInputType !== "password",
2241
- "px-4": !icon,
2242
- "border-inputText-border-danger focus:border-inputText-border-danger focus:ring-button-danger-border-focus": isError
2243
- },
2244
- className
2297
+ "w-fit h-10 outline-none rounded-input text-sm leading-none font-medium rounded-l-none flex items-center px-4",
2298
+ "bg-inputText-suffixBackground disabled:bg-inputText-background-disabled",
2299
+ "text-inputText-text-filled",
2300
+ "border-l border-inputText-border-default",
2301
+ "rounded-input rounded-l-none"
2245
2302
  ),
2246
- ...props,
2247
- disabled,
2248
- type
2249
- }
2250
- ),
2251
- onClean && props.value && /* @__PURE__ */ jsx(
2252
- "button",
2253
- {
2254
- type: "button",
2255
- className: cn("absolute top-1/2 transform -translate-y-1/2", {
2256
- "right-10": initialInputType === "password" || iconPlacement === "end",
2257
- "right-4": initialInputType === "text" && iconPlacement === "start"
2258
- }),
2259
- onClick: onClean,
2260
- children: /* @__PURE__ */ jsx(CircleX, { className: cn("w-4 h-4", iconClass) })
2261
- }
2262
- ),
2263
- initialInputType === "password" && /* @__PURE__ */ jsx(
2264
- "button",
2265
- {
2266
- type: "button",
2267
- className: "nebula-ds absolute right-4 top-1/2 transform -translate-y-1/2",
2268
- onClick: () => setType((prev) => prev === "text" ? "password" : "text"),
2269
- children: type === "text" ? /* @__PURE__ */ jsx(Eye, { className: cn("w-4 h-4", iconClass) }) : /* @__PURE__ */ jsx(EyeOff, { className: cn("w-4 h-4", iconClass) })
2270
- }
2271
- ),
2272
- icon && /* @__PURE__ */ jsx(
2273
- "span",
2274
- {
2275
- className: cn("absolute top-1/2 transform -translate-y-1/2", {
2276
- "left-4": iconPlacement === "start",
2277
- "right-4": iconPlacement === "end" && initialInputType !== "password"
2278
- }),
2279
- children: /* @__PURE__ */ jsx(
2280
- "span",
2281
- {
2282
- className: cn(
2283
- "w-4 h-4 flex items-center justify-center disabled:text-inputText-icon-disabled",
2284
- iconClass
2285
- ),
2286
- children: icon
2287
- }
2288
- )
2303
+ children: suffix
2289
2304
  }
2290
2305
  )
2291
2306
  ]
@@ -3866,13 +3881,44 @@ var Calendar = ({
3866
3881
  }
3867
3882
  );
3868
3883
  };
3869
-
3870
- // src/utils/valid-date-format.ts
3871
- function dateFormatIsValid(dateStr, locale) {
3872
- const regexBR = /^(?:(?:31\/(0[13578]|1[02]))\/(?:\d{4})|(?:29|30)\/(0[13-9]|1[0-2])\/(?:\d{4})|29\/02\/(?:\d\d(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)|(?:0[1-9]|1\d|2[0-8])\/(0[1-9]|1[0-2])\/(?:\d{4}))$/;
3873
- const regexUS = /^(?:(?:(0[13578]|1[02])\/31)\/(?:\d{4})|(?:(0[13-9]|1[0-2])\/(29|30))\/(?:\d{4})|(?:02\/29)\/(?:\d\d(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)|(?:(0[1-9]|1[0-2])\/(0[1-9]|1\d|2[0-8]))\/(?:\d{4}))$/;
3874
- const regex = locale === "en-US" ? regexUS : regexBR;
3875
- return regex.test(dateStr);
3884
+ function useClickOutside(refs, onClickOutside) {
3885
+ useEffect(() => {
3886
+ const refArray = Array.isArray(refs) ? refs : [refs];
3887
+ function handleClick(event) {
3888
+ const isInside = refArray.some(
3889
+ (ref) => ref?.current && ref?.current.contains(event.target)
3890
+ );
3891
+ if (!isInside) {
3892
+ onClickOutside();
3893
+ }
3894
+ }
3895
+ function handlePressEsc(event) {
3896
+ if (event.key === "Esc") {
3897
+ onClickOutside();
3898
+ }
3899
+ }
3900
+ document.addEventListener("mousedown", handleClick);
3901
+ document.addEventListener("touchstart", handleClick);
3902
+ document.addEventListener("keypress", handlePressEsc);
3903
+ return () => {
3904
+ document.removeEventListener("mousedown", handleClick);
3905
+ document.removeEventListener("touchstart", handleClick);
3906
+ document.removeEventListener("keypress", handlePressEsc);
3907
+ };
3908
+ }, [refs, onClickOutside]);
3909
+ }
3910
+ function useKeyPress(key, callback) {
3911
+ useEffect(() => {
3912
+ function handleKeyDown(event) {
3913
+ if (event.key === key) {
3914
+ callback();
3915
+ }
3916
+ }
3917
+ window.addEventListener("keydown", handleKeyDown);
3918
+ return () => {
3919
+ window.removeEventListener("keydown", handleKeyDown);
3920
+ };
3921
+ }, [key, callback]);
3876
3922
  }
3877
3923
  var formatDateToSubmit = (dateStr, timeFallback = "23:59") => {
3878
3924
  try {
@@ -3893,6 +3939,14 @@ var formatDateToSubmit = (dateStr, timeFallback = "23:59") => {
3893
3939
  return void 0;
3894
3940
  }
3895
3941
  };
3942
+
3943
+ // src/utils/valid-date-format.ts
3944
+ function dateFormatIsValid(dateStr, locale) {
3945
+ const regexBR = /^(?:(?:31\/(0[13578]|1[02]))\/(?:\d{4})|(?:29|30)\/(0[13-9]|1[0-2])\/(?:\d{4})|29\/02\/(?:\d\d(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)|(?:0[1-9]|1\d|2[0-8])\/(0[1-9]|1[0-2])\/(?:\d{4}))$/;
3946
+ const regexUS = /^(?:(?:(0[13578]|1[02])\/31)\/(?:\d{4})|(?:(0[13-9]|1[0-2])\/(29|30))\/(?:\d{4})|(?:02\/29)\/(?:\d\d(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)|(?:(0[1-9]|1[0-2])\/(0[1-9]|1\d|2[0-8]))\/(?:\d{4}))$/;
3947
+ const regex = locale === "en-US" ? regexUS : regexBR;
3948
+ return regex.test(dateStr);
3949
+ }
3896
3950
  var dateIsAvailable = (inputDate, disabledDates) => {
3897
3951
  if (!disabledDates || !inputDate) return true;
3898
3952
  const dateIsDisabled = (d, matcher) => {
@@ -4017,61 +4071,57 @@ var InputDatePickerSingle = ({
4017
4071
  replacement: { _: /\d/ }
4018
4072
  };
4019
4073
  const inputRef = useMask(maskOptions);
4020
- return /* @__PURE__ */ jsx("div", { className: "nebula-ds w-full", children: /* @__PURE__ */ jsxs(Popover, { open: popoverIsOpen, onOpenChange: setPopoverIsOpen, children: [
4021
- /* @__PURE__ */ jsx(PopoverTrigger, { className, asChild: true, children: /* @__PURE__ */ jsx(
4022
- "div",
4074
+ const conteinerRef = useRef(null);
4075
+ const calendarRef = useRef(null);
4076
+ useClickOutside([conteinerRef, calendarRef], () => {
4077
+ setPopoverIsOpen(false);
4078
+ });
4079
+ useKeyPress("Escape", () => {
4080
+ setPopoverIsOpen(false);
4081
+ });
4082
+ return /* @__PURE__ */ jsxs("div", { className: "nebula-ds w-full", ref: conteinerRef, children: [
4083
+ /* @__PURE__ */ jsx(
4084
+ InputText,
4023
4085
  {
4024
- onClick: (e) => e.preventDefault(),
4025
- onFocus: (e) => e.preventDefault(),
4026
- children: /* @__PURE__ */ jsx(
4027
- InputText,
4086
+ ref: inputRef,
4087
+ placeholder,
4088
+ value,
4089
+ className,
4090
+ onChange: (e) => handleInnerInputChange(e.target.value),
4091
+ onKeyDown: handleKeyDown,
4092
+ icon: /* @__PURE__ */ jsx(
4093
+ CalendarIcon,
4028
4094
  {
4029
- ref: inputRef,
4030
- placeholder,
4031
- value,
4032
- className,
4033
- onChange: (e) => handleInnerInputChange(e.target.value),
4034
- onKeyDown: handleKeyDown,
4035
- icon: /* @__PURE__ */ jsx(
4036
- CalendarIcon,
4037
- {
4038
- tabIndex: 0,
4039
- role: "button",
4040
- onClick: () => setPopoverIsOpen((s) => !s),
4041
- onKeyUp: (e) => {
4042
- if (e.key === "Enter") {
4043
- setPopoverIsOpen((s) => !s);
4044
- }
4045
- },
4046
- className: "nebula-ds cursor-pointer"
4047
- }
4048
- ),
4049
- iconPlacement: "end",
4095
+ tabIndex: 0,
4096
+ role: "button",
4097
+ onClick: () => setPopoverIsOpen((s) => !s),
4050
4098
  onKeyUp: (e) => {
4051
- if (e.key === "ArrowDown") {
4052
- setPopoverIsOpen(true);
4099
+ if (e.key === "Enter") {
4100
+ setPopoverIsOpen((s) => !s);
4053
4101
  }
4054
4102
  },
4055
- maxLength: 10,
4056
- onClean: onClean ? () => {
4057
- onClean();
4058
- handleClearValue();
4059
- } : void 0,
4060
- ...rest
4103
+ className: "nebula-ds cursor-pointer"
4061
4104
  }
4062
- )
4105
+ ),
4106
+ iconPlacement: "end",
4107
+ onKeyUp: (e) => {
4108
+ if (e.key === "ArrowDown") {
4109
+ setPopoverIsOpen(true);
4110
+ }
4111
+ },
4112
+ maxLength: 10,
4113
+ onClean: onClean ? () => {
4114
+ onClean();
4115
+ handleClearValue();
4116
+ } : void 0,
4117
+ ...rest
4063
4118
  }
4064
- ) }),
4065
- /* @__PURE__ */ jsx(
4066
- PopoverContent,
4119
+ ),
4120
+ /* @__PURE__ */ jsx("div", { className: "nebula-ds relative", children: popoverIsOpen && /* @__PURE__ */ jsx(
4121
+ "div",
4067
4122
  {
4068
- side: "bottom",
4069
- className: "nebula-ds p-0 border-none bg-transparent shadow-none absolute",
4070
- align: "start",
4071
- collisionPadding: 8,
4072
- avoidCollisions: true,
4073
- asChild: false,
4074
- style: { position: "absolute" },
4123
+ className: "nebula-ds absolute top-full left-0-0 z-40 pb-2 pt-1",
4124
+ ref: calendarRef,
4075
4125
  children: /* @__PURE__ */ jsx(
4076
4126
  Calendar,
4077
4127
  {
@@ -4087,8 +4137,8 @@ var InputDatePickerSingle = ({
4087
4137
  }
4088
4138
  )
4089
4139
  }
4090
- )
4091
- ] }) });
4140
+ ) })
4141
+ ] });
4092
4142
  };
4093
4143
  var InputTime = forwardRef(
4094
4144
  ({ value = "", onChange, placeholder = "--:--", ...rest }, ref) => {
@@ -4168,7 +4218,10 @@ var InputDateTimePickerSingle = ({
4168
4218
  ...rest
4169
4219
  }) => {
4170
4220
  const [innerTimeValue, setInnerTimeValue] = useState(
4171
- value?.split?.(DATA_TIME_SEPARATOR)?.at?.(-1) ?? ""
4221
+ () => {
4222
+ const [, time] = (value || "")?.split?.(DATA_TIME_SEPARATOR);
4223
+ return time ?? "";
4224
+ }
4172
4225
  );
4173
4226
  const formattedDateByLanguage = formatDateToSubmit(
4174
4227
  value?.split(DATA_TIME_SEPARATOR)?.at(0) ?? ""
@@ -4235,8 +4288,9 @@ var InputDateTimePickerSingle = ({
4235
4288
  if (date && !dateFormatIsValid(date, locale)) {
4236
4289
  handleClearValue();
4237
4290
  }
4291
+ const hasInputtedDate = date.length === "__/__/____".length;
4238
4292
  onChange?.(
4239
- date + (newTime ? DATA_TIME_SEPARATOR + newTime : ""),
4293
+ date + (newTime && hasInputtedDate ? DATA_TIME_SEPARATOR + newTime : ""),
4240
4294
  innerDate,
4241
4295
  newTime
4242
4296
  );
@@ -4284,60 +4338,56 @@ var InputDateTimePickerSingle = ({
4284
4338
  replacement: { _: /\d/ }
4285
4339
  };
4286
4340
  const inputRef = useMask(maskOptions);
4287
- return /* @__PURE__ */ jsx("div", { className: "nebula-ds w-full", children: /* @__PURE__ */ jsxs(Popover, { open: popoverIsOpen, onOpenChange: setPopoverIsOpen, children: [
4288
- /* @__PURE__ */ jsx(PopoverTrigger, { className, asChild: true, children: /* @__PURE__ */ jsx(
4289
- "div",
4341
+ const conteinerRef = useRef(null);
4342
+ const calendarRef = useRef(null);
4343
+ useClickOutside([conteinerRef, calendarRef], () => {
4344
+ setPopoverIsOpen(false);
4345
+ });
4346
+ useKeyPress("Escape", () => {
4347
+ setPopoverIsOpen(false);
4348
+ });
4349
+ return /* @__PURE__ */ jsxs("div", { className: "nebula-ds w-full", ref: conteinerRef, children: [
4350
+ /* @__PURE__ */ jsx(
4351
+ InputText,
4290
4352
  {
4291
- onClick: (e) => e.preventDefault(),
4292
- onFocus: (e) => e.preventDefault(),
4293
- children: /* @__PURE__ */ jsx(
4294
- InputText,
4353
+ ref: inputRef,
4354
+ placeholder,
4355
+ value,
4356
+ className,
4357
+ onChange: (e) => handleInnerInputChange(e.target.value),
4358
+ onKeyDown: handleKeyDown,
4359
+ icon: /* @__PURE__ */ jsx(
4360
+ CalendarIcon,
4295
4361
  {
4296
- ref: inputRef,
4297
- placeholder,
4298
- value,
4299
- className,
4300
- onChange: (e) => handleInnerInputChange(e.target.value),
4301
- onKeyDown: handleKeyDown,
4302
- icon: /* @__PURE__ */ jsx(
4303
- CalendarIcon,
4304
- {
4305
- tabIndex: 0,
4306
- role: "button",
4307
- onClick: () => setPopoverIsOpen((s) => !s),
4308
- onKeyUp: (e) => {
4309
- if (e.key === "Enter") {
4310
- setPopoverIsOpen((s) => !s);
4311
- }
4312
- },
4313
- className: "nebula-ds cursor-pointer"
4314
- }
4315
- ),
4316
- iconPlacement: "end",
4362
+ tabIndex: 0,
4363
+ role: "button",
4364
+ onClick: () => setPopoverIsOpen((s) => !s),
4317
4365
  onKeyUp: (e) => {
4318
- if (e.key === "ArrowDown") {
4319
- setPopoverIsOpen(true);
4366
+ if (e.key === "Enter") {
4367
+ setPopoverIsOpen((s) => !s);
4320
4368
  }
4321
4369
  },
4322
- onClean: onClean ? () => {
4323
- onClean();
4324
- handleClearValue();
4325
- } : void 0,
4326
- ...rest
4370
+ className: "nebula-ds cursor-pointer"
4327
4371
  }
4328
- )
4372
+ ),
4373
+ iconPlacement: "end",
4374
+ onKeyUp: (e) => {
4375
+ if (e.key === "ArrowDown") {
4376
+ setPopoverIsOpen(true);
4377
+ }
4378
+ },
4379
+ onClean: onClean ? () => {
4380
+ onClean();
4381
+ handleClearValue();
4382
+ } : void 0,
4383
+ ...rest
4329
4384
  }
4330
- ) }),
4331
- /* @__PURE__ */ jsx(
4332
- PopoverContent,
4385
+ ),
4386
+ /* @__PURE__ */ jsx("div", { className: "nebula-ds relative", children: popoverIsOpen && /* @__PURE__ */ jsx(
4387
+ "div",
4333
4388
  {
4334
- side: "bottom",
4335
- className: "nebula-ds p-0 border-none bg-transparent shadow-none",
4336
- align: "start",
4337
- collisionPadding: 8,
4338
- avoidCollisions: true,
4339
- asChild: false,
4340
- style: { position: "absolute" },
4389
+ className: "nebula-ds absolute top-full left-0-0 z-40 pb-2 pt-1",
4390
+ ref: calendarRef,
4341
4391
  children: /* @__PURE__ */ jsx(
4342
4392
  Calendar,
4343
4393
  {
@@ -4369,14 +4419,14 @@ var InputDateTimePickerSingle = ({
4369
4419
  }
4370
4420
  )
4371
4421
  }
4372
- )
4373
- ] }) });
4422
+ ) })
4423
+ ] });
4374
4424
  };
4375
- var FileUploadError = /* @__PURE__ */ ((FileUploadError2) => {
4376
- FileUploadError2["MAX_FILES_EXCEEDED"] = "MAX_FILES_EXCEEDED";
4377
- FileUploadError2["MAXIMUM_FILE_SIZE_EXCEEDED"] = "MAXIMUM_FILE_SIZE_EXCEEDED";
4378
- FileUploadError2["INVALID_FORMAT"] = "INVALID_FORMAT";
4379
- return FileUploadError2;
4425
+ var FileUploadError = /* @__PURE__ */ ((FileUploadError4) => {
4426
+ FileUploadError4["MAX_FILES_EXCEEDED"] = "MAX_FILES_EXCEEDED";
4427
+ FileUploadError4["MAXIMUM_FILE_SIZE_EXCEEDED"] = "MAXIMUM_FILE_SIZE_EXCEEDED";
4428
+ FileUploadError4["INVALID_FORMAT"] = "INVALID_FORMAT";
4429
+ return FileUploadError4;
4380
4430
  })(FileUploadError || {});
4381
4431
  var useFileUpload = (options = {}) => {
4382
4432
  const {
@@ -4477,9 +4527,6 @@ var useFileUpload = (options = {}) => {
4477
4527
  const newFilesArray = Array.from(newFiles);
4478
4528
  const errors = [];
4479
4529
  setState((prev) => ({ ...prev, errors: [] }));
4480
- if (!multiple) {
4481
- clearFiles();
4482
- }
4483
4530
  if (multiple && maxFiles !== Infinity && state.files.length + newFilesArray.length > maxFiles) {
4484
4531
  errors.push({ error: "MAX_FILES_EXCEEDED" /* MAX_FILES_EXCEEDED */ });
4485
4532
  setState((prev) => ({ ...prev, errors }));
@@ -4514,6 +4561,9 @@ var useFileUpload = (options = {}) => {
4514
4561
  }
4515
4562
  });
4516
4563
  if (validFiles.length > 0) {
4564
+ if (!multiple) {
4565
+ clearFiles();
4566
+ }
4517
4567
  onFilesAdded?.(validFiles);
4518
4568
  setState((prev) => {
4519
4569
  const newFiles2 = !multiple ? validFiles : [...prev.files, ...validFiles];
@@ -4810,6 +4860,7 @@ function FileUpload({
4810
4860
  ) })
4811
4861
  ] });
4812
4862
  }
4863
+ FileUpload.displayName = "FileUpload";
4813
4864
  var TextArea = React8.forwardRef(
4814
4865
  ({
4815
4866
  className,
@@ -4887,6 +4938,102 @@ var TextArea = React8.forwardRef(
4887
4938
  }
4888
4939
  );
4889
4940
  TextArea.displayName = "TextArea";
4941
+ var ProfileImage = ({
4942
+ maxSizeMB = 2,
4943
+ subtitle,
4944
+ onError,
4945
+ maxFiles = Infinity,
4946
+ onRemove,
4947
+ ...rest
4948
+ }) => {
4949
+ const maxSize = maxSizeMB * 1024 * 1024;
4950
+ const [
4951
+ { files, isDragging, errors },
4952
+ {
4953
+ handleDragEnter,
4954
+ handleDragLeave,
4955
+ handleDragOver,
4956
+ handleDrop,
4957
+ openFileDialog,
4958
+ removeFile,
4959
+ getInputProps
4960
+ }
4961
+ ] = useFileUpload({
4962
+ multiple: false,
4963
+ maxSize: maxSize > 0 ? maxSize : void 0,
4964
+ accept: "image/*",
4965
+ ...rest,
4966
+ maxFiles
4967
+ });
4968
+ useEffect(() => {
4969
+ onError?.(errors);
4970
+ }, [errors, onError]);
4971
+ const [file] = files;
4972
+ return /* @__PURE__ */ jsxs("div", { className: "nebula-ds flex flex-col gap-3", children: [
4973
+ /* @__PURE__ */ jsx("div", { className: "nebula-ds flex justify-center", children: /* @__PURE__ */ jsxs(
4974
+ "div",
4975
+ {
4976
+ role: "button",
4977
+ onClick: openFileDialog,
4978
+ onDragEnter: handleDragEnter,
4979
+ onDragLeave: handleDragLeave,
4980
+ onDragOver: handleDragOver,
4981
+ onDrop: handleDrop,
4982
+ "data-dragging": isDragging || void 0,
4983
+ className: cn(
4984
+ "relative border border-transparent rounded-full size-fit",
4985
+ "bg-fileUpload-background hover:bg-fileUpload-backgroundHover transition-colors",
4986
+ !file && "border-dashed border-fileUpload-border"
4987
+ ),
4988
+ "data-testid": "select-image-profile",
4989
+ children: [
4990
+ /* @__PURE__ */ jsx(
4991
+ "input",
4992
+ {
4993
+ ...getInputProps(),
4994
+ className: "nebula-ds sr-only",
4995
+ "aria-label": "Upload file"
4996
+ }
4997
+ ),
4998
+ /* @__PURE__ */ jsxs(
4999
+ "div",
5000
+ {
5001
+ className: "nebula-ds flex size-12 shrink-0 items-center justify-center rounded-full",
5002
+ "aria-hidden": "true",
5003
+ children: [
5004
+ file && file.preview && /* @__PURE__ */ jsx(
5005
+ "img",
5006
+ {
5007
+ src: file.preview,
5008
+ alt: file.file.name,
5009
+ className: "nebula-ds rounded-[inherit] object-cover h-full w-full"
5010
+ }
5011
+ ),
5012
+ !file && /* @__PURE__ */ jsx(UserIcon, { className: "nebula-ds size-4 opacity-60 text-fileUpload-icon" })
5013
+ ]
5014
+ }
5015
+ ),
5016
+ file && /* @__PURE__ */ jsx(
5017
+ "button",
5018
+ {
5019
+ className: "nebula-ds box-border absolute flex items-center justify-center -top-1 -right-1 rounded-full size-5 text-profileImage-removeImageButton-icon border-2 border-profileImage-removeImageButton-border bg-profileImage-removeImageButton-background hover:bg-profileImage-removeImageButton-hover",
5020
+ "data-testid": "remove-profile-image",
5021
+ onClick: (e) => {
5022
+ e.stopPropagation();
5023
+ removeFile(file.id);
5024
+ onRemove?.();
5025
+ },
5026
+ type: "button",
5027
+ children: /* @__PURE__ */ jsx(XIcon, { className: "nebula-ds size-2" })
5028
+ }
5029
+ )
5030
+ ]
5031
+ }
5032
+ ) }),
5033
+ !!subtitle && /* @__PURE__ */ jsx(Paragraph, { className: "nebula-ds text-center", size: "sm", children: subtitle })
5034
+ ] });
5035
+ };
5036
+ ProfileImage.displayName = "ProfileImage";
4890
5037
 
4891
5038
  // src/tailwind.ts
4892
5039
  function content({ base = "./" } = {}) {
@@ -4898,4 +5045,4 @@ var tailwind = {
4898
5045
  // plugin: () => require("tailwindcss")("node_modules/@nebulareact/dist/tailwind.config.js"),
4899
5046
  };
4900
5047
 
4901
- export { Accordion, AccordionContent, AccordionDescription, AccordionItem, AccordionTitle, AccordionTrigger, ActionBar, ActionBarButton, ActionBarClose, ActionBarContent, ActionBarDivider, ActionBarPortal, ActionBarTrigger, Alert, AlertButton, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, AlertTitle, StyledAsync as Async, StyledAsyncCreatable as AsyncCreatable, Badge, Box, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, Calendar, Caption, Checkbox, StyledCreatable as Creatable, Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, Drawer, DrawerBody, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, FileUpload, FileUploadError, Heading, InputDatePickerSingle, InputDateTimePickerSingle, InputPhone, InputText, InputTime, Label, Link, NebulaI18nProvider, Pagination, Paragraph, Popover, PopoverContent, PopoverTrigger, StyledSelect as Select, Separator2 as Separator, Skeleton, Space, SpaceDirectionEnum, SpaceSizeEnum, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, TextArea, Toaster, Tooltip, alertVariants, badgeSizeEnum, badgeVariantEnum, buttonSizeEnum, buttonVariantEnum, buttonVariantsConfig, dateIsAvailable, formatBytes, getNebulaLanguage, localeByi18nKey, messages16 as messages, separatorVariants, setNebulaLanguage, tagVariantsEnum, tailwind, toast, useNebulaI18n };
5048
+ export { Accordion, AccordionContent, AccordionDescription, AccordionItem, AccordionTitle, AccordionTrigger, ActionBar, ActionBarButton, ActionBarClose, ActionBarContent, ActionBarDivider, ActionBarPortal, ActionBarTrigger, Alert, AlertButton, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, AlertTitle, StyledAsync as Async, StyledAsyncCreatable as AsyncCreatable, Badge, Box, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, Calendar, Caption, Checkbox, StyledCreatable as Creatable, Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, Drawer, DrawerBody, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, FileUpload, FileUploadError, Heading, InputDatePickerSingle, InputDateTimePickerSingle, InputPhone, InputText, InputTime, Label, Link, NebulaI18nProvider, Pagination, Paragraph, Popover, PopoverContent, PopoverTrigger, ProfileImage, StyledSelect as Select, Separator2 as Separator, Skeleton, Space, SpaceDirectionEnum, SpaceSizeEnum, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, TextArea, Toaster, Tooltip, alertVariants, badgeSizeEnum, badgeVariantEnum, buttonSizeEnum, buttonVariantEnum, buttonVariantsConfig, dateIsAvailable, formatBytes, getNebulaLanguage, localeByi18nKey, messages16 as messages, separatorVariants, setNebulaLanguage, tagVariantsEnum, tailwind, toast, useClickOutside, useFileUpload, useKeyPress, useNebulaI18n };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ikatec/nebula-react",
3
- "version": "1.0.24",
3
+ "version": "1.0.26",
4
4
  "description": "React components",
5
5
  "publishConfig": {
6
6
  "access": "public"