@metropolle/design-system 1.2025.1-2.5.1903 → 1.2026.0-1.1.1728
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/css/components.css +414 -126
- package/dist/css/liquid-glass.css +468 -0
- package/dist/react/components/react/GlassCard/GlassCard.d.ts +46 -6
- package/dist/react/components/react/GlassCard/GlassCard.d.ts.map +1 -1
- package/dist/react/components/react/Modal/Modal.d.ts.map +1 -1
- package/dist/react/components/react/Select/Select.d.ts +61 -10
- package/dist/react/components/react/Select/Select.d.ts.map +1 -1
- package/dist/react/components/react/index.d.ts +1 -1
- package/dist/react/components/react/index.d.ts.map +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.esm.js +352 -42
- package/dist/react/index.esm.js.map +1 -1
- package/dist/react/index.js +351 -41
- package/dist/react/index.js.map +1 -1
- package/package.json +4 -2
package/dist/react/index.js
CHANGED
|
@@ -1372,12 +1372,35 @@ function cn(...classes) {
|
|
|
1372
1372
|
/**
|
|
1373
1373
|
* Glass Card Component
|
|
1374
1374
|
*
|
|
1375
|
-
* Componente de cartão com efeito glassmorphism
|
|
1376
|
-
*
|
|
1375
|
+
* Componente de cartão com efeito glassmorphism ou Liquid Glass (iOS 26 style).
|
|
1376
|
+
*
|
|
1377
|
+
* @example
|
|
1378
|
+
* ```tsx
|
|
1379
|
+
* // Liquid Glass (novo padrão)
|
|
1380
|
+
* <GlassCard glassStyle="liquid" intensity="md">
|
|
1381
|
+
* Content here
|
|
1382
|
+
* </GlassCard>
|
|
1383
|
+
*
|
|
1384
|
+
* // Glassmorphism tradicional (retrocompatível)
|
|
1385
|
+
* <GlassCard glassStyle="glass" variant="dark">
|
|
1386
|
+
* Content here
|
|
1387
|
+
* </GlassCard>
|
|
1388
|
+
* ```
|
|
1377
1389
|
*/
|
|
1378
|
-
const GlassCard = require$$0.forwardRef(({
|
|
1390
|
+
const GlassCard = require$$0.forwardRef(({ glassStyle = 'liquid', intensity = 'md', theme, variant = 'light', blur, opacity, children, className, enableHover = true, style, ...props }, ref) => {
|
|
1391
|
+
// Resolve theme from new prop or deprecated variant
|
|
1392
|
+
const resolvedTheme = theme ?? variant;
|
|
1393
|
+
// =====================
|
|
1394
|
+
// LIQUID GLASS MODE
|
|
1395
|
+
// =====================
|
|
1396
|
+
if (glassStyle === 'liquid') {
|
|
1397
|
+
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 }));
|
|
1398
|
+
}
|
|
1399
|
+
// =====================
|
|
1400
|
+
// GLASS MODE (legacy)
|
|
1401
|
+
// =====================
|
|
1379
1402
|
// Default opacities baseadas no design existente
|
|
1380
|
-
const defaultOpacity =
|
|
1403
|
+
const defaultOpacity = resolvedTheme === 'light' ? 0.15 : 0.8;
|
|
1381
1404
|
const finalOpacity = opacity ?? defaultOpacity;
|
|
1382
1405
|
// Use CSS classes for base styles to avoid hydration mismatches
|
|
1383
1406
|
const baseStyles = {
|
|
@@ -1385,12 +1408,16 @@ const GlassCard = require$$0.forwardRef(({ variant = 'light', blur = 20, opacity
|
|
|
1385
1408
|
};
|
|
1386
1409
|
// Only apply custom styles for non-default values
|
|
1387
1410
|
const customStyles = {};
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1411
|
+
// Support legacy blur prop or convert from intensity
|
|
1412
|
+
const resolvedBlur = blur ?? (intensity ? {
|
|
1413
|
+
xs: 2, sm: 4, md: 6, lg: 8, xl: 12
|
|
1414
|
+
}[intensity] : 20);
|
|
1415
|
+
if (resolvedBlur !== 20) {
|
|
1416
|
+
customStyles.backdropFilter = `blur(${resolvedBlur}px)`;
|
|
1417
|
+
customStyles.WebkitBackdropFilter = `blur(${resolvedBlur}px)`;
|
|
1391
1418
|
}
|
|
1392
1419
|
if (opacity !== undefined) {
|
|
1393
|
-
customStyles.background =
|
|
1420
|
+
customStyles.background = resolvedTheme === 'light'
|
|
1394
1421
|
? `rgba(255, 255, 255, ${finalOpacity})`
|
|
1395
1422
|
: `rgba(60, 60, 60, ${finalOpacity})`;
|
|
1396
1423
|
}
|
|
@@ -1405,7 +1432,7 @@ const GlassCard = require$$0.forwardRef(({ variant = 'light', blur = 20, opacity
|
|
|
1405
1432
|
borderColor: 'rgba(255, 255, 255, 0.2)',
|
|
1406
1433
|
background: opacity !== undefined ? `rgba(70, 70, 70, ${finalOpacity})` : undefined,
|
|
1407
1434
|
}
|
|
1408
|
-
}[
|
|
1435
|
+
}[resolvedTheme] : {};
|
|
1409
1436
|
const handleMouseEnter = (e) => {
|
|
1410
1437
|
if (!enableHover)
|
|
1411
1438
|
return;
|
|
@@ -1423,7 +1450,7 @@ const GlassCard = require$$0.forwardRef(({ variant = 'light', blur = 20, opacity
|
|
|
1423
1450
|
});
|
|
1424
1451
|
props.onMouseLeave?.(e);
|
|
1425
1452
|
};
|
|
1426
|
-
return (jsxRuntimeExports.jsx("div", { ref: ref, className: cn('mds-glass-card', `mds-glass-card--${
|
|
1453
|
+
return (jsxRuntimeExports.jsx("div", { ref: ref, className: cn('mds-glass-card', `mds-glass-card--${resolvedTheme}`, !enableHover && 'mds-glass-card--no-hover', className), style: {
|
|
1427
1454
|
...baseStyles,
|
|
1428
1455
|
...customStyles,
|
|
1429
1456
|
...style
|
|
@@ -1495,22 +1522,241 @@ const LoadingSpinner = () => (jsxRuntimeExports.jsxs("svg", { className: "mds-sp
|
|
|
1495
1522
|
/**
|
|
1496
1523
|
* Select Component (Design System)
|
|
1497
1524
|
*
|
|
1498
|
-
*
|
|
1499
|
-
*
|
|
1500
|
-
*
|
|
1501
|
-
*
|
|
1525
|
+
* Custom dropdown select that renders consistently across all browsers.
|
|
1526
|
+
* Unlike native <select>, this component renders the dropdown via JavaScript,
|
|
1527
|
+
* ensuring proper theming support on Edge/Chrome Windows.
|
|
1528
|
+
*
|
|
1529
|
+
* @example
|
|
1530
|
+
* ```tsx
|
|
1531
|
+
* <Select
|
|
1532
|
+
* options={[
|
|
1533
|
+
* { label: 'Option 1', value: '1' },
|
|
1534
|
+
* { label: 'Option 2', value: '2' },
|
|
1535
|
+
* ]}
|
|
1536
|
+
* value={selectedValue}
|
|
1537
|
+
* onChange={setSelectedValue}
|
|
1538
|
+
* placeholder="Select an option..."
|
|
1539
|
+
* />
|
|
1540
|
+
* ```
|
|
1502
1541
|
*/
|
|
1503
|
-
const Select = require$$0.forwardRef(({ options,
|
|
1504
|
-
const
|
|
1505
|
-
const
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1542
|
+
const Select = require$$0.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) => {
|
|
1543
|
+
const [isOpen, setIsOpen] = require$$0.useState(false);
|
|
1544
|
+
const [searchTerm, setSearchTerm] = require$$0.useState('');
|
|
1545
|
+
const [highlightedIndex, setHighlightedIndex] = require$$0.useState(-1);
|
|
1546
|
+
const [mounted, setMounted] = require$$0.useState(false);
|
|
1547
|
+
const triggerRef = require$$0.useRef(null);
|
|
1548
|
+
const dropdownRef = require$$0.useRef(null);
|
|
1549
|
+
const searchInputRef = require$$0.useRef(null);
|
|
1550
|
+
const listRef = require$$0.useRef(null);
|
|
1551
|
+
// Combine refs
|
|
1552
|
+
const combinedRef = (el) => {
|
|
1553
|
+
triggerRef.current = el;
|
|
1554
|
+
if (typeof ref === 'function') {
|
|
1555
|
+
ref(el);
|
|
1556
|
+
}
|
|
1557
|
+
else if (ref) {
|
|
1558
|
+
ref.current = el;
|
|
1559
|
+
}
|
|
1560
|
+
};
|
|
1561
|
+
// Client-side only
|
|
1562
|
+
require$$0.useEffect(() => {
|
|
1563
|
+
setMounted(true);
|
|
1564
|
+
}, []);
|
|
1565
|
+
// Filter options based on search
|
|
1566
|
+
const filteredOptions = require$$0.useMemo(() => {
|
|
1567
|
+
if (!searchTerm)
|
|
1568
|
+
return options;
|
|
1569
|
+
const term = searchTerm.toLowerCase();
|
|
1570
|
+
return options.filter(opt => {
|
|
1571
|
+
const label = typeof opt.label === 'string' ? opt.label : String(opt.value);
|
|
1572
|
+
return label.toLowerCase().includes(term);
|
|
1573
|
+
});
|
|
1574
|
+
}, [options, searchTerm]);
|
|
1575
|
+
// Get selected option label
|
|
1576
|
+
const selectedOption = require$$0.useMemo(() => {
|
|
1577
|
+
return options.find(opt => opt.value === value);
|
|
1578
|
+
}, [options, value]);
|
|
1579
|
+
// Handle dropdown positioning
|
|
1580
|
+
const [dropdownPosition, setDropdownPosition] = require$$0.useState({ top: 0, left: 0, width: 0 });
|
|
1581
|
+
const updateDropdownPosition = require$$0.useCallback(() => {
|
|
1582
|
+
if (!triggerRef.current)
|
|
1583
|
+
return;
|
|
1584
|
+
const rect = triggerRef.current.getBoundingClientRect();
|
|
1585
|
+
const viewportHeight = window.innerHeight;
|
|
1586
|
+
const spaceBelow = viewportHeight - rect.bottom;
|
|
1587
|
+
const spaceAbove = rect.top;
|
|
1588
|
+
// Determine if dropdown should open above or below
|
|
1589
|
+
const dropdownHeight = Math.min(maxHeight, filteredOptions.length * 40 + (searchable ? 48 : 0));
|
|
1590
|
+
const openAbove = spaceBelow < dropdownHeight && spaceAbove > spaceBelow;
|
|
1591
|
+
setDropdownPosition({
|
|
1592
|
+
top: openAbove ? rect.top - dropdownHeight : rect.bottom + 4,
|
|
1593
|
+
left: rect.left,
|
|
1594
|
+
width: rect.width,
|
|
1595
|
+
});
|
|
1596
|
+
}, [maxHeight, filteredOptions.length, searchable]);
|
|
1597
|
+
// Open dropdown
|
|
1598
|
+
const openDropdown = require$$0.useCallback(() => {
|
|
1599
|
+
if (disabled || loading)
|
|
1600
|
+
return;
|
|
1601
|
+
updateDropdownPosition();
|
|
1602
|
+
setIsOpen(true);
|
|
1603
|
+
setSearchTerm('');
|
|
1604
|
+
setHighlightedIndex(value ? filteredOptions.findIndex(opt => opt.value === value) : 0);
|
|
1605
|
+
}, [disabled, loading, updateDropdownPosition, value, filteredOptions]);
|
|
1606
|
+
// Close dropdown
|
|
1607
|
+
const closeDropdown = require$$0.useCallback(() => {
|
|
1608
|
+
setIsOpen(false);
|
|
1609
|
+
setSearchTerm('');
|
|
1610
|
+
setHighlightedIndex(-1);
|
|
1611
|
+
triggerRef.current?.focus();
|
|
1612
|
+
}, []);
|
|
1613
|
+
// Handle option select
|
|
1614
|
+
const handleSelect = require$$0.useCallback((optionValue) => {
|
|
1615
|
+
// Safety check: ensure we're passing a string, not an object
|
|
1616
|
+
const safeValue = typeof optionValue === 'string' ? optionValue : String(optionValue);
|
|
1617
|
+
onChange?.(safeValue);
|
|
1618
|
+
closeDropdown();
|
|
1619
|
+
}, [onChange, closeDropdown]);
|
|
1620
|
+
// Keyboard navigation
|
|
1621
|
+
const handleKeyDown = require$$0.useCallback((e) => {
|
|
1622
|
+
if (disabled || loading)
|
|
1623
|
+
return;
|
|
1624
|
+
switch (e.key) {
|
|
1625
|
+
case 'Enter':
|
|
1626
|
+
case ' ':
|
|
1627
|
+
e.preventDefault();
|
|
1628
|
+
if (isOpen && highlightedIndex >= 0 && filteredOptions[highlightedIndex]) {
|
|
1629
|
+
const opt = filteredOptions[highlightedIndex];
|
|
1630
|
+
if (!opt.disabled) {
|
|
1631
|
+
handleSelect(opt.value);
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
else if (!isOpen) {
|
|
1635
|
+
openDropdown();
|
|
1636
|
+
}
|
|
1637
|
+
break;
|
|
1638
|
+
case 'ArrowDown':
|
|
1639
|
+
e.preventDefault();
|
|
1640
|
+
if (!isOpen) {
|
|
1641
|
+
openDropdown();
|
|
1642
|
+
}
|
|
1643
|
+
else {
|
|
1644
|
+
setHighlightedIndex(prev => {
|
|
1645
|
+
const next = prev + 1;
|
|
1646
|
+
return next >= filteredOptions.length ? 0 : next;
|
|
1647
|
+
});
|
|
1648
|
+
}
|
|
1649
|
+
break;
|
|
1650
|
+
case 'ArrowUp':
|
|
1651
|
+
e.preventDefault();
|
|
1652
|
+
if (isOpen) {
|
|
1653
|
+
setHighlightedIndex(prev => {
|
|
1654
|
+
const next = prev - 1;
|
|
1655
|
+
return next < 0 ? filteredOptions.length - 1 : next;
|
|
1656
|
+
});
|
|
1657
|
+
}
|
|
1658
|
+
break;
|
|
1659
|
+
case 'Escape':
|
|
1660
|
+
e.preventDefault();
|
|
1661
|
+
closeDropdown();
|
|
1662
|
+
break;
|
|
1663
|
+
case 'Tab':
|
|
1664
|
+
if (isOpen) {
|
|
1665
|
+
closeDropdown();
|
|
1666
|
+
}
|
|
1667
|
+
break;
|
|
1668
|
+
case 'Home':
|
|
1669
|
+
if (isOpen) {
|
|
1670
|
+
e.preventDefault();
|
|
1671
|
+
setHighlightedIndex(0);
|
|
1672
|
+
}
|
|
1673
|
+
break;
|
|
1674
|
+
case 'End':
|
|
1675
|
+
if (isOpen) {
|
|
1676
|
+
e.preventDefault();
|
|
1677
|
+
setHighlightedIndex(filteredOptions.length - 1);
|
|
1678
|
+
}
|
|
1679
|
+
break;
|
|
1680
|
+
}
|
|
1681
|
+
}, [disabled, loading, isOpen, highlightedIndex, filteredOptions, handleSelect, openDropdown, closeDropdown]);
|
|
1682
|
+
// Click outside to close
|
|
1683
|
+
require$$0.useEffect(() => {
|
|
1684
|
+
if (!isOpen)
|
|
1685
|
+
return;
|
|
1686
|
+
const handleClickOutside = (e) => {
|
|
1687
|
+
if (triggerRef.current?.contains(e.target) ||
|
|
1688
|
+
dropdownRef.current?.contains(e.target)) {
|
|
1689
|
+
return;
|
|
1690
|
+
}
|
|
1691
|
+
closeDropdown();
|
|
1692
|
+
};
|
|
1693
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
1694
|
+
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
1695
|
+
}, [isOpen, closeDropdown]);
|
|
1696
|
+
// Update position on scroll/resize
|
|
1697
|
+
require$$0.useEffect(() => {
|
|
1698
|
+
if (!isOpen)
|
|
1699
|
+
return;
|
|
1700
|
+
const handleUpdate = () => updateDropdownPosition();
|
|
1701
|
+
window.addEventListener('scroll', handleUpdate, true);
|
|
1702
|
+
window.addEventListener('resize', handleUpdate);
|
|
1703
|
+
return () => {
|
|
1704
|
+
window.removeEventListener('scroll', handleUpdate, true);
|
|
1705
|
+
window.removeEventListener('resize', handleUpdate);
|
|
1706
|
+
};
|
|
1707
|
+
}, [isOpen, updateDropdownPosition]);
|
|
1708
|
+
// Focus search input when dropdown opens
|
|
1709
|
+
require$$0.useEffect(() => {
|
|
1710
|
+
if (isOpen && searchable && searchInputRef.current) {
|
|
1711
|
+
searchInputRef.current.focus();
|
|
1712
|
+
}
|
|
1713
|
+
}, [isOpen, searchable]);
|
|
1714
|
+
// Scroll highlighted option into view
|
|
1715
|
+
require$$0.useEffect(() => {
|
|
1716
|
+
if (!isOpen || highlightedIndex < 0 || !listRef.current)
|
|
1717
|
+
return;
|
|
1718
|
+
const highlighted = listRef.current.children[highlightedIndex];
|
|
1719
|
+
if (highlighted) {
|
|
1720
|
+
highlighted.scrollIntoView({ block: 'nearest' });
|
|
1721
|
+
}
|
|
1722
|
+
}, [isOpen, highlightedIndex]);
|
|
1723
|
+
// Size classes
|
|
1724
|
+
const sizeClasses = {
|
|
1725
|
+
sm: 'mds-select--sm',
|
|
1726
|
+
md: 'mds-select--md',
|
|
1727
|
+
lg: 'mds-select--lg',
|
|
1728
|
+
};
|
|
1729
|
+
// Variant classes
|
|
1730
|
+
const variantClasses = {
|
|
1731
|
+
base: 'mds-select--base',
|
|
1732
|
+
themed: 'mds-select--themed',
|
|
1733
|
+
dashboard: 'mds-select--themed',
|
|
1734
|
+
};
|
|
1735
|
+
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);
|
|
1736
|
+
const dropdownClasses = cn('mds-select-dropdown', variantClasses[variant], dropdownClassName);
|
|
1737
|
+
// Hidden input for form submission
|
|
1738
|
+
const hiddenInput = name ? (jsxRuntimeExports.jsx("input", { type: "hidden", name: name, value: value || '' })) : null;
|
|
1739
|
+
// Dropdown portal content
|
|
1740
|
+
const dropdownContent = isOpen && mounted ? reactDom.createPortal(jsxRuntimeExports.jsxs("div", { ref: dropdownRef, className: dropdownClasses, style: {
|
|
1741
|
+
position: 'fixed',
|
|
1742
|
+
top: dropdownPosition.top,
|
|
1743
|
+
left: dropdownPosition.left,
|
|
1744
|
+
width: dropdownPosition.width,
|
|
1745
|
+
maxHeight,
|
|
1746
|
+
zIndex,
|
|
1747
|
+
}, 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) => {
|
|
1748
|
+
setSearchTerm(e.target.value);
|
|
1749
|
+
setHighlightedIndex(0);
|
|
1750
|
+
}, 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: () => {
|
|
1751
|
+
if (!option.disabled) {
|
|
1752
|
+
handleSelect(option.value);
|
|
1753
|
+
}
|
|
1754
|
+
}, onMouseEnter: () => {
|
|
1755
|
+
if (!option.disabled) {
|
|
1756
|
+
setHighlightedIndex(index);
|
|
1757
|
+
}
|
|
1758
|
+
}, 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;
|
|
1759
|
+
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] }));
|
|
1514
1760
|
});
|
|
1515
1761
|
Select.displayName = 'Select';
|
|
1516
1762
|
|
|
@@ -2186,12 +2432,82 @@ const getTableConfig = (type) => {
|
|
|
2186
2432
|
}
|
|
2187
2433
|
};
|
|
2188
2434
|
|
|
2435
|
+
/**
|
|
2436
|
+
* Theme-aware styles generator - Liquid Glass pattern
|
|
2437
|
+
*
|
|
2438
|
+
* Light theme: White semi-transparent overlay to keep background bright
|
|
2439
|
+
* Dark theme: Dark overlay for contrast
|
|
2440
|
+
*/
|
|
2441
|
+
function getStyles(isDark) {
|
|
2442
|
+
return {
|
|
2443
|
+
// Overlay behind the modal
|
|
2444
|
+
overlay: {
|
|
2445
|
+
position: 'fixed',
|
|
2446
|
+
inset: 0,
|
|
2447
|
+
zIndex: 9999,
|
|
2448
|
+
display: 'flex',
|
|
2449
|
+
alignItems: 'center',
|
|
2450
|
+
justifyContent: 'center',
|
|
2451
|
+
padding: 20,
|
|
2452
|
+
// Light theme: white overlay to keep brightness
|
|
2453
|
+
// Dark theme: dark overlay for contrast
|
|
2454
|
+
backgroundColor: isDark ? 'rgba(0, 0, 0, 0.6)' : 'rgba(255, 255, 255, 0.4)',
|
|
2455
|
+
backdropFilter: 'blur(8px)',
|
|
2456
|
+
WebkitBackdropFilter: 'blur(8px)',
|
|
2457
|
+
},
|
|
2458
|
+
// Modal card - Liquid Glass
|
|
2459
|
+
card: {
|
|
2460
|
+
position: 'relative',
|
|
2461
|
+
maxWidth: 640,
|
|
2462
|
+
width: '100%',
|
|
2463
|
+
borderRadius: 24,
|
|
2464
|
+
overflow: 'hidden',
|
|
2465
|
+
// Light theme: Liquid Glass transparency
|
|
2466
|
+
// Dark theme: subtle glass effect
|
|
2467
|
+
background: isDark
|
|
2468
|
+
? 'rgba(255, 255, 255, 0.03)'
|
|
2469
|
+
: 'rgba(255, 255, 255, 0.55)',
|
|
2470
|
+
// Liquid Glass: Strong blur + saturation
|
|
2471
|
+
backdropFilter: 'blur(var(--mds-liquid-blur-xl, 24px)) saturate(var(--mds-liquid-saturate-vibrant, 140%))',
|
|
2472
|
+
WebkitBackdropFilter: 'blur(var(--mds-liquid-blur-xl, 24px)) saturate(var(--mds-liquid-saturate-vibrant, 140%))',
|
|
2473
|
+
// Liquid Glass: Subtle border for edge definition
|
|
2474
|
+
border: isDark
|
|
2475
|
+
? '1px solid rgba(255, 255, 255, 0.08)'
|
|
2476
|
+
: '1px solid rgba(255, 255, 255, 0.9)',
|
|
2477
|
+
// Liquid Glass: Layered shadows + inner glow
|
|
2478
|
+
boxShadow: isDark
|
|
2479
|
+
? '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))'
|
|
2480
|
+
: '0 8px 32px rgba(0, 0, 0, 0.08), inset 0 1px 0 rgba(255, 255, 255, 1)',
|
|
2481
|
+
// Liquid Glass: Smooth transition
|
|
2482
|
+
transition: 'var(--mds-liquid-transition, all 0.25s cubic-bezier(0.25, 0.1, 0.25, 1))',
|
|
2483
|
+
},
|
|
2484
|
+
};
|
|
2485
|
+
}
|
|
2189
2486
|
function Modal({ open, onClose, closeOnOverlay = true, children, className, style }) {
|
|
2190
2487
|
const [mounted, setMounted] = require$$0.useState(false);
|
|
2191
2488
|
const [visible, setVisible] = require$$0.useState(false);
|
|
2192
2489
|
const [renderPortal, setRenderPortal] = require$$0.useState(false);
|
|
2490
|
+
const [isDarkTheme, setIsDarkTheme] = require$$0.useState(true);
|
|
2193
2491
|
const containerRef = require$$0.useRef(null);
|
|
2194
2492
|
require$$0.useEffect(() => setMounted(true), []);
|
|
2493
|
+
// Detect theme - EXACT same pattern as ProfileCard.tsx
|
|
2494
|
+
require$$0.useEffect(() => {
|
|
2495
|
+
const checkTheme = () => {
|
|
2496
|
+
const theme = document.documentElement.getAttribute('data-theme');
|
|
2497
|
+
setIsDarkTheme(theme !== 'light');
|
|
2498
|
+
};
|
|
2499
|
+
checkTheme();
|
|
2500
|
+
// Watch for theme changes
|
|
2501
|
+
const observer = new MutationObserver((mutations) => {
|
|
2502
|
+
mutations.forEach((mutation) => {
|
|
2503
|
+
if (mutation.attributeName === 'data-theme') {
|
|
2504
|
+
checkTheme();
|
|
2505
|
+
}
|
|
2506
|
+
});
|
|
2507
|
+
});
|
|
2508
|
+
observer.observe(document.documentElement, { attributes: true });
|
|
2509
|
+
return () => observer.disconnect();
|
|
2510
|
+
}, []);
|
|
2195
2511
|
require$$0.useEffect(() => {
|
|
2196
2512
|
if (!mounted)
|
|
2197
2513
|
return;
|
|
@@ -2217,27 +2533,21 @@ function Modal({ open, onClose, closeOnOverlay = true, children, className, styl
|
|
|
2217
2533
|
}, [open, onClose]);
|
|
2218
2534
|
if (!mounted || (!renderPortal && !open))
|
|
2219
2535
|
return null;
|
|
2536
|
+
// Get theme-aware styles (same pattern as ProfileCard)
|
|
2537
|
+
const styles = getStyles(isDarkTheme);
|
|
2220
2538
|
const overlayStyle = {
|
|
2221
|
-
|
|
2222
|
-
inset: 0,
|
|
2223
|
-
backgroundColor: 'rgba(0, 0, 0, 0.7)',
|
|
2224
|
-
display: 'flex',
|
|
2225
|
-
alignItems: 'center',
|
|
2226
|
-
justifyContent: 'center',
|
|
2227
|
-
zIndex: 1000,
|
|
2228
|
-
padding: '16px',
|
|
2539
|
+
...styles.overlay,
|
|
2229
2540
|
opacity: visible ? 1 : 0,
|
|
2230
|
-
transition: 'opacity 200ms ease'
|
|
2541
|
+
transition: 'opacity 200ms ease',
|
|
2231
2542
|
};
|
|
2232
|
-
const
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
transform: visible ? 'scale(1)' : 'scale(0.98)',
|
|
2543
|
+
const cardStyle = {
|
|
2544
|
+
...styles.card,
|
|
2545
|
+
transform: visible ? 'scale(1)' : 'scale(0.96)',
|
|
2236
2546
|
opacity: visible ? 1 : 0,
|
|
2237
|
-
transition: 'opacity 200ms ease, transform 200ms
|
|
2238
|
-
...style
|
|
2547
|
+
transition: 'opacity 200ms ease, transform 200ms cubic-bezier(0.4, 0, 0.2, 1)',
|
|
2548
|
+
...style,
|
|
2239
2549
|
};
|
|
2240
|
-
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:
|
|
2550
|
+
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 }) }));
|
|
2241
2551
|
return reactDom.createPortal(content, document.body);
|
|
2242
2552
|
}
|
|
2243
2553
|
|