@metropolle/design-system 1.0.0-beta.1 → 1.0.0-beta.2025.10.1.1541.d0d0b36
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/README.md +1 -0
- package/dist/css/compat/back.css +466 -0
- package/dist/css/components.css +999 -3
- package/dist/css/mermaid.css +163 -0
- package/dist/css/tokens.css +53 -0
- package/dist/react/components/react/Modal/ConfirmDialog.d.ts +17 -0
- package/dist/react/components/react/Modal/ConfirmDialog.d.ts.map +1 -0
- package/dist/react/components/react/Modal/Modal.d.ts +12 -0
- package/dist/react/components/react/Modal/Modal.d.ts.map +1 -0
- package/dist/react/components/react/Modal/ModalBody.d.ts +9 -0
- package/dist/react/components/react/Modal/ModalBody.d.ts.map +1 -0
- package/dist/react/components/react/Modal/ModalFooter.d.ts +8 -0
- package/dist/react/components/react/Modal/ModalFooter.d.ts.map +1 -0
- package/dist/react/components/react/Modal/ModalHeader.d.ts +11 -0
- package/dist/react/components/react/Modal/ModalHeader.d.ts.map +1 -0
- package/dist/react/components/react/Modal/index.d.ts +6 -0
- package/dist/react/components/react/Modal/index.d.ts.map +1 -0
- package/dist/react/components/react/Select/Select.d.ts +20 -0
- package/dist/react/components/react/Select/Select.d.ts.map +1 -0
- package/dist/react/components/react/Select/index.d.ts +2 -0
- package/dist/react/components/react/Select/index.d.ts.map +1 -0
- package/dist/react/components/react/ThemeToggle/ThemeToggle.d.ts +28 -0
- package/dist/react/components/react/ThemeToggle/ThemeToggle.d.ts.map +1 -0
- package/dist/react/components/react/ThemeToggle/index.d.ts +3 -0
- package/dist/react/components/react/ThemeToggle/index.d.ts.map +1 -0
- package/dist/react/components/react/Typography/Typography.d.ts.map +1 -1
- package/dist/react/components/react/index.d.ts +9 -0
- package/dist/react/components/react/index.d.ts.map +1 -1
- package/dist/react/index.d.ts +17 -0
- package/dist/react/index.esm.js +224 -4
- package/dist/react/index.esm.js.map +1 -1
- package/dist/react/index.js +229 -2
- package/dist/react/index.js.map +1 -1
- package/dist/tokens/index.d.ts +19 -24
- package/dist/tokens/index.js +55 -2
- package/package.json +24 -14
package/dist/react/index.esm.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import require$$0, { forwardRef } from 'react';
|
|
1
|
+
import require$$0, { forwardRef, useState, useEffect, useRef } from 'react';
|
|
2
|
+
import { createPortal } from 'react-dom';
|
|
2
3
|
|
|
3
4
|
var jsxRuntime = {exports: {}};
|
|
4
5
|
|
|
@@ -1458,13 +1459,14 @@ const Typography = forwardRef(({ variant = 'body', size, as, children, className
|
|
|
1458
1459
|
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
1460
|
});
|
|
1460
1461
|
Typography.displayName = 'Typography';
|
|
1461
|
-
const BrandLogo = forwardRef(({ size = 'md',
|
|
1462
|
+
const BrandLogo = forwardRef(({ size = 'md', weight = 'bold', // Peso bold por padrão para a marca
|
|
1463
|
+
className, children = 'Metropolle', ...props }, ref) => {
|
|
1462
1464
|
const sizeMap = {
|
|
1463
1465
|
sm: '2xl',
|
|
1464
1466
|
md: '4xl',
|
|
1465
1467
|
lg: '4xl', // Same as md but with different mobile behavior
|
|
1466
1468
|
};
|
|
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 }));
|
|
1469
|
+
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
1470
|
});
|
|
1469
1471
|
BrandLogo.displayName = 'BrandLogo';
|
|
1470
1472
|
|
|
@@ -1488,5 +1490,223 @@ Button.displayName = 'Button';
|
|
|
1488
1490
|
*/
|
|
1489
1491
|
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
1492
|
|
|
1491
|
-
|
|
1493
|
+
/**
|
|
1494
|
+
* Select Component (Design System)
|
|
1495
|
+
*
|
|
1496
|
+
* Provides a themed select element with multiple variants:
|
|
1497
|
+
* - `base`: Standard form select with mds-input styling
|
|
1498
|
+
* - `themed`: Generic themed select with dashboard control styling (recommended)
|
|
1499
|
+
* - `dashboard`: Legacy alias for themed variant (backward compatibility)
|
|
1500
|
+
*/
|
|
1501
|
+
const Select = forwardRef(({ options, children, className, containerClassName, variant = 'themed', ...rest }, ref) => {
|
|
1502
|
+
const isThemed = variant === 'themed' || variant === 'dashboard';
|
|
1503
|
+
const selectEl = (jsxRuntimeExports.jsx("select", { ref: ref, className: cn(isThemed
|
|
1504
|
+
? 'mds-select-themed'
|
|
1505
|
+
: 'mds-input mds-select', className), ...rest, children: options
|
|
1506
|
+
? options.map(opt => (jsxRuntimeExports.jsx("option", { value: opt.value, children: opt.label }, opt.value)))
|
|
1507
|
+
: children }));
|
|
1508
|
+
if (isThemed) {
|
|
1509
|
+
return (jsxRuntimeExports.jsx("div", { className: cn('mds-dropdown', containerClassName), children: selectEl }));
|
|
1510
|
+
}
|
|
1511
|
+
return selectEl;
|
|
1512
|
+
});
|
|
1513
|
+
Select.displayName = 'Select';
|
|
1514
|
+
|
|
1515
|
+
function ThemeToggle({ size = 'md', className = '', disabled = false, onChange, storageKey = 'theme' }) {
|
|
1516
|
+
const [theme, setTheme] = useState('dark');
|
|
1517
|
+
const [mounted, setMounted] = useState(false);
|
|
1518
|
+
// Initialize theme on mount
|
|
1519
|
+
useEffect(() => {
|
|
1520
|
+
try {
|
|
1521
|
+
if (typeof window !== 'undefined') {
|
|
1522
|
+
const savedTheme = localStorage.getItem(storageKey) || 'dark';
|
|
1523
|
+
setTheme(savedTheme);
|
|
1524
|
+
document.documentElement.setAttribute('data-theme', savedTheme);
|
|
1525
|
+
setMounted(true);
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
catch (err) {
|
|
1529
|
+
setTheme('dark');
|
|
1530
|
+
setMounted(true);
|
|
1531
|
+
}
|
|
1532
|
+
}, [storageKey]);
|
|
1533
|
+
// Listen to external theme changes
|
|
1534
|
+
useEffect(() => {
|
|
1535
|
+
if (typeof window !== 'undefined') {
|
|
1536
|
+
const updateTheme = () => {
|
|
1537
|
+
const currentTheme = document.documentElement.getAttribute('data-theme') || 'dark';
|
|
1538
|
+
setTheme(currentTheme);
|
|
1539
|
+
};
|
|
1540
|
+
const observer = new MutationObserver(() => {
|
|
1541
|
+
updateTheme();
|
|
1542
|
+
});
|
|
1543
|
+
observer.observe(document.documentElement, {
|
|
1544
|
+
attributes: true,
|
|
1545
|
+
attributeFilter: ['data-theme']
|
|
1546
|
+
});
|
|
1547
|
+
return () => observer.disconnect();
|
|
1548
|
+
}
|
|
1549
|
+
}, []);
|
|
1550
|
+
const toggleTheme = () => {
|
|
1551
|
+
if (disabled)
|
|
1552
|
+
return;
|
|
1553
|
+
try {
|
|
1554
|
+
const newTheme = theme === 'light' ? 'dark' : 'light';
|
|
1555
|
+
document.documentElement.setAttribute('data-theme', newTheme);
|
|
1556
|
+
localStorage.setItem(storageKey, newTheme);
|
|
1557
|
+
setTheme(newTheme);
|
|
1558
|
+
onChange?.(newTheme);
|
|
1559
|
+
}
|
|
1560
|
+
catch (err) {
|
|
1561
|
+
console.warn('Failed to toggle theme:', err);
|
|
1562
|
+
}
|
|
1563
|
+
};
|
|
1564
|
+
// Don't render until mounted (prevents hydration mismatch)
|
|
1565
|
+
if (!mounted) {
|
|
1566
|
+
return (jsxRuntimeExports.jsx("div", { className: `mds-theme-toggle mds-theme-toggle--${size} ${className}`, style: { opacity: 0.5 }, "aria-hidden": "true" }));
|
|
1567
|
+
}
|
|
1568
|
+
const isDark = theme === 'dark';
|
|
1569
|
+
const buttonStyle = isDark
|
|
1570
|
+
? {
|
|
1571
|
+
backgroundColor: 'rgba(0, 0, 0, 0.35)',
|
|
1572
|
+
border: '1px solid rgba(255, 255, 255, 0.18)',
|
|
1573
|
+
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.3)'
|
|
1574
|
+
}
|
|
1575
|
+
: undefined;
|
|
1576
|
+
const buttonClasses = [
|
|
1577
|
+
'mds-theme-toggle',
|
|
1578
|
+
`mds-theme-toggle--${size}`,
|
|
1579
|
+
className
|
|
1580
|
+
].filter(Boolean).join(' ');
|
|
1581
|
+
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 }));
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
function Modal({ open, onClose, closeOnOverlay = true, children, className, style }) {
|
|
1585
|
+
const [mounted, setMounted] = useState(false);
|
|
1586
|
+
const [visible, setVisible] = useState(false);
|
|
1587
|
+
const [renderPortal, setRenderPortal] = useState(false);
|
|
1588
|
+
const containerRef = useRef(null);
|
|
1589
|
+
useEffect(() => setMounted(true), []);
|
|
1590
|
+
useEffect(() => {
|
|
1591
|
+
if (!mounted)
|
|
1592
|
+
return;
|
|
1593
|
+
if (open) {
|
|
1594
|
+
setVisible(true);
|
|
1595
|
+
setRenderPortal(true);
|
|
1596
|
+
}
|
|
1597
|
+
else {
|
|
1598
|
+
setVisible(false);
|
|
1599
|
+
const t = setTimeout(() => setRenderPortal(false), 200);
|
|
1600
|
+
return () => clearTimeout(t);
|
|
1601
|
+
}
|
|
1602
|
+
}, [open, mounted]);
|
|
1603
|
+
useEffect(() => {
|
|
1604
|
+
if (!open)
|
|
1605
|
+
return;
|
|
1606
|
+
const onKeyDown = (e) => {
|
|
1607
|
+
if (e.key === 'Escape')
|
|
1608
|
+
onClose();
|
|
1609
|
+
};
|
|
1610
|
+
document.addEventListener('keydown', onKeyDown);
|
|
1611
|
+
return () => document.removeEventListener('keydown', onKeyDown);
|
|
1612
|
+
}, [open, onClose]);
|
|
1613
|
+
if (!mounted || (!renderPortal && !open))
|
|
1614
|
+
return null;
|
|
1615
|
+
const overlayStyle = {
|
|
1616
|
+
position: 'fixed',
|
|
1617
|
+
inset: 0,
|
|
1618
|
+
backgroundColor: 'rgba(0, 0, 0, 0.7)',
|
|
1619
|
+
display: 'flex',
|
|
1620
|
+
alignItems: 'center',
|
|
1621
|
+
justifyContent: 'center',
|
|
1622
|
+
zIndex: 1000,
|
|
1623
|
+
padding: '16px',
|
|
1624
|
+
opacity: visible ? 1 : 0,
|
|
1625
|
+
transition: 'opacity 200ms ease'
|
|
1626
|
+
};
|
|
1627
|
+
const innerStyle = {
|
|
1628
|
+
maxWidth: '640px',
|
|
1629
|
+
width: '100%',
|
|
1630
|
+
transform: visible ? 'scale(1)' : 'scale(0.98)',
|
|
1631
|
+
opacity: visible ? 1 : 0,
|
|
1632
|
+
transition: 'opacity 200ms ease, transform 200ms ease',
|
|
1633
|
+
...style
|
|
1634
|
+
};
|
|
1635
|
+
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: innerStyle, onClick: (e) => e.stopPropagation(), ref: (el) => (containerRef.current = el), children: children }) }));
|
|
1636
|
+
return createPortal(content, document.body);
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
function ModalHeader({ title, icon, onClose, closeAriaLabel = 'Fechar', align = 'center' }) {
|
|
1640
|
+
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" }) }));
|
|
1641
|
+
if (align === 'center') {
|
|
1642
|
+
const iconBox = {
|
|
1643
|
+
position: 'absolute',
|
|
1644
|
+
left: 16,
|
|
1645
|
+
top: '50%',
|
|
1646
|
+
transform: 'translateY(-50%)',
|
|
1647
|
+
width: 32,
|
|
1648
|
+
height: 32,
|
|
1649
|
+
display: 'inline-flex',
|
|
1650
|
+
alignItems: 'center',
|
|
1651
|
+
justifyContent: 'center',
|
|
1652
|
+
fontSize: '1.25rem',
|
|
1653
|
+
lineHeight: 0
|
|
1654
|
+
};
|
|
1655
|
+
const closeBox = {
|
|
1656
|
+
position: 'absolute',
|
|
1657
|
+
right: 16,
|
|
1658
|
+
top: '50%',
|
|
1659
|
+
transform: 'translateY(-50%)',
|
|
1660
|
+
width: 32,
|
|
1661
|
+
height: 32,
|
|
1662
|
+
display: 'inline-flex',
|
|
1663
|
+
alignItems: 'center',
|
|
1664
|
+
justifyContent: 'center',
|
|
1665
|
+
background: 'transparent',
|
|
1666
|
+
border: 'none',
|
|
1667
|
+
padding: 0,
|
|
1668
|
+
cursor: 'pointer',
|
|
1669
|
+
lineHeight: 0
|
|
1670
|
+
};
|
|
1671
|
+
return (jsxRuntimeExports.jsxs("div", { className: "mds-modal-header", style: {
|
|
1672
|
+
position: 'relative',
|
|
1673
|
+
padding: '16px 24px',
|
|
1674
|
+
marginBottom: 16,
|
|
1675
|
+
borderBottom: '1px solid var(--border-color)'
|
|
1676
|
+
}, 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 }))] }));
|
|
1677
|
+
}
|
|
1678
|
+
return (jsxRuntimeExports.jsxs("div", { className: "mds-modal-header", style: {
|
|
1679
|
+
display: 'flex',
|
|
1680
|
+
alignItems: 'center',
|
|
1681
|
+
gap: 12,
|
|
1682
|
+
padding: '16px 24px',
|
|
1683
|
+
marginBottom: 16,
|
|
1684
|
+
borderBottom: '1px solid var(--border-color)'
|
|
1685
|
+
}, 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 }))] }));
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
function ModalBody({ children, style, className }) {
|
|
1689
|
+
return (jsxRuntimeExports.jsx("div", { className: className, style: { padding: '16px 24px', ...style }, children: children }));
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1692
|
+
function ModalFooter({ children, align = 'end' }) {
|
|
1693
|
+
const justify = align === 'start' ? 'flex-start' : align === 'center' ? 'center' : 'flex-end';
|
|
1694
|
+
return (jsxRuntimeExports.jsx("div", { style: { display: 'flex', gap: 12, justifyContent: justify, borderTop: '1px solid var(--border-color)', padding: '16px 24px', marginTop: 8 }, children: children }));
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
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" }) }));
|
|
1698
|
+
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" }) }));
|
|
1699
|
+
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" }) }));
|
|
1700
|
+
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" }) }));
|
|
1701
|
+
const toneIcon = {
|
|
1702
|
+
warning: IconWarning,
|
|
1703
|
+
danger: IconDanger,
|
|
1704
|
+
info: IconInfo,
|
|
1705
|
+
success: IconSuccess
|
|
1706
|
+
};
|
|
1707
|
+
function ConfirmDialog({ open, onClose, title, description, confirmText = 'Confirmar', cancelText = 'Cancelar', onConfirm, loading = false, tone = 'warning', icon, disableOverlayClose }) {
|
|
1708
|
+
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 })] })] }) }));
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
export { BrandLogo, Button, ConfirmDialog, GlassCard, Modal, ModalBody, ModalFooter, ModalHeader, Select, ThemeToggle, Typography, cn };
|
|
1492
1712
|
//# sourceMappingURL=index.esm.js.map
|