@mlw-packages/react-components 1.7.3 → 1.7.4

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
@@ -560,7 +560,6 @@ __export(index_exports, {
560
560
  ContextMenuTriggerBase: () => ContextMenuTriggerBase,
561
561
  CopyButton: () => CopyButton,
562
562
  DateTimePicker: () => DateTimePicker,
563
- DeleteButton: () => DeleteButton,
564
563
  DestructiveDialog: () => DestructiveDialog,
565
564
  DialogBase: () => DialogBase,
566
565
  DialogCloseBase: () => DialogCloseBase,
@@ -2728,7 +2727,8 @@ var DraggableTooltipComponent = ({
2728
2727
  highlightedSeries,
2729
2728
  toggleHighlight,
2730
2729
  showOnlyHighlighted,
2731
- valueFormatter: valueFormatter2
2730
+ valueFormatter: valueFormatter2,
2731
+ categoryFormatter
2732
2732
  }) => {
2733
2733
  const visibleKeys = (0, import_react16.useMemo)(
2734
2734
  () => showOnlyHighlighted && highlightedSeries && highlightedSeries.size > 0 ? dataKeys.filter((k) => highlightedSeries.has(k)) : dataKeys,
@@ -3136,7 +3136,7 @@ var DraggableTooltipComponent = ({
3136
3136
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "px-3 py-2 bg-accent/5 border-l-4 border-primary", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
3137
3137
  /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
3138
3138
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide", children: periodLabel }),
3139
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "font-bold text-lg text-foreground mt-1 truncate", children: data.name })
3139
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "font-bold text-lg text-foreground mt-1 truncate", children: categoryFormatter ? categoryFormatter(String(data.name)) : data.name })
3140
3140
  ] }),
3141
3141
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "text-right", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3142
3142
  TotalDisplay,
@@ -3280,15 +3280,28 @@ var RechartTooltipWithTotal = ({
3280
3280
  finalColors = {},
3281
3281
  periodLabel = "Per\xEDodo",
3282
3282
  totalLabel = "Total",
3283
- valueFormatter: valueFormatter2
3283
+ valueFormatter: valueFormatter2,
3284
+ categoryFormatter
3284
3285
  }) => {
3285
3286
  if (!active || !payload || payload.length === 0) return null;
3287
+ const displayLabel = categoryFormatter ? categoryFormatter(String(label ?? "")) : label;
3286
3288
  const numeric = payload.filter(
3287
3289
  (p) => typeof p.value === "number" && Number.isFinite(p.value)
3288
3290
  );
3289
3291
  const total = numeric.reduce((sum, p) => sum + (p.value || 0), 0);
3290
3292
  const isTotalNegative = total < 0;
3291
- const defaultTotalFormatted = total.toLocaleString("pt-BR");
3293
+ const defaultTotalFormatted = (() => {
3294
+ try {
3295
+ if (Math.abs(total) < 1e3) {
3296
+ return new Intl.NumberFormat("pt-BR", {
3297
+ minimumFractionDigits: 2,
3298
+ maximumFractionDigits: 2
3299
+ }).format(total);
3300
+ }
3301
+ } catch {
3302
+ }
3303
+ return total.toLocaleString("pt-BR");
3304
+ })();
3292
3305
  const displayTotal = valueFormatter2 ? valueFormatter2({
3293
3306
  value: total,
3294
3307
  formattedValue: defaultTotalFormatted,
@@ -3310,7 +3323,7 @@ var RechartTooltipWithTotal = ({
3310
3323
  /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-start justify-between mb-2", children: [
3311
3324
  /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "pr-2", children: [
3312
3325
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-xs text-muted-foreground", children: periodLabel }),
3313
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "font-medium text-foreground truncate", children: label })
3326
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "font-medium text-foreground truncate", children: displayLabel })
3314
3327
  ] }),
3315
3328
  /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "text-right ml-3", children: [
3316
3329
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-xs text-muted-foreground", children: totalLabel }),
@@ -3328,7 +3341,18 @@ var RechartTooltipWithTotal = ({
3328
3341
  const pct = absDenominator > 0 ? Math.abs(value) / absDenominator * 100 : 0;
3329
3342
  const baseColor = finalColors[entry.dataKey] || entry.color || "#999";
3330
3343
  const isNeg = value < 0;
3331
- const defaultFormatted = value.toLocaleString("pt-BR");
3344
+ const defaultFormatted = (() => {
3345
+ try {
3346
+ if (Math.abs(value) < 1e3) {
3347
+ return new Intl.NumberFormat("pt-BR", {
3348
+ minimumFractionDigits: 2,
3349
+ maximumFractionDigits: 2
3350
+ }).format(value);
3351
+ }
3352
+ } catch {
3353
+ }
3354
+ return value.toLocaleString("pt-BR");
3355
+ })();
3332
3356
  const displayValue = valueFormatter2 ? valueFormatter2({
3333
3357
  value: entry.value,
3334
3358
  formattedValue: defaultFormatted,
@@ -3385,9 +3409,11 @@ var TooltipSimple = ({
3385
3409
  label,
3386
3410
  finalColors = {},
3387
3411
  periodLabel = "Per\xEDodo",
3388
- valueFormatter: valueFormatter2
3412
+ valueFormatter: valueFormatter2,
3413
+ categoryFormatter
3389
3414
  }) => {
3390
3415
  if (!active || !payload || payload.length === 0) return null;
3416
+ const displayLabel = categoryFormatter ? categoryFormatter(String(label ?? "")) : label;
3391
3417
  return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
3392
3418
  "div",
3393
3419
  {
@@ -3398,12 +3424,23 @@ var TooltipSimple = ({
3398
3424
  children: [
3399
3425
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "mb-2", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex items-center justify-between gap-3", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "min-w-0", children: [
3400
3426
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-xs text-muted-foreground", children: periodLabel }),
3401
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "font-medium text-foreground truncate", children: label })
3427
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "font-medium text-foreground truncate", children: displayLabel })
3402
3428
  ] }) }) }),
3403
3429
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "divide-y divide-border rounded-md overflow-hidden", children: payload.map((entry, index) => {
3404
3430
  const value = typeof entry.value === "number" ? entry.value : 0;
3405
3431
  const color = finalColors[entry.dataKey] || entry.color || "#999";
3406
- const defaultFormatted = value.toLocaleString("pt-BR");
3432
+ const defaultFormatted = (() => {
3433
+ try {
3434
+ if (Math.abs(value) < 1e3) {
3435
+ return new Intl.NumberFormat("pt-BR", {
3436
+ minimumFractionDigits: 2,
3437
+ maximumFractionDigits: 2
3438
+ }).format(value);
3439
+ }
3440
+ } catch {
3441
+ }
3442
+ return value.toLocaleString("pt-BR");
3443
+ })();
3407
3444
  const displayValue = valueFormatter2 ? valueFormatter2({
3408
3445
  value: entry.value,
3409
3446
  formattedValue: defaultFormatted,
@@ -3455,9 +3492,17 @@ var formatCompactNumber = (value) => {
3455
3492
  } else if (absValue >= 1e6) {
3456
3493
  formatted = (absValue / 1e6).toFixed(1).replace(/\.0$/, "") + "M";
3457
3494
  } else if (absValue >= 1e3) {
3458
- formatted = (absValue / 1e3).toFixed(1).replace(/\.0$/, "") + "K";
3495
+ formatted = (absValue / 1e3).toFixed(1).replace(/\.0$/, "") + " mil";
3459
3496
  } else {
3460
- formatted = absValue.toString();
3497
+ try {
3498
+ const nf = new Intl.NumberFormat("pt-BR", {
3499
+ minimumFractionDigits: 2,
3500
+ maximumFractionDigits: 2
3501
+ });
3502
+ formatted = nf.format(absValue);
3503
+ } catch {
3504
+ formatted = String(absValue).replace(".", ",");
3505
+ }
3461
3506
  }
3462
3507
  return isNegative ? `-${formatted}` : formatted;
3463
3508
  };
@@ -3513,9 +3558,9 @@ var renderPillLabel = (color, variant, valueFormatter2) => {
3513
3558
  const py = parseNumber(props.y);
3514
3559
  const cyNum = parseNumber(props.cy);
3515
3560
  const centerY = yNum ?? (typeof py === "number" ? py : vb && typeof vb.y === "number" && typeof vb.height === "number" ? vb.y + vb.height / 2 : typeof cyNum === "number" ? cyNum : 0);
3516
- const rectX = centerX - pillWidth / 2;
3561
+ const rectX = centerX - pillWidth / 3.5;
3517
3562
  const rectY = centerY - pillHeight - 6;
3518
- const textX = centerX;
3563
+ const textX = centerX - pillWidth / 3.5 + pillWidth / 2;
3519
3564
  const textY = rectY + pillHeight / 2 + 3;
3520
3565
  const rectFill = variant === "filled" ? color : variant === "soft" ? `${color}20` : "#ffffff";
3521
3566
  const rectStroke = variant === "outline" ? `${color}CC` : void 0;
@@ -3536,7 +3581,7 @@ var renderPillLabel = (color, variant, valueFormatter2) => {
3536
3581
  "rect",
3537
3582
  {
3538
3583
  x: rectX,
3539
- y: rectY,
3584
+ y: rectY + 4,
3540
3585
  rx: pillHeight / 2,
3541
3586
  width: pillWidth,
3542
3587
  height: pillHeight,
@@ -3549,7 +3594,7 @@ var renderPillLabel = (color, variant, valueFormatter2) => {
3549
3594
  "text",
3550
3595
  {
3551
3596
  x: textX,
3552
- y: textY - 3,
3597
+ y: textY + 2,
3553
3598
  fill: textColor,
3554
3599
  fontSize: 13,
3555
3600
  fontWeight: 700,
@@ -3582,14 +3627,18 @@ var Chart = ({
3582
3627
  titlePosition = "left",
3583
3628
  showLabels = false,
3584
3629
  xAxis,
3630
+ xAxisLabel,
3631
+ yAxisLabel,
3585
3632
  labelMap,
3586
3633
  valueFormatter: valueFormatter2,
3634
+ categoryFormatter,
3587
3635
  enableHighlights = false,
3588
3636
  enableShowOnly = false,
3589
3637
  enablePeriodsDropdown = false,
3590
3638
  enableDraggableTooltips = false,
3591
3639
  showTooltipTotal = false,
3592
3640
  maxTooltips = 5,
3641
+ formatBR = false,
3593
3642
  chartMargin
3594
3643
  }) => {
3595
3644
  const smartConfig = (0, import_react18.useMemo)(() => {
@@ -3842,6 +3891,68 @@ var Chart = ({
3842
3891
  () => "text-xl font-semibold text-foreground mb-3",
3843
3892
  []
3844
3893
  );
3894
+ const finalValueFormatter = (0, import_react18.useMemo)(() => {
3895
+ const nf = new Intl.NumberFormat("pt-BR", {
3896
+ minimumFractionDigits: 2,
3897
+ maximumFractionDigits: 2
3898
+ });
3899
+ if (valueFormatter2) {
3900
+ if (formatBR) {
3901
+ const wrapped = (props) => {
3902
+ const { value, formattedValue } = props;
3903
+ let num = NaN;
3904
+ if (typeof value === "number") num = value;
3905
+ else if (typeof value === "string" && value.trim() !== "") {
3906
+ const parsed = Number(value);
3907
+ num = Number.isNaN(parsed) ? NaN : parsed;
3908
+ }
3909
+ const brFormatted = !Number.isNaN(num) ? nf.format(num) : String(formattedValue ?? value ?? "");
3910
+ return valueFormatter2({
3911
+ ...props,
3912
+ formattedValue: brFormatted,
3913
+ value: void 0
3914
+ });
3915
+ };
3916
+ return wrapped;
3917
+ }
3918
+ return valueFormatter2;
3919
+ }
3920
+ if (!formatBR) return void 0;
3921
+ const builtIn = (props) => {
3922
+ const { value, formattedValue } = props;
3923
+ let num = NaN;
3924
+ if (typeof value === "number") num = value;
3925
+ else if (typeof value === "string" && value.trim() !== "") {
3926
+ const parsed = Number(value);
3927
+ num = Number.isNaN(parsed) ? NaN : parsed;
3928
+ }
3929
+ if (!Number.isNaN(num)) return nf.format(num);
3930
+ return String(formattedValue ?? value ?? "");
3931
+ };
3932
+ return builtIn;
3933
+ }, [valueFormatter2, formatBR]);
3934
+ const yTickFormatter = (0, import_react18.useMemo)(() => {
3935
+ const nf = new Intl.NumberFormat("pt-BR", {
3936
+ minimumFractionDigits: 2,
3937
+ maximumFractionDigits: 2
3938
+ });
3939
+ const stripCurrency = (s) => String(s).replace(/^\s*R\$\s?/, "");
3940
+ if (finalValueFormatter) {
3941
+ return (v) => {
3942
+ const num = Number(String(v));
3943
+ const formatted = Number.isNaN(num) ? String(v ?? "") : nf.format(num);
3944
+ const out = finalValueFormatter({
3945
+ value: v,
3946
+ formattedValue: formatted
3947
+ });
3948
+ return stripCurrency(String(out));
3949
+ };
3950
+ }
3951
+ return (value) => {
3952
+ const num = Number(String(value));
3953
+ return Number.isNaN(num) ? String(value ?? "") : nf.format(num);
3954
+ };
3955
+ }, [finalValueFormatter]);
3845
3956
  const finalEnableHighlights = enableHighlights;
3846
3957
  const finalEnableShowOnly = enableShowOnly;
3847
3958
  const finalEnablePeriodsDropdown = enablePeriodsDropdown && enableDraggableTooltips;
@@ -3849,9 +3960,12 @@ var Chart = ({
3849
3960
  const defaultChartLeftMargin = 0;
3850
3961
  const containerPaddingLeft = 16;
3851
3962
  const finalChartRightMargin = chartMargin?.right ?? defaultChartRightMargin;
3852
- const finalChartLeftMargin = chartMargin?.left ?? defaultChartLeftMargin;
3963
+ const finalChartLeftMargin = chartMargin?.left ?? (yAxisLabel ? 40 : defaultChartLeftMargin);
3853
3964
  const finalChartTopMargin = chartMargin?.top ?? (showLabels ? 48 : 20);
3854
- const finalChartBottomMargin = chartMargin?.bottom ?? 5;
3965
+ const baseBottom = chartMargin?.bottom ?? 5;
3966
+ const extraForXAxisLabel = xAxisLabel ? 22 : 0;
3967
+ const extraForLegend = showLegend ? 36 : 0;
3968
+ const finalChartBottomMargin = baseBottom + extraForXAxisLabel + extraForLegend;
3855
3969
  const measuredInner = measuredWidth ? Math.max(0, measuredWidth - 32) : void 0;
3856
3970
  const effectiveChartWidth = typeof width === "number" ? width : measuredInner ?? computedWidth;
3857
3971
  const chartInnerWidth = effectiveChartWidth - finalChartLeftMargin - finalChartRightMargin;
@@ -4053,7 +4167,23 @@ var Chart = ({
4053
4167
  fontSize: 12,
4054
4168
  tickLine: false,
4055
4169
  axisLine: false,
4056
- tickFormatter: xAxisConfig.valueFormatter
4170
+ tickFormatter: (value) => {
4171
+ if (categoryFormatter)
4172
+ return categoryFormatter(value);
4173
+ if (xAxisConfig.valueFormatter)
4174
+ return xAxisConfig.valueFormatter(value);
4175
+ return String(value ?? "");
4176
+ },
4177
+ label: xAxisLabel ? {
4178
+ value: xAxisLabel,
4179
+ position: "insideBottomRight",
4180
+ offset: -5,
4181
+ style: {
4182
+ fontSize: 12,
4183
+ fill: "hsl(var(--muted-foreground))",
4184
+ fontWeight: 500
4185
+ }
4186
+ } : void 0
4057
4187
  }
4058
4188
  ),
4059
4189
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
@@ -4063,9 +4193,22 @@ var Chart = ({
4063
4193
  fontSize: 12,
4064
4194
  tickLine: false,
4065
4195
  axisLine: false,
4066
- tickFormatter: (value) => Number(value).toLocaleString("pt-BR"),
4196
+ tickFormatter: yTickFormatter,
4067
4197
  domain: [Math.min(minDataValue, 0), niceMax],
4068
- tickCount: 6
4198
+ tickCount: 6,
4199
+ label: yAxisLabel ? {
4200
+ value: yAxisLabel,
4201
+ angle: -90,
4202
+ // Render the label to the left (outside) of the chart area
4203
+ // to avoid overlapping the Y values / bars.
4204
+ position: "left",
4205
+ style: {
4206
+ fontSize: 12,
4207
+ fill: "hsl(var(--muted-foreground))",
4208
+ fontWeight: 500,
4209
+ textAnchor: "middle"
4210
+ }
4211
+ } : void 0
4069
4212
  }
4070
4213
  ),
4071
4214
  minDataValue < 0 && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
@@ -4084,13 +4227,15 @@ var Chart = ({
4084
4227
  TooltipWithTotal_default,
4085
4228
  {
4086
4229
  finalColors,
4087
- valueFormatter: valueFormatter2
4230
+ valueFormatter: finalValueFormatter,
4231
+ categoryFormatter
4088
4232
  }
4089
4233
  ) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4090
4234
  TooltipSimple_default,
4091
4235
  {
4092
4236
  finalColors,
4093
- valueFormatter: valueFormatter2
4237
+ valueFormatter: finalValueFormatter,
4238
+ categoryFormatter
4094
4239
  }
4095
4240
  ),
4096
4241
  cursor: { fill: "hsl(var(--muted))", opacity: 0.1 }
@@ -4101,7 +4246,8 @@ var Chart = ({
4101
4246
  {
4102
4247
  wrapperStyle: {
4103
4248
  color: "hsl(var(--foreground))",
4104
- fontSize: "14px"
4249
+ fontSize: "14px",
4250
+ paddingTop: "8px"
4105
4251
  }
4106
4252
  }
4107
4253
  ),
@@ -4141,7 +4287,7 @@ var Chart = ({
4141
4287
  content: pillLabelRenderer_default(
4142
4288
  color,
4143
4289
  "filled",
4144
- valueFormatter2
4290
+ finalValueFormatter
4145
4291
  ),
4146
4292
  offset: 8
4147
4293
  }
@@ -4174,7 +4320,7 @@ var Chart = ({
4174
4320
  content: pillLabelRenderer_default(
4175
4321
  color,
4176
4322
  "filled",
4177
- valueFormatter2
4323
+ finalValueFormatter
4178
4324
  ),
4179
4325
  offset: 14
4180
4326
  }
@@ -4207,7 +4353,7 @@ var Chart = ({
4207
4353
  content: pillLabelRenderer_default(
4208
4354
  color,
4209
4355
  "soft",
4210
- valueFormatter2
4356
+ finalValueFormatter
4211
4357
  ),
4212
4358
  offset: 12
4213
4359
  }
@@ -4237,7 +4383,8 @@ var Chart = ({
4237
4383
  onPositionChange: onTooltipPositionChange,
4238
4384
  periodLabel: "Per\xEDodo Selecionado",
4239
4385
  dataLabel: "Dados do Per\xEDodo",
4240
- valueFormatter: valueFormatter2,
4386
+ valueFormatter: finalValueFormatter,
4387
+ categoryFormatter,
4241
4388
  globalTooltipCount: activeTooltips.length,
4242
4389
  onCloseAll: () => window.dispatchEvent(new Event("closeAllTooltips")),
4243
4390
  closeAllButtonPosition: "top-center",
@@ -6045,2288 +6192,2218 @@ var CardFooterBase = React17.forwardRef(({ className, testid: dataTestId = "card
6045
6192
  CardFooterBase.displayName = "CardFooter";
6046
6193
 
6047
6194
  // src/components/ui/data/FileUploader.tsx
6048
- var React21 = __toESM(require("react"));
6195
+ var React18 = __toESM(require("react"));
6049
6196
  var import_framer_motion10 = require("framer-motion");
6050
- var import_react25 = require("@phosphor-icons/react");
6051
-
6052
- // src/components/ui/form/SmallButtons.tsx
6053
- var React20 = __toESM(require("react"));
6054
-
6055
- // src/components/ui/feedback/DestructiveDialog.tsx
6056
- var React19 = __toESM(require("react"));
6057
6197
  var import_react23 = require("@phosphor-icons/react");
6058
-
6059
- // src/components/ui/feedback/AlertDialogBase.tsx
6060
- var React18 = __toESM(require("react"));
6061
- var AlertDialogPrimitive = __toESM(require("@radix-ui/react-alert-dialog"));
6062
6198
  var import_jsx_runtime35 = require("react/jsx-runtime");
6063
- var AlertDialogBase = AlertDialogPrimitive.Root;
6064
- var AlertDialogTriggerBase = AlertDialogPrimitive.Trigger;
6065
- var AlertDialogPortalBase = AlertDialogPrimitive.Portal;
6066
- var AlertDialogOverlayBase = React18.forwardRef(({ className, testid = "alertdialog-overlay", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6067
- AlertDialogPrimitive.Overlay,
6068
- {
6069
- className: cn(
6070
- "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
6071
- className
6072
- ),
6073
- "data-testid": testid,
6074
- ...props,
6075
- ref
6199
+ var formatFileSize = (bytes) => {
6200
+ if (bytes === 0) return "0 Bytes";
6201
+ const k = 1024;
6202
+ const sizes = ["Bytes", "KB", "MB", "GB"];
6203
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
6204
+ return Math.round(bytes / Math.pow(k, i) * 100) / 100 + " " + sizes[i];
6205
+ };
6206
+ var getFileExtension = (filename) => {
6207
+ return filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2);
6208
+ };
6209
+ var getFileTypeIcon = (file) => {
6210
+ const extension = getFileExtension(file.name).toLowerCase();
6211
+ const mimeType = file.type.toLowerCase();
6212
+ if (extension === "pdf" || mimeType === "application/pdf") {
6213
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react23.FilePdfIcon, { size: 20, className: "text-red-500" });
6076
6214
  }
6077
- ));
6078
- AlertDialogOverlayBase.displayName = AlertDialogPrimitive.Overlay.displayName;
6079
- var AlertDialogContentBase = React18.forwardRef(({ className, testid = "alertdialog-content", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(AlertDialogPortalBase, { children: [
6080
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(AlertDialogOverlayBase, {}),
6081
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6082
- AlertDialogPrimitive.Content,
6083
- {
6084
- ref,
6085
- className: cn(
6086
- "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
6087
- className
6088
- ),
6089
- "data-testid": testid,
6090
- ...props
6091
- }
6092
- )
6093
- ] }));
6094
- AlertDialogContentBase.displayName = AlertDialogPrimitive.Content.displayName;
6095
- var AlertDialogHeaderBase = ({
6096
- className,
6097
- ...props
6098
- }) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6099
- "div",
6100
- {
6101
- className: cn(
6102
- "flex flex-col space-y-2 text-center sm:text-left",
6103
- className
6104
- ),
6105
- ...props
6215
+ if (["doc", "docx"].includes(extension) || mimeType.includes("word")) {
6216
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react23.FileDocIcon, { size: 20, className: "text-blue-500" });
6106
6217
  }
6107
- );
6108
- AlertDialogHeaderBase.displayName = "AlertDialogHeaderBase";
6109
- var AlertDialogFooterBase = ({
6110
- className,
6111
- ...props
6112
- }) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6113
- "div",
6114
- {
6115
- className: cn(
6116
- "flex flex-col-reverse sm:flex-row sm:justify-end",
6117
- className
6118
- ),
6119
- ...props
6218
+ if (["xls", "xlsx"].includes(extension) || mimeType.includes("sheet")) {
6219
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react23.FileXlsIcon, { size: 20, className: "text-green-500" });
6120
6220
  }
6121
- );
6122
- AlertDialogFooterBase.displayName = "AlertDialogFooterBase";
6123
- var AlertDialogTitleBase = React18.forwardRef(({ className, testid = "alertdialog-title", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6124
- AlertDialogPrimitive.Title,
6125
- {
6126
- ref,
6127
- className: cn("text-lg font-semibold", className),
6128
- "data-testid": testid,
6129
- ...props
6221
+ if (["ppt", "pptx"].includes(extension) || mimeType.includes("presentation")) {
6222
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react23.FilePptIcon, { size: 20, className: "text-orange-500" });
6130
6223
  }
6131
- ));
6132
- AlertDialogTitleBase.displayName = AlertDialogPrimitive.Title.displayName;
6133
- var AlertDialogDescriptionBase = React18.forwardRef(({ className, testid = "alertdialog-description", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6134
- AlertDialogPrimitive.Description,
6135
- {
6136
- ref,
6137
- className: cn("text-sm text-muted-foreground", className),
6138
- "data-testid": testid,
6139
- ...props
6224
+ if (extension === "csv" || mimeType === "text/csv") {
6225
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react23.FileCsvIcon, { size: 20, className: "text-green-600" });
6140
6226
  }
6141
- ));
6142
- AlertDialogDescriptionBase.displayName = AlertDialogPrimitive.Description.displayName;
6143
- var AlertDialogActionBase = React18.forwardRef(({ className, testid = "alertdialog-action", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6144
- AlertDialogPrimitive.Action,
6145
- {
6146
- ref,
6147
- className: cn(buttonVariantsBase(), className),
6148
- "data-testid": testid,
6149
- ...props
6227
+ if (["txt", "md", "json", "xml", "js", "ts", "html", "css"].includes(
6228
+ extension
6229
+ ) || mimeType.includes("text")) {
6230
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react23.FileTextIcon, { size: 20, className: "text-gray-500" });
6150
6231
  }
6151
- ));
6152
- AlertDialogActionBase.displayName = AlertDialogPrimitive.Action.displayName;
6153
- var AlertDialogCancelBase = React18.forwardRef(({ className, testid = "alertdialog-cancel", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6154
- AlertDialogPrimitive.Cancel,
6155
- {
6156
- ref,
6157
- className: cn(buttonVariantsBase({ variant: "outline" }), className),
6158
- "data-testid": testid,
6159
- ...props
6232
+ if (mimeType.startsWith("image/")) {
6233
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react23.FileImageIcon, { size: 20, className: "text-purple-500" });
6160
6234
  }
6161
- ));
6162
- AlertDialogCancelBase.displayName = AlertDialogPrimitive.Cancel.displayName;
6163
-
6164
- // src/components/ui/feedback/DestructiveDialog.tsx
6165
- var import_jsx_runtime36 = require("react/jsx-runtime");
6166
- var DestructiveDialog = ({
6167
- title,
6168
- description,
6169
- onConfirm,
6170
- onCancel,
6171
- children,
6172
- triggerContent
6173
- }) => {
6174
- const triggerEl = React19.isValidElement(children) ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(AlertDialogTriggerBase, { asChild: true, children }) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(AlertDialogTriggerBase, { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ButtonBase, { variant: "destructive", children: triggerContent ?? "Excluir" }) });
6175
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(AlertDialogBase, { children: [
6176
- triggerEl,
6177
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
6178
- AlertDialogContentBase,
6179
- {
6180
- className: cn("border border-destructive bg-background"),
6181
- children: [
6182
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-start gap-4", children: [
6183
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "flex items-center justify-center w-10 h-10 rounded-full ring-1 ring-destructive/30", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react23.XCircleIcon, { className: "w-6 h-6 text-destructive" }) }),
6184
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex-1", children: [
6185
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(AlertDialogTitleBase, { className: "text-lg sm:text-xl font-semibold text-destructive", children: title }),
6186
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(AlertDialogDescriptionBase, { className: "mt-2 text-sm text-muted-foreground", children: description })
6187
- ] })
6188
- ] }),
6189
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(AlertDialogFooterBase, { className: "mt-2 flex justify-end gap-3", children: [
6190
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6191
- AlertDialogCancelBase,
6192
- {
6193
- onClick: onCancel,
6194
- className: cn(
6195
- buttonVariantsBase({ variant: "outline", size: "default" }),
6196
- "hover:bg-foreground/5 hover:text-primary hover:opacity-90 hover:shadow-none"
6197
- ),
6198
- children: "Cancelar"
6199
- }
6200
- ),
6201
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6202
- AlertDialogActionBase,
6203
- {
6204
- onClick: onConfirm,
6205
- className: cn(
6206
- buttonVariantsBase({ variant: "destructive", size: "default" })
6207
- ),
6208
- children: "Confirmar"
6209
- }
6210
- )
6211
- ] })
6212
- ]
6213
- }
6214
- )
6215
- ] });
6235
+ if (mimeType.startsWith("video/")) {
6236
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react23.FileVideoIcon, { size: 20, className: "text-pink-500" });
6237
+ }
6238
+ if (mimeType.startsWith("audio/")) {
6239
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react23.FileAudioIcon, { size: 20, className: "text-indigo-500" });
6240
+ }
6241
+ if (["zip", "rar", "7z", "tar", "gz"].includes(extension)) {
6242
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react23.FileZipIcon, { size: 20, className: "text-yellow-600" });
6243
+ }
6244
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react23.FileIcon, { size: 20, className: "text-muted-foreground" });
6216
6245
  };
6217
-
6218
- // src/components/ui/form/SmallButtons.tsx
6219
- var import_react24 = require("@phosphor-icons/react");
6220
- var import_jsx_runtime37 = require("react/jsx-runtime");
6221
- var EditButton = React20.forwardRef(
6222
- ({
6223
- disabled,
6224
- onClick,
6225
- testid = "button-edit",
6226
- className,
6227
- iconSize = 18,
6228
- iconColor,
6229
- variant = "default",
6230
- size = "icon",
6231
- ...props
6232
- }, ref) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6233
- ButtonBase,
6234
- {
6235
- ref,
6236
- variant,
6237
- size,
6238
- onClick,
6239
- disabled,
6240
- testid,
6241
- className: cn(
6242
- "transition-all duration-200 ease-in-out group",
6243
- "hover:scale-105",
6244
- "active:scale-95",
6245
- "disabled:hover:scale-100",
6246
- className
6247
- ),
6248
- ...props,
6249
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6250
- import_react24.PencilSimpleIcon,
6251
- {
6252
- size: iconSize,
6253
- color: iconColor,
6254
- className: "transition-transform duration-200 group-hover:-rotate-12"
6255
- }
6256
- )
6246
+ var createImagePreview = (file) => {
6247
+ return new Promise((resolve) => {
6248
+ if (!file.type.startsWith("image/")) {
6249
+ resolve(null);
6250
+ return;
6257
6251
  }
6258
- )
6259
- );
6260
- EditButton.displayName = "EditButton";
6261
- var ChangeButton = React20.forwardRef(
6252
+ const reader = new FileReader();
6253
+ reader.onload = (e) => {
6254
+ resolve(e.target?.result);
6255
+ };
6256
+ reader.onerror = () => {
6257
+ resolve(null);
6258
+ };
6259
+ reader.readAsDataURL(file);
6260
+ });
6261
+ };
6262
+ var FileUploader = React18.forwardRef(
6262
6263
  ({
6263
- disabled,
6264
- onClick,
6265
- testid = "button-edit",
6266
6264
  className,
6267
- iconSize = 18,
6268
- iconColor,
6269
- variant = "default",
6270
- size = "icon",
6271
- ...props
6272
- }, ref) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6273
- ButtonBase,
6274
- {
6275
- ref,
6276
- variant,
6277
- size,
6278
- onClick,
6279
- disabled,
6280
- testid,
6281
- className: cn(
6282
- "transition-all duration-200 ease-in-out group",
6283
- "hover:scale-105",
6284
- "active:scale-95",
6285
- "disabled:hover:scale-100",
6286
- className
6287
- ),
6288
- ...props,
6289
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6290
- import_react24.ArrowsLeftRightIcon,
6291
- {
6292
- size: iconSize,
6293
- color: iconColor,
6294
- className: "transition-transform duration-200 group-hover:-rotate-180"
6295
- }
6296
- )
6297
- }
6298
- )
6299
- );
6300
- ChangeButton.displayName = "ChangeButton";
6301
- var SaveButton = React20.forwardRef(
6302
- ({
6303
- disabled,
6304
- onClick,
6305
- testid = "button-save",
6306
- className,
6307
- iconSize = 18,
6308
- iconColor,
6309
- variant = "default",
6310
- size = "icon",
6311
- ...props
6312
- }, ref) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6313
- ButtonBase,
6314
- {
6315
- ref,
6316
- variant,
6317
- size,
6318
- onClick,
6319
- disabled,
6320
- testid,
6321
- className: cn(
6322
- "transition-all duration-200 ease-in-out group",
6323
- "hover:scale-105",
6324
- "active:scale-95",
6325
- "disabled:hover:scale-100",
6326
- className
6327
- ),
6328
- ...props,
6329
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6330
- import_react24.FloppyDiskIcon,
6331
- {
6332
- size: iconSize,
6333
- color: iconColor,
6334
- className: "transition-transform duration-200 group-hover:scale-110"
6335
- }
6336
- )
6337
- }
6338
- )
6339
- );
6340
- SaveButton.displayName = "SaveButton";
6341
- var AddButton = React20.forwardRef(
6342
- ({
6343
- disabled,
6344
- onClick,
6345
- testid = "button-add",
6346
- className,
6347
- iconSize = 18,
6348
- iconColor,
6349
- variant = "default",
6350
- size = "icon",
6351
- ...props
6352
- }, ref) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6353
- ButtonBase,
6354
- {
6355
- ref,
6356
- variant,
6357
- size,
6358
- onClick,
6359
- disabled,
6360
- testid,
6361
- className: cn(
6362
- "transition-all duration-200 ease-in-out",
6363
- "hover:scale-105",
6364
- "active:scale-95",
6365
- "disabled:hover:scale-100",
6366
- className
6367
- ),
6368
- ...props,
6369
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6370
- import_react24.PlusIcon,
6371
- {
6372
- size: iconSize,
6373
- color: iconColor,
6374
- className: "transition-transform duration-300"
6375
- }
6376
- )
6377
- }
6378
- )
6379
- );
6380
- AddButton.displayName = "AddButton";
6381
- var CloseButton = React20.forwardRef(
6382
- ({
6383
- disabled,
6384
- onClick,
6385
- testid = "button-close",
6386
- className,
6387
- iconSize = 18,
6388
- iconColor,
6389
- variant = "ghost",
6390
- size = "icon",
6391
- ...props
6392
- }, ref) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6393
- ButtonBase,
6394
- {
6395
- ref,
6396
- variant,
6397
- size,
6398
- onClick,
6399
- disabled,
6400
- testid,
6401
- className: cn(
6402
- "transition-all duration-200 ease-in-out",
6403
- "hover:scale-110 hover:rotate-90 hover:bg-destructive/10",
6404
- "active:scale-95 active:rotate-0",
6405
- "disabled:hover:scale-100 disabled:hover:rotate-0",
6406
- className
6407
- ),
6408
- ...props,
6409
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6410
- import_react24.XIcon,
6411
- {
6412
- size: iconSize,
6413
- color: iconColor,
6414
- className: "transition-transform duration-300"
6415
- }
6416
- )
6417
- }
6418
- )
6419
- );
6420
- CloseButton.displayName = "CloseButton";
6421
- var DeleteButton = React20.forwardRef(
6422
- ({
6423
- disabled,
6424
- onClick,
6425
- testid = "button-delete",
6426
- className,
6427
- iconSize = 18,
6428
- iconColor,
6429
- variant = "destructive",
6430
- size = "icon",
6431
- destructiveTitle,
6432
- destructiveDescription,
6433
- destructiveOnConfirm,
6434
- destructiveOnCancel,
6435
- destructiveTriggerContent,
6265
+ accept,
6266
+ maxSize,
6267
+ maxFiles = 1,
6268
+ disabled = false,
6269
+ value = [],
6270
+ onValueChange,
6271
+ onUpload,
6272
+ showPreview = true,
6273
+ dropzoneText = "Arraste arquivos aqui ou clique para selecionar",
6274
+ dropzoneSubtext,
6275
+ animate = true,
6436
6276
  ...props
6437
6277
  }, ref) => {
6438
- const effectiveDestructiveTitle = destructiveTitle ?? props.title;
6439
- const trigger = /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6440
- ButtonBase,
6441
- {
6442
- ref,
6443
- variant,
6444
- size,
6445
- onClick,
6446
- disabled,
6447
- testid,
6448
- className: cn(
6449
- "transition-all duration-200 ease-in-out group",
6450
- "hover:scale-105",
6451
- "active:scale-95",
6452
- "disabled:hover:scale-100",
6453
- className
6454
- ),
6455
- ...props,
6456
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6457
- import_react24.TrashIcon,
6458
- {
6459
- size: iconSize,
6460
- color: iconColor,
6461
- className: "transition-transform duration-200 group-hover:scale-110"
6278
+ const [isDragging, setIsDragging] = React18.useState(false);
6279
+ const [files, setFiles] = React18.useState(value);
6280
+ const inputRef = React18.useRef(null);
6281
+ const dragCounterRef = React18.useRef(0);
6282
+ const multiple = maxFiles > 1;
6283
+ React18.useEffect(() => {
6284
+ setFiles(value);
6285
+ }, [value]);
6286
+ React18.useEffect(() => {
6287
+ return () => {
6288
+ files.forEach((file) => {
6289
+ if (file.preview) {
6290
+ URL.revokeObjectURL(file.preview);
6462
6291
  }
6463
- )
6292
+ });
6293
+ };
6294
+ }, [files]);
6295
+ const validateFile = (file) => {
6296
+ if (file.size > maxSize) {
6297
+ return `Arquivo muito grande. M\xE1ximo: ${formatFileSize(maxSize)}`;
6464
6298
  }
6465
- );
6466
- if (effectiveDestructiveTitle) {
6467
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6468
- DestructiveDialog,
6469
- {
6470
- title: effectiveDestructiveTitle,
6471
- description: destructiveDescription ?? "Essa a\xE7\xE3o \xE9 irrevers\xEDvel.",
6472
- onConfirm: destructiveOnConfirm ?? (() => {
6473
- }),
6474
- onCancel: destructiveOnCancel,
6475
- triggerContent: destructiveTriggerContent,
6476
- children: trigger
6299
+ if (accept.length > 0) {
6300
+ const fileExtension = `.${getFileExtension(file.name)}`;
6301
+ const fileType = file.type;
6302
+ const isAccepted = accept.some((acceptItem) => {
6303
+ if (acceptItem.startsWith(".")) {
6304
+ return fileExtension.toLowerCase() === acceptItem.toLowerCase();
6305
+ }
6306
+ if (acceptItem.endsWith("/*")) {
6307
+ return fileType.startsWith(acceptItem.replace("/*", ""));
6308
+ }
6309
+ return fileType === acceptItem;
6310
+ });
6311
+ if (!isAccepted) {
6312
+ return `Tipo de arquivo n\xE3o permitido. Aceitos: ${accept.join(", ")}`;
6477
6313
  }
6478
- );
6479
- }
6480
- return trigger;
6481
- }
6482
- );
6483
- DeleteButton.displayName = "DeleteButton";
6484
- var DownloadButton = ({
6485
- disabled,
6486
- onClick,
6487
- testid = "button-download",
6488
- ...props
6489
- }) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6490
- ButtonBase,
6491
- {
6492
- variant: "outline",
6493
- size: "icon",
6494
- onClick,
6495
- disabled,
6496
- testid,
6497
- className: cn(
6498
- "transition-all duration-200 ease-in-out group",
6499
- "hover:scale-105",
6500
- "active:scale-95",
6501
- "disabled:hover:scale-100"
6502
- ),
6503
- ...props,
6504
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6505
- import_react24.DownloadSimpleIcon,
6506
- {
6507
- size: 18,
6508
- className: "transition-transform duration-300 group-hover:translate-y-0.5"
6509
6314
  }
6510
- )
6511
- }
6512
- );
6513
- var UploadButton = ({
6514
- disabled,
6515
- onClick,
6516
- testid = "button-upload",
6517
- ...props
6518
- }) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6519
- ButtonBase,
6520
- {
6521
- variant: "outline",
6522
- size: "icon",
6523
- onClick,
6524
- disabled,
6525
- testid,
6526
- className: cn(
6527
- "transition-all duration-200 ease-in-out group",
6528
- "hover:scale-105",
6529
- "active:scale-95",
6530
- "disabled:hover:scale-100"
6531
- ),
6532
- ...props,
6533
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6534
- import_react24.UploadSimpleIcon,
6535
- {
6536
- size: 18,
6537
- className: "transition-transform duration-300 group-hover:-translate-y-0.5"
6315
+ return null;
6316
+ };
6317
+ const createFileWithPreview = async (file) => {
6318
+ const fileWithPreview = file;
6319
+ fileWithPreview.id = `${file.name}-${Date.now()}-${Math.random()}`;
6320
+ const error = validateFile(file);
6321
+ if (error) {
6322
+ fileWithPreview.error = error;
6538
6323
  }
6539
- )
6540
- }
6541
- );
6542
- var CopyButton = ({
6543
- disabled,
6544
- onClick,
6545
- testid = "button-copy",
6546
- ...props
6547
- }) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6548
- ButtonBase,
6549
- {
6550
- variant: "ghost",
6551
- size: "icon",
6552
- onClick,
6553
- disabled,
6554
- testid,
6555
- className: cn(
6556
- "transition-all duration-200 ease-in-out group",
6557
- "hover:scale-105",
6558
- "active:scale-90",
6559
- "disabled:hover:scale-100"
6560
- ),
6561
- ...props,
6562
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6563
- import_react24.CopyIcon,
6564
- {
6565
- size: 18,
6566
- className: "transition-transform duration-200 group-hover:scale-110"
6324
+ if (file.type.startsWith("image/")) {
6325
+ try {
6326
+ const preview = await createImagePreview(file);
6327
+ if (preview) {
6328
+ fileWithPreview.preview = preview;
6329
+ }
6330
+ } catch (error2) {
6331
+ console.warn("Erro ao criar preview da imagem:", error2);
6332
+ }
6567
6333
  }
6568
- )
6569
- }
6570
- );
6571
- var RefreshButton = ({
6572
- disabled,
6573
- onClick,
6574
- testid = "button-refresh",
6575
- ...props
6576
- }) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6577
- ButtonBase,
6578
- {
6579
- variant: "ghost",
6580
- size: "icon",
6581
- onClick,
6582
- disabled,
6583
- testid,
6584
- className: cn(
6585
- "transition-all duration-200 ease-in-out group",
6586
- "hover:scale-105",
6587
- "active:scale-95",
6588
- "disabled:hover:scale-100"
6589
- ),
6590
- ...props,
6591
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6592
- import_react24.ArrowClockwiseIcon,
6593
- {
6594
- size: 18,
6595
- className: "transition-transform duration-500 group-hover:rotate-180"
6334
+ return fileWithPreview;
6335
+ };
6336
+ const handleFiles = async (newFiles) => {
6337
+ if (disabled) return;
6338
+ const availableSlots = maxFiles - files.length;
6339
+ const filesToAdd = multiple ? newFiles.slice(0, availableSlots) : [newFiles[0]];
6340
+ const filesWithPreview = await Promise.all(
6341
+ filesToAdd.map((file) => createFileWithPreview(file))
6342
+ );
6343
+ const updatedFiles = multiple ? [...files, ...filesWithPreview] : filesWithPreview;
6344
+ setFiles(updatedFiles);
6345
+ onValueChange(updatedFiles);
6346
+ if (onUpload) {
6347
+ const validFiles = filesWithPreview.filter((f) => !f.error);
6348
+ if (validFiles.length > 0) {
6349
+ try {
6350
+ await onUpload(validFiles);
6351
+ } catch (error) {
6352
+ console.error("Erro no upload:", error);
6353
+ }
6354
+ }
6596
6355
  }
6597
- )
6598
- }
6599
- );
6600
- var SearchButton = ({
6601
- disabled,
6602
- onClick,
6603
- testid = "button-search",
6604
- ...props
6605
- }) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6606
- ButtonBase,
6607
- {
6608
- variant: "outline",
6609
- size: "icon",
6610
- onClick,
6611
- disabled,
6612
- testid,
6613
- className: cn(
6614
- "transition-all duration-200 ease-in-out group",
6615
- "hover:scale-105",
6616
- "active:scale-95",
6617
- "disabled:hover:scale-100"
6618
- ),
6619
- ...props,
6620
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6621
- import_react24.MagnifyingGlassIcon,
6622
- {
6623
- size: 18,
6624
- className: "transition-transform duration-200 group-hover:scale-110 group-hover:-rotate-12"
6356
+ };
6357
+ const handleDragEnter = (e) => {
6358
+ e.preventDefault();
6359
+ e.stopPropagation();
6360
+ dragCounterRef.current++;
6361
+ if (e.dataTransfer.items && e.dataTransfer.items.length > 0) {
6362
+ setIsDragging(true);
6625
6363
  }
6626
- )
6627
- }
6628
- );
6629
- var BackButton = ({
6630
- disabled,
6631
- onClick,
6632
- testid = "button-back",
6633
- ...props
6634
- }) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6635
- ButtonBase,
6636
- {
6637
- variant: "ghost",
6638
- size: "icon",
6639
- onClick,
6640
- disabled,
6641
- testid,
6642
- className: cn(
6643
- "transition-all duration-200 ease-in-out group",
6644
- "hover:scale-105",
6645
- "active:scale-95",
6646
- "disabled:hover:scale-100"
6647
- ),
6648
- ...props,
6649
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6650
- import_react24.ArrowLeftIcon,
6651
- {
6652
- size: 18,
6653
- className: "transition-transform duration-300 group-hover:-translate-x-1"
6364
+ };
6365
+ const handleDragLeave = (e) => {
6366
+ e.preventDefault();
6367
+ e.stopPropagation();
6368
+ dragCounterRef.current--;
6369
+ if (dragCounterRef.current === 0) {
6370
+ setIsDragging(false);
6654
6371
  }
6655
- )
6656
- }
6657
- );
6658
- var SettingsButton = ({
6659
- disabled,
6660
- onClick,
6661
- testid = "button-settings",
6662
- ...props
6663
- }) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6664
- ButtonBase,
6665
- {
6666
- variant: "ghost",
6667
- size: "icon",
6668
- onClick,
6669
- disabled,
6670
- testid,
6671
- className: cn(
6672
- "transition-all duration-200 ease-in-out group",
6673
- "hover:scale-105",
6674
- "active:scale-95",
6675
- "disabled:hover:scale-100"
6676
- ),
6677
- ...props,
6678
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6679
- import_react24.GearIcon,
6680
- {
6681
- size: 18,
6682
- className: "transition-transform duration-500 group-hover:rotate-90"
6372
+ };
6373
+ const handleDragOver = (e) => {
6374
+ e.preventDefault();
6375
+ e.stopPropagation();
6376
+ };
6377
+ const handleDrop = (e) => {
6378
+ e.preventDefault();
6379
+ e.stopPropagation();
6380
+ setIsDragging(false);
6381
+ dragCounterRef.current = 0;
6382
+ if (disabled) return;
6383
+ const droppedFiles = Array.from(e.dataTransfer.files);
6384
+ handleFiles(droppedFiles);
6385
+ };
6386
+ const handleInputChange = (e) => {
6387
+ if (e.target.files) {
6388
+ const selectedFiles = Array.from(e.target.files);
6389
+ handleFiles(selectedFiles);
6683
6390
  }
6684
- )
6685
- }
6686
- );
6687
- var NotificationButton = ({
6688
- disabled,
6689
- onClick,
6690
- testid = "button-notification",
6691
- ...props
6692
- }) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6693
- ButtonBase,
6694
- {
6695
- variant: "ghost",
6696
- size: "icon",
6697
- onClick,
6698
- disabled,
6699
- testid,
6700
- className: cn(
6701
- "transition-all duration-200 ease-in-out group",
6702
- "hover:scale-105",
6703
- "active:scale-95",
6704
- "disabled:hover:scale-100"
6705
- ),
6706
- ...props,
6707
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6708
- import_react24.BellIcon,
6709
- {
6710
- size: 18,
6711
- className: "transition-transform duration-300 group-hover:scale-110 group-hover:-rotate-12"
6391
+ };
6392
+ const handleRemoveFile = (fileId) => {
6393
+ const fileToRemove = files.find((f) => f.id === fileId);
6394
+ if (fileToRemove?.preview) {
6395
+ URL.revokeObjectURL(fileToRemove.preview);
6712
6396
  }
6713
- )
6714
- }
6715
- );
6716
- var MoreButton = ({
6717
- disabled,
6718
- onClick,
6719
- testid = "button-more",
6720
- ...props
6721
- }) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6722
- ButtonBase,
6723
- {
6724
- variant: "ghost",
6725
- size: "icon",
6726
- onClick,
6727
- disabled,
6728
- testid,
6729
- className: cn(
6730
- "transition-all duration-200 ease-in-out group",
6731
- "hover:scale-105",
6732
- "active:scale-95",
6733
- "disabled:hover:scale-100"
6734
- ),
6735
- ...props,
6736
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6737
- import_react24.DotsThreeIcon,
6738
- {
6739
- size: 18,
6740
- className: "transition-transform duration-200 group-hover:scale-110"
6397
+ const updatedFiles = files.filter((f) => f.id !== fileId);
6398
+ setFiles(updatedFiles);
6399
+ onValueChange(updatedFiles);
6400
+ };
6401
+ const handleClick = () => {
6402
+ if (!disabled) {
6403
+ inputRef.current?.click();
6741
6404
  }
6742
- )
6743
- }
6744
- );
6745
- var CheckButton = ({
6746
- disabled,
6747
- onClick,
6748
- testid = "button-check",
6749
- ...props
6750
- }) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6751
- ButtonBase,
6752
- {
6753
- variant: "default",
6754
- size: "icon",
6755
- onClick,
6756
- disabled,
6757
- testid,
6758
- className: cn(
6759
- "transition-all duration-200 ease-in-out group",
6760
- "hover:scale-110",
6761
- "active:scale-95",
6762
- "disabled:hover:scale-100"
6763
- ),
6764
- ...props,
6765
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6766
- import_react24.CheckIcon,
6405
+ };
6406
+ const acceptString = accept.join(",");
6407
+ const defaultSubtext = dropzoneSubtext || `Formatos: ${accept.join(", ")}. M\xE1ximo: ${formatFileSize(maxSize)}`;
6408
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { ref, className: cn("w-full", className), ...props, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
6409
+ import_framer_motion10.motion.div,
6767
6410
  {
6768
- size: 18,
6769
- className: "transition-transform duration-200 group-hover:scale-110"
6411
+ className: cn(
6412
+ "relative flex cursor-pointer flex-col items-center justify-center rounded-xl border-2 border-dashed p-10 transition-all duration-300 dark:shadow-black/20",
6413
+ isDragging && "border-primary bg-primary/10 scale-[1.02]",
6414
+ !isDragging && "border-border hover:border-primary/60 hover:bg-muted/50",
6415
+ disabled && "cursor-not-allowed opacity-50 hover:scale-100"
6416
+ ),
6417
+ onDragEnter: handleDragEnter,
6418
+ onDragOver: handleDragOver,
6419
+ onDragLeave: handleDragLeave,
6420
+ onDrop: handleDrop,
6421
+ onClick: handleClick,
6422
+ whileHover: !disabled ? { scale: 1.01 } : void 0,
6423
+ whileTap: !disabled ? { scale: 0.99 } : void 0,
6424
+ animate: isDragging ? {
6425
+ borderColor: `hsl(var(--primary))`,
6426
+ backgroundColor: `hsl(var(--primary) / 0.1)`,
6427
+ scale: 1.02
6428
+ } : {
6429
+ borderColor: `hsl(var(--border))`,
6430
+ backgroundColor: `hsl(var(--background))`,
6431
+ scale: 1
6432
+ },
6433
+ transition: {
6434
+ type: "spring",
6435
+ stiffness: 300,
6436
+ damping: 25,
6437
+ duration: 0.3
6438
+ },
6439
+ children: [
6440
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6441
+ "input",
6442
+ {
6443
+ ref: inputRef,
6444
+ type: "file",
6445
+ className: "hidden",
6446
+ accept: acceptString,
6447
+ multiple,
6448
+ disabled,
6449
+ onChange: handleInputChange
6450
+ }
6451
+ ),
6452
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6453
+ import_framer_motion10.motion.div,
6454
+ {
6455
+ animate: isDragging ? { scale: 1.2, rotate: 10 } : { scale: 1, rotate: 0 },
6456
+ transition: {
6457
+ type: "spring",
6458
+ stiffness: 300,
6459
+ damping: 20,
6460
+ duration: 0.3
6461
+ },
6462
+ children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6463
+ import_framer_motion10.motion.div,
6464
+ {
6465
+ className: cn(
6466
+ "mb-4 h-16 w-16 text-muted-foreground transition-colors duration-300 drop-shadow-lg flex items-center justify-center",
6467
+ isDragging && "text-primary"
6468
+ ),
6469
+ initial: false,
6470
+ animate: {
6471
+ color: isDragging ? `hsl(var(--primary))` : `hsl(var(--muted-foreground))`
6472
+ },
6473
+ transition: { duration: 0.3 },
6474
+ children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react23.CloudArrowUpIcon, { size: 64 })
6475
+ }
6476
+ )
6477
+ }
6478
+ ),
6479
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6480
+ import_framer_motion10.motion.p,
6481
+ {
6482
+ className: "mb-2 text-base font-semibold text-foreground",
6483
+ initial: animate ? { opacity: 0, y: -10 } : false,
6484
+ animate: { opacity: 1, y: 0 },
6485
+ transition: { delay: 0.1 },
6486
+ children: dropzoneText
6487
+ }
6488
+ ),
6489
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6490
+ import_framer_motion10.motion.p,
6491
+ {
6492
+ className: "text-sm text-muted-foreground",
6493
+ initial: animate ? { opacity: 0, y: -10 } : false,
6494
+ animate: { opacity: 1, y: 0 },
6495
+ transition: { delay: 0.2 },
6496
+ children: defaultSubtext
6497
+ }
6498
+ ),
6499
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_framer_motion10.AnimatePresence, { children: files.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
6500
+ import_framer_motion10.motion.div,
6501
+ {
6502
+ initial: { opacity: 0, scale: 0.8, y: 10 },
6503
+ animate: {
6504
+ opacity: 1,
6505
+ scale: 1,
6506
+ y: 0,
6507
+ backgroundColor: `hsl(var(--primary) / 0.1)`,
6508
+ borderColor: `hsl(var(--primary) / 0.2)`
6509
+ },
6510
+ exit: { opacity: 0, scale: 0.8, y: 10 },
6511
+ className: cn(
6512
+ "mt-4 flex items-center gap-2 rounded-full border px-4 py-2 backdrop-blur-sm bg-primary/20 border-primary/30 shadow-lg"
6513
+ ),
6514
+ transition: { duration: 0.3 },
6515
+ children: [
6516
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "h-4 w-4 text-primary flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react23.CheckIcon, { size: 16, className: "text-emerald-500" }) }),
6517
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
6518
+ import_framer_motion10.motion.span,
6519
+ {
6520
+ className: "text-sm font-semibold text-primary",
6521
+ animate: { color: `hsl(var(--primary))` },
6522
+ transition: { duration: 0.3 },
6523
+ children: [
6524
+ files.length,
6525
+ " ",
6526
+ files.length === 1 ? "arquivo selecionado" : "arquivos selecionados"
6527
+ ]
6528
+ }
6529
+ )
6530
+ ]
6531
+ }
6532
+ ) }),
6533
+ showPreview && files.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6534
+ import_framer_motion10.motion.div,
6535
+ {
6536
+ className: "mt-6 w-full",
6537
+ initial: animate ? { opacity: 0, y: 10 } : false,
6538
+ animate: { opacity: 1, y: 0 },
6539
+ transition: { delay: 0.3 },
6540
+ children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { children: [
6541
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("h4", { className: "mb-3 text-sm font-medium text-muted-foreground", children: [
6542
+ "Arquivos selecionados (",
6543
+ files.length,
6544
+ "/",
6545
+ maxFiles,
6546
+ ")"
6547
+ ] }),
6548
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "space-y-2 overflow-y-auto max-h-44", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_framer_motion10.AnimatePresence, { mode: "popLayout", children: files.map((file, index) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
6549
+ import_framer_motion10.motion.div,
6550
+ {
6551
+ layout: true,
6552
+ initial: animate ? { opacity: 0, x: -20 } : false,
6553
+ animate: { opacity: 1, x: 0 },
6554
+ exit: {
6555
+ opacity: 0,
6556
+ x: -20,
6557
+ transition: { duration: 0.2 }
6558
+ },
6559
+ transition: {
6560
+ delay: animate ? index * 0.05 : 0,
6561
+ layout: { duration: 0.2 }
6562
+ },
6563
+ className: cn(
6564
+ "flex items-center gap-3 rounded-md border p-3 transition-all duration-300",
6565
+ file.error ? "border-destructive/50 bg-destructive/5" : "border-border bg-background/80 hover:bg-muted/50 hover:shadow-md hover:shadow-primary/10 hover:border-primary/30"
6566
+ ),
6567
+ children: [
6568
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "flex h-12 w-12 shrink-0 items-center justify-center rounded-md bg-muted overflow-hidden", children: file.preview ? (
6569
+ // Preview de imagem
6570
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6571
+ "img",
6572
+ {
6573
+ src: file.preview,
6574
+ alt: file.name,
6575
+ className: "h-full w-full object-cover rounded-md"
6576
+ }
6577
+ )
6578
+ ) : (
6579
+ // Ícone baseado no tipo de arquivo
6580
+ getFileTypeIcon(file)
6581
+ ) }),
6582
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "min-w-0 flex-1", children: [
6583
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6584
+ "p",
6585
+ {
6586
+ className: "truncate text-sm font-medium text-foreground",
6587
+ title: `${file.name} (${file.type || "Tipo desconhecido"})`,
6588
+ children: file.name
6589
+ }
6590
+ ),
6591
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
6592
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { children: formatFileSize(file.size) }),
6593
+ file.type && /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
6594
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { children: "\u2022" }),
6595
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "uppercase", children: getFileExtension(file.name) })
6596
+ ] })
6597
+ ] }),
6598
+ file.error && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6599
+ import_framer_motion10.motion.p,
6600
+ {
6601
+ className: "mt-1 text-xs text-destructive",
6602
+ initial: { opacity: 0, y: -5 },
6603
+ animate: { opacity: 1, y: 0 },
6604
+ children: file.error
6605
+ }
6606
+ )
6607
+ ] }),
6608
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6609
+ ButtonBase,
6610
+ {
6611
+ variant: "destructive",
6612
+ size: "icon",
6613
+ onClick: (e) => {
6614
+ e?.stopPropagation();
6615
+ handleRemoveFile(file.id);
6616
+ },
6617
+ className: "",
6618
+ children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react23.XIcon, { size: 12 })
6619
+ }
6620
+ )
6621
+ ]
6622
+ },
6623
+ file.id
6624
+ )) }) })
6625
+ ] })
6626
+ }
6627
+ )
6628
+ ]
6770
6629
  }
6771
- )
6630
+ ) });
6772
6631
  }
6773
6632
  );
6774
- var FilterButton = ({
6775
- disabled,
6776
- onClick,
6777
- testid = "button-filter",
6778
- active = false,
6779
- className,
6780
- iconSize = 18,
6781
- iconColor,
6782
- variant,
6783
- size = "icon",
6784
- ...props
6785
- }) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6786
- ButtonBase,
6633
+ FileUploader.displayName = "FileUploader";
6634
+
6635
+ // src/components/ui/feedback/AlertDialogBase.tsx
6636
+ var React19 = __toESM(require("react"));
6637
+ var AlertDialogPrimitive = __toESM(require("@radix-ui/react-alert-dialog"));
6638
+ var import_jsx_runtime36 = require("react/jsx-runtime");
6639
+ var AlertDialogBase = AlertDialogPrimitive.Root;
6640
+ var AlertDialogTriggerBase = AlertDialogPrimitive.Trigger;
6641
+ var AlertDialogPortalBase = AlertDialogPrimitive.Portal;
6642
+ var AlertDialogOverlayBase = React19.forwardRef(({ className, testid = "alertdialog-overlay", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6643
+ AlertDialogPrimitive.Overlay,
6787
6644
  {
6788
- variant: variant || (active ? "default" : "outline"),
6789
- size,
6790
- onClick,
6791
- disabled,
6792
- testid,
6793
6645
  className: cn(
6794
- "transition-all duration-200 ease-in-out",
6795
- "hover:scale-105",
6796
- "active:scale-95",
6797
- "disabled:hover:scale-100",
6646
+ "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
6798
6647
  className
6799
6648
  ),
6649
+ "data-testid": testid,
6800
6650
  ...props,
6801
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6802
- import_react24.FunnelIcon,
6803
- {
6804
- size: iconSize,
6805
- color: iconColor,
6806
- weight: active ? "fill" : "regular",
6807
- className: "transition-all duration-200"
6808
- }
6809
- )
6651
+ ref
6810
6652
  }
6811
- );
6812
- var LikeButton = ({
6813
- disabled,
6814
- onClick,
6815
- testid = "button-like",
6816
- isLiked = false,
6817
- className,
6818
- iconSize = 18,
6819
- iconColor,
6820
- variant = "ghost",
6821
- size = "icon",
6653
+ ));
6654
+ AlertDialogOverlayBase.displayName = AlertDialogPrimitive.Overlay.displayName;
6655
+ var AlertDialogContentBase = React19.forwardRef(({ className, testid = "alertdialog-content", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(AlertDialogPortalBase, { children: [
6656
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(AlertDialogOverlayBase, {}),
6657
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6658
+ AlertDialogPrimitive.Content,
6659
+ {
6660
+ ref,
6661
+ className: cn(
6662
+ "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
6663
+ className
6664
+ ),
6665
+ "data-testid": testid,
6666
+ ...props
6667
+ }
6668
+ )
6669
+ ] }));
6670
+ AlertDialogContentBase.displayName = AlertDialogPrimitive.Content.displayName;
6671
+ var AlertDialogHeaderBase = ({
6672
+ className,
6822
6673
  ...props
6823
- }) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6824
- ButtonBase,
6674
+ }) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6675
+ "div",
6825
6676
  {
6826
- variant,
6827
- size,
6828
- onClick,
6829
- disabled,
6830
- testid,
6831
6677
  className: cn(
6832
- "transition-all duration-200 ease-in-out group",
6833
- "hover:scale-110",
6834
- "active:scale-95",
6835
- "disabled:hover:scale-100",
6836
- !iconColor && (isLiked ? "text-red-500 dark:text-red-400 hover:text-red-600 dark:hover:text-red-300" : "hover:text-red-500 dark:hover:text-red-400"),
6678
+ "flex flex-col space-y-2 text-center sm:text-left",
6837
6679
  className
6838
6680
  ),
6839
- ...props,
6840
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6841
- import_react24.HeartIcon,
6842
- {
6843
- size: iconSize,
6844
- color: iconColor,
6845
- weight: isLiked ? "fill" : "regular",
6846
- className: "transition-all duration-300 group-hover:scale-110"
6847
- }
6848
- )
6681
+ ...props
6849
6682
  }
6850
6683
  );
6851
- var FavoriteButton = ({
6852
- disabled,
6853
- onClick,
6854
- testid = "button-favorite",
6855
- isFavorite = false,
6684
+ AlertDialogHeaderBase.displayName = "AlertDialogHeaderBase";
6685
+ var AlertDialogFooterBase = ({
6856
6686
  className,
6857
- iconSize = 18,
6858
- iconColor,
6859
- variant = "ghost",
6860
- size = "icon",
6861
6687
  ...props
6862
- }) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6863
- ButtonBase,
6688
+ }) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6689
+ "div",
6864
6690
  {
6865
- variant,
6866
- size,
6867
- onClick,
6868
- disabled,
6869
- testid,
6870
6691
  className: cn(
6871
- "transition-all duration-200 ease-in-out group",
6872
- "hover:scale-110",
6873
- "active:scale-95",
6874
- "disabled:hover:scale-100",
6875
- !iconColor && (isFavorite ? "text-yellow-500 dark:text-yellow-400 hover:text-yellow-600 dark:hover:text-yellow-300" : "hover:text-yellow-500 dark:hover:text-yellow-400"),
6692
+ "flex flex-col-reverse sm:flex-row sm:justify-end",
6876
6693
  className
6877
6694
  ),
6878
- ...props,
6879
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6880
- import_react24.StarIcon,
6881
- {
6882
- size: iconSize,
6883
- color: iconColor,
6884
- weight: isFavorite ? "fill" : "regular",
6885
- className: "transition-all duration-300 group-hover:rotate-12"
6886
- }
6887
- )
6695
+ ...props
6888
6696
  }
6889
6697
  );
6890
- var VisibilityButton = ({
6891
- disabled,
6892
- onClick,
6893
- testid = "button-visibility",
6894
- isVisible = true,
6895
- className,
6896
- iconSize = 18,
6897
- iconColor,
6898
- variant = "ghost",
6899
- size = "icon",
6900
- ...props
6901
- }) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6902
- ButtonBase,
6698
+ AlertDialogFooterBase.displayName = "AlertDialogFooterBase";
6699
+ var AlertDialogTitleBase = React19.forwardRef(({ className, testid = "alertdialog-title", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6700
+ AlertDialogPrimitive.Title,
6903
6701
  {
6904
- variant,
6905
- size,
6906
- onClick,
6907
- disabled,
6908
- testid,
6909
- className: cn(
6910
- "transition-all duration-200 ease-in-out",
6911
- "hover:scale-105",
6912
- "active:scale-95",
6913
- "disabled:hover:scale-100",
6914
- className
6915
- ),
6916
- ...props,
6917
- children: isVisible ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6918
- import_react24.EyeIcon,
6919
- {
6920
- size: iconSize,
6921
- color: iconColor,
6922
- className: "transition-opacity duration-200"
6923
- }
6924
- ) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6925
- import_react24.EyeSlashIcon,
6702
+ ref,
6703
+ className: cn("text-lg font-semibold", className),
6704
+ "data-testid": testid,
6705
+ ...props
6706
+ }
6707
+ ));
6708
+ AlertDialogTitleBase.displayName = AlertDialogPrimitive.Title.displayName;
6709
+ var AlertDialogDescriptionBase = React19.forwardRef(({ className, testid = "alertdialog-description", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6710
+ AlertDialogPrimitive.Description,
6711
+ {
6712
+ ref,
6713
+ className: cn("text-sm text-muted-foreground", className),
6714
+ "data-testid": testid,
6715
+ ...props
6716
+ }
6717
+ ));
6718
+ AlertDialogDescriptionBase.displayName = AlertDialogPrimitive.Description.displayName;
6719
+ var AlertDialogActionBase = React19.forwardRef(({ className, testid = "alertdialog-action", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6720
+ AlertDialogPrimitive.Action,
6721
+ {
6722
+ ref,
6723
+ className: cn(buttonVariantsBase(), className),
6724
+ "data-testid": testid,
6725
+ ...props
6726
+ }
6727
+ ));
6728
+ AlertDialogActionBase.displayName = AlertDialogPrimitive.Action.displayName;
6729
+ var AlertDialogCancelBase = React19.forwardRef(({ className, testid = "alertdialog-cancel", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6730
+ AlertDialogPrimitive.Cancel,
6731
+ {
6732
+ ref,
6733
+ className: cn(buttonVariantsBase({ variant: "outline" }), className),
6734
+ "data-testid": testid,
6735
+ ...props
6736
+ }
6737
+ ));
6738
+ AlertDialogCancelBase.displayName = AlertDialogPrimitive.Cancel.displayName;
6739
+
6740
+ // src/components/ui/feedback/DestructiveDialog.tsx
6741
+ var React20 = __toESM(require("react"));
6742
+ var import_react24 = require("@phosphor-icons/react");
6743
+ var import_jsx_runtime37 = require("react/jsx-runtime");
6744
+ var DestructiveDialog = ({
6745
+ title,
6746
+ description,
6747
+ onConfirm,
6748
+ onCancel,
6749
+ children,
6750
+ triggerContent
6751
+ }) => {
6752
+ const triggerEl = React20.isValidElement(children) ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AlertDialogTriggerBase, { asChild: true, children }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AlertDialogTriggerBase, { children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ButtonBase, { variant: "destructive", children: triggerContent ?? "Excluir" }) });
6753
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(AlertDialogBase, { children: [
6754
+ triggerEl,
6755
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
6756
+ AlertDialogContentBase,
6926
6757
  {
6927
- size: iconSize,
6928
- color: iconColor,
6929
- className: "transition-opacity duration-200"
6758
+ className: cn("border border-destructive bg-background"),
6759
+ children: [
6760
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-start gap-4", children: [
6761
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "flex items-center justify-center w-10 h-10 rounded-full ring-1 ring-destructive/30", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_react24.XCircleIcon, { className: "w-6 h-6 text-destructive" }) }),
6762
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex-1", children: [
6763
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AlertDialogTitleBase, { className: "text-lg sm:text-xl font-semibold text-destructive", children: title }),
6764
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AlertDialogDescriptionBase, { className: "mt-2 text-sm text-muted-foreground", children: description })
6765
+ ] })
6766
+ ] }),
6767
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(AlertDialogFooterBase, { className: "mt-2 flex justify-end gap-3", children: [
6768
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6769
+ AlertDialogCancelBase,
6770
+ {
6771
+ onClick: onCancel,
6772
+ className: cn(
6773
+ buttonVariantsBase({ variant: "outline", size: "default" }),
6774
+ "hover:bg-foreground/5 hover:text-primary hover:opacity-90 hover:shadow-none"
6775
+ ),
6776
+ children: "Cancelar"
6777
+ }
6778
+ ),
6779
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6780
+ AlertDialogActionBase,
6781
+ {
6782
+ onClick: onConfirm,
6783
+ className: cn(
6784
+ buttonVariantsBase({ variant: "destructive", size: "default" })
6785
+ ),
6786
+ children: "Confirmar"
6787
+ }
6788
+ )
6789
+ ] })
6790
+ ]
6930
6791
  }
6931
6792
  )
6793
+ ] });
6794
+ };
6795
+
6796
+ // src/components/ui/feedback/LoadingBase.tsx
6797
+ var React21 = __toESM(require("react"));
6798
+ var import_class_variance_authority3 = require("class-variance-authority");
6799
+ var import_jsx_runtime38 = require("react/jsx-runtime");
6800
+ var loadingVariants = (0, import_class_variance_authority3.cva)(
6801
+ "rounded-full border-2 animate-spin border-muted border-t-primary",
6802
+ {
6803
+ variants: {
6804
+ size: {
6805
+ sm: "h-4 w-4",
6806
+ md: "h-6 w-6",
6807
+ lg: "h-8 w-8",
6808
+ xl: "h-12 w-12 border-[3px]"
6809
+ }
6810
+ },
6811
+ defaultVariants: {
6812
+ size: "md"
6813
+ }
6932
6814
  }
6933
6815
  );
6934
- var ViewButton = (props) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(VisibilityButton, { isVisible: true, testid: "button-view", ...props });
6935
- var HideButton = (props) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(VisibilityButton, { isVisible: false, testid: "button-hide", ...props });
6936
- var LockButton = ({
6937
- disabled,
6938
- onClick,
6939
- testid = "button-lock",
6940
- isLocked = true,
6941
- className,
6942
- iconSize = 18,
6943
- iconColor,
6944
- variant = "ghost",
6945
- size = "icon",
6946
- ...props
6947
- }) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6948
- ButtonBase,
6816
+ var dotsVariants = (0, import_class_variance_authority3.cva)(
6817
+ "flex items-center justify-center",
6949
6818
  {
6950
- variant,
6951
- size,
6952
- onClick,
6953
- disabled,
6954
- testid,
6955
- className: cn(
6956
- "transition-all duration-200 ease-in-out group",
6957
- "hover:scale-105",
6958
- "active:scale-95",
6959
- "disabled:hover:scale-100",
6960
- !iconColor && (isLocked ? "text-red-500 dark:text-red-400 hover:text-red-600 dark:hover:text-red-300" : "text-emerald-500 dark:text-emerald-400 hover:text-emerald-600 dark:hover:text-emerald-300"),
6961
- className
6962
- ),
6963
- ...props,
6964
- children: isLocked ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6965
- import_react24.LockIcon,
6966
- {
6967
- size: iconSize,
6968
- color: iconColor,
6969
- className: "transition-all duration-200 group-hover:scale-110"
6970
- }
6971
- ) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6972
- import_react24.LockOpenIcon,
6973
- {
6974
- size: iconSize,
6975
- color: iconColor,
6976
- className: "transition-all duration-200 group-hover:scale-110"
6819
+ variants: {
6820
+ size: {
6821
+ sm: "gap-1",
6822
+ md: "gap-1.5",
6823
+ lg: "gap-2",
6824
+ xl: "gap-2.5"
6977
6825
  }
6978
- )
6826
+ },
6827
+ defaultVariants: {
6828
+ size: "md"
6829
+ }
6979
6830
  }
6980
6831
  );
6981
- var UnlockButton = (props) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(LockButton, { isLocked: false, testid: "button-unlock", ...props });
6982
-
6983
- // src/components/ui/data/FileUploader.tsx
6984
- var import_jsx_runtime38 = require("react/jsx-runtime");
6985
- var formatFileSize = (bytes) => {
6986
- if (bytes === 0) return "0 Bytes";
6987
- const k = 1024;
6988
- const sizes = ["Bytes", "KB", "MB", "GB"];
6989
- const i = Math.floor(Math.log(bytes) / Math.log(k));
6990
- return Math.round(bytes / Math.pow(k, i) * 100) / 100 + " " + sizes[i];
6991
- };
6992
- var getFileExtension = (filename) => {
6993
- return filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2);
6994
- };
6995
- var getFileTypeIcon = (file) => {
6996
- const extension = getFileExtension(file.name).toLowerCase();
6997
- const mimeType = file.type.toLowerCase();
6998
- if (extension === "pdf" || mimeType === "application/pdf") {
6999
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react25.FilePdfIcon, { size: 20, className: "text-red-500" });
7000
- }
7001
- if (["doc", "docx"].includes(extension) || mimeType.includes("word")) {
7002
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react25.FileDocIcon, { size: 20, className: "text-blue-500" });
7003
- }
7004
- if (["xls", "xlsx"].includes(extension) || mimeType.includes("sheet")) {
7005
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react25.FileXlsIcon, { size: 20, className: "text-green-500" });
7006
- }
7007
- if (["ppt", "pptx"].includes(extension) || mimeType.includes("presentation")) {
7008
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react25.FilePptIcon, { size: 20, className: "text-orange-500" });
7009
- }
7010
- if (extension === "csv" || mimeType === "text/csv") {
7011
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react25.FileCsvIcon, { size: 20, className: "text-green-600" });
7012
- }
7013
- if (["txt", "md", "json", "xml", "js", "ts", "html", "css"].includes(
7014
- extension
7015
- ) || mimeType.includes("text")) {
7016
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react25.FileTextIcon, { size: 20, className: "text-gray-500" });
7017
- }
7018
- if (mimeType.startsWith("image/")) {
7019
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react25.FileImageIcon, { size: 20, className: "text-purple-500" });
7020
- }
7021
- if (mimeType.startsWith("video/")) {
7022
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react25.FileVideoIcon, { size: 20, className: "text-pink-500" });
7023
- }
7024
- if (mimeType.startsWith("audio/")) {
7025
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react25.FileAudioIcon, { size: 20, className: "text-indigo-500" });
7026
- }
7027
- if (["zip", "rar", "7z", "tar", "gz"].includes(extension)) {
7028
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react25.FileZipIcon, { size: 20, className: "text-yellow-600" });
7029
- }
7030
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react25.FileIcon, { size: 20, className: "text-muted-foreground" });
7031
- };
7032
- var createImagePreview = (file) => {
7033
- return new Promise((resolve) => {
7034
- if (!file.type.startsWith("image/")) {
7035
- resolve(null);
7036
- return;
6832
+ var dotVariants = (0, import_class_variance_authority3.cva)(
6833
+ "rounded-full bg-gradient-to-r from-primary to-primary/70 shadow-sm",
6834
+ {
6835
+ variants: {
6836
+ size: {
6837
+ sm: "h-1.5 w-2",
6838
+ md: "h-2.5 w-2.5",
6839
+ lg: "h-2.5 w-3",
6840
+ xl: "h-3.5 w-4"
6841
+ }
6842
+ },
6843
+ defaultVariants: {
6844
+ size: "md"
7037
6845
  }
7038
- const reader = new FileReader();
7039
- reader.onload = (e) => {
7040
- resolve(e.target?.result);
7041
- };
7042
- reader.onerror = () => {
7043
- resolve(null);
7044
- };
7045
- reader.readAsDataURL(file);
7046
- });
7047
- };
7048
- var FileUploader = React21.forwardRef(
7049
- ({
7050
- className,
7051
- accept,
7052
- maxSize,
7053
- maxFiles = 1,
7054
- disabled = false,
7055
- value = [],
7056
- onValueChange,
7057
- onUpload,
7058
- showPreview = true,
7059
- dropzoneText = "Arraste arquivos aqui ou clique para selecionar",
7060
- dropzoneSubtext,
7061
- animate = true,
7062
- ...props
7063
- }, ref) => {
7064
- const [isDragging, setIsDragging] = React21.useState(false);
7065
- const [files, setFiles] = React21.useState(value);
7066
- const inputRef = React21.useRef(null);
7067
- const dragCounterRef = React21.useRef(0);
7068
- const multiple = maxFiles > 1;
7069
- React21.useEffect(() => {
7070
- setFiles(value);
7071
- }, [value]);
6846
+ }
6847
+ );
6848
+ var LoadingBase = React21.forwardRef(
6849
+ ({ className, size, message, overlay = false, variant = "spinner", ...props }, ref) => {
7072
6850
  React21.useEffect(() => {
7073
- return () => {
7074
- files.forEach((file) => {
7075
- if (file.preview) {
7076
- URL.revokeObjectURL(file.preview);
7077
- }
7078
- });
7079
- };
7080
- }, [files]);
7081
- const validateFile = (file) => {
7082
- if (file.size > maxSize) {
7083
- return `Arquivo muito grande. M\xE1ximo: ${formatFileSize(maxSize)}`;
7084
- }
7085
- if (accept.length > 0) {
7086
- const fileExtension = `.${getFileExtension(file.name)}`;
7087
- const fileType = file.type;
7088
- const isAccepted = accept.some((acceptItem) => {
7089
- if (acceptItem.startsWith(".")) {
7090
- return fileExtension.toLowerCase() === acceptItem.toLowerCase();
6851
+ const style = document.createElement("style");
6852
+ style.textContent = `
6853
+ @keyframes dotBounce {
6854
+ 0%, 80%, 100% {
6855
+ transform: translateY(0);
6856
+ opacity: 0.8;
7091
6857
  }
7092
- if (acceptItem.endsWith("/*")) {
7093
- return fileType.startsWith(acceptItem.replace("/*", ""));
6858
+ 40% {
6859
+ transform: translateY(-8px);
6860
+ opacity: 1;
7094
6861
  }
7095
- return fileType === acceptItem;
7096
- });
7097
- if (!isAccepted) {
7098
- return `Tipo de arquivo n\xE3o permitido. Aceitos: ${accept.join(", ")}`;
7099
6862
  }
7100
- }
7101
- return null;
7102
- };
7103
- const createFileWithPreview = async (file) => {
7104
- const fileWithPreview = file;
7105
- fileWithPreview.id = `${file.name}-${Date.now()}-${Math.random()}`;
7106
- const error = validateFile(file);
7107
- if (error) {
7108
- fileWithPreview.error = error;
7109
- }
7110
- if (file.type.startsWith("image/")) {
7111
- try {
7112
- const preview = await createImagePreview(file);
7113
- if (preview) {
7114
- fileWithPreview.preview = preview;
7115
- }
7116
- } catch (error2) {
7117
- console.warn("Erro ao criar preview da imagem:", error2);
6863
+ `;
6864
+ document.head.appendChild(style);
6865
+ return () => {
6866
+ if (document.head.contains(style)) {
6867
+ document.head.removeChild(style);
7118
6868
  }
6869
+ };
6870
+ }, []);
6871
+ const renderSpinner = () => {
6872
+ if (variant === "dots") {
6873
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: cn(dotsVariants({ size })), "aria-hidden": "true", children: [
6874
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
6875
+ "div",
6876
+ {
6877
+ className: cn(dotVariants({ size })),
6878
+ style: {
6879
+ animation: "dotBounce 1.4s ease-in-out infinite",
6880
+ animationDelay: "0ms",
6881
+ transform: "translateY(0px)"
6882
+ }
6883
+ }
6884
+ ),
6885
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
6886
+ "div",
6887
+ {
6888
+ className: cn(dotVariants({ size })),
6889
+ style: {
6890
+ animation: "dotBounce 1.4s ease-in-out infinite",
6891
+ animationDelay: "0.16s",
6892
+ transform: "translateY(0px)"
6893
+ }
6894
+ }
6895
+ ),
6896
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
6897
+ "div",
6898
+ {
6899
+ className: cn(dotVariants({ size })),
6900
+ style: {
6901
+ animation: "dotBounce 1.4s ease-in-out infinite",
6902
+ animationDelay: "0.32s",
6903
+ transform: "translateY(0px)"
6904
+ }
6905
+ }
6906
+ )
6907
+ ] });
7119
6908
  }
7120
- return fileWithPreview;
7121
- };
7122
- const handleFiles = async (newFiles) => {
7123
- if (disabled) return;
7124
- const availableSlots = maxFiles - files.length;
7125
- const filesToAdd = multiple ? newFiles.slice(0, availableSlots) : [newFiles[0]];
7126
- const filesWithPreview = await Promise.all(
7127
- filesToAdd.map((file) => createFileWithPreview(file))
7128
- );
7129
- const updatedFiles = multiple ? [...files, ...filesWithPreview] : filesWithPreview;
7130
- setFiles(updatedFiles);
7131
- onValueChange(updatedFiles);
7132
- if (onUpload) {
7133
- const validFiles = filesWithPreview.filter((f) => !f.error);
7134
- if (validFiles.length > 0) {
7135
- try {
7136
- await onUpload(validFiles);
7137
- } catch (error) {
7138
- console.error("Erro no upload:", error);
7139
- }
6909
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
6910
+ "div",
6911
+ {
6912
+ className: cn(loadingVariants({ size })),
6913
+ style: {
6914
+ animation: "spin 1s linear infinite"
6915
+ },
6916
+ "aria-hidden": "true"
7140
6917
  }
7141
- }
6918
+ );
7142
6919
  };
7143
- const handleDragEnter = (e) => {
7144
- e.preventDefault();
7145
- e.stopPropagation();
7146
- dragCounterRef.current++;
7147
- if (e.dataTransfer.items && e.dataTransfer.items.length > 0) {
7148
- setIsDragging(true);
6920
+ const loadingContent = /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
6921
+ renderSpinner(),
6922
+ message && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("p", { className: "text-sm font-medium text-muted-foreground animate-pulse", children: message })
6923
+ ] });
6924
+ if (overlay) {
6925
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
6926
+ "div",
6927
+ {
6928
+ ref,
6929
+ className: cn(
6930
+ "fixed inset-0 z-50 flex items-center justify-center",
6931
+ "bg-background/80 dark:bg-background/60",
6932
+ "backdrop-blur-md backdrop-saturate-150",
6933
+ "transition-all duration-300 ease-in-out",
6934
+ "animate-in fade-in-0",
6935
+ className
6936
+ ),
6937
+ role: "status",
6938
+ "aria-label": message || "Carregando",
6939
+ ...props,
6940
+ children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: cn(
6941
+ "relative p-8 rounded-2xl",
6942
+ "bg-card/90 dark:bg-card/95",
6943
+ "border border-border/50",
6944
+ "shadow-2xl shadow-black/10 dark:shadow-black/30",
6945
+ "backdrop-blur-xl backdrop-saturate-150",
6946
+ "animate-in zoom-in-95 fade-in-0 duration-300",
6947
+ "text-center space-y-4"
6948
+ ), children: loadingContent })
6949
+ }
6950
+ );
6951
+ }
6952
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
6953
+ "div",
6954
+ {
6955
+ ref,
6956
+ className: cn("flex items-center justify-center", className),
6957
+ role: "status",
6958
+ "aria-label": message || "Carregando",
6959
+ ...props,
6960
+ children: loadingContent
7149
6961
  }
7150
- };
7151
- const handleDragLeave = (e) => {
7152
- e.preventDefault();
7153
- e.stopPropagation();
7154
- dragCounterRef.current--;
7155
- if (dragCounterRef.current === 0) {
7156
- setIsDragging(false);
7157
- }
7158
- };
7159
- const handleDragOver = (e) => {
7160
- e.preventDefault();
7161
- e.stopPropagation();
7162
- };
7163
- const handleDrop = (e) => {
7164
- e.preventDefault();
7165
- e.stopPropagation();
7166
- setIsDragging(false);
7167
- dragCounterRef.current = 0;
7168
- if (disabled) return;
7169
- const droppedFiles = Array.from(e.dataTransfer.files);
7170
- handleFiles(droppedFiles);
7171
- };
7172
- const handleInputChange = (e) => {
7173
- if (e.target.files) {
7174
- const selectedFiles = Array.from(e.target.files);
7175
- handleFiles(selectedFiles);
7176
- }
7177
- };
7178
- const handleRemoveFile = (fileId) => {
7179
- const fileToRemove = files.find((f) => f.id === fileId);
7180
- if (fileToRemove?.preview) {
7181
- URL.revokeObjectURL(fileToRemove.preview);
7182
- }
7183
- const updatedFiles = files.filter((f) => f.id !== fileId);
7184
- setFiles(updatedFiles);
7185
- onValueChange(updatedFiles);
7186
- };
7187
- const handleClick = () => {
7188
- if (!disabled) {
7189
- inputRef.current?.click();
7190
- }
7191
- };
7192
- const acceptString = accept.join(",");
7193
- const defaultSubtext = dropzoneSubtext || `Formatos: ${accept.join(", ")}. M\xE1ximo: ${formatFileSize(maxSize)}`;
7194
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { ref, className: cn("w-full", className), ...props, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
7195
- import_framer_motion10.motion.div,
6962
+ );
6963
+ }
6964
+ );
6965
+ LoadingBase.displayName = "LoadingBase";
6966
+
6967
+ // src/components/ui/feedback/ModalBase.tsx
6968
+ var React22 = __toESM(require("react"));
6969
+ var DialogPrimitive2 = __toESM(require("@radix-ui/react-dialog"));
6970
+ var import_react25 = require("@phosphor-icons/react");
6971
+ var import_jsx_runtime39 = require("react/jsx-runtime");
6972
+ var ModalBase = DialogPrimitive2.Root;
6973
+ var ModalTriggerBase = DialogPrimitive2.Trigger;
6974
+ var ModalPortalBase = DialogPrimitive2.Portal;
6975
+ var ModalCloseBase = DialogPrimitive2.Close;
6976
+ var ModalOverlayBase = React22.forwardRef(({ className, testid: dataTestId = "modal-overlay", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6977
+ DialogPrimitive2.Overlay,
6978
+ {
6979
+ ref,
6980
+ className: cn(
6981
+ "fixed inset-0 z-50 bg-black/60 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
6982
+ className
6983
+ ),
6984
+ "data-testid": dataTestId,
6985
+ ...props
6986
+ }
6987
+ ));
6988
+ ModalOverlayBase.displayName = DialogPrimitive2.Overlay.displayName;
6989
+ var ModalContentBase = React22.forwardRef(
6990
+ ({
6991
+ className,
6992
+ children,
6993
+ testid: dataTestId = "modal-content",
6994
+ size = "md",
6995
+ centered = true,
6996
+ backdropBlur = true,
6997
+ ...props
6998
+ }, ref) => {
6999
+ const sizeClass = size === "sm" ? "max-w-md" : size === "lg" ? "max-w-4xl" : size === "full" ? "w-full max-w-[calc(100%-2rem)]" : "max-w-2xl";
7000
+ const positionClass = centered ? "left-[50%] top-[50%] translate-x-[-50%] translate-y-[-50%]" : "left-[50%] top-20 translate-x-[-50%] translate-y-0 sm:translate-y-0";
7001
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(ModalPortalBase, { children: [
7002
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7003
+ ModalOverlayBase,
7004
+ {
7005
+ className: cn("bg-black/40", backdropBlur ? "backdrop-blur-sm" : "")
7006
+ }
7007
+ ),
7008
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7009
+ "style",
7010
+ {
7011
+ dangerouslySetInnerHTML: {
7012
+ __html: `
7013
+ @keyframes modal-fade-in { from { opacity: 0 } to { opacity: 1 } }
7014
+ @keyframes modal-fade-out { from { opacity: 1 } to { opacity: 0 } }
7015
+ @keyframes modal-scale-in { from { opacity: 0; transform: translate(-50%, -48%) scale(.98) } to { opacity:1; transform: translate(-50%, -50%) scale(1) } }
7016
+ @keyframes modal-scale-out { from { opacity:1; transform: translate(-50%, -50%) scale(1) } to { opacity: 0; transform: translate(-50%, -48%) scale(.98) } }
7017
+ @keyframes overlay-fade-in { from { opacity: 0 } to { opacity: 1 } }
7018
+ @keyframes overlay-fade-out { from { opacity: 1 } to { opacity: 0 } }
7019
+ .data-[state=open]\\:animate-modal-in { animation: modal-fade-in 220ms cubic-bezier(.16,.84,.24,1) both, modal-scale-in 220ms cubic-bezier(.16,.84,.24,1) both }
7020
+ .data-[state=closed]\\:animate-modal-out { animation: modal-scale-out 160ms cubic-bezier(.16,.84,.24,1) both, modal-fade-out 160ms cubic-bezier(.16,.84,.24,1) both }
7021
+ .data-[state=open]\\:animate-overlay-in { animation: overlay-fade-in 220ms cubic-bezier(.16,.84,.24,1) both }
7022
+ .data-[state=closed]\\:animate-overlay-out { animation: overlay-fade-out 160ms cubic-bezier(.16,.84,.24,1) both }
7023
+ `
7024
+ }
7025
+ }
7026
+ ),
7027
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
7028
+ DialogPrimitive2.Content,
7029
+ {
7030
+ ref,
7031
+ className: cn(
7032
+ "fixed z-50 grid w-full gap-4 border bg-background p-6 shadow-lg sm:rounded-lg max-h-[90dvh] overflow-auto",
7033
+ "data-[state=open]:animate-modal-in data-[state=closed]:animate-modal-out",
7034
+ positionClass,
7035
+ sizeClass,
7036
+ className
7037
+ ),
7038
+ "data-testid": dataTestId,
7039
+ ...props,
7040
+ children: [
7041
+ children,
7042
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(DialogPrimitive2.Close, { className: "absolute right-3 top-3 sm:right-4 sm:top-4 rounded-md bg-muted/10 p-1.5 opacity-80 hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none z-10 hover:bg-muted/20 transition-colors", children: [
7043
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_react25.XIcon, { className: "h-5 w-5 sm:h-4 sm:w-4 text-foreground" }),
7044
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "sr-only", children: "Close" })
7045
+ ] })
7046
+ ]
7047
+ }
7048
+ )
7049
+ ] });
7050
+ }
7051
+ );
7052
+ ModalContentBase.displayName = DialogPrimitive2.Content.displayName;
7053
+ var ModalHeaderBase = React22.forwardRef(({ className, testid: dataTestId = "modal-header", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7054
+ "div",
7055
+ {
7056
+ ref,
7057
+ className: cn(
7058
+ "flex flex-col space-y-1.5 text-center sm:text-left",
7059
+ className
7060
+ ),
7061
+ "data-testid": dataTestId,
7062
+ ...props
7063
+ }
7064
+ ));
7065
+ ModalHeaderBase.displayName = "ModalHeader";
7066
+ var ModalFooterBase = React22.forwardRef(({ className, testid: dataTestId = "modal-footer", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7067
+ "div",
7068
+ {
7069
+ ref,
7070
+ className: cn(
7071
+ "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
7072
+ className
7073
+ ),
7074
+ "data-testid": dataTestId,
7075
+ ...props
7076
+ }
7077
+ ));
7078
+ ModalFooterBase.displayName = "ModalFooter";
7079
+ var ModalTitleBase = React22.forwardRef(({ className, testid: dataTestId = "modal-title", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7080
+ DialogPrimitive2.Title,
7081
+ {
7082
+ ref,
7083
+ className: cn(
7084
+ "text-lg font-semibold leading-none tracking-tight",
7085
+ className
7086
+ ),
7087
+ "data-testid": dataTestId,
7088
+ ...props
7089
+ }
7090
+ ));
7091
+ ModalTitleBase.displayName = DialogPrimitive2.Title.displayName;
7092
+ var ModalDescriptionBase = React22.forwardRef(({ className, testid: dataTestId = "modal-description", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7093
+ DialogPrimitive2.Description,
7094
+ {
7095
+ ref,
7096
+ className: cn("text-sm text-muted-foreground", className),
7097
+ "data-testid": dataTestId,
7098
+ ...props
7099
+ }
7100
+ ));
7101
+ ModalDescriptionBase.displayName = DialogPrimitive2.Description.displayName;
7102
+
7103
+ // src/components/ui/feedback/ProgressBase.tsx
7104
+ var React23 = __toESM(require("react"));
7105
+ var ProgressPrimitive = __toESM(require("@radix-ui/react-progress"));
7106
+ var import_jsx_runtime40 = require("react/jsx-runtime");
7107
+ var ProgressBase = React23.forwardRef(
7108
+ ({
7109
+ className,
7110
+ value: rawValue,
7111
+ label,
7112
+ leftIcon,
7113
+ rightIcon,
7114
+ variant = "bar",
7115
+ segments = 5,
7116
+ steps = [],
7117
+ currentStep = 0,
7118
+ showValue = false,
7119
+ valuePosition = "right",
7120
+ autocolor,
7121
+ plusIndicator,
7122
+ ...props
7123
+ }, ref) => {
7124
+ const value = Number(rawValue || 0);
7125
+ const indicatorWidth = Math.min(value, 100);
7126
+ switch (variant) {
7127
+ case "segments":
7128
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7129
+ ProgressSegmentsBase,
7130
+ {
7131
+ label,
7132
+ segments,
7133
+ value: value || 0
7134
+ }
7135
+ );
7136
+ case "panels":
7137
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7138
+ ProgressPanelsBase,
7139
+ {
7140
+ label,
7141
+ steps,
7142
+ currentStep
7143
+ }
7144
+ );
7145
+ case "circles":
7146
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7147
+ ProgressCirclesBase,
7148
+ {
7149
+ label,
7150
+ steps,
7151
+ currentStep
7152
+ }
7153
+ );
7154
+ case "bar":
7155
+ default:
7156
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex flex-col gap-1 w-full min-w-[150px]", children: [
7157
+ label && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(LabelBase_default, { className: "py-2", children: label }),
7158
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex items-center gap-2", children: [
7159
+ showValue && valuePosition === "left" && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "w-12 text-sm text-right font-extrabold", children: [
7160
+ Math.round(value || 0),
7161
+ "%"
7162
+ ] }),
7163
+ leftIcon && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "flex items-center justify-center", children: leftIcon }),
7164
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
7165
+ ProgressPrimitive.Root,
7166
+ {
7167
+ ref,
7168
+ className: cn(
7169
+ " relative h-3 w-full overflow-visible rounded-full bg-muted/80 shadow-inner transition-all ",
7170
+ className
7171
+ ),
7172
+ value,
7173
+ ...props,
7174
+ children: [
7175
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7176
+ ProgressPrimitive.Indicator,
7177
+ {
7178
+ className: cn(
7179
+ "h-full transition-all duration-500 ease-in-out rounded-lg",
7180
+ // quando não usa autocolor, Indicator deve mostrar a cor primária
7181
+ autocolor && autocolor.length >= 2 ? "bg-transparent" : "bg-primary"
7182
+ ),
7183
+ style: { width: `${indicatorWidth}%` }
7184
+ }
7185
+ ),
7186
+ autocolor && Array.isArray(autocolor) && autocolor.length >= 2 && (() => {
7187
+ const [t1Raw, t2Raw] = autocolor;
7188
+ const [t1, t2] = [Number(t1Raw), Number(t2Raw)].sort(
7189
+ (a, b) => a - b
7190
+ );
7191
+ const v = Number(value || 0);
7192
+ let colorClass = "bg-red-500";
7193
+ if (v <= t1) {
7194
+ colorClass = "bg-red-500";
7195
+ } else if (v <= t2) {
7196
+ colorClass = "bg-yellow-500";
7197
+ } else {
7198
+ colorClass = "bg-emerald-500";
7199
+ }
7200
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7201
+ "div",
7202
+ {
7203
+ "aria-hidden": true,
7204
+ className: cn(
7205
+ "absolute top-0 left-0 h-full transition-all duration-500 ease-in-out rounded-lg",
7206
+ colorClass
7207
+ ),
7208
+ style: { width: `${indicatorWidth}%` }
7209
+ }
7210
+ );
7211
+ })(),
7212
+ plusIndicator && value > 100 && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7213
+ "div",
7214
+ {
7215
+ "aria-hidden": "true",
7216
+ className: "absolute top-0 bottom-0 w-0.5 bg-black/70 transition-all duration-500 ease-in-out pointer-events-none",
7217
+ style: { left: `100%` },
7218
+ children: value > 115 && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "absolute left-full ml-2 top-1/2 -translate-y-1/2 text-xs whitespace-nowrap font-extrabold", children: `+${Math.round(
7219
+ value - 100
7220
+ )}%` })
7221
+ }
7222
+ ),
7223
+ showValue && valuePosition === "inside" && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
7224
+ "span",
7225
+ {
7226
+ className: "absolute inset-0 flex items-center justify-center text-sm select-none pointer-events-none text-secondary font-extrabold",
7227
+ "aria-hidden": true,
7228
+ children: [
7229
+ Math.round(value || 0),
7230
+ "%"
7231
+ ]
7232
+ }
7233
+ )
7234
+ ]
7235
+ }
7236
+ ),
7237
+ showValue && valuePosition === "right" && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "w-12 text-sm font-extrabold text-left", children: [
7238
+ Math.round(value || 0),
7239
+ "%"
7240
+ ] }),
7241
+ rightIcon && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "flex items-center justify-center", children: rightIcon })
7242
+ ] })
7243
+ ] });
7244
+ }
7245
+ }
7246
+ );
7247
+ ProgressBase.displayName = "ProgressBase";
7248
+ var ProgressSegmentsBase = ({
7249
+ label,
7250
+ segments,
7251
+ value
7252
+ }) => {
7253
+ const filled = Math.round(value / 100 * segments);
7254
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex flex-col gap-1 w-full min-w-[150px]", children: [
7255
+ label && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(LabelBase_default, { className: "py-2", children: label }),
7256
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "flex gap-1 w-full", children: Array.from({ length: segments }).map((_, idx) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7257
+ "div",
7258
+ {
7259
+ className: cn(
7260
+ "h-2 flex-1 rounded-full transition-all duration-300",
7261
+ idx < filled ? "bg-primary" : "bg-zinc-300 hover:bg-zinc-400"
7262
+ )
7263
+ },
7264
+ idx
7265
+ )) })
7266
+ ] });
7267
+ };
7268
+ var ArrowRightIcon = () => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7269
+ "svg",
7270
+ {
7271
+ className: "w-6 h-6 text-zinc-400 transition-transform duration-300 group-hover:translate-x-1",
7272
+ fill: "none",
7273
+ stroke: "currentColor",
7274
+ strokeWidth: 2,
7275
+ viewBox: "0 0 24 24",
7276
+ xmlns: "http://www.w3.org/2000/svg",
7277
+ children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" })
7278
+ }
7279
+ );
7280
+ var ProgressPanelsBase = ({
7281
+ label,
7282
+ steps,
7283
+ currentStep
7284
+ }) => {
7285
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex flex-col gap-1 w-full", children: [
7286
+ label && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(LabelBase_default, { className: "py-2", children: label }),
7287
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "flex w-full gap-1 rounded-lg overflow-hidden", children: steps.map((step, idx) => {
7288
+ const isActive = idx === currentStep;
7289
+ const isLast = idx === steps.length - 1;
7290
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(React23.Fragment, { children: [
7291
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
7292
+ "div",
7293
+ {
7294
+ className: cn(
7295
+ "relative flex items-center justify-center cursor-pointer select-none rounded-lg border transition-shadow duration-300 ease-in-out",
7296
+ "hover:shadow-md hover:z-10",
7297
+ "aspect-[5/1] min-w-[90px] px-4",
7298
+ isActive ? "bg-primary/20 border-2 border-primary shadow-lg font-semibold" : "border-zinc-300"
7299
+ ),
7300
+ style: { flex: "1 1 0" },
7301
+ children: [
7302
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "truncate", children: step }),
7303
+ isActive && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "absolute bottom-0 left-0 h-1 w-full animate-pulse rounded-b-lg" })
7304
+ ]
7305
+ }
7306
+ ),
7307
+ !isLast && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "flex items-center px-2 group", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(ArrowRightIcon, {}) })
7308
+ ] }, idx);
7309
+ }) })
7310
+ ] });
7311
+ };
7312
+ var ProgressCirclesBase = ({
7313
+ label,
7314
+ steps,
7315
+ currentStep
7316
+ }) => {
7317
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex flex-col gap-2 w-full", children: [
7318
+ label && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("label", { className: "py-2 text-base font-semibold text-gray-700 dark:text-gray-300", children: label }),
7319
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "relative flex items-center justify-between w-full", children: [
7320
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "absolute top-5 left-0 w-full h-1 bg-zinc-200 dark:bg-zinc-700" }),
7321
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7322
+ "div",
7323
+ {
7324
+ className: "absolute top-5 left-0 h-1 bg-primary transition-all duration-300",
7325
+ style: {
7326
+ width: `${currentStep / (steps.length - 1) * 100}%`
7327
+ }
7328
+ }
7329
+ ),
7330
+ steps.map((step, idx) => {
7331
+ const isActive = idx <= currentStep;
7332
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
7333
+ "div",
7334
+ {
7335
+ className: "relative flex flex-col items-center w-10",
7336
+ style: { zIndex: isActive ? 10 : 1 },
7337
+ children: [
7338
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7339
+ "div",
7340
+ {
7341
+ className: cn(
7342
+ "w-10 h-10 rounded-full flex items-center justify-center font-bold text-sm transition-all duration-300 cursor-pointer select-none",
7343
+ isActive ? "bg-primary text-white dark:text-black shadow-md" : "bg-zinc-200 text-zinc-500 hover:bg-zinc-300 dark:bg-zinc-500 dark:text-black"
7344
+ ),
7345
+ children: idx + 1
7346
+ }
7347
+ ),
7348
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "text-xs text-center font-medium mt-1 max-w-[80px] break-words", children: step })
7349
+ ]
7350
+ },
7351
+ idx
7352
+ );
7353
+ })
7354
+ ] })
7355
+ ] });
7356
+ };
7357
+
7358
+ // src/components/ui/feedback/SkeletonBase.tsx
7359
+ var import_jsx_runtime41 = require("react/jsx-runtime");
7360
+ function SkeletonBase({
7361
+ className,
7362
+ ...props
7363
+ }) {
7364
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: cn("animate-pulse bg-primary/10", className), ...props });
7365
+ }
7366
+
7367
+ // src/components/ui/feedback/SonnerBase.tsx
7368
+ var import_react26 = require("@phosphor-icons/react");
7369
+ var import_sonner2 = require("sonner");
7370
+ var import_jsx_runtime42 = require("react/jsx-runtime");
7371
+ var iconBaseClass = "w-5 h-auto";
7372
+ var Toaster = ({ testId, ...props }) => {
7373
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
7374
+ import_sonner2.Toaster,
7375
+ {
7376
+ className: "toaster group",
7377
+ position: "top-center",
7378
+ toastOptions: {
7379
+ classNames: {
7380
+ toast: `
7381
+ group toast
7382
+ bg-background
7383
+ text-foreground
7384
+ shadow-lg rounded-md
7385
+ border-l-4
7386
+ border-border
7387
+ flex items-center gap-3
7388
+ data-[type=success]:border-l-green-500 data-[type=success]:bg-green-50 data-[type=success]:text-green-800 data-[type=success]:border-green-500
7389
+ data-[type=error]:border-l-red-500 data-[type=error]:bg-red-50 data-[type=error]:text-red-800 data-[type=error]:border-red-500
7390
+ data-[type=WarningIcon]:border-l-yellow-500 data-[type=WarningIcon]:bg-yellow-50 data-[type=WarningIcon]:text-yellow-800 data-[type=WarningIcon]:border-yellow-500
7391
+ data-[type=InfoIcon]:border-l-blue-500 data-[type=InfoIcon]:bg-blue-50 data-[type=InfoIcon]:text-blue-800 data-[type=InfoIcon]:border-blue-500
7392
+ `,
7393
+ description: `
7394
+ text-sm
7395
+ group-[.toast]:text-neutral-600
7396
+ `,
7397
+ actionButton: `
7398
+ ml-auto
7399
+ rounded-md px-3 py-1 text-sm font-semibold
7400
+ bg-neutral-800 text-white
7401
+ hover:bg-neutral-700
7402
+ transition-colors duration-200
7403
+ `,
7404
+ cancelButton: `
7405
+ ml-2
7406
+ rounded-md px-3 py-1 text-sm font-semibold
7407
+ bg-neutral-100 text-neutral-700
7408
+ hover:bg-neutral-200
7409
+ transition-colors duration-200
7410
+ `
7411
+ }
7412
+ },
7413
+ "data-testid": testId,
7414
+ ...props
7415
+ }
7416
+ );
7417
+ };
7418
+ var toast2 = {
7419
+ success: (message) => import_sonner2.toast.success(message, {
7420
+ icon: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react26.CheckCircleIcon, { className: `${iconBaseClass} text-green-600`, weight: "fill" }),
7421
+ className: "sonner-success"
7422
+ }),
7423
+ error: (message) => import_sonner2.toast.error(message, {
7424
+ icon: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react26.XCircleIcon, { className: `${iconBaseClass} text-red-600`, weight: "fill" }),
7425
+ className: "sonner-error"
7426
+ }),
7427
+ warning: (message) => import_sonner2.toast.warning(message, {
7428
+ icon: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react26.WarningIcon, { className: `${iconBaseClass} text-yellow-600`, weight: "fill" }),
7429
+ className: "sonner-WarningIcon"
7430
+ }),
7431
+ info: (message) => import_sonner2.toast.info(message, {
7432
+ icon: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react26.InfoIcon, { className: `${iconBaseClass} text-blue-600`, weight: "fill" }),
7433
+ className: "sonner-InfoIcon"
7434
+ }),
7435
+ loading: (message) => (0, import_sonner2.toast)(message, {
7436
+ icon: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react26.SpinnerIcon, { className: `${iconBaseClass} animate-spin text-neutral-500`, weight: "fill" }),
7437
+ className: "sonner-loading"
7438
+ })
7439
+ };
7440
+
7441
+ // src/components/ui/form/CheckBoxBase.tsx
7442
+ var React24 = __toESM(require("react"));
7443
+ var CheckboxPrimitive = __toESM(require("@radix-ui/react-checkbox"));
7444
+ var import_react27 = require("@phosphor-icons/react");
7445
+ var import_framer_motion11 = require("framer-motion");
7446
+ var import_jsx_runtime43 = require("react/jsx-runtime");
7447
+ var CheckboxBase = React24.forwardRef(({ className, testid: dataTestId = "checkbox-base", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
7448
+ CheckboxPrimitive.Root,
7449
+ {
7450
+ ref,
7451
+ className: cn(
7452
+ "peer h-4 w-4 shrink-0 rounded-md border border-primary shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground transition-colors",
7453
+ className
7454
+ ),
7455
+ "data-testid": dataTestId,
7456
+ ...props,
7457
+ children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(CheckboxPrimitive.Indicator, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
7458
+ import_framer_motion11.motion.div,
7196
7459
  {
7197
- className: cn(
7198
- "relative flex cursor-pointer flex-col items-center justify-center rounded-xl border-2 border-dashed p-10 transition-all duration-300 dark:shadow-black/20",
7199
- isDragging && "border-primary bg-primary/10 scale-[1.02]",
7200
- !isDragging && "border-border hover:border-primary/60 hover:bg-muted/50",
7201
- disabled && "cursor-not-allowed opacity-50 hover:scale-100"
7202
- ),
7203
- onDragEnter: handleDragEnter,
7204
- onDragOver: handleDragOver,
7205
- onDragLeave: handleDragLeave,
7206
- onDrop: handleDrop,
7207
- onClick: handleClick,
7208
- whileHover: !disabled ? { scale: 1.01 } : void 0,
7209
- whileTap: !disabled ? { scale: 0.99 } : void 0,
7210
- animate: isDragging ? {
7211
- borderColor: `hsl(var(--primary))`,
7212
- backgroundColor: `hsl(var(--primary) / 0.1)`,
7213
- scale: 1.02
7214
- } : {
7215
- borderColor: `hsl(var(--border))`,
7216
- backgroundColor: `hsl(var(--background))`,
7217
- scale: 1
7218
- },
7219
- transition: {
7220
- type: "spring",
7221
- stiffness: 300,
7222
- damping: 25,
7223
- duration: 0.3
7224
- },
7460
+ initial: { scale: 0, opacity: 0, rotate: -90 },
7461
+ animate: { scale: 1, opacity: 1, rotate: 0 },
7462
+ exit: { scale: 0, opacity: 0, rotate: 90 },
7463
+ transition: { type: "spring", stiffness: 500, damping: 30 },
7464
+ className: "flex items-center justify-center text-current",
7465
+ children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react27.CheckIcon, { className: "h-4 w-4", weight: "bold" })
7466
+ }
7467
+ ) })
7468
+ }
7469
+ ));
7470
+ CheckboxBase.displayName = CheckboxPrimitive.Root.displayName;
7471
+
7472
+ // src/components/ui/form/CollapsibleBase.tsx
7473
+ var React25 = __toESM(require("react"));
7474
+ var CollapsiblePrimitive = __toESM(require("@radix-ui/react-collapsible"));
7475
+ var import_react28 = require("@phosphor-icons/react");
7476
+ var import_jsx_runtime44 = require("react/jsx-runtime");
7477
+ var CollapsibleBase = React25.forwardRef(({ ...props }, ref) => {
7478
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(CollapsiblePrimitive.Root, { ref, "data-slot": "collapsible", ...props });
7479
+ });
7480
+ CollapsibleBase.displayName = CollapsiblePrimitive.Root.displayName;
7481
+ var CollapsibleTriggerBase = React25.forwardRef(({ className, children, leftIcon, showCaret = true, ...props }, ref) => {
7482
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
7483
+ CollapsiblePrimitive.CollapsibleTrigger,
7484
+ {
7485
+ ref,
7486
+ className: cn(
7487
+ "flex w-full items-center justify-between p-3 text-left font-medium transition-all duration-500 ease-[cubic-bezier(0.4,0,0.2,1)] hover:bg-accent hover:text-accent-foreground rounded-md outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 [&[data-state=open]_.caret-icon]:rotate-180",
7488
+ className
7489
+ ),
7490
+ "data-slot": "collapsible-trigger",
7491
+ ...props,
7492
+ children: [
7493
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center gap-2", children: [
7494
+ leftIcon && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "flex-shrink-0 [&>svg]:size-4", children: leftIcon }),
7495
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { children })
7496
+ ] }),
7497
+ showCaret && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "caret-icon flex-shrink-0 transition-transform duration-500 ease-[cubic-bezier(0.4,0,0.2,1)]", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react28.CaretUpDownIcon, { className: "h-4 w-4" }) })
7498
+ ]
7499
+ }
7500
+ );
7501
+ });
7502
+ CollapsibleTriggerBase.displayName = CollapsiblePrimitive.CollapsibleTrigger.displayName;
7503
+ var CollapsibleContentBase = React25.forwardRef(({ className, children, ...props }, ref) => {
7504
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
7505
+ CollapsiblePrimitive.CollapsibleContent,
7506
+ {
7507
+ ref,
7508
+ className: cn(
7509
+ "overflow-hidden data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down",
7510
+ className
7511
+ ),
7512
+ "data-slot": "collapsible-content",
7513
+ ...props,
7514
+ children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "pb-3 pt-1", children })
7515
+ }
7516
+ );
7517
+ });
7518
+ CollapsibleContentBase.displayName = CollapsiblePrimitive.CollapsibleContent.displayName;
7519
+
7520
+ // src/components/ui/form/DebounceInput.tsx
7521
+ var import_react29 = require("react");
7522
+ var import_react30 = require("@phosphor-icons/react");
7523
+ var import_jsx_runtime45 = require("react/jsx-runtime");
7524
+
7525
+ // src/components/ui/form/HoverCardBase.tsx
7526
+ var HoverCardPrimitive = __toESM(require("@radix-ui/react-hover-card"));
7527
+ var import_jsx_runtime46 = require("react/jsx-runtime");
7528
+ function HoverCardBase(props) {
7529
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(HoverCardPrimitive.Root, { ...props });
7530
+ }
7531
+ function HoverCardTriggerBase(props) {
7532
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(HoverCardPrimitive.Trigger, { ...props });
7533
+ }
7534
+ function HoverCardContentBase({
7535
+ className,
7536
+ align = "center",
7537
+ sideOffset = 4,
7538
+ ...props
7539
+ }) {
7540
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(HoverCardPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
7541
+ HoverCardPrimitive.Content,
7542
+ {
7543
+ align,
7544
+ sideOffset,
7545
+ className: cn(
7546
+ "z-50 w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none",
7547
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
7548
+ "data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0",
7549
+ "data-[state=open]:zoom-in-95 data-[state=closed]:zoom-out-95",
7550
+ "data-[side=bottom]:slide-in-from-top-2",
7551
+ "data-[side=left]:slide-in-from-right-2",
7552
+ "data-[side=right]:slide-in-from-left-2",
7553
+ "data-[side=top]:slide-in-from-bottom-2",
7554
+ className
7555
+ ),
7556
+ ...props
7557
+ }
7558
+ ) });
7559
+ }
7560
+
7561
+ // src/components/ui/form/Input-OTP-Base.tsx
7562
+ var React26 = __toESM(require("react"));
7563
+ var import_input_otp = require("input-otp");
7564
+ var import_react31 = require("@phosphor-icons/react");
7565
+ var import_jsx_runtime47 = require("react/jsx-runtime");
7566
+ function InputOTPBase({
7567
+ className,
7568
+ containerClassName,
7569
+ ...props
7570
+ }) {
7571
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
7572
+ import_input_otp.OTPInput,
7573
+ {
7574
+ "data-slot": "input-otp",
7575
+ containerClassName: cn(
7576
+ "flex items-center gap-2 has-disabled:opacity-50",
7577
+ containerClassName
7578
+ ),
7579
+ className: cn("disabled:cursor-not-allowed", className),
7580
+ ...props
7581
+ }
7582
+ );
7583
+ }
7584
+ function InputOTPGroupBase({ className, ...props }) {
7585
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
7586
+ "div",
7587
+ {
7588
+ "data-slot": "input-otp-group",
7589
+ className: cn("flex items-center", className),
7590
+ ...props
7591
+ }
7592
+ );
7593
+ }
7594
+ function InputOTPSlotBase({
7595
+ index,
7596
+ className,
7597
+ ...props
7598
+ }) {
7599
+ const inputOTPContext = React26.useContext(import_input_otp.OTPInputContext);
7600
+ const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {};
7601
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
7602
+ "div",
7603
+ {
7604
+ "data-slot": "input-otp-slot",
7605
+ "data-active": isActive,
7606
+ className: cn(
7607
+ "data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive dark:bg-input/30 border-input relative flex h-9 w-9 items-center justify-center border-y border-r text-sm shadow-xs transition-all outline-none first:rounded-l-md first:border-l last:rounded-r-md data-[active=true]:z-10 data-[active=true]:ring-[3px]",
7608
+ className
7609
+ ),
7610
+ ...props,
7611
+ children: [
7612
+ char,
7613
+ hasFakeCaret && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "pointer-events-none absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "animate-caret-blink bg-foreground h-4 w-px duration-1000" }) })
7614
+ ]
7615
+ }
7616
+ );
7617
+ }
7618
+ function InputOTPSeparatorBase({ ...props }) {
7619
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { "data-slot": "input-otp-separator", role: "separator", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react31.MinusIcon, {}) });
7620
+ }
7621
+
7622
+ // src/components/ui/form/SliderBase.tsx
7623
+ var React27 = __toESM(require("react"));
7624
+ var SliderPrimitive = __toESM(require("@radix-ui/react-slider"));
7625
+ var import_jsx_runtime48 = require("react/jsx-runtime");
7626
+ var SlideBase = React27.forwardRef(
7627
+ ({
7628
+ className,
7629
+ orientation = "horizontal",
7630
+ label,
7631
+ leftIcon,
7632
+ rightIcon,
7633
+ ...props
7634
+ }, ref) => {
7635
+ const isVertical = orientation === "vertical";
7636
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
7637
+ "div",
7638
+ {
7639
+ className: cn("flex flex-col gap-1", isVertical ? "h-full " : "w-full"),
7225
7640
  children: [
7226
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
7227
- "input",
7228
- {
7229
- ref: inputRef,
7230
- type: "file",
7231
- className: "hidden",
7232
- accept: acceptString,
7233
- multiple,
7234
- disabled,
7235
- onChange: handleInputChange
7236
- }
7237
- ),
7238
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
7239
- import_framer_motion10.motion.div,
7240
- {
7241
- animate: isDragging ? { scale: 1.2, rotate: 10 } : { scale: 1, rotate: 0 },
7242
- transition: {
7243
- type: "spring",
7244
- stiffness: 300,
7245
- damping: 20,
7246
- duration: 0.3
7247
- },
7248
- children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
7249
- import_framer_motion10.motion.div,
7250
- {
7251
- className: cn(
7252
- "mb-4 h-16 w-16 text-muted-foreground transition-colors duration-300 drop-shadow-lg flex items-center justify-center",
7253
- isDragging && "text-primary"
7254
- ),
7255
- initial: false,
7256
- animate: {
7257
- color: isDragging ? `hsl(var(--primary))` : `hsl(var(--muted-foreground))`
7258
- },
7259
- transition: { duration: 0.3 },
7260
- children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react25.CloudArrowUpIcon, { size: 64 })
7261
- }
7262
- )
7263
- }
7264
- ),
7265
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
7266
- import_framer_motion10.motion.p,
7267
- {
7268
- className: "mb-2 text-base font-semibold text-foreground",
7269
- initial: animate ? { opacity: 0, y: -10 } : false,
7270
- animate: { opacity: 1, y: 0 },
7271
- transition: { delay: 0.1 },
7272
- children: dropzoneText
7273
- }
7274
- ),
7275
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
7276
- import_framer_motion10.motion.p,
7277
- {
7278
- className: "text-sm text-muted-foreground",
7279
- initial: animate ? { opacity: 0, y: -10 } : false,
7280
- animate: { opacity: 1, y: 0 },
7281
- transition: { delay: 0.2 },
7282
- children: defaultSubtext
7283
- }
7284
- ),
7285
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_framer_motion10.AnimatePresence, { children: files.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
7286
- import_framer_motion10.motion.div,
7641
+ label && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(LabelBase_default, { className: "py-2", children: label }),
7642
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
7643
+ "div",
7287
7644
  {
7288
- initial: { opacity: 0, scale: 0.8, y: 10 },
7289
- animate: {
7290
- opacity: 1,
7291
- scale: 1,
7292
- y: 0,
7293
- backgroundColor: `hsl(var(--primary) / 0.1)`,
7294
- borderColor: `hsl(var(--primary) / 0.2)`
7295
- },
7296
- exit: { opacity: 0, scale: 0.8, y: 10 },
7297
7645
  className: cn(
7298
- "mt-4 flex items-center gap-2 rounded-full border px-4 py-2 backdrop-blur-sm bg-primary/20 border-primary/30 shadow-lg"
7646
+ "flex gap-2",
7647
+ isVertical ? "flex-col h-full" : "flex-row items-center w-full"
7299
7648
  ),
7300
- transition: { duration: 0.3 },
7301
7649
  children: [
7302
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "h-4 w-4 text-primary flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react25.CheckIcon, { size: 16, className: "text-emerald-500" }) }),
7303
- /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
7304
- import_framer_motion10.motion.span,
7305
- {
7306
- className: "text-sm font-semibold text-primary",
7307
- animate: { color: `hsl(var(--primary))` },
7308
- transition: { duration: 0.3 },
7309
- children: [
7310
- files.length,
7311
- " ",
7312
- files.length === 1 ? "arquivo selecionado" : "arquivos selecionados"
7313
- ]
7314
- }
7315
- )
7316
- ]
7317
- }
7318
- ) }),
7319
- showPreview && files.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
7320
- import_framer_motion10.motion.div,
7321
- {
7322
- className: "mt-6 w-full",
7323
- initial: animate ? { opacity: 0, y: 10 } : false,
7324
- animate: { opacity: 1, y: 0 },
7325
- transition: { delay: 0.3 },
7326
- children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { children: [
7327
- /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("h4", { className: "mb-3 text-sm font-medium text-muted-foreground", children: [
7328
- "Arquivos selecionados (",
7329
- files.length,
7330
- "/",
7331
- maxFiles,
7332
- ")"
7333
- ] }),
7334
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "space-y-2 overflow-y-auto max-h-44", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_framer_motion10.AnimatePresence, { mode: "popLayout", children: files.map((file, index) => /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
7335
- import_framer_motion10.motion.div,
7650
+ leftIcon && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "flex items-center justify-center", children: leftIcon }),
7651
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
7652
+ SliderPrimitive.Root,
7336
7653
  {
7337
- layout: true,
7338
- initial: animate ? { opacity: 0, x: -20 } : false,
7339
- animate: { opacity: 1, x: 0 },
7340
- exit: {
7341
- opacity: 0,
7342
- x: -20,
7343
- transition: { duration: 0.2 }
7344
- },
7345
- transition: {
7346
- delay: animate ? index * 0.05 : 0,
7347
- layout: { duration: 0.2 }
7348
- },
7654
+ ref,
7655
+ orientation,
7349
7656
  className: cn(
7350
- "flex items-center gap-3 rounded-md border p-3 transition-all duration-300",
7351
- file.error ? "border-destructive/50 bg-destructive/5" : "border-border bg-background/80 hover:bg-muted/50 hover:shadow-md hover:shadow-primary/10 hover:border-primary/30"
7657
+ "relative flex touch-none select-none items-center",
7658
+ isVertical ? "flex-col h-full" : "flex-row w-full",
7659
+ className
7352
7660
  ),
7661
+ ...props,
7353
7662
  children: [
7354
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "flex h-12 w-12 shrink-0 items-center justify-center rounded-md bg-muted overflow-hidden", children: file.preview ? (
7355
- // Preview de imagem
7356
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
7357
- "img",
7358
- {
7359
- src: file.preview,
7360
- alt: file.name,
7361
- className: "h-full w-full object-cover rounded-md"
7362
- }
7363
- )
7364
- ) : (
7365
- // Ícone baseado no tipo de arquivo
7366
- getFileTypeIcon(file)
7367
- ) }),
7368
- /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "min-w-0 flex-1", children: [
7369
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
7370
- "p",
7371
- {
7372
- className: "truncate text-sm font-medium text-foreground",
7373
- title: `${file.name} (${file.type || "Tipo desconhecido"})`,
7374
- children: file.name
7375
- }
7376
- ),
7377
- /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
7378
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { children: formatFileSize(file.size) }),
7379
- file.type && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
7380
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { children: "\u2022" }),
7381
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "uppercase", children: getFileExtension(file.name) })
7382
- ] })
7383
- ] }),
7384
- file.error && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
7385
- import_framer_motion10.motion.p,
7386
- {
7387
- className: "mt-1 text-xs text-destructive",
7388
- initial: { opacity: 0, y: -5 },
7389
- animate: { opacity: 1, y: 0 },
7390
- children: file.error
7391
- }
7392
- )
7393
- ] }),
7394
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
7395
- DeleteButton,
7663
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
7664
+ SliderPrimitive.Track,
7396
7665
  {
7397
- type: "button",
7398
- variant: "destructive",
7399
- size: "icon",
7400
- onClick: (e) => {
7401
- e?.stopPropagation();
7402
- handleRemoveFile(file.id);
7403
- },
7404
- className: "",
7405
- children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react25.XIcon, { size: 12 })
7666
+ className: cn(
7667
+ "relative overflow-hidden bg-primary/20 rounded-full",
7668
+ isVertical ? "w-1.5 h-full" : "h-1.5 w-full"
7669
+ ),
7670
+ children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
7671
+ SliderPrimitive.Range,
7672
+ {
7673
+ className: cn(
7674
+ "absolute bg-primary",
7675
+ isVertical ? "w-full" : "h-full"
7676
+ )
7677
+ }
7678
+ )
7679
+ }
7680
+ ),
7681
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
7682
+ SliderPrimitive.Thumb,
7683
+ {
7684
+ className: cn(
7685
+ "block h-4 w-4 rounded-full border border-primary/70 bg-background shadow-md transition-transform",
7686
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2",
7687
+ "hover:scale-125 active:scale-125"
7688
+ )
7406
7689
  }
7407
7690
  )
7408
7691
  ]
7409
- },
7410
- file.id
7411
- )) }) })
7412
- ] })
7692
+ }
7693
+ ),
7694
+ rightIcon && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "flex items-center justify-center", children: rightIcon })
7695
+ ]
7413
7696
  }
7414
7697
  )
7415
7698
  ]
7416
7699
  }
7417
- ) });
7700
+ );
7701
+ }
7702
+ );
7703
+ SlideBase.displayName = "SlideBase";
7704
+
7705
+ // src/components/ui/form/SmallButtons.tsx
7706
+ var React28 = __toESM(require("react"));
7707
+ var import_react32 = require("@phosphor-icons/react");
7708
+ var import_jsx_runtime49 = require("react/jsx-runtime");
7709
+ var EditButton = React28.forwardRef(
7710
+ ({
7711
+ disabled,
7712
+ onClick,
7713
+ testid = "button-edit",
7714
+ className,
7715
+ iconSize = 18,
7716
+ iconColor,
7717
+ variant = "default",
7718
+ size = "icon",
7719
+ ...props
7720
+ }, ref) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
7721
+ ButtonBase,
7722
+ {
7723
+ ref,
7724
+ variant,
7725
+ size,
7726
+ onClick,
7727
+ disabled,
7728
+ testid,
7729
+ className: cn(
7730
+ "transition-all duration-200 ease-in-out group",
7731
+ "hover:scale-105",
7732
+ "active:scale-95",
7733
+ "disabled:hover:scale-100",
7734
+ className
7735
+ ),
7736
+ ...props,
7737
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
7738
+ import_react32.PencilSimpleIcon,
7739
+ {
7740
+ size: iconSize,
7741
+ color: iconColor,
7742
+ className: "transition-transform duration-200 group-hover:-rotate-12"
7743
+ }
7744
+ )
7745
+ }
7746
+ )
7747
+ );
7748
+ EditButton.displayName = "EditButton";
7749
+ var ChangeButton = React28.forwardRef(
7750
+ ({
7751
+ disabled,
7752
+ onClick,
7753
+ testid = "button-edit",
7754
+ className,
7755
+ iconSize = 18,
7756
+ iconColor,
7757
+ variant = "default",
7758
+ size = "icon",
7759
+ ...props
7760
+ }, ref) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
7761
+ ButtonBase,
7762
+ {
7763
+ ref,
7764
+ variant,
7765
+ size,
7766
+ onClick,
7767
+ disabled,
7768
+ testid,
7769
+ className: cn(
7770
+ "transition-all duration-200 ease-in-out group",
7771
+ "hover:scale-105",
7772
+ "active:scale-95",
7773
+ "disabled:hover:scale-100",
7774
+ className
7775
+ ),
7776
+ ...props,
7777
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
7778
+ import_react32.ArrowsLeftRightIcon,
7779
+ {
7780
+ size: iconSize,
7781
+ color: iconColor,
7782
+ className: "transition-transform duration-200 group-hover:-rotate-180"
7783
+ }
7784
+ )
7785
+ }
7786
+ )
7787
+ );
7788
+ ChangeButton.displayName = "ChangeButton";
7789
+ var SaveButton = React28.forwardRef(
7790
+ ({
7791
+ disabled,
7792
+ onClick,
7793
+ testid = "button-save",
7794
+ className,
7795
+ iconSize = 18,
7796
+ iconColor,
7797
+ variant = "default",
7798
+ size = "icon",
7799
+ ...props
7800
+ }, ref) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
7801
+ ButtonBase,
7802
+ {
7803
+ ref,
7804
+ variant,
7805
+ size,
7806
+ onClick,
7807
+ disabled,
7808
+ testid,
7809
+ className: cn(
7810
+ "transition-all duration-200 ease-in-out group",
7811
+ "hover:scale-105",
7812
+ "active:scale-95",
7813
+ "disabled:hover:scale-100",
7814
+ className
7815
+ ),
7816
+ ...props,
7817
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
7818
+ import_react32.FloppyDiskIcon,
7819
+ {
7820
+ size: iconSize,
7821
+ color: iconColor,
7822
+ className: "transition-transform duration-200 group-hover:scale-110"
7823
+ }
7824
+ )
7825
+ }
7826
+ )
7827
+ );
7828
+ SaveButton.displayName = "SaveButton";
7829
+ var AddButton = React28.forwardRef(
7830
+ ({
7831
+ disabled,
7832
+ onClick,
7833
+ testid = "button-add",
7834
+ className,
7835
+ iconSize = 18,
7836
+ iconColor,
7837
+ variant = "default",
7838
+ size = "icon",
7839
+ ...props
7840
+ }, ref) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
7841
+ ButtonBase,
7842
+ {
7843
+ ref,
7844
+ variant,
7845
+ size,
7846
+ onClick,
7847
+ disabled,
7848
+ testid,
7849
+ className: cn(
7850
+ "transition-all duration-200 ease-in-out",
7851
+ "hover:scale-105",
7852
+ "active:scale-95",
7853
+ "disabled:hover:scale-100",
7854
+ className
7855
+ ),
7856
+ ...props,
7857
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
7858
+ import_react32.PlusIcon,
7859
+ {
7860
+ size: iconSize,
7861
+ color: iconColor,
7862
+ className: "transition-transform duration-300"
7863
+ }
7864
+ )
7865
+ }
7866
+ )
7867
+ );
7868
+ AddButton.displayName = "AddButton";
7869
+ var CloseButton = React28.forwardRef(
7870
+ ({
7871
+ disabled,
7872
+ onClick,
7873
+ testid = "button-close",
7874
+ className,
7875
+ iconSize = 18,
7876
+ iconColor,
7877
+ variant = "ghost",
7878
+ size = "icon",
7879
+ ...props
7880
+ }, ref) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
7881
+ ButtonBase,
7882
+ {
7883
+ ref,
7884
+ variant,
7885
+ size,
7886
+ onClick,
7887
+ disabled,
7888
+ testid,
7889
+ className: cn(
7890
+ "transition-all duration-200 ease-in-out",
7891
+ "hover:scale-110 hover:rotate-90 hover:bg-destructive/10",
7892
+ "active:scale-95 active:rotate-0",
7893
+ "disabled:hover:scale-100 disabled:hover:rotate-0",
7894
+ className
7895
+ ),
7896
+ ...props,
7897
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
7898
+ import_react32.XIcon,
7899
+ {
7900
+ size: iconSize,
7901
+ color: iconColor,
7902
+ className: "transition-transform duration-300"
7903
+ }
7904
+ )
7905
+ }
7906
+ )
7907
+ );
7908
+ CloseButton.displayName = "CloseButton";
7909
+ var DownloadButton = ({
7910
+ disabled,
7911
+ onClick,
7912
+ testid = "button-download",
7913
+ ...props
7914
+ }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
7915
+ ButtonBase,
7916
+ {
7917
+ variant: "outline",
7918
+ size: "icon",
7919
+ onClick,
7920
+ disabled,
7921
+ testid,
7922
+ className: cn(
7923
+ "transition-all duration-200 ease-in-out group",
7924
+ "hover:scale-105",
7925
+ "active:scale-95",
7926
+ "disabled:hover:scale-100"
7927
+ ),
7928
+ ...props,
7929
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
7930
+ import_react32.DownloadSimpleIcon,
7931
+ {
7932
+ size: 18,
7933
+ className: "transition-transform duration-300 group-hover:translate-y-0.5"
7934
+ }
7935
+ )
7418
7936
  }
7419
7937
  );
7420
- FileUploader.displayName = "FileUploader";
7421
-
7422
- // src/components/ui/feedback/LoadingBase.tsx
7423
- var React22 = __toESM(require("react"));
7424
- var import_class_variance_authority3 = require("class-variance-authority");
7425
- var import_jsx_runtime39 = require("react/jsx-runtime");
7426
- var loadingVariants = (0, import_class_variance_authority3.cva)(
7427
- "rounded-full border-2 animate-spin border-muted border-t-primary",
7938
+ var UploadButton = ({
7939
+ disabled,
7940
+ onClick,
7941
+ testid = "button-upload",
7942
+ ...props
7943
+ }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
7944
+ ButtonBase,
7428
7945
  {
7429
- variants: {
7430
- size: {
7431
- sm: "h-4 w-4",
7432
- md: "h-6 w-6",
7433
- lg: "h-8 w-8",
7434
- xl: "h-12 w-12 border-[3px]"
7946
+ variant: "outline",
7947
+ size: "icon",
7948
+ onClick,
7949
+ disabled,
7950
+ testid,
7951
+ className: cn(
7952
+ "transition-all duration-200 ease-in-out group",
7953
+ "hover:scale-105",
7954
+ "active:scale-95",
7955
+ "disabled:hover:scale-100"
7956
+ ),
7957
+ ...props,
7958
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
7959
+ import_react32.UploadSimpleIcon,
7960
+ {
7961
+ size: 18,
7962
+ className: "transition-transform duration-300 group-hover:-translate-y-0.5"
7435
7963
  }
7436
- },
7437
- defaultVariants: {
7438
- size: "md"
7439
- }
7964
+ )
7440
7965
  }
7441
7966
  );
7442
- var dotsVariants = (0, import_class_variance_authority3.cva)(
7443
- "flex items-center justify-center",
7967
+ var CopyButton = ({
7968
+ disabled,
7969
+ onClick,
7970
+ testid = "button-copy",
7971
+ ...props
7972
+ }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
7973
+ ButtonBase,
7444
7974
  {
7445
- variants: {
7446
- size: {
7447
- sm: "gap-1",
7448
- md: "gap-1.5",
7449
- lg: "gap-2",
7450
- xl: "gap-2.5"
7975
+ variant: "ghost",
7976
+ size: "icon",
7977
+ onClick,
7978
+ disabled,
7979
+ testid,
7980
+ className: cn(
7981
+ "transition-all duration-200 ease-in-out group",
7982
+ "hover:scale-105",
7983
+ "active:scale-90",
7984
+ "disabled:hover:scale-100"
7985
+ ),
7986
+ ...props,
7987
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
7988
+ import_react32.CopyIcon,
7989
+ {
7990
+ size: 18,
7991
+ className: "transition-transform duration-200 group-hover:scale-110"
7992
+ }
7993
+ )
7994
+ }
7995
+ );
7996
+ var RefreshButton = ({
7997
+ disabled,
7998
+ onClick,
7999
+ testid = "button-refresh",
8000
+ ...props
8001
+ }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8002
+ ButtonBase,
8003
+ {
8004
+ variant: "ghost",
8005
+ size: "icon",
8006
+ onClick,
8007
+ disabled,
8008
+ testid,
8009
+ className: cn(
8010
+ "transition-all duration-200 ease-in-out group",
8011
+ "hover:scale-105",
8012
+ "active:scale-95",
8013
+ "disabled:hover:scale-100"
8014
+ ),
8015
+ ...props,
8016
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8017
+ import_react32.ArrowClockwiseIcon,
8018
+ {
8019
+ size: 18,
8020
+ className: "transition-transform duration-500 group-hover:rotate-180"
7451
8021
  }
7452
- },
7453
- defaultVariants: {
7454
- size: "md"
7455
- }
8022
+ )
7456
8023
  }
7457
8024
  );
7458
- var dotVariants = (0, import_class_variance_authority3.cva)(
7459
- "rounded-full bg-gradient-to-r from-primary to-primary/70 shadow-sm",
8025
+ var SearchButton = ({
8026
+ disabled,
8027
+ onClick,
8028
+ testid = "button-search",
8029
+ ...props
8030
+ }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8031
+ ButtonBase,
7460
8032
  {
7461
- variants: {
7462
- size: {
7463
- sm: "h-1.5 w-2",
7464
- md: "h-2.5 w-2.5",
7465
- lg: "h-2.5 w-3",
7466
- xl: "h-3.5 w-4"
8033
+ variant: "outline",
8034
+ size: "icon",
8035
+ onClick,
8036
+ disabled,
8037
+ testid,
8038
+ className: cn(
8039
+ "transition-all duration-200 ease-in-out group",
8040
+ "hover:scale-105",
8041
+ "active:scale-95",
8042
+ "disabled:hover:scale-100"
8043
+ ),
8044
+ ...props,
8045
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8046
+ import_react32.MagnifyingGlassIcon,
8047
+ {
8048
+ size: 18,
8049
+ className: "transition-transform duration-200 group-hover:scale-110 group-hover:-rotate-12"
7467
8050
  }
7468
- },
7469
- defaultVariants: {
7470
- size: "md"
7471
- }
8051
+ )
7472
8052
  }
7473
8053
  );
7474
- var LoadingBase = React22.forwardRef(
7475
- ({ className, size, message, overlay = false, variant = "spinner", ...props }, ref) => {
7476
- React22.useEffect(() => {
7477
- const style = document.createElement("style");
7478
- style.textContent = `
7479
- @keyframes dotBounce {
7480
- 0%, 80%, 100% {
7481
- transform: translateY(0);
7482
- opacity: 0.8;
7483
- }
7484
- 40% {
7485
- transform: translateY(-8px);
7486
- opacity: 1;
7487
- }
7488
- }
7489
- `;
7490
- document.head.appendChild(style);
7491
- return () => {
7492
- if (document.head.contains(style)) {
7493
- document.head.removeChild(style);
7494
- }
7495
- };
7496
- }, []);
7497
- const renderSpinner = () => {
7498
- if (variant === "dots") {
7499
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: cn(dotsVariants({ size })), "aria-hidden": "true", children: [
7500
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7501
- "div",
7502
- {
7503
- className: cn(dotVariants({ size })),
7504
- style: {
7505
- animation: "dotBounce 1.4s ease-in-out infinite",
7506
- animationDelay: "0ms",
7507
- transform: "translateY(0px)"
7508
- }
7509
- }
7510
- ),
7511
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7512
- "div",
7513
- {
7514
- className: cn(dotVariants({ size })),
7515
- style: {
7516
- animation: "dotBounce 1.4s ease-in-out infinite",
7517
- animationDelay: "0.16s",
7518
- transform: "translateY(0px)"
7519
- }
7520
- }
7521
- ),
7522
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7523
- "div",
7524
- {
7525
- className: cn(dotVariants({ size })),
7526
- style: {
7527
- animation: "dotBounce 1.4s ease-in-out infinite",
7528
- animationDelay: "0.32s",
7529
- transform: "translateY(0px)"
7530
- }
7531
- }
7532
- )
7533
- ] });
7534
- }
7535
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7536
- "div",
7537
- {
7538
- className: cn(loadingVariants({ size })),
7539
- style: {
7540
- animation: "spin 1s linear infinite"
7541
- },
7542
- "aria-hidden": "true"
7543
- }
7544
- );
7545
- };
7546
- const loadingContent = /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
7547
- renderSpinner(),
7548
- message && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "text-sm font-medium text-muted-foreground animate-pulse", children: message })
7549
- ] });
7550
- if (overlay) {
7551
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7552
- "div",
7553
- {
7554
- ref,
7555
- className: cn(
7556
- "fixed inset-0 z-50 flex items-center justify-center",
7557
- "bg-background/80 dark:bg-background/60",
7558
- "backdrop-blur-md backdrop-saturate-150",
7559
- "transition-all duration-300 ease-in-out",
7560
- "animate-in fade-in-0",
7561
- className
7562
- ),
7563
- role: "status",
7564
- "aria-label": message || "Carregando",
7565
- ...props,
7566
- children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cn(
7567
- "relative p-8 rounded-2xl",
7568
- "bg-card/90 dark:bg-card/95",
7569
- "border border-border/50",
7570
- "shadow-2xl shadow-black/10 dark:shadow-black/30",
7571
- "backdrop-blur-xl backdrop-saturate-150",
7572
- "animate-in zoom-in-95 fade-in-0 duration-300",
7573
- "text-center space-y-4"
7574
- ), children: loadingContent })
7575
- }
7576
- );
7577
- }
7578
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7579
- "div",
8054
+ var BackButton = ({
8055
+ disabled,
8056
+ onClick,
8057
+ testid = "button-back",
8058
+ ...props
8059
+ }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8060
+ ButtonBase,
8061
+ {
8062
+ variant: "ghost",
8063
+ size: "icon",
8064
+ onClick,
8065
+ disabled,
8066
+ testid,
8067
+ className: cn(
8068
+ "transition-all duration-200 ease-in-out group",
8069
+ "hover:scale-105",
8070
+ "active:scale-95",
8071
+ "disabled:hover:scale-100"
8072
+ ),
8073
+ ...props,
8074
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8075
+ import_react32.ArrowLeftIcon,
7580
8076
  {
7581
- ref,
7582
- className: cn("flex items-center justify-center", className),
7583
- role: "status",
7584
- "aria-label": message || "Carregando",
7585
- ...props,
7586
- children: loadingContent
8077
+ size: 18,
8078
+ className: "transition-transform duration-300 group-hover:-translate-x-1"
7587
8079
  }
7588
- );
8080
+ )
7589
8081
  }
7590
8082
  );
7591
- LoadingBase.displayName = "LoadingBase";
7592
-
7593
- // src/components/ui/feedback/ModalBase.tsx
7594
- var React23 = __toESM(require("react"));
7595
- var DialogPrimitive2 = __toESM(require("@radix-ui/react-dialog"));
7596
- var import_react26 = require("@phosphor-icons/react");
7597
- var import_jsx_runtime40 = require("react/jsx-runtime");
7598
- var ModalBase = DialogPrimitive2.Root;
7599
- var ModalTriggerBase = DialogPrimitive2.Trigger;
7600
- var ModalPortalBase = DialogPrimitive2.Portal;
7601
- var ModalCloseBase = DialogPrimitive2.Close;
7602
- var ModalOverlayBase = React23.forwardRef(({ className, testid: dataTestId = "modal-overlay", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7603
- DialogPrimitive2.Overlay,
8083
+ var SettingsButton = ({
8084
+ disabled,
8085
+ onClick,
8086
+ testid = "button-settings",
8087
+ ...props
8088
+ }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8089
+ ButtonBase,
7604
8090
  {
7605
- ref,
8091
+ variant: "ghost",
8092
+ size: "icon",
8093
+ onClick,
8094
+ disabled,
8095
+ testid,
7606
8096
  className: cn(
7607
- "fixed inset-0 z-50 bg-black/60 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
7608
- className
8097
+ "transition-all duration-200 ease-in-out group",
8098
+ "hover:scale-105",
8099
+ "active:scale-95",
8100
+ "disabled:hover:scale-100"
7609
8101
  ),
7610
- "data-testid": dataTestId,
7611
- ...props
7612
- }
7613
- ));
7614
- ModalOverlayBase.displayName = DialogPrimitive2.Overlay.displayName;
7615
- var ModalContentBase = React23.forwardRef(
7616
- ({
7617
- className,
7618
- children,
7619
- testid: dataTestId = "modal-content",
7620
- size = "md",
7621
- centered = true,
7622
- backdropBlur = true,
7623
- ...props
7624
- }, ref) => {
7625
- const sizeClass = size === "sm" ? "max-w-md" : size === "lg" ? "max-w-4xl" : size === "full" ? "w-full max-w-[calc(100%-2rem)]" : "max-w-2xl";
7626
- const positionClass = centered ? "left-[50%] top-[50%] translate-x-[-50%] translate-y-[-50%]" : "left-[50%] top-20 translate-x-[-50%] translate-y-0 sm:translate-y-0";
7627
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(ModalPortalBase, { children: [
7628
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7629
- ModalOverlayBase,
7630
- {
7631
- className: cn("bg-black/40", backdropBlur ? "backdrop-blur-sm" : "")
7632
- }
7633
- ),
7634
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7635
- "style",
7636
- {
7637
- dangerouslySetInnerHTML: {
7638
- __html: `
7639
- @keyframes modal-fade-in { from { opacity: 0 } to { opacity: 1 } }
7640
- @keyframes modal-fade-out { from { opacity: 1 } to { opacity: 0 } }
7641
- @keyframes modal-scale-in { from { opacity: 0; transform: translate(-50%, -48%) scale(.98) } to { opacity:1; transform: translate(-50%, -50%) scale(1) } }
7642
- @keyframes modal-scale-out { from { opacity:1; transform: translate(-50%, -50%) scale(1) } to { opacity: 0; transform: translate(-50%, -48%) scale(.98) } }
7643
- @keyframes overlay-fade-in { from { opacity: 0 } to { opacity: 1 } }
7644
- @keyframes overlay-fade-out { from { opacity: 1 } to { opacity: 0 } }
7645
- .data-[state=open]\\:animate-modal-in { animation: modal-fade-in 220ms cubic-bezier(.16,.84,.24,1) both, modal-scale-in 220ms cubic-bezier(.16,.84,.24,1) both }
7646
- .data-[state=closed]\\:animate-modal-out { animation: modal-scale-out 160ms cubic-bezier(.16,.84,.24,1) both, modal-fade-out 160ms cubic-bezier(.16,.84,.24,1) both }
7647
- .data-[state=open]\\:animate-overlay-in { animation: overlay-fade-in 220ms cubic-bezier(.16,.84,.24,1) both }
7648
- .data-[state=closed]\\:animate-overlay-out { animation: overlay-fade-out 160ms cubic-bezier(.16,.84,.24,1) both }
7649
- `
7650
- }
7651
- }
7652
- ),
7653
- /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
7654
- DialogPrimitive2.Content,
7655
- {
7656
- ref,
7657
- className: cn(
7658
- "fixed z-50 grid w-full gap-4 border bg-background p-6 shadow-lg sm:rounded-lg max-h-[90dvh] overflow-auto",
7659
- "data-[state=open]:animate-modal-in data-[state=closed]:animate-modal-out",
7660
- positionClass,
7661
- sizeClass,
7662
- className
7663
- ),
7664
- "data-testid": dataTestId,
7665
- ...props,
7666
- children: [
7667
- children,
7668
- /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(DialogPrimitive2.Close, { className: "absolute right-3 top-3 sm:right-4 sm:top-4 rounded-md bg-muted/10 p-1.5 opacity-80 hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none z-10 hover:bg-muted/20 transition-colors", children: [
7669
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react26.XIcon, { className: "h-5 w-5 sm:h-4 sm:w-4 text-foreground" }),
7670
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "sr-only", children: "Close" })
7671
- ] })
7672
- ]
7673
- }
7674
- )
7675
- ] });
8102
+ ...props,
8103
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8104
+ import_react32.GearIcon,
8105
+ {
8106
+ size: 18,
8107
+ className: "transition-transform duration-500 group-hover:rotate-90"
8108
+ }
8109
+ )
7676
8110
  }
7677
8111
  );
7678
- ModalContentBase.displayName = DialogPrimitive2.Content.displayName;
7679
- var ModalHeaderBase = React23.forwardRef(({ className, testid: dataTestId = "modal-header", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7680
- "div",
8112
+ var NotificationButton = ({
8113
+ disabled,
8114
+ onClick,
8115
+ testid = "button-notification",
8116
+ ...props
8117
+ }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8118
+ ButtonBase,
7681
8119
  {
7682
- ref,
8120
+ variant: "ghost",
8121
+ size: "icon",
8122
+ onClick,
8123
+ disabled,
8124
+ testid,
7683
8125
  className: cn(
7684
- "flex flex-col space-y-1.5 text-center sm:text-left",
7685
- className
8126
+ "transition-all duration-200 ease-in-out group",
8127
+ "hover:scale-105",
8128
+ "active:scale-95",
8129
+ "disabled:hover:scale-100"
7686
8130
  ),
7687
- "data-testid": dataTestId,
7688
- ...props
8131
+ ...props,
8132
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8133
+ import_react32.BellIcon,
8134
+ {
8135
+ size: 18,
8136
+ className: "transition-transform duration-300 group-hover:scale-110 group-hover:-rotate-12"
8137
+ }
8138
+ )
7689
8139
  }
7690
- ));
7691
- ModalHeaderBase.displayName = "ModalHeader";
7692
- var ModalFooterBase = React23.forwardRef(({ className, testid: dataTestId = "modal-footer", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7693
- "div",
8140
+ );
8141
+ var MoreButton = ({
8142
+ disabled,
8143
+ onClick,
8144
+ testid = "button-more",
8145
+ ...props
8146
+ }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8147
+ ButtonBase,
7694
8148
  {
7695
- ref,
8149
+ variant: "ghost",
8150
+ size: "icon",
8151
+ onClick,
8152
+ disabled,
8153
+ testid,
7696
8154
  className: cn(
7697
- "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
7698
- className
8155
+ "transition-all duration-200 ease-in-out group",
8156
+ "hover:scale-105",
8157
+ "active:scale-95",
8158
+ "disabled:hover:scale-100"
7699
8159
  ),
7700
- "data-testid": dataTestId,
7701
- ...props
8160
+ ...props,
8161
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8162
+ import_react32.DotsThreeIcon,
8163
+ {
8164
+ size: 18,
8165
+ className: "transition-transform duration-200 group-hover:scale-110"
8166
+ }
8167
+ )
7702
8168
  }
7703
- ));
7704
- ModalFooterBase.displayName = "ModalFooter";
7705
- var ModalTitleBase = React23.forwardRef(({ className, testid: dataTestId = "modal-title", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7706
- DialogPrimitive2.Title,
8169
+ );
8170
+ var CheckButton = ({
8171
+ disabled,
8172
+ onClick,
8173
+ testid = "button-check",
8174
+ ...props
8175
+ }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8176
+ ButtonBase,
7707
8177
  {
7708
- ref,
8178
+ variant: "default",
8179
+ size: "icon",
8180
+ onClick,
8181
+ disabled,
8182
+ testid,
7709
8183
  className: cn(
7710
- "text-lg font-semibold leading-none tracking-tight",
7711
- className
8184
+ "transition-all duration-200 ease-in-out group",
8185
+ "hover:scale-110",
8186
+ "active:scale-95",
8187
+ "disabled:hover:scale-100"
7712
8188
  ),
7713
- "data-testid": dataTestId,
7714
- ...props
8189
+ ...props,
8190
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8191
+ import_react32.CheckIcon,
8192
+ {
8193
+ size: 18,
8194
+ className: "transition-transform duration-200 group-hover:scale-110"
8195
+ }
8196
+ )
7715
8197
  }
7716
- ));
7717
- ModalTitleBase.displayName = DialogPrimitive2.Title.displayName;
7718
- var ModalDescriptionBase = React23.forwardRef(({ className, testid: dataTestId = "modal-description", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7719
- DialogPrimitive2.Description,
8198
+ );
8199
+ var FilterButton = ({
8200
+ disabled,
8201
+ onClick,
8202
+ testid = "button-filter",
8203
+ active = false,
8204
+ className,
8205
+ iconSize = 18,
8206
+ iconColor,
8207
+ variant,
8208
+ size = "icon",
8209
+ ...props
8210
+ }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8211
+ ButtonBase,
7720
8212
  {
7721
- ref,
7722
- className: cn("text-sm text-muted-foreground", className),
7723
- "data-testid": dataTestId,
7724
- ...props
7725
- }
7726
- ));
7727
- ModalDescriptionBase.displayName = DialogPrimitive2.Description.displayName;
7728
-
7729
- // src/components/ui/feedback/ProgressBase.tsx
7730
- var React24 = __toESM(require("react"));
7731
- var ProgressPrimitive = __toESM(require("@radix-ui/react-progress"));
7732
- var import_jsx_runtime41 = require("react/jsx-runtime");
7733
- var ProgressBase = React24.forwardRef(
7734
- ({
7735
- className,
7736
- value: rawValue,
7737
- label,
7738
- leftIcon,
7739
- rightIcon,
7740
- variant = "bar",
7741
- segments = 5,
7742
- steps = [],
7743
- currentStep = 0,
7744
- showValue = false,
7745
- valuePosition = "right",
7746
- autocolor,
7747
- plusIndicator,
7748
- ...props
7749
- }, ref) => {
7750
- const value = Number(rawValue || 0);
7751
- const indicatorWidth = Math.min(value, 100);
7752
- switch (variant) {
7753
- case "segments":
7754
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
7755
- ProgressSegmentsBase,
7756
- {
7757
- label,
7758
- segments,
7759
- value: value || 0
7760
- }
7761
- );
7762
- case "panels":
7763
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
7764
- ProgressPanelsBase,
7765
- {
7766
- label,
7767
- steps,
7768
- currentStep
7769
- }
7770
- );
7771
- case "circles":
7772
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
7773
- ProgressCirclesBase,
7774
- {
7775
- label,
7776
- steps,
7777
- currentStep
7778
- }
7779
- );
7780
- case "bar":
7781
- default:
7782
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex flex-col gap-1 w-full min-w-[150px]", children: [
7783
- label && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(LabelBase_default, { className: "py-2", children: label }),
7784
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex items-center gap-2", children: [
7785
- showValue && valuePosition === "left" && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "w-12 text-sm text-right font-extrabold", children: [
7786
- Math.round(value || 0),
7787
- "%"
7788
- ] }),
7789
- leftIcon && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex items-center justify-center", children: leftIcon }),
7790
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
7791
- ProgressPrimitive.Root,
7792
- {
7793
- ref,
7794
- className: cn(
7795
- " relative h-3 w-full overflow-visible rounded-full bg-muted/80 shadow-inner transition-all ",
7796
- className
7797
- ),
7798
- value,
7799
- ...props,
7800
- children: [
7801
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
7802
- ProgressPrimitive.Indicator,
7803
- {
7804
- className: cn(
7805
- "h-full transition-all duration-500 ease-in-out rounded-lg",
7806
- // quando não usa autocolor, Indicator deve mostrar a cor primária
7807
- autocolor && autocolor.length >= 2 ? "bg-transparent" : "bg-primary"
7808
- ),
7809
- style: { width: `${indicatorWidth}%` }
7810
- }
7811
- ),
7812
- autocolor && Array.isArray(autocolor) && autocolor.length >= 2 && (() => {
7813
- const [t1Raw, t2Raw] = autocolor;
7814
- const [t1, t2] = [Number(t1Raw), Number(t2Raw)].sort(
7815
- (a, b) => a - b
7816
- );
7817
- const v = Number(value || 0);
7818
- let colorClass = "bg-red-500";
7819
- if (v <= t1) {
7820
- colorClass = "bg-red-500";
7821
- } else if (v <= t2) {
7822
- colorClass = "bg-yellow-500";
7823
- } else {
7824
- colorClass = "bg-emerald-500";
7825
- }
7826
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
7827
- "div",
7828
- {
7829
- "aria-hidden": true,
7830
- className: cn(
7831
- "absolute top-0 left-0 h-full transition-all duration-500 ease-in-out rounded-lg",
7832
- colorClass
7833
- ),
7834
- style: { width: `${indicatorWidth}%` }
7835
- }
7836
- );
7837
- })(),
7838
- plusIndicator && value > 100 && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
7839
- "div",
7840
- {
7841
- "aria-hidden": "true",
7842
- className: "absolute top-0 bottom-0 w-0.5 bg-black/70 transition-all duration-500 ease-in-out pointer-events-none",
7843
- style: { left: `100%` },
7844
- children: value > 115 && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "absolute left-full ml-2 top-1/2 -translate-y-1/2 text-xs whitespace-nowrap font-extrabold", children: `+${Math.round(
7845
- value - 100
7846
- )}%` })
7847
- }
7848
- ),
7849
- showValue && valuePosition === "inside" && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
7850
- "span",
7851
- {
7852
- className: "absolute inset-0 flex items-center justify-center text-sm select-none pointer-events-none text-secondary font-extrabold",
7853
- "aria-hidden": true,
7854
- children: [
7855
- Math.round(value || 0),
7856
- "%"
7857
- ]
7858
- }
7859
- )
7860
- ]
7861
- }
7862
- ),
7863
- showValue && valuePosition === "right" && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "w-12 text-sm font-extrabold text-left", children: [
7864
- Math.round(value || 0),
7865
- "%"
7866
- ] }),
7867
- rightIcon && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex items-center justify-center", children: rightIcon })
7868
- ] })
7869
- ] });
7870
- }
8213
+ variant: variant || (active ? "default" : "outline"),
8214
+ size,
8215
+ onClick,
8216
+ disabled,
8217
+ testid,
8218
+ className: cn(
8219
+ "transition-all duration-200 ease-in-out",
8220
+ "hover:scale-105",
8221
+ "active:scale-95",
8222
+ "disabled:hover:scale-100",
8223
+ className
8224
+ ),
8225
+ ...props,
8226
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8227
+ import_react32.FunnelIcon,
8228
+ {
8229
+ size: iconSize,
8230
+ color: iconColor,
8231
+ weight: active ? "fill" : "regular",
8232
+ className: "transition-all duration-200"
8233
+ }
8234
+ )
7871
8235
  }
7872
8236
  );
7873
- ProgressBase.displayName = "ProgressBase";
7874
- var ProgressSegmentsBase = ({
7875
- label,
7876
- segments,
7877
- value
7878
- }) => {
7879
- const filled = Math.round(value / 100 * segments);
7880
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex flex-col gap-1 w-full min-w-[150px]", children: [
7881
- label && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(LabelBase_default, { className: "py-2", children: label }),
7882
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex gap-1 w-full", children: Array.from({ length: segments }).map((_, idx) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
7883
- "div",
8237
+ var LikeButton = ({
8238
+ disabled,
8239
+ onClick,
8240
+ testid = "button-like",
8241
+ isLiked = false,
8242
+ className,
8243
+ iconSize = 18,
8244
+ iconColor,
8245
+ variant = "ghost",
8246
+ size = "icon",
8247
+ ...props
8248
+ }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8249
+ ButtonBase,
8250
+ {
8251
+ variant,
8252
+ size,
8253
+ onClick,
8254
+ disabled,
8255
+ testid,
8256
+ className: cn(
8257
+ "transition-all duration-200 ease-in-out group",
8258
+ "hover:scale-110",
8259
+ "active:scale-95",
8260
+ "disabled:hover:scale-100",
8261
+ !iconColor && (isLiked ? "text-red-500 dark:text-red-400 hover:text-red-600 dark:hover:text-red-300" : "hover:text-red-500 dark:hover:text-red-400"),
8262
+ className
8263
+ ),
8264
+ ...props,
8265
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8266
+ import_react32.HeartIcon,
7884
8267
  {
7885
- className: cn(
7886
- "h-2 flex-1 rounded-full transition-all duration-300",
7887
- idx < filled ? "bg-primary" : "bg-zinc-300 hover:bg-zinc-400"
7888
- )
7889
- },
7890
- idx
7891
- )) })
7892
- ] });
7893
- };
7894
- var ArrowRightIcon = () => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
7895
- "svg",
8268
+ size: iconSize,
8269
+ color: iconColor,
8270
+ weight: isLiked ? "fill" : "regular",
8271
+ className: "transition-all duration-300 group-hover:scale-110"
8272
+ }
8273
+ )
8274
+ }
8275
+ );
8276
+ var FavoriteButton = ({
8277
+ disabled,
8278
+ onClick,
8279
+ testid = "button-favorite",
8280
+ isFavorite = false,
8281
+ className,
8282
+ iconSize = 18,
8283
+ iconColor,
8284
+ variant = "ghost",
8285
+ size = "icon",
8286
+ ...props
8287
+ }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8288
+ ButtonBase,
7896
8289
  {
7897
- className: "w-6 h-6 text-zinc-400 transition-transform duration-300 group-hover:translate-x-1",
7898
- fill: "none",
7899
- stroke: "currentColor",
7900
- strokeWidth: 2,
7901
- viewBox: "0 0 24 24",
7902
- xmlns: "http://www.w3.org/2000/svg",
7903
- children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" })
8290
+ variant,
8291
+ size,
8292
+ onClick,
8293
+ disabled,
8294
+ testid,
8295
+ className: cn(
8296
+ "transition-all duration-200 ease-in-out group",
8297
+ "hover:scale-110",
8298
+ "active:scale-95",
8299
+ "disabled:hover:scale-100",
8300
+ !iconColor && (isFavorite ? "text-yellow-500 dark:text-yellow-400 hover:text-yellow-600 dark:hover:text-yellow-300" : "hover:text-yellow-500 dark:hover:text-yellow-400"),
8301
+ className
8302
+ ),
8303
+ ...props,
8304
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8305
+ import_react32.StarIcon,
8306
+ {
8307
+ size: iconSize,
8308
+ color: iconColor,
8309
+ weight: isFavorite ? "fill" : "regular",
8310
+ className: "transition-all duration-300 group-hover:rotate-12"
8311
+ }
8312
+ )
7904
8313
  }
7905
8314
  );
7906
- var ProgressPanelsBase = ({
7907
- label,
7908
- steps,
7909
- currentStep
7910
- }) => {
7911
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex flex-col gap-1 w-full", children: [
7912
- label && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(LabelBase_default, { className: "py-2", children: label }),
7913
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex w-full gap-1 rounded-lg overflow-hidden", children: steps.map((step, idx) => {
7914
- const isActive = idx === currentStep;
7915
- const isLast = idx === steps.length - 1;
7916
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(React24.Fragment, { children: [
7917
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
7918
- "div",
7919
- {
7920
- className: cn(
7921
- "relative flex items-center justify-center cursor-pointer select-none rounded-lg border transition-shadow duration-300 ease-in-out",
7922
- "hover:shadow-md hover:z-10",
7923
- "aspect-[5/1] min-w-[90px] px-4",
7924
- isActive ? "bg-primary/20 border-2 border-primary shadow-lg font-semibold" : "border-zinc-300"
7925
- ),
7926
- style: { flex: "1 1 0" },
7927
- children: [
7928
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "truncate", children: step }),
7929
- isActive && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "absolute bottom-0 left-0 h-1 w-full animate-pulse rounded-b-lg" })
7930
- ]
7931
- }
7932
- ),
7933
- !isLast && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex items-center px-2 group", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(ArrowRightIcon, {}) })
7934
- ] }, idx);
7935
- }) })
7936
- ] });
7937
- };
7938
- var ProgressCirclesBase = ({
7939
- label,
7940
- steps,
7941
- currentStep
7942
- }) => {
7943
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex flex-col gap-2 w-full", children: [
7944
- label && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("label", { className: "py-2 text-base font-semibold text-gray-700 dark:text-gray-300", children: label }),
7945
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "relative flex items-center justify-between w-full", children: [
7946
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "absolute top-5 left-0 w-full h-1 bg-zinc-200 dark:bg-zinc-700" }),
7947
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
7948
- "div",
7949
- {
7950
- className: "absolute top-5 left-0 h-1 bg-primary transition-all duration-300",
7951
- style: {
7952
- width: `${currentStep / (steps.length - 1) * 100}%`
7953
- }
7954
- }
7955
- ),
7956
- steps.map((step, idx) => {
7957
- const isActive = idx <= currentStep;
7958
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
7959
- "div",
7960
- {
7961
- className: "relative flex flex-col items-center w-10",
7962
- style: { zIndex: isActive ? 10 : 1 },
7963
- children: [
7964
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
7965
- "div",
7966
- {
7967
- className: cn(
7968
- "w-10 h-10 rounded-full flex items-center justify-center font-bold text-sm transition-all duration-300 cursor-pointer select-none",
7969
- isActive ? "bg-primary text-white dark:text-black shadow-md" : "bg-zinc-200 text-zinc-500 hover:bg-zinc-300 dark:bg-zinc-500 dark:text-black"
7970
- ),
7971
- children: idx + 1
7972
- }
7973
- ),
7974
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "text-xs text-center font-medium mt-1 max-w-[80px] break-words", children: step })
7975
- ]
7976
- },
7977
- idx
7978
- );
7979
- })
7980
- ] })
7981
- ] });
7982
- };
7983
-
7984
- // src/components/ui/feedback/SkeletonBase.tsx
7985
- var import_jsx_runtime42 = require("react/jsx-runtime");
7986
- function SkeletonBase({
8315
+ var VisibilityButton = ({
8316
+ disabled,
8317
+ onClick,
8318
+ testid = "button-visibility",
8319
+ isVisible = true,
7987
8320
  className,
8321
+ iconSize = 18,
8322
+ iconColor,
8323
+ variant = "ghost",
8324
+ size = "icon",
7988
8325
  ...props
7989
- }) {
7990
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: cn("animate-pulse bg-primary/10", className), ...props });
7991
- }
7992
-
7993
- // src/components/ui/feedback/SonnerBase.tsx
7994
- var import_react27 = require("@phosphor-icons/react");
7995
- var import_sonner2 = require("sonner");
7996
- var import_jsx_runtime43 = require("react/jsx-runtime");
7997
- var iconBaseClass = "w-5 h-auto";
7998
- var Toaster = ({ testId, ...props }) => {
7999
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
8000
- import_sonner2.Toaster,
8001
- {
8002
- className: "toaster group",
8003
- position: "top-center",
8004
- toastOptions: {
8005
- classNames: {
8006
- toast: `
8007
- group toast
8008
- bg-background
8009
- text-foreground
8010
- shadow-lg rounded-md
8011
- border-l-4
8012
- border-border
8013
- flex items-center gap-3
8014
- data-[type=success]:border-l-green-500 data-[type=success]:bg-green-50 data-[type=success]:text-green-800 data-[type=success]:border-green-500
8015
- data-[type=error]:border-l-red-500 data-[type=error]:bg-red-50 data-[type=error]:text-red-800 data-[type=error]:border-red-500
8016
- data-[type=WarningIcon]:border-l-yellow-500 data-[type=WarningIcon]:bg-yellow-50 data-[type=WarningIcon]:text-yellow-800 data-[type=WarningIcon]:border-yellow-500
8017
- data-[type=InfoIcon]:border-l-blue-500 data-[type=InfoIcon]:bg-blue-50 data-[type=InfoIcon]:text-blue-800 data-[type=InfoIcon]:border-blue-500
8018
- `,
8019
- description: `
8020
- text-sm
8021
- group-[.toast]:text-neutral-600
8022
- `,
8023
- actionButton: `
8024
- ml-auto
8025
- rounded-md px-3 py-1 text-sm font-semibold
8026
- bg-neutral-800 text-white
8027
- hover:bg-neutral-700
8028
- transition-colors duration-200
8029
- `,
8030
- cancelButton: `
8031
- ml-2
8032
- rounded-md px-3 py-1 text-sm font-semibold
8033
- bg-neutral-100 text-neutral-700
8034
- hover:bg-neutral-200
8035
- transition-colors duration-200
8036
- `
8037
- }
8038
- },
8039
- "data-testid": testId,
8040
- ...props
8041
- }
8042
- );
8043
- };
8044
- var toast2 = {
8045
- success: (message) => import_sonner2.toast.success(message, {
8046
- icon: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react27.CheckCircleIcon, { className: `${iconBaseClass} text-green-600`, weight: "fill" }),
8047
- className: "sonner-success"
8048
- }),
8049
- error: (message) => import_sonner2.toast.error(message, {
8050
- icon: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react27.XCircleIcon, { className: `${iconBaseClass} text-red-600`, weight: "fill" }),
8051
- className: "sonner-error"
8052
- }),
8053
- warning: (message) => import_sonner2.toast.warning(message, {
8054
- icon: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react27.WarningIcon, { className: `${iconBaseClass} text-yellow-600`, weight: "fill" }),
8055
- className: "sonner-WarningIcon"
8056
- }),
8057
- info: (message) => import_sonner2.toast.info(message, {
8058
- icon: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react27.InfoIcon, { className: `${iconBaseClass} text-blue-600`, weight: "fill" }),
8059
- className: "sonner-InfoIcon"
8060
- }),
8061
- loading: (message) => (0, import_sonner2.toast)(message, {
8062
- icon: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react27.SpinnerIcon, { className: `${iconBaseClass} animate-spin text-neutral-500`, weight: "fill" }),
8063
- className: "sonner-loading"
8064
- })
8065
- };
8066
-
8067
- // src/components/ui/form/CheckBoxBase.tsx
8068
- var React25 = __toESM(require("react"));
8069
- var CheckboxPrimitive = __toESM(require("@radix-ui/react-checkbox"));
8070
- var import_react28 = require("@phosphor-icons/react");
8071
- var import_framer_motion11 = require("framer-motion");
8072
- var import_jsx_runtime44 = require("react/jsx-runtime");
8073
- var CheckboxBase = React25.forwardRef(({ className, testid: dataTestId = "checkbox-base", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
8074
- CheckboxPrimitive.Root,
8326
+ }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8327
+ ButtonBase,
8075
8328
  {
8076
- ref,
8329
+ variant,
8330
+ size,
8331
+ onClick,
8332
+ disabled,
8333
+ testid,
8077
8334
  className: cn(
8078
- "peer h-4 w-4 shrink-0 rounded-md border border-primary shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground transition-colors",
8335
+ "transition-all duration-200 ease-in-out",
8336
+ "hover:scale-105",
8337
+ "active:scale-95",
8338
+ "disabled:hover:scale-100",
8079
8339
  className
8080
8340
  ),
8081
- "data-testid": dataTestId,
8082
8341
  ...props,
8083
- children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(CheckboxPrimitive.Indicator, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
8084
- import_framer_motion11.motion.div,
8342
+ children: isVisible ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8343
+ import_react32.EyeIcon,
8085
8344
  {
8086
- initial: { scale: 0, opacity: 0, rotate: -90 },
8087
- animate: { scale: 1, opacity: 1, rotate: 0 },
8088
- exit: { scale: 0, opacity: 0, rotate: 90 },
8089
- transition: { type: "spring", stiffness: 500, damping: 30 },
8090
- className: "flex items-center justify-center text-current",
8091
- children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react28.CheckIcon, { className: "h-4 w-4", weight: "bold" })
8345
+ size: iconSize,
8346
+ color: iconColor,
8347
+ className: "transition-opacity duration-200"
8092
8348
  }
8093
- ) })
8349
+ ) : /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8350
+ import_react32.EyeSlashIcon,
8351
+ {
8352
+ size: iconSize,
8353
+ color: iconColor,
8354
+ className: "transition-opacity duration-200"
8355
+ }
8356
+ )
8094
8357
  }
8095
- ));
8096
- CheckboxBase.displayName = CheckboxPrimitive.Root.displayName;
8097
-
8098
- // src/components/ui/form/CollapsibleBase.tsx
8099
- var React26 = __toESM(require("react"));
8100
- var CollapsiblePrimitive = __toESM(require("@radix-ui/react-collapsible"));
8101
- var import_react29 = require("@phosphor-icons/react");
8102
- var import_jsx_runtime45 = require("react/jsx-runtime");
8103
- var CollapsibleBase = React26.forwardRef(({ ...props }, ref) => {
8104
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(CollapsiblePrimitive.Root, { ref, "data-slot": "collapsible", ...props });
8105
- });
8106
- CollapsibleBase.displayName = CollapsiblePrimitive.Root.displayName;
8107
- var CollapsibleTriggerBase = React26.forwardRef(({ className, children, leftIcon, showCaret = true, ...props }, ref) => {
8108
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
8109
- CollapsiblePrimitive.CollapsibleTrigger,
8110
- {
8111
- ref,
8112
- className: cn(
8113
- "flex w-full items-center justify-between p-3 text-left font-medium transition-all duration-500 ease-[cubic-bezier(0.4,0,0.2,1)] hover:bg-accent hover:text-accent-foreground rounded-md outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 [&[data-state=open]_.caret-icon]:rotate-180",
8114
- className
8115
- ),
8116
- "data-slot": "collapsible-trigger",
8117
- ...props,
8118
- children: [
8119
- /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center gap-2", children: [
8120
- leftIcon && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "flex-shrink-0 [&>svg]:size-4", children: leftIcon }),
8121
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { children })
8122
- ] }),
8123
- showCaret && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "caret-icon flex-shrink-0 transition-transform duration-500 ease-[cubic-bezier(0.4,0,0.2,1)]", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react29.CaretUpDownIcon, { className: "h-4 w-4" }) })
8124
- ]
8125
- }
8126
- );
8127
- });
8128
- CollapsibleTriggerBase.displayName = CollapsiblePrimitive.CollapsibleTrigger.displayName;
8129
- var CollapsibleContentBase = React26.forwardRef(({ className, children, ...props }, ref) => {
8130
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
8131
- CollapsiblePrimitive.CollapsibleContent,
8132
- {
8133
- ref,
8134
- className: cn(
8135
- "overflow-hidden data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down",
8136
- className
8137
- ),
8138
- "data-slot": "collapsible-content",
8139
- ...props,
8140
- children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "pb-3 pt-1", children })
8141
- }
8142
- );
8143
- });
8144
- CollapsibleContentBase.displayName = CollapsiblePrimitive.CollapsibleContent.displayName;
8145
-
8146
- // src/components/ui/form/DebounceInput.tsx
8147
- var import_react30 = require("react");
8148
- var import_react31 = require("@phosphor-icons/react");
8149
- var import_jsx_runtime46 = require("react/jsx-runtime");
8150
-
8151
- // src/components/ui/form/HoverCardBase.tsx
8152
- var HoverCardPrimitive = __toESM(require("@radix-ui/react-hover-card"));
8153
- var import_jsx_runtime47 = require("react/jsx-runtime");
8154
- function HoverCardBase(props) {
8155
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(HoverCardPrimitive.Root, { ...props });
8156
- }
8157
- function HoverCardTriggerBase(props) {
8158
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(HoverCardPrimitive.Trigger, { ...props });
8159
- }
8160
- function HoverCardContentBase({
8161
- className,
8162
- align = "center",
8163
- sideOffset = 4,
8164
- ...props
8165
- }) {
8166
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(HoverCardPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
8167
- HoverCardPrimitive.Content,
8168
- {
8169
- align,
8170
- sideOffset,
8171
- className: cn(
8172
- "z-50 w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none",
8173
- "data-[state=open]:animate-in data-[state=closed]:animate-out",
8174
- "data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0",
8175
- "data-[state=open]:zoom-in-95 data-[state=closed]:zoom-out-95",
8176
- "data-[side=bottom]:slide-in-from-top-2",
8177
- "data-[side=left]:slide-in-from-right-2",
8178
- "data-[side=right]:slide-in-from-left-2",
8179
- "data-[side=top]:slide-in-from-bottom-2",
8180
- className
8181
- ),
8182
- ...props
8183
- }
8184
- ) });
8185
- }
8186
-
8187
- // src/components/ui/form/Input-OTP-Base.tsx
8188
- var React27 = __toESM(require("react"));
8189
- var import_input_otp = require("input-otp");
8190
- var import_react32 = require("@phosphor-icons/react");
8191
- var import_jsx_runtime48 = require("react/jsx-runtime");
8192
- function InputOTPBase({
8193
- className,
8194
- containerClassName,
8195
- ...props
8196
- }) {
8197
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
8198
- import_input_otp.OTPInput,
8199
- {
8200
- "data-slot": "input-otp",
8201
- containerClassName: cn(
8202
- "flex items-center gap-2 has-disabled:opacity-50",
8203
- containerClassName
8204
- ),
8205
- className: cn("disabled:cursor-not-allowed", className),
8206
- ...props
8207
- }
8208
- );
8209
- }
8210
- function InputOTPGroupBase({ className, ...props }) {
8211
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
8212
- "div",
8213
- {
8214
- "data-slot": "input-otp-group",
8215
- className: cn("flex items-center", className),
8216
- ...props
8217
- }
8218
- );
8219
- }
8220
- function InputOTPSlotBase({
8221
- index,
8358
+ );
8359
+ var ViewButton = (props) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(VisibilityButton, { isVisible: true, testid: "button-view", ...props });
8360
+ var HideButton = (props) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(VisibilityButton, { isVisible: false, testid: "button-hide", ...props });
8361
+ var LockButton = ({
8362
+ disabled,
8363
+ onClick,
8364
+ testid = "button-lock",
8365
+ isLocked = true,
8222
8366
  className,
8367
+ iconSize = 18,
8368
+ iconColor,
8369
+ variant = "ghost",
8370
+ size = "icon",
8223
8371
  ...props
8224
- }) {
8225
- const inputOTPContext = React27.useContext(import_input_otp.OTPInputContext);
8226
- const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {};
8227
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
8228
- "div",
8229
- {
8230
- "data-slot": "input-otp-slot",
8231
- "data-active": isActive,
8232
- className: cn(
8233
- "data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive dark:bg-input/30 border-input relative flex h-9 w-9 items-center justify-center border-y border-r text-sm shadow-xs transition-all outline-none first:rounded-l-md first:border-l last:rounded-r-md data-[active=true]:z-10 data-[active=true]:ring-[3px]",
8234
- className
8235
- ),
8236
- ...props,
8237
- children: [
8238
- char,
8239
- hasFakeCaret && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "pointer-events-none absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "animate-caret-blink bg-foreground h-4 w-px duration-1000" }) })
8240
- ]
8241
- }
8242
- );
8243
- }
8244
- function InputOTPSeparatorBase({ ...props }) {
8245
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { "data-slot": "input-otp-separator", role: "separator", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_react32.MinusIcon, {}) });
8246
- }
8247
-
8248
- // src/components/ui/form/SliderBase.tsx
8249
- var React28 = __toESM(require("react"));
8250
- var SliderPrimitive = __toESM(require("@radix-ui/react-slider"));
8251
- var import_jsx_runtime49 = require("react/jsx-runtime");
8252
- var SlideBase = React28.forwardRef(
8253
- ({
8254
- className,
8255
- orientation = "horizontal",
8256
- label,
8257
- leftIcon,
8258
- rightIcon,
8259
- ...props
8260
- }, ref) => {
8261
- const isVertical = orientation === "vertical";
8262
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
8263
- "div",
8372
+ }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8373
+ ButtonBase,
8374
+ {
8375
+ variant,
8376
+ size,
8377
+ onClick,
8378
+ disabled,
8379
+ testid,
8380
+ className: cn(
8381
+ "transition-all duration-200 ease-in-out group",
8382
+ "hover:scale-105",
8383
+ "active:scale-95",
8384
+ "disabled:hover:scale-100",
8385
+ !iconColor && (isLocked ? "text-red-500 dark:text-red-400 hover:text-red-600 dark:hover:text-red-300" : "text-emerald-500 dark:text-emerald-400 hover:text-emerald-600 dark:hover:text-emerald-300"),
8386
+ className
8387
+ ),
8388
+ ...props,
8389
+ children: isLocked ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8390
+ import_react32.LockIcon,
8264
8391
  {
8265
- className: cn("flex flex-col gap-1", isVertical ? "h-full " : "w-full"),
8266
- children: [
8267
- label && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(LabelBase_default, { className: "py-2", children: label }),
8268
- /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
8269
- "div",
8270
- {
8271
- className: cn(
8272
- "flex gap-2",
8273
- isVertical ? "flex-col h-full" : "flex-row items-center w-full"
8274
- ),
8275
- children: [
8276
- leftIcon && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "flex items-center justify-center", children: leftIcon }),
8277
- /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
8278
- SliderPrimitive.Root,
8279
- {
8280
- ref,
8281
- orientation,
8282
- className: cn(
8283
- "relative flex touch-none select-none items-center",
8284
- isVertical ? "flex-col h-full" : "flex-row w-full",
8285
- className
8286
- ),
8287
- ...props,
8288
- children: [
8289
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8290
- SliderPrimitive.Track,
8291
- {
8292
- className: cn(
8293
- "relative overflow-hidden bg-primary/20 rounded-full",
8294
- isVertical ? "w-1.5 h-full" : "h-1.5 w-full"
8295
- ),
8296
- children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8297
- SliderPrimitive.Range,
8298
- {
8299
- className: cn(
8300
- "absolute bg-primary",
8301
- isVertical ? "w-full" : "h-full"
8302
- )
8303
- }
8304
- )
8305
- }
8306
- ),
8307
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8308
- SliderPrimitive.Thumb,
8309
- {
8310
- className: cn(
8311
- "block h-4 w-4 rounded-full border border-primary/70 bg-background shadow-md transition-transform",
8312
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2",
8313
- "hover:scale-125 active:scale-125"
8314
- )
8315
- }
8316
- )
8317
- ]
8318
- }
8319
- ),
8320
- rightIcon && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "flex items-center justify-center", children: rightIcon })
8321
- ]
8322
- }
8323
- )
8324
- ]
8392
+ size: iconSize,
8393
+ color: iconColor,
8394
+ className: "transition-all duration-200 group-hover:scale-110"
8325
8395
  }
8326
- );
8396
+ ) : /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
8397
+ import_react32.LockOpenIcon,
8398
+ {
8399
+ size: iconSize,
8400
+ color: iconColor,
8401
+ className: "transition-all duration-200 group-hover:scale-110"
8402
+ }
8403
+ )
8327
8404
  }
8328
8405
  );
8329
- SlideBase.displayName = "SlideBase";
8406
+ var UnlockButton = (props) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(LockButton, { isLocked: false, testid: "button-unlock", ...props });
8330
8407
 
8331
8408
  // src/components/ui/form/SwitchBase.tsx
8332
8409
  var React29 = __toESM(require("react"));
@@ -10708,7 +10785,8 @@ function DateTimePicker({
10708
10785
  label,
10709
10786
  date,
10710
10787
  onChange,
10711
- display,
10788
+ displayFormat,
10789
+ hideTime,
10712
10790
  hideSeconds,
10713
10791
  hideHour,
10714
10792
  hideMinute,
@@ -10739,12 +10817,16 @@ function DateTimePicker({
10739
10817
  onChange(newDate);
10740
10818
  };
10741
10819
  const getTimeFormat = () => {
10820
+ if (hideTime) return "";
10742
10821
  if (hideHour && hideMinute) return "";
10743
10822
  if (hideHour) return hideSeconds ? "mm" : "mm:ss";
10744
10823
  if (hideMinute) return hideSeconds ? "HH" : "HH':00'";
10745
10824
  return hideSeconds ? "HH:mm" : "HH:mm:ss";
10746
10825
  };
10747
10826
  const getDisplayFormat = () => {
10827
+ if (displayFormat) {
10828
+ return displayFormat;
10829
+ }
10748
10830
  const timeFormat = getTimeFormat();
10749
10831
  if (!timeFormat) return "PPP";
10750
10832
  return `PPP - ${timeFormat}`;
@@ -10766,7 +10848,7 @@ function DateTimePicker({
10766
10848
  !date && "text-muted-foreground/"
10767
10849
  ),
10768
10850
  children: [
10769
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { className: "truncate flex-1", children: date ? display ? (0, import_date_fns.format)(date, "dd/MM/yyyy") : (0, import_date_fns.format)(date, getDisplayFormat(), { locale: import_locale.ptBR }) : "Selecione uma Data" }),
10851
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { className: "truncate flex-1", children: date ? (0, import_date_fns.format)(date, getDisplayFormat(), { locale: import_locale.ptBR }) : "Selecione uma data" }),
10770
10852
  /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(import_react44.CalendarBlankIcon, { className: "flex-shrink-0 w-5 h-5 sm:w-6 sm:h-6" })
10771
10853
  ]
10772
10854
  }
@@ -10792,10 +10874,13 @@ function DateTimePicker({
10792
10874
  initialFocus: true,
10793
10875
  fromDate,
10794
10876
  toDate,
10795
- className: cn("w-full", hideHour && hideMinute && "border-0")
10877
+ className: cn(
10878
+ "w-full",
10879
+ (hideTime || hideHour && hideMinute) && "border-0"
10880
+ )
10796
10881
  }
10797
10882
  ),
10798
- !(hideHour && hideMinute) && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: "flex justify-center w-full px-2", children: /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
10883
+ !hideTime && !(hideHour && hideMinute) && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: "flex justify-center w-full px-2", children: /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
10799
10884
  PopoverBase,
10800
10885
  {
10801
10886
  open: timePickerOpen,
@@ -11037,7 +11122,7 @@ function RangePicker({
11037
11122
  whileHover: { scale: 1.03 },
11038
11123
  whileTap: { scale: 0.95 },
11039
11124
  children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
11040
- DeleteButton,
11125
+ ButtonBase,
11041
11126
  {
11042
11127
  variant: "outline",
11043
11128
  onClick: handleClear,