ivt
Version:
Ivt Components Library
811 lines (807 loc) • 42.9 kB
JavaScript
import * as React from 'react';
import { useId, useState, useRef, useEffect } from 'react';
import { N as NumericFormat, P as PatternFormat } from '../chunks/react-number-format.es-HizMU4ab.mjs';
import { M as MultiSelect } from '../chunks/multi-select-ILUAJeKL.mjs';
import { c as cn } from '../chunks/utils-BDcRwQMd.mjs';
import { f as formatDateToBrazilian } from '../chunks/date-Dqmv8Nr4.mjs';
import { f as formatMoney } from '../chunks/format-numbers-LmnBEQr0.mjs';
import { s as styleInputError, a as styleInput } from '../chunks/styles-lQyUmHf7.mjs';
import { f as FormField, a as FormItem, b as FormLabel, c as FormControl, d as FormDescription, e as FormMessage, F as Form } from '../chunks/form-paAECAsZ.mjs';
import { C as CalendarRange } from '../chunks/CalendarRange-BZ-rc5Ns.mjs';
import { C as Combobox } from '../chunks/combobox-D9iqP8Dp.mjs';
import { T as Toggle } from '../chunks/toggle-Du3jnh1s.mjs';
import { I as InputOTP, a as InputOTPGroup, b as InputOTPSlot } from '../chunks/input-otp-BNC4E0wv.mjs';
import { S as Slider } from '../chunks/slider-D3yx--Ba.mjs';
import { R as RadioGroup, a as RadioGroupItem } from '../chunks/radio-group-BlSUw5ql.mjs';
import { S as Switch } from '../chunks/switch-COE1z3YV.mjs';
import { D as DatePicker } from '../chunks/date-picker-BBCtT16G.mjs';
import { C as CalendarPopover, A as AutoComplete } from '../chunks/CalendarPopover-DNS2oszG.mjs';
import { I as InputFile } from '../chunks/input-file-BH3SMNJ7.mjs';
import { L as ListItem } from '../chunks/ListItem-CtUZSq2i.mjs';
import { L as Label } from '../chunks/label-D0iRy8Wj.mjs';
import { C as Checkbox } from '../chunks/checkbox-DvxpZsiG.mjs';
import { S as Select, h as SelectTrigger, i as SelectValue, a as SelectContent, c as SelectItem } from '../chunks/select-BBatgGtL.mjs';
import { I as Input } from '../chunks/input-B-W81Xmi.mjs';
import { T as Textarea } from '../chunks/textarea-DM2uvcxK.mjs';
import { S as Separator } from '../chunks/separator-DYyhdAi6.mjs';
import 'class-variance-authority';
import '../chunks/string-DRS4HkY8.mjs';
import '../chunks/x-B6hDJA_l.mjs';
import '../chunks/createLucideIcon-C11Tr46U.mjs';
import '../chunks/chevrons-up-down-CdBVNy4c.mjs';
import '../chunks/check-Ds358kZc.mjs';
import '../chunks/wand-sparkles-DqgQle7F.mjs';
import '../chunks/popover-CdZgcLPo.mjs';
import '../chunks/index-Dsw02Eup.mjs';
import 'react-dom';
import '@radix-ui/react-slot';
import 'react/jsx-runtime';
import '../chunks/index-D4jPaBZ2.mjs';
import '../chunks/index-4NpeUekv.mjs';
import '../chunks/index-DC-gAYjS.mjs';
import '../chunks/index-z4Hk6sF4.mjs';
import '../chunks/tslib.es6-Q9puKanr.mjs';
import '../chunks/index-gX0V59dZ.mjs';
import '../chunks/index-C8u7IIcP.mjs';
import '../chunks/index-B87m6Bfb.mjs';
import '../chunks/index-DAa5gqEY.mjs';
import '../chunks/index-BksCjWh6.mjs';
import '../chunks/index-DfeRLazC.mjs';
import '../chunks/index-1toTCGyr.mjs';
import '../chunks/button-CZpmCmNo.mjs';
import '../chunks/badge-ZU62MOiS.mjs';
import '../chunks/tooltip-njN_ok-r.mjs';
import '../chunks/index-BJrVyyCQ.mjs';
import '../chunks/command-o67hOCgH.mjs';
import '../chunks/index-CaYwp6E6.mjs';
import '../chunks/dialog-DL1cSseU.mjs';
import '../chunks/bundle-mjs-CXmmFvYo.mjs';
import '../chunks/format-8qs-kXlN.mjs';
import '../chunks/calendar-days-DnYx8d46.mjs';
import '../chunks/calendar-CDJv1B--.mjs';
import '../chunks/chevron-left-Baq244Ce.mjs';
import '../chunks/chevron-right-Dq6zFe5E.mjs';
import '../chunks/chevron-down-CDFTds2-.mjs';
import '../chunks/index-CcmH_f2V.mjs';
import '../chunks/index-UxWlwQlk.mjs';
import '../chunks/index-COfEgTJM.mjs';
import '@radix-ui/react-collection';
import '../chunks/index-DIHpzffL.mjs';
import '../chunks/index.module-Czm-Rcez.mjs';
import '../chunks/loader-circle-BMRpEmW6.mjs';
import '../chunks/TooltipIndicator-o_ekzuQD.mjs';
import '@radix-ui/react-select';
/**
* Formata uma data para o padrão brasileiro (dd/MM/yyyy)
* @param date Data a ser formatada (Date, string ou undefined)
* @returns String formatada ou undefined se não houver valor
*/ function formatDate(date) {
if (!date) return undefined;
return formatDateToBrazilian(date);
}
/**
* Formata um CNPJ no padrão brasileiro (##.###.###/####-##)
* @param cnpj CNPJ a ser formatado (string com ou sem formatação)
* @returns String formatada ou undefined se não houver valor
*/ function formatCNPJ(cnpj) {
if (!cnpj) return undefined;
// Remove caracteres não numéricos
const cleaned = cnpj.replace(/\D/g, "");
// Verifica se tem 14 dígitos
if (cleaned.length !== 14) {
// Se não tiver 14 dígitos, retorna o valor original
return cnpj;
}
// Formata: ##.###.###/####-##
return `${cleaned.slice(0, 2)}.${cleaned.slice(2, 5)}.${cleaned.slice(5, 8)}/${cleaned.slice(8, 12)}-${cleaned.slice(12, 14)}`;
}
/**
* Formata um valor numérico como moeda brasileira (R$)
* @param value Valor numérico a ser formatado
* @returns String formatada ou undefined se não houver valor
*/ function formatCurrency(value) {
if (value === null || value === undefined) return undefined;
return formatMoney({
value,
currency: "BRL",
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
}
function AutocompleteFieldWrapper({ field, form, autocompleteConfig, placeholder, disabled, isError }) {
const [open, setOpen] = useState(false);
const [selectedOption, setSelectedOption] = useState(null);
const selectedOptionRef = useRef(null);
const getOptionLabel = autocompleteConfig.getOptionLabel || ((option)=>option.label || String(option.id));
const getOptionKey = autocompleteConfig.getOptionKey || ((option)=>option.id);
const getOptionValue = autocompleteConfig.getOptionValue || ((option)=>option.id);
useEffect(()=>{
if (selectedOptionRef.current && field.value) {
const currentValue = getOptionValue(selectedOptionRef.current);
const newValue = typeof field.value === "object" && field.value !== null ? getOptionValue(field.value) : field.value;
if (currentValue === newValue) {
return;
}
}
if (field.value && typeof field.value === "object" && field.value !== null) {
selectedOptionRef.current = field.value;
setSelectedOption(field.value);
return;
}
if (field.value && autocompleteConfig.fetchOptions) {
const isNumericValue = typeof field.value === "number";
const searchTerm = isNumericValue ? "" : field.value;
autocompleteConfig.fetchOptions(searchTerm).then((options)=>{
let found = null;
if (isNumericValue) {
found = options.find((opt)=>getOptionKey(opt) === field.value);
} else {
found = options.find((opt)=>getOptionValue(opt) === field.value);
if (!found) {
found = options.find((opt)=>{
const label = getOptionLabel(opt);
return label === field.value || label.toLowerCase().includes(field.value.toLowerCase());
});
}
}
if (found) {
selectedOptionRef.current = found;
setSelectedOption(found);
} else {
selectedOptionRef.current = null;
setSelectedOption(null);
}
}).catch(()=>{
selectedOptionRef.current = null;
setSelectedOption(null);
});
} else if (!field.value) {
selectedOptionRef.current = null;
setSelectedOption(null);
}
}, [
field.value,
autocompleteConfig.fetchOptions,
getOptionValue,
getOptionLabel,
getOptionKey
]);
return /*#__PURE__*/ React.createElement(AutoComplete, {
value: selectedOption,
onChange: (option)=>{
const value = option ? getOptionValue(option) : null;
field.onChange(value);
selectedOptionRef.current = option;
setSelectedOption(option);
if (option && autocompleteConfig.onChangeCallback) {
autocompleteConfig.onChangeCallback(option, form);
}
},
placeholder: placeholder || "Digite para buscar...",
searchPlaceholder: autocompleteConfig.searchPlaceholder || "Buscar...",
open: open,
onOpenChange: setOpen,
fetchOptions: autocompleteConfig.fetchOptions,
disabled: disabled,
messageEmpty: autocompleteConfig.messageEmpty || "Nenhum resultado encontrado...",
getOptionLabel: getOptionLabel,
getOptionKey: getOptionKey,
clearable: autocompleteConfig.clearable ?? true,
className: cn("border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-sm focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 truncate max-w-150", autocompleteConfig?.className, isError && styleInputError)
});
}
function BaseFormField({ config, control, readOnly = false, form }) {
const baseId = useId();
const { name, label, type, placeholder, description, required, options, items, allowNegative, decimalScale, disabled, prefix, radioOptions, otpLength, sliderRange, format: patternFormat, mask, autocompleteConfig, comboboxConfig, inlineElement, render: customRender, maxLength, endAdornment, multiSelectConfig, dateConfig, fileConfig, isCheckboxDefault } = config;
const formatReadOnlyValue = (value, fieldType)=>{
if (value === null || value === undefined || value === "") {
return undefined;
}
switch(fieldType){
case "date":
case "date-picker":
return formatDate(value);
case "currency":
return formatCurrency(value);
case "number":
return typeof value === "number" ? value.toLocaleString("pt-BR", {
minimumFractionDigits: decimalScale ?? 0,
maximumFractionDigits: decimalScale ?? 7
}) : String(value);
case "pattern":
if (patternFormat && typeof value === "string") {
if (patternFormat.includes("##.###.###/####-##")) {
return formatCNPJ(value);
}
return value;
}
return String(value);
case "select":
if (options && options.length > 0) {
const option = options.find((opt)=>{
const optValue = typeof opt === "object" ? opt.value : opt;
return String(optValue) === String(value);
});
if (option) {
return typeof option === "object" ? option.label : option;
}
}
return String(value);
case "checkbox":
case "switch":
case "toggle":
return value ? "Sim" : "Não";
case "radio":
if (radioOptions) {
const option = radioOptions.find((opt)=>String(opt.value) === String(value));
return option ? option.label : String(value);
}
return String(value);
case "slider":
return typeof value === "number" ? String(value) : undefined;
case "numberRange":
{
if (typeof value === "object" && value !== null && ("min" in value || "max" in value)) {
const range = value;
const minStr = range.min !== null && range.min !== undefined ? range.min.toLocaleString("pt-BR", {
minimumFractionDigits: decimalScale ?? 0,
maximumFractionDigits: decimalScale ?? 7
}) : "";
const maxStr = range.max !== null && range.max !== undefined ? range.max.toLocaleString("pt-BR", {
minimumFractionDigits: decimalScale ?? 0,
maximumFractionDigits: decimalScale ?? 7
}) : "";
if (minStr && maxStr) {
return `${minStr} - ${maxStr}`;
}
if (minStr) return `Mín: ${minStr}`;
if (maxStr) return `Máx: ${maxStr}`;
}
return undefined;
}
case "dateRange":
{
if (typeof value === "object" && value !== null && "from" in value) {
const range = value;
if (range.from && range.to) {
return `${formatDate(range.from)} - ${formatDate(range.to)}`;
}
if (range.from) {
return `De: ${formatDate(range.from)}`;
}
}
return undefined;
}
case "multiselect":
{
if (Array.isArray(value) && value.length > 0) {
return value.join(", ");
}
return undefined;
}
case "combobox":
{
if (typeof value === "string" || typeof value === "number") {
const valStr = String(value);
if (config.comboboxConfig?.items) {
const option = config.comboboxConfig.items.find((opt)=>String(opt.value) === valStr);
return option ? option.label : valStr;
}
return valStr;
}
return String(value);
}
default:
return String(value);
}
};
if (readOnly) {
return /*#__PURE__*/ React.createElement(FormField, {
control: control,
name: name,
render: ({ field })=>/*#__PURE__*/ React.createElement(ListItem, {
title: label ?? "",
value: formatReadOnlyValue(field.value, type)
})
});
}
return /*#__PURE__*/ React.createElement(FormField, {
control: control,
name: name,
render: ({ field, fieldState })=>{
const isError = fieldState?.invalid;
if (customRender && form) {
return /*#__PURE__*/ React.createElement(FormItem, {
className: cn(type === "checkbox" && "flex flex-row items-start space-y-0 space-x-3 rounded-md border p-4", type === "checkbox" && isCheckboxDefault && "border-none p-0")
}, type !== "checkbox" && type !== "switch" && /*#__PURE__*/ React.createElement(FormLabel, {
htmlFor: name
}, label, label && required && /*#__PURE__*/ React.createElement("span", {
className: "text-destructive",
style: {
float: "none",
width: "auto",
marginRight: 0,
marginTop: 0
}
}, "*"), /*#__PURE__*/ React.createElement("span", {
className: !label ? "text-transparent" : ""
}, ":")), /*#__PURE__*/ React.createElement("div", {
className: cn(inlineElement && "flex w-full items-center gap-2")
}, /*#__PURE__*/ React.createElement("div", {
className: cn(inlineElement && "min-w-0 flex-1")
}, /*#__PURE__*/ React.createElement(FormControl, {
className: isError ? styleInputError : ""
}, customRender({
field,
form
}))), inlineElement && /*#__PURE__*/ React.createElement("div", {
className: "shrink-0"
}, inlineElement)), type !== "checkbox" && description && !isError && /*#__PURE__*/ React.createElement(FormDescription, null, description), /*#__PURE__*/ React.createElement(FormMessage, null));
}
return /*#__PURE__*/ React.createElement(FormItem, {
className: cn(type === "checkbox" && "flex flex-row items-start space-y-0 space-x-3 rounded-md border p-4", isCheckboxDefault && "border-none p-0")
}, type !== "checkbox" && type !== "switch" && /*#__PURE__*/ React.createElement(FormLabel, {
htmlFor: name
}, label, label && required && /*#__PURE__*/ React.createElement("span", {
className: "text-destructive",
style: {
float: "none",
width: "auto",
marginRight: 0,
marginTop: 0
}
}, "*"), /*#__PURE__*/ React.createElement("span", {
className: !label ? "text-transparent" : ""
}, ":")), /*#__PURE__*/ React.createElement("div", {
className: cn(inlineElement && "flex w-full items-center gap-2")
}, /*#__PURE__*/ React.createElement("div", {
className: cn(inlineElement && "min-w-0 flex-1")
}, /*#__PURE__*/ React.createElement(FormControl, null, (()=>{
switch(type){
case "text":
case "email":
case "url":
case "tel":
return /*#__PURE__*/ React.createElement("div", {
className: "relative"
}, /*#__PURE__*/ React.createElement(Input, {
...field,
type: type,
placeholder: placeholder,
disabled: disabled,
maxLength: maxLength,
value: field.value || "",
className: cn(isError ? styleInputError : "", endAdornment && "pr-20")
}), endAdornment && /*#__PURE__*/ React.createElement("div", {
className: "text-muted-foreground pointer-events-none absolute top-1/2 right-3 -translate-y-1/2 text-xs"
}, endAdornment(field.value)));
case "file":
return /*#__PURE__*/ React.createElement(InputFile, {
id: String(name),
name: String(name),
value: field.value,
onChange: (e)=>{
const file = e.target.files?.[0] || null;
field.onChange(file);
},
accept: fileConfig?.accept,
disabled: disabled,
isError: isError,
placeholder: placeholder
});
case "textarea":
return /*#__PURE__*/ React.createElement(Textarea, {
className: cn("min-h-20", isError && styleInputError),
...field,
placeholder: placeholder,
disabled: disabled,
value: field.value || "",
maxLength: maxLength
});
case "number":
return /*#__PURE__*/ React.createElement(NumericFormat, {
id: name,
customInput: Input,
decimalSeparator: ",",
thousandSeparator: ".",
decimalScale: decimalScale ?? 7,
value: field.value ?? "",
onValueChange: (values)=>{
if (values.value === "") {
field.onChange(null);
} else {
field.onChange(values.floatValue);
}
},
placeholder: placeholder,
disabled: disabled,
className: cn("h-9", isError && styleInputError)
});
case "currency":
return /*#__PURE__*/ React.createElement(NumericFormat, {
id: name,
customInput: Input,
decimalSeparator: ",",
thousandSeparator: ".",
decimalScale: decimalScale ?? 2,
value: field.value ?? "",
onValueChange: (values)=>{
if (values.value === "") {
field.onChange(null);
} else {
field.onChange(values.floatValue);
}
},
placeholder: placeholder,
disabled: disabled,
prefix: prefix ?? "R$ ",
className: cn("h-9", isError && styleInputError)
});
case "pattern":
return /*#__PURE__*/ React.createElement(PatternFormat, {
customInput: Input,
format: patternFormat || "",
mask: mask || "_",
placeholder: placeholder,
disabled: disabled,
value: field.value || "",
onValueChange: (values)=>{
field.onChange(values.value);
},
className: isError ? styleInputError : ""
});
case "select":
{
const selectValue = String(field.value || "");
return /*#__PURE__*/ React.createElement(Select, {
onValueChange: field.onChange,
value: selectValue,
disabled: disabled,
clearable: config.selectConfig?.clearable ?? true
}, /*#__PURE__*/ React.createElement(FormControl, null, /*#__PURE__*/ React.createElement(SelectTrigger, {
id: name,
className: cn("w-full", isError && styleInputError)
}, /*#__PURE__*/ React.createElement(SelectValue, {
placeholder: placeholder || "Selecione"
}))), /*#__PURE__*/ React.createElement(SelectContent, {
className: "max-h-75 overflow-x-hidden overflow-y-auto"
}, options?.map((opt)=>{
const val = typeof opt === "object" ? String(opt.value) : opt;
const lab = typeof opt === "object" ? opt.label : opt;
return /*#__PURE__*/ React.createElement(SelectItem, {
key: val,
value: val
}, lab);
})));
}
case "date":
return /*#__PURE__*/ React.createElement(CalendarPopover, {
id: name,
date: field.value,
setDate: field.onChange,
placeholder: placeholder,
disabled: disabled,
disableFuture: false,
disableWeekends: false,
className: cn("w-full", isError && styleInputError)
});
case "date-picker":
return /*#__PURE__*/ React.createElement(DatePicker, {
id: name,
date: field.value,
setDate: field.onChange,
placeholder: placeholder,
disabled: disabled,
className: cn("w-full", isError && styleInputError)
});
case "checkbox":
return /*#__PURE__*/ React.createElement("div", {
className: "flex items-center gap-2"
}, /*#__PURE__*/ React.createElement(Checkbox, {
checked: !!field.value,
onCheckedChange: field.onChange,
disabled: disabled,
id: name
}), /*#__PURE__*/ React.createElement("div", {
className: "space-y-1 leading-none"
}, /*#__PURE__*/ React.createElement(FormLabel, {
htmlFor: name
}, label), description && !isError && /*#__PURE__*/ React.createElement(FormDescription, null, description)));
case "switch":
return /*#__PURE__*/ React.createElement("div", {
className: "flex items-center justify-between"
}, /*#__PURE__*/ React.createElement(FormLabel, {
htmlFor: name
}, label), /*#__PURE__*/ React.createElement(Switch, {
checked: !!field.value,
onCheckedChange: field.onChange,
disabled: disabled
}));
case "radio":
return /*#__PURE__*/ React.createElement(RadioGroup, {
value: String(field.value ?? ""),
onValueChange: field.onChange,
className: "flex flex-col gap-2",
disabled: disabled ?? false
}, (radioOptions ?? [])?.map((opt)=>{
const radioId = `${String(name)}-${opt.value}`;
return /*#__PURE__*/ React.createElement("div", {
key: opt.value,
className: "flex items-center gap-2"
}, /*#__PURE__*/ React.createElement(RadioGroupItem, {
value: opt.value,
id: radioId
}), /*#__PURE__*/ React.createElement(Label, {
htmlFor: radioId
}, opt.label));
}));
case "slider":
return /*#__PURE__*/ React.createElement("div", {
className: "space-y-2"
}, /*#__PURE__*/ React.createElement(Slider, {
value: [
Number(field.value ?? sliderRange?.min ?? 0)
],
onValueChange: (vals)=>field.onChange(vals[0]),
min: sliderRange?.min ?? 0,
max: sliderRange?.max ?? 100,
step: sliderRange?.step ?? 1,
disabled: disabled
}), typeof field.value === "number" && /*#__PURE__*/ React.createElement("p", {
className: "text-muted-foreground text-xs"
}, "Valor: ", field.value));
case "otp":
return /*#__PURE__*/ React.createElement(InputOTP, {
maxLength: otpLength ?? 6,
value: String(field.value ?? ""),
onChange: field.onChange,
disabled: disabled
}, /*#__PURE__*/ React.createElement(InputOTPGroup, null, Array.from({
length: otpLength ?? 6
}, (_, i)=>({
id: `${baseId}-otp-${i}`,
index: i
})).map((slot)=>/*#__PURE__*/ React.createElement(InputOTPSlot, {
key: slot.id,
index: slot.index
}))));
case "toggle":
return /*#__PURE__*/ React.createElement("div", {
className: "flex items-center gap-2"
}, /*#__PURE__*/ React.createElement(Toggle, {
pressed: !!field.value,
onPressedChange: (pressed)=>field.onChange(pressed),
disabled: disabled,
className: cn(isError && styleInputError)
}, label));
case "autocomplete":
{
if (!autocompleteConfig || !form) {
return null;
}
return /*#__PURE__*/ React.createElement(AutocompleteFieldWrapper, {
field: field,
form: form,
autocompleteConfig: autocompleteConfig,
placeholder: placeholder,
disabled: disabled,
isError: isError
});
}
case "combobox":
{
if (!comboboxConfig) return null;
return /*#__PURE__*/ React.createElement("div", {
tabIndex: -1,
className: "outline-none"
}, /*#__PURE__*/ React.createElement(Combobox, {
id: name,
items: comboboxConfig.items,
value: String(field.value ?? ""),
onValueChange: (val)=>{
if (comboboxConfig.valueType === "number") {
field.onChange(val !== "" ? Number(val) : null);
} else {
field.onChange(val || null);
}
},
placeholder: placeholder,
searchPlaceholder: comboboxConfig.searchPlaceholder,
emptyMessage: comboboxConfig.emptyMessage,
groupHeading: comboboxConfig.groupHeading,
normalizeSearch: comboboxConfig.normalizeSearch,
disabled: disabled,
widthClassName: "w-full",
className: cn(isError && styleInputError)
}));
}
case "dateRange":
{
return /*#__PURE__*/ React.createElement("div", {
tabIndex: -1,
className: "outline-none"
}, /*#__PURE__*/ React.createElement(CalendarRange, {
id: name,
numberOfMonths: 2,
value: field.value,
onChange: (value)=>{
field.onChange(value);
if (form) {
setTimeout(()=>{
form.trigger([
name
]);
}, 0);
}
},
placeholder: placeholder,
className: cn("h-9 w-full", isError && styleInputError),
disabled: disabled || dateConfig?.disabled,
...dateConfig
}));
}
case "numberRange":
{
return /*#__PURE__*/ React.createElement("div", {
className: "flex gap-2"
}, /*#__PURE__*/ React.createElement(NumericFormat, {
id: name,
placeholder: "Mínimo",
value: field.value?.min ?? "",
allowNegative: allowNegative ?? true,
allowLeadingZeros: false,
maxLength: undefined,
decimalSeparator: ",",
thousandSeparator: ".",
decimalScale: decimalScale ?? 8,
fixedDecimalScale: false,
onValueChange: (values)=>{
const numericValue = values.floatValue ?? null;
field.onChange({
...field.value ?? {
min: null,
max: null
},
min: numericValue
});
},
className: styleInput,
disabled: disabled
}), /*#__PURE__*/ React.createElement(NumericFormat, {
id: name,
placeholder: "Máximo",
value: field.value?.max ?? "",
allowNegative: allowNegative ?? true,
allowLeadingZeros: false,
maxLength: undefined,
decimalSeparator: ",",
thousandSeparator: ".",
decimalScale: decimalScale ?? 8,
fixedDecimalScale: false,
onValueChange: (values)=>{
const numericValue = values.floatValue ?? null;
field.onChange({
...field.value ?? {
min: null,
max: null
},
max: numericValue
});
},
className: styleInput,
disabled: disabled
}));
}
case "multiselect":
{
const multiSelectOptions = items?.map((item)=>({
label: item,
value: item
})) || options?.map((opt)=>typeof opt === "string" ? {
label: opt,
value: opt
} : {
label: opt.label,
value: String(opt.value)
}) || [];
const typedValue = Array.isArray(field.value) ? field.value.map(String) : [];
return /*#__PURE__*/ React.createElement("div", {
tabIndex: -1,
className: "outline-none"
}, /*#__PURE__*/ React.createElement(MultiSelect, {
id: name,
options: multiSelectOptions,
onValueChange: (val)=>{
if (multiSelectConfig?.valueType === "number") {
field.onChange(val.map(Number));
} else {
field.onChange(val);
}
},
defaultValue: typedValue,
value: typedValue,
placeholder: placeholder,
variant: "default",
maxCount: multiSelectConfig?.maxCount,
subtle: multiSelectConfig?.subtle,
messageEmpty: multiSelectConfig?.emptyMessage,
searchPlaceholder: multiSelectConfig?.searchPlaceholder,
groupHeading: multiSelectConfig?.groupHeading,
normalizeSearch: multiSelectConfig?.normalizeSearch,
className: isError && styleInputError,
disabled: disabled
}));
}
default:
return null;
}
})())), inlineElement && /*#__PURE__*/ React.createElement("div", {
className: "shrink-0"
}, inlineElement)), type !== "checkbox" && description && !isError && /*#__PURE__*/ React.createElement(FormDescription, null, description), /*#__PURE__*/ React.createElement(FormMessage, null));
}
});
}
BaseFormField.displayName = "BaseFormField";
function FormLayout({ form, sections, onSubmit, onError, formId, title, description, headerContent, readOnly = false, formRef, children, stepNavigator }) {
const getColSpanClass = (cols)=>{
if (!cols || cols === 1) return "col-span-12 md:col-span-6 xl:col-span-4";
if (cols === 2) return "col-span-12 md:col-span-12 xl:col-span-8";
if (cols === 3) return "col-span-12";
if (cols === 6) return "col-span-12 2xl:col-span-6";
return "col-span-12";
};
return /*#__PURE__*/ React.createElement(Form, form, onSubmit ? /*#__PURE__*/ React.createElement("form", {
onSubmit: form.handleSubmit(onSubmit, onError),
id: formId,
ref: formRef,
className: "relative space-y-8"
}, (title || description) && /*#__PURE__*/ React.createElement("div", {
className: "mb-6 space-y-2"
}, /*#__PURE__*/ React.createElement("div", {
className: "flex items-start justify-between"
}, /*#__PURE__*/ React.createElement("div", null, title && /*#__PURE__*/ React.createElement("h2", {
className: "text-xl font-semibold tracking-tight"
}, title), description && /*#__PURE__*/ React.createElement("p", {
className: "text-muted-foreground text-sm"
}, description)), headerContent)), children, sections?.map((section, idx)=>/*#__PURE__*/ React.createElement("div", {
key: section.title ? `${section.title}-${idx}` : `section-${idx}`,
className: "space-y-4"
}, (section.title || section.description) && /*#__PURE__*/ React.createElement("div", {
className: "flex items-center gap-2"
}, section.title && /*#__PURE__*/ React.createElement("h3", null, section.title), /*#__PURE__*/ React.createElement(Separator, {
className: "flex-1"
})), /*#__PURE__*/ React.createElement("div", {
className: cn("grid grid-cols-12", readOnly ? "gap-2" : "gap-4")
}, section.fields.map((config)=>/*#__PURE__*/ React.createElement("div", {
key: String(config.name),
className: getColSpanClass(config.cols)
}, /*#__PURE__*/ React.createElement(BaseFormField, {
config: config,
control: form.control,
readOnly: readOnly,
form: form
})))))), stepNavigator) : /*#__PURE__*/ React.createElement("div", {
id: formId,
className: "relative space-y-8 px-1"
}, children, sections?.map((section, idx)=>/*#__PURE__*/ React.createElement("div", {
key: section.title ? `${section.title}-${idx}` : `section-${idx}`,
className: "space-y-4"
}, (section.title || section.description) && /*#__PURE__*/ React.createElement("div", {
className: "flex items-center gap-2"
}, section.title && /*#__PURE__*/ React.createElement("h3", null, section.title), /*#__PURE__*/ React.createElement(Separator, {
className: "flex-1"
})), /*#__PURE__*/ React.createElement("div", {
className: cn("grid grid-cols-12", readOnly ? "gap-2" : "gap-4")
}, section.fields.map((config)=>/*#__PURE__*/ React.createElement("div", {
key: String(config.name),
className: getColSpanClass(config.cols)
}, /*#__PURE__*/ React.createElement(BaseFormField, {
config: config,
control: form.control,
readOnly: readOnly,
form: form
})))))), stepNavigator));
}
FormLayout.displayName = "FormLayout";
export { BaseFormField, FormLayout };
//# sourceMappingURL=index.mjs.map