@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.
Files changed (36) hide show
  1. package/README.md +1 -0
  2. package/dist/css/compat/back.css +466 -0
  3. package/dist/css/components.css +999 -3
  4. package/dist/css/mermaid.css +163 -0
  5. package/dist/css/tokens.css +53 -0
  6. package/dist/react/components/react/Modal/ConfirmDialog.d.ts +17 -0
  7. package/dist/react/components/react/Modal/ConfirmDialog.d.ts.map +1 -0
  8. package/dist/react/components/react/Modal/Modal.d.ts +12 -0
  9. package/dist/react/components/react/Modal/Modal.d.ts.map +1 -0
  10. package/dist/react/components/react/Modal/ModalBody.d.ts +9 -0
  11. package/dist/react/components/react/Modal/ModalBody.d.ts.map +1 -0
  12. package/dist/react/components/react/Modal/ModalFooter.d.ts +8 -0
  13. package/dist/react/components/react/Modal/ModalFooter.d.ts.map +1 -0
  14. package/dist/react/components/react/Modal/ModalHeader.d.ts +11 -0
  15. package/dist/react/components/react/Modal/ModalHeader.d.ts.map +1 -0
  16. package/dist/react/components/react/Modal/index.d.ts +6 -0
  17. package/dist/react/components/react/Modal/index.d.ts.map +1 -0
  18. package/dist/react/components/react/Select/Select.d.ts +20 -0
  19. package/dist/react/components/react/Select/Select.d.ts.map +1 -0
  20. package/dist/react/components/react/Select/index.d.ts +2 -0
  21. package/dist/react/components/react/Select/index.d.ts.map +1 -0
  22. package/dist/react/components/react/ThemeToggle/ThemeToggle.d.ts +28 -0
  23. package/dist/react/components/react/ThemeToggle/ThemeToggle.d.ts.map +1 -0
  24. package/dist/react/components/react/ThemeToggle/index.d.ts +3 -0
  25. package/dist/react/components/react/ThemeToggle/index.d.ts.map +1 -0
  26. package/dist/react/components/react/Typography/Typography.d.ts.map +1 -1
  27. package/dist/react/components/react/index.d.ts +9 -0
  28. package/dist/react/components/react/index.d.ts.map +1 -1
  29. package/dist/react/index.d.ts +17 -0
  30. package/dist/react/index.esm.js +224 -4
  31. package/dist/react/index.esm.js.map +1 -1
  32. package/dist/react/index.js +229 -2
  33. package/dist/react/index.js.map +1 -1
  34. package/dist/tokens/index.d.ts +19 -24
  35. package/dist/tokens/index.js +55 -2
  36. package/package.json +24 -14
@@ -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', className, children = 'Metropolle', ...props }, ref) => {
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
- export { BrandLogo, Button, GlassCard, Typography, cn };
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