ivt
Version:
Ivt Components Library
206 lines (203 loc) • 10.8 kB
JavaScript
import React__default from 'react';
import { N as NumericFormat } from '../chunks/react-number-format.es-DSc45Db0.mjs';
import { c as cn } from '../chunks/utils-05LlW3Cl.mjs';
import { C as Checkbox } from '../chunks/checkbox-D9LLByPZ.mjs';
import { T as Table, a as TableHeader, e as TableRow, d as TableHead, b as TableBody, f as TableCell } from '../chunks/table-Bxaxu8Lu.mjs';
import { S as Select, h as SelectTrigger, i as SelectValue, a as SelectContent, c as SelectItem } from '../chunks/select-C4BJbkha.mjs';
import { I as Input } from '../chunks/input-BEkvMaQp.mjs';
import { B as Button } from '../chunks/button-Co_1yLv6.mjs';
import '../chunks/bundle-mjs-BYcyWisL.mjs';
import '../chunks/index-1tQVI0Jh.mjs';
import '../chunks/index-DT8WgpCS.mjs';
import 'react/jsx-runtime';
import '../chunks/index-Bl-WJHvp.mjs';
import '../chunks/index-D4FMFHi9.mjs';
import '../chunks/index-DKOlG3mh.mjs';
import '../chunks/index-FL3PKmOS.mjs';
import '../chunks/index-DmY774z-.mjs';
import '../chunks/index-C6s8KI_8.mjs';
import '../chunks/index-DgKlJYZP.mjs';
import 'react-dom';
import '@radix-ui/react-slot';
import '../chunks/check-BBGTedl-.mjs';
import '../chunks/createLucideIcon-DLrNgMqk.mjs';
import '@radix-ui/react-select';
import '../chunks/chevron-down-DNXEgdv9.mjs';
import 'class-variance-authority';
const styleInput = "border-input file:text-foreground placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:ring-1 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm";
function formatNumberWithComma({ value, minimumFractionDigits = 0, maximumFractionDigits = 12, currency }) {
const options = {
minimumFractionDigits,
maximumFractionDigits
};
if (currency) {
options.style = "currency";
options.currency = currency;
}
// Conversão segura para evitar NaN
const numberValue = Number(value);
if (Number.isNaN(numberValue)) return String(value);
const formatter = new Intl.NumberFormat("pt-BR", options);
return formatter.format(numberValue);
}
// biome-ignore lint/suspicious/noExplicitAny: <any>
function EditableTable({ data, columns, rowKey, onSave, onChange, onCancel, className, isIntegrationTable = true }) {
const [editing, setEditing] = React__default.useState(null);
const [tempValues, setTempValues] = React__default.useState({});
// biome-ignore lint/suspicious/noExplicitAny: <any>
const handleTempChange = (id, field, value)=>{
setTempValues((prev)=>({
...prev,
[id]: {
...prev[id],
[field]: value
}
}));
onChange?.(id, field, value);
};
const confirmEditing = async (id, field)=>{
const value = tempValues[id]?.[field];
const row = data.find((r)=>r[rowKey] === id);
if (!row) return;
if (value !== undefined) await onSave(field, value, row);
setEditing(null);
setTempValues((prev)=>{
const next = {
...prev
};
delete next[id]?.[field];
return next;
});
window.getSelection()?.removeAllRanges();
};
const cancelEditing = (id, field)=>{
onCancel?.(id, field);
setEditing(null);
window.getSelection()?.removeAllRanges();
};
return /*#__PURE__*/ React__default.createElement("div", {
className: cn("overflow-x-auto rounded-lg", className)
}, /*#__PURE__*/ React__default.createElement(Table, {
className: "min-w-full"
}, /*#__PURE__*/ React__default.createElement(TableHeader, {
className: "bg-card sticky top-0 z-5"
}, /*#__PURE__*/ React__default.createElement(TableRow, null, columns.map((col)=>/*#__PURE__*/ React__default.createElement(TableHead, {
className: "h-10 font-medium",
key: String(col.key)
}, col.label, " ", col.required && /*#__PURE__*/ React__default.createElement("span", {
className: "text-destructive"
}, "*"))))), /*#__PURE__*/ React__default.createElement(TableBody, {
className: "text-muted-foreground"
}, data.map((row, rowIndex)=>/*#__PURE__*/ React__default.createElement(TableRow, {
key: String(row[rowKey]),
className: "even:bg-soft"
}, columns.map((col)=>{
const value = row[col.key];
const rowId = row[rowKey];
const isEditing = editing?.id === rowId && editing.field === col.key;
const cellContent = ()=>{
if (col.render && !isEditing) {
return /*#__PURE__*/ React__default.createElement("div", {
key: String(col.key)
}, col.render(value, row, rowIndex));
}
if (col.type === "select") {
const currentValue = tempValues[rowId]?.[col.key] ?? value ?? "";
const isEditableSelect = rowIndex === 0 || !isIntegrationTable;
if (!isEditableSelect) {
const selectedLabel = col.options?.find((opt)=>String(opt.value) === String(currentValue))?.label ?? "-";
return /*#__PURE__*/ React__default.createElement("div", {
key: `${rowId}-${String(col.key)}-readonly`,
className: "text-foreground px-2 text-sm"
}, selectedLabel);
}
return /*#__PURE__*/ React__default.createElement(Select, {
key: `${rowId}-${String(col.key)}-select`,
value: String(currentValue),
onValueChange: async (val)=>{
handleTempChange(rowId, col.key, val);
const rowData = data.find((r)=>r[rowKey] === rowId);
if (rowData) {
await onSave(col.key, val, rowData);
}
}
}, /*#__PURE__*/ React__default.createElement(SelectTrigger, {
className: "text-foreground bg-background *:svg-text-foreground h-9 w-fit min-w-20 text-sm"
}, /*#__PURE__*/ React__default.createElement(SelectValue, null)), /*#__PURE__*/ React__default.createElement(SelectContent, {
className: "max-h-[300px] overflow-y-auto overflow-x-hidden"
}, col.options?.map((opt)=>/*#__PURE__*/ React__default.createElement(SelectItem, {
key: String(opt.value),
value: String(opt.value)
}, opt.label))));
}
if (col.type === "boolean") {
return /*#__PURE__*/ React__default.createElement(Checkbox, {
key: `${rowId}-${String(col.key)}`,
checked: !!value,
onCheckedChange: (checked)=>{
handleTempChange(rowId, col.key, checked);
const rowData = data.find((r)=>r[rowKey] === rowId);
if (rowData) {
onSave(col.key, checked, rowData);
}
},
onBlur: ()=>confirmEditing(rowId, col.key)
});
}
if (isEditing && col.type === "number") {
return /*#__PURE__*/ React__default.createElement(NumericFormat, {
key: `${rowId}-${String(col.key)}-edit`,
autoFocus: true,
value: tempValues[rowId]?.[col.key] ?? value ?? "",
valueIsNumericString: true,
decimalSeparator: ",",
thousandSeparator: ".",
className: cn(styleInput, "bg-background box-border h-9 w-full"),
onValueChange: (v)=>handleTempChange(rowId, col.key, String(v.floatValue)),
onKeyDown: (e)=>{
if (e.key === "Enter") confirmEditing(rowId, col.key);
if (e.key === "Escape") cancelEditing(rowId, col.key);
},
onBlur: ()=>cancelEditing(rowId, col.key)
});
}
if (isEditing && col.type === "text") {
return /*#__PURE__*/ React__default.createElement(Input, {
key: `${rowId}-${String(col.key)}-edit`,
autoFocus: true,
type: "text",
value: tempValues[rowId]?.[col.key] ?? value ?? "",
className: cn(styleInput, "bg-background box-border h-9 w-full"),
onChange: (e)=>handleTempChange(rowId, col.key, e.target.value),
onKeyDown: (e)=>{
if (e.key === "Enter") confirmEditing(rowId, col.key);
if (e.key === "Escape") cancelEditing(rowId, col.key);
},
onBlur: ()=>cancelEditing(rowId, col.key)
});
}
return /*#__PURE__*/ React__default.createElement(Button, {
variant: "table",
className: cn(styleInput, "bg-background box-border h-9 w-full cursor-default justify-start"),
onClick: ()=>col.editable && setEditing({
id: rowId,
field: col.key
})
}, value === null || value === undefined || value === "" ? col.editable ? "Clique para editar..." : "-" : col.type === "number" ? formatNumberWithComma({
value,
minimumFractionDigits: 2,
maximumFractionDigits: 10
}) || "0,00" : /*#__PURE__*/ React__default.createElement("span", {
className: "truncate block w-full text-left"
}, String(value)));
};
return /*#__PURE__*/ React__default.createElement(TableCell, {
key: String(col.key),
className: "p-2"
}, /*#__PURE__*/ React__default.createElement("div", {
className: "md:w-[150px]"
}, cellContent()));
}))))));
}
export { EditableTable, styleInput };
//# sourceMappingURL=index.mjs.map