@metropolle/design-system 1.2025.1-2.29.949 → 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 +338 -123
- 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 +315 -32
- package/dist/react/index.esm.js.map +1 -1
- package/dist/react/index.js +314 -31
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
package/dist/react/index.js
CHANGED
|
@@ -1522,22 +1522,241 @@ const LoadingSpinner = () => (jsxRuntimeExports.jsxs("svg", { className: "mds-sp
|
|
|
1522
1522
|
/**
|
|
1523
1523
|
* Select Component (Design System)
|
|
1524
1524
|
*
|
|
1525
|
-
*
|
|
1526
|
-
*
|
|
1527
|
-
*
|
|
1528
|
-
*
|
|
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
|
+
* ```
|
|
1529
1541
|
*/
|
|
1530
|
-
const Select = require$$0.forwardRef(({ options,
|
|
1531
|
-
const
|
|
1532
|
-
const
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
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] }));
|
|
1541
1760
|
});
|
|
1542
1761
|
Select.displayName = 'Select';
|
|
1543
1762
|
|
|
@@ -2213,12 +2432,82 @@ const getTableConfig = (type) => {
|
|
|
2213
2432
|
}
|
|
2214
2433
|
};
|
|
2215
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
|
+
}
|
|
2216
2486
|
function Modal({ open, onClose, closeOnOverlay = true, children, className, style }) {
|
|
2217
2487
|
const [mounted, setMounted] = require$$0.useState(false);
|
|
2218
2488
|
const [visible, setVisible] = require$$0.useState(false);
|
|
2219
2489
|
const [renderPortal, setRenderPortal] = require$$0.useState(false);
|
|
2490
|
+
const [isDarkTheme, setIsDarkTheme] = require$$0.useState(true);
|
|
2220
2491
|
const containerRef = require$$0.useRef(null);
|
|
2221
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
|
+
}, []);
|
|
2222
2511
|
require$$0.useEffect(() => {
|
|
2223
2512
|
if (!mounted)
|
|
2224
2513
|
return;
|
|
@@ -2244,27 +2533,21 @@ function Modal({ open, onClose, closeOnOverlay = true, children, className, styl
|
|
|
2244
2533
|
}, [open, onClose]);
|
|
2245
2534
|
if (!mounted || (!renderPortal && !open))
|
|
2246
2535
|
return null;
|
|
2536
|
+
// Get theme-aware styles (same pattern as ProfileCard)
|
|
2537
|
+
const styles = getStyles(isDarkTheme);
|
|
2247
2538
|
const overlayStyle = {
|
|
2248
|
-
|
|
2249
|
-
inset: 0,
|
|
2250
|
-
backgroundColor: 'rgba(0, 0, 0, 0.7)',
|
|
2251
|
-
display: 'flex',
|
|
2252
|
-
alignItems: 'center',
|
|
2253
|
-
justifyContent: 'center',
|
|
2254
|
-
zIndex: 1000,
|
|
2255
|
-
padding: '16px',
|
|
2539
|
+
...styles.overlay,
|
|
2256
2540
|
opacity: visible ? 1 : 0,
|
|
2257
|
-
transition: 'opacity 200ms ease'
|
|
2541
|
+
transition: 'opacity 200ms ease',
|
|
2258
2542
|
};
|
|
2259
|
-
const
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
transform: visible ? 'scale(1)' : 'scale(0.98)',
|
|
2543
|
+
const cardStyle = {
|
|
2544
|
+
...styles.card,
|
|
2545
|
+
transform: visible ? 'scale(1)' : 'scale(0.96)',
|
|
2263
2546
|
opacity: visible ? 1 : 0,
|
|
2264
|
-
transition: 'opacity 200ms ease, transform 200ms
|
|
2265
|
-
...style
|
|
2547
|
+
transition: 'opacity 200ms ease, transform 200ms cubic-bezier(0.4, 0, 0.2, 1)',
|
|
2548
|
+
...style,
|
|
2266
2549
|
};
|
|
2267
|
-
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 }) }));
|
|
2268
2551
|
return reactDom.createPortal(content, document.body);
|
|
2269
2552
|
}
|
|
2270
2553
|
|