sevatech-library 1.0.0 → 1.0.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/dist/esm/index.js CHANGED
@@ -1,26 +1,26 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
- import { Stack, TableCell, tableCellClasses, LinearProgress, linearProgressClasses, useTheme, Skeleton, Box, Icon, Typography, Link, Breadcrumbs, IconButton, Menu, MenuItem, CircularProgress, Button, Chip, Select, Avatar, Container, TextField, InputAdornment, Dialog, DialogContent, DialogActions, styled as styled$1, Autocomplete, Switch } from '@mui/material';
3
- import React, { useState, useRef, useMemo, useCallback, useEffect, useId } from 'react';
2
+ import { Stack, TableCell, tableCellClasses, LinearProgress, linearProgressClasses, useTheme, Skeleton, Box, Icon, Typography, Link, CircularProgress, Button, Dialog, DialogContent, DialogActions, styled as styled$1, Autocomplete, Switch } from '@mui/material';
3
+ import React, { useState } from 'react';
4
4
  import { styled } from '@mui/material/styles';
5
5
  import LinkIcon from '@mui/icons-material/Link';
6
6
  import CheckIcon from '@mui/icons-material/Check';
7
7
  import RemoveIcon from '@mui/icons-material/Remove';
8
8
  import FiberManualRecordIcon from '@mui/icons-material/FiberManualRecord';
9
- import { DatePicker } from '@mui/x-date-pickers/DatePicker';
10
- import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
11
- import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
12
- import dayjs from 'dayjs';
13
- import AddIcon from '@mui/icons-material/Add';
9
+ import '@mui/x-date-pickers/DatePicker';
10
+ import '@mui/x-date-pickers/LocalizationProvider';
11
+ import '@mui/x-date-pickers/AdapterDayjs';
12
+ import 'dayjs';
13
+ import '@mui/icons-material/Add';
14
14
  import MuiTextField from '@mui/material/TextField';
15
15
  import { Form } from 'formik';
16
16
  import Slider from 'react-slick';
17
17
  import 'slick-carousel/slick/slick.css';
18
18
  import 'slick-carousel/slick/slick-theme.css';
19
- import AttachMoneyIcon from '@mui/icons-material/AttachMoney';
20
- import SearchIcon from '@mui/icons-material/Search';
21
- import { LayoutGroup, motion } from 'framer-motion';
22
- import CheckCircleIcon from '@mui/icons-material/CheckCircle';
23
- import RefreshIcon from '@mui/icons-material/Refresh';
19
+ import '@mui/icons-material/AttachMoney';
20
+ import '@mui/icons-material/Search';
21
+ import 'framer-motion';
22
+ import '@mui/icons-material/CheckCircle';
23
+ import '@mui/icons-material/Refresh';
24
24
 
25
25
  const AVATAR_SIZES = {
26
26
  xs: 24,
@@ -231,7 +231,7 @@ const FONT_SIZE_ICON = {
231
231
  medium: '19px',
232
232
  small: '12px',
233
233
  };
234
- const FONT_SIZE_LOADING$1 = {
234
+ const FONT_SIZE_LOADING = {
235
235
  large: 40,
236
236
  medium: 22.5,
237
237
  small: 16,
@@ -272,7 +272,7 @@ var style_constant = /*#__PURE__*/Object.freeze({
272
272
  BORDER_RADIUS_ELEMENT_TAG: BORDER_RADIUS_ELEMENT_TAG,
273
273
  BORDER_RADIUS_ELEMENT_WRAPPER: BORDER_RADIUS_ELEMENT_WRAPPER,
274
274
  FONT_SIZE_ICON: FONT_SIZE_ICON,
275
- FONT_SIZE_LOADING: FONT_SIZE_LOADING$1,
275
+ FONT_SIZE_LOADING: FONT_SIZE_LOADING,
276
276
  GAP_ICON_CONTENT_BY_SIZE: GAP_ICON_CONTENT_BY_SIZE,
277
277
  HEIGHT_DEFAULT_TEXT_FIELD_BUTTON: HEIGHT_DEFAULT_TEXT_FIELD_BUTTON,
278
278
  HEIGHT_ELEMENT_OTHER: HEIGHT_ELEMENT_OTHER,
@@ -908,7 +908,7 @@ styled(Stack)(() => ({
908
908
  alignItems: 'center',
909
909
  justifyContent: 'center',
910
910
  }));
911
- const StackRowAlignCenterJustEnd = styled(Stack)(() => ({
911
+ styled(Stack)(() => ({
912
912
  flexDirection: 'row',
913
913
  alignItems: 'center',
914
914
  justifyContent: 'flex-end',
@@ -921,7 +921,7 @@ styled(Stack)(() => ({
921
921
  flexDirection: 'row',
922
922
  justifyContent: 'space-between',
923
923
  }));
924
- const StackRowAlignCenterJustBetween = styled(Stack)(() => ({
924
+ styled(Stack)(() => ({
925
925
  flexDirection: 'row',
926
926
  alignItems: 'center',
927
927
  justifyContent: 'space-between',
@@ -1200,60 +1200,6 @@ const AvatarUserComponent = ({ title, description, descriptionHref, onDescriptio
1200
1200
  }, children: [jsx(LinkIcon, { sx: { fontSize: 16, color: descriptionColor } }), description] }))] })] }));
1201
1201
  };
1202
1202
 
1203
- const SEPARATOR_URLS = {
1204
- '>': '/images/icon/chevron-right.svg',
1205
- '/': '/images/icon/slash-separator.svg',
1206
- };
1207
- const BreadcrumbsComponent = ({ items, separator = '>', maxItems = 5, idSelect, sx, sxItem, onChange, }) => {
1208
- // state
1209
- const [anchorEl, setAnchorEl] = useState(null);
1210
- const showCollapsed = items.length > maxItems;
1211
- const visibleItems = showCollapsed ? [items[0], ...items.slice(-2)] : items;
1212
- const collapsedItems = showCollapsed ? items.slice(1, -2) : [];
1213
- // function
1214
- const handleMenuOpen = (event) => {
1215
- setAnchorEl(event.currentTarget);
1216
- };
1217
- const handleMenuClose = () => {
1218
- setAnchorEl(null);
1219
- };
1220
- const renderItem = (item) => {
1221
- const isActive = item.id === idSelect;
1222
- return (jsxs(Link, { href: item.href, onClick: (e) => {
1223
- if (item.onClick) {
1224
- e.preventDefault();
1225
- item.onClick();
1226
- }
1227
- if (onChange) {
1228
- onChange(item.id);
1229
- }
1230
- }, sx: {
1231
- display: 'flex',
1232
- alignItems: 'center',
1233
- gap: GAP_ICON_CONTENT_BY_SIZE.medium,
1234
- ...TYPOGRAPHY_STYLES.textSm.semiBold,
1235
- color: isActive ? '#000000' : '#676E76',
1236
- cursor: 'pointer',
1237
- textDecoration: 'none',
1238
- ...sxItem,
1239
- }, children: [item.icon && jsx(IconElement, { icon: item.icon }), item.label] }, item.id));
1240
- };
1241
- const renderSeparator = () => jsx(ImageElement, { sx: { width: 14, height: 14 }, url: SEPARATOR_URLS[separator] });
1242
- return (jsxs(React.Fragment, { children: [jsx(Breadcrumbs, { "aria-label": "breadcrumb", sx: { ...sx }, children: showCollapsed ? (jsxs(StackRowAlignCenter, { sx: { gap: GAP_ICON_CONTENT_BY_SIZE.small }, children: [renderItem(items[0]), renderSeparator(), jsx(IconButton, { size: "small", onClick: handleMenuOpen, sx: { p: 0, mt: 'auto' }, children: jsx(IconElement, { icon: "more_horiz" }) }), renderSeparator(), visibleItems.slice(1).map((item, idx) => (jsxs(React.Fragment, { children: [idx > 0 && renderSeparator(), renderItem(item)] }, item.id)))] })) : (items.map((item) => renderItem(item))) }), jsx(Menu, { anchorEl: anchorEl, open: Boolean(anchorEl), onClose: handleMenuClose, disableScrollLock: true, children: collapsedItems.map((item) => {
1243
- const isActive = item.id === idSelect;
1244
- return (jsxs(MenuItem, { onClick: () => {
1245
- if (item.onClick) {
1246
- item.onClick();
1247
- }
1248
- handleMenuClose();
1249
- }, sx: {
1250
- gap: GAP_ICON_CONTENT_BY_SIZE.medium,
1251
- color: isActive ? '#0F766E' : '#111827',
1252
- bgcolor: isActive ? '#E0F2FE' : 'transparent',
1253
- }, children: [item.icon && jsx(IconElement, { icon: item.icon }), item.label] }, item.id));
1254
- }) })] }));
1255
- };
1256
-
1257
1203
  /** Shade values mapping */
1258
1204
  const SHADE_VALUES = {
1259
1205
  light: 100,
@@ -1394,17 +1340,6 @@ const ButtonComponent = ({ variant = 'solid', color = 'brand', shade = 'dark', s
1394
1340
  return (jsx(Button, { sx: { ...buttonSx, ...sx }, disabled: disabled || loading, fullWidth: fullWidth, startIcon: !isIconOnly ? prefixContent : undefined, endIcon: !isIconOnly ? suffixContent : undefined, ...props, children: isIconOnly ? (jsxs(Fragment, { children: [prefixContent, suffixContent] })) : (jsxs(Fragment, { children: [activeDot, children] })) }));
1395
1341
  };
1396
1342
 
1397
- const ButtonBarComponent = ({ layout, children, gap = 12, style }) => {
1398
- const containerStyle = {
1399
- display: 'flex',
1400
- flexDirection: layout === 'horizontal' ? 'row' : 'column',
1401
- gap: `${gap}px`,
1402
- alignItems: layout === 'horizontal' ? 'center' : 'stretch',
1403
- ...style,
1404
- };
1405
- return jsx("div", { style: containerStyle, children: children });
1406
- };
1407
-
1408
1343
  const CHECKBOX_COLORS = {
1409
1344
  default: {
1410
1345
  border: '#D0D5DD',
@@ -1528,356 +1463,44 @@ const CheckboxComponent = ({ checked = false, disabled = false, shape = 'square'
1528
1463
  }, children: title })] }));
1529
1464
  };
1530
1465
 
1531
- const CHIP_LABEL_PADDING = {
1532
- WITH_ICON_LEFT: '4px 8px 4px 4px',
1533
- WITH_ICON_RIGHT: '4px 4px 4px 8px',
1534
- NO_ICON: '4px 8px',
1535
- };
1536
- const CHIP_SIZE_CONFIG = {
1466
+ const CONTENT_TYPO = {
1537
1467
  small: {
1538
- height: 24,
1539
- fontSize: '12px',
1540
- borderRadius: '12px',
1541
- iconSize: '16px',
1468
+ titleFontSize: 14,
1469
+ titleFontWeight: 500,
1470
+ contentFontSize: 14,
1471
+ lineHeight: '20px',
1542
1472
  },
1543
1473
  medium: {
1544
- height: 32,
1545
- fontSize: '14px',
1546
- borderRadius: '16px',
1547
- iconSize: '18px',
1548
- },
1549
- large: {
1550
- height: 40,
1551
- fontSize: '16px',
1552
- borderRadius: '20px',
1553
- iconSize: '22px',
1474
+ titleFontSize: 16,
1475
+ titleFontWeight: 600,
1476
+ contentFontSize: 16,
1477
+ lineHeight: '24px',
1554
1478
  },
1555
1479
  };
1556
-
1557
- const getLabelPadding = (hasIcon, position) => {
1558
- if (!hasIcon)
1559
- return CHIP_LABEL_PADDING.NO_ICON;
1560
- return position === 'left' ? CHIP_LABEL_PADDING.WITH_ICON_LEFT : CHIP_LABEL_PADDING.WITH_ICON_RIGHT;
1561
- };
1562
- const ChipIcon = ({ icon, size, sxIcon }) => (jsx(Box, { sx: {
1563
- display: 'inline-flex',
1564
- alignItems: 'center',
1565
- justifyContent: 'center',
1566
- borderRadius: '50%',
1567
- padding: '2px',
1568
- '& svg': {
1569
- width: size,
1570
- height: size,
1571
- display: 'block',
1572
- },
1573
- ...sxIcon,
1574
- }, children: icon }));
1575
- const ChipComponent = ({ label, onAction, icon, disabled = false, clickable = true, sx, sxIcon, iconPosition = 'right', size = 'medium', }) => {
1576
- const sizeConfig = CHIP_SIZE_CONFIG[size];
1577
- const hasIcon = Boolean(icon);
1578
- return (jsx(Chip, { disabled: disabled, clickable: clickable, onClick: onAction, label: jsxs(StackRowAlignCenter, { sx: { gap: '8px' }, children: [hasIcon && iconPosition === 'left' && jsx(ChipIcon, { icon: icon, size: sizeConfig.iconSize, sxIcon: sxIcon }), jsx(Box, { component: "span", children: label }), hasIcon && iconPosition === 'right' && jsx(ChipIcon, { icon: icon, size: sizeConfig.iconSize, sxIcon: sxIcon })] }), sx: {
1579
- height: sizeConfig.height,
1580
- fontSize: sizeConfig.fontSize,
1581
- borderRadius: sizeConfig.borderRadius,
1582
- cursor: clickable ? 'pointer' : 'default',
1583
- backgroundColor: 'transparent',
1584
- border: '1px solid #D1D5DB',
1585
- '& .MuiChip-label': {
1586
- padding: getLabelPadding(hasIcon, iconPosition),
1587
- display: 'flex',
1588
- alignItems: 'center',
1589
- },
1590
- '& .MuiChip-label svg': {
1591
- flexShrink: 0,
1592
- color: '#4B5563',
1593
- },
1594
- '&.Mui-disabled': {
1595
- opacity: 0.5,
1596
- color: '#9E9E9E',
1597
- },
1598
- ...sx,
1599
- } }));
1600
- };
1601
-
1602
- const DateFieldComponent = ({ label = 'Label', placeholder = 'DD/MM/YYYY', value, disabled = false, error = false, success = false, errorMessage, successMessage, borderRadius = 6, helperText = '', onChange, locale = 'vi', format = 'DD/MM/YYYY', sx, disablePastDates = false, ...props }) => {
1603
- // Convert string to Dayjs if needed
1604
- const dayjsValue = value && typeof value === 'string' ? dayjs(value, format) : value instanceof dayjs ? value : null;
1605
- const handleDateChange = (date) => {
1606
- onChange?.(date);
1607
- };
1608
- // Disable past dates function
1609
- const shouldDisableDate = (date) => {
1610
- if (!disablePastDates)
1611
- return false;
1612
- return date.isBefore(dayjs(), 'day');
1613
- };
1614
- return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
1615
- display: 'block',
1616
- ...TYPOGRAPHY.textFieldLabel,
1617
- color: COLOR_GRAY[800],
1618
- marginBottom: '4px',
1619
- }, children: label })), jsx(LocalizationProvider, { dateAdapter: AdapterDayjs, adapterLocale: locale, children: jsx(DatePicker, { value: dayjsValue, onChange: handleDateChange, disabled: disabled, format: format, shouldDisableDate: shouldDisableDate, slotProps: {
1620
- textField: {
1621
- placeholder,
1622
- error: error || false,
1623
- helperText: error ? errorMessage : helperText,
1624
- size: 'small',
1625
- fullWidth: true,
1626
- disabled: disabled,
1627
- },
1628
- openPickerButton: {
1629
- size: 'small',
1630
- },
1631
- }, slots: {
1632
- openPickerIcon: (props) => jsx(IconElement, { icon: "calendar_today", ...props }),
1633
- }, sx: {
1634
- width: '100%',
1635
- '& .MuiPickersInputBase-root': {
1636
- borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
1637
- '& fieldset': { borderColor: COLOR_NEUTRAL[300] },
1638
- '&:hover fieldset': { borderColor: COLOR_NEUTRAL[400] },
1639
- '&.Mui-focused fieldset': { borderColor: COLOR_NEUTRAL[300], borderWidth: '2px' },
1640
- '&.Mui-focused': {
1641
- boxShadow: '0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px #FEE4E2',
1642
- },
1643
- '&.Mui-disabled': {
1644
- backgroundColor: COLOR_NEUTRAL[100],
1645
- '& fieldset': { borderColor: COLOR_NEUTRAL[200] },
1646
- '& input': { color: COLOR_NEUTRAL[400], WebkitTextFillColor: COLOR_NEUTRAL[400] },
1647
- },
1648
- '&.Mui-error fieldset': { borderColor: COLOR_ERROR[500] },
1649
- '&.Mui-error.Mui-focused fieldset': { borderColor: COLOR_ERROR[500], borderWidth: '2px' },
1650
- '&.Mui-error.Mui-focused': {
1651
- boxShadow: `0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px rgba(255, 66, 79, 0.15)`,
1652
- },
1653
- ...(success && {
1654
- '&.Mui-focused': {
1655
- boxShadow: `0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px ${COLOR_SUCCESS[100]}`,
1656
- },
1657
- }),
1658
- },
1659
- '& .MuiInputBase-input': {
1660
- ...TYPOGRAPHY.text14Regular,
1661
- padding: '12px 8px',
1662
- color: COLOR_GRAY[900],
1663
- '&::placeholder': { color: COLOR_NEUTRAL[400], opacity: 0.7 },
1664
- },
1665
- }, ...props }) }), success && !error && successMessage && (jsx(Typography, { sx: {
1666
- ...TYPOGRAPHY.textFieldHelper,
1667
- color: COLOR_SUCCESS[500],
1668
- marginTop: '4px',
1669
- }, children: successMessage }))] }));
1670
- };
1671
-
1672
- const DateRangePickerComponent = ({ label = 'Date Range', fromDate, toDate, disabled = false, error = false, success = false, errorMessage, successMessage, borderRadius = 6, helperText = '', onChange, locale = 'vi', format = 'DD/MM/YYYY', minDate, maxDate, sx, disablePastDates = false, ...props }) => {
1673
- // Convert string to Dayjs if needed
1674
- const dayjsFromDate = fromDate && typeof fromDate === 'string' ? dayjs(fromDate, format) : fromDate instanceof dayjs ? fromDate : null;
1675
- const dayjsToDate = toDate && typeof toDate === 'string' ? dayjs(toDate, format) : toDate instanceof dayjs ? toDate : null;
1676
- // State for picker
1677
- const [pickerOpen, setPickerOpen] = useState(false);
1678
- const [selectingPhase, setSelectingPhase] = useState('from');
1679
- const inputRef = useRef(null);
1680
- // Disable past dates function
1681
- const shouldDisableDate = (date) => {
1682
- if (!disablePastDates)
1683
- return false;
1684
- return date.isBefore(dayjs(), 'day');
1685
- };
1686
- const handleInputClick = () => {
1687
- setPickerOpen(true);
1688
- // Only reset to 'from' if both dates are empty (fresh start)
1689
- if (!dayjsFromDate && !dayjsToDate) {
1690
- setSelectingPhase('from');
1691
- }
1692
- };
1693
- const handleDateChange = (date) => {
1694
- if (selectingPhase === 'from') {
1695
- onChange?.([date, dayjsToDate]);
1696
- if (date) {
1697
- // Auto switch to toDate selection
1698
- setSelectingPhase('to');
1699
- }
1700
- }
1701
- else {
1702
- onChange?.([dayjsFromDate, date]);
1703
- // Keep picker open for user to potentially change toDate
1480
+ const CheckboxContentComponent = ({ checked = false, disabled = false, title, content, size = 'medium', variant = 'filled', shape = 'square', iconType = 'check', onChange, sxCheckbox, sxLabel, sx, }) => {
1481
+ const typo = CONTENT_TYPO[size];
1482
+ const handleToggle = () => {
1483
+ if (!disabled) {
1484
+ onChange?.(!checked);
1704
1485
  }
1705
1486
  };
1706
- return (jsx(LocalizationProvider, { dateAdapter: AdapterDayjs, adapterLocale: locale, children: jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
1707
- display: 'block',
1708
- ...TYPOGRAPHY.textFieldLabel,
1709
- color: COLOR_GRAY[800],
1710
- marginBottom: '4px',
1711
- }, children: label })), jsxs(Box, { ref: inputRef, onClick: !disabled ? handleInputClick : undefined, sx: {
1712
- display: 'flex',
1713
- alignItems: 'center',
1714
- gap: '12px',
1715
- padding: '12px 8px',
1716
- borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
1717
- border: `1px solid ${error ? COLOR_ERROR[500] : COLOR_NEUTRAL[300]}`,
1718
- backgroundColor: disabled ? COLOR_NEUTRAL[100] : 'white',
1719
- cursor: disabled ? 'default' : 'pointer',
1720
- transition: 'all 0.2s ease',
1721
- ...(disabled
1722
- ? {}
1723
- : {
1724
- '&:hover': {
1725
- borderColor: error ? COLOR_ERROR[500] : COLOR_NEUTRAL[400],
1726
- },
1727
- }),
1728
- }, children: [jsxs(Typography, { sx: {
1729
- flex: 1,
1730
- ...TYPOGRAPHY.text14Regular,
1731
- color: dayjsFromDate || dayjsToDate ? COLOR_GRAY[900] : COLOR_NEUTRAL[400],
1732
- }, children: [dayjsFromDate ? dayjsFromDate.format(format) : format, " \u2192", ' ', dayjsToDate ? dayjsToDate.format(format) : format] }), jsx(Box, { sx: {
1733
- display: 'flex',
1734
- alignItems: 'center',
1735
- justifyContent: 'center',
1736
- width: '24px',
1737
- height: '24px',
1738
- color: COLOR_NEUTRAL[400],
1739
- }, children: jsx(IconElement, { icon: "calendar_today" }) })] }), jsx(DatePicker, { open: pickerOpen, onOpen: () => setPickerOpen(true), onClose: () => setPickerOpen(false), value: selectingPhase === 'from' ? dayjsFromDate : dayjsToDate, onChange: handleDateChange, disabled: disabled, format: format, minDate: selectingPhase === 'from' ? minDate : dayjsFromDate || minDate, maxDate: selectingPhase === 'to' ? maxDate : dayjsToDate || maxDate, shouldDisableDate: shouldDisableDate, slotProps: {
1740
- textField: {
1741
- hidden: true,
1742
- size: 'small',
1743
- sx: {
1744
- display: 'none',
1745
- },
1746
- },
1747
- popper: {
1748
- anchorEl: inputRef.current,
1749
- placement: 'bottom-start',
1750
- },
1751
- } }), helperText && !error && !success && (jsx(Typography, { sx: {
1752
- ...TYPOGRAPHY.textFieldHelper,
1753
- color: COLOR_NEUTRAL[400],
1754
- marginTop: '4px',
1755
- }, children: helperText })), error && errorMessage && (jsx(Typography, { sx: {
1756
- ...TYPOGRAPHY.textFieldHelper,
1757
- color: COLOR_ERROR[500],
1758
- marginTop: '4px',
1759
- }, children: errorMessage })), success && !error && successMessage && (jsx(Typography, { sx: {
1760
- ...TYPOGRAPHY.textFieldHelper,
1761
- color: COLOR_SUCCESS[500],
1762
- marginTop: '4px',
1763
- }, children: successMessage }))] }) }));
1764
- };
1765
-
1766
- const DropdownFieldComponent = ({ label = '', placeholder = 'Select option', value = null, disabled = false, error = false, success = false, errorMessage, successMessage, borderRadius = 6, onChange, helperText = '', options = [], checkIconColor = COLOR_ACCENT[900], sx, }) => {
1767
- const borderRadiusValue = borderRadius === 'max' ? '100px' : `${borderRadius}px`;
1768
- const selectedOption = useMemo(() => options.find((opt) => opt.value === value), [options, value]);
1769
- const getHelperText = useCallback(() => {
1770
- if (error && errorMessage)
1771
- return errorMessage;
1772
- if (success && successMessage)
1773
- return successMessage;
1774
- if (helperText)
1775
- return helperText;
1776
- return '';
1777
- }, [error, errorMessage, success, successMessage, helperText]);
1778
- const getHelperTextColor = useCallback(() => {
1779
- if (error)
1780
- return COLOR_ERROR[500];
1781
- if (success)
1782
- return COLOR_SUCCESS[500];
1783
- return COLOR_NEUTRAL[400];
1784
- }, [error, success]);
1785
- const getBorderColor = useCallback(() => {
1786
- if (error)
1787
- return COLOR_ERROR[500];
1788
- if (success)
1789
- return COLOR_SUCCESS[500];
1790
- return COLOR_NEUTRAL[300];
1791
- }, [error, success]);
1792
- const selectSx = useMemo(() => ({
1793
- '& .MuiOutlinedInput-root': {
1794
- borderRadius: borderRadiusValue,
1795
- backgroundColor: disabled ? COLOR_NEUTRAL[100] : 'white',
1796
- transition: 'all 0.2s ease',
1797
- '& fieldset': {
1798
- borderColor: getBorderColor(),
1799
- },
1800
- '&:hover fieldset': {
1801
- borderColor: disabled ? getBorderColor() : error ? COLOR_ERROR[500] : COLOR_NEUTRAL[400],
1802
- },
1803
- '&.Mui-focused fieldset': {
1804
- borderColor: error ? COLOR_ERROR[500] : COLOR_NEUTRAL[400],
1805
- borderWidth: '1.5px',
1806
- },
1807
- },
1808
- '& .MuiOutlinedInput-input': {
1809
- padding: '12px 14px',
1810
- color: COLOR_GRAY[900],
1811
- '&::placeholder': {
1812
- color: COLOR_NEUTRAL[400],
1813
- opacity: 1,
1814
- },
1815
- },
1816
- }), [borderRadiusValue, disabled, error, getBorderColor]);
1817
- return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
1818
- display: 'block',
1819
- ...TYPOGRAPHY.textFieldLabel,
1820
- color: COLOR_GRAY[800],
1821
- marginBottom: '4px',
1822
- }, children: label })), jsx(Select, { fullWidth: true, value: value || '', onChange: (e) => {
1823
- const selectedValue = e.target.value;
1824
- const matchedOption = options.find((opt) => String(opt.value) === String(selectedValue));
1825
- if (matchedOption) {
1826
- onChange?.(matchedOption.value);
1827
- }
1828
- }, disabled: disabled, displayEmpty: true, MenuProps: {
1829
- disableScrollLock: true,
1830
- }, renderValue: () => {
1831
- if (!value) {
1832
- return (jsx(Box, { sx: { color: COLOR_NEUTRAL[400], display: 'flex', alignItems: 'center', gap: '8px' }, children: placeholder }));
1833
- }
1834
- return (jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: '8px' }, children: [selectedOption?.statusIndicator && (jsx(Box, { sx: {
1835
- width: '8px',
1836
- height: '8px',
1837
- borderRadius: '50%',
1838
- backgroundColor: '#4CAF50',
1839
- } })), selectedOption?.avatar && (jsx(Avatar, { src: selectedOption.avatar, sx: {
1840
- width: '24px',
1841
- height: '24px',
1842
- fontSize: '12px',
1843
- } })), selectedOption?.icon && jsx(IconElement, { icon: selectedOption.icon }), jsx(Typography, { sx: { color: COLOR_GRAY[900], ...TYPOGRAPHY.text14Regular }, children: selectedOption?.label })] }));
1844
- }, sx: selectSx, children: options.map((option) => (jsx(MenuItem, { value: option.value, children: jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: '8px', width: '100%' }, children: [option.statusIndicator && (jsx(Box, { sx: {
1845
- width: '8px',
1846
- height: '8px',
1847
- borderRadius: '50%',
1848
- backgroundColor: '#4CAF50',
1849
- } })), option.avatar && (jsx(Avatar, { src: option.avatar, sx: {
1850
- width: '24px',
1851
- height: '24px',
1852
- fontSize: '12px',
1853
- } })), option.icon && jsx(IconElement, { icon: option.icon }), jsx(Typography, { sx: { color: COLOR_GRAY[900], ...TYPOGRAPHY.text14Regular }, children: option.label }), value === option.value && (jsx(Box, { sx: { marginLeft: 'auto', display: 'flex', alignItems: 'center' }, children: jsx(IconElement, { icon: "check", sx: { color: checkIconColor } }) }))] }) }, option.value))) }), getHelperText() && (jsx(Box, { sx: {
1854
- color: getHelperTextColor(),
1855
- marginTop: '4px',
1856
- ...TYPOGRAPHY.textFieldHelper,
1857
- }, children: getHelperText() }))] }));
1858
- };
1859
-
1860
- const BACKGROUND_COLOR_GRID = '#FFFFFF';
1861
- const COLOR_CONTENT_GRID = '#27272A';
1862
- const BORDER_RADIUS_GRID_CONTAINER = 8;
1863
- const BORDER_RADIUS_GRID = 4;
1864
- const GridComponent = ({ sx = {}, sxContainer = {}, content = 'Grids', children, }) => {
1865
- return (jsxs(Stack, { sx: {
1866
- bgcolor: BACKGROUND_COLOR_GRID,
1867
- p: BORDER_RADIUS_GRID_CONTAINER,
1868
- borderRadius: BORDER_RADIUS_GRID_CONTAINER,
1869
- gap: BORDER_RADIUS_GRID,
1487
+ return (jsxs(Box, { onClick: handleToggle, sx: {
1488
+ display: 'flex',
1489
+ alignItems: 'flex-start',
1490
+ gap: '12px',
1491
+ cursor: disabled ? 'not-allowed' : 'pointer',
1492
+ width: 'fit-content',
1870
1493
  ...sx,
1871
- }, children: [content && (jsx(Typography, { sx: {
1872
- color: COLOR_CONTENT_GRID,
1873
- ...TYPOGRAPHY_STYLES.lg.bold,
1874
- }, children: content })), jsx(Container, { maxWidth: false, sx: {
1875
- bgcolor: BACKGROUND_COLOR_GRID,
1876
- borderRadius: BORDER_RADIUS_GRID,
1877
- minHeight: 400,
1878
- boxShadow: '0 0 8px -4px rgba(16, 24, 40, 0.3)',
1879
- ...sxContainer,
1880
- }, children: children })] }));
1494
+ }, children: [jsx(CheckboxComponent, { checked: checked, disabled: disabled, size: size, variant: variant, shape: shape, iconType: iconType, onChange: onChange, sxCheckbox: sxCheckbox }), jsxs(Box, { children: [jsx(Typography, { fontSize: typo.titleFontSize, fontWeight: typo.titleFontWeight, lineHeight: typo.lineHeight, sx: {
1495
+ userSelect: 'none',
1496
+ ...(disabled && { opacity: 0.6 }),
1497
+ ...sxLabel,
1498
+ }, children: title }), content && (jsx(Typography, { fontSize: typo.contentFontSize, lineHeight: typo.lineHeight, sx: {
1499
+ mt: '4px',
1500
+ userSelect: 'none',
1501
+ ...(disabled && { opacity: 0.6 }),
1502
+ ...sxLabel,
1503
+ }, children: content }))] })] }));
1881
1504
  };
1882
1505
 
1883
1506
  var BorderRadius;
@@ -1900,159 +1523,6 @@ var ButtonSize;
1900
1523
  ButtonSize[ButtonSize["SMALL"] = 32] = "SMALL";
1901
1524
  ButtonSize[ButtonSize["MEDIUM"] = 40] = "MEDIUM";
1902
1525
  })(ButtonSize || (ButtonSize = {}));
1903
- const Colors = {
1904
- BORDER_COLOR_BUTTON: '#07554B',
1905
- BORDER_COLOR_DISABLE: '#0000000D',
1906
- HOVER_BG_COLOR: 'rgba(7, 85, 75, 0.04)',
1907
- BACKGROUND_COLOR: '#FFFFFF',
1908
- TEXT_COLOR_READONLY: '#27272A',
1909
- };
1910
- const FONT_SIZE_LOADING = {
1911
- large: 40,
1912
- };
1913
- const BORDER_TEXT_FIELD_LOADING = 20;
1914
-
1915
- const InputStepperSkeleton = ({ orientation, buttonShape }) => {
1916
- return (jsxs(Box, { display: "inline-flex", flexDirection: orientation === Orientation.HORIZONTAL ? 'row' : 'column', alignItems: "center", gap: 1, children: [jsx(Skeleton, { variant: buttonShape === ShapeType.CIRCLE ? 'circular' : 'rectangular', width: FONT_SIZE_LOADING.large, height: FONT_SIZE_LOADING.large, sx: {
1917
- borderRadius: buttonShape === ShapeType.CIRCLE ? BorderRadius.CIRCLE : BorderRadius.SQUARE,
1918
- maxHeight: FONT_SIZE_LOADING.large,
1919
- } }), jsx(Skeleton, { width: FONT_SIZE_LOADING.large, sx: {
1920
- borderRadius: `${BORDER_TEXT_FIELD_LOADING}px`,
1921
- } }), jsx(Skeleton, { variant: buttonShape === ShapeType.CIRCLE ? 'circular' : 'rectangular', width: FONT_SIZE_LOADING.large, height: FONT_SIZE_LOADING.large, sx: {
1922
- borderRadius: buttonShape === ShapeType.CIRCLE ? BorderRadius.CIRCLE : BorderRadius.SQUARE,
1923
- maxHeight: FONT_SIZE_LOADING.large,
1924
- } })] }));
1925
- };
1926
-
1927
- const InputStepperComponent = ({ value: controlledValue, onChange, min, max, step = 1, disabled = false, readOnly = false, orientation = Orientation.HORIZONTAL, loading = false, sx = {}, sxTextField = {}, // style cho input chứa value
1928
- sxButton = {}, // style cho 2 button
1929
- buttonShape = ShapeType.SQUARE, buttonColor, textFieldShape = ShapeType.SQUARE, decrementIcon = jsx(RemoveIcon, {}), incrementIcon = jsx(AddIcon, {}), }) => {
1930
- const [internalValue, setInternalValue] = useState(controlledValue ?? min ?? 0);
1931
- const value = controlledValue !== undefined ? controlledValue : internalValue;
1932
- const updateValue = (newValue) => {
1933
- let finalValue = newValue;
1934
- if (min !== undefined && newValue < min)
1935
- finalValue = min;
1936
- if (max !== undefined && newValue > max)
1937
- finalValue = max;
1938
- if (controlledValue === undefined) {
1939
- setInternalValue(finalValue);
1940
- }
1941
- onChange?.(finalValue);
1942
- };
1943
- const handleIncrement = () => {
1944
- updateValue(Number(value) + step);
1945
- };
1946
- const handleDecrement = () => {
1947
- updateValue(Number(value) - step);
1948
- };
1949
- const handleInputChange = (event) => {
1950
- if (!readOnly) {
1951
- const newValue = event.target.value === '' ? min || 0 : Number(event.target.value);
1952
- if (!isNaN(newValue)) {
1953
- updateValue(newValue);
1954
- }
1955
- }
1956
- };
1957
- const isDecrementDisabled = disabled || (min !== undefined && Number(value) <= min);
1958
- const isIncrementDisabled = disabled || (max !== undefined && Number(value) >= max);
1959
- const buttonSize = ButtonSize.MEDIUM;
1960
- if (loading) {
1961
- return jsx(InputStepperSkeleton, { orientation: orientation, buttonShape: buttonShape });
1962
- }
1963
- return (jsxs(Box, { display: "inline-flex", flexDirection: orientation === 'horizontal' ? 'row' : 'column', alignItems: "center", gap: PADDING_GAP_ITEM, sx: {
1964
- opacity: disabled ? 0.5 : 1,
1965
- pointerEvents: disabled ? 'none' : 'auto',
1966
- ...sx,
1967
- }, children: [jsx(IconButton, { onClick: handleDecrement, disabled: isDecrementDisabled, sx: {
1968
- borderRadius: buttonShape === 'circle' ? BorderRadius.CIRCLE : BorderRadius.SQUARE,
1969
- width: buttonSize,
1970
- height: buttonSize,
1971
- padding: PADDING_GAP_ITEM,
1972
- border: isDecrementDisabled
1973
- ? `1px solid ${Colors.BORDER_COLOR_DISABLE}`
1974
- : `1px solid ${Colors.BORDER_COLOR_BUTTON}`,
1975
- backgroundColor: Colors.BACKGROUND_COLOR,
1976
- color: buttonColor || Colors.BORDER_COLOR_BUTTON,
1977
- '&:hover': {
1978
- backgroundColor: Colors.HOVER_BG_COLOR,
1979
- },
1980
- ...(isDecrementDisabled ? {} : sxButton),
1981
- }, children: decrementIcon }), jsx(TextField, { value: value, onChange: handleInputChange, disabled: disabled, inputProps: {
1982
- min,
1983
- max,
1984
- step,
1985
- readOnly,
1986
- }, type: "number", sx: {
1987
- minWidth: buttonSize,
1988
- width: sxTextField?.width || buttonSize,
1989
- minHeight: buttonSize,
1990
- height: sxTextField?.height || buttonSize,
1991
- overflow: 'hidden',
1992
- borderRadius: textFieldShape === 'circle' ? BorderRadius.CIRCLE : BorderRadius.SQUARE,
1993
- color: readOnly ? Colors.TEXT_COLOR_READONLY : '',
1994
- backgroundColor: readOnly ? 'transparent !important' : sxTextField?.backgroundColor,
1995
- '& .MuiOutlinedInput-root': {
1996
- width: '100%',
1997
- height: '100%',
1998
- borderRadius: 'inherit',
1999
- '& fieldset': {
2000
- borderColor: readOnly || disabled ? 'transparent' : sxTextField?.borderColor || Colors.BORDER_COLOR_BUTTON,
2001
- borderWidth: readOnly || disabled ? 0 : 1,
2002
- borderRadius: textFieldShape === 'circle' ? BorderRadius.CIRCLE : BorderRadius.SQUARE,
2003
- },
2004
- '&:hover fieldset': readOnly || disabled
2005
- ? {}
2006
- : {
2007
- borderColor: sxTextField?.borderColorHover || Colors.BORDER_COLOR_BUTTON,
2008
- },
2009
- '&.Mui-focused fieldset': readOnly
2010
- ? {
2011
- borderColor: 'transparent',
2012
- borderWidth: 0,
2013
- }
2014
- : {
2015
- borderColor: sxTextField?.borderColorFocused || Colors.BORDER_COLOR_BUTTON,
2016
- borderWidth: 1,
2017
- },
2018
- '&.Mui-disabled fieldset': {
2019
- borderColor: Colors.BORDER_COLOR_DISABLE,
2020
- backgroundColor: readOnly ? 'transparent' : Colors.BORDER_COLOR_DISABLE,
2021
- },
2022
- },
2023
- '& input[type=number]::-webkit-outer-spin-button, & input[type=number]::-webkit-inner-spin-button': {
2024
- WebkitAppearance: 'none',
2025
- margin: 0,
2026
- },
2027
- '& input[type=number]': {
2028
- MozAppearance: 'textfield',
2029
- },
2030
- '& .MuiInputBase-input': {
2031
- textAlign: sxTextField?.textAlign || 'center',
2032
- padding: sxTextField?.padding || '4px 8px',
2033
- fontSize: readOnly ? '16px' : sxTextField?.fontSize || '1rem',
2034
- cursor: readOnly ? 'not-allowed' : 'text',
2035
- borderRadius: 'inherit',
2036
- backgroundColor: readOnly ? 'transparent' : sxTextField?.backgroundColor || 'transparent',
2037
- color: readOnly ? Colors.TEXT_COLOR_READONLY : sxTextField?.color || 'inherit',
2038
- fontWeight: sxTextField?.fontWeight || (readOnly ? 700 : 'normal'),
2039
- },
2040
- } }), jsx(IconButton, { onClick: handleIncrement, disabled: isIncrementDisabled, sx: {
2041
- borderRadius: buttonShape === 'circle' ? BorderRadius.CIRCLE : BorderRadius.SQUARE,
2042
- width: buttonSize,
2043
- height: buttonSize,
2044
- padding: PADDING_GAP_ITEM,
2045
- border: isIncrementDisabled
2046
- ? `1px solid ${Colors.BORDER_COLOR_DISABLE}`
2047
- : `1px solid ${Colors.BORDER_COLOR_BUTTON}`,
2048
- backgroundColor: Colors.BACKGROUND_COLOR,
2049
- color: buttonColor || Colors.BORDER_COLOR_BUTTON,
2050
- '&:hover': {
2051
- backgroundColor: Colors.HOVER_BG_COLOR,
2052
- },
2053
- ...(isIncrementDisabled ? {} : sxButton),
2054
- }, children: incrementIcon })] }));
2055
- };
2056
1526
 
2057
1527
  const LinkInternalElement = ({ content, onClick, sx = {} }) => {
2058
1528
  return (jsx(Typography, { onClick: onClick, sx: {
@@ -2075,7 +1545,7 @@ const LinkElement = ({ onClick, sx = {}, target = '_self', ...rest }) => {
2075
1545
  }, ...rest }));
2076
1546
  };
2077
1547
 
2078
- const StyledTextField$3 = styled(MuiTextField)(({ theme }) => {
1548
+ styled(MuiTextField)(({ theme }) => {
2079
1549
  return {
2080
1550
  '& .MuiOutlinedInput-root': {
2081
1551
  '& fieldset': { borderColor: COLOR_NEUTRAL[300] },
@@ -2117,57 +1587,6 @@ const StyledTextField$3 = styled(MuiTextField)(({ theme }) => {
2117
1587
  },
2118
1588
  };
2119
1589
  });
2120
- const LinkFieldComponent = ({ label = 'Website', placeholder = 'www.untitledui.com', value, disabled = false, error = false, success = false, errorMessage, successMessage, borderRadius = 6, helperText = 'This is a hint text to help user.', onChange, protocol = 'http://', iconAfter, sx, ...props }) => {
2121
- const [validationError, setValidationError] = useState(false);
2122
- const isValidLink = (url) => {
2123
- if (!url)
2124
- return true; // Empty is valid (optional field)
2125
- try {
2126
- const urlToTest = url.includes('://') ? url : `${protocol}${url}`;
2127
- new URL(urlToTest);
2128
- // Kiểm tra domain phải có dấu chấm (ít nhất là có TLD)
2129
- const hostname = new URL(urlToTest).hostname;
2130
- if (!hostname || !hostname.includes('.')) {
2131
- return false;
2132
- }
2133
- return true;
2134
- }
2135
- catch {
2136
- return false;
2137
- }
2138
- };
2139
- const handleBlur = (event) => {
2140
- const inputValue = event.target.value;
2141
- if (inputValue && !isValidLink(inputValue)) {
2142
- setValidationError(true);
2143
- }
2144
- else {
2145
- setValidationError(false);
2146
- }
2147
- };
2148
- return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
2149
- display: 'block',
2150
- ...TYPOGRAPHY.textFieldLabel,
2151
- color: COLOR_GRAY[800],
2152
- marginBottom: '4px',
2153
- }, children: label })), jsx(StyledTextField$3, { placeholder: placeholder, value: value, disabled: disabled, error: error || validationError, helperText: error || validationError ? (error ? errorMessage : 'đây không phải link') : '', size: "small", fullWidth: true, onChange: onChange, onBlur: handleBlur, InputProps: {
2154
- startAdornment: (jsx(InputAdornment, { position: "start", children: jsx(Typography, { sx: { color: COLOR_NEUTRAL[300], ...TYPOGRAPHY.text14Regular }, children: protocol }) })),
2155
- endAdornment: (success || error || validationError) && (jsx(InputAdornment, { position: "end", children: iconAfter ? (iconAfter) : (jsx(IconElement, { icon: error || validationError ? 'info' : 'check_circle', sx: { color: error || validationError ? COLOR_ERROR[500] : COLOR_SUCCESS[500] } })) })),
2156
- }, sx: {
2157
- '& .MuiOutlinedInput-root': {
2158
- borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
2159
- ...(success && {
2160
- '&.Mui-focused': {
2161
- boxShadow: `0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px ${COLOR_SUCCESS[100]}`,
2162
- },
2163
- }),
2164
- },
2165
- } }), success && !error && successMessage && (jsx(Typography, { sx: {
2166
- ...TYPOGRAPHY.textFieldHelper,
2167
- color: COLOR_SUCCESS[500],
2168
- marginTop: '4px',
2169
- }, children: successMessage }))] }));
2170
- };
2171
1590
 
2172
1591
  const MODAL_ICON_COLORS = {
2173
1592
  check_circle: '#10B981',
@@ -2277,15 +1696,7 @@ const ModalCardComponent = ({ open, isForm = false, onClose, items, nodeContent,
2277
1696
  }, children: jsxs(StackRowAlignCenter, { sx: { width: '100%' }, children: [nodeBottomLeft && jsx(Box, { sx: { width: '100%' }, children: nodeBottomLeft }), (buttonLeft || buttonCenter || buttonRight) && (jsxs(StackRow, { sx: { width: '100%', gap: PADDING_GAP_LAYOUT }, children: [buttonLeft && (jsx(Box, { sx: { flex: 1 }, children: jsx(ButtonComponent, { ...buttonLeft, fullWidth: true }) })), buttonCenter && (jsx(Box, { sx: { flex: 1 }, children: jsx(ButtonComponent, { ...buttonCenter, fullWidth: true }) })), buttonRight && (jsx(Box, { sx: { flex: 1 }, children: jsx(ButtonComponent, { ...buttonRight, fullWidth: true }) }))] }))] }) }))] }) }));
2278
1697
  };
2279
1698
 
2280
- const CURRENCIES = ['USD', 'EUR', 'GBP', 'JPY', 'AUD', 'CAD', 'CHF', 'CNY', 'VND', 'INR'];
2281
- // Format number with thousand separators
2282
- const formatMoneyDisplay = (value) => {
2283
- if (!value)
2284
- return '';
2285
- const numericOnly = value.replace(/\D/g, '');
2286
- return numericOnly.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
2287
- };
2288
- const StyledTextField$2 = styled(MuiTextField)(({ theme }) => {
1699
+ styled(MuiTextField)(({ theme }) => {
2289
1700
  return {
2290
1701
  '& .MuiOutlinedInput-root': {
2291
1702
  '& fieldset': { borderColor: COLOR_NEUTRAL[300] },
@@ -2327,64 +1738,8 @@ const StyledTextField$2 = styled(MuiTextField)(({ theme }) => {
2327
1738
  },
2328
1739
  };
2329
1740
  });
2330
- const MoneyFieldComponent = ({ label = 'Sale amount', placeholder = '1,000.00', value, disabled = false, error = false, success = false, errorMessage, successMessage, borderRadius = 6, helperText = 'This is a hint text to help user.', onChange, currency = 'USD', onCurrencyChange, iconBefore, optionCurrencies = CURRENCIES, sx, ...props }) => {
2331
- const [selectedCurrency, setSelectedCurrency] = useState(currency);
2332
- const handleCurrencyChange = (e) => {
2333
- const newCurrency = e.target.value;
2334
- setSelectedCurrency(newCurrency);
2335
- onCurrencyChange?.(newCurrency);
2336
- };
2337
- const handleMoneyChange = (e) => {
2338
- const rawValue = e.target.value.replace(/,/g, '');
2339
- onChange?.({ ...e, target: { ...e.target, value: rawValue } });
2340
- };
2341
- return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
2342
- display: 'block',
2343
- ...TYPOGRAPHY.textFieldLabel,
2344
- color: COLOR_GRAY[800],
2345
- marginBottom: '4px',
2346
- }, children: label })), jsx(StyledTextField$2, { placeholder: placeholder, value: formatMoneyDisplay(value), disabled: disabled, error: error, helperText: error ? errorMessage : helperText, size: "small", fullWidth: true, onChange: handleMoneyChange, InputProps: {
2347
- startAdornment: (jsx(InputAdornment, { position: "start", children: iconBefore ? iconBefore : jsx(AttachMoneyIcon, { sx: { fontSize: '18px', color: COLOR_GRAY[400], mr: 0.5 } }) })),
2348
- endAdornment: (jsx(InputAdornment, { position: "end", children: jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1 }, children: [(success || error) && (jsx(IconElement, { icon: error ? 'info' : 'check_circle', sx: { color: error ? COLOR_ERROR[500] : COLOR_SUCCESS[500] } })), jsx(Select, { value: selectedCurrency, onChange: handleCurrencyChange, disabled: disabled, variant: "standard", sx: {
2349
- border: 'none',
2350
- outline: 'none',
2351
- '& .MuiSelect-standard': { border: 'none' },
2352
- '&.MuiInput-underline:before': { borderBottom: 'none' },
2353
- '&.MuiInput-underline:hover:before': { borderBottom: 'none' },
2354
- '&.MuiInput-underline:after': { borderBottom: 'none' },
2355
- minWidth: '70px',
2356
- fontSize: '14px',
2357
- color: COLOR_GRAY[500],
2358
- }, children: optionCurrencies.map((curr) => (jsx(MenuItem, { value: curr, children: curr }, curr))) })] }) })),
2359
- }, sx: {
2360
- '& .MuiOutlinedInput-root': {
2361
- borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
2362
- ...(success && {
2363
- '&.Mui-focused': {
2364
- boxShadow: `0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px ${COLOR_SUCCESS[100]}`,
2365
- },
2366
- }),
2367
- },
2368
- } }), success && !error && successMessage && (jsx(Typography, { sx: {
2369
- ...TYPOGRAPHY.textFieldHelper,
2370
- color: COLOR_SUCCESS[600],
2371
- marginTop: '4px',
2372
- }, children: successMessage }))] }));
2373
- };
2374
1741
 
2375
- const COUNTRY_CODES = [
2376
- { code: 'US', name: 'United States', flag: '🇺🇸', value: '+1' },
2377
- { code: 'GB', name: 'United Kingdom', flag: '🇬🇧', value: '+44' },
2378
- { code: 'CA', name: 'Canada', flag: '🇨🇦', value: '+1' },
2379
- { code: 'AU', name: 'Australia', flag: '🇦🇺', value: '+61' },
2380
- { code: 'VN', name: 'Vietnam', flag: '🇻🇳', value: '+84' },
2381
- { code: 'JP', name: 'Japan', flag: '🇯🇵', value: '+81' },
2382
- { code: 'CN', name: 'China', flag: '🇨🇳', value: '+86' },
2383
- { code: 'IN', name: 'India', flag: '🇮🇳', value: '+91' },
2384
- { code: 'DE', name: 'Germany', flag: '🇩🇪', value: '+49' },
2385
- { code: 'FR', name: 'France', flag: '🇫🇷', value: '+33' },
2386
- ];
2387
- const StyledTextField$1 = styled(MuiTextField)(({ theme }) => {
1742
+ styled(MuiTextField)(({ theme }) => {
2388
1743
  return {
2389
1744
  '& .MuiOutlinedInput-root': {
2390
1745
  '& fieldset': { borderColor: COLOR_NEUTRAL[300] },
@@ -2426,250 +1781,8 @@ const StyledTextField$1 = styled(MuiTextField)(({ theme }) => {
2426
1781
  },
2427
1782
  };
2428
1783
  });
2429
- const PhoneNumberFieldComponent = ({ label = 'Số điện thoại', placeholder = '0123 456 789', value, disabled = false, error = false, success = false, errorMessage, successMessage, borderRadius = 6, helperText, onChange, countryCode = 'US', onCountryCodeChange, countries = COUNTRY_CODES, sx, ...props }) => {
2430
- const handleCountryChange = (e) => {
2431
- const newCode = e.target.value;
2432
- onCountryCodeChange?.(newCode);
2433
- };
2434
- return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
2435
- display: 'block',
2436
- ...TYPOGRAPHY.textFieldLabel,
2437
- color: COLOR_GRAY[800],
2438
- marginBottom: '4px',
2439
- }, children: label })), jsx(StyledTextField$1, { placeholder: placeholder, value: value, disabled: disabled, error: error, helperText: error ? errorMessage : helperText, size: "small", fullWidth: true, onChange: onChange, InputProps: {
2440
- startAdornment: (jsx(InputAdornment, { position: "start", sx: { mr: 0 }, children: jsx(Select, { value: countryCode, onChange: handleCountryChange, disabled: disabled, variant: "standard", sx: {
2441
- border: 'none',
2442
- outline: 'none',
2443
- '& .MuiSelect-standard': { border: 'none' },
2444
- '&.MuiInput-underline:before': { borderBottom: 'none' },
2445
- '&.MuiInput-underline:hover:before': { borderBottom: 'none' },
2446
- '&.MuiInput-underline:after': { borderBottom: 'none' },
2447
- minWidth: '50px',
2448
- fontSize: '14px',
2449
- color: COLOR_GRAY[500],
2450
- display: 'flex',
2451
- alignItems: 'center',
2452
- gap: 0.5,
2453
- }, children: countries.map((c) => (jsx(MenuItem, { value: c.code, children: c.code }, c.code))) }) })),
2454
- endAdornment: (success || error) && (jsx(InputAdornment, { position: "end", children: jsx(IconElement, { icon: error ? 'info' : 'check_circle', sx: { color: error ? COLOR_ERROR[500] : COLOR_SUCCESS[500] } }) })),
2455
- }, sx: {
2456
- '& .MuiOutlinedInput-root': {
2457
- borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
2458
- ...(success && {
2459
- '&.Mui-focused': {
2460
- boxShadow: `0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px ${COLOR_SUCCESS[100]}`,
2461
- },
2462
- }),
2463
- },
2464
- } }), success && !error && successMessage && (jsx(Typography, { sx: {
2465
- ...TYPOGRAPHY.textFieldHelper,
2466
- color: COLOR_SUCCESS[600],
2467
- marginTop: '4px',
2468
- }, children: successMessage }))] }));
2469
- };
2470
1784
 
2471
- const PIN_SIZES = {
2472
- sm: { width: 40, height: 40, fontSize: 18 },
2473
- md: { width: 48, height: 48, fontSize: 20 },
2474
- lg: { width: 56, height: 56, fontSize: 24 },
2475
- };
2476
- const PIN_SPACING = {
2477
- sm: 8,
2478
- md: 12,
2479
- lg: 16,
2480
- };
2481
-
2482
- const PINComponent = ({ length = 6, value, onChange, label, error = false, errorMessage, type = 'text', disabled = false, autoFocus = false, onComplete, align = 'left', spacing = 'md', size = 'md', masked = false, borderFocusColor, sx, }) => {
2483
- const { palette } = useTheme();
2484
- const inputRefs = useRef([]);
2485
- useEffect(() => {
2486
- if (autoFocus && inputRefs.current[0]) {
2487
- inputRefs.current[0].focus();
2488
- }
2489
- }, [autoFocus]);
2490
- const handleChange = (index, val) => {
2491
- if (!/^\d*$/.test(val))
2492
- return;
2493
- const newValue = value.split('');
2494
- newValue[index] = val;
2495
- const updatedValue = newValue.join('').slice(0, length);
2496
- onChange(updatedValue);
2497
- if (val && index < length - 1) {
2498
- inputRefs.current[index + 1]?.focus();
2499
- }
2500
- if (updatedValue.length === length) {
2501
- onComplete?.(updatedValue);
2502
- }
2503
- };
2504
- const handleKeyDown = (index, e) => {
2505
- if (e.key === 'Backspace' && !value[index] && index > 0) {
2506
- inputRefs.current[index - 1]?.focus();
2507
- }
2508
- };
2509
- const renderPINDisplay = (index) => {
2510
- const inputValue = value[index] || '';
2511
- const isFilled = !!inputValue;
2512
- const sizeStyle = PIN_SIZES[size];
2513
- const borderColor = error ? palette.error.main : COLOR_GRAY[200];
2514
- const borderFocusColorValue = borderFocusColor || (error ? palette.error.main : COLOR_GRAY[900]);
2515
- if (type === 'bullet') {
2516
- return (jsxs(Box, { sx: { position: 'relative', width: sizeStyle.width, height: sizeStyle.height }, children: [jsx(TextField, { ref: (el) => {
2517
- const input = el?.querySelector('input');
2518
- if (input) {
2519
- inputRefs.current[index] = input;
2520
- }
2521
- }, type: "text", inputMode: "numeric", value: inputValue, onChange: (e) => handleChange(index, e.target.value), onKeyDown: (e) => handleKeyDown(index, e), disabled: disabled, error: error, sx: {
2522
- width: '100%',
2523
- height: '100%',
2524
- '& .MuiOutlinedInput-root': {
2525
- height: '100%',
2526
- padding: 0,
2527
- '& input': {
2528
- textAlign: 'center',
2529
- fontSize: sizeStyle.fontSize,
2530
- fontWeight: 600,
2531
- padding: 0,
2532
- color: masked && isFilled ? 'transparent' : 'inherit',
2533
- WebkitTextFillColor: masked && isFilled ? 'transparent' : 'unset',
2534
- caretColor: palette.primary.main,
2535
- '&::placeholder': {
2536
- color: palette.action.disabled,
2537
- opacity: 1,
2538
- },
2539
- },
2540
- '& fieldset': {
2541
- borderColor: borderColor,
2542
- borderRadius: '8px',
2543
- },
2544
- '&:hover fieldset': {
2545
- borderColor: error ? palette.error.main : borderFocusColorValue,
2546
- },
2547
- '&.Mui-focused fieldset': {
2548
- borderColor: borderFocusColorValue,
2549
- borderWidth: 1,
2550
- },
2551
- },
2552
- '& input': {
2553
- maxLength: 1,
2554
- },
2555
- }, placeholder: "-" }), masked && isFilled && (jsx(Box, { sx: {
2556
- position: 'absolute',
2557
- top: '50%',
2558
- left: '50%',
2559
- transform: 'translate(-50%, -50%)',
2560
- fontSize: sizeStyle.fontSize,
2561
- fontWeight: 600,
2562
- color: error ? palette.error.main : palette.text.primary,
2563
- pointerEvents: 'none',
2564
- }, children: "\u25CF" }))] }));
2565
- }
2566
- if (type === 'circle') {
2567
- return (jsxs(Box, { sx: { position: 'relative', width: sizeStyle.width, height: sizeStyle.height }, children: [jsx(TextField, { ref: (el) => {
2568
- const input = el?.querySelector('input');
2569
- if (input) {
2570
- inputRefs.current[index] = input;
2571
- }
2572
- }, type: "text", inputMode: "numeric", value: inputValue, onChange: (e) => handleChange(index, e.target.value), onKeyDown: (e) => handleKeyDown(index, e), disabled: disabled, error: error, sx: {
2573
- width: '100%',
2574
- height: '100%',
2575
- '& .MuiOutlinedInput-root': {
2576
- height: '100%',
2577
- padding: 0,
2578
- borderRadius: '50%',
2579
- '& input': {
2580
- textAlign: 'center',
2581
- fontSize: sizeStyle.fontSize,
2582
- fontWeight: 600,
2583
- padding: 0,
2584
- color: masked && isFilled ? 'transparent' : 'inherit',
2585
- WebkitTextFillColor: masked && isFilled ? 'transparent' : 'unset',
2586
- caretColor: palette.primary.main,
2587
- '&::placeholder': {
2588
- color: palette.action.disabled,
2589
- opacity: 1,
2590
- },
2591
- },
2592
- '& fieldset': {
2593
- borderColor: borderColor,
2594
- borderRadius: '50%',
2595
- },
2596
- '&:hover fieldset': {
2597
- borderColor: error ? palette.error.main : borderFocusColorValue,
2598
- },
2599
- '&.Mui-focused fieldset': {
2600
- borderColor: borderFocusColorValue,
2601
- borderWidth: 1,
2602
- },
2603
- },
2604
- '& input': {
2605
- maxLength: 1,
2606
- },
2607
- }, placeholder: "-" }), masked && isFilled && (jsx(Box, { sx: {
2608
- position: 'absolute',
2609
- top: '50%',
2610
- left: '50%',
2611
- transform: 'translate(-50%, -50%)',
2612
- fontSize: sizeStyle.fontSize,
2613
- fontWeight: 600,
2614
- color: error ? palette.error.main : palette.text.primary,
2615
- pointerEvents: 'none',
2616
- }, children: "\u25CF" }))] }));
2617
- }
2618
- // Default text type
2619
- return (jsx(TextField, { ref: (el) => {
2620
- const input = el?.querySelector('input');
2621
- if (input) {
2622
- inputRefs.current[index] = input;
2623
- }
2624
- }, type: "text", inputMode: "numeric", value: inputValue, onChange: (e) => handleChange(index, e.target.value), onKeyDown: (e) => handleKeyDown(index, e), disabled: disabled, error: error, sx: {
2625
- width: sizeStyle.width,
2626
- '& .MuiOutlinedInput-root': {
2627
- height: sizeStyle.height,
2628
- padding: 0,
2629
- '& input': {
2630
- textAlign: 'center',
2631
- fontSize: sizeStyle.fontSize,
2632
- fontWeight: 600,
2633
- padding: 0,
2634
- '&::placeholder': {
2635
- color: palette.action.disabled,
2636
- opacity: 1,
2637
- },
2638
- },
2639
- '& fieldset': {
2640
- borderColor: borderColor,
2641
- },
2642
- '&:hover fieldset': {
2643
- borderColor: error ? palette.error.main : borderFocusColorValue,
2644
- },
2645
- '&.Mui-focused fieldset': {
2646
- borderColor: borderFocusColorValue,
2647
- borderWidth: 1,
2648
- },
2649
- },
2650
- '& input': {
2651
- maxLength: 1,
2652
- },
2653
- }, placeholder: "-" }));
2654
- };
2655
- return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Box, { sx: {
2656
- mb: 1,
2657
- fontSize: 14,
2658
- fontWeight: 500,
2659
- color: palette.text.primary,
2660
- }, children: label })), jsx(Box, { sx: {
2661
- display: 'flex',
2662
- gap: `${PIN_SPACING[spacing]}px`,
2663
- justifyContent: align === 'center' ? 'center' : align === 'right' ? 'flex-end' : 'flex-start',
2664
- }, children: Array.from({ length }).map((_, index) => (jsx(Box, { children: renderPINDisplay(index) }, index))) }), error && errorMessage && (jsx(Box, { sx: {
2665
- mt: 1,
2666
- fontSize: 12,
2667
- color: palette.error.main,
2668
- textAlign: align,
2669
- }, children: errorMessage }))] }));
2670
- };
2671
-
2672
- const StyledAutocomplete$1 = styled$1(Autocomplete)(({ theme }) => ({
1785
+ styled$1(Autocomplete)(({ theme }) => ({
2673
1786
  '& .MuiOutlinedInput-root': {
2674
1787
  padding: '8px !important',
2675
1788
  display: 'flex',
@@ -2730,138 +1843,8 @@ const StyledAutocomplete$1 = styled$1(Autocomplete)(({ theme }) => ({
2730
1843
  },
2731
1844
  },
2732
1845
  }));
2733
- const SearchDropdownComponent = ({ value, onChange, onClear, onInputChange, onSearch, borderRadius = 6, disabled = false, multiple = false, label = '', placeholder = 'Search...', error = false, errorMessage, success = false, successMessage, helperText = '', options = [], loading = false, sx, }) => {
2734
- const DEBOUNCE_DELAY = 500;
2735
- const [inputValue, setInputValue] = useState('');
2736
- const [filteredOptions, setFilteredOptions] = useState(options);
2737
- const [isLoading, setIsLoading] = useState(false);
2738
- const debounceTimerRef = useRef(null);
2739
- const onSearchRef = useRef(onSearch);
2740
- const onInputChangeRef = useRef(onInputChange);
2741
- const optionsRef = useRef(options);
2742
- // Update refs when props change
2743
- useEffect(() => {
2744
- onSearchRef.current = onSearch;
2745
- onInputChangeRef.current = onInputChange;
2746
- optionsRef.current = options;
2747
- }, [onSearch, onInputChange, options]);
2748
- // Normalize value to array for internal state
2749
- const selectedValues = useMemo(() => {
2750
- if (!value)
2751
- return [];
2752
- const values = Array.isArray(value) ? value : [value];
2753
- return values.map((v) => (typeof v === 'object' ? v : { label: String(v), value: v }));
2754
- }, [value]);
2755
- // Search logic with debounce
2756
- useEffect(() => {
2757
- if (debounceTimerRef.current) {
2758
- clearTimeout(debounceTimerRef.current);
2759
- }
2760
- // Reset to original options when input is empty
2761
- if (!inputValue.trim()) {
2762
- setFilteredOptions(optionsRef.current);
2763
- return;
2764
- }
2765
- debounceTimerRef.current = setTimeout(async () => {
2766
- const searchFn = onSearchRef.current;
2767
- if (searchFn) {
2768
- // Async search
2769
- setIsLoading(true);
2770
- try {
2771
- const results = await searchFn(inputValue);
2772
- setFilteredOptions(results);
2773
- }
2774
- catch (error) {
2775
- console.error('Search error:', error);
2776
- setFilteredOptions([]);
2777
- }
2778
- finally {
2779
- setIsLoading(false);
2780
- }
2781
- }
2782
- else {
2783
- // Local filtering
2784
- const filtered = optionsRef.current.filter((opt) => opt.label.toLowerCase().includes(inputValue.toLowerCase()));
2785
- setFilteredOptions(filtered);
2786
- }
2787
- onInputChangeRef.current?.(inputValue);
2788
- }, DEBOUNCE_DELAY);
2789
- return () => {
2790
- if (debounceTimerRef.current) {
2791
- clearTimeout(debounceTimerRef.current);
2792
- }
2793
- };
2794
- }, [inputValue]);
2795
- const handleInputChange = (event, newInputValue) => {
2796
- setInputValue(newInputValue);
2797
- };
2798
- const handleChange = (event, newValue) => {
2799
- if (multiple) {
2800
- const result = Array.isArray(newValue) ? newValue : newValue ? [newValue] : [];
2801
- onChange?.(result.length > 0 ? result : null);
2802
- }
2803
- else {
2804
- onChange?.(newValue || null);
2805
- }
2806
- };
2807
- const handleClear = () => {
2808
- setInputValue('');
2809
- setFilteredOptions(optionsRef.current);
2810
- onClear?.();
2811
- };
2812
- return (jsxs(Box, { sx: { width: '100%', ...sx }, children: [label && (jsx(Typography, { variant: "subtitle2", sx: {
2813
- fontWeight: 500,
2814
- color: COLOR_GRAY[900],
2815
- marginBottom: '6px',
2816
- display: 'block',
2817
- }, children: label })), jsx(StyledAutocomplete$1, { multiple: multiple, freeSolo: true, options: filteredOptions, getOptionLabel: (option) => {
2818
- if (!option)
2819
- return '';
2820
- if (typeof option === 'object' && 'label' in option)
2821
- return option.label;
2822
- return String(option);
2823
- }, isOptionEqualToValue: (option, val) => {
2824
- if (!option || !val)
2825
- return false;
2826
- if (typeof option === 'object' && typeof val === 'object' && 'value' in option && 'value' in val) {
2827
- return option.value === val.value;
2828
- }
2829
- return false;
2830
- }, value: multiple ? selectedValues : selectedValues[0] || null, inputValue: inputValue, onInputChange: handleInputChange, onChange: handleChange, disabled: disabled || loading, loading: isLoading || loading, noOptionsText: inputValue ? 'No results found' : 'Type to search', sx: {
2831
- '& .MuiOutlinedInput-root': {
2832
- borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
2833
- borderColor: error ? COLOR_ERROR[500] : success ? COLOR_SUCCESS[500] : undefined,
2834
- },
2835
- }, renderInput: (params) => (jsx(TextField, { ...params, placeholder: placeholder, variant: "outlined", size: "small", error: error, InputProps: {
2836
- ...params.InputProps,
2837
- startAdornment: (jsxs(Fragment, { children: [jsx(InputAdornment, { position: "start", sx: { marginLeft: '4px', marginRight: '0px' }, children: jsx(SearchIcon, { sx: { color: '#999', fontSize: '18px' } }) }), params.InputProps?.startAdornment] })),
2838
- } })), renderTags: (value, getTagProps) => value.map((option, index) => {
2839
- const label = typeof option === 'object' && option && 'label' in option ? option.label : String(option);
2840
- return jsx(Chip, { ...getTagProps({ index }), label: label, size: "small" });
2841
- }), renderOption: (props, option) => {
2842
- const { key, ...otherProps } = props;
2843
- const label = option?.label || '';
2844
- return (jsx(Box, { ...otherProps, component: "li", children: label }, key));
2845
- }, componentsProps: {
2846
- clearIndicator: {
2847
- onClick: handleClear,
2848
- },
2849
- } }), error && errorMessage && (jsx(Box, { sx: {
2850
- fontSize: '12px',
2851
- color: COLOR_ERROR[500],
2852
- marginTop: '4px',
2853
- }, children: errorMessage })), success && successMessage && (jsx(Box, { sx: {
2854
- fontSize: '12px',
2855
- color: COLOR_SUCCESS[500],
2856
- marginTop: '4px',
2857
- }, children: successMessage })), helperText && !error && !success && (jsx(Box, { sx: {
2858
- fontSize: '12px',
2859
- color: COLOR_NEUTRAL[500],
2860
- marginTop: '4px',
2861
- }, children: helperText }))] }));
2862
- };
2863
1846
 
2864
- const StyledAutocomplete = styled$1(Autocomplete)(({ theme }) => ({
1847
+ styled$1(Autocomplete)(({ theme }) => ({
2865
1848
  '& .MuiOutlinedInput-root': {
2866
1849
  padding: '0 !important',
2867
1850
  display: 'flex',
@@ -2900,45 +1883,6 @@ const StyledAutocomplete = styled$1(Autocomplete)(({ theme }) => ({
2900
1883
  paddingRight: '8px',
2901
1884
  },
2902
1885
  }));
2903
- const SearchFieldComponent = ({ value, onChange, onClear, onInputChange, borderRadius = 6, disabled = false, placeholder = 'Placeholder', sx, }) => {
2904
- const DEBOUNCE_DELAY = 1000;
2905
- const [inputValue, setInputValue] = useState('');
2906
- const debounceTimer = useRef(null);
2907
- useEffect(() => {
2908
- if (debounceTimer.current) {
2909
- clearTimeout(debounceTimer.current);
2910
- }
2911
- debounceTimer.current = setTimeout(() => {
2912
- onInputChange?.(new Event('debounce'), inputValue, 'debounce');
2913
- }, DEBOUNCE_DELAY);
2914
- return () => {
2915
- if (debounceTimer.current) {
2916
- clearTimeout(debounceTimer.current);
2917
- }
2918
- };
2919
- }, [inputValue, onInputChange]);
2920
- const handleInputChange = useCallback((event, value) => {
2921
- setInputValue(value);
2922
- }, []);
2923
- const handleClear = useCallback(() => {
2924
- setInputValue('');
2925
- onClear?.();
2926
- onInputChange?.(new Event('clear'), '', 'clear');
2927
- }, [onClear, onInputChange]);
2928
- return (jsx(StyledAutocomplete, { freeSolo: true, options: [], inputValue: inputValue, onInputChange: handleInputChange, disabled: disabled, onChange: onChange, noOptionsText: null, sx: {
2929
- '& .MuiOutlinedInput-root': {
2930
- borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
2931
- },
2932
- ...sx,
2933
- }, renderInput: (params) => (jsx(TextField, { ...params, placeholder: placeholder, variant: "outlined", size: "small", InputProps: {
2934
- ...params.InputProps,
2935
- startAdornment: (jsx(InputAdornment, { position: "start", sx: { marginLeft: '8px' }, children: jsx(SearchIcon, { sx: { color: '#999', fontSize: '20px' } }) })),
2936
- } })), componentsProps: {
2937
- clearIndicator: {
2938
- onClick: handleClear,
2939
- },
2940
- } }));
2941
- };
2942
1886
 
2943
1887
  const SWITCH_SIZE = {
2944
1888
  small: { width: '36px', height: '20px', thumbSize: '16px' },
@@ -2958,7 +1902,7 @@ const SWITCH_COLORS = {
2958
1902
  thumbFocusColor: '#F4EBFF',
2959
1903
  },
2960
1904
  };
2961
- const StyledSwitch = styled$1(Switch, {
1905
+ styled$1(Switch, {
2962
1906
  shouldForwardProp: (prop) => prop !== 'size',
2963
1907
  })(({ theme, size = 'medium' }) => {
2964
1908
  const mode = theme.palette.mode;
@@ -3011,61 +1955,7 @@ const StyledSwitch = styled$1(Switch, {
3011
1955
  },
3012
1956
  };
3013
1957
  });
3014
- const SwitchComponent = ({ title, sx, ...switchProps }) => {
3015
- if (!title) {
3016
- return jsx(StyledSwitch, { disableRipple: true, ...switchProps });
3017
- }
3018
- return (jsxs(StackRowAlignCenterJustEnd, { sx: {
3019
- display: 'inline-flex',
3020
- alignItems: 'center',
3021
- gap: '12px',
3022
- ...sx,
3023
- }, children: [jsx(StyledSwitch, { disableRipple: true, ...switchProps }), title] }));
3024
- };
3025
1958
 
3026
- const TAB_STYLES = {
3027
- position: 'relative',
3028
- padding: '18px 16px',
3029
- cursor: 'pointer',
3030
- minHeight: 44,
3031
- '&:hover': {
3032
- bgcolor: '#F3F4F6',
3033
- },
3034
- };
3035
- const TAB_UNDERLINE_STYLES = {
3036
- width: '1px',
3037
- alignSelf: 'stretch',
3038
- bgcolor: '#E5E7EB',
3039
- };
3040
- const TABS_CONTAINER_HORIZONTAL = {
3041
- display: 'flex',
3042
- alignItems: 'center',
3043
- borderBottom: '2px solid #E5E7EB',
3044
- };
3045
- const TAB_ACTIVE_BACKGROUND_HORIZONTAL = {
3046
- position: 'absolute',
3047
- bottom: -2,
3048
- left: 0,
3049
- right: 0,
3050
- height: '2px',
3051
- bgcolor: '#0F766E',
3052
- };
3053
- const TABS_CONTAINER_VERTICAL = {
3054
- position: 'relative',
3055
- padding: '10px',
3056
- cursor: 'pointer',
3057
- minHeight: 40,
3058
- '&:hover': {
3059
- bgcolor: '#F3F4F6',
3060
- },
3061
- width: '100%',
3062
- };
3063
- const TAB_ACTIVE_BACKGROUND_VERTICAL = {
3064
- position: 'absolute',
3065
- inset: 0,
3066
- bgcolor: '#E6EEED',
3067
- borderRadius: 1,
3068
- };
3069
1959
  var TabColors;
3070
1960
  (function (TabColors) {
3071
1961
  TabColors["ACTIVE_TEXT"] = "#0F766E";
@@ -3074,171 +1964,7 @@ var TabColors;
3074
1964
  TabColors["MENU_ACTIVE_BACKGROUND"] = "#E0F2FE";
3075
1965
  })(TabColors || (TabColors = {}));
3076
1966
 
3077
- const TabsComponent = ({ idSelect, tabs, size, direction = 'row', maxDisplay, onChange, sx, sxTabs, sxWrapper, }) => {
3078
- // state
3079
- const [selected, setSelected] = useState(idSelect);
3080
- const [anchorEl, setAnchorEl] = useState(null);
3081
- const layoutGroupId = useId();
3082
- useEffect(() => {
3083
- setSelected(idSelect);
3084
- }, [idSelect]);
3085
- const isVertical = direction === 'column';
3086
- const showOverflow = !isVertical && maxDisplay && tabs.length > maxDisplay;
3087
- const visibleTabs = showOverflow ? tabs.slice(0, maxDisplay) : tabs;
3088
- const overflowTabs = showOverflow ? tabs.slice(maxDisplay) : [];
3089
- // function
3090
- const handleOpenDropdown = (event) => {
3091
- setAnchorEl(event.currentTarget);
3092
- };
3093
- const handleTabClick = (tab) => {
3094
- setSelected(tab.id);
3095
- onChange?.(tab.id);
3096
- if (tab.onClick) {
3097
- tab.onClick();
3098
- }
3099
- };
3100
- const handleOverflowItemClick = (tab) => {
3101
- handleTabClick(tab);
3102
- setAnchorEl(null);
3103
- };
3104
- return (jsx(React.Fragment, { children: isVertical ? (jsx(LayoutGroup, { id: layoutGroupId, children: jsx(Stack, { direction: "column", sx: { width: 'fit-content', gap: PADDING_GAP_ITEM_SMALL, ...sxWrapper }, children: tabs.map((tab) => {
3105
- const isActive = tab.id === selected;
3106
- return (jsx(LinkElement, { href: tab.href, onClick: tab.onClick, id: tab.id, children: jsxs(Box, { sx: { position: 'relative' }, children: [jsx(Stack, { component: motion.div, sx: {
3107
- ...TABS_CONTAINER_VERTICAL,
3108
- color: isActive ? TabColors.ACTIVE_TEXT : TabColors.INACTIVE_TEXT,
3109
- }, onTap: () => handleTabClick(tab), children: jsxs(Box, { sx: {
3110
- ...TYPOGRAPHY_STYLES.textMd.medium,
3111
- display: 'flex',
3112
- alignItems: 'center',
3113
- gap: tab.icon ? 0.5 : 0,
3114
- position: 'relative',
3115
- zIndex: 1,
3116
- ...sx,
3117
- }, children: [tab.icon && jsx(IconElement, { size: size, icon: tab.icon }), tab.name] }) }), isActive && (jsx(Box, { component: motion.div, sx: { ...TAB_ACTIVE_BACKGROUND_VERTICAL }, layoutId: `${layoutGroupId}-background` }))] }) }, tab.id));
3118
- }) }) })) : (jsx(LayoutGroup, { id: layoutGroupId, children: jsxs(Box, { sx: { position: 'relative', display: 'flex', alignItems: 'center' }, children: [jsxs(Box, { sx: { ...TABS_CONTAINER_HORIZONTAL }, children: [visibleTabs.map((tab) => {
3119
- const isActive = tab.id === selected;
3120
- return (jsx(LinkElement, { href: tab.href, onClick: tab.onClick, id: tab.id, children: jsxs(Stack, { component: motion.div, sx: {
3121
- color: isActive ? TabColors.ACTIVE_TEXT : TabColors.INACTIVE_TEXT,
3122
- position: 'relative',
3123
- padding: '18px 16px',
3124
- cursor: 'pointer',
3125
- minHeight: 40,
3126
- '&:hover': {
3127
- bgcolor: TabColors.HOVER_BACKGROUND,
3128
- },
3129
- ...sxTabs,
3130
- }, onTap: () => handleTabClick(tab), children: [jsxs(Box, { sx: {
3131
- ...TYPOGRAPHY_STYLES.textMd.medium,
3132
- display: 'flex',
3133
- alignItems: 'center',
3134
- gap: tab.icon ? 0.5 : 0,
3135
- ...sx,
3136
- }, children: [tab.icon && jsx(IconElement, { size: size, icon: tab.icon }), tab.name] }), isActive && (jsx(Box, { component: motion.div, sx: { ...TAB_ACTIVE_BACKGROUND_HORIZONTAL }, layoutId: `${layoutGroupId}-underline` }))] }) }, tab.id));
3137
- }), showOverflow && (jsxs(React.Fragment, { children: [jsx(Box, { sx: { ...TAB_UNDERLINE_STYLES } }), jsx(Stack, { sx: {
3138
- ...TAB_STYLES,
3139
- }, onClick: handleOpenDropdown, children: jsx(IconElement, { icon: "more_horiz", size: size }) })] }))] }), jsx(Menu, { disableScrollLock: true, anchorEl: anchorEl, open: Boolean(anchorEl), onClose: () => setAnchorEl(null), anchorOrigin: {
3140
- vertical: 'bottom',
3141
- horizontal: 'left',
3142
- }, transformOrigin: {
3143
- vertical: 'top',
3144
- horizontal: 'left',
3145
- }, children: overflowTabs.map((tab) => {
3146
- const isActive = tab.id === selected;
3147
- return (jsx(MenuItem, { onClick: () => handleOverflowItemClick(tab), sx: {
3148
- color: isActive ? TabColors.ACTIVE_TEXT : TabColors.INACTIVE_TEXT,
3149
- bgcolor: isActive ? TabColors.MENU_ACTIVE_BACKGROUND : 'transparent',
3150
- '&:hover': {
3151
- bgcolor: isActive ? TabColors.MENU_ACTIVE_BACKGROUND : TabColors.HOVER_BACKGROUND,
3152
- },
3153
- }, children: jsxs(Box, { sx: {
3154
- display: 'flex',
3155
- alignItems: 'center',
3156
- gap: tab.icon ? 0.5 : 0,
3157
- }, children: [tab.icon && jsx(IconElement, { size: size, icon: tab.icon }), tab.name] }) }, tab.id));
3158
- }) })] }) })) }));
3159
- };
3160
-
3161
- const TextAreaComponent = ({ label = '', placeholder = '', value = '', disabled = false, error = false, success = false, errorMessage, successMessage, borderRadius = 6, onChange, onBlur, helperText = '', rows = 4, maxLength, sx, }) => {
3162
- const borderRadiusValue = borderRadius === 'max' ? '100px' : `${borderRadius}px`;
3163
- const getHelperText = () => {
3164
- if (error && errorMessage)
3165
- return errorMessage;
3166
- if (success && successMessage)
3167
- return successMessage;
3168
- if (helperText)
3169
- return helperText;
3170
- return '';
3171
- };
3172
- const getHelperTextColor = () => {
3173
- if (error)
3174
- return COLOR_ERROR[500];
3175
- if (success)
3176
- return COLOR_SUCCESS[500];
3177
- return COLOR_NEUTRAL[400];
3178
- };
3179
- const getBorderColor = () => {
3180
- if (error)
3181
- return COLOR_ERROR[500];
3182
- if (success)
3183
- return COLOR_SUCCESS[500];
3184
- return COLOR_NEUTRAL[300];
3185
- };
3186
- return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
3187
- display: 'block',
3188
- ...TYPOGRAPHY.textFieldLabel,
3189
- color: COLOR_GRAY[800],
3190
- marginBottom: '4px',
3191
- }, children: label })), jsxs(Box, { sx: { position: 'relative' }, children: [jsx(TextField, { fullWidth: true, multiline: true, rows: rows, placeholder: placeholder, value: value, disabled: disabled, onChange: (e) => onChange?.(e.target.value), onBlur: (e) => onBlur?.(e.target.value), inputProps: {
3192
- maxLength: maxLength,
3193
- style: {
3194
- ...TYPOGRAPHY.text14Regular,
3195
- paddingBottom: maxLength ? '24px' : '0px',
3196
- },
3197
- }, sx: {
3198
- '& .MuiOutlinedInput-root': {
3199
- borderRadius: borderRadiusValue,
3200
- backgroundColor: disabled ? COLOR_NEUTRAL[100] : 'white',
3201
- transition: 'all 0.2s ease',
3202
- '& fieldset': {
3203
- borderColor: getBorderColor(),
3204
- },
3205
- '&:hover fieldset': {
3206
- borderColor: disabled ? getBorderColor() : error ? COLOR_ERROR[500] : COLOR_NEUTRAL[400],
3207
- },
3208
- '&.Mui-focused fieldset': {
3209
- borderColor: error ? COLOR_ERROR[500] : COLOR_NEUTRAL[400],
3210
- borderWidth: '1.5px',
3211
- },
3212
- },
3213
- '& .MuiOutlinedInput-input': {
3214
- color: value ? COLOR_GRAY[900] : COLOR_NEUTRAL[400],
3215
- '&::placeholder': {
3216
- color: COLOR_NEUTRAL[400],
3217
- opacity: 1,
3218
- },
3219
- '&:disabled': {
3220
- color: COLOR_NEUTRAL[400],
3221
- WebkitTextFillColor: COLOR_NEUTRAL[400],
3222
- },
3223
- },
3224
- '& .MuiOutlinedInput-notchedOutline': {
3225
- borderColor: getBorderColor(),
3226
- },
3227
- } }), maxLength && (jsxs(Box, { sx: {
3228
- position: 'absolute',
3229
- bottom: '8px',
3230
- right: '12px',
3231
- fontSize: '12px',
3232
- color: COLOR_NEUTRAL[400],
3233
- pointerEvents: 'none',
3234
- }, children: ["(", value?.length, "/", maxLength, ")"] }))] }), getHelperText() && (jsx(Box, { sx: {
3235
- color: getHelperTextColor(),
3236
- marginTop: '4px',
3237
- ...TYPOGRAPHY.textFieldHelper,
3238
- }, children: getHelperText() }))] }));
3239
- };
3240
-
3241
- const StyledTextField = styled(MuiTextField)(({ theme }) => {
1967
+ styled(MuiTextField)(({ theme }) => {
3242
1968
  return {
3243
1969
  '& .MuiOutlinedInput-root': {
3244
1970
  '& fieldset': { borderColor: COLOR_NEUTRAL[300] },
@@ -3280,221 +2006,10 @@ const StyledTextField = styled(MuiTextField)(({ theme }) => {
3280
2006
  },
3281
2007
  };
3282
2008
  });
3283
- const TextFieldComponent = ({ label, placeholder = 'Placeholder', value, disabled = false, error = false, success = false, errorMessage, successMessage, borderRadius = 6, helperText, onChange, iconBefore, iconAfter, sx, ...props }) => {
3284
- return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
3285
- display: 'block',
3286
- ...TYPOGRAPHY.textFieldLabel,
3287
- color: COLOR_GRAY[800],
3288
- marginBottom: '4px',
3289
- }, children: label })), jsx(StyledTextField, { placeholder: placeholder, value: value, disabled: disabled, error: error, helperText: error ? errorMessage : helperText, size: "small", fullWidth: true, onChange: onChange, InputProps: {
3290
- startAdornment: iconBefore ? jsx(InputAdornment, { position: "start", children: iconBefore }) : undefined,
3291
- endAdornment: iconAfter ? jsx(InputAdornment, { position: "end", children: iconAfter }) : undefined,
3292
- }, sx: {
3293
- '& .MuiOutlinedInput-root': {
3294
- borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
3295
- ...(success && {
3296
- '&.Mui-focused': {
3297
- boxShadow: `0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px ${COLOR_SUCCESS[100]}`,
3298
- },
3299
- }),
3300
- },
3301
- }, ...props }), success && !error && successMessage && (jsx(Typography, { sx: {
3302
- ...TYPOGRAPHY.textFieldHelper,
3303
- color: COLOR_SUCCESS[500],
3304
- marginTop: '4px',
3305
- }, children: successMessage }))] }));
3306
- };
3307
2009
 
3308
- const SX_STYLES = {
2010
+ ({
3309
2011
  progressBar: {
3310
- position: 'absolute',
3311
- top: 0,
3312
- left: 0,
3313
- height: '100%',
3314
- backgroundColor: COLOR_GRAY[200],
3315
- opacity: 0.8,
3316
- transition: 'width 0.3s ease, opacity 0.3s ease',
3317
- animation: 'wave 1.5s linear infinite',
3318
- '@keyframes wave': {
3319
- '0%': { backgroundPosition: '0% 0%' },
3320
- '50%': { backgroundPosition: '100% 0%' },
3321
- '100%': { backgroundPosition: '0% 0%' },
3322
- },
3323
- },
3324
- imageIcon: {
3325
- width: '40px',
3326
- height: '40px',
3327
- flexShrink: 0,
3328
- position: 'relative',
3329
- zIndex: 1,
3330
- },
3331
- contentBox: {
3332
- flexGrow: 1,
3333
- minWidth: 0,
3334
- position: 'relative',
3335
- zIndex: 1,
3336
- },
3337
- textBox: {
3338
- minWidth: 0,
3339
- flexGrow: 1,
3340
- mr: 2,
3341
- },
3342
- actionBox: {
3343
- flexShrink: 0,
3344
- display: 'flex',
3345
- alignItems: 'center',
3346
- position: 'relative',
3347
- zIndex: 1,
3348
- },
3349
- linearProgress: {
3350
- mt: 1,
3351
- width: '100%',
3352
- },
3353
- };
3354
-
3355
- const VIDEO_EXTENSIONS = ['mp4', 'mov', 'avi', 'wmv', 'flv', 'mkv', 'webm'];
3356
- const ICON_PATH = {
3357
- VIDEO: '/images/icon/film.svg',
3358
- FILE: '/images/icon/file.svg',
3359
- };
3360
- // ============================================================================
3361
- // Helper Functions
3362
- // ============================================================================
3363
- const formatFileSize = (bytes) => {
3364
- if (bytes === 0)
3365
- return '0 Bytes';
3366
- const k = 1024;
3367
- const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
3368
- const i = Math.floor(Math.log(bytes) / Math.log(k));
3369
- return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
3370
- };
3371
- const getFileIcon = (fileName) => {
3372
- const ext = fileName.split('.').pop()?.toLowerCase();
3373
- return ext && VIDEO_EXTENSIONS.includes(ext) ? ICON_PATH.VIDEO : ICON_PATH.FILE;
3374
- };
3375
- // ============================================================================
3376
- // Component
3377
- // ============================================================================
3378
- const UploaderItemComponent = ({ file, progress = 0, status = 'pending', onDelete, onRetry, isProcess = true, borderSuccess, borderError = COLOR_ERROR[600], sx, }) => {
3379
- // Memoize
3380
- const iconSrc = useMemo(() => getFileIcon(file.name), [file.name]);
3381
- // Status flags
3382
- const isCompleted = status === 'success';
3383
- const isFailed = status === 'failed';
3384
- const isUploading = status === 'uploading';
3385
- // Determine colors based on status
3386
- const borderColor = isFailed
3387
- ? String(borderError)
3388
- : isCompleted && borderSuccess
3389
- ? String(borderSuccess)
3390
- : '#e0e0e0';
3391
- const textColor = isFailed ? String(borderError) : '#737373';
3392
- const subtitleColor = isFailed ? String(borderError) : '#a3a3a3';
3393
- // Render progress info
3394
- const renderProgressInfo = () => {
3395
- if (isUploading && !isCompleted)
3396
- return ` • ${Math.round(progress)}% uploaded`;
3397
- if (isFailed)
3398
- return ' • Upload failed';
3399
- return '';
3400
- };
3401
- return (jsxs(Box, { sx: {
3402
- display: 'flex',
3403
- alignItems: 'flex-start',
3404
- padding: '16px',
3405
- border: '1px solid',
3406
- borderColor: borderColor,
3407
- borderRadius: '8px',
3408
- gap: '16px',
3409
- position: 'relative',
3410
- overflow: 'hidden',
3411
- transition: 'background-color 0.3s ease',
3412
- backgroundColor: 'background.paper',
3413
- ...sx,
3414
- }, children: [!isProcess && isUploading && !isCompleted && !isFailed && (jsx(Box, { sx: { ...SX_STYLES.progressBar, width: `${progress}%` } })), jsx(Box, { component: "img", src: iconSrc, alt: "file icon", sx: SX_STYLES.imageIcon }), jsxs(Box, { sx: SX_STYLES.contentBox, children: [jsxs(StackRowAlignCenterJustBetween, { children: [jsxs(Box, { sx: SX_STYLES.textBox, children: [jsx(Typography, { noWrap: true, title: file.name, sx: { ...TYPOGRAPHY.text14Medium, color: textColor }, children: file.name }), jsxs(Typography, { sx: { ...TYPOGRAPHY.text14Regular, color: subtitleColor }, children: [formatFileSize(file.size), renderProgressInfo()] })] }), jsxs(Box, { sx: SX_STYLES.actionBox, children: [!isProcess && isUploading && !isCompleted && (jsx(Box, { sx: { position: 'relative', display: 'inline-flex', mr: 1 }, children: jsx(CircularProgress, { variant: "determinate", value: progress, color: "success", size: 24 }) })), isCompleted && jsx(CheckCircleIcon, { color: "success", sx: { mr: 1 } }), isFailed && onRetry && (jsx(IconButton, { size: "small", onClick: onRetry, title: "Retry upload", children: jsx(RefreshIcon, { fontSize: "small", sx: { color: borderError } }) })), !isFailed && onDelete && (jsx(IconButton, { size: "small", onClick: onDelete, children: jsx(IconElement, { icon: "delete" }) }))] })] }), isProcess && isUploading && (jsx(Box, { sx: SX_STYLES.linearProgress, children: jsx(LinearProgress, { variant: "determinate", value: progress, color: "success", sx: { height: 8, borderRadius: 4 } }) }))] })] }));
3415
- };
3416
-
3417
- const UploaderComponent = ({ onFilesSelected, accept = '*', multiple = true, children, sx, labelSx, uploadLabel = 'Click to upload', appearance, files: externalFiles, onDeleteFile, onRetryFile, borderError, }) => {
3418
- const fileInputRef = useRef(null);
3419
- const [isDragging, setIsDragging] = useState(false);
3420
- // Sử dụng external files nếu có, nếu không hiển thị rỗng
3421
- const displayFiles = externalFiles || [];
3422
- const handleClick = () => {
3423
- fileInputRef.current?.click();
3424
- };
3425
- const handleFileChange = (event) => {
3426
- const selectedFiles = event.target.files;
3427
- if (selectedFiles) {
3428
- const fileArray = Array.from(selectedFiles);
3429
- onFilesSelected(fileArray);
3430
- }
3431
- event.target.value = '';
3432
- };
3433
- const handleDeleteFile = (file) => {
3434
- if (onDeleteFile) {
3435
- onDeleteFile(file);
3436
- }
3437
- };
3438
- const handleDragOver = (e) => {
3439
- e.preventDefault();
3440
- e.stopPropagation();
3441
- setIsDragging(true);
3442
- };
3443
- const handleDragLeave = (e) => {
3444
- e.preventDefault();
3445
- e.stopPropagation();
3446
- setIsDragging(false);
3447
- };
3448
- const handleDrop = (e) => {
3449
- e.preventDefault();
3450
- e.stopPropagation();
3451
- setIsDragging(false);
3452
- const files = e.dataTransfer.files;
3453
- if (files) {
3454
- onFilesSelected(Array.from(files));
3455
- }
3456
- };
3457
- return (jsxs(Box, { sx: {
3458
- border: '2px solid',
3459
- borderColor: appearance?.borderColor || 'action.selected',
3460
- borderRadius: '8px',
3461
- padding: '32px 24px',
3462
- textAlign: 'center',
3463
- cursor: 'pointer',
3464
- transition: 'all 0.3s ease',
3465
- backgroundColor: isDragging ? 'action.selected' : appearance?.background || 'background.paper',
3466
- '&:hover': {
3467
- borderColor: appearance?.borderColorHover || appearance?.borderColor || 'primary.main',
3468
- filter: 'brightness(0.92)',
3469
- },
3470
- ...sx,
3471
- }, onClick: handleClick, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, children: [jsx("input", { ref: fileInputRef, type: "file", accept: accept, multiple: multiple, onChange: handleFileChange, style: { display: 'none' } }), displayFiles.length === 0 && (jsx(Fragment, { children: children ? (jsxs(Box, { children: [children, jsxs(Box, { component: "p", sx: {
3472
- color: 'primary.main',
3473
- textDecoration: 'underline',
3474
- fontWeight: 500,
3475
- fontSize: '14px',
3476
- marginTop: '12px',
3477
- margin: '12px 0 0 0',
3478
- ...labelSx,
3479
- }, children: [uploadLabel, " or drag and drop"] })] })) : (jsxs(Box, { children: [jsx(Box, { component: "img", src: "/images/icon/uploader.svg", alt: "Upload icon", sx: {
3480
- width: '46px',
3481
- height: '46px',
3482
- marginBottom: '12px',
3483
- } }), jsxs(Box, { component: "p", sx: {
3484
- color: 'primary.main',
3485
- textDecoration: 'underline',
3486
- fontWeight: 500,
3487
- fontSize: '14px',
3488
- margin: 0,
3489
- ...labelSx,
3490
- }, children: [uploadLabel, " or drag and drop"] })] })) })), displayFiles && displayFiles.length > 0 && (jsx(Box, { sx: {
3491
- marginTop: '24px',
3492
- display: 'flex',
3493
- flexDirection: 'column',
3494
- gap: '12px',
3495
- textAlign: 'left',
3496
- }, onClick: (e) => e.stopPropagation(), children: displayFiles.map((item, index) => (jsx(UploaderItemComponent, { file: item.file, progress: item.progress, status: item.status, isProcess: item.isProcess ?? true, onDelete: () => handleDeleteFile(item.file), onRetry: () => onRetryFile?.(item.id), borderSuccess: appearance?.borderSuccess, borderError: borderError }, item.id || index))) }))] }));
3497
- };
2012
+ backgroundColor: COLOR_GRAY[200]}});
3498
2013
 
3499
- export { AVATAR_SIZES, AvatarColor, AvatarComponent, AvatarGroupComponent as AvatarGroup, AvatarLabelGroupComponent as AvatarLabelGroup, AvatarProfileComponent as AvatarProfile, AvatarUserComponent as AvatarUser, BADGE_FONT_SIZES, BADGE_SIZES, BadgeImage, BadgeLive, BadgeNumber, BadgeOnline, BreadcrumbsComponent as Breadcrumbs, ButtonBarComponent as ButtonBar, ButtonComponent, COLOR_ACCENT, COLOR_BRAND, COLOR_ERROR, COLOR_GRAY, COLOR_INFO, COLOR_NEUTRAL, COLOR_SUCCESS, COLOR_WARNING, CheckboxComponent as Checkbox, ChipComponent as Chip, DateFieldComponent as DateField, DateRangePickerComponent as DateRangePicker, DialogWrapper, DropdownFieldComponent as DropdownField, FONT_FAMILY, FONT_SIZE, FONT_STYLE, FONT_WEIGHT, GridComponent as Grid, IconElement, ImageElement, ImageSizeType, InputStepperComponent as InputStepper, LINE_HEIGHT, LinkElement, LinkFieldComponent as LinkField, LinkInternalElement, MAP_SIZE, ModalComponent as Modal, ModalCardComponent as ModalCard, ModalDescription, ModalIcon, ModalTitle, MoneyFieldComponent as MoneyField, PINComponent as PIN, PhoneNumberFieldComponent as PhoneField, SIZE_EXTRA_LARGE, style_constant as STYLE, SearchDropdownComponent as SearchDropdown, SearchFieldComponent as SearchField, SwitchComponent as Switch, TYPOGRAPHY, TYPOGRAPHY_STYLES, TabsComponent as Tabs, TextAreaComponent as TextArea, TextFieldComponent as TextField, TypographyOneLine, UploaderComponent as Uploader, createTypography, getBadgePosition };
2014
+ export { AVATAR_SIZES, AvatarColor, AvatarComponent, AvatarGroupComponent, AvatarLabelGroupComponent, AvatarProfileComponent, AvatarUserComponent, BADGE_FONT_SIZES, BADGE_SIZES, BadgeImage, BadgeLive, BadgeNumber, BadgeOnline, ButtonComponent, COLOR_ACCENT, COLOR_BRAND, COLOR_ERROR, COLOR_GRAY, COLOR_INFO, COLOR_NEUTRAL, COLOR_SUCCESS, COLOR_WARNING, CheckboxContentComponent, DialogWrapper, FONT_FAMILY, FONT_SIZE, FONT_STYLE, FONT_WEIGHT, IconElement, ImageElement, ImageSizeType, LINE_HEIGHT, LinkElement, LinkInternalElement, MAP_SIZE, ModalComponent as Modal, ModalCardComponent as ModalCard, ModalDescription, ModalIcon, ModalTitle, SIZE_EXTRA_LARGE, style_constant as STYLE, TYPOGRAPHY, TYPOGRAPHY_STYLES, TypographyOneLine, createTypography, getBadgePosition };
3500
2015
  //# sourceMappingURL=index.js.map