@facter/ds-core 1.33.11 → 1.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -16,12 +16,11 @@ var DialogPrimitive = require('@radix-ui/react-dialog');
16
16
  var sonner = require('sonner');
17
17
  var SwitchPrimitives = require('@radix-ui/react-switch');
18
18
  var reactHookForm = require('react-hook-form');
19
- var reactDom = require('react-dom');
19
+ var TooltipPrimitive = require('@radix-ui/react-tooltip');
20
+ var PopoverPrimitive = require('@radix-ui/react-popover');
20
21
  var RadioGroupPrimitive = require('@radix-ui/react-radio-group');
21
22
  var AvatarPrimitive = require('@radix-ui/react-avatar');
22
23
  var DropdownMenuPrimitive = require('@radix-ui/react-dropdown-menu');
23
- var PopoverPrimitive = require('@radix-ui/react-popover');
24
- var TooltipPrimitive = require('@radix-ui/react-tooltip');
25
24
  var ScrollAreaPrimitive = require('@radix-ui/react-scroll-area');
26
25
  var SeparatorPrimitive = require('@radix-ui/react-separator');
27
26
  var reactSlot = require('@radix-ui/react-slot');
@@ -51,11 +50,11 @@ var TabsPrimitive__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive);
51
50
  var CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespace(CheckboxPrimitive);
52
51
  var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive);
53
52
  var SwitchPrimitives__namespace = /*#__PURE__*/_interopNamespace(SwitchPrimitives);
53
+ var TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespace(TooltipPrimitive);
54
+ var PopoverPrimitive__namespace = /*#__PURE__*/_interopNamespace(PopoverPrimitive);
54
55
  var RadioGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(RadioGroupPrimitive);
55
56
  var AvatarPrimitive__namespace = /*#__PURE__*/_interopNamespace(AvatarPrimitive);
56
57
  var DropdownMenuPrimitive__namespace = /*#__PURE__*/_interopNamespace(DropdownMenuPrimitive);
57
- var PopoverPrimitive__namespace = /*#__PURE__*/_interopNamespace(PopoverPrimitive);
58
- var TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespace(TooltipPrimitive);
59
58
  var ScrollAreaPrimitive__namespace = /*#__PURE__*/_interopNamespace(ScrollAreaPrimitive);
60
59
  var SeparatorPrimitive__namespace = /*#__PURE__*/_interopNamespace(SeparatorPrimitive);
61
60
 
@@ -197,6 +196,7 @@ var Input = React10__namespace.forwardRef(
197
196
  label,
198
197
  icon: Icon2,
199
198
  required,
199
+ labelSuffix,
200
200
  containerClassName,
201
201
  labelClassName,
202
202
  ...props
@@ -241,7 +241,7 @@ var Input = React10__namespace.forwardRef(
241
241
  "label",
242
242
  {
243
243
  className: cn(
244
- "absolute left-3 top-[-6px] text-xs font-medium bg-background px-1 cursor-pointer",
244
+ "absolute left-3 top-[-6px] text-xs font-medium bg-background px-1 cursor-pointer inline-flex items-center gap-1",
245
245
  error ? "text-red-500" : "text-foreground",
246
246
  Icon2 && "left-10",
247
247
  labelClassName
@@ -249,7 +249,8 @@ var Input = React10__namespace.forwardRef(
249
249
  onClick: focusInput,
250
250
  children: [
251
251
  label,
252
- required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500 ml-0.5", children: "*" })
252
+ required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500 ml-0.5", children: "*" }),
253
+ labelSuffix
253
254
  ]
254
255
  }
255
256
  ),
@@ -3257,238 +3258,487 @@ function FormFieldProvider({ name, children }) {
3257
3258
  );
3258
3259
  return /* @__PURE__ */ jsxRuntime.jsx(FormFieldContext.Provider, { value, children });
3259
3260
  }
3260
- function applyMask(value, mask) {
3261
- const digits = value.replace(/\D/g, "");
3262
- switch (mask) {
3263
- case "phone":
3264
- if (digits.length <= 10) {
3265
- return digits.replace(/(\d{2})(\d{4})(\d{0,4})/, "($1) $2-$3").trim();
3266
- }
3267
- return digits.replace(/(\d{2})(\d{5})(\d{0,4})/, "($1) $2-$3").trim();
3268
- case "cpf":
3269
- return digits.replace(/(\d{3})(\d)/, "$1.$2").replace(/(\d{3})(\d)/, "$1.$2").replace(/(\d{3})(\d{1,2})$/, "$1-$2");
3270
- case "cnpj":
3271
- return digits.replace(/(\d{2})(\d)/, "$1.$2").replace(/(\d{3})(\d)/, "$1.$2").replace(/(\d{3})(\d)/, "$1/$2").replace(/(\d{4})(\d{1,2})$/, "$1-$2");
3272
- case "cep":
3273
- return digits.replace(/(\d{5})(\d{0,3})/, "$1-$2");
3274
- case "money":
3275
- if (!digits) return "";
3276
- const cents = parseInt(digits, 10) / 100;
3277
- return new Intl.NumberFormat("pt-BR", {
3278
- style: "currency",
3279
- currency: "BRL"
3280
- }).format(cents);
3281
- case "percent":
3282
- if (!digits) return "";
3283
- const percent = parseInt(digits, 10) / 100;
3284
- return `${percent.toFixed(2)}%`;
3285
- case "plate":
3286
- const upper = value.toUpperCase().replace(/[^A-Z0-9]/g, "");
3287
- if (upper.length <= 3) return upper;
3288
- if (upper.length <= 7) {
3289
- return upper.replace(/([A-Z]{3})(\d{0,1})([A-Z0-9]{0,1})(\d{0,2})/, "$1-$2$3$4");
3290
- }
3291
- return upper.slice(0, 7).replace(/([A-Z]{3})(\d{0,1})([A-Z0-9]{0,1})(\d{0,2})/, "$1-$2$3$4");
3292
- case "date":
3293
- return digits.replace(/(\d{2})(\d)/, "$1/$2").replace(/(\d{2})(\d)/, "$1/$2").slice(0, 10);
3294
- case "time":
3295
- return digits.replace(/(\d{2})(\d{0,2})/, "$1:$2").slice(0, 5);
3296
- case "datetime":
3297
- const dateTime = digits.replace(/(\d{2})(\d)/, "$1/$2").replace(/(\d{2})(\d)/, "$1/$2").replace(/(\d{4})(\d)/, "$1 $2").replace(/(\d{2})(\d{0,2})$/, "$1:$2");
3298
- return dateTime.slice(0, 16);
3299
- default:
3300
- return value;
3301
- }
3302
- }
3303
- function getMaxLength(mask) {
3304
- switch (mask) {
3305
- case "phone":
3306
- return 15;
3307
- case "cpf":
3308
- return 14;
3309
- case "cnpj":
3310
- return 18;
3311
- case "cep":
3312
- return 9;
3313
- case "plate":
3314
- return 8;
3315
- case "date":
3316
- return 10;
3317
- case "time":
3318
- return 5;
3319
- case "datetime":
3320
- return 16;
3321
- default:
3322
- return void 0;
3323
- }
3324
- }
3325
- function parseValue(displayValue, mask) {
3326
- if (!displayValue) return void 0;
3327
- switch (mask) {
3328
- case "money":
3329
- const moneyDigits = displayValue.replace(/\D/g, "");
3330
- return moneyDigits ? parseInt(moneyDigits, 10) / 100 : void 0;
3331
- case "percent":
3332
- const percentDigits = displayValue.replace(/\D/g, "");
3333
- return percentDigits ? parseInt(percentDigits, 10) / 100 : void 0;
3334
- default:
3335
- return displayValue || void 0;
3261
+ var TooltipProvider = TooltipPrimitive__namespace.Provider;
3262
+ var TooltipRoot = TooltipPrimitive__namespace.Root;
3263
+ var TooltipTrigger = TooltipPrimitive__namespace.Trigger;
3264
+ var TooltipPortal = TooltipPrimitive__namespace.Portal;
3265
+ var TooltipArrow = React10__namespace.forwardRef(({ className, variant = "light", ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
3266
+ TooltipPrimitive__namespace.Arrow,
3267
+ {
3268
+ ref,
3269
+ className: cn(
3270
+ "z-50",
3271
+ variant === "dark" ? "fill-popover" : "fill-background",
3272
+ className
3273
+ ),
3274
+ ...props
3336
3275
  }
3337
- }
3338
- function FormInput({
3339
- name,
3340
- label,
3341
- description,
3342
- required,
3343
- disabled,
3344
- className,
3345
- mask,
3346
- icon,
3347
- showPasswordToggle = true,
3348
- inputSize = "default",
3349
- hideError = false,
3350
- type = "text",
3351
- maxLength,
3352
- ...inputProps
3353
- }) {
3354
- const form = reactHookForm.useFormContext();
3355
- const fieldState = form.getFieldState(name, form.formState);
3356
- const error = fieldState.error?.message;
3357
- const getInputType = React10__namespace.useCallback(() => {
3358
- if (["money", "percent", "phone", "cpf", "cnpj", "cep"].includes(mask || "")) {
3359
- return "tel";
3360
- }
3361
- return type;
3362
- }, [mask, type]);
3363
- return /* @__PURE__ */ jsxRuntime.jsx(FormFieldProvider, { name, children: /* @__PURE__ */ jsxRuntime.jsx(
3364
- reactHookForm.Controller,
3365
- {
3366
- control: form.control,
3367
- name,
3368
- render: ({ field }) => {
3369
- const getDisplayValue = () => {
3370
- if (field.value === void 0 || field.value === null) return "";
3371
- if (mask) {
3372
- return applyMask(String(field.value), mask);
3373
- }
3374
- return String(field.value);
3375
- };
3376
- const handleChange = (e) => {
3377
- let newValue = e.target.value;
3378
- if (mask) {
3379
- newValue = applyMask(newValue, mask);
3380
- const parsed = parseValue(newValue, mask);
3381
- field.onChange(parsed);
3382
- } else {
3383
- field.onChange(newValue || void 0);
3384
- }
3385
- };
3386
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-1", className), children: [
3387
- /* @__PURE__ */ jsxRuntime.jsx(
3388
- Input,
3389
- {
3390
- ...inputProps,
3391
- ref: field.ref,
3392
- name: field.name,
3393
- value: getDisplayValue(),
3394
- onChange: handleChange,
3395
- onBlur: field.onBlur,
3396
- disabled,
3397
- type: getInputType(),
3398
- label,
3399
- required,
3400
- error: !!error,
3401
- icon,
3402
- inputSize,
3403
- maxLength: maxLength ?? getMaxLength(mask)
3404
- }
3405
- ),
3406
- description && !error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground px-1", children: description }),
3407
- !hideError && error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-red-500 px-1", children: error })
3408
- ] });
3276
+ ));
3277
+ TooltipArrow.displayName = "TooltipArrow";
3278
+ var tooltipContentVariants = classVarianceAuthority.cva(
3279
+ "z-50 overflow-hidden rounded-lg shadow-lg outline-none animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
3280
+ {
3281
+ variants: {
3282
+ variant: {
3283
+ light: "bg-background text-foreground border border-border",
3284
+ dark: "bg-popover text-popover-foreground border border-border"
3285
+ },
3286
+ size: {
3287
+ sm: "max-w-[200px] p-2",
3288
+ md: "max-w-[280px] p-3",
3289
+ lg: "max-w-[360px] p-4"
3409
3290
  }
3291
+ },
3292
+ defaultVariants: {
3293
+ variant: "light",
3294
+ size: "md"
3410
3295
  }
3411
- ) });
3412
- }
3413
- FormInput.displayName = "Form.Input";
3414
- function FormSelect({
3415
- name,
3416
- label,
3417
- description,
3418
- required,
3419
- disabled,
3420
- className,
3421
- options,
3422
- placeholder = "Selecione...",
3423
- icon,
3424
- hideError = false,
3425
- selectSize = "default",
3426
- emptyText = "Nenhuma op\xE7\xE3o dispon\xEDvel",
3427
- loading = false,
3428
- variant = "default",
3429
- searchable = false,
3430
- onSearch,
3431
- onLoadMore,
3432
- hasMore,
3433
- searchPlaceholder = "Buscar..."
3434
- }) {
3435
- const form = reactHookForm.useFormContext();
3436
- const fieldState = form.getFieldState(name, form.formState);
3437
- const error = fieldState.error?.message;
3438
- return /* @__PURE__ */ jsxRuntime.jsx(FormFieldProvider, { name, children: /* @__PURE__ */ jsxRuntime.jsx(
3439
- reactHookForm.Controller,
3296
+ }
3297
+ );
3298
+ var TooltipContent = React10__namespace.forwardRef(
3299
+ ({
3300
+ className,
3301
+ variant = "light",
3302
+ size = "md",
3303
+ sideOffset = 8,
3304
+ showArrow = true,
3305
+ onDismiss,
3306
+ children,
3307
+ ...props
3308
+ }, ref) => /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs(
3309
+ TooltipPrimitive__namespace.Content,
3440
3310
  {
3441
- control: form.control,
3442
- name,
3443
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-1", className), children: [
3444
- variant === "card" ? /* @__PURE__ */ jsxRuntime.jsx(
3445
- CardSelect,
3311
+ ref,
3312
+ sideOffset,
3313
+ className: cn(tooltipContentVariants({ variant, size }), className),
3314
+ ...props,
3315
+ children: [
3316
+ onDismiss && /* @__PURE__ */ jsxRuntime.jsx(
3317
+ "button",
3446
3318
  {
3447
- options,
3448
- value: field.value,
3449
- onChange: (v) => field.onChange(v || void 0),
3450
- disabled,
3451
- label,
3452
- required,
3453
- error: !!error,
3454
- placeholder,
3455
- searchable,
3456
- onSearch,
3457
- onLoadMore,
3458
- hasMore,
3459
- loading,
3460
- emptyText,
3461
- searchPlaceholder
3319
+ onClick: onDismiss,
3320
+ className: "absolute top-2 right-2 p-1 rounded-full transition-colors hover:bg-muted text-muted-foreground hover:text-foreground",
3321
+ "aria-label": "Fechar",
3322
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-3.5 w-3.5" })
3462
3323
  }
3463
- ) : /* @__PURE__ */ jsxRuntime.jsx(
3464
- Select,
3324
+ ),
3325
+ children,
3326
+ showArrow && /* @__PURE__ */ jsxRuntime.jsx(TooltipArrow, { variant: variant ?? "light", width: 12, height: 6 })
3327
+ ]
3328
+ }
3329
+ ) })
3330
+ );
3331
+ TooltipContent.displayName = TooltipPrimitive__namespace.Content.displayName;
3332
+ var TooltipHeader = React10__namespace.forwardRef(
3333
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("flex flex-col gap-1", className), ...props })
3334
+ );
3335
+ TooltipHeader.displayName = "TooltipHeader";
3336
+ var TooltipTitle = React10__namespace.forwardRef(
3337
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
3338
+ "h4",
3339
+ {
3340
+ ref,
3341
+ className: cn("text-sm font-semibold leading-tight", className),
3342
+ ...props
3343
+ }
3344
+ )
3345
+ );
3346
+ TooltipTitle.displayName = "TooltipTitle";
3347
+ var TooltipDescription = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
3348
+ "p",
3349
+ {
3350
+ ref,
3351
+ className: cn("text-xs leading-relaxed text-muted-foreground", className),
3352
+ ...props
3353
+ }
3354
+ ));
3355
+ TooltipDescription.displayName = "TooltipDescription";
3356
+ var TooltipActions = React10__namespace.forwardRef(
3357
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
3358
+ "div",
3359
+ {
3360
+ ref,
3361
+ className: cn("flex items-center gap-2 mt-3", className),
3362
+ ...props
3363
+ }
3364
+ )
3365
+ );
3366
+ TooltipActions.displayName = "TooltipActions";
3367
+ var tooltipActionVariants = classVarianceAuthority.cva(
3368
+ "inline-flex items-center justify-center text-xs font-medium rounded-md transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
3369
+ {
3370
+ variants: {
3371
+ variant: {
3372
+ primary: "bg-primary text-primary-foreground hover:bg-primary/90 px-3 py-1.5",
3373
+ secondary: "bg-transparent text-muted-foreground hover:text-foreground hover:underline px-2 py-1.5",
3374
+ outline: "border border-border bg-background text-foreground hover:bg-muted px-3 py-1.5"
3375
+ }
3376
+ },
3377
+ defaultVariants: {
3378
+ variant: "primary"
3379
+ }
3380
+ }
3381
+ );
3382
+ var TooltipAction = React10__namespace.forwardRef(
3383
+ ({ className, variant = "primary", ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
3384
+ "button",
3385
+ {
3386
+ ref,
3387
+ className: cn(tooltipActionVariants({ variant }), className),
3388
+ ...props
3389
+ }
3390
+ )
3391
+ );
3392
+ TooltipAction.displayName = "TooltipAction";
3393
+ var TooltipIcon = React10__namespace.forwardRef(
3394
+ ({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
3395
+ "div",
3396
+ {
3397
+ ref,
3398
+ className: cn(
3399
+ "flex items-center justify-center w-10 h-10 rounded-full mb-3 bg-muted",
3400
+ className
3401
+ ),
3402
+ ...props,
3403
+ children
3404
+ }
3405
+ )
3406
+ );
3407
+ TooltipIcon.displayName = "TooltipIcon";
3408
+ var SimpleTooltip = ({
3409
+ children,
3410
+ content,
3411
+ variant = "light",
3412
+ side = "top",
3413
+ align = "center",
3414
+ delayDuration = 200,
3415
+ open,
3416
+ defaultOpen,
3417
+ onOpenChange
3418
+ }) => /* @__PURE__ */ jsxRuntime.jsxs(
3419
+ TooltipRoot,
3420
+ {
3421
+ open,
3422
+ defaultOpen,
3423
+ onOpenChange,
3424
+ delayDuration,
3425
+ children: [
3426
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children }),
3427
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { variant, side, align, size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs", children: content }) })
3428
+ ]
3429
+ }
3430
+ );
3431
+ SimpleTooltip.displayName = "SimpleTooltip";
3432
+ var Tooltip = Object.assign(TooltipRoot, {
3433
+ Provider: TooltipProvider,
3434
+ Trigger: TooltipTrigger,
3435
+ Portal: TooltipPortal,
3436
+ Content: TooltipContent,
3437
+ Arrow: TooltipArrow,
3438
+ Header: TooltipHeader,
3439
+ Title: TooltipTitle,
3440
+ Description: TooltipDescription,
3441
+ Actions: TooltipActions,
3442
+ Action: TooltipAction,
3443
+ Icon: TooltipIcon,
3444
+ Simple: SimpleTooltip
3445
+ });
3446
+ var FormLabel = React10__namespace.forwardRef(
3447
+ ({ className, required, children, ...props }, ref) => {
3448
+ const fieldContext = useFormFieldContextOptional();
3449
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3450
+ "label",
3451
+ {
3452
+ ref,
3453
+ htmlFor: fieldContext?.id,
3454
+ className: cn(
3455
+ "text-sm font-medium leading-none",
3456
+ fieldContext?.error && "text-red-500",
3457
+ className
3458
+ ),
3459
+ ...props,
3460
+ children: [
3461
+ children,
3462
+ (required || fieldContext?.isRequired) && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500 ml-0.5", children: "*" })
3463
+ ]
3464
+ }
3465
+ );
3466
+ }
3467
+ );
3468
+ FormLabel.displayName = "Form.Label";
3469
+ var FormDescription = React10__namespace.forwardRef(({ className, ...props }, ref) => {
3470
+ const fieldContext = useFormFieldContextOptional();
3471
+ if (fieldContext?.error) {
3472
+ return null;
3473
+ }
3474
+ return /* @__PURE__ */ jsxRuntime.jsx(
3475
+ "p",
3476
+ {
3477
+ ref,
3478
+ className: cn("text-xs text-muted-foreground", className),
3479
+ ...props
3480
+ }
3481
+ );
3482
+ });
3483
+ FormDescription.displayName = "Form.Description";
3484
+ var FormError = React10__namespace.forwardRef(
3485
+ ({ className, message, children, ...props }, ref) => {
3486
+ const fieldContext = useFormFieldContextOptional();
3487
+ const errorMessage = message ?? fieldContext?.error;
3488
+ if (!errorMessage && !children) {
3489
+ return null;
3490
+ }
3491
+ return /* @__PURE__ */ jsxRuntime.jsx(
3492
+ "p",
3493
+ {
3494
+ ref,
3495
+ className: cn("text-xs text-red-500", className),
3496
+ ...props,
3497
+ children: children || errorMessage
3498
+ }
3499
+ );
3500
+ }
3501
+ );
3502
+ FormError.displayName = "Form.Error";
3503
+ var FormFieldWrapper = React10__namespace.forwardRef(({ className, label, description, required, error, children, ...props }, ref) => {
3504
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: cn("space-y-1", className), ...props, children: [
3505
+ label && /* @__PURE__ */ jsxRuntime.jsx(FormLabel, { required, children: label }),
3506
+ children,
3507
+ description && /* @__PURE__ */ jsxRuntime.jsx(FormDescription, { children: description }),
3508
+ error && /* @__PURE__ */ jsxRuntime.jsx(FormError, { message: error })
3509
+ ] });
3510
+ });
3511
+ FormFieldWrapper.displayName = "Form.FieldWrapper";
3512
+ function FieldTooltipIcon({ tooltip }) {
3513
+ return /* @__PURE__ */ jsxRuntime.jsxs(TooltipRoot, { delayDuration: 200, children: [
3514
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Info, { className: "h-3 w-3 text-primary cursor-help shrink-0" }) }),
3515
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", size: "md", children: typeof tooltip === "string" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs", children: tooltip }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-0.5", children: [
3516
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-semibold leading-snug", children: tooltip.title }),
3517
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground leading-snug", children: tooltip.description })
3518
+ ] }) })
3519
+ ] });
3520
+ }
3521
+ function applyMask(value, mask) {
3522
+ const digits = value.replace(/\D/g, "");
3523
+ switch (mask) {
3524
+ case "phone":
3525
+ if (digits.length <= 10) {
3526
+ return digits.replace(/(\d{2})(\d{4})(\d{0,4})/, "($1) $2-$3").trim();
3527
+ }
3528
+ return digits.replace(/(\d{2})(\d{5})(\d{0,4})/, "($1) $2-$3").trim();
3529
+ case "cpf":
3530
+ return digits.replace(/(\d{3})(\d)/, "$1.$2").replace(/(\d{3})(\d)/, "$1.$2").replace(/(\d{3})(\d{1,2})$/, "$1-$2");
3531
+ case "cnpj":
3532
+ return digits.replace(/(\d{2})(\d)/, "$1.$2").replace(/(\d{3})(\d)/, "$1.$2").replace(/(\d{3})(\d)/, "$1/$2").replace(/(\d{4})(\d{1,2})$/, "$1-$2");
3533
+ case "cep":
3534
+ return digits.replace(/(\d{5})(\d{0,3})/, "$1-$2");
3535
+ case "money":
3536
+ if (!digits) return "";
3537
+ const cents = parseInt(digits, 10) / 100;
3538
+ return new Intl.NumberFormat("pt-BR", {
3539
+ style: "currency",
3540
+ currency: "BRL"
3541
+ }).format(cents);
3542
+ case "percent":
3543
+ if (!digits) return "";
3544
+ const percent = parseInt(digits, 10) / 100;
3545
+ return `${percent.toFixed(2)}%`;
3546
+ case "plate":
3547
+ const upper = value.toUpperCase().replace(/[^A-Z0-9]/g, "");
3548
+ if (upper.length <= 3) return upper;
3549
+ if (upper.length <= 7) {
3550
+ return upper.replace(/([A-Z]{3})(\d{0,1})([A-Z0-9]{0,1})(\d{0,2})/, "$1-$2$3$4");
3551
+ }
3552
+ return upper.slice(0, 7).replace(/([A-Z]{3})(\d{0,1})([A-Z0-9]{0,1})(\d{0,2})/, "$1-$2$3$4");
3553
+ case "date":
3554
+ return digits.replace(/(\d{2})(\d)/, "$1/$2").replace(/(\d{2})(\d)/, "$1/$2").slice(0, 10);
3555
+ case "time":
3556
+ return digits.replace(/(\d{2})(\d{0,2})/, "$1:$2").slice(0, 5);
3557
+ case "datetime":
3558
+ const dateTime = digits.replace(/(\d{2})(\d)/, "$1/$2").replace(/(\d{2})(\d)/, "$1/$2").replace(/(\d{4})(\d)/, "$1 $2").replace(/(\d{2})(\d{0,2})$/, "$1:$2");
3559
+ return dateTime.slice(0, 16);
3560
+ default:
3561
+ return value;
3562
+ }
3563
+ }
3564
+ function getMaxLength(mask) {
3565
+ switch (mask) {
3566
+ case "phone":
3567
+ return 15;
3568
+ case "cpf":
3569
+ return 14;
3570
+ case "cnpj":
3571
+ return 18;
3572
+ case "cep":
3573
+ return 9;
3574
+ case "plate":
3575
+ return 8;
3576
+ case "date":
3577
+ return 10;
3578
+ case "time":
3579
+ return 5;
3580
+ case "datetime":
3581
+ return 16;
3582
+ default:
3583
+ return void 0;
3584
+ }
3585
+ }
3586
+ function parseValue(displayValue, mask) {
3587
+ if (!displayValue) return void 0;
3588
+ switch (mask) {
3589
+ case "money":
3590
+ const moneyDigits = displayValue.replace(/\D/g, "");
3591
+ return moneyDigits ? parseInt(moneyDigits, 10) / 100 : void 0;
3592
+ case "percent":
3593
+ const percentDigits = displayValue.replace(/\D/g, "");
3594
+ return percentDigits ? parseInt(percentDigits, 10) / 100 : void 0;
3595
+ default:
3596
+ return displayValue || void 0;
3597
+ }
3598
+ }
3599
+ function FormInput({
3600
+ name,
3601
+ label,
3602
+ description,
3603
+ tooltip,
3604
+ required,
3605
+ disabled,
3606
+ className,
3607
+ mask,
3608
+ icon,
3609
+ showPasswordToggle = true,
3610
+ inputSize = "default",
3611
+ hideError = false,
3612
+ type = "text",
3613
+ maxLength,
3614
+ ...inputProps
3615
+ }) {
3616
+ const form = reactHookForm.useFormContext();
3617
+ const fieldState = form.getFieldState(name, form.formState);
3618
+ const error = fieldState.error?.message;
3619
+ const getInputType = React10__namespace.useCallback(() => {
3620
+ if (["money", "percent", "phone", "cpf", "cnpj", "cep"].includes(mask || "")) {
3621
+ return "tel";
3622
+ }
3623
+ return type;
3624
+ }, [mask, type]);
3625
+ return /* @__PURE__ */ jsxRuntime.jsx(FormFieldProvider, { name, children: /* @__PURE__ */ jsxRuntime.jsx(
3626
+ reactHookForm.Controller,
3627
+ {
3628
+ control: form.control,
3629
+ name,
3630
+ render: ({ field }) => {
3631
+ const getDisplayValue = () => {
3632
+ if (field.value === void 0 || field.value === null) return "";
3633
+ if (mask) {
3634
+ return applyMask(String(field.value), mask);
3635
+ }
3636
+ return String(field.value);
3637
+ };
3638
+ const handleChange = (e) => {
3639
+ let newValue = e.target.value;
3640
+ if (mask) {
3641
+ newValue = applyMask(newValue, mask);
3642
+ const parsed = parseValue(newValue, mask);
3643
+ field.onChange(parsed);
3644
+ } else {
3645
+ field.onChange(newValue || void 0);
3646
+ }
3647
+ };
3648
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-1", className), children: [
3649
+ /* @__PURE__ */ jsxRuntime.jsx(
3650
+ Input,
3651
+ {
3652
+ ...inputProps,
3653
+ ref: field.ref,
3654
+ name: field.name,
3655
+ value: getDisplayValue(),
3656
+ onChange: handleChange,
3657
+ onBlur: field.onBlur,
3658
+ disabled,
3659
+ type: getInputType(),
3660
+ label,
3661
+ required,
3662
+ error: !!error,
3663
+ icon,
3664
+ inputSize,
3665
+ maxLength: maxLength ?? getMaxLength(mask),
3666
+ labelSuffix: tooltip ? /* @__PURE__ */ jsxRuntime.jsx(FieldTooltipIcon, { tooltip }) : void 0
3667
+ }
3668
+ ),
3669
+ description && !error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground px-1", children: description }),
3670
+ !hideError && error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-red-500 px-1", children: error })
3671
+ ] });
3672
+ }
3673
+ }
3674
+ ) });
3675
+ }
3676
+ FormInput.displayName = "Form.Input";
3677
+ var Popover = PopoverPrimitive__namespace.Root;
3678
+ var PopoverTrigger = PopoverPrimitive__namespace.Trigger;
3679
+ var PopoverContent = React10__namespace.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
3680
+ PopoverPrimitive__namespace.Content,
3681
+ {
3682
+ ref,
3683
+ align,
3684
+ sideOffset,
3685
+ className: cn(
3686
+ "z-50 w-auto rounded-md border bg-popover p-4 text-popover-foreground shadow-lg outline-none 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-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
3687
+ className
3688
+ ),
3689
+ ...props
3690
+ }
3691
+ ) }));
3692
+ PopoverContent.displayName = PopoverPrimitive__namespace.Content.displayName;
3693
+ function FormSelect({
3694
+ name,
3695
+ label,
3696
+ description,
3697
+ tooltip,
3698
+ required,
3699
+ disabled,
3700
+ className,
3701
+ options,
3702
+ placeholder = "Selecione...",
3703
+ hideError = false,
3704
+ emptyText = "Nenhuma op\xE7\xE3o dispon\xEDvel",
3705
+ loading = false,
3706
+ searchable = false,
3707
+ onSearch,
3708
+ onLoadMore,
3709
+ hasMore,
3710
+ searchPlaceholder = "Buscar...",
3711
+ dropdownPosition = "bottom"
3712
+ }) {
3713
+ const form = reactHookForm.useFormContext();
3714
+ const fieldState = form.getFieldState(name, form.formState);
3715
+ const error = fieldState.error?.message;
3716
+ return /* @__PURE__ */ jsxRuntime.jsx(FormFieldProvider, { name, children: /* @__PURE__ */ jsxRuntime.jsx(
3717
+ reactHookForm.Controller,
3718
+ {
3719
+ control: form.control,
3720
+ name,
3721
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-1", className), children: [
3722
+ /* @__PURE__ */ jsxRuntime.jsx(
3723
+ SelectDropdown,
3465
3724
  {
3466
- value: field.value ?? "",
3467
- onValueChange: (value) => {
3468
- field.onChange(value || void 0);
3469
- },
3470
- disabled: disabled || loading,
3725
+ options,
3726
+ value: field.value,
3727
+ onChange: (v) => field.onChange(v || void 0),
3728
+ disabled,
3471
3729
  label,
3730
+ tooltip,
3472
3731
  required,
3473
3732
  error: !!error,
3474
- icon,
3475
- selectSize,
3476
3733
  placeholder,
3477
- children: loading ? /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "__loading__", disabled: true, children: "Carregando..." }) : options.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "__empty__", disabled: true, children: emptyText }) : options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
3478
- SelectItem,
3479
- {
3480
- value: option.value,
3481
- disabled: option.disabled,
3482
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
3483
- option.icon && /* @__PURE__ */ jsxRuntime.jsx(option.icon, { className: "h-4 w-4 text-muted-foreground" }),
3484
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3485
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: option.label }),
3486
- option.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground ml-2", children: option.description })
3487
- ] })
3488
- ] })
3489
- },
3490
- option.value
3491
- ))
3734
+ searchable,
3735
+ onSearch,
3736
+ onLoadMore,
3737
+ hasMore,
3738
+ loading,
3739
+ emptyText,
3740
+ searchPlaceholder,
3741
+ dropdownPosition
3492
3742
  }
3493
3743
  ),
3494
3744
  description && !error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground px-1", children: description }),
@@ -3497,229 +3747,550 @@ function FormSelect({
3497
3747
  }
3498
3748
  ) });
3499
3749
  }
3500
- FormSelect.displayName = "Form.Select";
3501
- function CardSelect({
3750
+ FormSelect.displayName = "Form.Select";
3751
+ function SelectDropdown({
3752
+ options,
3753
+ value,
3754
+ onChange,
3755
+ disabled,
3756
+ label,
3757
+ tooltip,
3758
+ required,
3759
+ error,
3760
+ placeholder = "Selecione...",
3761
+ searchable,
3762
+ onSearch,
3763
+ onLoadMore,
3764
+ hasMore,
3765
+ loading,
3766
+ emptyText = "Nenhuma op\xE7\xE3o dispon\xEDvel",
3767
+ searchPlaceholder = "Buscar...",
3768
+ dropdownPosition = "bottom"
3769
+ }) {
3770
+ const [open, setOpen] = React10__namespace.useState(false);
3771
+ const [search, setSearch] = React10__namespace.useState("");
3772
+ const selected = options.find((o) => o.value === value);
3773
+ const contentRef = React10__namespace.useRef(null);
3774
+ const listRef = React10__namespace.useRef(null);
3775
+ const searchRef = React10__namespace.useRef(null);
3776
+ const filteredOptions = React10__namespace.useMemo(() => {
3777
+ if (!searchable || onSearch || !search) return options;
3778
+ const q = search.toLowerCase();
3779
+ return options.filter(
3780
+ (o) => o.label.toLowerCase().includes(q) || o.description?.toLowerCase().includes(q)
3781
+ );
3782
+ }, [options, search, searchable, onSearch]);
3783
+ const handleSearch = React10__namespace.useCallback(
3784
+ (val) => {
3785
+ setSearch(val);
3786
+ if (onSearch) onSearch(val);
3787
+ },
3788
+ [onSearch]
3789
+ );
3790
+ const handleOpenChange = React10__namespace.useCallback(
3791
+ (nextOpen) => {
3792
+ setOpen(nextOpen);
3793
+ if (!nextOpen) {
3794
+ setSearch("");
3795
+ if (onSearch) onSearch("");
3796
+ }
3797
+ },
3798
+ [onSearch]
3799
+ );
3800
+ const handleScroll = React10__namespace.useCallback(() => {
3801
+ if (!onLoadMore || !hasMore || loading) return;
3802
+ const el = listRef.current;
3803
+ if (!el) return;
3804
+ const { scrollTop, scrollHeight, clientHeight } = el;
3805
+ if (scrollHeight - scrollTop - clientHeight < 80) {
3806
+ onLoadMore();
3807
+ }
3808
+ }, [onLoadMore, hasMore, loading]);
3809
+ React10__namespace.useEffect(() => {
3810
+ if (!open) return;
3811
+ let cancelled = false;
3812
+ let removeHandler;
3813
+ requestAnimationFrame(() => {
3814
+ if (cancelled) return;
3815
+ const content = contentRef.current;
3816
+ const list = listRef.current;
3817
+ if (!content || !list) return;
3818
+ const handleWheel = (e) => {
3819
+ if (!content.contains(e.target)) return;
3820
+ const { scrollTop, scrollHeight, clientHeight } = list;
3821
+ if (scrollHeight <= clientHeight) return;
3822
+ e.preventDefault();
3823
+ e.stopPropagation();
3824
+ list.scrollTop = Math.max(0, Math.min(scrollTop + e.deltaY, scrollHeight - clientHeight));
3825
+ };
3826
+ document.addEventListener("wheel", handleWheel, { passive: false, capture: true });
3827
+ removeHandler = () => document.removeEventListener("wheel", handleWheel, { capture: true });
3828
+ });
3829
+ return () => {
3830
+ cancelled = true;
3831
+ removeHandler?.();
3832
+ };
3833
+ }, [open]);
3834
+ const side = dropdownPosition === "top" ? "top" : "bottom";
3835
+ const avoidCollisions = dropdownPosition === "auto";
3836
+ return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: handleOpenChange, children: [
3837
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
3838
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
3839
+ "button",
3840
+ {
3841
+ type: "button",
3842
+ disabled,
3843
+ className: cn(
3844
+ "flex w-full items-center justify-between rounded-md border-2 bg-background px-3 text-sm transition-colors",
3845
+ "focus:outline-none focus:border-primary",
3846
+ "disabled:cursor-not-allowed disabled:opacity-50",
3847
+ label ? "h-12 pt-4 pb-2" : "h-9 py-2",
3848
+ error ? "border-red-500" : "border-border",
3849
+ open && !error && "border-primary"
3850
+ ),
3851
+ children: [
3852
+ selected ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 truncate", children: [
3853
+ selected.icon && /* @__PURE__ */ jsxRuntime.jsx(selected.icon, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
3854
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: selected.label })
3855
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: placeholder }),
3856
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: cn("h-4 w-4 shrink-0 opacity-50 transition-transform", open && "rotate-180") })
3857
+ ]
3858
+ }
3859
+ ) }),
3860
+ label && /* @__PURE__ */ jsxRuntime.jsxs(
3861
+ "label",
3862
+ {
3863
+ className: cn(
3864
+ "absolute left-3 top-[-6px] text-xs font-medium bg-background px-1 inline-flex items-center gap-1",
3865
+ tooltip ? "pointer-events-auto" : "pointer-events-none",
3866
+ error ? "text-red-500" : "text-foreground"
3867
+ ),
3868
+ children: [
3869
+ label,
3870
+ required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500 ml-0.5", children: "*" }),
3871
+ tooltip && /* @__PURE__ */ jsxRuntime.jsx(FieldTooltipIcon, { tooltip })
3872
+ ]
3873
+ }
3874
+ )
3875
+ ] }),
3876
+ /* @__PURE__ */ jsxRuntime.jsxs(
3877
+ PopoverContent,
3878
+ {
3879
+ ref: contentRef,
3880
+ side,
3881
+ align: "start",
3882
+ sideOffset: 4,
3883
+ avoidCollisions,
3884
+ collisionPadding: 16,
3885
+ className: "p-0 overflow-hidden flex flex-col",
3886
+ style: {
3887
+ width: "var(--radix-popover-trigger-width)",
3888
+ maxHeight: "min(340px, var(--radix-popover-content-available-height, 340px))"
3889
+ },
3890
+ onOpenAutoFocus: (e) => {
3891
+ e.preventDefault();
3892
+ if (searchable) {
3893
+ setTimeout(() => searchRef.current?.focus(), 0);
3894
+ }
3895
+ },
3896
+ children: [
3897
+ searchable && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-border", children: [
3898
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
3899
+ /* @__PURE__ */ jsxRuntime.jsx(
3900
+ "input",
3901
+ {
3902
+ ref: searchRef,
3903
+ type: "text",
3904
+ value: search,
3905
+ onChange: (e) => handleSearch(e.target.value),
3906
+ placeholder: searchPlaceholder,
3907
+ className: "flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground"
3908
+ }
3909
+ )
3910
+ ] }),
3911
+ /* @__PURE__ */ jsxRuntime.jsx(
3912
+ "div",
3913
+ {
3914
+ ref: listRef,
3915
+ className: "overflow-y-auto overscroll-contain min-h-0 flex-1",
3916
+ onScroll: handleScroll,
3917
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-1", children: [
3918
+ filteredOptions.length === 0 && !loading ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "py-4 text-center text-sm text-muted-foreground", children: emptyText }) : filteredOptions.map((option) => {
3919
+ const isSelected = value === option.value;
3920
+ const isDisabled = option.disabled || disabled;
3921
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3922
+ "button",
3923
+ {
3924
+ type: "button",
3925
+ disabled: isDisabled,
3926
+ onClick: () => {
3927
+ onChange(option.value);
3928
+ setOpen(false);
3929
+ },
3930
+ className: cn(
3931
+ "flex w-full items-center gap-2 rounded-sm px-2 text-left text-sm outline-none",
3932
+ "cursor-pointer hover:bg-accent hover:text-accent-foreground",
3933
+ isSelected && "bg-accent/50",
3934
+ isDisabled && "pointer-events-none opacity-50",
3935
+ option.description ? "py-2" : "py-1.5"
3936
+ ),
3937
+ children: [
3938
+ option.icon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-primary/10", children: /* @__PURE__ */ jsxRuntime.jsx(option.icon, { className: "h-3 w-3 text-primary" }) }),
3939
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
3940
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block leading-tight", children: option.label }),
3941
+ option.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-xs leading-tight text-muted-foreground", children: option.description })
3942
+ ] }),
3943
+ isSelected && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4 shrink-0 text-primary" })
3944
+ ]
3945
+ },
3946
+ option.value
3947
+ );
3948
+ }),
3949
+ loading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-3", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }) })
3950
+ ] })
3951
+ }
3952
+ )
3953
+ ]
3954
+ }
3955
+ )
3956
+ ] });
3957
+ }
3958
+ function FormMultiSelect({
3959
+ name,
3960
+ label,
3961
+ description,
3962
+ tooltip,
3963
+ required,
3964
+ disabled,
3965
+ className,
3966
+ options,
3967
+ placeholder = "Selecione...",
3968
+ hideError = false,
3969
+ emptyText = "Nenhuma op\xE7\xE3o dispon\xEDvel",
3970
+ loading = false,
3971
+ searchable = false,
3972
+ searchPlaceholder = "Buscar...",
3973
+ clearable = true,
3974
+ maxVisibleChips = 3,
3975
+ dropdownPosition = "bottom"
3976
+ }) {
3977
+ const form = reactHookForm.useFormContext();
3978
+ const fieldState = form.getFieldState(name, form.formState);
3979
+ const error = fieldState.error?.message;
3980
+ return /* @__PURE__ */ jsxRuntime.jsx(FormFieldProvider, { name, children: /* @__PURE__ */ jsxRuntime.jsx(
3981
+ reactHookForm.Controller,
3982
+ {
3983
+ control: form.control,
3984
+ name,
3985
+ render: ({ field }) => {
3986
+ const values = Array.isArray(field.value) ? field.value : [];
3987
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-1", className), children: [
3988
+ /* @__PURE__ */ jsxRuntime.jsx(
3989
+ MultiSelectDropdown,
3990
+ {
3991
+ options,
3992
+ value: values,
3993
+ onChange: (v) => field.onChange(v),
3994
+ disabled,
3995
+ label,
3996
+ tooltip,
3997
+ required,
3998
+ error: !!error,
3999
+ placeholder,
4000
+ searchable,
4001
+ loading,
4002
+ emptyText,
4003
+ searchPlaceholder,
4004
+ clearable,
4005
+ maxVisibleChips,
4006
+ dropdownPosition
4007
+ }
4008
+ ),
4009
+ description && !error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground px-1", children: description }),
4010
+ !hideError && error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-red-500 px-1", children: error })
4011
+ ] });
4012
+ }
4013
+ }
4014
+ ) });
4015
+ }
4016
+ FormMultiSelect.displayName = "Form.MultiSelect";
4017
+ function MultiSelectDropdown({
3502
4018
  options,
3503
4019
  value,
3504
4020
  onChange,
3505
4021
  disabled,
3506
4022
  label,
4023
+ tooltip,
3507
4024
  required,
3508
4025
  error,
3509
4026
  placeholder = "Selecione...",
3510
4027
  searchable,
3511
- onSearch,
3512
- onLoadMore,
3513
- hasMore,
3514
4028
  loading,
3515
4029
  emptyText = "Nenhuma op\xE7\xE3o dispon\xEDvel",
3516
- searchPlaceholder = "Buscar..."
4030
+ searchPlaceholder = "Buscar...",
4031
+ clearable = true,
4032
+ maxVisibleChips = 3,
4033
+ dropdownPosition = "bottom"
3517
4034
  }) {
3518
4035
  const [open, setOpen] = React10__namespace.useState(false);
3519
4036
  const [search, setSearch] = React10__namespace.useState("");
3520
- const selected = options.find((o) => o.value === value);
3521
- const containerRef = React10__namespace.useRef(null);
3522
- const dropdownRef = React10__namespace.useRef(null);
4037
+ const [computedMax, setComputedMax] = React10__namespace.useState(maxVisibleChips);
4038
+ const [prevValueKey, setPrevValueKey] = React10__namespace.useState(() => value.join(","));
4039
+ const contentRef = React10__namespace.useRef(null);
3523
4040
  const listRef = React10__namespace.useRef(null);
3524
4041
  const searchRef = React10__namespace.useRef(null);
3525
- const [dropdownPos, setDropdownPos] = React10__namespace.useState({});
4042
+ const chipsRef = React10__namespace.useRef(null);
4043
+ const selectedOptions = React10__namespace.useMemo(
4044
+ () => options.filter((o) => value.includes(o.value)),
4045
+ [options, value]
4046
+ );
4047
+ const valueKey = value.join(",");
4048
+ if (valueKey !== prevValueKey) {
4049
+ setPrevValueKey(valueKey);
4050
+ setComputedMax(maxVisibleChips);
4051
+ }
4052
+ React10__namespace.useLayoutEffect(() => {
4053
+ const container = chipsRef.current;
4054
+ if (!container || selectedOptions.length === 0) return;
4055
+ const containerRect = container.getBoundingClientRect();
4056
+ const containerWidth = containerRect.width;
4057
+ const chips = container.querySelectorAll("[data-chip]");
4058
+ if (chips.length === 0 || containerWidth === 0) return;
4059
+ const gap = 4;
4060
+ const buffer = 4;
4061
+ const badge = container.querySelector("[data-badge]");
4062
+ const badgeWidth = badge ? badge.getBoundingClientRect().width : 28;
4063
+ const availableWidth = containerWidth - buffer;
4064
+ let usedWidth = 0;
4065
+ let fits = 0;
4066
+ for (let i = 0; i < chips.length; i++) {
4067
+ const chipWidth = chips[i].getBoundingClientRect().width;
4068
+ const widthWithGap = fits > 0 ? chipWidth + gap : chipWidth;
4069
+ const remaining = selectedOptions.length - (fits + 1);
4070
+ const needsBadge = remaining > 0;
4071
+ const badgeSpace = needsBadge ? badgeWidth + gap : 0;
4072
+ if (usedWidth + widthWithGap + badgeSpace > availableWidth && fits > 0) {
4073
+ break;
4074
+ }
4075
+ usedWidth += widthWithGap;
4076
+ fits++;
4077
+ }
4078
+ const newMax = Math.max(1, fits);
4079
+ if (newMax !== computedMax) {
4080
+ setComputedMax(newMax);
4081
+ }
4082
+ });
3526
4083
  const filteredOptions = React10__namespace.useMemo(() => {
3527
- if (!searchable || onSearch || !search) return options;
4084
+ if (!searchable || !search) return options;
3528
4085
  const q = search.toLowerCase();
3529
4086
  return options.filter(
3530
4087
  (o) => o.label.toLowerCase().includes(q) || o.description?.toLowerCase().includes(q)
3531
4088
  );
3532
- }, [options, search, searchable, onSearch]);
3533
- const handleSearch = React10__namespace.useCallback(
3534
- (value2) => {
3535
- setSearch(value2);
3536
- if (onSearch) onSearch(value2);
4089
+ }, [options, search, searchable]);
4090
+ const toggleOption = React10__namespace.useCallback(
4091
+ (optionValue) => {
4092
+ if (value.includes(optionValue)) {
4093
+ onChange(value.filter((v) => v !== optionValue));
4094
+ } else {
4095
+ onChange([...value, optionValue]);
4096
+ }
3537
4097
  },
3538
- [onSearch]
4098
+ [value, onChange]
3539
4099
  );
3540
- React10__namespace.useEffect(() => {
3541
- if (!open || !containerRef.current) return;
3542
- const updatePosition = () => {
3543
- const rect = containerRef.current.getBoundingClientRect();
3544
- const spaceBelow = window.innerHeight - rect.bottom;
3545
- const estimatedHeight = 340;
3546
- const showAbove = spaceBelow < estimatedHeight && rect.top > spaceBelow;
3547
- setDropdownPos({
3548
- position: "fixed",
3549
- left: rect.left,
3550
- width: rect.width,
3551
- zIndex: 9999,
3552
- ...showAbove ? { bottom: window.innerHeight - rect.top + 4 } : { top: rect.bottom + 4 }
3553
- });
3554
- };
3555
- updatePosition();
3556
- window.addEventListener("scroll", updatePosition, true);
3557
- window.addEventListener("resize", updatePosition);
3558
- return () => {
3559
- window.removeEventListener("scroll", updatePosition, true);
3560
- window.removeEventListener("resize", updatePosition);
3561
- };
3562
- }, [open]);
3563
- React10__namespace.useEffect(() => {
3564
- if (!open) return;
3565
- const handleClickOutside = (e) => {
3566
- const target = e.target;
3567
- if (containerRef.current && !containerRef.current.contains(target) && (!dropdownRef.current || !dropdownRef.current.contains(target))) {
3568
- setOpen(false);
3569
- }
3570
- };
3571
- document.addEventListener("mousedown", handleClickOutside);
3572
- return () => document.removeEventListener("mousedown", handleClickOutside);
3573
- }, [open]);
3574
- React10__namespace.useEffect(() => {
3575
- if (!open) return;
3576
- const handleEscape = (e) => {
3577
- if (e.key === "Escape") setOpen(false);
3578
- };
3579
- document.addEventListener("keydown", handleEscape);
3580
- return () => document.removeEventListener("keydown", handleEscape);
3581
- }, [open]);
3582
- React10__namespace.useEffect(() => {
3583
- if (!open) {
4100
+ const handleClearAll = React10__namespace.useCallback(
4101
+ (e) => {
4102
+ e.stopPropagation();
4103
+ onChange([]);
4104
+ },
4105
+ [onChange]
4106
+ );
4107
+ const handleRemoveChip = React10__namespace.useCallback(
4108
+ (e, optionValue) => {
4109
+ e.stopPropagation();
4110
+ onChange(value.filter((v) => v !== optionValue));
4111
+ },
4112
+ [value, onChange]
4113
+ );
4114
+ const handleOpenChange = React10__namespace.useCallback((nextOpen) => {
4115
+ setOpen(nextOpen);
4116
+ if (!nextOpen) {
3584
4117
  setSearch("");
3585
- if (onSearch) onSearch("");
3586
- }
3587
- }, [open, onSearch]);
3588
- React10__namespace.useEffect(() => {
3589
- if (open && searchable) {
3590
- setTimeout(() => searchRef.current?.focus(), 0);
3591
4118
  }
3592
- }, [open, searchable]);
4119
+ }, []);
3593
4120
  React10__namespace.useEffect(() => {
3594
- const el = listRef.current;
3595
- if (!el || !open) return;
3596
- const handleWheel = (e) => {
3597
- const { scrollTop, scrollHeight, clientHeight } = el;
3598
- const isScrollable = scrollHeight > clientHeight;
3599
- if (!isScrollable) return;
3600
- e.preventDefault();
3601
- e.stopPropagation();
3602
- el.scrollTop = Math.max(
3603
- 0,
3604
- Math.min(scrollTop + e.deltaY, scrollHeight - clientHeight)
3605
- );
4121
+ if (!open) return;
4122
+ let cancelled = false;
4123
+ let removeHandler;
4124
+ requestAnimationFrame(() => {
4125
+ if (cancelled) return;
4126
+ const content = contentRef.current;
4127
+ const list = listRef.current;
4128
+ if (!content || !list) return;
4129
+ const handleWheel = (e) => {
4130
+ if (!content.contains(e.target)) return;
4131
+ const { scrollTop, scrollHeight, clientHeight } = list;
4132
+ if (scrollHeight <= clientHeight) return;
4133
+ e.preventDefault();
4134
+ e.stopPropagation();
4135
+ list.scrollTop = Math.max(0, Math.min(scrollTop + e.deltaY, scrollHeight - clientHeight));
4136
+ };
4137
+ document.addEventListener("wheel", handleWheel, { passive: false, capture: true });
4138
+ removeHandler = () => document.removeEventListener("wheel", handleWheel, { capture: true });
4139
+ });
4140
+ return () => {
4141
+ cancelled = true;
4142
+ removeHandler?.();
3606
4143
  };
3607
- el.addEventListener("wheel", handleWheel, { passive: false, capture: true });
3608
- return () => el.removeEventListener("wheel", handleWheel, { capture: true });
3609
- }, [open, filteredOptions]);
3610
- const handleScroll = React10__namespace.useCallback(() => {
3611
- if (!onLoadMore || !hasMore || loading) return;
3612
- const el = listRef.current;
3613
- if (!el) return;
3614
- const { scrollTop, scrollHeight, clientHeight } = el;
3615
- if (scrollHeight - scrollTop - clientHeight < 80) {
3616
- onLoadMore();
3617
- }
3618
- }, [onLoadMore, hasMore, loading]);
3619
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: "relative", children: [
3620
- /* @__PURE__ */ jsxRuntime.jsxs(
3621
- "button",
3622
- {
3623
- type: "button",
3624
- disabled,
3625
- onClick: () => setOpen((prev) => !prev),
3626
- className: cn(
3627
- "flex w-full items-center justify-between rounded-md border-2 bg-background px-3 text-sm transition-colors",
3628
- "focus:outline-none focus:border-primary",
3629
- "disabled:cursor-not-allowed disabled:opacity-50",
3630
- label ? "h-12 pt-4 pb-2" : "h-9 py-2",
3631
- error ? "border-red-500" : "border-border",
3632
- open && !error && "border-primary"
3633
- ),
3634
- children: [
3635
- selected ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 truncate", children: [
3636
- selected.icon && /* @__PURE__ */ jsxRuntime.jsx(selected.icon, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
3637
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: selected.label })
3638
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: placeholder }),
3639
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: cn("h-4 w-4 shrink-0 opacity-50 transition-transform", open && "rotate-180") })
3640
- ]
3641
- }
3642
- ),
3643
- label && /* @__PURE__ */ jsxRuntime.jsxs(
3644
- "label",
3645
- {
3646
- className: cn(
3647
- "absolute left-3 top-[-6px] text-xs font-medium bg-background px-1 pointer-events-none",
3648
- error ? "text-red-500" : "text-foreground"
3649
- ),
3650
- children: [
3651
- label,
3652
- required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500 ml-0.5", children: "*" })
3653
- ]
3654
- }
3655
- ),
3656
- open && reactDom.createPortal(
3657
- /* @__PURE__ */ jsxRuntime.jsxs(
3658
- "div",
4144
+ }, [open]);
4145
+ const side = dropdownPosition === "top" ? "top" : "bottom";
4146
+ const avoidCollisions = dropdownPosition === "auto";
4147
+ const visibleChips = selectedOptions.slice(0, computedMax);
4148
+ const overflowCount = selectedOptions.length - computedMax;
4149
+ return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: handleOpenChange, children: [
4150
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
4151
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
4152
+ "button",
3659
4153
  {
3660
- ref: dropdownRef,
3661
- style: dropdownPos,
3662
- className: "rounded-md border border-border bg-popover shadow-md overflow-hidden animate-in fade-in-0 zoom-in-95 slide-in-from-top-2 duration-150",
4154
+ type: "button",
4155
+ disabled,
4156
+ className: cn(
4157
+ "flex w-full items-center justify-between rounded-md border-2 bg-background px-3 text-sm transition-colors",
4158
+ "focus:outline-none focus:border-primary",
4159
+ "disabled:cursor-not-allowed disabled:opacity-50",
4160
+ label ? "min-h-[3rem] pt-4 pb-1.5" : "min-h-[2.25rem] py-1.5",
4161
+ error ? "border-red-500" : "border-border",
4162
+ open && !error && "border-primary"
4163
+ ),
3663
4164
  children: [
3664
- searchable && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-border", children: [
3665
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
3666
- /* @__PURE__ */ jsxRuntime.jsx(
3667
- "input",
4165
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: chipsRef, className: "flex gap-1 items-center flex-1 overflow-hidden", children: selectedOptions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4166
+ visibleChips.map((option) => /* @__PURE__ */ jsxRuntime.jsxs(
4167
+ "span",
4168
+ {
4169
+ "data-chip": true,
4170
+ className: "inline-flex items-center gap-1 max-w-[150px] shrink-0 rounded-sm bg-primary/10 px-1.5 py-0.5 text-xs font-medium text-primary",
4171
+ children: [
4172
+ option.icon && /* @__PURE__ */ jsxRuntime.jsx(option.icon, { className: "h-3 w-3 shrink-0" }),
4173
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: option.label }),
4174
+ /* @__PURE__ */ jsxRuntime.jsx(
4175
+ lucideReact.X,
4176
+ {
4177
+ className: "h-3 w-3 shrink-0 cursor-pointer hover:text-destructive",
4178
+ onClick: (e) => handleRemoveChip(e, option.value)
4179
+ }
4180
+ )
4181
+ ]
4182
+ },
4183
+ option.value
4184
+ )),
4185
+ overflowCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-badge": true, className: "inline-flex items-center justify-center h-5 min-w-5 px-1.5 shrink-0 rounded-full bg-gray-100 text-gray-500 text-[10px] font-medium", children: [
4186
+ "+",
4187
+ overflowCount
4188
+ ] })
4189
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: placeholder }) }),
4190
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 ml-1 shrink-0", children: [
4191
+ clearable && selectedOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
4192
+ lucideReact.X,
3668
4193
  {
3669
- ref: searchRef,
3670
- type: "text",
3671
- value: search,
3672
- onChange: (e) => handleSearch(e.target.value),
3673
- placeholder: searchPlaceholder,
3674
- className: "flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground"
4194
+ className: "h-4 w-4 text-muted-foreground hover:text-foreground cursor-pointer",
4195
+ onClick: handleClearAll
3675
4196
  }
3676
- )
3677
- ] }),
4197
+ ),
4198
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: cn("h-4 w-4 opacity-50 transition-transform", open && "rotate-180") })
4199
+ ] })
4200
+ ]
4201
+ }
4202
+ ) }),
4203
+ label && /* @__PURE__ */ jsxRuntime.jsxs(
4204
+ "label",
4205
+ {
4206
+ className: cn(
4207
+ "absolute left-3 top-[-6px] text-xs font-medium bg-background px-1 inline-flex items-center gap-1",
4208
+ tooltip ? "pointer-events-auto" : "pointer-events-none",
4209
+ error ? "text-red-500" : "text-foreground"
4210
+ ),
4211
+ children: [
4212
+ label,
4213
+ required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500 ml-0.5", children: "*" }),
4214
+ tooltip && /* @__PURE__ */ jsxRuntime.jsx(FieldTooltipIcon, { tooltip })
4215
+ ]
4216
+ }
4217
+ )
4218
+ ] }),
4219
+ /* @__PURE__ */ jsxRuntime.jsxs(
4220
+ PopoverContent,
4221
+ {
4222
+ ref: contentRef,
4223
+ side,
4224
+ align: "start",
4225
+ sideOffset: 4,
4226
+ avoidCollisions,
4227
+ collisionPadding: 16,
4228
+ className: "p-0 overflow-hidden flex flex-col",
4229
+ style: {
4230
+ width: "var(--radix-popover-trigger-width)",
4231
+ maxHeight: "min(340px, var(--radix-popover-content-available-height, 340px))"
4232
+ },
4233
+ onOpenAutoFocus: (e) => {
4234
+ e.preventDefault();
4235
+ if (searchable) {
4236
+ setTimeout(() => searchRef.current?.focus(), 0);
4237
+ }
4238
+ },
4239
+ children: [
4240
+ searchable && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-border", children: [
4241
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
3678
4242
  /* @__PURE__ */ jsxRuntime.jsx(
3679
- "div",
4243
+ "input",
3680
4244
  {
3681
- ref: listRef,
3682
- className: "overflow-y-auto overscroll-contain max-h-[300px]",
3683
- onScroll: handleScroll,
3684
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "divide-y divide-border/50 p-2", children: [
3685
- filteredOptions.length === 0 && !loading ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "py-4 text-center text-sm text-muted-foreground", children: emptyText }) : filteredOptions.map((option) => {
3686
- const isSelected = value === option.value;
3687
- const isDisabled = option.disabled || disabled;
3688
- return /* @__PURE__ */ jsxRuntime.jsxs(
3689
- "button",
3690
- {
3691
- type: "button",
3692
- disabled: isDisabled,
3693
- onClick: () => {
3694
- onChange(option.value);
3695
- setOpen(false);
3696
- },
3697
- className: cn(
3698
- "flex w-full items-center gap-3 p-3 text-left transition-all",
3699
- "cursor-pointer hover:bg-accent",
3700
- isSelected && "bg-primary/5",
3701
- isDisabled && "cursor-not-allowed opacity-50 hover:bg-transparent"
3702
- ),
3703
- children: [
3704
- option.icon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-primary/10", children: /* @__PURE__ */ jsxRuntime.jsx(option.icon, { className: "h-3.5 w-3.5 text-primary" }) }),
3705
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
3706
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium leading-tight", children: option.label }),
3707
- option.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-0.5 text-xs leading-tight text-muted-foreground", children: option.description })
3708
- ] }),
3709
- isSelected && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3 w-3" }) })
3710
- ]
3711
- },
3712
- option.value
3713
- );
3714
- }),
3715
- loading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-3", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }) })
3716
- ] })
4245
+ ref: searchRef,
4246
+ type: "text",
4247
+ value: search,
4248
+ onChange: (e) => setSearch(e.target.value),
4249
+ placeholder: searchPlaceholder,
4250
+ className: "flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground"
3717
4251
  }
3718
4252
  )
3719
- ]
3720
- }
3721
- ),
3722
- document.body
4253
+ ] }),
4254
+ /* @__PURE__ */ jsxRuntime.jsx(
4255
+ "div",
4256
+ {
4257
+ ref: listRef,
4258
+ className: "overflow-y-auto overscroll-contain min-h-0 flex-1",
4259
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-1", children: [
4260
+ filteredOptions.length === 0 && !loading ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "py-4 text-center text-sm text-muted-foreground", children: emptyText }) : filteredOptions.map((option) => {
4261
+ const isSelected = value.includes(option.value);
4262
+ const isDisabled = option.disabled || disabled;
4263
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4264
+ "button",
4265
+ {
4266
+ type: "button",
4267
+ disabled: isDisabled,
4268
+ onClick: () => toggleOption(option.value),
4269
+ className: cn(
4270
+ "flex w-full items-center gap-2 rounded-sm px-2 text-left text-sm outline-none",
4271
+ "cursor-pointer hover:bg-accent hover:text-accent-foreground",
4272
+ isSelected && "bg-accent/50",
4273
+ isDisabled && "pointer-events-none opacity-50",
4274
+ option.description ? "py-2" : "py-1.5"
4275
+ ),
4276
+ children: [
4277
+ option.icon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-primary/10", children: /* @__PURE__ */ jsxRuntime.jsx(option.icon, { className: "h-3 w-3 text-primary" }) }),
4278
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
4279
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block leading-tight", children: option.label }),
4280
+ option.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-xs leading-tight text-muted-foreground", children: option.description })
4281
+ ] }),
4282
+ isSelected && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4 shrink-0 text-primary" })
4283
+ ]
4284
+ },
4285
+ option.value
4286
+ );
4287
+ }),
4288
+ loading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-3", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }) })
4289
+ ] })
4290
+ }
4291
+ )
4292
+ ]
4293
+ }
3723
4294
  )
3724
4295
  ] });
3725
4296
  }
@@ -3987,107 +4558,41 @@ function FormRadioGroup({
3987
4558
  id: optionId,
3988
4559
  value: option.value,
3989
4560
  disabled: option.disabled || disabled,
3990
- className: cn(
3991
- "aspect-square h-4 w-4 rounded-full border",
3992
- isSelected ? styles.radio : "border-border text-muted-foreground",
3993
- "ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
3994
- "disabled:cursor-not-allowed disabled:opacity-50"
3995
- ),
3996
- children: /* @__PURE__ */ jsxRuntime.jsx(RadioGroupPrimitive__namespace.Indicator, { className: "flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Circle, { className: "h-2.5 w-2.5 fill-current text-current" }) })
3997
- }
3998
- ),
3999
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-0.5 leading-none", children: [
4000
- /* @__PURE__ */ jsxRuntime.jsx(
4001
- "span",
4002
- {
4003
- className: cn(
4004
- "text-sm font-medium leading-none",
4005
- isSelected && styles.text
4006
- ),
4007
- children: option.label
4008
- }
4009
- ),
4010
- option.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: option.description })
4011
- ] })
4012
- ]
4013
- },
4014
- option.value
4015
- );
4016
- })
4017
- }
4018
- ),
4019
- !hideError && error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-red-500", children: error })
4020
- ] })
4021
- }
4022
- ) });
4023
- }
4024
- FormRadioGroup.displayName = "Form.RadioGroup";
4025
- var FormLabel = React10__namespace.forwardRef(
4026
- ({ className, required, children, ...props }, ref) => {
4027
- const fieldContext = useFormFieldContextOptional();
4028
- return /* @__PURE__ */ jsxRuntime.jsxs(
4029
- "label",
4030
- {
4031
- ref,
4032
- htmlFor: fieldContext?.id,
4033
- className: cn(
4034
- "text-sm font-medium leading-none",
4035
- fieldContext?.error && "text-red-500",
4036
- className
4037
- ),
4038
- ...props,
4039
- children: [
4040
- children,
4041
- (required || fieldContext?.isRequired) && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500 ml-0.5", children: "*" })
4042
- ]
4043
- }
4044
- );
4045
- }
4046
- );
4047
- FormLabel.displayName = "Form.Label";
4048
- var FormDescription = React10__namespace.forwardRef(({ className, ...props }, ref) => {
4049
- const fieldContext = useFormFieldContextOptional();
4050
- if (fieldContext?.error) {
4051
- return null;
4052
- }
4053
- return /* @__PURE__ */ jsxRuntime.jsx(
4054
- "p",
4055
- {
4056
- ref,
4057
- className: cn("text-xs text-muted-foreground", className),
4058
- ...props
4059
- }
4060
- );
4061
- });
4062
- FormDescription.displayName = "Form.Description";
4063
- var FormError = React10__namespace.forwardRef(
4064
- ({ className, message, children, ...props }, ref) => {
4065
- const fieldContext = useFormFieldContextOptional();
4066
- const errorMessage = message ?? fieldContext?.error;
4067
- if (!errorMessage && !children) {
4068
- return null;
4561
+ className: cn(
4562
+ "aspect-square h-4 w-4 rounded-full border",
4563
+ isSelected ? styles.radio : "border-border text-muted-foreground",
4564
+ "ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
4565
+ "disabled:cursor-not-allowed disabled:opacity-50"
4566
+ ),
4567
+ children: /* @__PURE__ */ jsxRuntime.jsx(RadioGroupPrimitive__namespace.Indicator, { className: "flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Circle, { className: "h-2.5 w-2.5 fill-current text-current" }) })
4568
+ }
4569
+ ),
4570
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-0.5 leading-none", children: [
4571
+ /* @__PURE__ */ jsxRuntime.jsx(
4572
+ "span",
4573
+ {
4574
+ className: cn(
4575
+ "text-sm font-medium leading-none",
4576
+ isSelected && styles.text
4577
+ ),
4578
+ children: option.label
4579
+ }
4580
+ ),
4581
+ option.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: option.description })
4582
+ ] })
4583
+ ]
4584
+ },
4585
+ option.value
4586
+ );
4587
+ })
4588
+ }
4589
+ ),
4590
+ !hideError && error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-red-500", children: error })
4591
+ ] })
4069
4592
  }
4070
- return /* @__PURE__ */ jsxRuntime.jsx(
4071
- "p",
4072
- {
4073
- ref,
4074
- className: cn("text-xs text-red-500", className),
4075
- ...props,
4076
- children: children || errorMessage
4077
- }
4078
- );
4079
- }
4080
- );
4081
- FormError.displayName = "Form.Error";
4082
- var FormFieldWrapper = React10__namespace.forwardRef(({ className, label, description, required, error, children, ...props }, ref) => {
4083
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: cn("space-y-1", className), ...props, children: [
4084
- label && /* @__PURE__ */ jsxRuntime.jsx(FormLabel, { required, children: label }),
4085
- children,
4086
- description && /* @__PURE__ */ jsxRuntime.jsx(FormDescription, { children: description }),
4087
- error && /* @__PURE__ */ jsxRuntime.jsx(FormError, { message: error })
4088
- ] });
4089
- });
4090
- FormFieldWrapper.displayName = "Form.FieldWrapper";
4593
+ ) });
4594
+ }
4595
+ FormRadioGroup.displayName = "Form.RadioGroup";
4091
4596
  function FormRoot({
4092
4597
  form,
4093
4598
  onSubmit,
@@ -4111,6 +4616,7 @@ var Form = Object.assign(FormRoot, {
4111
4616
  // Campos com auto-bind
4112
4617
  Input: FormInput,
4113
4618
  Select: FormSelect,
4619
+ MultiSelect: FormMultiSelect,
4114
4620
  Textarea: FormTextarea,
4115
4621
  Checkbox: FormCheckbox,
4116
4622
  Switch: FormSwitch,
@@ -4284,207 +4790,6 @@ var DropdownMenuShortcut = ({
4284
4790
  );
4285
4791
  };
4286
4792
  DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
4287
- var Popover = PopoverPrimitive__namespace.Root;
4288
- var PopoverTrigger = PopoverPrimitive__namespace.Trigger;
4289
- var PopoverContent = React10__namespace.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
4290
- PopoverPrimitive__namespace.Content,
4291
- {
4292
- ref,
4293
- align,
4294
- sideOffset,
4295
- className: cn(
4296
- "z-50 w-auto rounded-md border bg-popover p-4 text-popover-foreground shadow-lg outline-none 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-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
4297
- className
4298
- ),
4299
- ...props
4300
- }
4301
- ) }));
4302
- PopoverContent.displayName = PopoverPrimitive__namespace.Content.displayName;
4303
- var TooltipProvider = TooltipPrimitive__namespace.Provider;
4304
- var TooltipRoot = TooltipPrimitive__namespace.Root;
4305
- var TooltipTrigger = TooltipPrimitive__namespace.Trigger;
4306
- var TooltipPortal = TooltipPrimitive__namespace.Portal;
4307
- var TooltipArrow = React10__namespace.forwardRef(({ className, variant = "light", ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4308
- TooltipPrimitive__namespace.Arrow,
4309
- {
4310
- ref,
4311
- className: cn(
4312
- "z-50",
4313
- variant === "dark" ? "fill-popover" : "fill-background",
4314
- className
4315
- ),
4316
- ...props
4317
- }
4318
- ));
4319
- TooltipArrow.displayName = "TooltipArrow";
4320
- var tooltipContentVariants = classVarianceAuthority.cva(
4321
- "z-50 overflow-hidden rounded-lg shadow-lg outline-none animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
4322
- {
4323
- variants: {
4324
- variant: {
4325
- light: "bg-background text-foreground border border-border",
4326
- dark: "bg-popover text-popover-foreground border border-border"
4327
- },
4328
- size: {
4329
- sm: "max-w-[200px] p-2",
4330
- md: "max-w-[280px] p-3",
4331
- lg: "max-w-[360px] p-4"
4332
- }
4333
- },
4334
- defaultVariants: {
4335
- variant: "light",
4336
- size: "md"
4337
- }
4338
- }
4339
- );
4340
- var TooltipContent = React10__namespace.forwardRef(
4341
- ({
4342
- className,
4343
- variant = "light",
4344
- size = "md",
4345
- sideOffset = 8,
4346
- showArrow = true,
4347
- onDismiss,
4348
- children,
4349
- ...props
4350
- }, ref) => /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs(
4351
- TooltipPrimitive__namespace.Content,
4352
- {
4353
- ref,
4354
- sideOffset,
4355
- className: cn(tooltipContentVariants({ variant, size }), className),
4356
- ...props,
4357
- children: [
4358
- onDismiss && /* @__PURE__ */ jsxRuntime.jsx(
4359
- "button",
4360
- {
4361
- onClick: onDismiss,
4362
- className: "absolute top-2 right-2 p-1 rounded-full transition-colors hover:bg-muted text-muted-foreground hover:text-foreground",
4363
- "aria-label": "Fechar",
4364
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-3.5 w-3.5" })
4365
- }
4366
- ),
4367
- children,
4368
- showArrow && /* @__PURE__ */ jsxRuntime.jsx(TooltipArrow, { variant: variant ?? "light", width: 12, height: 6 })
4369
- ]
4370
- }
4371
- ) })
4372
- );
4373
- TooltipContent.displayName = TooltipPrimitive__namespace.Content.displayName;
4374
- var TooltipHeader = React10__namespace.forwardRef(
4375
- ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("flex flex-col gap-1", className), ...props })
4376
- );
4377
- TooltipHeader.displayName = "TooltipHeader";
4378
- var TooltipTitle = React10__namespace.forwardRef(
4379
- ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4380
- "h4",
4381
- {
4382
- ref,
4383
- className: cn("text-sm font-semibold leading-tight", className),
4384
- ...props
4385
- }
4386
- )
4387
- );
4388
- TooltipTitle.displayName = "TooltipTitle";
4389
- var TooltipDescription = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4390
- "p",
4391
- {
4392
- ref,
4393
- className: cn("text-xs leading-relaxed text-muted-foreground", className),
4394
- ...props
4395
- }
4396
- ));
4397
- TooltipDescription.displayName = "TooltipDescription";
4398
- var TooltipActions = React10__namespace.forwardRef(
4399
- ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4400
- "div",
4401
- {
4402
- ref,
4403
- className: cn("flex items-center gap-2 mt-3", className),
4404
- ...props
4405
- }
4406
- )
4407
- );
4408
- TooltipActions.displayName = "TooltipActions";
4409
- var tooltipActionVariants = classVarianceAuthority.cva(
4410
- "inline-flex items-center justify-center text-xs font-medium rounded-md transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
4411
- {
4412
- variants: {
4413
- variant: {
4414
- primary: "bg-primary text-primary-foreground hover:bg-primary/90 px-3 py-1.5",
4415
- secondary: "bg-transparent text-muted-foreground hover:text-foreground hover:underline px-2 py-1.5",
4416
- outline: "border border-border bg-background text-foreground hover:bg-muted px-3 py-1.5"
4417
- }
4418
- },
4419
- defaultVariants: {
4420
- variant: "primary"
4421
- }
4422
- }
4423
- );
4424
- var TooltipAction = React10__namespace.forwardRef(
4425
- ({ className, variant = "primary", ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4426
- "button",
4427
- {
4428
- ref,
4429
- className: cn(tooltipActionVariants({ variant }), className),
4430
- ...props
4431
- }
4432
- )
4433
- );
4434
- TooltipAction.displayName = "TooltipAction";
4435
- var TooltipIcon = React10__namespace.forwardRef(
4436
- ({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4437
- "div",
4438
- {
4439
- ref,
4440
- className: cn(
4441
- "flex items-center justify-center w-10 h-10 rounded-full mb-3 bg-muted",
4442
- className
4443
- ),
4444
- ...props,
4445
- children
4446
- }
4447
- )
4448
- );
4449
- TooltipIcon.displayName = "TooltipIcon";
4450
- var SimpleTooltip = ({
4451
- children,
4452
- content,
4453
- variant = "light",
4454
- side = "top",
4455
- align = "center",
4456
- delayDuration = 200,
4457
- open,
4458
- defaultOpen,
4459
- onOpenChange
4460
- }) => /* @__PURE__ */ jsxRuntime.jsxs(
4461
- TooltipRoot,
4462
- {
4463
- open,
4464
- defaultOpen,
4465
- onOpenChange,
4466
- delayDuration,
4467
- children: [
4468
- /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children }),
4469
- /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { variant, side, align, size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs", children: content }) })
4470
- ]
4471
- }
4472
- );
4473
- SimpleTooltip.displayName = "SimpleTooltip";
4474
- var Tooltip = Object.assign(TooltipRoot, {
4475
- Provider: TooltipProvider,
4476
- Trigger: TooltipTrigger,
4477
- Portal: TooltipPortal,
4478
- Content: TooltipContent,
4479
- Arrow: TooltipArrow,
4480
- Header: TooltipHeader,
4481
- Title: TooltipTitle,
4482
- Description: TooltipDescription,
4483
- Actions: TooltipActions,
4484
- Action: TooltipAction,
4485
- Icon: TooltipIcon,
4486
- Simple: SimpleTooltip
4487
- });
4488
4793
  var AuthLayoutContext = React10__namespace.createContext({
4489
4794
  imagePosition: "left"
4490
4795
  });