@ikatec/nebula-react 1.0.25 → 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.
Files changed (3) hide show
  1. package/dist/index.js +197 -80
  2. package/dist/index.mjs +198 -82
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2242,15 +2242,9 @@ var StyledAsyncCreatable = createStyledSelect(
2242
2242
  "AsyncCreatable"
2243
2243
  );
2244
2244
  var InputText = React8__namespace.forwardRef(
2245
- ({
2246
- className,
2247
- icon,
2248
- isError = false,
2249
- onClean,
2250
- iconPlacement = "start",
2251
- disabled,
2252
- ...props
2253
- }, ref) => {
2245
+ ({ className, isError = false, onClean, disabled, suffix, ...props }, ref) => {
2246
+ const icon = "icon" in props ? props.icon : null;
2247
+ const iconPlacement = "iconPlacement" in props || props.type !== "password" ? props.iconPlacement || "start" : null;
2254
2248
  const initialInputType = props.type || "text";
2255
2249
  const [type, setType] = React8__namespace.useState(initialInputType);
2256
2250
  const iconClass = {
@@ -2261,71 +2255,92 @@ var InputText = React8__namespace.forwardRef(
2261
2255
  return /* @__PURE__ */ jsxRuntime.jsxs(
2262
2256
  "div",
2263
2257
  {
2264
- className: cn("relative w-full", {
2265
- "pointer-events-none": disabled
2266
- }),
2258
+ className: cn(
2259
+ "w-full flex outline-none",
2260
+ "rounded-input",
2261
+ "border border-inputText-border-default focus-within:ring-[3px] focus-within:ring-inputText-border-focus focus-within:border-inputText-border-focus",
2262
+ "focus-within:text-inputText-text-focus placeholder:text-inputText-text-default disabled:text-inputText-text-disabled",
2263
+ isError && "border-inputText-border-danger focus-within:border-inputText-border-danger focus-within:ring-button-danger-border-focus",
2264
+ disabled && "pointer-events-none"
2265
+ ),
2267
2266
  children: [
2268
- /* @__PURE__ */ jsxRuntime.jsx(
2269
- "input",
2267
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nebula-ds relative w-full", children: [
2268
+ /* @__PURE__ */ jsxRuntime.jsx(
2269
+ "input",
2270
+ {
2271
+ ref,
2272
+ className: cn(
2273
+ "w-full h-10 outline-none text-sm leading-none font-medium",
2274
+ "bg-inputText-background-default disabled:bg-inputText-background-disabled",
2275
+ "text-inputText-text-filled",
2276
+ "disabled:cursor-not-allowed",
2277
+ "rounded-input",
2278
+ "pl-4",
2279
+ !!suffix && "rounded-r-none",
2280
+ {
2281
+ "pl-10 pr-4": !!icon && iconPlacement === "start",
2282
+ "pr-10": initialInputType === "password",
2283
+ "pr-10 pl-4": !!icon && iconPlacement === "end" && initialInputType !== "password"
2284
+ },
2285
+ className
2286
+ ),
2287
+ ...{ ...props, icon: void 0, iconPlacement: void 0 },
2288
+ disabled,
2289
+ type
2290
+ }
2291
+ ),
2292
+ onClean && props.value && /* @__PURE__ */ jsxRuntime.jsx(
2293
+ "button",
2294
+ {
2295
+ type: "button",
2296
+ className: cn("absolute top-1/2 transform -translate-y-1/2", {
2297
+ "right-10": initialInputType === "password" || iconPlacement === "end",
2298
+ "right-4": initialInputType === "text" && iconPlacement === "start"
2299
+ }),
2300
+ onClick: onClean,
2301
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleX, { className: cn("w-4 h-4", iconClass) })
2302
+ }
2303
+ ),
2304
+ initialInputType === "password" && /* @__PURE__ */ jsxRuntime.jsx(
2305
+ "button",
2306
+ {
2307
+ type: "button",
2308
+ className: "nebula-ds absolute right-4 top-1/2 transform -translate-y-1/2",
2309
+ onClick: () => setType((prev) => prev === "text" ? "password" : "text"),
2310
+ children: type === "text" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eye, { className: cn("w-4 h-4", iconClass) }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.EyeOff, { className: cn("w-4 h-4", iconClass) })
2311
+ }
2312
+ ),
2313
+ icon && initialInputType !== "password" && /* @__PURE__ */ jsxRuntime.jsx(
2314
+ "span",
2315
+ {
2316
+ className: cn("absolute top-1/2 transform -translate-y-1/2", {
2317
+ "left-4": iconPlacement === "start",
2318
+ "right-4": iconPlacement === "end"
2319
+ }),
2320
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2321
+ "span",
2322
+ {
2323
+ className: cn(
2324
+ "w-4 h-4 flex items-center justify-center disabled:text-inputText-icon-disabled",
2325
+ iconClass
2326
+ ),
2327
+ children: icon
2328
+ }
2329
+ )
2330
+ }
2331
+ )
2332
+ ] }),
2333
+ !!suffix && /* @__PURE__ */ jsxRuntime.jsx(
2334
+ "div",
2270
2335
  {
2271
- ref,
2272
2336
  className: cn(
2273
- "w-full h-10 outline-none rounded-input text-sm leading-none font-medium",
2274
- "bg-inputText-background-default disabled:bg-inputText-background-disabled",
2275
- "border border-inputText-border-default focus:ring-[3px] focus:ring-inputText-border-focus focus:border-inputText-border-focus",
2276
- "text-inputText-text-filled focus:text-inputText-text-focus placeholder:text-inputText-text-default disabled:text-inputText-text-disabled",
2277
- "disabled:cursor-not-allowed",
2278
- {
2279
- "pl-10 pr-4": !!icon && iconPlacement === "start",
2280
- "pr-10 pl-4": !!icon && iconPlacement === "end" && initialInputType !== "password",
2281
- "px-4": !icon,
2282
- "border-inputText-border-danger focus:border-inputText-border-danger focus:ring-button-danger-border-focus": isError
2283
- },
2284
- className
2337
+ "w-fit h-10 outline-none rounded-input text-sm leading-none font-medium rounded-l-none flex items-center px-4",
2338
+ "bg-inputText-suffixBackground disabled:bg-inputText-background-disabled",
2339
+ "text-inputText-text-filled",
2340
+ "border-l border-inputText-border-default",
2341
+ "rounded-input rounded-l-none"
2285
2342
  ),
2286
- ...props,
2287
- disabled,
2288
- type
2289
- }
2290
- ),
2291
- onClean && props.value && /* @__PURE__ */ jsxRuntime.jsx(
2292
- "button",
2293
- {
2294
- type: "button",
2295
- className: cn("absolute top-1/2 transform -translate-y-1/2", {
2296
- "right-10": initialInputType === "password" || iconPlacement === "end",
2297
- "right-4": initialInputType === "text" && iconPlacement === "start"
2298
- }),
2299
- onClick: onClean,
2300
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleX, { className: cn("w-4 h-4", iconClass) })
2301
- }
2302
- ),
2303
- initialInputType === "password" && /* @__PURE__ */ jsxRuntime.jsx(
2304
- "button",
2305
- {
2306
- type: "button",
2307
- className: "nebula-ds absolute right-4 top-1/2 transform -translate-y-1/2",
2308
- onClick: () => setType((prev) => prev === "text" ? "password" : "text"),
2309
- children: type === "text" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eye, { className: cn("w-4 h-4", iconClass) }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.EyeOff, { className: cn("w-4 h-4", iconClass) })
2310
- }
2311
- ),
2312
- icon && /* @__PURE__ */ jsxRuntime.jsx(
2313
- "span",
2314
- {
2315
- className: cn("absolute top-1/2 transform -translate-y-1/2", {
2316
- "left-4": iconPlacement === "start",
2317
- "right-4": iconPlacement === "end" && initialInputType !== "password"
2318
- }),
2319
- children: /* @__PURE__ */ jsxRuntime.jsx(
2320
- "span",
2321
- {
2322
- className: cn(
2323
- "w-4 h-4 flex items-center justify-center disabled:text-inputText-icon-disabled",
2324
- iconClass
2325
- ),
2326
- children: icon
2327
- }
2328
- )
2343
+ children: suffix
2329
2344
  }
2330
2345
  )
2331
2346
  ]
@@ -4243,7 +4258,10 @@ var InputDateTimePickerSingle = ({
4243
4258
  ...rest
4244
4259
  }) => {
4245
4260
  const [innerTimeValue, setInnerTimeValue] = React8.useState(
4246
- value?.split?.(DATA_TIME_SEPARATOR)?.at?.(-1) ?? ""
4261
+ () => {
4262
+ const [, time] = (value || "")?.split?.(DATA_TIME_SEPARATOR);
4263
+ return time ?? "";
4264
+ }
4247
4265
  );
4248
4266
  const formattedDateByLanguage = formatDateToSubmit(
4249
4267
  value?.split(DATA_TIME_SEPARATOR)?.at(0) ?? ""
@@ -4310,8 +4328,9 @@ var InputDateTimePickerSingle = ({
4310
4328
  if (date && !dateFormatIsValid(date, locale)) {
4311
4329
  handleClearValue();
4312
4330
  }
4331
+ const hasInputtedDate = date.length === "__/__/____".length;
4313
4332
  onChange?.(
4314
- date + (newTime ? DATA_TIME_SEPARATOR + newTime : ""),
4333
+ date + (newTime && hasInputtedDate ? DATA_TIME_SEPARATOR + newTime : ""),
4315
4334
  innerDate,
4316
4335
  newTime
4317
4336
  );
@@ -4443,11 +4462,11 @@ var InputDateTimePickerSingle = ({
4443
4462
  ) })
4444
4463
  ] });
4445
4464
  };
4446
- var FileUploadError = /* @__PURE__ */ ((FileUploadError2) => {
4447
- FileUploadError2["MAX_FILES_EXCEEDED"] = "MAX_FILES_EXCEEDED";
4448
- FileUploadError2["MAXIMUM_FILE_SIZE_EXCEEDED"] = "MAXIMUM_FILE_SIZE_EXCEEDED";
4449
- FileUploadError2["INVALID_FORMAT"] = "INVALID_FORMAT";
4450
- return FileUploadError2;
4465
+ var FileUploadError = /* @__PURE__ */ ((FileUploadError4) => {
4466
+ FileUploadError4["MAX_FILES_EXCEEDED"] = "MAX_FILES_EXCEEDED";
4467
+ FileUploadError4["MAXIMUM_FILE_SIZE_EXCEEDED"] = "MAXIMUM_FILE_SIZE_EXCEEDED";
4468
+ FileUploadError4["INVALID_FORMAT"] = "INVALID_FORMAT";
4469
+ return FileUploadError4;
4451
4470
  })(FileUploadError || {});
4452
4471
  var useFileUpload = (options = {}) => {
4453
4472
  const {
@@ -4548,9 +4567,6 @@ var useFileUpload = (options = {}) => {
4548
4567
  const newFilesArray = Array.from(newFiles);
4549
4568
  const errors = [];
4550
4569
  setState((prev) => ({ ...prev, errors: [] }));
4551
- if (!multiple) {
4552
- clearFiles();
4553
- }
4554
4570
  if (multiple && maxFiles !== Infinity && state.files.length + newFilesArray.length > maxFiles) {
4555
4571
  errors.push({ error: "MAX_FILES_EXCEEDED" /* MAX_FILES_EXCEEDED */ });
4556
4572
  setState((prev) => ({ ...prev, errors }));
@@ -4585,6 +4601,9 @@ var useFileUpload = (options = {}) => {
4585
4601
  }
4586
4602
  });
4587
4603
  if (validFiles.length > 0) {
4604
+ if (!multiple) {
4605
+ clearFiles();
4606
+ }
4588
4607
  onFilesAdded?.(validFiles);
4589
4608
  setState((prev) => {
4590
4609
  const newFiles2 = !multiple ? validFiles : [...prev.files, ...validFiles];
@@ -4881,6 +4900,7 @@ function FileUpload({
4881
4900
  ) })
4882
4901
  ] });
4883
4902
  }
4903
+ FileUpload.displayName = "FileUpload";
4884
4904
  var TextArea = React8__namespace.forwardRef(
4885
4905
  ({
4886
4906
  className,
@@ -4958,6 +4978,102 @@ var TextArea = React8__namespace.forwardRef(
4958
4978
  }
4959
4979
  );
4960
4980
  TextArea.displayName = "TextArea";
4981
+ var ProfileImage = ({
4982
+ maxSizeMB = 2,
4983
+ subtitle,
4984
+ onError,
4985
+ maxFiles = Infinity,
4986
+ onRemove,
4987
+ ...rest
4988
+ }) => {
4989
+ const maxSize = maxSizeMB * 1024 * 1024;
4990
+ const [
4991
+ { files, isDragging, errors },
4992
+ {
4993
+ handleDragEnter,
4994
+ handleDragLeave,
4995
+ handleDragOver,
4996
+ handleDrop,
4997
+ openFileDialog,
4998
+ removeFile,
4999
+ getInputProps
5000
+ }
5001
+ ] = useFileUpload({
5002
+ multiple: false,
5003
+ maxSize: maxSize > 0 ? maxSize : void 0,
5004
+ accept: "image/*",
5005
+ ...rest,
5006
+ maxFiles
5007
+ });
5008
+ React8.useEffect(() => {
5009
+ onError?.(errors);
5010
+ }, [errors, onError]);
5011
+ const [file] = files;
5012
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nebula-ds flex flex-col gap-3", children: [
5013
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nebula-ds flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs(
5014
+ "div",
5015
+ {
5016
+ role: "button",
5017
+ onClick: openFileDialog,
5018
+ onDragEnter: handleDragEnter,
5019
+ onDragLeave: handleDragLeave,
5020
+ onDragOver: handleDragOver,
5021
+ onDrop: handleDrop,
5022
+ "data-dragging": isDragging || void 0,
5023
+ className: cn(
5024
+ "relative border border-transparent rounded-full size-fit",
5025
+ "bg-fileUpload-background hover:bg-fileUpload-backgroundHover transition-colors",
5026
+ !file && "border-dashed border-fileUpload-border"
5027
+ ),
5028
+ "data-testid": "select-image-profile",
5029
+ children: [
5030
+ /* @__PURE__ */ jsxRuntime.jsx(
5031
+ "input",
5032
+ {
5033
+ ...getInputProps(),
5034
+ className: "nebula-ds sr-only",
5035
+ "aria-label": "Upload file"
5036
+ }
5037
+ ),
5038
+ /* @__PURE__ */ jsxRuntime.jsxs(
5039
+ "div",
5040
+ {
5041
+ className: "nebula-ds flex size-12 shrink-0 items-center justify-center rounded-full",
5042
+ "aria-hidden": "true",
5043
+ children: [
5044
+ file && file.preview && /* @__PURE__ */ jsxRuntime.jsx(
5045
+ "img",
5046
+ {
5047
+ src: file.preview,
5048
+ alt: file.file.name,
5049
+ className: "nebula-ds rounded-[inherit] object-cover h-full w-full"
5050
+ }
5051
+ ),
5052
+ !file && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UserIcon, { className: "nebula-ds size-4 opacity-60 text-fileUpload-icon" })
5053
+ ]
5054
+ }
5055
+ ),
5056
+ file && /* @__PURE__ */ jsxRuntime.jsx(
5057
+ "button",
5058
+ {
5059
+ 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",
5060
+ "data-testid": "remove-profile-image",
5061
+ onClick: (e) => {
5062
+ e.stopPropagation();
5063
+ removeFile(file.id);
5064
+ onRemove?.();
5065
+ },
5066
+ type: "button",
5067
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, { className: "nebula-ds size-2" })
5068
+ }
5069
+ )
5070
+ ]
5071
+ }
5072
+ ) }),
5073
+ !!subtitle && /* @__PURE__ */ jsxRuntime.jsx(Paragraph, { className: "nebula-ds text-center", size: "sm", children: subtitle })
5074
+ ] });
5075
+ };
5076
+ ProfileImage.displayName = "ProfileImage";
4961
5077
 
4962
5078
  // src/tailwind.ts
4963
5079
  function content({ base = "./" } = {}) {
@@ -5061,6 +5177,7 @@ exports.Paragraph = Paragraph;
5061
5177
  exports.Popover = Popover;
5062
5178
  exports.PopoverContent = PopoverContent;
5063
5179
  exports.PopoverTrigger = PopoverTrigger;
5180
+ exports.ProfileImage = ProfileImage;
5064
5181
  exports.Select = StyledSelect;
5065
5182
  exports.Separator = Separator2;
5066
5183
  exports.Skeleton = Skeleton;
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
  ]
@@ -4203,7 +4218,10 @@ var InputDateTimePickerSingle = ({
4203
4218
  ...rest
4204
4219
  }) => {
4205
4220
  const [innerTimeValue, setInnerTimeValue] = useState(
4206
- value?.split?.(DATA_TIME_SEPARATOR)?.at?.(-1) ?? ""
4221
+ () => {
4222
+ const [, time] = (value || "")?.split?.(DATA_TIME_SEPARATOR);
4223
+ return time ?? "";
4224
+ }
4207
4225
  );
4208
4226
  const formattedDateByLanguage = formatDateToSubmit(
4209
4227
  value?.split(DATA_TIME_SEPARATOR)?.at(0) ?? ""
@@ -4270,8 +4288,9 @@ var InputDateTimePickerSingle = ({
4270
4288
  if (date && !dateFormatIsValid(date, locale)) {
4271
4289
  handleClearValue();
4272
4290
  }
4291
+ const hasInputtedDate = date.length === "__/__/____".length;
4273
4292
  onChange?.(
4274
- date + (newTime ? DATA_TIME_SEPARATOR + newTime : ""),
4293
+ date + (newTime && hasInputtedDate ? DATA_TIME_SEPARATOR + newTime : ""),
4275
4294
  innerDate,
4276
4295
  newTime
4277
4296
  );
@@ -4403,11 +4422,11 @@ var InputDateTimePickerSingle = ({
4403
4422
  ) })
4404
4423
  ] });
4405
4424
  };
4406
- var FileUploadError = /* @__PURE__ */ ((FileUploadError2) => {
4407
- FileUploadError2["MAX_FILES_EXCEEDED"] = "MAX_FILES_EXCEEDED";
4408
- FileUploadError2["MAXIMUM_FILE_SIZE_EXCEEDED"] = "MAXIMUM_FILE_SIZE_EXCEEDED";
4409
- FileUploadError2["INVALID_FORMAT"] = "INVALID_FORMAT";
4410
- 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;
4411
4430
  })(FileUploadError || {});
4412
4431
  var useFileUpload = (options = {}) => {
4413
4432
  const {
@@ -4508,9 +4527,6 @@ var useFileUpload = (options = {}) => {
4508
4527
  const newFilesArray = Array.from(newFiles);
4509
4528
  const errors = [];
4510
4529
  setState((prev) => ({ ...prev, errors: [] }));
4511
- if (!multiple) {
4512
- clearFiles();
4513
- }
4514
4530
  if (multiple && maxFiles !== Infinity && state.files.length + newFilesArray.length > maxFiles) {
4515
4531
  errors.push({ error: "MAX_FILES_EXCEEDED" /* MAX_FILES_EXCEEDED */ });
4516
4532
  setState((prev) => ({ ...prev, errors }));
@@ -4545,6 +4561,9 @@ var useFileUpload = (options = {}) => {
4545
4561
  }
4546
4562
  });
4547
4563
  if (validFiles.length > 0) {
4564
+ if (!multiple) {
4565
+ clearFiles();
4566
+ }
4548
4567
  onFilesAdded?.(validFiles);
4549
4568
  setState((prev) => {
4550
4569
  const newFiles2 = !multiple ? validFiles : [...prev.files, ...validFiles];
@@ -4841,6 +4860,7 @@ function FileUpload({
4841
4860
  ) })
4842
4861
  ] });
4843
4862
  }
4863
+ FileUpload.displayName = "FileUpload";
4844
4864
  var TextArea = React8.forwardRef(
4845
4865
  ({
4846
4866
  className,
@@ -4918,6 +4938,102 @@ var TextArea = React8.forwardRef(
4918
4938
  }
4919
4939
  );
4920
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";
4921
5037
 
4922
5038
  // src/tailwind.ts
4923
5039
  function content({ base = "./" } = {}) {
@@ -4929,4 +5045,4 @@ var tailwind = {
4929
5045
  // plugin: () => require("tailwindcss")("node_modules/@nebulareact/dist/tailwind.config.js"),
4930
5046
  };
4931
5047
 
4932
- 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, useClickOutside, useFileUpload, useKeyPress, 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.25",
3
+ "version": "1.0.26",
4
4
  "description": "React components",
5
5
  "publishConfig": {
6
6
  "access": "public"