@officesdk/design 0.2.4 → 0.2.6

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.
@@ -1,6 +1,6 @@
1
1
  import ReactDOM from 'react-dom';
2
- import React3, { forwardRef, useState, createContext, useEffect, useMemo, useRef, useCallback, useContext } from 'react';
3
- import { ArrowRightIcon, CloseIcon, SearchIcon, ErrorIcon, WarningIcon, InfoIcon, SuccessIcon, CheckIcon, ChevronDownIcon } from '@officesdk/design/icons';
2
+ import React3, { forwardRef, useState, useEffect, createContext, useCallback, useContext, useMemo, useRef } from 'react';
3
+ import { ArrowRightIcon, CloseIcon, SearchIcon, ErrorIcon, WarningIcon, InfoIcon, SuccessIcon, CheckIcon, ArrowDownIcon } from '@officesdk/design/icons';
4
4
  import { lightTheme } from '@officesdk/design/theme';
5
5
  import baseStyled, { createGlobalStyle as createGlobalStyle$1 } from 'styled-components';
6
6
  import RcTooltip from 'rc-tooltip';
@@ -1278,15 +1278,355 @@ var init_Slider2 = __esm({
1278
1278
  init_valueMap();
1279
1279
  }
1280
1280
  });
1281
- var NumberInputContainer, InputWrapper, UnitText, StyledInput, ButtonGroup, StepButton, UpArrow, DownArrow, NumberInput;
1281
+ var ToastContext, ToastWrapper2, ToastContainer2, useToast;
1282
+ var init_ToastContainer = __esm({
1283
+ "src/Toast/ToastContainer.tsx"() {
1284
+ init_styled();
1285
+ init_Toast();
1286
+ ToastContext = createContext(null);
1287
+ ToastWrapper2 = styled.div`
1288
+ position: fixed;
1289
+ z-index: 9999;
1290
+ display: flex;
1291
+ flex-direction: column;
1292
+ gap: 12px;
1293
+ pointer-events: none;
1294
+
1295
+ > * {
1296
+ pointer-events: auto;
1297
+ }
1298
+
1299
+ ${({ $placement, theme: theme2 }) => {
1300
+ const offset = theme2.components?.toast?.offset || { vertical: "24px", horizontal: "24px" };
1301
+ const vertical = offset.vertical || "24px";
1302
+ const horizontal = offset.horizontal || "24px";
1303
+ const styles = {
1304
+ "top-right": `
1305
+ top: ${vertical};
1306
+ right: ${horizontal};
1307
+ `,
1308
+ "top-left": `
1309
+ top: ${vertical};
1310
+ left: ${horizontal};
1311
+ `,
1312
+ "top-center": `
1313
+ top: ${vertical};
1314
+ left: 50%;
1315
+ transform: translateX(-50%);
1316
+ `,
1317
+ "bottom-right": `
1318
+ bottom: ${vertical};
1319
+ right: ${horizontal};
1320
+ `,
1321
+ "bottom-left": `
1322
+ bottom: ${vertical};
1323
+ left: ${horizontal};
1324
+ `,
1325
+ "bottom-center": `
1326
+ bottom: ${vertical};
1327
+ left: 50%;
1328
+ transform: translateX(-50%);
1329
+ `
1330
+ };
1331
+ return styles[$placement] || styles["top-right"];
1332
+ }}
1333
+ `;
1334
+ ToastContainer2 = ({
1335
+ placement = "top-right",
1336
+ maxCount = 5,
1337
+ defaultDuration = 3e3,
1338
+ children
1339
+ }) => {
1340
+ const [toasts, setToasts] = useState([]);
1341
+ const showToast = useCallback((props) => {
1342
+ const id = `toast-${Date.now()}-${Math.random()}`;
1343
+ const newToast = {
1344
+ ...props,
1345
+ id,
1346
+ duration: props.duration ?? defaultDuration
1347
+ };
1348
+ setToasts((prev) => {
1349
+ const updated = [...prev, newToast];
1350
+ return updated.slice(-maxCount);
1351
+ });
1352
+ return id;
1353
+ }, [maxCount, defaultDuration]);
1354
+ const hideToast = useCallback((id) => {
1355
+ setToasts((prev) => prev.filter((toast2) => toast2.id !== id));
1356
+ }, []);
1357
+ const success = useCallback((message, options) => {
1358
+ return showToast({ ...options, variant: "success", message });
1359
+ }, [showToast]);
1360
+ const info = useCallback((message, options) => {
1361
+ return showToast({ ...options, variant: "info", message });
1362
+ }, [showToast]);
1363
+ const error = useCallback((message, options) => {
1364
+ return showToast({ ...options, variant: "error", message });
1365
+ }, [showToast]);
1366
+ const warn = useCallback((message, options) => {
1367
+ return showToast({ ...options, variant: "warn", message });
1368
+ }, [showToast]);
1369
+ const loading = useCallback((message, options) => {
1370
+ return showToast({ ...options, variant: "loading", message });
1371
+ }, [showToast]);
1372
+ const contextValue = {
1373
+ showToast,
1374
+ hideToast,
1375
+ success,
1376
+ info,
1377
+ error,
1378
+ warn,
1379
+ loading
1380
+ };
1381
+ return /* @__PURE__ */ React3.createElement(ToastContext.Provider, { value: contextValue }, children, /* @__PURE__ */ React3.createElement(ToastWrapper2, { $placement: placement }, toasts.map((toast2) => /* @__PURE__ */ React3.createElement(
1382
+ Toast,
1383
+ {
1384
+ key: toast2.id,
1385
+ ...toast2,
1386
+ onClose: () => hideToast(toast2.id)
1387
+ }
1388
+ ))));
1389
+ };
1390
+ useToast = () => {
1391
+ const context = useContext(ToastContext);
1392
+ if (!context) {
1393
+ throw new Error("useToast must be used within ToastContainer");
1394
+ }
1395
+ return context;
1396
+ };
1397
+ ToastContainer2.displayName = "ToastContainer";
1398
+ }
1399
+ });
1400
+ var UIConfigContext, UIConfigProvider, useUIConfig;
1401
+ var init_UIConfigProvider = __esm({
1402
+ "src/UIConfigProvider/UIConfigProvider.tsx"() {
1403
+ init_IconProvider();
1404
+ init_ToastContainer();
1405
+ init_configManager();
1406
+ init_context();
1407
+ UIConfigContext = createContext(null);
1408
+ UIConfigProvider = ({ config, children }) => {
1409
+ useEffect(() => {
1410
+ registerGlobalContext({
1411
+ theme: config.theme,
1412
+ render: config.renderFunction
1413
+ });
1414
+ initUIConfig(config);
1415
+ }, [config]);
1416
+ const { icons = {} } = config;
1417
+ const toastConfig = {
1418
+ maxCount: config.toast?.maxCount ?? 5,
1419
+ defaultDuration: config.toast?.defaultDuration ?? 3e3
1420
+ };
1421
+ return /* @__PURE__ */ React3.createElement(UIConfigContext.Provider, { value: config }, /* @__PURE__ */ React3.createElement(IconProvider, { icons }, /* @__PURE__ */ React3.createElement(
1422
+ ToastContainer2,
1423
+ {
1424
+ maxCount: toastConfig.maxCount,
1425
+ defaultDuration: toastConfig.defaultDuration
1426
+ },
1427
+ children
1428
+ )));
1429
+ };
1430
+ useUIConfig = () => {
1431
+ const context = useContext(UIConfigContext);
1432
+ return context || getUIConfig();
1433
+ };
1434
+ UIConfigProvider.displayName = "UIConfigProvider";
1435
+ }
1436
+ });
1437
+
1438
+ // src/UIConfigProvider/createUIConfig.ts
1439
+ var createUIConfig, mergeUIConfig;
1440
+ var init_createUIConfig = __esm({
1441
+ "src/UIConfigProvider/createUIConfig.ts"() {
1442
+ createUIConfig = (config) => {
1443
+ return {
1444
+ // Theme is required
1445
+ theme: config.theme,
1446
+ // Icons with default
1447
+ icons: config.icons ?? {},
1448
+ // Toast with defaults
1449
+ toast: {
1450
+ maxCount: config.toast?.maxCount ?? 5,
1451
+ defaultDuration: config.toast?.defaultDuration ?? 3e3,
1452
+ position: config.toast?.position ?? "top-right",
1453
+ offset: {
1454
+ x: config.toast?.offset?.x ?? 24,
1455
+ y: config.toast?.offset?.y ?? 24
1456
+ }
1457
+ },
1458
+ // Locale with default
1459
+ locale: config.locale ?? "en-US",
1460
+ // I18n with defaults
1461
+ i18n: {
1462
+ toast: {
1463
+ closeLabel: config.i18n?.toast?.closeLabel ?? "Close"
1464
+ },
1465
+ button: {
1466
+ loadingText: config.i18n?.button?.loadingText ?? "Loading..."
1467
+ },
1468
+ common: {
1469
+ confirm: config.i18n?.common?.confirm ?? "Confirm",
1470
+ cancel: config.i18n?.common?.cancel ?? "Cancel",
1471
+ ok: config.i18n?.common?.ok ?? "OK"
1472
+ }
1473
+ },
1474
+ // Z-index with defaults
1475
+ zIndex: {
1476
+ toast: config.zIndex?.toast ?? 9999,
1477
+ modal: config.zIndex?.modal ?? 1e4,
1478
+ dropdown: config.zIndex?.dropdown ?? 1e3,
1479
+ tooltip: config.zIndex?.tooltip ?? 1001
1480
+ },
1481
+ // Animation with defaults
1482
+ animation: {
1483
+ duration: config.animation?.duration ?? 200,
1484
+ easing: config.animation?.easing ?? "cubic-bezier(0.4, 0, 0.2, 1)",
1485
+ disabled: config.animation?.disabled ?? false
1486
+ },
1487
+ // A11y with defaults
1488
+ a11y: {
1489
+ announceMessages: config.a11y?.announceMessages ?? true,
1490
+ focusVisible: config.a11y?.focusVisible ?? true,
1491
+ reduceMotion: config.a11y?.reduceMotion ?? false
1492
+ }
1493
+ };
1494
+ };
1495
+ mergeUIConfig = (baseConfig, ...configs) => {
1496
+ const merged = configs.reduce((acc, config) => ({
1497
+ ...acc,
1498
+ ...config,
1499
+ toast: { ...acc.toast, ...config.toast },
1500
+ i18n: { ...acc.i18n, ...config.i18n },
1501
+ zIndex: { ...acc.zIndex, ...config.zIndex },
1502
+ animation: { ...acc.animation, ...config.animation },
1503
+ a11y: { ...acc.a11y, ...config.a11y }
1504
+ }), baseConfig);
1505
+ return merged;
1506
+ };
1507
+ }
1508
+ });
1509
+
1510
+ // src/UIConfigProvider/index.ts
1511
+ var init_UIConfigProvider2 = __esm({
1512
+ "src/UIConfigProvider/index.ts"() {
1513
+ init_UIConfigProvider();
1514
+ init_createUIConfig();
1515
+ init_configManager();
1516
+ }
1517
+ });
1518
+
1519
+ // src/utils/numberLocale.ts
1520
+ var localeConfigCache, getNumberLocaleConfig, formatNumber, formatNumberForEdit, parseLocalizedNumber;
1521
+ var init_numberLocale = __esm({
1522
+ "src/utils/numberLocale.ts"() {
1523
+ localeConfigCache = /* @__PURE__ */ new Map();
1524
+ getNumberLocaleConfig = (locale) => {
1525
+ const cached = localeConfigCache.get(locale);
1526
+ if (cached) {
1527
+ return cached;
1528
+ }
1529
+ try {
1530
+ const formatter = new Intl.NumberFormat(locale);
1531
+ const parts = formatter.formatToParts(1234.5);
1532
+ const decimal = parts.find((p) => p.type === "decimal")?.value ?? ".";
1533
+ const group = parts.find((p) => p.type === "group")?.value ?? ",";
1534
+ const config = {
1535
+ decimalSeparator: decimal,
1536
+ thousandsSeparator: group
1537
+ };
1538
+ localeConfigCache.set(locale, config);
1539
+ return config;
1540
+ } catch {
1541
+ const fallback = {
1542
+ decimalSeparator: ".",
1543
+ thousandsSeparator: ","
1544
+ };
1545
+ return fallback;
1546
+ }
1547
+ };
1548
+ formatNumber = (value, locale, precision) => {
1549
+ try {
1550
+ const options = {};
1551
+ if (precision !== void 0) {
1552
+ options.minimumFractionDigits = precision;
1553
+ options.maximumFractionDigits = precision;
1554
+ }
1555
+ return new Intl.NumberFormat(locale, options).format(value);
1556
+ } catch {
1557
+ if (precision !== void 0) {
1558
+ return value.toFixed(precision);
1559
+ }
1560
+ return String(value);
1561
+ }
1562
+ };
1563
+ formatNumberForEdit = (value, locale, precision) => {
1564
+ const config = getNumberLocaleConfig(locale);
1565
+ let str;
1566
+ if (precision !== void 0) {
1567
+ str = value.toFixed(precision);
1568
+ } else {
1569
+ str = String(value);
1570
+ }
1571
+ if (config.decimalSeparator !== ".") {
1572
+ str = str.replace(".", config.decimalSeparator);
1573
+ }
1574
+ return str;
1575
+ };
1576
+ parseLocalizedNumber = (value, locale) => {
1577
+ if (!value || value.trim() === "") {
1578
+ return null;
1579
+ }
1580
+ const config = getNumberLocaleConfig(locale);
1581
+ let normalized = value.trim();
1582
+ if (config.thousandsSeparator === "." && config.decimalSeparator === ",") {
1583
+ normalized = normalized.replace(/\./g, "");
1584
+ normalized = normalized.replace(",", ".");
1585
+ } else if (config.decimalSeparator === ",") {
1586
+ normalized = normalized.replace(/[\s\u00A0\u202F]/g, "");
1587
+ normalized = normalized.replace(",", ".");
1588
+ } else if (config.thousandsSeparator === "," && config.decimalSeparator === ".") {
1589
+ normalized = normalized.replace(/,/g, "");
1590
+ } else {
1591
+ if (config.thousandsSeparator) {
1592
+ const escapedThousands = config.thousandsSeparator.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1593
+ normalized = normalized.replace(new RegExp(escapedThousands, "g"), "");
1594
+ }
1595
+ if (config.decimalSeparator !== ".") {
1596
+ normalized = normalized.replace(config.decimalSeparator, ".");
1597
+ }
1598
+ }
1599
+ const parsed = parseFloat(normalized);
1600
+ return isNaN(parsed) ? null : parsed;
1601
+ };
1602
+ }
1603
+ });
1604
+ var getDecimalPlaces, precisionAdd, precisionSubtract, NumberInputContainer, InputWrapper, UnitText, StyledInput, ButtonGroup, StepButton, UpArrow, DownArrow, NumberInput;
1282
1605
  var init_NumberInput = __esm({
1283
1606
  "src/NumberInput/NumberInput.tsx"() {
1284
1607
  init_styled();
1608
+ init_UIConfigProvider2();
1609
+ init_numberLocale();
1610
+ getDecimalPlaces = (num) => {
1611
+ const str = String(num);
1612
+ const decimalIndex = str.indexOf(".");
1613
+ if (decimalIndex === -1) return 0;
1614
+ return str.length - decimalIndex - 1;
1615
+ };
1616
+ precisionAdd = (a, b) => {
1617
+ const precision = Math.max(getDecimalPlaces(a), getDecimalPlaces(b));
1618
+ const multiplier = Math.pow(10, precision);
1619
+ return Math.round(a * multiplier + b * multiplier) / multiplier;
1620
+ };
1621
+ precisionSubtract = (a, b) => {
1622
+ const precision = Math.max(getDecimalPlaces(a), getDecimalPlaces(b));
1623
+ const multiplier = Math.pow(10, precision);
1624
+ return Math.round(a * multiplier - b * multiplier) / multiplier;
1625
+ };
1285
1626
  NumberInputContainer = styled.div`
1286
1627
  display: inline-flex;
1287
1628
  align-items: center;
1288
1629
  background: white;
1289
- border: 1px solid;
1290
1630
  border-radius: ${({ theme: theme2, $size }) => theme2.components.inputNumber[$size].borderRadius};
1291
1631
  flex-shrink: 0;
1292
1632
 
@@ -1298,26 +1638,47 @@ var init_NumberInput = __esm({
1298
1638
  width: 80px;
1299
1639
  `}
1300
1640
 
1301
- ${({ $disabled, $alert, $isFocused, theme: theme2 }) => {
1641
+ ${({ $disabled, $alert, $isFocused, $lineType, theme: theme2 }) => {
1642
+ if ($lineType === "borderless") {
1643
+ return `
1644
+ border: none;
1645
+ background: transparent;
1646
+ ${$disabled ? "cursor: not-allowed;" : ""}
1647
+ `;
1648
+ }
1649
+ if ($lineType === "underlined") {
1650
+ const borderColor = $disabled ? theme2.colors.palettes.transparency["10"] : $alert ? theme2.colors.palettes.red["6"] : $isFocused ? theme2.colors.palettes.transparency["30"] : "transparent";
1651
+ return `
1652
+ border: none;
1653
+ border-bottom: 1px solid ${borderColor};
1654
+ border-radius: 0;
1655
+ ${$disabled ? "cursor: not-allowed;" : ""}
1656
+ ${!$disabled && !$isFocused && !$alert ? `
1657
+ &:hover {
1658
+ border-bottom-color: ${theme2.colors.palettes.transparency["20"]};
1659
+ }
1660
+ ` : ""}
1661
+ `;
1662
+ }
1302
1663
  if ($disabled) {
1303
1664
  return `
1304
- border-color: ${theme2.colors.palettes.transparency["10"]};
1665
+ border: 1px solid ${theme2.colors.palettes.transparency["10"]};
1305
1666
  cursor: not-allowed;
1306
1667
  `;
1307
1668
  }
1308
1669
  if ($alert) {
1309
1670
  return `
1310
- border-color: ${theme2.colors.palettes.red["6"]};
1671
+ border: 1px solid ${theme2.colors.palettes.red["6"]};
1311
1672
  `;
1312
1673
  }
1313
1674
  if ($isFocused) {
1314
1675
  return `
1315
- border-color: ${theme2.colors.palettes.transparency["30"]};
1676
+ border: 1px solid ${theme2.colors.palettes.transparency["30"]};
1316
1677
  box-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.04);
1317
1678
  `;
1318
1679
  }
1319
1680
  return `
1320
- border-color: ${theme2.colors.palettes.transparency["10"]};
1681
+ border: 1px solid ${theme2.colors.palettes.transparency["10"]};
1321
1682
 
1322
1683
  &:hover {
1323
1684
  border-color: ${theme2.colors.palettes.transparency["20"]};
@@ -1396,18 +1757,40 @@ var init_NumberInput = __esm({
1396
1757
  display: flex;
1397
1758
  flex-direction: column;
1398
1759
  height: 100%;
1399
- border-left: 1px solid;
1400
1760
  flex-shrink: 0;
1761
+ position: relative;
1762
+
1763
+ ${({ $disabled, $alert, $lineType, theme: theme2 }) => {
1764
+ if ($lineType === "borderless" || $lineType === "underlined") {
1765
+ return "";
1766
+ }
1767
+ const borderColor = $disabled ? theme2.colors.palettes.transparency["10"] : $alert ? theme2.colors.palettes.red["6"] : theme2.colors.palettes.transparency["10"];
1768
+ return `border-left: 1px solid ${borderColor};`;
1769
+ }}
1401
1770
 
1402
- ${({ $disabled, $alert, theme: theme2 }) => {
1771
+ /* Centered divider line between buttons */
1772
+ &::after {
1773
+ content: '';
1774
+ position: absolute;
1775
+ left: 0;
1776
+ right: 0;
1777
+ top: 50%;
1778
+ transform: translateY(-50%);
1779
+ height: 1px;
1780
+ pointer-events: none;
1781
+ background-color: ${({ $disabled, $alert, $lineType, theme: theme2 }) => {
1782
+ if ($lineType === "borderless" || $lineType === "underlined") {
1783
+ return "transparent";
1784
+ }
1403
1785
  if ($disabled) {
1404
- return `border-color: ${theme2.colors.palettes.transparency["10"]};`;
1786
+ return theme2.colors.palettes.transparency["10"];
1405
1787
  }
1406
1788
  if ($alert) {
1407
- return `border-color: ${theme2.colors.palettes.red["6"]};`;
1789
+ return theme2.colors.palettes.red["6"];
1408
1790
  }
1409
- return `border-color: ${theme2.colors.palettes.transparency["10"]};`;
1410
- }}
1791
+ return theme2.colors.palettes.transparency["10"];
1792
+ }};
1793
+ }
1411
1794
  `;
1412
1795
  StepButton = styled.button`
1413
1796
  flex: 1 1 50%;
@@ -1422,15 +1805,6 @@ var init_NumberInput = __esm({
1422
1805
  min-height: 0;
1423
1806
  overflow: hidden;
1424
1807
 
1425
- ${({ $position, $alert, $disabled, theme: theme2 }) => {
1426
- if ($position === "up") {
1427
- return `
1428
- border-bottom: 1px solid ${$disabled ? theme2.colors.palettes.transparency["10"] : $alert ? theme2.colors.palettes.red["6"] : theme2.colors.palettes.transparency["10"]};
1429
- `;
1430
- }
1431
- return "";
1432
- }}
1433
-
1434
1808
  ${({ $disabled, theme: theme2 }) => {
1435
1809
  if ($disabled) {
1436
1810
  return `
@@ -1471,13 +1845,20 @@ var init_NumberInput = __esm({
1471
1845
  parser,
1472
1846
  unit,
1473
1847
  placeholder,
1848
+ showStepButtons = true,
1849
+ showStepButtonsTrigger = "normal",
1850
+ lineType = "outlined",
1851
+ useThousandsSeparator = false,
1474
1852
  onChange,
1475
1853
  className,
1476
1854
  style
1477
1855
  }) => {
1856
+ const config = useUIConfig();
1857
+ const locale = config?.locale ?? "en-US";
1478
1858
  const [internalValue, setInternalValue] = useState(controlledValue ?? defaultValue);
1479
1859
  const [displayValue, setDisplayValue] = useState("");
1480
1860
  const [isFocused, setIsFocused] = useState(false);
1861
+ const [isHovered, setIsHovered] = useState(false);
1481
1862
  const inputRef = useRef(null);
1482
1863
  const value = controlledValue !== void 0 ? controlledValue : internalValue;
1483
1864
  const formatValue = useCallback(
@@ -1488,28 +1869,49 @@ var init_NumberInput = __esm({
1488
1869
  if (formatter) {
1489
1870
  return formatter(val);
1490
1871
  }
1491
- if (precision !== void 0) {
1492
- return val.toFixed(precision);
1872
+ if (useThousandsSeparator) {
1873
+ return formatNumber(val, locale, precision);
1874
+ }
1875
+ return formatNumberForEdit(val, locale, precision);
1876
+ },
1877
+ [formatter, precision, locale, useThousandsSeparator]
1878
+ );
1879
+ const formatValueForEdit = useCallback(
1880
+ (val) => {
1881
+ if (val === void 0) {
1882
+ return "";
1883
+ }
1884
+ if (formatter) {
1885
+ return formatter(val);
1493
1886
  }
1494
- return String(val);
1887
+ return formatNumberForEdit(val, locale, precision);
1495
1888
  },
1496
- [formatter, precision]
1889
+ [formatter, precision, locale]
1497
1890
  );
1498
1891
  const parseValue = useCallback(
1499
1892
  (displayVal) => {
1500
1893
  if (parser) {
1501
1894
  return parser(displayVal);
1502
1895
  }
1503
- const parsed = parseFloat(displayVal);
1504
- return isNaN(parsed) ? null : parsed;
1896
+ return parseLocalizedNumber(displayVal, locale);
1505
1897
  },
1506
- [parser]
1898
+ [parser, locale]
1507
1899
  );
1508
1900
  useEffect(() => {
1509
1901
  if (!isFocused) {
1510
1902
  setDisplayValue(formatValue(value));
1511
1903
  }
1512
1904
  }, [value, isFocused, formatValue]);
1905
+ const applyPrecision = useCallback(
1906
+ (val) => {
1907
+ if (val === void 0 || precision === void 0) {
1908
+ return val;
1909
+ }
1910
+ const multiplier = Math.pow(10, precision);
1911
+ return Math.round(val * multiplier) / multiplier;
1912
+ },
1913
+ [precision]
1914
+ );
1513
1915
  const clampValue = useCallback(
1514
1916
  (val) => {
1515
1917
  if (val === void 0) {
@@ -1532,13 +1934,23 @@ var init_NumberInput = __esm({
1532
1934
  const increment = useCallback(() => {
1533
1935
  if (disabled) return;
1534
1936
  const currentValue = value ?? 0;
1535
- handleValueChange(currentValue + step);
1536
- }, [disabled, value, step, handleValueChange]);
1937
+ const newValue = precisionAdd(currentValue, step);
1938
+ handleValueChange(newValue);
1939
+ if (isFocused) {
1940
+ const clampedValue = clampValue(newValue);
1941
+ setDisplayValue(formatValueForEdit(clampedValue));
1942
+ }
1943
+ }, [disabled, value, step, handleValueChange, isFocused, clampValue, formatValueForEdit]);
1537
1944
  const decrement = useCallback(() => {
1538
1945
  if (disabled) return;
1539
1946
  const currentValue = value ?? 0;
1540
- handleValueChange(currentValue - step);
1541
- }, [disabled, value, step, handleValueChange]);
1947
+ const newValue = precisionSubtract(currentValue, step);
1948
+ handleValueChange(newValue);
1949
+ if (isFocused) {
1950
+ const clampedValue = clampValue(newValue);
1951
+ setDisplayValue(formatValueForEdit(clampedValue));
1952
+ }
1953
+ }, [disabled, value, step, handleValueChange, isFocused, clampValue, formatValueForEdit]);
1542
1954
  const handleInputChange = useCallback((e) => {
1543
1955
  setDisplayValue(e.target.value);
1544
1956
  }, []);
@@ -1551,20 +1963,17 @@ var init_NumberInput = __esm({
1551
1963
  } else {
1552
1964
  const parsed = parseValue(trimmedValue);
1553
1965
  if (parsed !== null) {
1554
- handleValueChange(parsed);
1966
+ const preciseValue = applyPrecision(parsed);
1967
+ handleValueChange(preciseValue);
1555
1968
  } else {
1556
1969
  setDisplayValue(formatValue(value));
1557
1970
  }
1558
1971
  }
1559
- }, [displayValue, parseValue, handleValueChange, value, formatValue]);
1972
+ }, [displayValue, parseValue, handleValueChange, value, formatValue, applyPrecision]);
1560
1973
  const handleFocus = useCallback(() => {
1561
1974
  setIsFocused(true);
1562
- if (value !== void 0) {
1563
- setDisplayValue(String(value));
1564
- } else {
1565
- setDisplayValue("");
1566
- }
1567
- }, [value]);
1975
+ setDisplayValue(formatValueForEdit(value));
1976
+ }, [value, formatValueForEdit]);
1568
1977
  const handleKeyDown = useCallback(
1569
1978
  (e) => {
1570
1979
  if (e.key === "ArrowUp") {
@@ -1579,6 +1988,12 @@ var init_NumberInput = __esm({
1579
1988
  },
1580
1989
  [increment, decrement]
1581
1990
  );
1991
+ const handleMouseEnter = useCallback(() => {
1992
+ setIsHovered(true);
1993
+ }, []);
1994
+ const handleMouseLeave = useCallback(() => {
1995
+ setIsHovered(false);
1996
+ }, []);
1582
1997
  return /* @__PURE__ */ React3.createElement(
1583
1998
  NumberInputContainer,
1584
1999
  {
@@ -1586,8 +2001,11 @@ var init_NumberInput = __esm({
1586
2001
  $disabled: disabled,
1587
2002
  $alert: alert,
1588
2003
  $isFocused: isFocused,
2004
+ $lineType: lineType,
1589
2005
  className,
1590
- style
2006
+ style,
2007
+ onMouseEnter: handleMouseEnter,
2008
+ onMouseLeave: handleMouseLeave
1591
2009
  },
1592
2010
  /* @__PURE__ */ React3.createElement(InputWrapper, null, /* @__PURE__ */ React3.createElement(
1593
2011
  StyledInput,
@@ -1605,12 +2023,10 @@ var init_NumberInput = __esm({
1605
2023
  $disabled: disabled
1606
2024
  }
1607
2025
  ), unit && /* @__PURE__ */ React3.createElement(UnitText, { $size: size, $disabled: disabled }, unit)),
1608
- /* @__PURE__ */ React3.createElement(ButtonGroup, { $alert: alert, $disabled: disabled }, /* @__PURE__ */ React3.createElement(
2026
+ showStepButtons && (showStepButtonsTrigger !== "hover" || isHovered || isFocused) && /* @__PURE__ */ React3.createElement(ButtonGroup, { $alert: alert, $disabled: disabled, $lineType: lineType }, /* @__PURE__ */ React3.createElement(
1609
2027
  StepButton,
1610
2028
  {
1611
2029
  type: "button",
1612
- $position: "up",
1613
- $alert: alert,
1614
2030
  $disabled: disabled,
1615
2031
  onClick: increment,
1616
2032
  disabled,
@@ -1621,8 +2037,6 @@ var init_NumberInput = __esm({
1621
2037
  StepButton,
1622
2038
  {
1623
2039
  type: "button",
1624
- $position: "down",
1625
- $alert: alert,
1626
2040
  $disabled: disabled,
1627
2041
  onClick: decrement,
1628
2042
  disabled,
@@ -2712,124 +3126,7 @@ init_Icon2();
2712
3126
 
2713
3127
  // src/Toast/index.ts
2714
3128
  init_Toast();
2715
-
2716
- // src/Toast/ToastContainer.tsx
2717
- init_styled();
2718
- init_Toast();
2719
- var ToastContext = createContext(null);
2720
- var ToastWrapper2 = styled.div`
2721
- position: fixed;
2722
- z-index: 9999;
2723
- display: flex;
2724
- flex-direction: column;
2725
- gap: 12px;
2726
- pointer-events: none;
2727
-
2728
- > * {
2729
- pointer-events: auto;
2730
- }
2731
-
2732
- ${({ $placement, theme: theme2 }) => {
2733
- const offset = theme2.components?.toast?.offset || { vertical: "24px", horizontal: "24px" };
2734
- const vertical = offset.vertical || "24px";
2735
- const horizontal = offset.horizontal || "24px";
2736
- const styles = {
2737
- "top-right": `
2738
- top: ${vertical};
2739
- right: ${horizontal};
2740
- `,
2741
- "top-left": `
2742
- top: ${vertical};
2743
- left: ${horizontal};
2744
- `,
2745
- "top-center": `
2746
- top: ${vertical};
2747
- left: 50%;
2748
- transform: translateX(-50%);
2749
- `,
2750
- "bottom-right": `
2751
- bottom: ${vertical};
2752
- right: ${horizontal};
2753
- `,
2754
- "bottom-left": `
2755
- bottom: ${vertical};
2756
- left: ${horizontal};
2757
- `,
2758
- "bottom-center": `
2759
- bottom: ${vertical};
2760
- left: 50%;
2761
- transform: translateX(-50%);
2762
- `
2763
- };
2764
- return styles[$placement] || styles["top-right"];
2765
- }}
2766
- `;
2767
- var ToastContainer2 = ({
2768
- placement = "top-right",
2769
- maxCount = 5,
2770
- defaultDuration = 3e3,
2771
- children
2772
- }) => {
2773
- const [toasts, setToasts] = useState([]);
2774
- const showToast = useCallback((props) => {
2775
- const id = `toast-${Date.now()}-${Math.random()}`;
2776
- const newToast = {
2777
- ...props,
2778
- id,
2779
- duration: props.duration ?? defaultDuration
2780
- };
2781
- setToasts((prev) => {
2782
- const updated = [...prev, newToast];
2783
- return updated.slice(-maxCount);
2784
- });
2785
- return id;
2786
- }, [maxCount, defaultDuration]);
2787
- const hideToast = useCallback((id) => {
2788
- setToasts((prev) => prev.filter((toast2) => toast2.id !== id));
2789
- }, []);
2790
- const success = useCallback((message, options) => {
2791
- return showToast({ ...options, variant: "success", message });
2792
- }, [showToast]);
2793
- const info = useCallback((message, options) => {
2794
- return showToast({ ...options, variant: "info", message });
2795
- }, [showToast]);
2796
- const error = useCallback((message, options) => {
2797
- return showToast({ ...options, variant: "error", message });
2798
- }, [showToast]);
2799
- const warn = useCallback((message, options) => {
2800
- return showToast({ ...options, variant: "warn", message });
2801
- }, [showToast]);
2802
- const loading = useCallback((message, options) => {
2803
- return showToast({ ...options, variant: "loading", message });
2804
- }, [showToast]);
2805
- const contextValue = {
2806
- showToast,
2807
- hideToast,
2808
- success,
2809
- info,
2810
- error,
2811
- warn,
2812
- loading
2813
- };
2814
- return /* @__PURE__ */ React3.createElement(ToastContext.Provider, { value: contextValue }, children, /* @__PURE__ */ React3.createElement(ToastWrapper2, { $placement: placement }, toasts.map((toast2) => /* @__PURE__ */ React3.createElement(
2815
- Toast,
2816
- {
2817
- key: toast2.id,
2818
- ...toast2,
2819
- onClose: () => hideToast(toast2.id)
2820
- }
2821
- ))));
2822
- };
2823
- var useToast = () => {
2824
- const context = useContext(ToastContext);
2825
- if (!context) {
2826
- throw new Error("useToast must be used within ToastContainer");
2827
- }
2828
- return context;
2829
- };
2830
- ToastContainer2.displayName = "ToastContainer";
2831
-
2832
- // src/Toast/index.ts
3129
+ init_ToastContainer();
2833
3130
  init_toastManager();
2834
3131
 
2835
3132
  // src/Tabs/Tabs.tsx
@@ -2856,10 +3153,12 @@ var TabList = styled.div`
2856
3153
  height: 100%;
2857
3154
 
2858
3155
 
2859
- ${({ $variant, theme: theme2 }) => {
3156
+ ${({ $variant, $justify, theme: theme2 }) => {
2860
3157
  const variantConfig = theme2.components.tab[$variant];
3158
+ const justifyContent = $variant === "line" ? $justify === "center" ? "center" : $justify === "end" ? "flex-end" : "flex-start" : "flex-start";
2861
3159
  return `
2862
3160
  gap: ${variantConfig.layout.gap};
3161
+ justify-content: ${justifyContent};
2863
3162
  `;
2864
3163
  }}
2865
3164
 
@@ -2990,6 +3289,7 @@ var Tabs = ({
2990
3289
  variant = "line",
2991
3290
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2992
3291
  size: _size = "large",
3292
+ justify = "start",
2993
3293
  onChange,
2994
3294
  className,
2995
3295
  style,
@@ -3010,7 +3310,7 @@ var Tabs = ({
3010
3310
  },
3011
3311
  [controlledActiveKey, onChange]
3012
3312
  );
3013
- return /* @__PURE__ */ React3.createElement(TabContainer, { $variant: variant, className, style }, /* @__PURE__ */ React3.createElement(TabList, { $variant: variant, role: "tablist" }, items.map((item) => /* @__PURE__ */ React3.createElement(
3313
+ return /* @__PURE__ */ React3.createElement(TabContainer, { $variant: variant, className, style }, /* @__PURE__ */ React3.createElement(TabList, { $variant: variant, $justify: justify, role: "tablist" }, items.map((item) => /* @__PURE__ */ React3.createElement(
3014
3314
  TabItem,
3015
3315
  {
3016
3316
  key: item.key,
@@ -3225,6 +3525,8 @@ var TooltipGlobalStyles = createGlobalStyle$1`
3225
3525
  line-height: ${() => getGlobalTheme().components.tooltip.black.lineHeight};
3226
3526
  font-weight: ${() => getGlobalTheme().components.tooltip.black.fontWeight};
3227
3527
  max-width: ${() => getGlobalTheme().components.tooltip.black.maxWidth};
3528
+ white-space: normal;
3529
+ word-wrap: break-word;
3228
3530
  text-align: left;
3229
3531
  text-decoration: none;
3230
3532
  }
@@ -3244,6 +3546,9 @@ var TooltipGlobalStyles = createGlobalStyle$1`
3244
3546
  font-size: ${() => getGlobalTheme().components.tooltip.white.small.fontSize};
3245
3547
  line-height: ${() => getGlobalTheme().components.tooltip.white.small.lineHeight};
3246
3548
  font-weight: ${() => getGlobalTheme().components.tooltip.white.small.fontWeight};
3549
+ max-width: ${() => getGlobalTheme().components.tooltip.white.small.maxWidth};
3550
+ white-space: normal;
3551
+ word-wrap: break-word;
3247
3552
  text-align: left;
3248
3553
  text-decoration: none;
3249
3554
  }
@@ -3263,6 +3568,9 @@ var TooltipGlobalStyles = createGlobalStyle$1`
3263
3568
  font-size: ${() => getGlobalTheme().components.tooltip.white.large.fontSize};
3264
3569
  line-height: ${() => getGlobalTheme().components.tooltip.white.large.lineHeight};
3265
3570
  font-weight: ${() => getGlobalTheme().components.tooltip.white.large.fontWeight};
3571
+ max-width: ${() => getGlobalTheme().components.tooltip.white.large.maxWidth};
3572
+ white-space: normal;
3573
+ word-wrap: break-word;
3266
3574
  text-align: left;
3267
3575
  text-decoration: none;
3268
3576
  }
@@ -3654,7 +3962,7 @@ var ToolbarButton = ({
3654
3962
  },
3655
3963
  renderIcon(),
3656
3964
  renderLabel(),
3657
- /* @__PURE__ */ React3.createElement(DropdownArrow, { $disabled: disabled }, /* @__PURE__ */ React3.createElement(ChevronDownIcon, null))
3965
+ /* @__PURE__ */ React3.createElement(DropdownArrow, { $disabled: disabled }, /* @__PURE__ */ React3.createElement(ArrowDownIcon, null))
3658
3966
  )
3659
3967
  );
3660
3968
  }
@@ -3690,7 +3998,7 @@ var ToolbarButton = ({
3690
3998
  onClick: handleDropdownClick,
3691
3999
  disabled
3692
4000
  },
3693
- /* @__PURE__ */ React3.createElement(DropdownArrow, { $disabled: disabled }, /* @__PURE__ */ React3.createElement(ChevronDownIcon, null))
4001
+ /* @__PURE__ */ React3.createElement(DropdownArrow, { $disabled: disabled }, /* @__PURE__ */ React3.createElement(ArrowDownIcon, null))
3694
4002
  )
3695
4003
  );
3696
4004
  }
@@ -3883,6 +4191,7 @@ var DropdownButton2 = forwardRef(
3883
4191
  style,
3884
4192
  textStyle,
3885
4193
  onClick,
4194
+ children,
3886
4195
  ...rest
3887
4196
  }, ref) => {
3888
4197
  const effectiveSize = size || (variant === "framed" ? "large" : "medium");
@@ -3912,7 +4221,7 @@ var DropdownButton2 = forwardRef(
3912
4221
  ...rest
3913
4222
  },
3914
4223
  iconElement && /* @__PURE__ */ React3.createElement(IconWrapper5, { $size: effectiveSize }, iconElement),
3915
- /* @__PURE__ */ React3.createElement(TextContent, { $disabled: disabled, $hasValue: hasValue, style: textStyle }, value || placeholder),
4224
+ children ? children : /* @__PURE__ */ React3.createElement(TextContent, { $disabled: disabled, $hasValue: hasValue, style: textStyle }, value || placeholder),
3916
4225
  /* @__PURE__ */ React3.createElement(IndicatorWrapper, { $size: effectiveSize, $open: open, $disabled: disabled }, indicatorIcon || /* @__PURE__ */ React3.createElement(ArrowRightIcon, null))
3917
4226
  );
3918
4227
  }
@@ -4959,110 +5268,8 @@ var Loading = ({
4959
5268
  };
4960
5269
  Loading.displayName = "Loading";
4961
5270
 
4962
- // src/UIConfigProvider/UIConfigProvider.tsx
4963
- init_IconProvider();
4964
- init_configManager();
4965
- init_context();
4966
- var UIConfigContext = createContext(null);
4967
- var UIConfigProvider = ({ config, children }) => {
4968
- useEffect(() => {
4969
- registerGlobalContext({
4970
- theme: config.theme,
4971
- render: config.renderFunction
4972
- });
4973
- initUIConfig(config);
4974
- }, [config]);
4975
- const { icons = {} } = config;
4976
- const toastConfig = {
4977
- maxCount: config.toast?.maxCount ?? 5,
4978
- defaultDuration: config.toast?.defaultDuration ?? 3e3
4979
- };
4980
- return /* @__PURE__ */ React3.createElement(UIConfigContext.Provider, { value: config }, /* @__PURE__ */ React3.createElement(IconProvider, { icons }, /* @__PURE__ */ React3.createElement(
4981
- ToastContainer2,
4982
- {
4983
- maxCount: toastConfig.maxCount,
4984
- defaultDuration: toastConfig.defaultDuration
4985
- },
4986
- children
4987
- )));
4988
- };
4989
- var useUIConfig = () => {
4990
- const context = useContext(UIConfigContext);
4991
- return context || getUIConfig();
4992
- };
4993
- UIConfigProvider.displayName = "UIConfigProvider";
4994
-
4995
- // src/UIConfigProvider/createUIConfig.ts
4996
- var createUIConfig = (config) => {
4997
- return {
4998
- // Theme is required
4999
- theme: config.theme,
5000
- // Icons with default
5001
- icons: config.icons ?? {},
5002
- // Toast with defaults
5003
- toast: {
5004
- maxCount: config.toast?.maxCount ?? 5,
5005
- defaultDuration: config.toast?.defaultDuration ?? 3e3,
5006
- position: config.toast?.position ?? "top-right",
5007
- offset: {
5008
- x: config.toast?.offset?.x ?? 24,
5009
- y: config.toast?.offset?.y ?? 24
5010
- }
5011
- },
5012
- // Locale with default
5013
- locale: config.locale ?? "en-US",
5014
- // I18n with defaults
5015
- i18n: {
5016
- toast: {
5017
- closeLabel: config.i18n?.toast?.closeLabel ?? "Close"
5018
- },
5019
- button: {
5020
- loadingText: config.i18n?.button?.loadingText ?? "Loading..."
5021
- },
5022
- common: {
5023
- confirm: config.i18n?.common?.confirm ?? "Confirm",
5024
- cancel: config.i18n?.common?.cancel ?? "Cancel",
5025
- ok: config.i18n?.common?.ok ?? "OK"
5026
- }
5027
- },
5028
- // Z-index with defaults
5029
- zIndex: {
5030
- toast: config.zIndex?.toast ?? 9999,
5031
- modal: config.zIndex?.modal ?? 1e4,
5032
- dropdown: config.zIndex?.dropdown ?? 1e3,
5033
- tooltip: config.zIndex?.tooltip ?? 1001
5034
- },
5035
- // Animation with defaults
5036
- animation: {
5037
- duration: config.animation?.duration ?? 200,
5038
- easing: config.animation?.easing ?? "cubic-bezier(0.4, 0, 0.2, 1)",
5039
- disabled: config.animation?.disabled ?? false
5040
- },
5041
- // A11y with defaults
5042
- a11y: {
5043
- announceMessages: config.a11y?.announceMessages ?? true,
5044
- focusVisible: config.a11y?.focusVisible ?? true,
5045
- reduceMotion: config.a11y?.reduceMotion ?? false
5046
- }
5047
- };
5048
- };
5049
- var mergeUIConfig = (baseConfig, ...configs) => {
5050
- const merged = configs.reduce((acc, config) => ({
5051
- ...acc,
5052
- ...config,
5053
- toast: { ...acc.toast, ...config.toast },
5054
- i18n: { ...acc.i18n, ...config.i18n },
5055
- zIndex: { ...acc.zIndex, ...config.zIndex },
5056
- animation: { ...acc.animation, ...config.animation },
5057
- a11y: { ...acc.a11y, ...config.a11y }
5058
- }), baseConfig);
5059
- return merged;
5060
- };
5061
-
5062
- // src/UIConfigProvider/index.ts
5063
- init_configManager();
5064
-
5065
5271
  // src/index.ts
5272
+ init_UIConfigProvider2();
5066
5273
  init_styled();
5067
5274
  init_context();
5068
5275