hazo_ui 2.1.2 → 2.2.1
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/README.md +286 -33
- package/dist/index.cjs +205 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -13
- package/dist/index.d.ts +37 -13
- package/dist/index.js +202 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -662,7 +662,7 @@ function FilterFieldItem({
|
|
|
662
662
|
)
|
|
663
663
|
] });
|
|
664
664
|
}
|
|
665
|
-
function
|
|
665
|
+
function HazoUiMultiFilterDialog({
|
|
666
666
|
availableFields,
|
|
667
667
|
onFilterChange,
|
|
668
668
|
initialFilters = []
|
|
@@ -982,7 +982,7 @@ function SortableSortFieldItem({
|
|
|
982
982
|
}
|
|
983
983
|
);
|
|
984
984
|
}
|
|
985
|
-
function
|
|
985
|
+
function HazoUiMultiSortDialog({
|
|
986
986
|
availableFields,
|
|
987
987
|
onSortChange,
|
|
988
988
|
initialSortFields = []
|
|
@@ -1247,7 +1247,7 @@ function getIconComponent(iconSet, iconName) {
|
|
|
1247
1247
|
const IconComponent = iconLibrary[iconName];
|
|
1248
1248
|
return IconComponent || null;
|
|
1249
1249
|
}
|
|
1250
|
-
function
|
|
1250
|
+
function HazoUiFlexRadio({
|
|
1251
1251
|
layout = "horizontal",
|
|
1252
1252
|
style = "radio",
|
|
1253
1253
|
display_label = true,
|
|
@@ -1432,7 +1432,7 @@ function MultiStateRadio({
|
|
|
1432
1432
|
] }, item.value);
|
|
1433
1433
|
};
|
|
1434
1434
|
const containerClasses = cn(
|
|
1435
|
-
"
|
|
1435
|
+
"cls_hazo_ui_flex_radio border border-input rounded-md",
|
|
1436
1436
|
compressed ? "" : "p-2 sm:p-3",
|
|
1437
1437
|
layout === "horizontal" ? cn(
|
|
1438
1438
|
"flex flex-row flex-wrap",
|
|
@@ -1466,10 +1466,208 @@ function MultiStateRadio({
|
|
|
1466
1466
|
}
|
|
1467
1467
|
}
|
|
1468
1468
|
}
|
|
1469
|
+
function validateInput(value, input_type, text_len_min, text_len_max, num_min, num_max, regex, num_decimals) {
|
|
1470
|
+
if (value === "") {
|
|
1471
|
+
return { isValid: true };
|
|
1472
|
+
}
|
|
1473
|
+
switch (input_type) {
|
|
1474
|
+
case "numeric": {
|
|
1475
|
+
const numValue = parseFloat(value);
|
|
1476
|
+
if (isNaN(numValue)) {
|
|
1477
|
+
return { isValid: false, errorMessage: "Must be a valid number" };
|
|
1478
|
+
}
|
|
1479
|
+
if (num_decimals !== void 0) {
|
|
1480
|
+
const decimalPlaces = value.split(".")[1]?.length || 0;
|
|
1481
|
+
if (decimalPlaces > num_decimals) {
|
|
1482
|
+
return {
|
|
1483
|
+
isValid: false,
|
|
1484
|
+
errorMessage: `Maximum ${num_decimals} decimal place${num_decimals !== 1 ? "s" : ""} allowed`
|
|
1485
|
+
};
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
if (num_min !== void 0 && numValue < num_min) {
|
|
1489
|
+
return { isValid: false, errorMessage: `Must be at least ${num_min}` };
|
|
1490
|
+
}
|
|
1491
|
+
if (num_max !== void 0 && numValue > num_max) {
|
|
1492
|
+
return { isValid: false, errorMessage: `Must be at most ${num_max}` };
|
|
1493
|
+
}
|
|
1494
|
+
break;
|
|
1495
|
+
}
|
|
1496
|
+
case "alpha": {
|
|
1497
|
+
const alphaRegex = /^[A-Za-z\s]*$/;
|
|
1498
|
+
if (!alphaRegex.test(value)) {
|
|
1499
|
+
return { isValid: false, errorMessage: "Only letters are allowed" };
|
|
1500
|
+
}
|
|
1501
|
+
break;
|
|
1502
|
+
}
|
|
1503
|
+
case "email": {
|
|
1504
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
1505
|
+
if (!emailRegex.test(value)) {
|
|
1506
|
+
return { isValid: false, errorMessage: "Must be a valid email address" };
|
|
1507
|
+
}
|
|
1508
|
+
break;
|
|
1509
|
+
}
|
|
1510
|
+
case "mixed": {
|
|
1511
|
+
if (text_len_min !== void 0 && value.length < text_len_min) {
|
|
1512
|
+
return {
|
|
1513
|
+
isValid: false,
|
|
1514
|
+
errorMessage: `Must be at least ${text_len_min} character${text_len_min !== 1 ? "s" : ""}`
|
|
1515
|
+
};
|
|
1516
|
+
}
|
|
1517
|
+
if (text_len_max !== void 0 && value.length > text_len_max) {
|
|
1518
|
+
return {
|
|
1519
|
+
isValid: false,
|
|
1520
|
+
errorMessage: `Must be at most ${text_len_max} character${text_len_max !== 1 ? "s" : ""}`
|
|
1521
|
+
};
|
|
1522
|
+
}
|
|
1523
|
+
break;
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
if (regex) {
|
|
1527
|
+
const regexPattern = typeof regex === "string" ? new RegExp(regex) : regex;
|
|
1528
|
+
if (!regexPattern.test(value)) {
|
|
1529
|
+
return { isValid: false, errorMessage: "Invalid format" };
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
return { isValid: true };
|
|
1533
|
+
}
|
|
1534
|
+
function filterInputValue(value, input_type, num_decimals) {
|
|
1535
|
+
switch (input_type) {
|
|
1536
|
+
case "numeric": {
|
|
1537
|
+
let filtered = value.replace(/[^\d.-]/g, "");
|
|
1538
|
+
const parts = filtered.split(".");
|
|
1539
|
+
if (parts.length > 2) {
|
|
1540
|
+
filtered = parts[0] + "." + parts.slice(1).join("");
|
|
1541
|
+
}
|
|
1542
|
+
if (num_decimals === 0 && filtered.includes(".")) {
|
|
1543
|
+
filtered = filtered.replace(".", "");
|
|
1544
|
+
}
|
|
1545
|
+
if (num_decimals !== void 0 && num_decimals > 0) {
|
|
1546
|
+
const parts2 = filtered.split(".");
|
|
1547
|
+
if (parts2.length === 2 && parts2[1].length > num_decimals) {
|
|
1548
|
+
filtered = parts2[0] + "." + parts2[1].substring(0, num_decimals);
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
return filtered;
|
|
1552
|
+
}
|
|
1553
|
+
case "alpha": {
|
|
1554
|
+
return value.replace(/[^A-Za-z\s]/g, "");
|
|
1555
|
+
}
|
|
1556
|
+
case "email":
|
|
1557
|
+
case "mixed":
|
|
1558
|
+
default: {
|
|
1559
|
+
return value;
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
var HazoUiFlexInput = React6__namespace.forwardRef(
|
|
1564
|
+
({
|
|
1565
|
+
className,
|
|
1566
|
+
input_type = "mixed",
|
|
1567
|
+
text_len_min,
|
|
1568
|
+
text_len_max,
|
|
1569
|
+
num_min,
|
|
1570
|
+
num_max,
|
|
1571
|
+
regex,
|
|
1572
|
+
num_decimals,
|
|
1573
|
+
format_guide,
|
|
1574
|
+
format_guide_info = false,
|
|
1575
|
+
value: controlledValue,
|
|
1576
|
+
onChange,
|
|
1577
|
+
onBlur,
|
|
1578
|
+
...props
|
|
1579
|
+
}, ref) => {
|
|
1580
|
+
const [internalValue, setInternalValue] = React6__namespace.useState(
|
|
1581
|
+
typeof controlledValue === "string" ? controlledValue : typeof controlledValue === "number" ? String(controlledValue) : ""
|
|
1582
|
+
);
|
|
1583
|
+
const [errorMessage, setErrorMessage] = React6__namespace.useState();
|
|
1584
|
+
const isControlled = controlledValue !== void 0;
|
|
1585
|
+
const currentValue = isControlled ? typeof controlledValue === "string" ? controlledValue : String(controlledValue || "") : internalValue;
|
|
1586
|
+
React6__namespace.useEffect(() => {
|
|
1587
|
+
if (isControlled) {
|
|
1588
|
+
const newValue = typeof controlledValue === "string" ? controlledValue : String(controlledValue || "");
|
|
1589
|
+
if (newValue !== internalValue) {
|
|
1590
|
+
setInternalValue(newValue);
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
}, [controlledValue, isControlled]);
|
|
1594
|
+
const handleChange = (e) => {
|
|
1595
|
+
let newValue = e.target.value;
|
|
1596
|
+
if (input_type === "numeric" || input_type === "alpha") {
|
|
1597
|
+
newValue = filterInputValue(newValue, input_type, num_decimals);
|
|
1598
|
+
}
|
|
1599
|
+
if (!isControlled) {
|
|
1600
|
+
setInternalValue(newValue);
|
|
1601
|
+
}
|
|
1602
|
+
if (errorMessage) {
|
|
1603
|
+
setErrorMessage(void 0);
|
|
1604
|
+
}
|
|
1605
|
+
if (onChange) {
|
|
1606
|
+
const syntheticEvent = {
|
|
1607
|
+
...e,
|
|
1608
|
+
target: { ...e.target, value: newValue }
|
|
1609
|
+
};
|
|
1610
|
+
onChange(syntheticEvent);
|
|
1611
|
+
}
|
|
1612
|
+
};
|
|
1613
|
+
const handleBlur = (e) => {
|
|
1614
|
+
const validation = validateInput(
|
|
1615
|
+
currentValue,
|
|
1616
|
+
input_type,
|
|
1617
|
+
text_len_min,
|
|
1618
|
+
text_len_max,
|
|
1619
|
+
num_min,
|
|
1620
|
+
num_max,
|
|
1621
|
+
regex,
|
|
1622
|
+
num_decimals
|
|
1623
|
+
);
|
|
1624
|
+
if (!validation.isValid) {
|
|
1625
|
+
setErrorMessage(validation.errorMessage || format_guide || "Invalid input");
|
|
1626
|
+
} else {
|
|
1627
|
+
setErrorMessage(void 0);
|
|
1628
|
+
}
|
|
1629
|
+
if (onBlur) {
|
|
1630
|
+
onBlur(e);
|
|
1631
|
+
}
|
|
1632
|
+
};
|
|
1633
|
+
const htmlInputType = input_type === "email" ? "email" : input_type === "numeric" ? "text" : "text";
|
|
1634
|
+
const hasError = errorMessage !== void 0;
|
|
1635
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_hazo_ui_flex_input_container w-full", children: [
|
|
1636
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1637
|
+
Input,
|
|
1638
|
+
{
|
|
1639
|
+
ref,
|
|
1640
|
+
type: htmlInputType,
|
|
1641
|
+
value: currentValue,
|
|
1642
|
+
onChange: handleChange,
|
|
1643
|
+
onBlur: handleBlur,
|
|
1644
|
+
className: cn(
|
|
1645
|
+
hasError && "border-destructive focus-visible:ring-destructive",
|
|
1646
|
+
className
|
|
1647
|
+
),
|
|
1648
|
+
...props
|
|
1649
|
+
}
|
|
1650
|
+
),
|
|
1651
|
+
hasError && errorMessage && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "cls_error_message mt-1 text-sm text-destructive", children: errorMessage }),
|
|
1652
|
+
format_guide_info && format_guide && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1653
|
+
"p",
|
|
1654
|
+
{
|
|
1655
|
+
className: cn(
|
|
1656
|
+
"cls_format_guide_info mt-1 text-xs italic text-muted-foreground",
|
|
1657
|
+
hasError && "mt-0"
|
|
1658
|
+
),
|
|
1659
|
+
children: format_guide
|
|
1660
|
+
}
|
|
1661
|
+
)
|
|
1662
|
+
] });
|
|
1663
|
+
}
|
|
1664
|
+
);
|
|
1665
|
+
HazoUiFlexInput.displayName = "HazoUiFlexInput";
|
|
1469
1666
|
|
|
1470
1667
|
exports.ExampleComponent = ExampleComponent;
|
|
1471
|
-
exports.
|
|
1472
|
-
exports.
|
|
1473
|
-
exports.
|
|
1668
|
+
exports.HazoUiFlexInput = HazoUiFlexInput;
|
|
1669
|
+
exports.HazoUiFlexRadio = HazoUiFlexRadio;
|
|
1670
|
+
exports.HazoUiMultiFilterDialog = HazoUiMultiFilterDialog;
|
|
1671
|
+
exports.HazoUiMultiSortDialog = HazoUiMultiSortDialog;
|
|
1474
1672
|
//# sourceMappingURL=index.cjs.map
|
|
1475
1673
|
//# sourceMappingURL=index.cjs.map
|