@ikatec/nebula-react 1.0.27 → 1.0.28

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.js CHANGED
@@ -29,6 +29,7 @@ var reactDayPicker = require('react-day-picker');
29
29
  var locale = require('react-day-picker/locale');
30
30
  var mask = require('@react-input/mask');
31
31
  var SliderPrimitive = require('@radix-ui/react-slider');
32
+ var RadioGroupPrimitive = require('@radix-ui/react-radio-group');
32
33
 
33
34
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
34
35
 
@@ -69,6 +70,7 @@ var TabsPrimitive__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive);
69
70
  var RPNInput__namespace = /*#__PURE__*/_interopNamespace(RPNInput);
70
71
  var flags__default = /*#__PURE__*/_interopDefault(flags);
71
72
  var SliderPrimitive__namespace = /*#__PURE__*/_interopNamespace(SliderPrimitive);
73
+ var RadioGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(RadioGroupPrimitive);
72
74
 
73
75
  // src/button.tsx
74
76
 
@@ -2282,12 +2284,13 @@ var InputText = React8__namespace.forwardRef(
2282
2284
  "div",
2283
2285
  {
2284
2286
  className: cn(
2285
- "w-full flex outline-none",
2287
+ "flex outline-none",
2286
2288
  "rounded-input",
2287
2289
  "border border-inputText-border-default focus-within:ring-[3px] focus-within:ring-inputText-border-focus focus-within:border-inputText-border-focus",
2288
2290
  "focus-within:text-inputText-text-focus placeholder:text-inputText-text-default disabled:text-inputText-text-disabled",
2289
2291
  isError && "border-inputText-border-danger focus-within:border-inputText-border-danger focus-within:ring-button-danger-border-focus",
2290
- disabled && "pointer-events-none"
2292
+ disabled && "pointer-events-none",
2293
+ className
2291
2294
  ),
2292
2295
  children: [
2293
2296
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nebula-ds relative w-full", children: [
@@ -2296,7 +2299,7 @@ var InputText = React8__namespace.forwardRef(
2296
2299
  {
2297
2300
  ref,
2298
2301
  className: cn(
2299
- "w-full h-10 outline-none text-sm leading-none font-medium",
2302
+ "h-10 outline-none text-sm leading-none font-medium",
2300
2303
  "bg-inputText-background-default disabled:bg-inputText-background-disabled",
2301
2304
  "text-inputText-text-filled",
2302
2305
  "disabled:cursor-not-allowed",
@@ -2308,7 +2311,7 @@ var InputText = React8__namespace.forwardRef(
2308
2311
  "pr-10": initialInputType === "password",
2309
2312
  "pr-10 pl-4": !!icon && iconPlacement === "end" && initialInputType !== "password"
2310
2313
  },
2311
- className
2314
+ "!w-full"
2312
2315
  ),
2313
2316
  ...{ ...props, icon: void 0, iconPlacement: void 0 },
2314
2317
  disabled,
@@ -3517,10 +3520,11 @@ var PhoneInput = React8__namespace.default.forwardRef(({ className, ...props },
3517
3520
  "data-slot": "phone-input",
3518
3521
  ref,
3519
3522
  className: cn(
3520
- "-ms-px rounded-s-none shadow-none focus-visible:z-10 ring-0 focus:ring-0 border-0 w-full h-auto",
3523
+ "-ms-px rounded-s-none shadow-none focus-visible:z-10 ring-0 focus-within:ring-0 border-0 w-full h-auto",
3521
3524
  className
3522
3525
  ),
3523
- ...props
3526
+ ...props,
3527
+ type: "text"
3524
3528
  }
3525
3529
  )
3526
3530
  ] });
@@ -5006,113 +5010,6 @@ var TextArea = React8__namespace.forwardRef(
5006
5010
  }
5007
5011
  );
5008
5012
  TextArea.displayName = "TextArea";
5009
- var ProfileImage = ({
5010
- maxSizeMB = 2,
5011
- subtitle,
5012
- onError,
5013
- maxFiles = Infinity,
5014
- onRemove,
5015
- image,
5016
- ...rest
5017
- }) => {
5018
- const maxSize = maxSizeMB * 1024 * 1024;
5019
- const id = React8.useId();
5020
- const [
5021
- { files, isDragging, errors },
5022
- {
5023
- handleDragEnter,
5024
- handleDragLeave,
5025
- handleDragOver,
5026
- handleDrop,
5027
- openFileDialog,
5028
- removeFile,
5029
- getInputProps
5030
- }
5031
- ] = useFileUpload({
5032
- initialFiles: image ? [
5033
- {
5034
- id,
5035
- url: image,
5036
- name: image,
5037
- size: 0,
5038
- type: "image"
5039
- }
5040
- ] : [],
5041
- multiple: false,
5042
- maxSize: maxSize > 0 ? maxSize : void 0,
5043
- accept: "image/*",
5044
- ...rest,
5045
- maxFiles
5046
- });
5047
- React8.useEffect(() => {
5048
- onError?.(errors);
5049
- }, [errors, onError]);
5050
- const [file] = files;
5051
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nebula-ds flex flex-col gap-3", children: [
5052
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nebula-ds flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs(
5053
- "div",
5054
- {
5055
- role: "button",
5056
- onClick: openFileDialog,
5057
- onDragEnter: handleDragEnter,
5058
- onDragLeave: handleDragLeave,
5059
- onDragOver: handleDragOver,
5060
- onDrop: handleDrop,
5061
- "data-dragging": isDragging || void 0,
5062
- className: cn(
5063
- "relative border border-transparent rounded-full size-fit",
5064
- "bg-fileUpload-background hover:bg-fileUpload-backgroundHover transition-colors",
5065
- !file && "border-dashed border-fileUpload-border"
5066
- ),
5067
- "data-testid": "select-image-profile",
5068
- children: [
5069
- /* @__PURE__ */ jsxRuntime.jsx(
5070
- "input",
5071
- {
5072
- ...getInputProps(),
5073
- className: "nebula-ds sr-only",
5074
- "aria-label": "Upload file"
5075
- }
5076
- ),
5077
- /* @__PURE__ */ jsxRuntime.jsxs(
5078
- "div",
5079
- {
5080
- className: "nebula-ds flex size-12 shrink-0 items-center justify-center rounded-full",
5081
- "aria-hidden": "true",
5082
- children: [
5083
- file && file.preview && /* @__PURE__ */ jsxRuntime.jsx(
5084
- "img",
5085
- {
5086
- src: file.preview,
5087
- alt: file.file.name,
5088
- className: "nebula-ds rounded-[inherit] object-cover h-full w-full"
5089
- }
5090
- ),
5091
- !file && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UserIcon, { className: "nebula-ds size-4 opacity-60 text-fileUpload-icon" })
5092
- ]
5093
- }
5094
- ),
5095
- file && /* @__PURE__ */ jsxRuntime.jsx(
5096
- "button",
5097
- {
5098
- 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",
5099
- "data-testid": "remove-profile-image",
5100
- onClick: (e) => {
5101
- e.stopPropagation();
5102
- removeFile(file.id);
5103
- onRemove?.();
5104
- },
5105
- type: "button",
5106
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, { className: "nebula-ds size-2" })
5107
- }
5108
- )
5109
- ]
5110
- }
5111
- ) }),
5112
- !!subtitle && /* @__PURE__ */ jsxRuntime.jsx(Paragraph, { className: "nebula-ds text-center", size: "sm", children: subtitle })
5113
- ] });
5114
- };
5115
- ProfileImage.displayName = "ProfileImage";
5116
5013
  function clamp(value, min, max) {
5117
5014
  return Math.min(Math.max(value, min), max);
5118
5015
  }
@@ -6000,8 +5897,8 @@ function Cropper2({
6000
5897
  onOpenChange,
6001
5898
  open,
6002
5899
  previewUrl,
6003
- onRemove: removeFile,
6004
5900
  onApply,
5901
+ onCancelCrop,
6005
5902
  rounded = false,
6006
5903
  portal = false
6007
5904
  }) {
@@ -6014,7 +5911,6 @@ function Cropper2({
6014
5911
  const handleApply = async () => {
6015
5912
  if (!previewUrl || !croppedAreaPixels) {
6016
5913
  if (previewUrl) {
6017
- removeFile();
6018
5914
  setCroppedAreaPixels(null);
6019
5915
  }
6020
5916
  return;
@@ -6035,6 +5931,13 @@ function Cropper2({
6035
5931
  onOpenChange(false);
6036
5932
  }
6037
5933
  };
5934
+ const handleCancelCrop = () => {
5935
+ setFinalImageUrl(null);
5936
+ setCroppedAreaPixels(null);
5937
+ setZoom(1);
5938
+ onOpenChange?.(false);
5939
+ onCancelCrop?.();
5940
+ };
6038
5941
  React8.useEffect(() => {
6039
5942
  const currentFinalUrl = finalImageUrl;
6040
5943
  return () => {
@@ -6044,94 +5947,649 @@ function Cropper2({
6044
5947
  };
6045
5948
  }, [finalImageUrl]);
6046
5949
  const { cropper } = useNebulaI18n().messages;
6047
- return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(
6048
- DialogContent,
5950
+ return /* @__PURE__ */ jsxRuntime.jsx(
5951
+ Dialog,
6049
5952
  {
6050
- className: "nebula-ds gap-0 p-0 sm:max-w-140 *:[button]:hidden border border-cropper-dialogBorderColor",
6051
- portal,
6052
- showClose: false,
6053
- onOpenAutoFocus: (e) => e.preventDefault(),
6054
- children: [
6055
- /* @__PURE__ */ jsxRuntime.jsx(DialogHeader, { className: "nebula-ds contents space-y-0 text-left", children: /* @__PURE__ */ jsxRuntime.jsxs(DialogTitle, { className: "nebula-ds flex items-center justify-between p-4 text-base", children: [
6056
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nebula-ds flex items-center gap-2", children: [
5953
+ open,
5954
+ onOpenChange: (isOpen) => {
5955
+ if (!isOpen && !finalImageUrl) {
5956
+ handleCancelCrop();
5957
+ }
5958
+ onOpenChange?.(isOpen);
5959
+ },
5960
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
5961
+ DialogContent,
5962
+ {
5963
+ className: "nebula-ds gap-0 p-0 sm:max-w-140 *:[button]:hidden border border-cropper-dialogBorderColor",
5964
+ portal,
5965
+ showClose: false,
5966
+ onOpenAutoFocus: (e) => e.preventDefault(),
5967
+ children: [
5968
+ /* @__PURE__ */ jsxRuntime.jsx(DialogHeader, { className: "nebula-ds contents space-y-0 text-left", children: /* @__PURE__ */ jsxRuntime.jsxs(DialogTitle, { className: "nebula-ds flex items-center justify-between p-4 text-base", children: [
5969
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nebula-ds flex items-center gap-2", children: [
5970
+ /* @__PURE__ */ jsxRuntime.jsx(
5971
+ Button,
5972
+ {
5973
+ icon: true,
5974
+ type: "button",
5975
+ variant: "ghost",
5976
+ onClick: handleCancelCrop,
5977
+ "aria-label": "close-cropper-dialog",
5978
+ "data-testid": "close-cropper-dialog",
5979
+ size: "sm",
5980
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, { "aria-hidden": "true" })
5981
+ }
5982
+ ),
5983
+ cropper.dialogTitle
5984
+ ] }),
5985
+ /* @__PURE__ */ jsxRuntime.jsx(
5986
+ Button,
5987
+ {
5988
+ autoFocus: false,
5989
+ onClick: handleApply,
5990
+ disabled: !previewUrl,
5991
+ variant: "primary",
5992
+ size: "sm",
5993
+ type: "button",
5994
+ "aria-label": "apply-cropper-image",
5995
+ "data-testid": "apply-cropper-image",
5996
+ children: cropper.applyButtonLabel
5997
+ }
5998
+ )
5999
+ ] }) }),
6000
+ previewUrl && /* @__PURE__ */ jsxRuntime.jsxs(
6001
+ CropperRoot2,
6002
+ {
6003
+ className: "nebula-ds h-96 sm:h-120",
6004
+ image: previewUrl,
6005
+ zoom,
6006
+ onCropChange: handleCropChange,
6007
+ onZoomChange: setZoom,
6008
+ children: [
6009
+ /* @__PURE__ */ jsxRuntime.jsx(CropperDescription2, {}),
6010
+ /* @__PURE__ */ jsxRuntime.jsx(CropperImage2, {}),
6011
+ /* @__PURE__ */ jsxRuntime.jsx(CropperCropArea2, { rounded })
6012
+ ]
6013
+ }
6014
+ ),
6015
+ /* @__PURE__ */ jsxRuntime.jsx(DialogFooter, { className: "nebula-ds border-t border-t-cropper-dialogBorderColor px-4 py-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nebula-ds mx-auto flex w-full max-w-80 items-center gap-4", children: [
6016
+ /* @__PURE__ */ jsxRuntime.jsx(
6017
+ lucideReact.MinusIcon,
6018
+ {
6019
+ className: "nebula-ds shrink-0 size-5 text-cropper-sliderIconColor",
6020
+ size: 16,
6021
+ "aria-hidden": "true"
6022
+ }
6023
+ ),
6024
+ /* @__PURE__ */ jsxRuntime.jsx(
6025
+ Slider,
6026
+ {
6027
+ defaultValue: [1],
6028
+ value: [zoom],
6029
+ min: 1,
6030
+ max: 3,
6031
+ step: 0.1,
6032
+ onValueChange: (value) => setZoom(value[0]),
6033
+ "aria-label": "Zoom slider"
6034
+ }
6035
+ ),
6036
+ /* @__PURE__ */ jsxRuntime.jsx(
6037
+ lucideReact.PlusIcon,
6038
+ {
6039
+ className: "nebula-ds shrink-0 size-5 text-cropper-sliderIconColor",
6040
+ size: 16,
6041
+ "aria-hidden": "true"
6042
+ }
6043
+ )
6044
+ ] }) })
6045
+ ]
6046
+ }
6047
+ )
6048
+ }
6049
+ );
6050
+ }
6051
+ var ProfileImage = ({
6052
+ maxSizeMB = 5,
6053
+ subtitle,
6054
+ onError,
6055
+ maxFiles = Infinity,
6056
+ onRemove,
6057
+ image,
6058
+ cropperProps,
6059
+ onChange
6060
+ }) => {
6061
+ const maxSize = maxSizeMB * 1024 * 1024;
6062
+ const id = React8.useId();
6063
+ const withCropper = React8.useMemo(() => !!cropperProps, [cropperProps]);
6064
+ const handleFileChange = (file2, blob) => {
6065
+ if (!file2) {
6066
+ return;
6067
+ }
6068
+ let fileLike = file2;
6069
+ if (withCropper && !blob) {
6070
+ return;
6071
+ }
6072
+ if (withCropper && blob) {
6073
+ fileLike = new File([blob], file2.name, { type: file2.type });
6074
+ }
6075
+ onChange?.(fileLike);
6076
+ };
6077
+ const [
6078
+ { files, isDragging, errors },
6079
+ {
6080
+ handleDragEnter,
6081
+ handleDragLeave,
6082
+ handleDragOver,
6083
+ handleDrop,
6084
+ openFileDialog,
6085
+ removeFile,
6086
+ getInputProps
6087
+ }
6088
+ ] = useFileUpload({
6089
+ maxFiles,
6090
+ initialFiles: image ? [
6091
+ {
6092
+ id,
6093
+ url: image,
6094
+ name: image,
6095
+ size: 0,
6096
+ type: "image"
6097
+ }
6098
+ ] : [],
6099
+ multiple: false,
6100
+ maxSize: maxSize > 0 ? maxSize : void 0,
6101
+ accept: "image/*",
6102
+ onFilesChange([file2]) {
6103
+ handleFileChange(file2?.file);
6104
+ }
6105
+ });
6106
+ const [finalImageUrl, setFinalImageUrl] = React8.useState(null);
6107
+ const [isDialogOpen, setIsDialogOpen] = React8.useState(false);
6108
+ React8.useEffect(() => {
6109
+ onError?.(errors);
6110
+ }, [errors, onError]);
6111
+ const [file] = files;
6112
+ const fileId = file?.id;
6113
+ const previousFileIdRef = React8.useRef(null);
6114
+ const previewUrl = file?.preview || null;
6115
+ const profileImagePreview = React8.useMemo(() => {
6116
+ if (withCropper) return finalImageUrl;
6117
+ return previewUrl;
6118
+ }, [previewUrl, withCropper, finalImageUrl]);
6119
+ React8.useEffect(() => {
6120
+ if (!withCropper) return;
6121
+ if (fileId && fileId !== previousFileIdRef.current) {
6122
+ setIsDialogOpen(true);
6123
+ }
6124
+ previousFileIdRef.current = fileId;
6125
+ }, [fileId, withCropper]);
6126
+ const handleApply = async (croppedUrl, croppedBlob) => {
6127
+ try {
6128
+ const newFinalUrl = URL.createObjectURL(croppedBlob);
6129
+ if (finalImageUrl) {
6130
+ URL.revokeObjectURL(finalImageUrl);
6131
+ }
6132
+ setFinalImageUrl(newFinalUrl);
6133
+ handleFileChange(file?.file, croppedBlob);
6134
+ setIsDialogOpen(false);
6135
+ } catch (error2) {
6136
+ setIsDialogOpen(false);
6137
+ }
6138
+ };
6139
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6140
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nebula-ds flex flex-col gap-3", children: [
6141
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nebula-ds flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs(
6142
+ "div",
6143
+ {
6144
+ role: "button",
6145
+ onClick: openFileDialog,
6146
+ onDragEnter: handleDragEnter,
6147
+ onDragLeave: handleDragLeave,
6148
+ onDragOver: handleDragOver,
6149
+ onDrop: handleDrop,
6150
+ "data-dragging": isDragging || void 0,
6151
+ className: cn(
6152
+ "relative border border-transparent rounded-full size-fit",
6153
+ "bg-fileUpload-background hover:bg-fileUpload-backgroundHover transition-colors",
6154
+ !file && "border-dashed border-fileUpload-border"
6155
+ ),
6156
+ "data-testid": "select-image-profile",
6157
+ children: [
6057
6158
  /* @__PURE__ */ jsxRuntime.jsx(
6058
- Button,
6159
+ "input",
6059
6160
  {
6060
- icon: true,
6061
- type: "button",
6062
- variant: "ghost",
6063
- onClick: () => onOpenChange(false),
6064
- "aria-label": "close-cropper-dialog",
6065
- "data-testid": "close-cropper-dialog",
6066
- size: "sm",
6067
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, { "aria-hidden": "true" })
6161
+ ...getInputProps(),
6162
+ className: "nebula-ds sr-only",
6163
+ "aria-label": "Upload file"
6068
6164
  }
6069
6165
  ),
6070
- cropper.dialogTitle
6071
- ] }),
6072
- /* @__PURE__ */ jsxRuntime.jsx(
6073
- Button,
6074
- {
6075
- autoFocus: false,
6076
- onClick: handleApply,
6077
- disabled: !previewUrl,
6078
- variant: "primary",
6079
- size: "sm",
6080
- type: "button",
6081
- "aria-label": "apply-cropper-image",
6082
- "data-testid": "apply-cropper-image",
6083
- children: cropper.applyButtonLabel
6084
- }
6085
- )
6086
- ] }) }),
6087
- previewUrl && /* @__PURE__ */ jsxRuntime.jsxs(
6088
- CropperRoot2,
6166
+ /* @__PURE__ */ jsxRuntime.jsxs(
6167
+ "div",
6168
+ {
6169
+ className: "nebula-ds flex size-12 shrink-0 items-center justify-center rounded-full",
6170
+ "aria-hidden": "true",
6171
+ children: [
6172
+ profileImagePreview && /* @__PURE__ */ jsxRuntime.jsx(
6173
+ "img",
6174
+ {
6175
+ src: profileImagePreview,
6176
+ alt: fileId,
6177
+ className: "nebula-ds rounded-[inherit] object-cover h-full w-full"
6178
+ }
6179
+ ),
6180
+ !file && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UserIcon, { className: "nebula-ds size-4 opacity-60 text-fileUpload-icon" })
6181
+ ]
6182
+ }
6183
+ ),
6184
+ profileImagePreview && file && /* @__PURE__ */ jsxRuntime.jsx(
6185
+ "button",
6186
+ {
6187
+ 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",
6188
+ "data-testid": "remove-profile-image",
6189
+ onClick: (e) => {
6190
+ e.stopPropagation();
6191
+ removeFile(file.id);
6192
+ setFinalImageUrl(null);
6193
+ onChange?.(void 0);
6194
+ onRemove?.();
6195
+ },
6196
+ type: "button",
6197
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, { className: "nebula-ds size-2" })
6198
+ }
6199
+ )
6200
+ ]
6201
+ }
6202
+ ) }),
6203
+ !!subtitle && /* @__PURE__ */ jsxRuntime.jsx(Paragraph, { className: "nebula-ds text-center", size: "sm", children: subtitle })
6204
+ ] }),
6205
+ withCropper && /* @__PURE__ */ jsxRuntime.jsx(
6206
+ Cropper2,
6207
+ {
6208
+ ...cropperProps,
6209
+ open: isDialogOpen,
6210
+ previewUrl,
6211
+ onOpenChange: setIsDialogOpen,
6212
+ onApply: handleApply,
6213
+ onCancelCrop: () => {
6214
+ fileId && removeFile(fileId);
6215
+ setFinalImageUrl(null);
6216
+ onChange?.(void 0);
6217
+ }
6218
+ }
6219
+ )
6220
+ ] });
6221
+ };
6222
+ ProfileImage.displayName = "ProfileImage";
6223
+ function RadioGroup2({
6224
+ className,
6225
+ ...props
6226
+ }) {
6227
+ return /* @__PURE__ */ jsxRuntime.jsx(
6228
+ RadioGroupPrimitive__namespace.Root,
6229
+ {
6230
+ "data-slot": "radio-group",
6231
+ className: cn("grid gap-3", className),
6232
+ ...props
6233
+ }
6234
+ );
6235
+ }
6236
+ function RadioGroupItem({
6237
+ className,
6238
+ ...props
6239
+ }) {
6240
+ return /* @__PURE__ */ jsxRuntime.jsx(
6241
+ RadioGroupPrimitive__namespace.Item,
6242
+ {
6243
+ "data-slot": "radio-group-item",
6244
+ className: cn(
6245
+ `
6246
+ border-2
6247
+ data-[state=checked]:border-4
6248
+
6249
+ border-radio-border-unselected-default
6250
+ data-[state=checked]:border-radio-background-selected-default
6251
+ hover:border-radio-border-unselected-hover
6252
+ data-[state=checked]:hover:border-radio-background-selected-hover
6253
+
6254
+ bg-radio-background-unselected-default
6255
+ data-[state=checked]:bg-radio-background-unselected-default
6256
+ hover:bg-radio-background-unselected-hover
6257
+ data-[state=checked]:hover:bg-radio-background-unselected-hover
6258
+
6259
+ disabled:border-radio-border-unselected-disabled
6260
+ disabled:bg-radio-background-unselected-disabled
6261
+ data-[state=checked]:disabled:bg-radio-background-unselected-default
6262
+ data-[state=checked]:disabled:border-radio-background-selected-disabled
6263
+
6264
+ focus-visible:ring-[2px]
6265
+ focus-visible:border-radio-border-selected-focus
6266
+
6267
+ aria-invalid:ring-destructive/20
6268
+ dark:aria-invalid:ring-destructive/40
6269
+ aria-invalid:border-destructive
6270
+
6271
+ aspect-square
6272
+ size-4
6273
+ shrink-0
6274
+ rounded-full
6275
+ shadow-xs
6276
+ transition-all
6277
+ outline-none
6278
+ disabled:cursor-not-allowed
6279
+ `,
6280
+ className
6281
+ ),
6282
+ ...props,
6283
+ children: /* @__PURE__ */ jsxRuntime.jsx(RadioGroupPrimitive__namespace.Indicator, { className: "nebula-ds flex items-center justify-center text-current", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nebula-ds rounded-full w-2 h-2" }) })
6284
+ }
6285
+ );
6286
+ }
6287
+ var StepperContext = React8.createContext(void 0);
6288
+ var StepItemContext = React8.createContext(
6289
+ void 0
6290
+ );
6291
+ var useStepper = () => {
6292
+ const context = React8.useContext(StepperContext);
6293
+ if (!context) {
6294
+ throw new Error("useStepper must be used within a Stepper");
6295
+ }
6296
+ return context;
6297
+ };
6298
+ var useStepItem = () => {
6299
+ const context = React8.useContext(StepItemContext);
6300
+ if (!context) {
6301
+ throw new Error("useStepItem must be used within a StepperItem");
6302
+ }
6303
+ return context;
6304
+ };
6305
+ function Stepper({
6306
+ defaultValue = 0,
6307
+ value,
6308
+ onValueChange,
6309
+ orientation = "horizontal",
6310
+ className,
6311
+ ...props
6312
+ }) {
6313
+ const [activeStep, setInternalStep] = React8__namespace.useState(defaultValue);
6314
+ const setActiveStep = React8__namespace.useCallback(
6315
+ (step) => {
6316
+ if (value === void 0) {
6317
+ setInternalStep(step);
6318
+ }
6319
+ onValueChange?.(step);
6320
+ },
6321
+ [value, onValueChange]
6322
+ );
6323
+ const currentStep = value ?? activeStep;
6324
+ return /* @__PURE__ */ jsxRuntime.jsx(
6325
+ StepperContext.Provider,
6326
+ {
6327
+ value: {
6328
+ activeStep: currentStep,
6329
+ setActiveStep,
6330
+ orientation
6331
+ },
6332
+ children: /* @__PURE__ */ jsxRuntime.jsx(
6333
+ "div",
6334
+ {
6335
+ "data-slot": "stepper",
6336
+ className: cn(
6337
+ `
6338
+ group/stepper
6339
+ gap-2
6340
+ inline-flex
6341
+ data-[orientation=horizontal]:w-full
6342
+ data-[orientation=horizontal]:flex-row
6343
+ data-[orientation=vertical]:flex-col
6344
+ `,
6345
+ className
6346
+ ),
6347
+ "data-orientation": orientation,
6348
+ ...props
6349
+ }
6350
+ )
6351
+ }
6352
+ );
6353
+ }
6354
+ function StepperItem({
6355
+ step,
6356
+ completed = false,
6357
+ disabled = false,
6358
+ loading = false,
6359
+ className,
6360
+ children,
6361
+ ...props
6362
+ }) {
6363
+ const { activeStep } = useStepper();
6364
+ const state = completed || step < activeStep ? "completed" : activeStep === step ? "active" : "inactive";
6365
+ const isLoading = loading && step === activeStep;
6366
+ return /* @__PURE__ */ jsxRuntime.jsx(
6367
+ StepItemContext.Provider,
6368
+ {
6369
+ value: { step, state, isDisabled: disabled, isLoading },
6370
+ children: /* @__PURE__ */ jsxRuntime.jsx(
6371
+ "div",
6372
+ {
6373
+ "data-slot": "stepper-item",
6374
+ className: cn(
6375
+ `
6376
+ group/step
6377
+ gap-2
6378
+ flex
6379
+ items-center
6380
+ group-data-[orientation=horizontal]/stepper:flex-row
6381
+ group-data-[orientation=vertical]/stepper:flex-col
6382
+ group-data-[orientation=vertical]/stepper:items-start
6383
+ `,
6384
+ className
6385
+ ),
6386
+ "data-state": state,
6387
+ ...isLoading ? { "data-loading": true } : {},
6388
+ ...props,
6389
+ children
6390
+ }
6391
+ )
6392
+ }
6393
+ );
6394
+ }
6395
+ function StepperTrigger({
6396
+ asChild = false,
6397
+ className,
6398
+ children,
6399
+ isClickable = true,
6400
+ ...props
6401
+ }) {
6402
+ const { setActiveStep } = useStepper();
6403
+ const { step, isDisabled } = useStepItem();
6404
+ if (asChild) {
6405
+ const Comp = asChild ? reactSlot.Slot : "span";
6406
+ return /* @__PURE__ */ jsxRuntime.jsx(Comp, { "data-slot": "stepper-trigger", className, children });
6407
+ }
6408
+ return /* @__PURE__ */ jsxRuntime.jsx(
6409
+ "button",
6410
+ {
6411
+ "data-slot": "stepper-trigger",
6412
+ className: cn(
6413
+ `
6414
+ gap-2
6415
+ inline-flex
6416
+ items-center
6417
+ rounded-full
6418
+ outline-none
6419
+ focus-visible:z-10
6420
+ focus-visible:border-ring
6421
+ focus-visible:ring-ring/50
6422
+ focus-visible:ring-[3px]
6423
+ disabled:pointer-events-none
6424
+ disabled:opacity-50
6425
+ `,
6426
+ className
6427
+ ),
6428
+ onClick: () => isClickable ? setActiveStep(step) : null,
6429
+ disabled: isDisabled,
6430
+ ...props,
6431
+ children
6432
+ }
6433
+ );
6434
+ }
6435
+ function StepperIndicator({
6436
+ asChild = false,
6437
+ className,
6438
+ children,
6439
+ ...props
6440
+ }) {
6441
+ const { state, step, isLoading } = useStepItem();
6442
+ return /* @__PURE__ */ jsxRuntime.jsx(
6443
+ "span",
6444
+ {
6445
+ "data-slot": "stepper-indicator",
6446
+ className: cn(
6447
+ `
6448
+ flex
6449
+ size-5
6450
+ shrink-0
6451
+ items-center
6452
+ justify-center
6453
+ rounded-full
6454
+ font-semibold
6455
+ text-xs
6456
+ transition-colors
6457
+ bg-stepper-background-default
6458
+ text-stepper-count-default
6459
+ data-[state=active]:bg-stepper-background-active
6460
+ data-[state=active]:text-stepper-count-active
6461
+ data-[state=completed]:bg-stepper-background-active
6462
+ data-[state=completed]:text-stepper-count-active
6463
+ `,
6464
+ className
6465
+ ),
6466
+ "data-state": state,
6467
+ ...props,
6468
+ children: asChild ? children : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6469
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx(
6470
+ lucideReact.LoaderCircleIcon,
6089
6471
  {
6090
- className: "nebula-ds h-96 sm:h-120",
6091
- image: previewUrl,
6092
- zoom,
6093
- onCropChange: handleCropChange,
6094
- onZoomChange: setZoom,
6095
- children: [
6096
- /* @__PURE__ */ jsxRuntime.jsx(CropperDescription2, {}),
6097
- /* @__PURE__ */ jsxRuntime.jsx(CropperImage2, {}),
6098
- /* @__PURE__ */ jsxRuntime.jsx(CropperCropArea2, { rounded })
6099
- ]
6472
+ className: "nebula-ds animate-spin",
6473
+ size: 14,
6474
+ "aria-hidden": "true"
6475
+ }
6476
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
6477
+ "span",
6478
+ {
6479
+ className: cn(
6480
+ `
6481
+ transition-all
6482
+ group-data-[state=completed]/step:scale-0
6483
+ group-data-[state=completed]/step:opacity-0
6484
+ `
6485
+ ),
6486
+ children: step
6100
6487
  }
6101
6488
  ),
6102
- /* @__PURE__ */ jsxRuntime.jsx(DialogFooter, { className: "nebula-ds border-t border-t-cropper-dialogBorderColor px-4 py-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nebula-ds mx-auto flex w-full max-w-80 items-center gap-4", children: [
6103
- /* @__PURE__ */ jsxRuntime.jsx(
6104
- lucideReact.MinusIcon,
6105
- {
6106
- className: "nebula-ds shrink-0 size-5 text-cropper-sliderIconColor",
6107
- size: 16,
6108
- "aria-hidden": "true"
6109
- }
6110
- ),
6111
- /* @__PURE__ */ jsxRuntime.jsx(
6112
- Slider,
6113
- {
6114
- defaultValue: [1],
6115
- value: [zoom],
6116
- min: 1,
6117
- max: 3,
6118
- step: 0.1,
6119
- onValueChange: (value) => setZoom(value[0]),
6120
- "aria-label": "Zoom slider"
6121
- }
6122
- ),
6123
- /* @__PURE__ */ jsxRuntime.jsx(
6124
- lucideReact.PlusIcon,
6125
- {
6126
- className: "nebula-ds shrink-0 size-5 text-cropper-sliderIconColor",
6127
- size: 16,
6128
- "aria-hidden": "true"
6129
- }
6130
- )
6131
- ] }) })
6132
- ]
6489
+ /* @__PURE__ */ jsxRuntime.jsx(
6490
+ lucideReact.CheckIcon,
6491
+ {
6492
+ className: cn(
6493
+ `
6494
+ absolute
6495
+ scale-0
6496
+ opacity-0
6497
+ transition-all
6498
+ group-data-[state=completed]/step:scale-100
6499
+ group-data-[state=completed]/step:opacity-100
6500
+ `
6501
+ ),
6502
+ size: 16,
6503
+ "aria-hidden": "true"
6504
+ }
6505
+ )
6506
+ ] })
6133
6507
  }
6134
- ) });
6508
+ );
6509
+ }
6510
+ function StepperTitle({
6511
+ className,
6512
+ ...props
6513
+ }) {
6514
+ const { state } = useStepItem();
6515
+ return /* @__PURE__ */ jsxRuntime.jsx(
6516
+ "h3",
6517
+ {
6518
+ "data-slot": "stepper-title",
6519
+ className: cn(
6520
+ `
6521
+ text-sm
6522
+ font-medium
6523
+ text-stepper-title-default
6524
+ data-[state=active]:text-stepper-title-active
6525
+ data-[state=completed]:text-stepper-title-active
6526
+ `,
6527
+ className
6528
+ ),
6529
+ "data-state": state,
6530
+ ...props
6531
+ }
6532
+ );
6533
+ }
6534
+ function StepperDescription({
6535
+ className,
6536
+ ...props
6537
+ }) {
6538
+ return /* @__PURE__ */ jsxRuntime.jsx(
6539
+ "p",
6540
+ {
6541
+ "data-slot": "stepper-description",
6542
+ className: cn(
6543
+ `
6544
+ text-sm
6545
+ text-muted-foreground
6546
+ `,
6547
+ className
6548
+ ),
6549
+ ...props
6550
+ }
6551
+ );
6552
+ }
6553
+ function StepperSeparator({
6554
+ className,
6555
+ ...props
6556
+ }) {
6557
+ const { step } = useStepItem();
6558
+ const { activeStep, orientation } = useStepper();
6559
+ const separatorState = step < activeStep ? "completed" : "inactive";
6560
+ const line = /* @__PURE__ */ jsxRuntime.jsx(
6561
+ "div",
6562
+ {
6563
+ "data-slot": "stepper-separator",
6564
+ "data-orientation": orientation,
6565
+ className: cn(
6566
+ `
6567
+ rounded-full
6568
+ bg-stepper-separator-default
6569
+ `,
6570
+ orientation === "horizontal" && `
6571
+ w-5
6572
+ h-[2px]
6573
+ flex-1
6574
+ `,
6575
+ orientation === "vertical" && `
6576
+ w-[2px]
6577
+ h-5
6578
+ flex-none
6579
+ `,
6580
+ separatorState === "completed" && `
6581
+ bg-stepper-separator-active
6582
+ `,
6583
+ className
6584
+ ),
6585
+ "data-state": separatorState,
6586
+ ...props
6587
+ }
6588
+ );
6589
+ if (orientation === "vertical") {
6590
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nebula-ds flex w-5 justify-center", children: line });
6591
+ }
6592
+ return line;
6135
6593
  }
6136
6594
 
6137
6595
  // src/tailwind.ts
@@ -6241,6 +6699,8 @@ exports.Popover = Popover;
6241
6699
  exports.PopoverContent = PopoverContent;
6242
6700
  exports.PopoverTrigger = PopoverTrigger;
6243
6701
  exports.ProfileImage = ProfileImage;
6702
+ exports.RadioGroup = RadioGroup2;
6703
+ exports.RadioGroupItem = RadioGroupItem;
6244
6704
  exports.Select = StyledSelect;
6245
6705
  exports.Separator = Separator2;
6246
6706
  exports.Skeleton = Skeleton;
@@ -6248,6 +6708,13 @@ exports.Slider = Slider;
6248
6708
  exports.Space = Space;
6249
6709
  exports.SpaceDirectionEnum = SpaceDirectionEnum;
6250
6710
  exports.SpaceSizeEnum = SpaceSizeEnum;
6711
+ exports.Stepper = Stepper;
6712
+ exports.StepperDescription = StepperDescription;
6713
+ exports.StepperIndicator = StepperIndicator;
6714
+ exports.StepperItem = StepperItem;
6715
+ exports.StepperSeparator = StepperSeparator;
6716
+ exports.StepperTitle = StepperTitle;
6717
+ exports.StepperTrigger = StepperTrigger;
6251
6718
  exports.Switch = Switch;
6252
6719
  exports.Table = Table;
6253
6720
  exports.TableBody = TableBody;