@metropolle/design-system 1.0.0-beta.20250821022912.15e7eda → 1.0.0-beta.2026.1.1.1723.0f6bc6d

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.
Files changed (57) hide show
  1. package/README.md +1 -0
  2. package/dist/css/compat/back.css +466 -0
  3. package/dist/css/components.css +1476 -8
  4. package/dist/css/liquid-glass.css +468 -0
  5. package/dist/css/mermaid.css +163 -0
  6. package/dist/css/tokens.css +67 -0
  7. package/dist/react/components/react/DataTable/DataTable.d.ts +4 -0
  8. package/dist/react/components/react/DataTable/DataTable.d.ts.map +1 -0
  9. package/dist/react/components/react/DataTable/TableHeader.d.ts +4 -0
  10. package/dist/react/components/react/DataTable/TableHeader.d.ts.map +1 -0
  11. package/dist/react/components/react/DataTable/TableRow.d.ts +4 -0
  12. package/dist/react/components/react/DataTable/TableRow.d.ts.map +1 -0
  13. package/dist/react/components/react/DataTable/examples.d.ts +28 -0
  14. package/dist/react/components/react/DataTable/examples.d.ts.map +1 -0
  15. package/dist/react/components/react/DataTable/index.d.ts +7 -0
  16. package/dist/react/components/react/DataTable/index.d.ts.map +1 -0
  17. package/dist/react/components/react/DataTable/migration-example.d.ts +46 -0
  18. package/dist/react/components/react/DataTable/migration-example.d.ts.map +1 -0
  19. package/dist/react/components/react/DataTable/renderers.d.ts +24 -0
  20. package/dist/react/components/react/DataTable/renderers.d.ts.map +1 -0
  21. package/dist/react/components/react/DataTable/types.d.ts +57 -0
  22. package/dist/react/components/react/DataTable/types.d.ts.map +1 -0
  23. package/dist/react/components/react/GlassCard/GlassCard.d.ts +46 -6
  24. package/dist/react/components/react/GlassCard/GlassCard.d.ts.map +1 -1
  25. package/dist/react/components/react/Modal/ConfirmDialog.d.ts +17 -0
  26. package/dist/react/components/react/Modal/ConfirmDialog.d.ts.map +1 -0
  27. package/dist/react/components/react/Modal/Modal.d.ts +12 -0
  28. package/dist/react/components/react/Modal/Modal.d.ts.map +1 -0
  29. package/dist/react/components/react/Modal/ModalBody.d.ts +9 -0
  30. package/dist/react/components/react/Modal/ModalBody.d.ts.map +1 -0
  31. package/dist/react/components/react/Modal/ModalFooter.d.ts +8 -0
  32. package/dist/react/components/react/Modal/ModalFooter.d.ts.map +1 -0
  33. package/dist/react/components/react/Modal/ModalHeader.d.ts +11 -0
  34. package/dist/react/components/react/Modal/ModalHeader.d.ts.map +1 -0
  35. package/dist/react/components/react/Modal/index.d.ts +6 -0
  36. package/dist/react/components/react/Modal/index.d.ts.map +1 -0
  37. package/dist/react/components/react/Select/Select.d.ts +71 -0
  38. package/dist/react/components/react/Select/Select.d.ts.map +1 -0
  39. package/dist/react/components/react/Select/index.d.ts +2 -0
  40. package/dist/react/components/react/Select/index.d.ts.map +1 -0
  41. package/dist/react/components/react/ThemeToggle/ThemeToggle.d.ts +28 -0
  42. package/dist/react/components/react/ThemeToggle/ThemeToggle.d.ts.map +1 -0
  43. package/dist/react/components/react/ThemeToggle/index.d.ts +3 -0
  44. package/dist/react/components/react/ThemeToggle/index.d.ts.map +1 -0
  45. package/dist/react/components/react/Typography/Typography.d.ts.map +1 -1
  46. package/dist/react/components/react/index.d.ts +11 -0
  47. package/dist/react/components/react/index.d.ts.map +1 -1
  48. package/dist/react/index.d.ts +11 -0
  49. package/dist/react/index.esm.js +1147 -14
  50. package/dist/react/index.esm.js.map +1 -1
  51. package/dist/react/index.js +1164 -12
  52. package/dist/react/index.js.map +1 -1
  53. package/dist/tokens/colors.json +100 -18
  54. package/dist/tokens/index.d.ts +19 -24
  55. package/dist/tokens/index.js +69 -2
  56. package/dist/tokens/index.json +100 -18
  57. package/package.json +23 -13
@@ -1,4 +1,5 @@
1
- import require$$0, { forwardRef } from 'react';
1
+ import require$$0, { forwardRef, useState, useRef, useEffect, useMemo, useCallback } from 'react';
2
+ import { createPortal } from 'react-dom';
2
3
 
3
4
  var jsxRuntime = {exports: {}};
4
5
 
@@ -1369,12 +1370,35 @@ function cn(...classes) {
1369
1370
  /**
1370
1371
  * Glass Card Component
1371
1372
  *
1372
- * Componente de cartão com efeito glassmorphism baseado na identidade Metropolle.
1373
- * Migrado dos componentes Angular existentes com melhorias.
1373
+ * Componente de cartão com efeito glassmorphism ou Liquid Glass (iOS 26 style).
1374
+ *
1375
+ * @example
1376
+ * ```tsx
1377
+ * // Liquid Glass (novo padrão)
1378
+ * <GlassCard glassStyle="liquid" intensity="md">
1379
+ * Content here
1380
+ * </GlassCard>
1381
+ *
1382
+ * // Glassmorphism tradicional (retrocompatível)
1383
+ * <GlassCard glassStyle="glass" variant="dark">
1384
+ * Content here
1385
+ * </GlassCard>
1386
+ * ```
1374
1387
  */
1375
- const GlassCard = forwardRef(({ variant = 'light', blur = 20, opacity, children, className, enableHover = true, style, ...props }, ref) => {
1388
+ const GlassCard = forwardRef(({ glassStyle = 'liquid', intensity = 'md', theme, variant = 'light', blur, opacity, children, className, enableHover = true, style, ...props }, ref) => {
1389
+ // Resolve theme from new prop or deprecated variant
1390
+ const resolvedTheme = theme ?? variant;
1391
+ // =====================
1392
+ // LIQUID GLASS MODE
1393
+ // =====================
1394
+ if (glassStyle === 'liquid') {
1395
+ return (jsxRuntimeExports.jsx("div", { ref: ref, className: cn('mds-liquid-glass', `mds-liquid-glass--${intensity}`, !enableHover && 'mds-liquid-glass--no-hover', className), style: style, ...props, children: children }));
1396
+ }
1397
+ // =====================
1398
+ // GLASS MODE (legacy)
1399
+ // =====================
1376
1400
  // Default opacities baseadas no design existente
1377
- const defaultOpacity = variant === 'light' ? 0.15 : 0.8;
1401
+ const defaultOpacity = resolvedTheme === 'light' ? 0.15 : 0.8;
1378
1402
  const finalOpacity = opacity ?? defaultOpacity;
1379
1403
  // Use CSS classes for base styles to avoid hydration mismatches
1380
1404
  const baseStyles = {
@@ -1382,12 +1406,16 @@ const GlassCard = forwardRef(({ variant = 'light', blur = 20, opacity, children,
1382
1406
  };
1383
1407
  // Only apply custom styles for non-default values
1384
1408
  const customStyles = {};
1385
- if (blur !== 20) {
1386
- customStyles.backdropFilter = `blur(${blur}px)`;
1387
- customStyles.WebkitBackdropFilter = `blur(${blur}px)`;
1409
+ // Support legacy blur prop or convert from intensity
1410
+ const resolvedBlur = blur ?? (intensity ? {
1411
+ xs: 2, sm: 4, md: 6, lg: 8, xl: 12
1412
+ }[intensity] : 20);
1413
+ if (resolvedBlur !== 20) {
1414
+ customStyles.backdropFilter = `blur(${resolvedBlur}px)`;
1415
+ customStyles.WebkitBackdropFilter = `blur(${resolvedBlur}px)`;
1388
1416
  }
1389
1417
  if (opacity !== undefined) {
1390
- customStyles.background = variant === 'light'
1418
+ customStyles.background = resolvedTheme === 'light'
1391
1419
  ? `rgba(255, 255, 255, ${finalOpacity})`
1392
1420
  : `rgba(60, 60, 60, ${finalOpacity})`;
1393
1421
  }
@@ -1402,7 +1430,7 @@ const GlassCard = forwardRef(({ variant = 'light', blur = 20, opacity, children,
1402
1430
  borderColor: 'rgba(255, 255, 255, 0.2)',
1403
1431
  background: opacity !== undefined ? `rgba(70, 70, 70, ${finalOpacity})` : undefined,
1404
1432
  }
1405
- }[variant] : {};
1433
+ }[resolvedTheme] : {};
1406
1434
  const handleMouseEnter = (e) => {
1407
1435
  if (!enableHover)
1408
1436
  return;
@@ -1420,7 +1448,7 @@ const GlassCard = forwardRef(({ variant = 'light', blur = 20, opacity, children,
1420
1448
  });
1421
1449
  props.onMouseLeave?.(e);
1422
1450
  };
1423
- return (jsxRuntimeExports.jsx("div", { ref: ref, className: cn('mds-glass-card', `mds-glass-card--${variant}`, !enableHover && 'mds-glass-card--no-hover', className), style: {
1451
+ return (jsxRuntimeExports.jsx("div", { ref: ref, className: cn('mds-glass-card', `mds-glass-card--${resolvedTheme}`, !enableHover && 'mds-glass-card--no-hover', className), style: {
1424
1452
  ...baseStyles,
1425
1453
  ...customStyles,
1426
1454
  ...style
@@ -1458,13 +1486,14 @@ const Typography = forwardRef(({ variant = 'body', size, as, children, className
1458
1486
  return (jsxRuntimeExports.jsx(Component, { ref: ref, className: cn('mds-text', `mds-text--${variant}`, `mds-text--size-${finalSize}`, `mds-text--color-${color}`, `mds-text--weight-${weight}`, className), ...props, children: children }));
1459
1487
  });
1460
1488
  Typography.displayName = 'Typography';
1461
- const BrandLogo = forwardRef(({ size = 'md', className, children = 'Metropolle', ...props }, ref) => {
1489
+ const BrandLogo = forwardRef(({ size = 'md', weight = 'bold', // Peso bold por padrão para a marca
1490
+ className, children = 'Metropolle', ...props }, ref) => {
1462
1491
  const sizeMap = {
1463
1492
  sm: '2xl',
1464
1493
  md: '4xl',
1465
1494
  lg: '4xl', // Same as md but with different mobile behavior
1466
1495
  };
1467
- return (jsxRuntimeExports.jsx(Typography, { ref: ref, variant: "brand", size: sizeMap[size], className: cn('mds-brand-logo', `mds-brand-logo--${size}`, className), ...props, children: children }));
1496
+ return (jsxRuntimeExports.jsx(Typography, { ref: ref, variant: "brand", size: sizeMap[size], weight: weight, className: cn('mds-brand-logo', `mds-brand-logo--${size}`, className), ...props, children: children }));
1468
1497
  });
1469
1498
  BrandLogo.displayName = 'BrandLogo';
1470
1499
 
@@ -1488,5 +1517,1109 @@ Button.displayName = 'Button';
1488
1517
  */
1489
1518
  const LoadingSpinner = () => (jsxRuntimeExports.jsxs("svg", { className: "mds-spinner", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", children: [jsxRuntimeExports.jsx("circle", { className: "mds-spinner__track", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "2", fill: "none", opacity: "0.25" }), jsxRuntimeExports.jsx("circle", { className: "mds-spinner__path", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "2", fill: "none", strokeDasharray: "40 20", strokeLinecap: "round" })] }));
1490
1519
 
1491
- export { BrandLogo, Button, GlassCard, Typography, cn };
1520
+ /**
1521
+ * Select Component (Design System)
1522
+ *
1523
+ * Custom dropdown select that renders consistently across all browsers.
1524
+ * Unlike native <select>, this component renders the dropdown via JavaScript,
1525
+ * ensuring proper theming support on Edge/Chrome Windows.
1526
+ *
1527
+ * @example
1528
+ * ```tsx
1529
+ * <Select
1530
+ * options={[
1531
+ * { label: 'Option 1', value: '1' },
1532
+ * { label: 'Option 2', value: '2' },
1533
+ * ]}
1534
+ * value={selectedValue}
1535
+ * onChange={setSelectedValue}
1536
+ * placeholder="Select an option..."
1537
+ * />
1538
+ * ```
1539
+ */
1540
+ const Select = forwardRef(({ options, value, onChange, placeholder = 'Select...', variant = 'themed', size = 'md', disabled = false, loading = false, error = false, className, dropdownClassName, id, name, 'aria-label': ariaLabel, fullWidth = false, searchable = false, searchPlaceholder = 'Search...', maxHeight = 300, zIndex = 1050, }, ref) => {
1541
+ const [isOpen, setIsOpen] = useState(false);
1542
+ const [searchTerm, setSearchTerm] = useState('');
1543
+ const [highlightedIndex, setHighlightedIndex] = useState(-1);
1544
+ const [mounted, setMounted] = useState(false);
1545
+ const triggerRef = useRef(null);
1546
+ const dropdownRef = useRef(null);
1547
+ const searchInputRef = useRef(null);
1548
+ const listRef = useRef(null);
1549
+ // Combine refs
1550
+ const combinedRef = (el) => {
1551
+ triggerRef.current = el;
1552
+ if (typeof ref === 'function') {
1553
+ ref(el);
1554
+ }
1555
+ else if (ref) {
1556
+ ref.current = el;
1557
+ }
1558
+ };
1559
+ // Client-side only
1560
+ useEffect(() => {
1561
+ setMounted(true);
1562
+ }, []);
1563
+ // Filter options based on search
1564
+ const filteredOptions = useMemo(() => {
1565
+ if (!searchTerm)
1566
+ return options;
1567
+ const term = searchTerm.toLowerCase();
1568
+ return options.filter(opt => {
1569
+ const label = typeof opt.label === 'string' ? opt.label : String(opt.value);
1570
+ return label.toLowerCase().includes(term);
1571
+ });
1572
+ }, [options, searchTerm]);
1573
+ // Get selected option label
1574
+ const selectedOption = useMemo(() => {
1575
+ return options.find(opt => opt.value === value);
1576
+ }, [options, value]);
1577
+ // Handle dropdown positioning
1578
+ const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0, width: 0 });
1579
+ const updateDropdownPosition = useCallback(() => {
1580
+ if (!triggerRef.current)
1581
+ return;
1582
+ const rect = triggerRef.current.getBoundingClientRect();
1583
+ const viewportHeight = window.innerHeight;
1584
+ const spaceBelow = viewportHeight - rect.bottom;
1585
+ const spaceAbove = rect.top;
1586
+ // Determine if dropdown should open above or below
1587
+ const dropdownHeight = Math.min(maxHeight, filteredOptions.length * 40 + (searchable ? 48 : 0));
1588
+ const openAbove = spaceBelow < dropdownHeight && spaceAbove > spaceBelow;
1589
+ setDropdownPosition({
1590
+ top: openAbove ? rect.top - dropdownHeight : rect.bottom + 4,
1591
+ left: rect.left,
1592
+ width: rect.width,
1593
+ });
1594
+ }, [maxHeight, filteredOptions.length, searchable]);
1595
+ // Open dropdown
1596
+ const openDropdown = useCallback(() => {
1597
+ if (disabled || loading)
1598
+ return;
1599
+ updateDropdownPosition();
1600
+ setIsOpen(true);
1601
+ setSearchTerm('');
1602
+ setHighlightedIndex(value ? filteredOptions.findIndex(opt => opt.value === value) : 0);
1603
+ }, [disabled, loading, updateDropdownPosition, value, filteredOptions]);
1604
+ // Close dropdown
1605
+ const closeDropdown = useCallback(() => {
1606
+ setIsOpen(false);
1607
+ setSearchTerm('');
1608
+ setHighlightedIndex(-1);
1609
+ triggerRef.current?.focus();
1610
+ }, []);
1611
+ // Handle option select
1612
+ const handleSelect = useCallback((optionValue) => {
1613
+ // Safety check: ensure we're passing a string, not an object
1614
+ const safeValue = typeof optionValue === 'string' ? optionValue : String(optionValue);
1615
+ onChange?.(safeValue);
1616
+ closeDropdown();
1617
+ }, [onChange, closeDropdown]);
1618
+ // Keyboard navigation
1619
+ const handleKeyDown = useCallback((e) => {
1620
+ if (disabled || loading)
1621
+ return;
1622
+ switch (e.key) {
1623
+ case 'Enter':
1624
+ case ' ':
1625
+ e.preventDefault();
1626
+ if (isOpen && highlightedIndex >= 0 && filteredOptions[highlightedIndex]) {
1627
+ const opt = filteredOptions[highlightedIndex];
1628
+ if (!opt.disabled) {
1629
+ handleSelect(opt.value);
1630
+ }
1631
+ }
1632
+ else if (!isOpen) {
1633
+ openDropdown();
1634
+ }
1635
+ break;
1636
+ case 'ArrowDown':
1637
+ e.preventDefault();
1638
+ if (!isOpen) {
1639
+ openDropdown();
1640
+ }
1641
+ else {
1642
+ setHighlightedIndex(prev => {
1643
+ const next = prev + 1;
1644
+ return next >= filteredOptions.length ? 0 : next;
1645
+ });
1646
+ }
1647
+ break;
1648
+ case 'ArrowUp':
1649
+ e.preventDefault();
1650
+ if (isOpen) {
1651
+ setHighlightedIndex(prev => {
1652
+ const next = prev - 1;
1653
+ return next < 0 ? filteredOptions.length - 1 : next;
1654
+ });
1655
+ }
1656
+ break;
1657
+ case 'Escape':
1658
+ e.preventDefault();
1659
+ closeDropdown();
1660
+ break;
1661
+ case 'Tab':
1662
+ if (isOpen) {
1663
+ closeDropdown();
1664
+ }
1665
+ break;
1666
+ case 'Home':
1667
+ if (isOpen) {
1668
+ e.preventDefault();
1669
+ setHighlightedIndex(0);
1670
+ }
1671
+ break;
1672
+ case 'End':
1673
+ if (isOpen) {
1674
+ e.preventDefault();
1675
+ setHighlightedIndex(filteredOptions.length - 1);
1676
+ }
1677
+ break;
1678
+ }
1679
+ }, [disabled, loading, isOpen, highlightedIndex, filteredOptions, handleSelect, openDropdown, closeDropdown]);
1680
+ // Click outside to close
1681
+ useEffect(() => {
1682
+ if (!isOpen)
1683
+ return;
1684
+ const handleClickOutside = (e) => {
1685
+ if (triggerRef.current?.contains(e.target) ||
1686
+ dropdownRef.current?.contains(e.target)) {
1687
+ return;
1688
+ }
1689
+ closeDropdown();
1690
+ };
1691
+ document.addEventListener('mousedown', handleClickOutside);
1692
+ return () => document.removeEventListener('mousedown', handleClickOutside);
1693
+ }, [isOpen, closeDropdown]);
1694
+ // Update position on scroll/resize
1695
+ useEffect(() => {
1696
+ if (!isOpen)
1697
+ return;
1698
+ const handleUpdate = () => updateDropdownPosition();
1699
+ window.addEventListener('scroll', handleUpdate, true);
1700
+ window.addEventListener('resize', handleUpdate);
1701
+ return () => {
1702
+ window.removeEventListener('scroll', handleUpdate, true);
1703
+ window.removeEventListener('resize', handleUpdate);
1704
+ };
1705
+ }, [isOpen, updateDropdownPosition]);
1706
+ // Focus search input when dropdown opens
1707
+ useEffect(() => {
1708
+ if (isOpen && searchable && searchInputRef.current) {
1709
+ searchInputRef.current.focus();
1710
+ }
1711
+ }, [isOpen, searchable]);
1712
+ // Scroll highlighted option into view
1713
+ useEffect(() => {
1714
+ if (!isOpen || highlightedIndex < 0 || !listRef.current)
1715
+ return;
1716
+ const highlighted = listRef.current.children[highlightedIndex];
1717
+ if (highlighted) {
1718
+ highlighted.scrollIntoView({ block: 'nearest' });
1719
+ }
1720
+ }, [isOpen, highlightedIndex]);
1721
+ // Size classes
1722
+ const sizeClasses = {
1723
+ sm: 'mds-select--sm',
1724
+ md: 'mds-select--md',
1725
+ lg: 'mds-select--lg',
1726
+ };
1727
+ // Variant classes
1728
+ const variantClasses = {
1729
+ base: 'mds-select--base',
1730
+ themed: 'mds-select--themed',
1731
+ dashboard: 'mds-select--themed',
1732
+ };
1733
+ const triggerClasses = cn('mds-select-trigger', sizeClasses[size], variantClasses[variant], isOpen && 'mds-select-trigger--open', disabled && 'mds-select-trigger--disabled', loading && 'mds-select-trigger--loading', error && 'mds-select-trigger--error', fullWidth && 'mds-select-trigger--full-width', className);
1734
+ const dropdownClasses = cn('mds-select-dropdown', variantClasses[variant], dropdownClassName);
1735
+ // Hidden input for form submission
1736
+ const hiddenInput = name ? (jsxRuntimeExports.jsx("input", { type: "hidden", name: name, value: value || '' })) : null;
1737
+ // Dropdown portal content
1738
+ const dropdownContent = isOpen && mounted ? createPortal(jsxRuntimeExports.jsxs("div", { ref: dropdownRef, className: dropdownClasses, style: {
1739
+ position: 'fixed',
1740
+ top: dropdownPosition.top,
1741
+ left: dropdownPosition.left,
1742
+ width: dropdownPosition.width,
1743
+ maxHeight,
1744
+ zIndex,
1745
+ }, role: "listbox", "aria-label": ariaLabel || placeholder, children: [searchable && (jsxRuntimeExports.jsxs("div", { className: "mds-select-search", children: [jsxRuntimeExports.jsx("input", { ref: searchInputRef, type: "text", className: "mds-select-search__input", placeholder: searchPlaceholder, value: searchTerm, onChange: (e) => {
1746
+ setSearchTerm(e.target.value);
1747
+ setHighlightedIndex(0);
1748
+ }, onKeyDown: handleKeyDown, "aria-label": "Search options" }), jsxRuntimeExports.jsx("svg", { className: "mds-select-search__icon", viewBox: "0 0 20 20", fill: "currentColor", children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", d: "M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z", clipRule: "evenodd" }) })] })), jsxRuntimeExports.jsx("ul", { ref: listRef, className: "mds-select-options", children: filteredOptions.length === 0 ? (jsxRuntimeExports.jsx("li", { className: "mds-select-option mds-select-option--empty", children: "No options found" })) : (filteredOptions.map((option, index) => (jsxRuntimeExports.jsxs("li", { className: cn('mds-select-option', option.value === value && 'mds-select-option--selected', index === highlightedIndex && 'mds-select-option--highlighted', option.disabled && 'mds-select-option--disabled'), role: "option", "aria-selected": option.value === value, "aria-disabled": option.disabled, onClick: () => {
1749
+ if (!option.disabled) {
1750
+ handleSelect(option.value);
1751
+ }
1752
+ }, onMouseEnter: () => {
1753
+ if (!option.disabled) {
1754
+ setHighlightedIndex(index);
1755
+ }
1756
+ }, children: [jsxRuntimeExports.jsx("span", { className: "mds-select-option__label", children: option.label }), option.value === value && (jsxRuntimeExports.jsx("svg", { className: "mds-select-option__check", viewBox: "0 0 20 20", fill: "currentColor", children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }))] }, option.value)))) })] }), document.body) : null;
1757
+ return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [hiddenInput, jsxRuntimeExports.jsxs("button", { ref: combinedRef, type: "button", id: id, className: triggerClasses, onClick: () => isOpen ? closeDropdown() : openDropdown(), onKeyDown: handleKeyDown, disabled: disabled || loading, "aria-haspopup": "listbox", "aria-expanded": isOpen, "aria-label": ariaLabel, "aria-invalid": error, children: [jsxRuntimeExports.jsx("span", { className: cn('mds-select-trigger__value', !selectedOption && 'mds-select-trigger__placeholder'), children: loading ? 'Loading...' : (selectedOption?.label || placeholder) }), jsxRuntimeExports.jsx("span", { className: "mds-select-trigger__icon", children: loading ? (jsxRuntimeExports.jsx("svg", { className: "mds-select-spinner", viewBox: "0 0 24 24", fill: "none", children: jsxRuntimeExports.jsx("circle", { cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeDasharray: "32", strokeDashoffset: "32", children: jsxRuntimeExports.jsx("animate", { attributeName: "stroke-dashoffset", values: "32;0", dur: "1s", repeatCount: "indefinite" }) }) })) : (jsxRuntimeExports.jsx("svg", { className: "mds-select-chevron", viewBox: "0 0 20 20", fill: "currentColor", children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", d: "M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z", clipRule: "evenodd" }) })) })] }), dropdownContent] }));
1758
+ });
1759
+ Select.displayName = 'Select';
1760
+
1761
+ function ThemeToggle({ size = 'md', className = '', disabled = false, onChange, storageKey = 'theme' }) {
1762
+ const [theme, setTheme] = useState('dark');
1763
+ const [mounted, setMounted] = useState(false);
1764
+ // Initialize theme on mount
1765
+ useEffect(() => {
1766
+ try {
1767
+ if (typeof window !== 'undefined') {
1768
+ const savedTheme = localStorage.getItem(storageKey) || 'dark';
1769
+ setTheme(savedTheme);
1770
+ document.documentElement.setAttribute('data-theme', savedTheme);
1771
+ setMounted(true);
1772
+ }
1773
+ }
1774
+ catch (err) {
1775
+ setTheme('dark');
1776
+ setMounted(true);
1777
+ }
1778
+ }, [storageKey]);
1779
+ // Listen to external theme changes
1780
+ useEffect(() => {
1781
+ if (typeof window !== 'undefined') {
1782
+ const updateTheme = () => {
1783
+ const currentTheme = document.documentElement.getAttribute('data-theme') || 'dark';
1784
+ setTheme(currentTheme);
1785
+ };
1786
+ const observer = new MutationObserver(() => {
1787
+ updateTheme();
1788
+ });
1789
+ observer.observe(document.documentElement, {
1790
+ attributes: true,
1791
+ attributeFilter: ['data-theme']
1792
+ });
1793
+ return () => observer.disconnect();
1794
+ }
1795
+ }, []);
1796
+ const toggleTheme = () => {
1797
+ if (disabled)
1798
+ return;
1799
+ try {
1800
+ const newTheme = theme === 'light' ? 'dark' : 'light';
1801
+ document.documentElement.setAttribute('data-theme', newTheme);
1802
+ localStorage.setItem(storageKey, newTheme);
1803
+ setTheme(newTheme);
1804
+ onChange?.(newTheme);
1805
+ }
1806
+ catch (err) {
1807
+ console.warn('Failed to toggle theme:', err);
1808
+ }
1809
+ };
1810
+ // Don't render until mounted (prevents hydration mismatch)
1811
+ if (!mounted) {
1812
+ return (jsxRuntimeExports.jsx("div", { className: `mds-theme-toggle mds-theme-toggle--${size} ${className}`, style: { opacity: 0.5 }, "aria-hidden": "true" }));
1813
+ }
1814
+ const isDark = theme === 'dark';
1815
+ const buttonStyle = isDark
1816
+ ? {
1817
+ backgroundColor: 'rgba(0, 0, 0, 0.35)',
1818
+ border: '1px solid rgba(255, 255, 255, 0.18)',
1819
+ boxShadow: '0 2px 8px rgba(0, 0, 0, 0.3)'
1820
+ }
1821
+ : undefined;
1822
+ const buttonClasses = [
1823
+ 'mds-theme-toggle',
1824
+ `mds-theme-toggle--${size}`,
1825
+ className
1826
+ ].filter(Boolean).join(' ');
1827
+ return (jsxRuntimeExports.jsx("button", { onClick: toggleTheme, className: buttonClasses, disabled: disabled, type: "button", "aria-pressed": isDark, "aria-label": `Switch to ${isDark ? 'light' : 'dark'} mode`, title: `Switch to ${isDark ? 'light' : 'dark'} mode`, "data-theme": isDark ? 'dark' : 'light', style: buttonStyle }));
1828
+ }
1829
+
1830
+ const TableHeader = ({ columns, gridTemplate, onSort, sortColumn, sortDirection }) => {
1831
+ return (jsxRuntimeExports.jsx("div", { role: "rowgroup", style: {
1832
+ display: 'grid',
1833
+ gridTemplateColumns: gridTemplate,
1834
+ gap: '16px',
1835
+ padding: '16px 20px',
1836
+ borderBottom: '1px solid var(--border-color)',
1837
+ backgroundColor: 'rgba(255, 255, 255, 0.05)'
1838
+ }, children: columns.map((column) => (jsxRuntimeExports.jsxs("div", { role: "columnheader", style: {
1839
+ color: 'var(--text-primary)',
1840
+ fontWeight: '500',
1841
+ fontSize: '14px',
1842
+ display: 'flex',
1843
+ alignItems: 'center',
1844
+ justifyContent: column.align === 'center' ? 'center' :
1845
+ column.align === 'right' ? 'flex-end' : 'flex-start',
1846
+ cursor: column.sortable && onSort ? 'pointer' : 'default',
1847
+ gap: '4px',
1848
+ transition: 'color 0.2s ease'
1849
+ }, onClick: () => column.sortable && onSort && onSort(column.key), onMouseEnter: (e) => {
1850
+ if (column.sortable && onSort) {
1851
+ e.currentTarget.style.color = '#ffffff';
1852
+ }
1853
+ }, onMouseLeave: (e) => {
1854
+ e.currentTarget.style.color = 'var(--text-primary)';
1855
+ }, children: [column.label, column.sortable && onSort && (jsxRuntimeExports.jsx("span", { style: {
1856
+ fontSize: '12px',
1857
+ opacity: sortColumn === column.key ? 1 : 0.5
1858
+ }, children: sortColumn === column.key ?
1859
+ (sortDirection === 'asc' ? '↑' : '↓') : '↕' }))] }, column.key))) }));
1860
+ };
1861
+
1862
+ const TableRow = ({ item, index, columns, actions = [], gridTemplate, isLast, variant, onActionClick }) => {
1863
+ return (jsxRuntimeExports.jsxs("div", { role: "row", style: {
1864
+ display: 'grid',
1865
+ gridTemplateColumns: gridTemplate,
1866
+ gap: '16px',
1867
+ padding: variant === 'compact' ? '12px 20px' : '16px 20px',
1868
+ borderBottom: isLast ? 'none' : '1px solid var(--border-color)',
1869
+ backgroundColor: 'transparent',
1870
+ transition: 'background-color 0.2s ease'
1871
+ }, onMouseEnter: (e) => {
1872
+ e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.05)';
1873
+ }, onMouseLeave: (e) => {
1874
+ e.currentTarget.style.backgroundColor = 'transparent';
1875
+ }, children: [columns.map((column) => (jsxRuntimeExports.jsx("div", { role: "cell", style: {
1876
+ display: 'flex',
1877
+ flexDirection: 'column',
1878
+ gap: '4px',
1879
+ justifyContent: 'center',
1880
+ alignItems: column.align === 'center' ? 'center' :
1881
+ column.align === 'right' ? 'flex-end' : 'flex-start'
1882
+ }, children: column.render ?
1883
+ column.render(item[column.key], item, index) :
1884
+ jsxRuntimeExports.jsx("div", { style: {
1885
+ color: 'var(--text-primary)',
1886
+ fontSize: '14px'
1887
+ }, children: item[column.key] }) }, column.key))), actions.length > 0 && (jsxRuntimeExports.jsx("div", { role: "cell", style: {
1888
+ display: 'flex',
1889
+ gap: '8px',
1890
+ justifyContent: 'center',
1891
+ alignItems: 'center'
1892
+ }, children: actions.map((action) => {
1893
+ const isDisabled = action.disabled?.(item) || false;
1894
+ const isLoading = action.loading?.(item) || false;
1895
+ return (jsxRuntimeExports.jsxs("button", { onClick: () => !isDisabled && !isLoading && onActionClick(action, item), disabled: isDisabled || isLoading, style: {
1896
+ background: 'none',
1897
+ border: action.variant === 'danger' ? '1px solid rgba(239, 68, 68, 0.3)' :
1898
+ '1px solid var(--border-color)',
1899
+ borderRadius: '6px',
1900
+ padding: '6px 12px',
1901
+ color: action.variant === 'danger' ? '#f87171' : 'var(--text-primary)',
1902
+ fontSize: '12px',
1903
+ cursor: isDisabled || isLoading ? 'not-allowed' : 'pointer',
1904
+ display: 'flex',
1905
+ alignItems: 'center',
1906
+ gap: '4px',
1907
+ transition: 'all 0.2s ease',
1908
+ opacity: isDisabled || isLoading ? 0.5 : 1,
1909
+ whiteSpace: 'nowrap'
1910
+ }, onMouseEnter: (e) => {
1911
+ if (!isDisabled && !isLoading) {
1912
+ if (action.variant === 'danger') {
1913
+ e.currentTarget.style.backgroundColor = 'rgba(239, 68, 68, 0.1)';
1914
+ e.currentTarget.style.borderColor = 'rgba(239, 68, 68, 0.5)';
1915
+ }
1916
+ else {
1917
+ e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.1)';
1918
+ e.currentTarget.style.borderColor = 'var(--text-primary)';
1919
+ }
1920
+ }
1921
+ }, onMouseLeave: (e) => {
1922
+ if (!isDisabled && !isLoading) {
1923
+ e.currentTarget.style.backgroundColor = 'transparent';
1924
+ e.currentTarget.style.borderColor = action.variant === 'danger' ?
1925
+ 'rgba(239, 68, 68, 0.3)' : 'var(--border-color)';
1926
+ }
1927
+ }, children: [action.icon && action.icon, action.label] }, action.key));
1928
+ }) }))] }));
1929
+ };
1930
+
1931
+ const DataTable = ({ data, columns, loading = false, searchTerm = '', actions = [], variant = 'default', responsive = 'stack', onSort, emptyMessage = 'Nenhum item encontrado', loadingMessage = 'Carregando...', className, style, maxHeight = '600px', showSearchCount = true, rowHover = true, striped = false }) => {
1932
+ const [sortColumn, setSortColumn] = useState('');
1933
+ const [sortDirection, setSortDirection] = useState('asc');
1934
+ // Filter data based on search term
1935
+ const filteredData = useMemo(() => {
1936
+ if (!searchTerm)
1937
+ return data;
1938
+ return data.filter(item => {
1939
+ return columns.some(column => {
1940
+ const value = item[column.key];
1941
+ if (value === null || value === undefined)
1942
+ return false;
1943
+ return String(value).toLowerCase().includes(searchTerm.toLowerCase());
1944
+ });
1945
+ });
1946
+ }, [data, searchTerm, columns]);
1947
+ // Generate grid template based on columns and actions
1948
+ const gridTemplate = useMemo(() => {
1949
+ const columnWidths = columns.map(col => col.width || '1fr').join(' ');
1950
+ const actionsWidth = actions.length > 0 ? ' 120px' : '';
1951
+ return columnWidths + actionsWidth;
1952
+ }, [columns, actions]);
1953
+ // Handle sort
1954
+ const handleSort = (columnKey) => {
1955
+ let direction = 'asc';
1956
+ if (sortColumn === columnKey && sortDirection === 'asc') {
1957
+ direction = 'desc';
1958
+ }
1959
+ setSortColumn(columnKey);
1960
+ setSortDirection(direction);
1961
+ if (onSort) {
1962
+ onSort(columnKey, direction);
1963
+ }
1964
+ };
1965
+ // Handle action click
1966
+ const handleActionClick = (action, item) => {
1967
+ action.onClick(item);
1968
+ };
1969
+ // Loading state
1970
+ if (loading) {
1971
+ return (jsxRuntimeExports.jsx("div", { className: className, style: {
1972
+ position: 'relative',
1973
+ borderRadius: '24px',
1974
+ backdropFilter: 'blur(24px)',
1975
+ backgroundColor: 'rgba(255, 255, 255, 0.1)',
1976
+ border: '1px solid rgba(255, 255, 255, 0.3)',
1977
+ boxShadow: '0 12px 40px rgba(0, 0, 0, 0.15)',
1978
+ padding: '32px',
1979
+ ...style
1980
+ }, children: jsxRuntimeExports.jsxs("div", { style: {
1981
+ display: 'flex',
1982
+ alignItems: 'center',
1983
+ justifyContent: 'center',
1984
+ gap: '12px'
1985
+ }, children: [jsxRuntimeExports.jsx("div", { style: {
1986
+ width: '32px',
1987
+ height: '32px',
1988
+ border: '2px solid transparent',
1989
+ borderTop: '2px solid white',
1990
+ borderRadius: '50%',
1991
+ animation: 'spin 1s linear infinite'
1992
+ } }), jsxRuntimeExports.jsx("span", { style: { color: 'var(--text-primary)' }, children: loadingMessage })] }) }));
1993
+ }
1994
+ // Empty state
1995
+ if (filteredData.length === 0) {
1996
+ return (jsxRuntimeExports.jsx("div", { className: className, style: {
1997
+ position: 'relative',
1998
+ borderRadius: '24px',
1999
+ backdropFilter: 'blur(24px)',
2000
+ backgroundColor: 'rgba(255, 255, 255, 0.1)',
2001
+ border: '1px solid rgba(255, 255, 255, 0.3)',
2002
+ boxShadow: '0 12px 40px rgba(0, 0, 0, 0.15)',
2003
+ padding: '40px',
2004
+ textAlign: 'center',
2005
+ ...style
2006
+ }, children: jsxRuntimeExports.jsx("div", { style: {
2007
+ color: 'var(--text-secondary)',
2008
+ fontSize: '16px'
2009
+ }, children: emptyMessage }) }));
2010
+ }
2011
+ return (jsxRuntimeExports.jsxs("div", { className: className, style: {
2012
+ position: 'relative',
2013
+ borderRadius: '24px',
2014
+ backdropFilter: 'blur(24px)',
2015
+ backgroundColor: 'rgba(255, 255, 255, 0.1)',
2016
+ border: '1px solid rgba(255, 255, 255, 0.3)',
2017
+ boxShadow: '0 12px 40px rgba(0, 0, 0, 0.15)',
2018
+ overflow: 'hidden',
2019
+ ...style
2020
+ }, role: "table", "aria-label": "Tabela de dados", children: [showSearchCount && searchTerm && (jsxRuntimeExports.jsxs("div", { style: {
2021
+ padding: '16px',
2022
+ color: 'var(--text-secondary)',
2023
+ fontSize: '14px',
2024
+ borderBottom: '1px solid var(--border-color)'
2025
+ }, children: ["Mostrando", ' ', jsxRuntimeExports.jsx("span", { style: { fontWeight: '500', color: 'var(--text-primary)' }, children: filteredData.length }), ' ', "de", ' ', jsxRuntimeExports.jsx("span", { style: { fontWeight: '500', color: 'var(--text-primary)' }, children: data.length }), ' ', "itens"] })), jsxRuntimeExports.jsx(TableHeader, { columns: columns, gridTemplate: gridTemplate, onSort: onSort ? handleSort : undefined, sortColumn: sortColumn, sortDirection: sortDirection }), jsxRuntimeExports.jsx("div", { role: "rowgroup", style: {
2026
+ maxHeight,
2027
+ overflowY: 'auto'
2028
+ }, children: filteredData.map((item, index) => (jsxRuntimeExports.jsx(TableRow, { item: item, index: index, columns: columns, actions: actions, gridTemplate: gridTemplate, isLast: index === filteredData.length - 1, variant: variant, onActionClick: handleActionClick }, item.id || index))) })] }));
2029
+ };
2030
+
2031
+ const CellRenderers = {
2032
+ // ID cell - monospace background
2033
+ id: (value) => (jsxRuntimeExports.jsx("div", { className: "data-table-code", style: {
2034
+ color: 'var(--text-secondary)',
2035
+ fontSize: '12px',
2036
+ backgroundColor: 'rgba(255, 255, 255, 0.05)',
2037
+ padding: '2px 8px',
2038
+ borderRadius: '4px',
2039
+ textAlign: 'center',
2040
+ fontFamily: 'monospace'
2041
+ }, children: value })),
2042
+ // Name cell - primary text with background
2043
+ name: (value) => (jsxRuntimeExports.jsx("div", { className: "data-table-code", style: {
2044
+ color: 'var(--text-primary)',
2045
+ fontSize: '14px',
2046
+ backgroundColor: 'rgba(255, 255, 255, 0.1)',
2047
+ padding: '4px 12px',
2048
+ borderRadius: '8px',
2049
+ fontFamily: 'monospace'
2050
+ }, children: value })),
2051
+ // Parameter value - masked if secure
2052
+ parameterValue: (value, item) => {
2053
+ const displayValue = item.type === 'SecureString' ? '••••••••' :
2054
+ (value?.length > 50 ? `${value.substring(0, 50)}...` : value);
2055
+ return (jsxRuntimeExports.jsx("div", { className: "data-table-code", style: {
2056
+ color: 'var(--text-primary)',
2057
+ fontSize: '14px',
2058
+ backgroundColor: 'rgba(255, 255, 255, 0.1)',
2059
+ borderRadius: '8px',
2060
+ maxWidth: '300px',
2061
+ wordBreak: 'break-all',
2062
+ padding: '4px 12px',
2063
+ fontFamily: 'monospace'
2064
+ }, children: displayValue }));
2065
+ },
2066
+ // Badge renderer for types/statuses
2067
+ badge: (value, variant = 'primary') => (jsxRuntimeExports.jsx("span", { className: `data-table-badge ${variant}`, children: value })),
2068
+ // Parameter type badge
2069
+ parameterType: (value) => {
2070
+ const variant = value === 'SecureString' ? 'danger' :
2071
+ value === 'StringList' ? 'success' : 'primary';
2072
+ return CellRenderers.badge(value, variant);
2073
+ },
2074
+ // Environment badge
2075
+ environment: (value, item) => {
2076
+ const env = item.name?.includes('/prod/') ? 'PROD' : 'DEV';
2077
+ const variant = env === 'PROD' ? 'info' : 'warning';
2078
+ return CellRenderers.badge(env, variant);
2079
+ },
2080
+ // Action type badge for audit logs
2081
+ actionType: (value) => {
2082
+ const variant = value === 'CREATE' ? 'success' :
2083
+ value === 'UPDATE' ? 'primary' : 'danger';
2084
+ return CellRenderers.badge(value, variant);
2085
+ },
2086
+ // Date formatter
2087
+ date: (value) => (jsxRuntimeExports.jsx("div", { style: {
2088
+ color: 'var(--text-primary)',
2089
+ fontSize: '14px'
2090
+ }, children: value ? new Date(value).toLocaleString('pt-BR') : '-' })),
2091
+ // Description/secondary text
2092
+ description: (value) => (jsxRuntimeExports.jsx("div", { style: {
2093
+ color: 'var(--text-secondary)',
2094
+ fontSize: '12px',
2095
+ maxWidth: '300px',
2096
+ overflow: 'hidden',
2097
+ textOverflow: 'ellipsis',
2098
+ whiteSpace: 'nowrap'
2099
+ }, children: value })),
2100
+ // JSON preview for audit changes
2101
+ jsonPreview: (value) => {
2102
+ const jsonString = JSON.stringify(value);
2103
+ const preview = jsonString.length > 30 ? jsonString.substring(0, 30) + '...' : jsonString;
2104
+ return (jsxRuntimeExports.jsx("div", { style: {
2105
+ color: 'var(--text-secondary)',
2106
+ fontSize: '12px',
2107
+ fontFamily: 'monospace',
2108
+ maxWidth: '150px',
2109
+ overflow: 'hidden',
2110
+ textOverflow: 'ellipsis',
2111
+ whiteSpace: 'nowrap'
2112
+ }, children: preview }));
2113
+ },
2114
+ // Combined cell with main value and description
2115
+ combined: (mainValue, description) => (jsxRuntimeExports.jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '8px' }, children: [CellRenderers.name(mainValue), description && CellRenderers.description(description)] })),
2116
+ // Combined with badges
2117
+ combinedWithBadges: (mainValue, badges) => (jsxRuntimeExports.jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '8px' }, children: [CellRenderers.name(mainValue), jsxRuntimeExports.jsx("div", { style: { display: 'flex', gap: '8px', flexWrap: 'wrap' }, children: badges.map((badge, index) => (jsxRuntimeExports.jsx("span", { className: `data-table-badge ${badge.variant || 'primary'}`, children: badge.value }, index))) })] }))
2118
+ };
2119
+ // Common action icons
2120
+ const ActionIcons = {
2121
+ edit: (jsxRuntimeExports.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", children: jsxRuntimeExports.jsx("path", { d: "M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z" }) })),
2122
+ delete: (jsxRuntimeExports.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", children: jsxRuntimeExports.jsx("path", { d: "M9,3V4H4V6H5V19A2,2 0 0,0 7,21H17A2,2 0 0,0 19,19V6H20V4H15V3H9M7,6H17V19H7V6M9,8V17H11V8H9M13,8V17H15V8H13Z" }) })),
2123
+ view: (jsxRuntimeExports.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", children: jsxRuntimeExports.jsx("path", { d: "M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z" }) })),
2124
+ loading: (jsxRuntimeExports.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", className: "data-table-spinner", children: jsxRuntimeExports.jsx("path", { d: "M12,4V2A10,10 0 0,0 2,12H4A8,8 0 0,1 12,4Z" }) }))
2125
+ };
2126
+
2127
+ // Configuração para ParametersTable (Settings)
2128
+ const parametersTableConfig = {
2129
+ columns: [
2130
+ {
2131
+ key: 'name',
2132
+ label: 'Parâmetro',
2133
+ width: '1fr',
2134
+ render: (value, item) => CellRenderers.combinedWithBadges(value, [
2135
+ { value: item.type, variant: item.type === 'SecureString' ? 'danger' :
2136
+ item.type === 'StringList' ? 'success' : 'primary' },
2137
+ { value: item.name.includes('/prod/') ? 'PROD' : 'DEV',
2138
+ variant: item.name.includes('/prod/') ? 'info' : 'warning' }
2139
+ ])
2140
+ },
2141
+ {
2142
+ key: 'value',
2143
+ label: 'Valor',
2144
+ width: '2fr',
2145
+ render: (value, item) => (jsxRuntimeExports.jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '8px' }, children: [CellRenderers.parameterValue(value, item), CellRenderers.description(item.description)] }))
2146
+ }
2147
+ ],
2148
+ actions: [
2149
+ {
2150
+ key: 'edit',
2151
+ label: '✏️',
2152
+ variant: 'secondary',
2153
+ onClick: (item) => console.log('Edit', item),
2154
+ disabled: (item) => false
2155
+ },
2156
+ {
2157
+ key: 'delete',
2158
+ label: '🗑️',
2159
+ variant: 'danger',
2160
+ onClick: (item) => console.log('Delete', item),
2161
+ disabled: (item) => false,
2162
+ loading: (item) => item.deleting || false
2163
+ }
2164
+ ]
2165
+ };
2166
+ // Configuração para GeographyTable - Regions
2167
+ const regionsTableConfig = {
2168
+ columns: [
2169
+ {
2170
+ key: 'region_id',
2171
+ label: 'ID',
2172
+ width: '80px',
2173
+ render: CellRenderers.id
2174
+ },
2175
+ {
2176
+ key: 'name',
2177
+ label: 'Nome',
2178
+ width: '1fr',
2179
+ render: CellRenderers.name
2180
+ },
2181
+ {
2182
+ key: 'code',
2183
+ label: 'Código',
2184
+ width: '120px',
2185
+ render: CellRenderers.name
2186
+ },
2187
+ {
2188
+ key: 'created_at',
2189
+ label: 'Criado em',
2190
+ width: '140px',
2191
+ render: CellRenderers.date
2192
+ },
2193
+ {
2194
+ key: 'created_by',
2195
+ label: 'Criado por',
2196
+ width: '140px',
2197
+ render: (value) => CellRenderers.name(value)
2198
+ }
2199
+ ],
2200
+ actions: [
2201
+ {
2202
+ key: 'edit',
2203
+ label: '✏️',
2204
+ variant: 'secondary',
2205
+ onClick: (item) => console.log('Edit region', item)
2206
+ },
2207
+ {
2208
+ key: 'delete',
2209
+ label: '🗑️',
2210
+ variant: 'danger',
2211
+ onClick: (item) => console.log('Delete region', item),
2212
+ loading: (item) => item.deleting || false
2213
+ }
2214
+ ]
2215
+ };
2216
+ // Configuração para GeographyTable - Countries
2217
+ const countriesTableConfig = {
2218
+ columns: [
2219
+ {
2220
+ key: 'country_id',
2221
+ label: 'ID',
2222
+ width: '80px',
2223
+ render: CellRenderers.id
2224
+ },
2225
+ {
2226
+ key: 'name',
2227
+ label: 'Nome',
2228
+ width: '1fr',
2229
+ render: CellRenderers.name
2230
+ },
2231
+ {
2232
+ key: 'iso2',
2233
+ label: 'Código',
2234
+ width: '120px',
2235
+ render: (value, item) => CellRenderers.combinedWithBadges(value, [
2236
+ { value: item.iso3, variant: 'primary' }
2237
+ ])
2238
+ },
2239
+ {
2240
+ key: 'capital',
2241
+ label: 'Capital',
2242
+ width: '140px',
2243
+ render: CellRenderers.name
2244
+ },
2245
+ {
2246
+ key: 'region',
2247
+ label: 'Região',
2248
+ width: '120px',
2249
+ render: (value) => CellRenderers.badge(value, 'info')
2250
+ }
2251
+ ],
2252
+ actions: [
2253
+ {
2254
+ key: 'edit',
2255
+ label: '✏️',
2256
+ variant: 'secondary',
2257
+ onClick: (item) => console.log('Edit country', item)
2258
+ },
2259
+ {
2260
+ key: 'delete',
2261
+ label: '🗑️',
2262
+ variant: 'danger',
2263
+ onClick: (item) => console.log('Delete country', item)
2264
+ }
2265
+ ]
2266
+ };
2267
+ // Configuração para Audit Log
2268
+ const auditLogTableConfig = {
2269
+ columns: [
2270
+ {
2271
+ key: 'timestamp',
2272
+ label: 'Data/Hora',
2273
+ width: '140px',
2274
+ render: CellRenderers.date
2275
+ },
2276
+ {
2277
+ key: 'user_email',
2278
+ label: 'Usuário',
2279
+ width: '180px',
2280
+ render: CellRenderers.name
2281
+ },
2282
+ {
2283
+ key: 'action',
2284
+ label: 'Ação',
2285
+ width: '100px',
2286
+ render: CellRenderers.actionType
2287
+ },
2288
+ {
2289
+ key: 'entity_type',
2290
+ label: 'Tipo',
2291
+ width: '120px',
2292
+ render: (value) => CellRenderers.badge(value, 'primary')
2293
+ },
2294
+ {
2295
+ key: 'entity_id',
2296
+ label: 'ID',
2297
+ width: '120px',
2298
+ render: CellRenderers.description
2299
+ },
2300
+ {
2301
+ key: 'changes',
2302
+ label: 'Alterações',
2303
+ width: '1fr',
2304
+ render: (value, item) => (jsxRuntimeExports.jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '8px' }, children: [CellRenderers.jsonPreview(value), jsxRuntimeExports.jsxs("button", { onClick: () => console.log('View details', item), style: {
2305
+ background: 'none',
2306
+ border: '1px solid var(--border-color)',
2307
+ borderRadius: '4px',
2308
+ padding: '4px 8px',
2309
+ color: 'var(--text-primary)',
2310
+ fontSize: '12px',
2311
+ cursor: 'pointer',
2312
+ display: 'flex',
2313
+ alignItems: 'center',
2314
+ gap: '4px',
2315
+ transition: 'all 0.2s ease',
2316
+ whiteSpace: 'nowrap'
2317
+ }, children: [ActionIcons.view, "Ver Detalhes"] })] }))
2318
+ }
2319
+ ]
2320
+ };
2321
+ // Configuração para States
2322
+ const statesTableConfig = {
2323
+ columns: [
2324
+ {
2325
+ key: 'state_id',
2326
+ label: 'ID',
2327
+ width: '80px',
2328
+ render: CellRenderers.id
2329
+ },
2330
+ {
2331
+ key: 'name',
2332
+ label: 'Nome',
2333
+ width: '1fr',
2334
+ render: CellRenderers.name
2335
+ },
2336
+ {
2337
+ key: 'code',
2338
+ label: 'Código',
2339
+ width: '120px',
2340
+ render: CellRenderers.name
2341
+ },
2342
+ {
2343
+ key: 'country_name',
2344
+ label: 'País',
2345
+ width: '140px',
2346
+ render: (value) => CellRenderers.badge(value, 'info')
2347
+ }
2348
+ ],
2349
+ actions: [
2350
+ {
2351
+ key: 'edit',
2352
+ label: '✏️',
2353
+ variant: 'secondary',
2354
+ onClick: (item) => console.log('Edit state', item)
2355
+ },
2356
+ {
2357
+ key: 'delete',
2358
+ label: '🗑️',
2359
+ variant: 'danger',
2360
+ onClick: (item) => console.log('Delete state', item)
2361
+ }
2362
+ ]
2363
+ };
2364
+ // Configuração para Cities
2365
+ const citiesTableConfig = {
2366
+ columns: [
2367
+ {
2368
+ key: 'city_id',
2369
+ label: 'ID',
2370
+ width: '80px',
2371
+ render: CellRenderers.id
2372
+ },
2373
+ {
2374
+ key: 'name',
2375
+ label: 'Nome',
2376
+ width: '1fr',
2377
+ render: CellRenderers.name
2378
+ },
2379
+ {
2380
+ key: 'population',
2381
+ label: 'População',
2382
+ width: '120px',
2383
+ render: (value) => (jsxRuntimeExports.jsx("div", { style: { color: 'var(--text-primary)', fontSize: '14px' }, children: value ? value.toLocaleString('pt-BR') : '-' }))
2384
+ },
2385
+ {
2386
+ key: 'state_name',
2387
+ label: 'Estado',
2388
+ width: '140px',
2389
+ render: (value) => CellRenderers.badge(value, 'success')
2390
+ },
2391
+ {
2392
+ key: 'country_name',
2393
+ label: 'País',
2394
+ width: '120px',
2395
+ render: (value) => CellRenderers.badge(value, 'info')
2396
+ }
2397
+ ],
2398
+ actions: [
2399
+ {
2400
+ key: 'edit',
2401
+ label: '✏️',
2402
+ variant: 'secondary',
2403
+ onClick: (item) => console.log('Edit city', item)
2404
+ },
2405
+ {
2406
+ key: 'delete',
2407
+ label: '🗑️',
2408
+ variant: 'danger',
2409
+ onClick: (item) => console.log('Delete city', item)
2410
+ }
2411
+ ]
2412
+ };
2413
+ // Função helper para aplicar configuração baseada no tipo
2414
+ const getTableConfig = (type) => {
2415
+ switch (type) {
2416
+ case 'parameters':
2417
+ return parametersTableConfig;
2418
+ case 'regions':
2419
+ return regionsTableConfig;
2420
+ case 'countries':
2421
+ return countriesTableConfig;
2422
+ case 'states':
2423
+ return statesTableConfig;
2424
+ case 'cities':
2425
+ return citiesTableConfig;
2426
+ case 'audit':
2427
+ return auditLogTableConfig;
2428
+ default:
2429
+ return parametersTableConfig;
2430
+ }
2431
+ };
2432
+
2433
+ /**
2434
+ * Theme-aware styles generator - Liquid Glass pattern
2435
+ *
2436
+ * Light theme: White semi-transparent overlay to keep background bright
2437
+ * Dark theme: Dark overlay for contrast
2438
+ */
2439
+ function getStyles(isDark) {
2440
+ return {
2441
+ // Overlay behind the modal
2442
+ overlay: {
2443
+ position: 'fixed',
2444
+ inset: 0,
2445
+ zIndex: 9999,
2446
+ display: 'flex',
2447
+ alignItems: 'center',
2448
+ justifyContent: 'center',
2449
+ padding: 20,
2450
+ // Light theme: white overlay to keep brightness
2451
+ // Dark theme: dark overlay for contrast
2452
+ backgroundColor: isDark ? 'rgba(0, 0, 0, 0.6)' : 'rgba(255, 255, 255, 0.4)',
2453
+ backdropFilter: 'blur(8px)',
2454
+ WebkitBackdropFilter: 'blur(8px)',
2455
+ },
2456
+ // Modal card - Liquid Glass
2457
+ card: {
2458
+ position: 'relative',
2459
+ maxWidth: 640,
2460
+ width: '100%',
2461
+ borderRadius: 24,
2462
+ overflow: 'hidden',
2463
+ // Light theme: Liquid Glass transparency
2464
+ // Dark theme: subtle glass effect
2465
+ background: isDark
2466
+ ? 'rgba(255, 255, 255, 0.03)'
2467
+ : 'rgba(255, 255, 255, 0.55)',
2468
+ // Liquid Glass: Strong blur + saturation
2469
+ backdropFilter: 'blur(var(--mds-liquid-blur-xl, 24px)) saturate(var(--mds-liquid-saturate-vibrant, 140%))',
2470
+ WebkitBackdropFilter: 'blur(var(--mds-liquid-blur-xl, 24px)) saturate(var(--mds-liquid-saturate-vibrant, 140%))',
2471
+ // Liquid Glass: Subtle border for edge definition
2472
+ border: isDark
2473
+ ? '1px solid rgba(255, 255, 255, 0.08)'
2474
+ : '1px solid rgba(255, 255, 255, 0.9)',
2475
+ // Liquid Glass: Layered shadows + inner glow
2476
+ boxShadow: isDark
2477
+ ? 'var(--mds-liquid-shadow-elevated, 0 12px 40px rgba(0, 0, 0, 0.3)), var(--mds-liquid-glow-edge, inset 0 1px 0 rgba(255, 255, 255, 0.1))'
2478
+ : '0 8px 32px rgba(0, 0, 0, 0.08), inset 0 1px 0 rgba(255, 255, 255, 1)',
2479
+ // Liquid Glass: Smooth transition
2480
+ transition: 'var(--mds-liquid-transition, all 0.25s cubic-bezier(0.25, 0.1, 0.25, 1))',
2481
+ },
2482
+ };
2483
+ }
2484
+ function Modal({ open, onClose, closeOnOverlay = true, children, className, style }) {
2485
+ const [mounted, setMounted] = useState(false);
2486
+ const [visible, setVisible] = useState(false);
2487
+ const [renderPortal, setRenderPortal] = useState(false);
2488
+ const [isDarkTheme, setIsDarkTheme] = useState(true);
2489
+ const containerRef = useRef(null);
2490
+ useEffect(() => setMounted(true), []);
2491
+ // Detect theme - EXACT same pattern as ProfileCard.tsx
2492
+ useEffect(() => {
2493
+ const checkTheme = () => {
2494
+ const theme = document.documentElement.getAttribute('data-theme');
2495
+ setIsDarkTheme(theme !== 'light');
2496
+ };
2497
+ checkTheme();
2498
+ // Watch for theme changes
2499
+ const observer = new MutationObserver((mutations) => {
2500
+ mutations.forEach((mutation) => {
2501
+ if (mutation.attributeName === 'data-theme') {
2502
+ checkTheme();
2503
+ }
2504
+ });
2505
+ });
2506
+ observer.observe(document.documentElement, { attributes: true });
2507
+ return () => observer.disconnect();
2508
+ }, []);
2509
+ useEffect(() => {
2510
+ if (!mounted)
2511
+ return;
2512
+ if (open) {
2513
+ setVisible(true);
2514
+ setRenderPortal(true);
2515
+ }
2516
+ else {
2517
+ setVisible(false);
2518
+ const t = setTimeout(() => setRenderPortal(false), 200);
2519
+ return () => clearTimeout(t);
2520
+ }
2521
+ }, [open, mounted]);
2522
+ useEffect(() => {
2523
+ if (!open)
2524
+ return;
2525
+ const onKeyDown = (e) => {
2526
+ if (e.key === 'Escape')
2527
+ onClose();
2528
+ };
2529
+ document.addEventListener('keydown', onKeyDown);
2530
+ return () => document.removeEventListener('keydown', onKeyDown);
2531
+ }, [open, onClose]);
2532
+ if (!mounted || (!renderPortal && !open))
2533
+ return null;
2534
+ // Get theme-aware styles (same pattern as ProfileCard)
2535
+ const styles = getStyles(isDarkTheme);
2536
+ const overlayStyle = {
2537
+ ...styles.overlay,
2538
+ opacity: visible ? 1 : 0,
2539
+ transition: 'opacity 200ms ease',
2540
+ };
2541
+ const cardStyle = {
2542
+ ...styles.card,
2543
+ transform: visible ? 'scale(1)' : 'scale(0.96)',
2544
+ opacity: visible ? 1 : 0,
2545
+ transition: 'opacity 200ms ease, transform 200ms cubic-bezier(0.4, 0, 0.2, 1)',
2546
+ ...style,
2547
+ };
2548
+ const content = (jsxRuntimeExports.jsx("div", { className: "modal-overlay mds-modal-overlay", style: overlayStyle, onClick: closeOnOverlay ? onClose : undefined, "aria-modal": "true", role: "dialog", children: jsxRuntimeExports.jsx("div", { className: className, style: cardStyle, onClick: (e) => e.stopPropagation(), ref: (el) => (containerRef.current = el), children: children }) }));
2549
+ return createPortal(content, document.body);
2550
+ }
2551
+
2552
+ function ModalHeader({ title, icon, onClose, closeAriaLabel = 'Fechar', align = 'center' }) {
2553
+ const CloseIcon = (jsxRuntimeExports.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": true, children: jsxRuntimeExports.jsx("path", { d: "M18.3 5.71a1 1 0 00-1.41 0L12 10.59 7.11 5.7A1 1 0 105.7 7.11L10.59 12l-4.9 4.89a1 1 0 101.42 1.42L12 13.41l4.89 4.9a1 1 0 001.42-1.42L13.41 12l4.9-4.89a1 1 0 000-1.4z" }) }));
2554
+ if (align === 'center') {
2555
+ const iconBox = {
2556
+ position: 'absolute',
2557
+ left: 16,
2558
+ top: '50%',
2559
+ transform: 'translateY(-50%)',
2560
+ width: 32,
2561
+ height: 32,
2562
+ display: 'inline-flex',
2563
+ alignItems: 'center',
2564
+ justifyContent: 'center',
2565
+ fontSize: '1.25rem',
2566
+ lineHeight: 0
2567
+ };
2568
+ const closeBox = {
2569
+ position: 'absolute',
2570
+ right: 16,
2571
+ top: '50%',
2572
+ transform: 'translateY(-50%)',
2573
+ width: 32,
2574
+ height: 32,
2575
+ display: 'inline-flex',
2576
+ alignItems: 'center',
2577
+ justifyContent: 'center',
2578
+ background: 'transparent',
2579
+ border: 'none',
2580
+ padding: 0,
2581
+ cursor: 'pointer',
2582
+ lineHeight: 0
2583
+ };
2584
+ return (jsxRuntimeExports.jsxs("div", { className: "mds-modal-header", style: {
2585
+ position: 'relative',
2586
+ padding: '16px 24px',
2587
+ marginBottom: 16,
2588
+ borderBottom: '1px solid var(--border-color)'
2589
+ }, children: [icon && (jsxRuntimeExports.jsx("div", { "aria-hidden": true, style: iconBox, children: icon })), jsxRuntimeExports.jsx("div", { style: { textAlign: 'center' }, children: typeof title === 'string' ? (jsxRuntimeExports.jsx("h3", { style: { margin: 0 }, children: title })) : (title) }), onClose && (jsxRuntimeExports.jsx("button", { type: "button", "aria-label": closeAriaLabel, onClick: onClose, style: closeBox, children: CloseIcon }))] }));
2590
+ }
2591
+ return (jsxRuntimeExports.jsxs("div", { className: "mds-modal-header", style: {
2592
+ display: 'flex',
2593
+ alignItems: 'center',
2594
+ gap: 12,
2595
+ padding: '16px 24px',
2596
+ marginBottom: 16,
2597
+ borderBottom: '1px solid var(--border-color)'
2598
+ }, children: [icon && (jsxRuntimeExports.jsx("div", { "aria-hidden": true, style: { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: 32, height: 32, fontSize: '1.25rem', lineHeight: 0 }, children: icon })), jsxRuntimeExports.jsx("div", { style: { margin: 0, fontSize: '1.125rem', fontWeight: 600, flex: 1 }, children: typeof title === 'string' ? (jsxRuntimeExports.jsx("h3", { style: { margin: 0 }, children: title })) : (title) }), onClose && (jsxRuntimeExports.jsx("button", { type: "button", "aria-label": closeAriaLabel, onClick: onClose, style: { marginLeft: 'auto', background: 'transparent', border: 'none', width: 32, height: 32, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', lineHeight: 0 }, children: CloseIcon }))] }));
2599
+ }
2600
+
2601
+ function ModalBody({ children, style, className }) {
2602
+ return (jsxRuntimeExports.jsx("div", { className: className, style: { padding: '16px 24px', ...style }, children: children }));
2603
+ }
2604
+
2605
+ function ModalFooter({ children, align = 'end' }) {
2606
+ const justify = align === 'start' ? 'flex-start' : align === 'center' ? 'center' : 'flex-end';
2607
+ return (jsxRuntimeExports.jsx("div", { style: { display: 'flex', gap: 12, justifyContent: justify, borderTop: '1px solid var(--border-color)', padding: '16px 24px', marginTop: 8 }, children: children }));
2608
+ }
2609
+
2610
+ const IconWarning = (jsxRuntimeExports.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": true, children: jsxRuntimeExports.jsx("path", { d: "M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z" }) }));
2611
+ const IconDanger = (jsxRuntimeExports.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": true, children: jsxRuntimeExports.jsx("path", { d: "M12 2a10 10 0 100 20 10 10 0 000-20zm-1 5h2v8h-2V7zm0 10h2v2h-2v-2z" }) }));
2612
+ const IconInfo = (jsxRuntimeExports.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": true, children: jsxRuntimeExports.jsx("path", { d: "M11 9h2V7h-2v2zm0 8h2v-6h-2v6zm1-15a10 10 0 100 20 10 10 0 000-20z" }) }));
2613
+ const IconSuccess = (jsxRuntimeExports.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": true, children: jsxRuntimeExports.jsx("path", { d: "M12 2a10 10 0 100 20 10 10 0 000-20zm-1 14l-4-4 1.41-1.41L11 12.17l4.59-4.58L17 9l-6 7z" }) }));
2614
+ const toneIcon = {
2615
+ warning: IconWarning,
2616
+ danger: IconDanger,
2617
+ info: IconInfo,
2618
+ success: IconSuccess
2619
+ };
2620
+ function ConfirmDialog({ open, onClose, title, description, confirmText = 'Confirmar', cancelText = 'Cancelar', onConfirm, loading = false, tone = 'warning', icon, disableOverlayClose }) {
2621
+ return (jsxRuntimeExports.jsx(Modal, { open: open, onClose: onClose, closeOnOverlay: !disableOverlayClose, children: jsxRuntimeExports.jsxs("div", { className: "mds-modal-card", style: { maxWidth: 480, width: '100%' }, children: [jsxRuntimeExports.jsx(ModalHeader, { title: title, icon: icon ?? toneIcon[tone], onClose: onClose, align: "center" }), description && (jsxRuntimeExports.jsx("div", { style: { padding: '0 24px 16px 24px' }, children: description })), jsxRuntimeExports.jsxs("div", { style: { display: 'flex', gap: 12, justifyContent: 'flex-end', borderTop: '1px solid var(--border-color)', padding: '16px 24px', marginTop: 8 }, children: [jsxRuntimeExports.jsx("button", { type: "button", onClick: onClose, className: "mds-button mds-button--secondary", children: cancelText }), jsxRuntimeExports.jsx("button", { type: "button", onClick: onConfirm, disabled: loading, className: "mds-button mds-button--primary", children: loading ? 'Processando...' : confirmText })] })] }) }));
2622
+ }
2623
+
2624
+ export { ActionIcons, BrandLogo, Button, CellRenderers, ConfirmDialog, DataTable, GlassCard, Modal, ModalBody, ModalFooter, ModalHeader, Select, TableHeader, TableRow, ThemeToggle, Typography, auditLogTableConfig, citiesTableConfig, cn, countriesTableConfig, getTableConfig, parametersTableConfig, regionsTableConfig, statesTableConfig };
1492
2625
  //# sourceMappingURL=index.esm.js.map