@oondemand/oon-core-front 0.3.31 → 0.3.32
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 +164 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1369,6 +1369,111 @@ function ReferenceSelect({
|
|
|
1369
1369
|
] });
|
|
1370
1370
|
}
|
|
1371
1371
|
|
|
1372
|
+
// src/components/internal/inputMasks.ts
|
|
1373
|
+
var digitsOnly = (value) => String(value ?? "").replace(/\D/g, "");
|
|
1374
|
+
var normalizedName = (value) => String(value ?? "").normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
|
|
1375
|
+
var hasLetters = (value) => /[a-zA-Z]/.test(String(value ?? ""));
|
|
1376
|
+
function personType(values) {
|
|
1377
|
+
return normalizedName(values?.tipo ?? values?.tipoPessoa ?? values?.pessoaTipo);
|
|
1378
|
+
}
|
|
1379
|
+
function resolveInputMask(field, values) {
|
|
1380
|
+
if (field.mask) return field.mask;
|
|
1381
|
+
if (field.kind === "currency" || field.kind === "currencyConverted") return "currency";
|
|
1382
|
+
if (field.kind && !["string", "number"].includes(field.kind)) return void 0;
|
|
1383
|
+
const name = normalizedName(field.field);
|
|
1384
|
+
if (!name) return void 0;
|
|
1385
|
+
if (name.includes("cnpj")) return "cnpj";
|
|
1386
|
+
if (name.includes("cpf")) return "cpf";
|
|
1387
|
+
if (/documento|document|inscricaofiscal/.test(name)) {
|
|
1388
|
+
const tipo = personType(values);
|
|
1389
|
+
if (tipo === "est" || tipo.includes("estrangeir") || tipo.includes("foreign")) return void 0;
|
|
1390
|
+
if (tipo === "pf" || tipo.includes("fisica")) return "cpf";
|
|
1391
|
+
if (tipo === "pj" || tipo.includes("juridica")) return "cnpj";
|
|
1392
|
+
return "document";
|
|
1393
|
+
}
|
|
1394
|
+
if (/telefone|celular|whatsapp|fone|phone/.test(name)) return "phone";
|
|
1395
|
+
return void 0;
|
|
1396
|
+
}
|
|
1397
|
+
function formatCpf(value) {
|
|
1398
|
+
const digits = digitsOnly(value).slice(0, 11);
|
|
1399
|
+
return digits.replace(/^(\d{3})(\d)/, "$1.$2").replace(/^(\d{3})\.(\d{3})(\d)/, "$1.$2.$3").replace(/\.(\d{3})(\d)/, ".$1-$2");
|
|
1400
|
+
}
|
|
1401
|
+
function formatCnpj(value) {
|
|
1402
|
+
const digits = digitsOnly(value).slice(0, 14);
|
|
1403
|
+
return digits.replace(/^(\d{2})(\d)/, "$1.$2").replace(/^(\d{2})\.(\d{3})(\d)/, "$1.$2.$3").replace(/\.(\d{3})(\d)/, ".$1/$2").replace(/(\/\d{4})(\d)/, "$1-$2");
|
|
1404
|
+
}
|
|
1405
|
+
function formatPhone(value) {
|
|
1406
|
+
const digits = digitsOnly(value).slice(0, 11);
|
|
1407
|
+
if (!digits) return "";
|
|
1408
|
+
if (digits.length <= 2) return `(${digits}`;
|
|
1409
|
+
const ddd = digits.slice(0, 2);
|
|
1410
|
+
const number = digits.slice(2);
|
|
1411
|
+
const prefixLength = number.length > 8 ? 5 : 4;
|
|
1412
|
+
const prefix = number.slice(0, prefixLength);
|
|
1413
|
+
const suffix = number.slice(prefixLength);
|
|
1414
|
+
return `(${ddd}) ${prefix}${suffix ? `-${suffix}` : ""}`;
|
|
1415
|
+
}
|
|
1416
|
+
function parseCurrencyInitial(value) {
|
|
1417
|
+
if (value == null || value === "") return "";
|
|
1418
|
+
if (typeof value === "number") return Number.isFinite(value) ? String(value) : "";
|
|
1419
|
+
const raw = String(value).trim();
|
|
1420
|
+
if (!raw) return "";
|
|
1421
|
+
if (/^-?\d+(?:\.\d+)?$/.test(raw)) return raw;
|
|
1422
|
+
const localized = raw.replace(/[^\d,.-]/g, "").replace(/\.(?=\d{3}(?:\D|$))/g, "").replace(",", ".");
|
|
1423
|
+
const parsed = Number(localized);
|
|
1424
|
+
return Number.isFinite(parsed) ? String(parsed) : "";
|
|
1425
|
+
}
|
|
1426
|
+
function formatCurrency(value) {
|
|
1427
|
+
const normalized = parseCurrencyInitial(value);
|
|
1428
|
+
if (!normalized) return "";
|
|
1429
|
+
const numeric = Number(normalized);
|
|
1430
|
+
if (!Number.isFinite(numeric)) return "";
|
|
1431
|
+
return new Intl.NumberFormat("pt-BR", {
|
|
1432
|
+
style: "currency",
|
|
1433
|
+
currency: "BRL",
|
|
1434
|
+
minimumFractionDigits: 2,
|
|
1435
|
+
maximumFractionDigits: 2
|
|
1436
|
+
}).format(numeric);
|
|
1437
|
+
}
|
|
1438
|
+
function normalizeMaskedValue(value, mask) {
|
|
1439
|
+
if (!mask) return String(value ?? "");
|
|
1440
|
+
if (mask === "currency") return parseCurrencyInitial(value);
|
|
1441
|
+
if (mask === "document" && hasLetters(value)) return String(value ?? "").slice(0, 30);
|
|
1442
|
+
const limit = mask === "cnpj" ? 14 : mask === "cpf" ? 11 : mask === "phone" ? 11 : 14;
|
|
1443
|
+
return digitsOnly(value).slice(0, limit);
|
|
1444
|
+
}
|
|
1445
|
+
function formatMaskedValue(value, mask) {
|
|
1446
|
+
if (!mask) return String(value ?? "");
|
|
1447
|
+
if (mask === "currency") return formatCurrency(value);
|
|
1448
|
+
if (mask === "phone") return formatPhone(value);
|
|
1449
|
+
if (mask === "cpf") return formatCpf(value);
|
|
1450
|
+
if (mask === "cnpj") return formatCnpj(value);
|
|
1451
|
+
if (hasLetters(value)) return String(value ?? "");
|
|
1452
|
+
const digits = digitsOnly(value);
|
|
1453
|
+
return digits.length > 11 ? formatCnpj(digits) : formatCpf(digits);
|
|
1454
|
+
}
|
|
1455
|
+
function parseMaskedInput(value, mask) {
|
|
1456
|
+
if (!mask) return value;
|
|
1457
|
+
if (mask === "currency") {
|
|
1458
|
+
const digits = digitsOnly(value);
|
|
1459
|
+
if (!digits) return "";
|
|
1460
|
+
const amount = Number(digits) / 100;
|
|
1461
|
+
return `${value.includes("-") ? "-" : ""}${amount.toFixed(2)}`;
|
|
1462
|
+
}
|
|
1463
|
+
return normalizeMaskedValue(value, mask);
|
|
1464
|
+
}
|
|
1465
|
+
function inputModeForMask(mask) {
|
|
1466
|
+
if (mask === "document") return "text";
|
|
1467
|
+
return mask ? "numeric" : void 0;
|
|
1468
|
+
}
|
|
1469
|
+
function maxLengthForMask(mask) {
|
|
1470
|
+
if (mask === "cpf") return 14;
|
|
1471
|
+
if (mask === "cnpj") return 18;
|
|
1472
|
+
if (mask === "document") return 30;
|
|
1473
|
+
if (mask === "phone") return 15;
|
|
1474
|
+
return void 0;
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1372
1477
|
// src/components/internal/DynamicForm.tsx
|
|
1373
1478
|
import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1374
1479
|
var idFor = (field) => `oon-form-field-${field.replace(/[^a-zA-Z0-9_-]/g, "-")}`;
|
|
@@ -1404,6 +1509,9 @@ function toValue(value, kind) {
|
|
|
1404
1509
|
}
|
|
1405
1510
|
return String(value);
|
|
1406
1511
|
}
|
|
1512
|
+
function initialFieldValue(field, value) {
|
|
1513
|
+
return normalizeMaskedValue(toValue(value, field.kind), resolveInputMask(field));
|
|
1514
|
+
}
|
|
1407
1515
|
function coerce(value, kind) {
|
|
1408
1516
|
if (value === "") return void 0;
|
|
1409
1517
|
if (["number", "currency", "currencyConverted"].includes(kind ?? "")) return Number(value);
|
|
@@ -1509,7 +1617,7 @@ function resolveReference(field, values) {
|
|
|
1509
1617
|
return { filters, disabled: missing.length > 0 };
|
|
1510
1618
|
}
|
|
1511
1619
|
function DynamicForm({ title, eyebrow = "Cadastro", fields, initialValues, submitting, error, onSubmit, onCancel, onFieldChange }) {
|
|
1512
|
-
const [values, setValues] = useState5(() => Object.fromEntries(fields.map((field) => [field.field,
|
|
1620
|
+
const [values, setValues] = useState5(() => Object.fromEntries(fields.map((field) => [field.field, initialFieldValue(field, initialValues?.[field.field])])));
|
|
1513
1621
|
const [errors, setErrors] = useState5({});
|
|
1514
1622
|
const [dismissed, setDismissed] = useState5(false);
|
|
1515
1623
|
const items = useMemo4(() => buildItems(fields), [fields]);
|
|
@@ -1632,7 +1740,7 @@ function DynamicForm({ title, eyebrow = "Cadastro", fields, initialValues, submi
|
|
|
1632
1740
|
}
|
|
1633
1741
|
if (field.kind === "ref" && field.ref) {
|
|
1634
1742
|
const reference = resolveReference(field, values);
|
|
1635
|
-
return wrap(/* @__PURE__ */ jsx9(ReferenceSelect, { field: field.field, inputId: id, errorId, label, refModel: field.ref, value: values[field.field] ?? "", initialValue: initialValues?.[field.field], required: field.required, invalid: !!message, error: message, filters: reference.filters, emptyFields: field.referenceEmptyFields, disabled: reference.disabled, disabledMessage: field.referenceDisabledMessage, onChange: (
|
|
1743
|
+
return wrap(/* @__PURE__ */ jsx9(ReferenceSelect, { field: field.field, inputId: id, errorId, label, refModel: field.ref, value: values[field.field] ?? "", initialValue: initialValues?.[field.field], required: field.required, invalid: !!message, error: message, filters: reference.filters, emptyFields: field.referenceEmptyFields, disabled: reference.disabled, disabledMessage: field.referenceDisabledMessage, onChange: (value2) => change(field.field, value2) }));
|
|
1636
1744
|
}
|
|
1637
1745
|
if (field.kind === "enum" && field.options?.length) return wrap(/* @__PURE__ */ jsxs5(NativeSelect2.Root, { size: "sm", children: [
|
|
1638
1746
|
/* @__PURE__ */ jsxs5(NativeSelect2.Field, { id, "aria-invalid": !!message, "aria-describedby": errorId, value: values[field.field] ?? "", ...controlProps(!!message), onChange: (event) => change(field.field, event.currentTarget.value), children: [
|
|
@@ -1650,8 +1758,27 @@ function DynamicForm({ title, eyebrow = "Cadastro", fields, initialValues, submi
|
|
|
1650
1758
|
/* @__PURE__ */ jsx9(NativeSelect2.Indicator, {})
|
|
1651
1759
|
] }));
|
|
1652
1760
|
if (multiline) return wrap(/* @__PURE__ */ jsx9(Textarea, { id, rows: field.rows ?? 4, resize: "vertical", "aria-invalid": !!message, "aria-describedby": errorId, value: values[field.field] ?? "", ...controlProps(!!message), lineHeight: "1.5", onChange: (event) => change(field.field, event.currentTarget.value) }));
|
|
1653
|
-
const
|
|
1654
|
-
|
|
1761
|
+
const mask = resolveInputMask(field);
|
|
1762
|
+
const type = mask ? "text" : field.kind === "date" ? "date" : field.kind === "number" ? "number" : "text";
|
|
1763
|
+
const value = values[field.field] ?? "";
|
|
1764
|
+
return wrap(
|
|
1765
|
+
/* @__PURE__ */ jsx9(
|
|
1766
|
+
Input3,
|
|
1767
|
+
{
|
|
1768
|
+
id,
|
|
1769
|
+
type,
|
|
1770
|
+
step: type === "number" ? "any" : void 0,
|
|
1771
|
+
inputMode: inputModeForMask(mask),
|
|
1772
|
+
maxLength: maxLengthForMask(mask),
|
|
1773
|
+
autoComplete: "off",
|
|
1774
|
+
"aria-invalid": !!message,
|
|
1775
|
+
"aria-describedby": errorId,
|
|
1776
|
+
value: mask ? formatMaskedValue(value, mask) : value,
|
|
1777
|
+
...controlProps(!!message),
|
|
1778
|
+
onChange: (event) => change(field.field, parseMaskedInput(event.currentTarget.value, mask))
|
|
1779
|
+
}
|
|
1780
|
+
)
|
|
1781
|
+
);
|
|
1655
1782
|
};
|
|
1656
1783
|
const invalid = fields.filter((field) => errors[field.field]);
|
|
1657
1784
|
const generic = dismissed ? null : messageOf(error);
|
|
@@ -1775,7 +1902,13 @@ import { Input as Input4, NativeSelect as NativeSelect3, Textarea as Textarea2 }
|
|
|
1775
1902
|
import { jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1776
1903
|
function CoreInlineEditableCell({ column, meta, value, onChange }) {
|
|
1777
1904
|
const kind = column.editor ?? meta?.kind ?? column.kind ?? "string";
|
|
1778
|
-
const
|
|
1905
|
+
const plainValue = value == null ? "" : String(value);
|
|
1906
|
+
const common = {
|
|
1907
|
+
size: "xs",
|
|
1908
|
+
fontSize: "11px",
|
|
1909
|
+
value: plainValue,
|
|
1910
|
+
onChange: (event) => onChange(event.currentTarget.value)
|
|
1911
|
+
};
|
|
1779
1912
|
if (kind === "boolean") return /* @__PURE__ */ jsxs7(NativeSelect3.Root, { size: "xs", children: [
|
|
1780
1913
|
/* @__PURE__ */ jsxs7(NativeSelect3.Field, { ...common, children: [
|
|
1781
1914
|
/* @__PURE__ */ jsx11("option", { value: "", children: "\u2014" }),
|
|
@@ -1792,8 +1925,21 @@ function CoreInlineEditableCell({ column, meta, value, onChange }) {
|
|
|
1792
1925
|
/* @__PURE__ */ jsx11(NativeSelect3.Indicator, {})
|
|
1793
1926
|
] });
|
|
1794
1927
|
if (kind === "textarea") return /* @__PURE__ */ jsx11(Textarea2, { ...common, rows: 2 });
|
|
1795
|
-
const
|
|
1796
|
-
|
|
1928
|
+
const mask = resolveInputMask({ field: column.field, kind });
|
|
1929
|
+
const type = mask ? "text" : kind === "date" ? "date" : kind === "number" ? "number" : "text";
|
|
1930
|
+
return /* @__PURE__ */ jsx11(
|
|
1931
|
+
Input4,
|
|
1932
|
+
{
|
|
1933
|
+
size: "xs",
|
|
1934
|
+
fontSize: "11px",
|
|
1935
|
+
type,
|
|
1936
|
+
step: type === "number" ? "any" : void 0,
|
|
1937
|
+
inputMode: inputModeForMask(mask),
|
|
1938
|
+
maxLength: maxLengthForMask(mask),
|
|
1939
|
+
value: mask ? formatMaskedValue(plainValue, mask) : plainValue,
|
|
1940
|
+
onChange: (event) => onChange(parseMaskedInput(event.currentTarget.value, mask))
|
|
1941
|
+
}
|
|
1942
|
+
);
|
|
1797
1943
|
}
|
|
1798
1944
|
|
|
1799
1945
|
// src/components/internal/CoreRowAction.tsx
|
|
@@ -2120,6 +2266,9 @@ function toValue2(value, kind) {
|
|
|
2120
2266
|
}
|
|
2121
2267
|
return String(value);
|
|
2122
2268
|
}
|
|
2269
|
+
function initialFieldValue2(field, value) {
|
|
2270
|
+
return normalizeMaskedValue(toValue2(value, field.kind), resolveInputMask(field));
|
|
2271
|
+
}
|
|
2123
2272
|
function isMultiline2(field) {
|
|
2124
2273
|
return /observa|descricao|mensagem|detalhe|necessidade/i.test(field.field);
|
|
2125
2274
|
}
|
|
@@ -2273,6 +2422,7 @@ function FieldControl({
|
|
|
2273
2422
|
)
|
|
2274
2423
|
] });
|
|
2275
2424
|
}
|
|
2425
|
+
const mask = resolveInputMask(field);
|
|
2276
2426
|
const control = field.kind === "enum" && field.options?.length ? /* @__PURE__ */ jsxs10(NativeSelect4.Root, { size: "sm", children: [
|
|
2277
2427
|
/* @__PURE__ */ jsxs10(NativeSelect4.Field, { id: inputId, value, ...invalidProps, onChange: (event) => onChange(event.currentTarget.value), children: [
|
|
2278
2428
|
/* @__PURE__ */ jsx14("option", { value: "", children: "\u2014 Selecione \u2014" }),
|
|
@@ -2291,10 +2441,13 @@ function FieldControl({
|
|
|
2291
2441
|
{
|
|
2292
2442
|
id: inputId,
|
|
2293
2443
|
size: "sm",
|
|
2294
|
-
type: field.kind === "date" ? "date" :
|
|
2295
|
-
|
|
2444
|
+
type: mask ? "text" : field.kind === "date" ? "date" : field.kind === "number" ? "number" : "text",
|
|
2445
|
+
step: !mask && field.kind === "number" ? "any" : void 0,
|
|
2446
|
+
inputMode: inputModeForMask(mask),
|
|
2447
|
+
maxLength: maxLengthForMask(mask),
|
|
2448
|
+
value: mask ? formatMaskedValue(value, mask) : value,
|
|
2296
2449
|
...invalidProps,
|
|
2297
|
-
onChange: (event) => onChange(event.currentTarget.value)
|
|
2450
|
+
onChange: (event) => onChange(parseMaskedInput(event.currentTarget.value, mask))
|
|
2298
2451
|
}
|
|
2299
2452
|
);
|
|
2300
2453
|
return /* @__PURE__ */ jsxs10(Box7, { children: [
|
|
@@ -2343,7 +2496,7 @@ function InlineParentForm({
|
|
|
2343
2496
|
const [error, setError] = useState8(null);
|
|
2344
2497
|
const [fieldErrors, setFieldErrors] = useState8({});
|
|
2345
2498
|
useEffect5(() => {
|
|
2346
|
-
setValues(Object.fromEntries(fields.map((field) => [field.field,
|
|
2499
|
+
setValues(Object.fromEntries(fields.map((field) => [field.field, initialFieldValue2(field, parent[field.field])])));
|
|
2347
2500
|
setError(null);
|
|
2348
2501
|
setFieldErrors({});
|
|
2349
2502
|
}, [parent, rawFields]);
|