@metropolle/design-system 1.0.0-beta.20250821024300.dfbe136 → 1.0.0-beta.2026.1.10.2327.6729fca
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 +478 -0
- package/dist/css/components.css +3638 -8
- package/dist/css/liquid-glass.css +468 -0
- package/dist/css/mermaid.css +163 -0
- package/dist/css/tokens.css +67 -0
- package/dist/react/components/react/Button/Button.d.ts +1 -1
- package/dist/react/components/react/Button/Button.d.ts.map +1 -1
- package/dist/react/components/react/DataTable/DataTable.d.ts +4 -0
- package/dist/react/components/react/DataTable/DataTable.d.ts.map +1 -0
- package/dist/react/components/react/DataTable/TableHeader.d.ts +4 -0
- package/dist/react/components/react/DataTable/TableHeader.d.ts.map +1 -0
- package/dist/react/components/react/DataTable/TableRow.d.ts +4 -0
- package/dist/react/components/react/DataTable/TableRow.d.ts.map +1 -0
- package/dist/react/components/react/DataTable/examples.d.ts +28 -0
- package/dist/react/components/react/DataTable/examples.d.ts.map +1 -0
- package/dist/react/components/react/DataTable/index.d.ts +7 -0
- package/dist/react/components/react/DataTable/index.d.ts.map +1 -0
- package/dist/react/components/react/DataTable/migration-example.d.ts +46 -0
- package/dist/react/components/react/DataTable/migration-example.d.ts.map +1 -0
- package/dist/react/components/react/DataTable/renderers.d.ts +24 -0
- package/dist/react/components/react/DataTable/renderers.d.ts.map +1 -0
- package/dist/react/components/react/DataTable/types.d.ts +58 -0
- package/dist/react/components/react/DataTable/types.d.ts.map +1 -0
- package/dist/react/components/react/DetailModal/DetailModal.d.ts +55 -0
- package/dist/react/components/react/DetailModal/DetailModal.d.ts.map +1 -0
- package/dist/react/components/react/DetailModal/index.d.ts +3 -0
- package/dist/react/components/react/DetailModal/index.d.ts.map +1 -0
- package/dist/react/components/react/FormField/FormField.d.ts +26 -0
- package/dist/react/components/react/FormField/FormField.d.ts.map +1 -0
- package/dist/react/components/react/FormField/index.d.ts +3 -0
- package/dist/react/components/react/FormField/index.d.ts.map +1 -0
- package/dist/react/components/react/FormGrid/FormGrid.d.ts +20 -0
- package/dist/react/components/react/FormGrid/FormGrid.d.ts.map +1 -0
- package/dist/react/components/react/FormGrid/index.d.ts +3 -0
- package/dist/react/components/react/FormGrid/index.d.ts.map +1 -0
- package/dist/react/components/react/FormModal/FormModal.d.ts +58 -0
- package/dist/react/components/react/FormModal/FormModal.d.ts.map +1 -0
- package/dist/react/components/react/FormModal/index.d.ts +3 -0
- package/dist/react/components/react/FormModal/index.d.ts.map +1 -0
- package/dist/react/components/react/FormSection/FormSection.d.ts +20 -0
- package/dist/react/components/react/FormSection/FormSection.d.ts.map +1 -0
- package/dist/react/components/react/FormSection/index.d.ts +3 -0
- package/dist/react/components/react/FormSection/index.d.ts.map +1 -0
- package/dist/react/components/react/GlassCard/GlassCard.d.ts +56 -6
- package/dist/react/components/react/GlassCard/GlassCard.d.ts.map +1 -1
- package/dist/react/components/react/GlassCard/index.d.ts +1 -1
- package/dist/react/components/react/GlassCard/index.d.ts.map +1 -1
- package/dist/react/components/react/InfoBox/InfoBox.d.ts +46 -0
- package/dist/react/components/react/InfoBox/InfoBox.d.ts.map +1 -0
- package/dist/react/components/react/InfoBox/index.d.ts +3 -0
- package/dist/react/components/react/InfoBox/index.d.ts.map +1 -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/ProfileCard/ProfileCard.d.ts +55 -0
- package/dist/react/components/react/ProfileCard/ProfileCard.d.ts.map +1 -0
- package/dist/react/components/react/ProfileCard/index.d.ts +3 -0
- package/dist/react/components/react/ProfileCard/index.d.ts.map +1 -0
- package/dist/react/components/react/Select/Select.d.ts +71 -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 +25 -0
- package/dist/react/components/react/index.d.ts.map +1 -1
- package/dist/react/index.d.ts +32 -7
- package/dist/react/index.esm.js +1586 -14
- package/dist/react/index.esm.js.map +1 -1
- package/dist/react/index.js +1611 -12
- package/dist/react/index.js.map +1 -1
- package/dist/tokens/colors.json +100 -18
- package/dist/tokens/index.d.ts +19 -24
- package/dist/tokens/index.js +69 -2
- package/dist/tokens/index.json +100 -18
- package/package.json +24 -13
package/dist/react/index.esm.js
CHANGED
|
@@ -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,47 @@ function cn(...classes) {
|
|
|
1369
1370
|
/**
|
|
1370
1371
|
* Glass Card Component
|
|
1371
1372
|
*
|
|
1372
|
-
* Componente de cartão com efeito glassmorphism
|
|
1373
|
-
*
|
|
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(({
|
|
1388
|
+
const GlassCard = forwardRef(({ glassStyle = 'liquid', intensity = 'md', theme, variant = 'light', blur, opacity, children, className, enableHover = true, cardVariant = 'default', 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
|
+
// PROC-007: Card variant styles
|
|
1396
|
+
const variantStyles = {
|
|
1397
|
+
default: {},
|
|
1398
|
+
highlight: {
|
|
1399
|
+
borderLeft: '4px solid var(--mds-color-brand-primary, #0055FF)',
|
|
1400
|
+
boxShadow: '0 4px 20px rgba(0, 85, 255, 0.15)'
|
|
1401
|
+
},
|
|
1402
|
+
subtle: {
|
|
1403
|
+
background: 'rgba(255, 255, 255, 0.02)',
|
|
1404
|
+
border: '1px solid rgba(255, 255, 255, 0.05)'
|
|
1405
|
+
}
|
|
1406
|
+
};
|
|
1407
|
+
return (jsxRuntimeExports.jsx("div", { ref: ref, className: cn('mds-liquid-glass', `mds-liquid-glass--${intensity}`, `mds-liquid-glass--${cardVariant}`, !enableHover && 'mds-liquid-glass--no-hover', className), style: { ...variantStyles[cardVariant], ...style }, ...props, children: children }));
|
|
1408
|
+
}
|
|
1409
|
+
// =====================
|
|
1410
|
+
// GLASS MODE (legacy)
|
|
1411
|
+
// =====================
|
|
1376
1412
|
// Default opacities baseadas no design existente
|
|
1377
|
-
const defaultOpacity =
|
|
1413
|
+
const defaultOpacity = resolvedTheme === 'light' ? 0.15 : 0.8;
|
|
1378
1414
|
const finalOpacity = opacity ?? defaultOpacity;
|
|
1379
1415
|
// Use CSS classes for base styles to avoid hydration mismatches
|
|
1380
1416
|
const baseStyles = {
|
|
@@ -1382,12 +1418,16 @@ const GlassCard = forwardRef(({ variant = 'light', blur = 20, opacity, children,
|
|
|
1382
1418
|
};
|
|
1383
1419
|
// Only apply custom styles for non-default values
|
|
1384
1420
|
const customStyles = {};
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1421
|
+
// Support legacy blur prop or convert from intensity
|
|
1422
|
+
const resolvedBlur = blur ?? (intensity ? {
|
|
1423
|
+
xs: 2, sm: 4, md: 6, lg: 8, xl: 12
|
|
1424
|
+
}[intensity] : 20);
|
|
1425
|
+
if (resolvedBlur !== 20) {
|
|
1426
|
+
customStyles.backdropFilter = `blur(${resolvedBlur}px)`;
|
|
1427
|
+
customStyles.WebkitBackdropFilter = `blur(${resolvedBlur}px)`;
|
|
1388
1428
|
}
|
|
1389
1429
|
if (opacity !== undefined) {
|
|
1390
|
-
customStyles.background =
|
|
1430
|
+
customStyles.background = resolvedTheme === 'light'
|
|
1391
1431
|
? `rgba(255, 255, 255, ${finalOpacity})`
|
|
1392
1432
|
: `rgba(60, 60, 60, ${finalOpacity})`;
|
|
1393
1433
|
}
|
|
@@ -1402,7 +1442,7 @@ const GlassCard = forwardRef(({ variant = 'light', blur = 20, opacity, children,
|
|
|
1402
1442
|
borderColor: 'rgba(255, 255, 255, 0.2)',
|
|
1403
1443
|
background: opacity !== undefined ? `rgba(70, 70, 70, ${finalOpacity})` : undefined,
|
|
1404
1444
|
}
|
|
1405
|
-
}[
|
|
1445
|
+
}[resolvedTheme] : {};
|
|
1406
1446
|
const handleMouseEnter = (e) => {
|
|
1407
1447
|
if (!enableHover)
|
|
1408
1448
|
return;
|
|
@@ -1420,7 +1460,7 @@ const GlassCard = forwardRef(({ variant = 'light', blur = 20, opacity, children,
|
|
|
1420
1460
|
});
|
|
1421
1461
|
props.onMouseLeave?.(e);
|
|
1422
1462
|
};
|
|
1423
|
-
return (jsxRuntimeExports.jsx("div", { ref: ref, className: cn('mds-glass-card', `mds-glass-card--${
|
|
1463
|
+
return (jsxRuntimeExports.jsx("div", { ref: ref, className: cn('mds-glass-card', `mds-glass-card--${resolvedTheme}`, !enableHover && 'mds-glass-card--no-hover', className), style: {
|
|
1424
1464
|
...baseStyles,
|
|
1425
1465
|
...customStyles,
|
|
1426
1466
|
...style
|
|
@@ -1428,6 +1468,125 @@ const GlassCard = forwardRef(({ variant = 'light', blur = 20, opacity, children,
|
|
|
1428
1468
|
});
|
|
1429
1469
|
GlassCard.displayName = 'GlassCard';
|
|
1430
1470
|
|
|
1471
|
+
// Default placeholder avatar - adapts to theme with high transparency
|
|
1472
|
+
const getPlaceholderAvatar = (isDark) => {
|
|
1473
|
+
const bgColor = isDark ? 'rgba(26, 26, 46, 0.15)' : 'rgba(255, 255, 255, 0.1)';
|
|
1474
|
+
const fgColor = isDark ? 'rgba(255, 255, 255, 0.08)' : 'rgba(0, 0, 0, 0.06)';
|
|
1475
|
+
return 'data:image/svg+xml,' + encodeURIComponent(`
|
|
1476
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" fill="none">
|
|
1477
|
+
<rect width="200" height="200" fill="${bgColor}"/>
|
|
1478
|
+
<circle cx="100" cy="80" r="40" fill="${fgColor}"/>
|
|
1479
|
+
<ellipse cx="100" cy="180" rx="60" ry="50" fill="${fgColor}"/>
|
|
1480
|
+
</svg>
|
|
1481
|
+
`);
|
|
1482
|
+
};
|
|
1483
|
+
// =============================================================================
|
|
1484
|
+
// Icons
|
|
1485
|
+
// =============================================================================
|
|
1486
|
+
const Icons = {
|
|
1487
|
+
shield: (jsxRuntimeExports.jsx("svg", { viewBox: "0 0 24 24", children: jsxRuntimeExports.jsx("path", { d: "M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm-2 16l-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9l-8 8z", fill: "currentColor" }) })),
|
|
1488
|
+
plus: (jsxRuntimeExports.jsx("svg", { viewBox: "0 0 24 24", children: jsxRuntimeExports.jsx("path", { d: "M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z", fill: "currentColor" }) })),
|
|
1489
|
+
instagram: jsxRuntimeExports.jsx("path", { d: "M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z" }),
|
|
1490
|
+
x: jsxRuntimeExports.jsx("path", { d: "M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" }),
|
|
1491
|
+
linkedin: jsxRuntimeExports.jsx("path", { d: "M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" }),
|
|
1492
|
+
website: jsxRuntimeExports.jsx("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z" }),
|
|
1493
|
+
};
|
|
1494
|
+
function SocialLink({ href, title, icon }) {
|
|
1495
|
+
const iconPath = Icons[icon];
|
|
1496
|
+
if (!iconPath || typeof iconPath === 'object')
|
|
1497
|
+
return null;
|
|
1498
|
+
return (jsxRuntimeExports.jsx("a", { href: href, className: "mds-profile-card__social-link", title: title, target: "_blank", rel: "noopener noreferrer", children: jsxRuntimeExports.jsx("svg", { viewBox: "0 0 24 24", children: iconPath }) }));
|
|
1499
|
+
}
|
|
1500
|
+
function StatItem({ label, verified }) {
|
|
1501
|
+
return (jsxRuntimeExports.jsxs("div", { className: "mds-profile-card__stat-item", children: [jsxRuntimeExports.jsx("span", { className: "mds-profile-card__stat-label", children: label }), jsxRuntimeExports.jsx("span", { className: `mds-profile-card__stat-value ${verified ? 'mds-profile-card__stat-value--verified' : ''}`, children: verified ? 'Verified' : 'Not Verified' })] }));
|
|
1502
|
+
}
|
|
1503
|
+
// =============================================================================
|
|
1504
|
+
// Main Component
|
|
1505
|
+
// =============================================================================
|
|
1506
|
+
function ProfileCard({ user, variant = 'full', photoWidth, showSocial = false, socialLinks, showRotatingInfo = false, photoSlot, className = '', onSocialClick, }) {
|
|
1507
|
+
const [showVerifiedPopup, setShowVerifiedPopup] = useState(false);
|
|
1508
|
+
const [showSocialPopup, setShowSocialPopup] = useState(false);
|
|
1509
|
+
const [currentInfoIndex, setCurrentInfoIndex] = useState(0);
|
|
1510
|
+
const [isDarkTheme, setIsDarkTheme] = useState(true);
|
|
1511
|
+
const verifiedRef = useRef(null);
|
|
1512
|
+
const socialRef = useRef(null);
|
|
1513
|
+
// Calculate photo width based on variant
|
|
1514
|
+
const computedPhotoWidth = photoWidth ?? (variant === 'full' ? 280 : 200);
|
|
1515
|
+
// Detect theme
|
|
1516
|
+
useEffect(() => {
|
|
1517
|
+
const checkTheme = () => {
|
|
1518
|
+
const theme = document.documentElement.getAttribute('data-theme');
|
|
1519
|
+
setIsDarkTheme(theme !== 'light');
|
|
1520
|
+
};
|
|
1521
|
+
checkTheme();
|
|
1522
|
+
const observer = new MutationObserver((mutations) => {
|
|
1523
|
+
mutations.forEach((mutation) => {
|
|
1524
|
+
if (mutation.attributeName === 'data-theme') {
|
|
1525
|
+
checkTheme();
|
|
1526
|
+
}
|
|
1527
|
+
});
|
|
1528
|
+
});
|
|
1529
|
+
observer.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] });
|
|
1530
|
+
return () => observer.disconnect();
|
|
1531
|
+
}, []);
|
|
1532
|
+
// Dynamic info texts for rotating display
|
|
1533
|
+
const infoTexts = [
|
|
1534
|
+
`Member since ${new Date(user.created_at).getFullYear()}`,
|
|
1535
|
+
...(user.verified >= 1 ? ['Email Verified'] : []),
|
|
1536
|
+
...(user.verified >= 2 ? ['Identity Verified'] : []),
|
|
1537
|
+
...(user.verified >= 3 ? ['Professional Verified'] : []),
|
|
1538
|
+
];
|
|
1539
|
+
// Rotate info text
|
|
1540
|
+
useEffect(() => {
|
|
1541
|
+
if (!showRotatingInfo)
|
|
1542
|
+
return;
|
|
1543
|
+
const interval = setInterval(() => {
|
|
1544
|
+
setCurrentInfoIndex((prev) => (prev + 1) % infoTexts.length);
|
|
1545
|
+
}, 10000);
|
|
1546
|
+
return () => clearInterval(interval);
|
|
1547
|
+
}, [infoTexts.length, showRotatingInfo]);
|
|
1548
|
+
// Close popups on click outside
|
|
1549
|
+
useEffect(() => {
|
|
1550
|
+
const handleClickOutside = (e) => {
|
|
1551
|
+
if (verifiedRef.current && !verifiedRef.current.contains(e.target)) {
|
|
1552
|
+
setShowVerifiedPopup(false);
|
|
1553
|
+
}
|
|
1554
|
+
if (socialRef.current && !socialRef.current.contains(e.target)) {
|
|
1555
|
+
setShowSocialPopup(false);
|
|
1556
|
+
}
|
|
1557
|
+
};
|
|
1558
|
+
document.addEventListener('click', handleClickOutside);
|
|
1559
|
+
return () => document.removeEventListener('click', handleClickOutside);
|
|
1560
|
+
}, []);
|
|
1561
|
+
// Get display values
|
|
1562
|
+
const displayName = user.full_name || user.username || 'User';
|
|
1563
|
+
const profession = user.profession_name || user.profession_code || '';
|
|
1564
|
+
const getLocation = () => {
|
|
1565
|
+
if (!user.city_code && !user.state_code && !user.country_code)
|
|
1566
|
+
return null;
|
|
1567
|
+
const city = user.city_name || user.city_code?.toUpperCase() || '';
|
|
1568
|
+
const state = user.state_code?.toUpperCase() || '';
|
|
1569
|
+
const country = user.country_name || user.country_code?.toUpperCase() || '';
|
|
1570
|
+
const parts = [city, state, country].filter(Boolean);
|
|
1571
|
+
return parts.join(', ');
|
|
1572
|
+
};
|
|
1573
|
+
const memberSince = new Date(user.created_at).getFullYear().toString();
|
|
1574
|
+
const photoUrl = user.photo_url_medium || user.photo_url_full || getPlaceholderAvatar(isDarkTheme);
|
|
1575
|
+
return (jsxRuntimeExports.jsxs("article", { className: `mds-profile-card ${className}`, style: { '--mds-profile-card-photo-width': `${computedPhotoWidth}px` }, children: [jsxRuntimeExports.jsx("div", { className: "mds-profile-card__grain" }), jsxRuntimeExports.jsx("div", { className: "mds-profile-card__photo", children: photoSlot ? (jsxRuntimeExports.jsx("div", { className: "mds-profile-card__photo-slot", children: photoSlot })) : (jsxRuntimeExports.jsx("img", { src: photoUrl, alt: displayName, className: "mds-profile-card__avatar" })) }), jsxRuntimeExports.jsxs("div", { className: "mds-profile-card__content", children: [jsxRuntimeExports.jsxs("div", { className: "mds-profile-card__identity", children: [jsxRuntimeExports.jsx("h1", { className: "mds-profile-card__name", children: displayName.toUpperCase() }), variant === 'full' && profession && (jsxRuntimeExports.jsx("p", { className: "mds-profile-card__profession", children: profession.toUpperCase() })), variant === 'compact' && (jsxRuntimeExports.jsx("p", { className: "mds-profile-card__username", children: user.username }))] }), jsxRuntimeExports.jsxs("div", { className: "mds-profile-card__details", children: [variant === 'full' && getLocation() && (jsxRuntimeExports.jsx("p", { className: "mds-profile-card__location", children: getLocation() })), variant === 'full' && (jsxRuntimeExports.jsx("span", { className: "mds-profile-card__username-detail", children: user.username })), variant === 'compact' && user.email && (jsxRuntimeExports.jsx("p", { className: "mds-profile-card__email", children: user.email })), variant === 'compact' && (jsxRuntimeExports.jsxs("span", { className: "mds-profile-card__member", children: ["Member since ", memberSince] }))] }), variant === 'compact' && (jsxRuntimeExports.jsxs("div", { className: "mds-profile-card__verification", children: [jsxRuntimeExports.jsxs("button", { className: "mds-profile-card__verified-badge", title: `Verification Level ${user.verified}`, onClick: (e) => {
|
|
1576
|
+
e.stopPropagation();
|
|
1577
|
+
setShowVerifiedPopup(!showVerifiedPopup);
|
|
1578
|
+
}, children: [Icons.shield, jsxRuntimeExports.jsxs("span", { children: ["Level ", user.verified] })] }), jsxRuntimeExports.jsxs("div", { className: "mds-profile-card__dots", children: [jsxRuntimeExports.jsx("span", { className: `mds-profile-card__dot ${user.verified >= 1 ? 'active' : ''}`, title: "Email Verified" }), jsxRuntimeExports.jsx("span", { className: `mds-profile-card__dot ${user.verified >= 2 ? 'active' : ''}`, title: "Identity Verified" }), jsxRuntimeExports.jsx("span", { className: `mds-profile-card__dot ${user.verified >= 3 ? 'active' : ''}`, title: "Professional Verified" })] })] })), showSocial && (jsxRuntimeExports.jsxs("div", { ref: socialRef, className: "mds-profile-card__social", children: [jsxRuntimeExports.jsx("button", { className: "mds-profile-card__social-trigger", onClick: (e) => {
|
|
1579
|
+
e.stopPropagation();
|
|
1580
|
+
setShowSocialPopup(!showSocialPopup);
|
|
1581
|
+
setShowVerifiedPopup(false);
|
|
1582
|
+
onSocialClick?.();
|
|
1583
|
+
}, "aria-label": "Show social links", children: Icons.plus }), showSocialPopup && socialLinks && (jsxRuntimeExports.jsxs("div", { className: "mds-profile-card__social-popup", children: [socialLinks.instagram && jsxRuntimeExports.jsx(SocialLink, { href: socialLinks.instagram, title: "Instagram", icon: "instagram" }), socialLinks.x && jsxRuntimeExports.jsx(SocialLink, { href: socialLinks.x, title: "X", icon: "x" }), socialLinks.linkedin && jsxRuntimeExports.jsx(SocialLink, { href: socialLinks.linkedin, title: "LinkedIn", icon: "linkedin" }), socialLinks.website && jsxRuntimeExports.jsx(SocialLink, { href: socialLinks.website, title: "Website", icon: "website" })] }))] })), variant === 'full' && (jsxRuntimeExports.jsxs("div", { className: "mds-profile-card__dynamic-group", children: [showRotatingInfo && (jsxRuntimeExports.jsx("span", { className: "mds-profile-card__dynamic-info", children: infoTexts[currentInfoIndex] })), jsxRuntimeExports.jsxs("div", { ref: verifiedRef, className: "mds-profile-card__verified-section", children: [jsxRuntimeExports.jsx("button", { className: "mds-profile-card__verified-trigger", onClick: (e) => {
|
|
1584
|
+
e.stopPropagation();
|
|
1585
|
+
setShowVerifiedPopup(!showVerifiedPopup);
|
|
1586
|
+
setShowSocialPopup(false);
|
|
1587
|
+
}, title: "Verification Status", children: Icons.shield }), showVerifiedPopup && (jsxRuntimeExports.jsxs("div", { className: "mds-profile-card__verified-popup", children: [jsxRuntimeExports.jsxs("div", { className: "mds-profile-card__verified-header", children: ["Verification Level ", user.verified] }), jsxRuntimeExports.jsxs("div", { className: "mds-profile-card__verified-stats", children: [jsxRuntimeExports.jsx(StatItem, { label: "Email", verified: user.verified >= 1 }), jsxRuntimeExports.jsx(StatItem, { label: "Identity", verified: user.verified >= 2 }), jsxRuntimeExports.jsx(StatItem, { label: "Professional", verified: user.verified >= 3 })] }), jsxRuntimeExports.jsxs("div", { className: "mds-profile-card__verified-date", children: ["Since ", memberSince] })] }))] }), showRotatingInfo && (jsxRuntimeExports.jsx("div", { className: "mds-profile-card__info-dots", children: infoTexts.map((_, index) => (jsxRuntimeExports.jsx("span", { className: `mds-profile-card__info-dot ${index === currentInfoIndex ? 'active' : ''}` }, index))) }))] }))] })] }));
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1431
1590
|
const variantElementMap = {
|
|
1432
1591
|
h1: 'h1',
|
|
1433
1592
|
h2: 'h2',
|
|
@@ -1458,13 +1617,14 @@ const Typography = forwardRef(({ variant = 'body', size, as, children, className
|
|
|
1458
1617
|
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
1618
|
});
|
|
1460
1619
|
Typography.displayName = 'Typography';
|
|
1461
|
-
const BrandLogo = forwardRef(({ size = 'md',
|
|
1620
|
+
const BrandLogo = forwardRef(({ size = 'md', weight = 'bold', // Peso bold por padrão para a marca
|
|
1621
|
+
className, children = 'Metropolle', ...props }, ref) => {
|
|
1462
1622
|
const sizeMap = {
|
|
1463
1623
|
sm: '2xl',
|
|
1464
1624
|
md: '4xl',
|
|
1465
1625
|
lg: '4xl', // Same as md but with different mobile behavior
|
|
1466
1626
|
};
|
|
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 }));
|
|
1627
|
+
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
1628
|
});
|
|
1469
1629
|
BrandLogo.displayName = 'BrandLogo';
|
|
1470
1630
|
|
|
@@ -1488,5 +1648,1417 @@ Button.displayName = 'Button';
|
|
|
1488
1648
|
*/
|
|
1489
1649
|
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
1650
|
|
|
1491
|
-
|
|
1651
|
+
/**
|
|
1652
|
+
* Select Component (Design System)
|
|
1653
|
+
*
|
|
1654
|
+
* Custom dropdown select that renders consistently across all browsers.
|
|
1655
|
+
* Unlike native <select>, this component renders the dropdown via JavaScript,
|
|
1656
|
+
* ensuring proper theming support on Edge/Chrome Windows.
|
|
1657
|
+
*
|
|
1658
|
+
* @example
|
|
1659
|
+
* ```tsx
|
|
1660
|
+
* <Select
|
|
1661
|
+
* options={[
|
|
1662
|
+
* { label: 'Option 1', value: '1' },
|
|
1663
|
+
* { label: 'Option 2', value: '2' },
|
|
1664
|
+
* ]}
|
|
1665
|
+
* value={selectedValue}
|
|
1666
|
+
* onChange={setSelectedValue}
|
|
1667
|
+
* placeholder="Select an option..."
|
|
1668
|
+
* />
|
|
1669
|
+
* ```
|
|
1670
|
+
*/
|
|
1671
|
+
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) => {
|
|
1672
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
1673
|
+
const [searchTerm, setSearchTerm] = useState('');
|
|
1674
|
+
const [highlightedIndex, setHighlightedIndex] = useState(-1);
|
|
1675
|
+
const [mounted, setMounted] = useState(false);
|
|
1676
|
+
const triggerRef = useRef(null);
|
|
1677
|
+
const dropdownRef = useRef(null);
|
|
1678
|
+
const searchInputRef = useRef(null);
|
|
1679
|
+
const listRef = useRef(null);
|
|
1680
|
+
// Combine refs
|
|
1681
|
+
const combinedRef = (el) => {
|
|
1682
|
+
triggerRef.current = el;
|
|
1683
|
+
if (typeof ref === 'function') {
|
|
1684
|
+
ref(el);
|
|
1685
|
+
}
|
|
1686
|
+
else if (ref) {
|
|
1687
|
+
ref.current = el;
|
|
1688
|
+
}
|
|
1689
|
+
};
|
|
1690
|
+
// Client-side only
|
|
1691
|
+
useEffect(() => {
|
|
1692
|
+
setMounted(true);
|
|
1693
|
+
}, []);
|
|
1694
|
+
// Filter options based on search
|
|
1695
|
+
const filteredOptions = useMemo(() => {
|
|
1696
|
+
if (!searchTerm)
|
|
1697
|
+
return options;
|
|
1698
|
+
const term = searchTerm.toLowerCase();
|
|
1699
|
+
return options.filter(opt => {
|
|
1700
|
+
const label = typeof opt.label === 'string' ? opt.label : String(opt.value);
|
|
1701
|
+
return label.toLowerCase().includes(term);
|
|
1702
|
+
});
|
|
1703
|
+
}, [options, searchTerm]);
|
|
1704
|
+
// Get selected option label
|
|
1705
|
+
const selectedOption = useMemo(() => {
|
|
1706
|
+
return options.find(opt => opt.value === value);
|
|
1707
|
+
}, [options, value]);
|
|
1708
|
+
// Handle dropdown positioning
|
|
1709
|
+
const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0, width: 0 });
|
|
1710
|
+
const updateDropdownPosition = useCallback(() => {
|
|
1711
|
+
if (!triggerRef.current)
|
|
1712
|
+
return;
|
|
1713
|
+
const rect = triggerRef.current.getBoundingClientRect();
|
|
1714
|
+
const viewportHeight = window.innerHeight;
|
|
1715
|
+
const spaceBelow = viewportHeight - rect.bottom;
|
|
1716
|
+
const spaceAbove = rect.top;
|
|
1717
|
+
// Determine if dropdown should open above or below
|
|
1718
|
+
const dropdownHeight = Math.min(maxHeight, filteredOptions.length * 40 + (searchable ? 48 : 0));
|
|
1719
|
+
const openAbove = spaceBelow < dropdownHeight && spaceAbove > spaceBelow;
|
|
1720
|
+
setDropdownPosition({
|
|
1721
|
+
top: openAbove ? rect.top - dropdownHeight : rect.bottom + 4,
|
|
1722
|
+
left: rect.left,
|
|
1723
|
+
width: rect.width,
|
|
1724
|
+
});
|
|
1725
|
+
}, [maxHeight, filteredOptions.length, searchable]);
|
|
1726
|
+
// Open dropdown
|
|
1727
|
+
const openDropdown = useCallback(() => {
|
|
1728
|
+
if (disabled || loading)
|
|
1729
|
+
return;
|
|
1730
|
+
updateDropdownPosition();
|
|
1731
|
+
setIsOpen(true);
|
|
1732
|
+
setSearchTerm('');
|
|
1733
|
+
setHighlightedIndex(value ? filteredOptions.findIndex(opt => opt.value === value) : 0);
|
|
1734
|
+
}, [disabled, loading, updateDropdownPosition, value, filteredOptions]);
|
|
1735
|
+
// Close dropdown
|
|
1736
|
+
const closeDropdown = useCallback(() => {
|
|
1737
|
+
setIsOpen(false);
|
|
1738
|
+
setSearchTerm('');
|
|
1739
|
+
setHighlightedIndex(-1);
|
|
1740
|
+
triggerRef.current?.focus();
|
|
1741
|
+
}, []);
|
|
1742
|
+
// Handle option select
|
|
1743
|
+
const handleSelect = useCallback((optionValue) => {
|
|
1744
|
+
// Safety check: ensure we're passing a string, not an object
|
|
1745
|
+
const safeValue = typeof optionValue === 'string' ? optionValue : String(optionValue);
|
|
1746
|
+
onChange?.(safeValue);
|
|
1747
|
+
closeDropdown();
|
|
1748
|
+
}, [onChange, closeDropdown]);
|
|
1749
|
+
// Keyboard navigation
|
|
1750
|
+
const handleKeyDown = useCallback((e) => {
|
|
1751
|
+
if (disabled || loading)
|
|
1752
|
+
return;
|
|
1753
|
+
switch (e.key) {
|
|
1754
|
+
case 'Enter':
|
|
1755
|
+
case ' ':
|
|
1756
|
+
e.preventDefault();
|
|
1757
|
+
if (isOpen && highlightedIndex >= 0 && filteredOptions[highlightedIndex]) {
|
|
1758
|
+
const opt = filteredOptions[highlightedIndex];
|
|
1759
|
+
if (!opt.disabled) {
|
|
1760
|
+
handleSelect(opt.value);
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
else if (!isOpen) {
|
|
1764
|
+
openDropdown();
|
|
1765
|
+
}
|
|
1766
|
+
break;
|
|
1767
|
+
case 'ArrowDown':
|
|
1768
|
+
e.preventDefault();
|
|
1769
|
+
if (!isOpen) {
|
|
1770
|
+
openDropdown();
|
|
1771
|
+
}
|
|
1772
|
+
else {
|
|
1773
|
+
setHighlightedIndex(prev => {
|
|
1774
|
+
const next = prev + 1;
|
|
1775
|
+
return next >= filteredOptions.length ? 0 : next;
|
|
1776
|
+
});
|
|
1777
|
+
}
|
|
1778
|
+
break;
|
|
1779
|
+
case 'ArrowUp':
|
|
1780
|
+
e.preventDefault();
|
|
1781
|
+
if (isOpen) {
|
|
1782
|
+
setHighlightedIndex(prev => {
|
|
1783
|
+
const next = prev - 1;
|
|
1784
|
+
return next < 0 ? filteredOptions.length - 1 : next;
|
|
1785
|
+
});
|
|
1786
|
+
}
|
|
1787
|
+
break;
|
|
1788
|
+
case 'Escape':
|
|
1789
|
+
e.preventDefault();
|
|
1790
|
+
closeDropdown();
|
|
1791
|
+
break;
|
|
1792
|
+
case 'Tab':
|
|
1793
|
+
if (isOpen) {
|
|
1794
|
+
closeDropdown();
|
|
1795
|
+
}
|
|
1796
|
+
break;
|
|
1797
|
+
case 'Home':
|
|
1798
|
+
if (isOpen) {
|
|
1799
|
+
e.preventDefault();
|
|
1800
|
+
setHighlightedIndex(0);
|
|
1801
|
+
}
|
|
1802
|
+
break;
|
|
1803
|
+
case 'End':
|
|
1804
|
+
if (isOpen) {
|
|
1805
|
+
e.preventDefault();
|
|
1806
|
+
setHighlightedIndex(filteredOptions.length - 1);
|
|
1807
|
+
}
|
|
1808
|
+
break;
|
|
1809
|
+
}
|
|
1810
|
+
}, [disabled, loading, isOpen, highlightedIndex, filteredOptions, handleSelect, openDropdown, closeDropdown]);
|
|
1811
|
+
// Click outside to close
|
|
1812
|
+
useEffect(() => {
|
|
1813
|
+
if (!isOpen)
|
|
1814
|
+
return;
|
|
1815
|
+
const handleClickOutside = (e) => {
|
|
1816
|
+
if (triggerRef.current?.contains(e.target) ||
|
|
1817
|
+
dropdownRef.current?.contains(e.target)) {
|
|
1818
|
+
return;
|
|
1819
|
+
}
|
|
1820
|
+
closeDropdown();
|
|
1821
|
+
};
|
|
1822
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
1823
|
+
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
1824
|
+
}, [isOpen, closeDropdown]);
|
|
1825
|
+
// Update position on scroll/resize
|
|
1826
|
+
useEffect(() => {
|
|
1827
|
+
if (!isOpen)
|
|
1828
|
+
return;
|
|
1829
|
+
const handleUpdate = () => updateDropdownPosition();
|
|
1830
|
+
window.addEventListener('scroll', handleUpdate, true);
|
|
1831
|
+
window.addEventListener('resize', handleUpdate);
|
|
1832
|
+
return () => {
|
|
1833
|
+
window.removeEventListener('scroll', handleUpdate, true);
|
|
1834
|
+
window.removeEventListener('resize', handleUpdate);
|
|
1835
|
+
};
|
|
1836
|
+
}, [isOpen, updateDropdownPosition]);
|
|
1837
|
+
// Focus search input when dropdown opens
|
|
1838
|
+
useEffect(() => {
|
|
1839
|
+
if (isOpen && searchable && searchInputRef.current) {
|
|
1840
|
+
searchInputRef.current.focus();
|
|
1841
|
+
}
|
|
1842
|
+
}, [isOpen, searchable]);
|
|
1843
|
+
// Scroll highlighted option into view
|
|
1844
|
+
useEffect(() => {
|
|
1845
|
+
if (!isOpen || highlightedIndex < 0 || !listRef.current)
|
|
1846
|
+
return;
|
|
1847
|
+
const highlighted = listRef.current.children[highlightedIndex];
|
|
1848
|
+
if (highlighted) {
|
|
1849
|
+
highlighted.scrollIntoView({ block: 'nearest' });
|
|
1850
|
+
}
|
|
1851
|
+
}, [isOpen, highlightedIndex]);
|
|
1852
|
+
// Size classes
|
|
1853
|
+
const sizeClasses = {
|
|
1854
|
+
sm: 'mds-select--sm',
|
|
1855
|
+
md: 'mds-select--md',
|
|
1856
|
+
lg: 'mds-select--lg',
|
|
1857
|
+
};
|
|
1858
|
+
// Variant classes
|
|
1859
|
+
const variantClasses = {
|
|
1860
|
+
base: 'mds-select--base',
|
|
1861
|
+
themed: 'mds-select--themed',
|
|
1862
|
+
dashboard: 'mds-select--themed',
|
|
1863
|
+
};
|
|
1864
|
+
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);
|
|
1865
|
+
const dropdownClasses = cn('mds-select-dropdown', variantClasses[variant], dropdownClassName);
|
|
1866
|
+
// Hidden input for form submission
|
|
1867
|
+
const hiddenInput = name ? (jsxRuntimeExports.jsx("input", { type: "hidden", name: name, value: value || '' })) : null;
|
|
1868
|
+
// Dropdown portal content
|
|
1869
|
+
const dropdownContent = isOpen && mounted ? createPortal(jsxRuntimeExports.jsxs("div", { ref: dropdownRef, className: dropdownClasses, style: {
|
|
1870
|
+
position: 'fixed',
|
|
1871
|
+
top: dropdownPosition.top,
|
|
1872
|
+
left: dropdownPosition.left,
|
|
1873
|
+
width: dropdownPosition.width,
|
|
1874
|
+
maxHeight,
|
|
1875
|
+
zIndex,
|
|
1876
|
+
}, 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) => {
|
|
1877
|
+
setSearchTerm(e.target.value);
|
|
1878
|
+
setHighlightedIndex(0);
|
|
1879
|
+
}, 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: () => {
|
|
1880
|
+
if (!option.disabled) {
|
|
1881
|
+
handleSelect(option.value);
|
|
1882
|
+
}
|
|
1883
|
+
}, onMouseEnter: () => {
|
|
1884
|
+
if (!option.disabled) {
|
|
1885
|
+
setHighlightedIndex(index);
|
|
1886
|
+
}
|
|
1887
|
+
}, 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;
|
|
1888
|
+
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] }));
|
|
1889
|
+
});
|
|
1890
|
+
Select.displayName = 'Select';
|
|
1891
|
+
|
|
1892
|
+
function ThemeToggle({ size = 'md', className = '', disabled = false, onChange, storageKey = 'theme' }) {
|
|
1893
|
+
const [theme, setTheme] = useState('dark');
|
|
1894
|
+
const [mounted, setMounted] = useState(false);
|
|
1895
|
+
// Initialize theme on mount
|
|
1896
|
+
useEffect(() => {
|
|
1897
|
+
try {
|
|
1898
|
+
if (typeof window !== 'undefined') {
|
|
1899
|
+
const savedTheme = localStorage.getItem(storageKey) || 'dark';
|
|
1900
|
+
setTheme(savedTheme);
|
|
1901
|
+
document.documentElement.setAttribute('data-theme', savedTheme);
|
|
1902
|
+
setMounted(true);
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
catch (err) {
|
|
1906
|
+
setTheme('dark');
|
|
1907
|
+
setMounted(true);
|
|
1908
|
+
}
|
|
1909
|
+
}, [storageKey]);
|
|
1910
|
+
// Listen to external theme changes
|
|
1911
|
+
useEffect(() => {
|
|
1912
|
+
if (typeof window !== 'undefined') {
|
|
1913
|
+
const updateTheme = () => {
|
|
1914
|
+
const currentTheme = document.documentElement.getAttribute('data-theme') || 'dark';
|
|
1915
|
+
setTheme(currentTheme);
|
|
1916
|
+
};
|
|
1917
|
+
const observer = new MutationObserver(() => {
|
|
1918
|
+
updateTheme();
|
|
1919
|
+
});
|
|
1920
|
+
observer.observe(document.documentElement, {
|
|
1921
|
+
attributes: true,
|
|
1922
|
+
attributeFilter: ['data-theme']
|
|
1923
|
+
});
|
|
1924
|
+
return () => observer.disconnect();
|
|
1925
|
+
}
|
|
1926
|
+
}, []);
|
|
1927
|
+
const toggleTheme = () => {
|
|
1928
|
+
if (disabled)
|
|
1929
|
+
return;
|
|
1930
|
+
try {
|
|
1931
|
+
const newTheme = theme === 'light' ? 'dark' : 'light';
|
|
1932
|
+
document.documentElement.setAttribute('data-theme', newTheme);
|
|
1933
|
+
localStorage.setItem(storageKey, newTheme);
|
|
1934
|
+
setTheme(newTheme);
|
|
1935
|
+
onChange?.(newTheme);
|
|
1936
|
+
}
|
|
1937
|
+
catch (err) {
|
|
1938
|
+
console.warn('Failed to toggle theme:', err);
|
|
1939
|
+
}
|
|
1940
|
+
};
|
|
1941
|
+
// Don't render until mounted (prevents hydration mismatch)
|
|
1942
|
+
if (!mounted) {
|
|
1943
|
+
return (jsxRuntimeExports.jsx("div", { className: `mds-theme-toggle mds-theme-toggle--${size} ${className}`, style: { opacity: 0.5 }, "aria-hidden": "true" }));
|
|
1944
|
+
}
|
|
1945
|
+
const isDark = theme === 'dark';
|
|
1946
|
+
const buttonStyle = isDark
|
|
1947
|
+
? {
|
|
1948
|
+
backgroundColor: 'rgba(0, 0, 0, 0.35)',
|
|
1949
|
+
border: '1px solid rgba(255, 255, 255, 0.18)',
|
|
1950
|
+
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.3)'
|
|
1951
|
+
}
|
|
1952
|
+
: undefined;
|
|
1953
|
+
const buttonClasses = [
|
|
1954
|
+
'mds-theme-toggle',
|
|
1955
|
+
`mds-theme-toggle--${size}`,
|
|
1956
|
+
className
|
|
1957
|
+
].filter(Boolean).join(' ');
|
|
1958
|
+
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 }));
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1961
|
+
const TableHeader = ({ columns, gridTemplate, onSort, sortColumn, sortDirection, hasActions = false }) => {
|
|
1962
|
+
return (jsxRuntimeExports.jsxs("div", { role: "rowgroup", style: {
|
|
1963
|
+
display: 'grid',
|
|
1964
|
+
gridTemplateColumns: gridTemplate,
|
|
1965
|
+
gap: '16px',
|
|
1966
|
+
padding: '16px 20px',
|
|
1967
|
+
borderBottom: '1px solid var(--border-color)',
|
|
1968
|
+
backgroundColor: 'rgba(255, 255, 255, 0.05)'
|
|
1969
|
+
}, children: [columns.map((column) => (jsxRuntimeExports.jsxs("div", { role: "columnheader", style: {
|
|
1970
|
+
color: 'var(--text-primary)',
|
|
1971
|
+
fontWeight: '500',
|
|
1972
|
+
fontSize: '14px',
|
|
1973
|
+
display: 'flex',
|
|
1974
|
+
alignItems: 'center',
|
|
1975
|
+
justifyContent: column.align === 'center' ? 'center' :
|
|
1976
|
+
column.align === 'right' ? 'flex-end' : 'flex-start',
|
|
1977
|
+
cursor: column.sortable && onSort ? 'pointer' : 'default',
|
|
1978
|
+
gap: '4px',
|
|
1979
|
+
transition: 'color 0.2s ease'
|
|
1980
|
+
}, onClick: () => column.sortable && onSort && onSort(column.key), onMouseEnter: (e) => {
|
|
1981
|
+
if (column.sortable && onSort) {
|
|
1982
|
+
e.currentTarget.style.color = '#ffffff';
|
|
1983
|
+
}
|
|
1984
|
+
}, onMouseLeave: (e) => {
|
|
1985
|
+
e.currentTarget.style.color = 'var(--text-primary)';
|
|
1986
|
+
}, children: [column.label, column.sortable && onSort && (jsxRuntimeExports.jsx("span", { style: {
|
|
1987
|
+
fontSize: '12px',
|
|
1988
|
+
opacity: sortColumn === column.key ? 1 : 0.5
|
|
1989
|
+
}, children: sortColumn === column.key ?
|
|
1990
|
+
(sortDirection === 'asc' ? '↑' : '↓') : '↕' }))] }, column.key))), hasActions && (jsxRuntimeExports.jsx("div", { role: "columnheader", style: {
|
|
1991
|
+
color: 'var(--text-primary)',
|
|
1992
|
+
fontWeight: '500',
|
|
1993
|
+
fontSize: '14px',
|
|
1994
|
+
display: 'flex',
|
|
1995
|
+
alignItems: 'center',
|
|
1996
|
+
justifyContent: 'center'
|
|
1997
|
+
}, children: "Actions" }))] }));
|
|
1998
|
+
};
|
|
1999
|
+
|
|
2000
|
+
const TableRow = ({ item, index, columns, actions = [], gridTemplate, isLast, variant, onActionClick }) => {
|
|
2001
|
+
return (jsxRuntimeExports.jsxs("div", { role: "row", style: {
|
|
2002
|
+
display: 'grid',
|
|
2003
|
+
gridTemplateColumns: gridTemplate,
|
|
2004
|
+
gap: '16px',
|
|
2005
|
+
padding: variant === 'compact' ? '12px 20px' : '16px 20px',
|
|
2006
|
+
borderBottom: isLast ? 'none' : '1px solid var(--border-color)',
|
|
2007
|
+
backgroundColor: 'transparent',
|
|
2008
|
+
transition: 'background-color 0.2s ease'
|
|
2009
|
+
}, onMouseEnter: (e) => {
|
|
2010
|
+
e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.05)';
|
|
2011
|
+
}, onMouseLeave: (e) => {
|
|
2012
|
+
e.currentTarget.style.backgroundColor = 'transparent';
|
|
2013
|
+
}, children: [columns.map((column) => (jsxRuntimeExports.jsx("div", { role: "cell", style: {
|
|
2014
|
+
display: 'flex',
|
|
2015
|
+
flexDirection: 'column',
|
|
2016
|
+
gap: '4px',
|
|
2017
|
+
justifyContent: 'center',
|
|
2018
|
+
alignItems: column.align === 'center' ? 'center' :
|
|
2019
|
+
column.align === 'right' ? 'flex-end' : 'flex-start'
|
|
2020
|
+
}, children: column.render ?
|
|
2021
|
+
column.render(item[column.key], item, index) :
|
|
2022
|
+
jsxRuntimeExports.jsx("div", { style: {
|
|
2023
|
+
color: 'var(--text-primary)',
|
|
2024
|
+
fontSize: '14px'
|
|
2025
|
+
}, children: item[column.key] }) }, column.key))), actions.length > 0 && (jsxRuntimeExports.jsx("div", { role: "cell", style: {
|
|
2026
|
+
display: 'flex',
|
|
2027
|
+
gap: '8px',
|
|
2028
|
+
justifyContent: 'center',
|
|
2029
|
+
alignItems: 'center'
|
|
2030
|
+
}, children: actions.map((action) => {
|
|
2031
|
+
const isDisabled = action.disabled?.(item) || false;
|
|
2032
|
+
const isLoading = action.loading?.(item) || false;
|
|
2033
|
+
return (jsxRuntimeExports.jsxs("button", { onClick: () => !isDisabled && !isLoading && onActionClick(action, item), disabled: isDisabled || isLoading, style: {
|
|
2034
|
+
background: 'none',
|
|
2035
|
+
border: 'none',
|
|
2036
|
+
borderRadius: '6px',
|
|
2037
|
+
padding: '6px 8px',
|
|
2038
|
+
color: action.variant === 'danger' ? '#f87171' : 'var(--text-primary)',
|
|
2039
|
+
fontSize: '12px',
|
|
2040
|
+
cursor: isDisabled || isLoading ? 'not-allowed' : 'pointer',
|
|
2041
|
+
display: 'flex',
|
|
2042
|
+
alignItems: 'center',
|
|
2043
|
+
gap: '4px',
|
|
2044
|
+
transition: 'all 0.2s ease',
|
|
2045
|
+
opacity: isDisabled || isLoading ? 0.5 : 1,
|
|
2046
|
+
whiteSpace: 'nowrap'
|
|
2047
|
+
}, onMouseEnter: (e) => {
|
|
2048
|
+
if (!isDisabled && !isLoading) {
|
|
2049
|
+
if (action.variant === 'danger') {
|
|
2050
|
+
e.currentTarget.style.backgroundColor = 'rgba(239, 68, 68, 0.1)';
|
|
2051
|
+
}
|
|
2052
|
+
else {
|
|
2053
|
+
e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.1)';
|
|
2054
|
+
}
|
|
2055
|
+
}
|
|
2056
|
+
}, onMouseLeave: (e) => {
|
|
2057
|
+
if (!isDisabled && !isLoading) {
|
|
2058
|
+
e.currentTarget.style.backgroundColor = 'transparent';
|
|
2059
|
+
}
|
|
2060
|
+
}, children: [action.icon && action.icon, action.label] }, action.key));
|
|
2061
|
+
}) }))] }));
|
|
2062
|
+
};
|
|
2063
|
+
|
|
2064
|
+
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 }) => {
|
|
2065
|
+
const [sortColumn, setSortColumn] = useState('');
|
|
2066
|
+
const [sortDirection, setSortDirection] = useState('asc');
|
|
2067
|
+
// Filter data based on search term
|
|
2068
|
+
const filteredData = useMemo(() => {
|
|
2069
|
+
if (!searchTerm)
|
|
2070
|
+
return data;
|
|
2071
|
+
return data.filter(item => {
|
|
2072
|
+
return columns.some(column => {
|
|
2073
|
+
const value = item[column.key];
|
|
2074
|
+
if (value === null || value === undefined)
|
|
2075
|
+
return false;
|
|
2076
|
+
return String(value).toLowerCase().includes(searchTerm.toLowerCase());
|
|
2077
|
+
});
|
|
2078
|
+
});
|
|
2079
|
+
}, [data, searchTerm, columns]);
|
|
2080
|
+
// Generate grid template based on columns and actions
|
|
2081
|
+
const gridTemplate = useMemo(() => {
|
|
2082
|
+
const columnWidths = columns.map(col => col.width || '1fr').join(' ');
|
|
2083
|
+
const actionsWidth = actions.length > 0 ? ' 120px' : '';
|
|
2084
|
+
return columnWidths + actionsWidth;
|
|
2085
|
+
}, [columns, actions]);
|
|
2086
|
+
// Handle sort
|
|
2087
|
+
const handleSort = (columnKey) => {
|
|
2088
|
+
let direction = 'asc';
|
|
2089
|
+
if (sortColumn === columnKey && sortDirection === 'asc') {
|
|
2090
|
+
direction = 'desc';
|
|
2091
|
+
}
|
|
2092
|
+
setSortColumn(columnKey);
|
|
2093
|
+
setSortDirection(direction);
|
|
2094
|
+
if (onSort) {
|
|
2095
|
+
onSort(columnKey, direction);
|
|
2096
|
+
}
|
|
2097
|
+
};
|
|
2098
|
+
// Handle action click
|
|
2099
|
+
const handleActionClick = (action, item) => {
|
|
2100
|
+
action.onClick(item);
|
|
2101
|
+
};
|
|
2102
|
+
// Loading state
|
|
2103
|
+
if (loading) {
|
|
2104
|
+
return (jsxRuntimeExports.jsx("div", { className: className, style: {
|
|
2105
|
+
position: 'relative',
|
|
2106
|
+
borderRadius: '24px',
|
|
2107
|
+
backdropFilter: 'blur(24px)',
|
|
2108
|
+
backgroundColor: 'rgba(255, 255, 255, 0.1)',
|
|
2109
|
+
border: '1px solid rgba(255, 255, 255, 0.3)',
|
|
2110
|
+
boxShadow: '0 12px 40px rgba(0, 0, 0, 0.15)',
|
|
2111
|
+
padding: '32px',
|
|
2112
|
+
...style
|
|
2113
|
+
}, children: jsxRuntimeExports.jsxs("div", { style: {
|
|
2114
|
+
display: 'flex',
|
|
2115
|
+
alignItems: 'center',
|
|
2116
|
+
justifyContent: 'center',
|
|
2117
|
+
gap: '12px'
|
|
2118
|
+
}, children: [jsxRuntimeExports.jsx("div", { style: {
|
|
2119
|
+
width: '32px',
|
|
2120
|
+
height: '32px',
|
|
2121
|
+
border: '2px solid transparent',
|
|
2122
|
+
borderTop: '2px solid white',
|
|
2123
|
+
borderRadius: '50%',
|
|
2124
|
+
animation: 'spin 1s linear infinite'
|
|
2125
|
+
} }), jsxRuntimeExports.jsx("span", { style: { color: 'var(--text-primary)' }, children: loadingMessage })] }) }));
|
|
2126
|
+
}
|
|
2127
|
+
// Empty state
|
|
2128
|
+
if (filteredData.length === 0) {
|
|
2129
|
+
return (jsxRuntimeExports.jsx("div", { className: className, style: {
|
|
2130
|
+
position: 'relative',
|
|
2131
|
+
borderRadius: '24px',
|
|
2132
|
+
backdropFilter: 'blur(24px)',
|
|
2133
|
+
backgroundColor: 'rgba(255, 255, 255, 0.1)',
|
|
2134
|
+
border: '1px solid rgba(255, 255, 255, 0.3)',
|
|
2135
|
+
boxShadow: '0 12px 40px rgba(0, 0, 0, 0.15)',
|
|
2136
|
+
padding: '40px',
|
|
2137
|
+
textAlign: 'center',
|
|
2138
|
+
...style
|
|
2139
|
+
}, children: jsxRuntimeExports.jsx("div", { style: {
|
|
2140
|
+
color: 'var(--text-secondary)',
|
|
2141
|
+
fontSize: '16px'
|
|
2142
|
+
}, children: emptyMessage }) }));
|
|
2143
|
+
}
|
|
2144
|
+
return (jsxRuntimeExports.jsxs("div", { className: className, style: {
|
|
2145
|
+
position: 'relative',
|
|
2146
|
+
borderRadius: '24px',
|
|
2147
|
+
backdropFilter: 'blur(24px)',
|
|
2148
|
+
backgroundColor: 'rgba(255, 255, 255, 0.1)',
|
|
2149
|
+
border: '1px solid rgba(255, 255, 255, 0.3)',
|
|
2150
|
+
boxShadow: '0 12px 40px rgba(0, 0, 0, 0.15)',
|
|
2151
|
+
overflow: 'hidden',
|
|
2152
|
+
...style
|
|
2153
|
+
}, role: "table", "aria-label": "Tabela de dados", children: [showSearchCount && searchTerm && (jsxRuntimeExports.jsxs("div", { style: {
|
|
2154
|
+
padding: '16px',
|
|
2155
|
+
color: 'var(--text-secondary)',
|
|
2156
|
+
fontSize: '14px',
|
|
2157
|
+
borderBottom: '1px solid var(--border-color)'
|
|
2158
|
+
}, 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, hasActions: actions.length > 0 }), jsxRuntimeExports.jsx("div", { role: "rowgroup", style: {
|
|
2159
|
+
maxHeight,
|
|
2160
|
+
overflowY: 'auto'
|
|
2161
|
+
}, 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))) })] }));
|
|
2162
|
+
};
|
|
2163
|
+
|
|
2164
|
+
const CellRenderers = {
|
|
2165
|
+
// ID cell - monospace background
|
|
2166
|
+
id: (value) => (jsxRuntimeExports.jsx("div", { className: "data-table-code", style: {
|
|
2167
|
+
color: 'var(--text-secondary)',
|
|
2168
|
+
fontSize: '12px',
|
|
2169
|
+
backgroundColor: 'rgba(255, 255, 255, 0.05)',
|
|
2170
|
+
padding: '2px 8px',
|
|
2171
|
+
borderRadius: '4px',
|
|
2172
|
+
textAlign: 'center',
|
|
2173
|
+
fontFamily: 'monospace'
|
|
2174
|
+
}, children: value })),
|
|
2175
|
+
// Name cell - primary text with background
|
|
2176
|
+
name: (value) => (jsxRuntimeExports.jsx("div", { className: "data-table-code", style: {
|
|
2177
|
+
color: 'var(--text-primary)',
|
|
2178
|
+
fontSize: '14px',
|
|
2179
|
+
backgroundColor: 'rgba(255, 255, 255, 0.1)',
|
|
2180
|
+
padding: '4px 12px',
|
|
2181
|
+
borderRadius: '8px',
|
|
2182
|
+
fontFamily: 'monospace'
|
|
2183
|
+
}, children: value })),
|
|
2184
|
+
// Parameter value - masked if secure
|
|
2185
|
+
parameterValue: (value, item) => {
|
|
2186
|
+
const displayValue = item.type === 'SecureString' ? '••••••••' :
|
|
2187
|
+
(value?.length > 50 ? `${value.substring(0, 50)}...` : value);
|
|
2188
|
+
return (jsxRuntimeExports.jsx("div", { className: "data-table-code", style: {
|
|
2189
|
+
color: 'var(--text-primary)',
|
|
2190
|
+
fontSize: '14px',
|
|
2191
|
+
backgroundColor: 'rgba(255, 255, 255, 0.1)',
|
|
2192
|
+
borderRadius: '8px',
|
|
2193
|
+
maxWidth: '300px',
|
|
2194
|
+
wordBreak: 'break-all',
|
|
2195
|
+
padding: '4px 12px',
|
|
2196
|
+
fontFamily: 'monospace'
|
|
2197
|
+
}, children: displayValue }));
|
|
2198
|
+
},
|
|
2199
|
+
// Badge renderer for types/statuses
|
|
2200
|
+
badge: (value, variant = 'primary') => (jsxRuntimeExports.jsx("span", { className: `data-table-badge ${variant}`, children: value })),
|
|
2201
|
+
// Parameter type badge
|
|
2202
|
+
parameterType: (value) => {
|
|
2203
|
+
const variant = value === 'SecureString' ? 'danger' :
|
|
2204
|
+
value === 'StringList' ? 'success' : 'primary';
|
|
2205
|
+
return CellRenderers.badge(value, variant);
|
|
2206
|
+
},
|
|
2207
|
+
// Environment badge
|
|
2208
|
+
environment: (value, item) => {
|
|
2209
|
+
const env = item.name?.includes('/prod/') ? 'PROD' : 'DEV';
|
|
2210
|
+
const variant = env === 'PROD' ? 'info' : 'warning';
|
|
2211
|
+
return CellRenderers.badge(env, variant);
|
|
2212
|
+
},
|
|
2213
|
+
// Action type badge for audit logs
|
|
2214
|
+
actionType: (value) => {
|
|
2215
|
+
const variant = value === 'CREATE' ? 'success' :
|
|
2216
|
+
value === 'UPDATE' ? 'primary' : 'danger';
|
|
2217
|
+
return CellRenderers.badge(value, variant);
|
|
2218
|
+
},
|
|
2219
|
+
// Date formatter
|
|
2220
|
+
date: (value) => (jsxRuntimeExports.jsx("div", { style: {
|
|
2221
|
+
color: 'var(--text-primary)',
|
|
2222
|
+
fontSize: '14px'
|
|
2223
|
+
}, children: value ? new Date(value).toLocaleString('pt-BR') : '-' })),
|
|
2224
|
+
// Description/secondary text
|
|
2225
|
+
description: (value) => (jsxRuntimeExports.jsx("div", { style: {
|
|
2226
|
+
color: 'var(--text-secondary)',
|
|
2227
|
+
fontSize: '12px',
|
|
2228
|
+
maxWidth: '300px',
|
|
2229
|
+
overflow: 'hidden',
|
|
2230
|
+
textOverflow: 'ellipsis',
|
|
2231
|
+
whiteSpace: 'nowrap'
|
|
2232
|
+
}, children: value })),
|
|
2233
|
+
// JSON preview for audit changes
|
|
2234
|
+
jsonPreview: (value) => {
|
|
2235
|
+
const jsonString = JSON.stringify(value);
|
|
2236
|
+
const preview = jsonString.length > 30 ? jsonString.substring(0, 30) + '...' : jsonString;
|
|
2237
|
+
return (jsxRuntimeExports.jsx("div", { style: {
|
|
2238
|
+
color: 'var(--text-secondary)',
|
|
2239
|
+
fontSize: '12px',
|
|
2240
|
+
fontFamily: 'monospace',
|
|
2241
|
+
maxWidth: '150px',
|
|
2242
|
+
overflow: 'hidden',
|
|
2243
|
+
textOverflow: 'ellipsis',
|
|
2244
|
+
whiteSpace: 'nowrap'
|
|
2245
|
+
}, children: preview }));
|
|
2246
|
+
},
|
|
2247
|
+
// Combined cell with main value and description
|
|
2248
|
+
combined: (mainValue, description) => (jsxRuntimeExports.jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '8px' }, children: [CellRenderers.name(mainValue), description && CellRenderers.description(description)] })),
|
|
2249
|
+
// Combined with badges
|
|
2250
|
+
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))) })] }))
|
|
2251
|
+
};
|
|
2252
|
+
// Common action icons
|
|
2253
|
+
const ActionIcons = {
|
|
2254
|
+
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" }) })),
|
|
2255
|
+
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" }) })),
|
|
2256
|
+
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" }) })),
|
|
2257
|
+
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" }) }))
|
|
2258
|
+
};
|
|
2259
|
+
|
|
2260
|
+
// Configuração para ParametersTable (Settings)
|
|
2261
|
+
const parametersTableConfig = {
|
|
2262
|
+
columns: [
|
|
2263
|
+
{
|
|
2264
|
+
key: 'name',
|
|
2265
|
+
label: 'Parâmetro',
|
|
2266
|
+
width: '1fr',
|
|
2267
|
+
render: (value, item) => CellRenderers.combinedWithBadges(value, [
|
|
2268
|
+
{ value: item.type, variant: item.type === 'SecureString' ? 'danger' :
|
|
2269
|
+
item.type === 'StringList' ? 'success' : 'primary' },
|
|
2270
|
+
{ value: item.name.includes('/prod/') ? 'PROD' : 'DEV',
|
|
2271
|
+
variant: item.name.includes('/prod/') ? 'info' : 'warning' }
|
|
2272
|
+
])
|
|
2273
|
+
},
|
|
2274
|
+
{
|
|
2275
|
+
key: 'value',
|
|
2276
|
+
label: 'Valor',
|
|
2277
|
+
width: '2fr',
|
|
2278
|
+
render: (value, item) => (jsxRuntimeExports.jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '8px' }, children: [CellRenderers.parameterValue(value, item), CellRenderers.description(item.description)] }))
|
|
2279
|
+
}
|
|
2280
|
+
],
|
|
2281
|
+
actions: [
|
|
2282
|
+
{
|
|
2283
|
+
key: 'edit',
|
|
2284
|
+
label: '✏️',
|
|
2285
|
+
variant: 'secondary',
|
|
2286
|
+
onClick: (item) => console.log('Edit', item),
|
|
2287
|
+
disabled: (item) => false
|
|
2288
|
+
},
|
|
2289
|
+
{
|
|
2290
|
+
key: 'delete',
|
|
2291
|
+
label: '🗑️',
|
|
2292
|
+
variant: 'danger',
|
|
2293
|
+
onClick: (item) => console.log('Delete', item),
|
|
2294
|
+
disabled: (item) => false,
|
|
2295
|
+
loading: (item) => item.deleting || false
|
|
2296
|
+
}
|
|
2297
|
+
]
|
|
2298
|
+
};
|
|
2299
|
+
// Configuração para GeographyTable - Regions
|
|
2300
|
+
const regionsTableConfig = {
|
|
2301
|
+
columns: [
|
|
2302
|
+
{
|
|
2303
|
+
key: 'region_id',
|
|
2304
|
+
label: 'ID',
|
|
2305
|
+
width: '80px',
|
|
2306
|
+
render: CellRenderers.id
|
|
2307
|
+
},
|
|
2308
|
+
{
|
|
2309
|
+
key: 'name',
|
|
2310
|
+
label: 'Nome',
|
|
2311
|
+
width: '1fr',
|
|
2312
|
+
render: CellRenderers.name
|
|
2313
|
+
},
|
|
2314
|
+
{
|
|
2315
|
+
key: 'code',
|
|
2316
|
+
label: 'Código',
|
|
2317
|
+
width: '120px',
|
|
2318
|
+
render: CellRenderers.name
|
|
2319
|
+
},
|
|
2320
|
+
{
|
|
2321
|
+
key: 'created_at',
|
|
2322
|
+
label: 'Criado em',
|
|
2323
|
+
width: '140px',
|
|
2324
|
+
render: CellRenderers.date
|
|
2325
|
+
},
|
|
2326
|
+
{
|
|
2327
|
+
key: 'created_by',
|
|
2328
|
+
label: 'Criado por',
|
|
2329
|
+
width: '140px',
|
|
2330
|
+
render: (value) => CellRenderers.name(value)
|
|
2331
|
+
}
|
|
2332
|
+
],
|
|
2333
|
+
actions: [
|
|
2334
|
+
{
|
|
2335
|
+
key: 'edit',
|
|
2336
|
+
label: '✏️',
|
|
2337
|
+
variant: 'secondary',
|
|
2338
|
+
onClick: (item) => console.log('Edit region', item)
|
|
2339
|
+
},
|
|
2340
|
+
{
|
|
2341
|
+
key: 'delete',
|
|
2342
|
+
label: '🗑️',
|
|
2343
|
+
variant: 'danger',
|
|
2344
|
+
onClick: (item) => console.log('Delete region', item),
|
|
2345
|
+
loading: (item) => item.deleting || false
|
|
2346
|
+
}
|
|
2347
|
+
]
|
|
2348
|
+
};
|
|
2349
|
+
// Configuração para GeographyTable - Countries
|
|
2350
|
+
const countriesTableConfig = {
|
|
2351
|
+
columns: [
|
|
2352
|
+
{
|
|
2353
|
+
key: 'country_id',
|
|
2354
|
+
label: 'ID',
|
|
2355
|
+
width: '80px',
|
|
2356
|
+
render: CellRenderers.id
|
|
2357
|
+
},
|
|
2358
|
+
{
|
|
2359
|
+
key: 'name',
|
|
2360
|
+
label: 'Nome',
|
|
2361
|
+
width: '1fr',
|
|
2362
|
+
render: CellRenderers.name
|
|
2363
|
+
},
|
|
2364
|
+
{
|
|
2365
|
+
key: 'iso2',
|
|
2366
|
+
label: 'Código',
|
|
2367
|
+
width: '120px',
|
|
2368
|
+
render: (value, item) => CellRenderers.combinedWithBadges(value, [
|
|
2369
|
+
{ value: item.iso3, variant: 'primary' }
|
|
2370
|
+
])
|
|
2371
|
+
},
|
|
2372
|
+
{
|
|
2373
|
+
key: 'capital',
|
|
2374
|
+
label: 'Capital',
|
|
2375
|
+
width: '140px',
|
|
2376
|
+
render: CellRenderers.name
|
|
2377
|
+
},
|
|
2378
|
+
{
|
|
2379
|
+
key: 'region',
|
|
2380
|
+
label: 'Região',
|
|
2381
|
+
width: '120px',
|
|
2382
|
+
render: (value) => CellRenderers.badge(value, 'info')
|
|
2383
|
+
}
|
|
2384
|
+
],
|
|
2385
|
+
actions: [
|
|
2386
|
+
{
|
|
2387
|
+
key: 'edit',
|
|
2388
|
+
label: '✏️',
|
|
2389
|
+
variant: 'secondary',
|
|
2390
|
+
onClick: (item) => console.log('Edit country', item)
|
|
2391
|
+
},
|
|
2392
|
+
{
|
|
2393
|
+
key: 'delete',
|
|
2394
|
+
label: '🗑️',
|
|
2395
|
+
variant: 'danger',
|
|
2396
|
+
onClick: (item) => console.log('Delete country', item)
|
|
2397
|
+
}
|
|
2398
|
+
]
|
|
2399
|
+
};
|
|
2400
|
+
// Configuração para Audit Log
|
|
2401
|
+
const auditLogTableConfig = {
|
|
2402
|
+
columns: [
|
|
2403
|
+
{
|
|
2404
|
+
key: 'timestamp',
|
|
2405
|
+
label: 'Data/Hora',
|
|
2406
|
+
width: '140px',
|
|
2407
|
+
render: CellRenderers.date
|
|
2408
|
+
},
|
|
2409
|
+
{
|
|
2410
|
+
key: 'user_email',
|
|
2411
|
+
label: 'Usuário',
|
|
2412
|
+
width: '180px',
|
|
2413
|
+
render: CellRenderers.name
|
|
2414
|
+
},
|
|
2415
|
+
{
|
|
2416
|
+
key: 'action',
|
|
2417
|
+
label: 'Ação',
|
|
2418
|
+
width: '100px',
|
|
2419
|
+
render: CellRenderers.actionType
|
|
2420
|
+
},
|
|
2421
|
+
{
|
|
2422
|
+
key: 'entity_type',
|
|
2423
|
+
label: 'Tipo',
|
|
2424
|
+
width: '120px',
|
|
2425
|
+
render: (value) => CellRenderers.badge(value, 'primary')
|
|
2426
|
+
},
|
|
2427
|
+
{
|
|
2428
|
+
key: 'entity_id',
|
|
2429
|
+
label: 'ID',
|
|
2430
|
+
width: '120px',
|
|
2431
|
+
render: CellRenderers.description
|
|
2432
|
+
},
|
|
2433
|
+
{
|
|
2434
|
+
key: 'changes',
|
|
2435
|
+
label: 'Alterações',
|
|
2436
|
+
width: '1fr',
|
|
2437
|
+
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: {
|
|
2438
|
+
background: 'none',
|
|
2439
|
+
border: '1px solid var(--border-color)',
|
|
2440
|
+
borderRadius: '4px',
|
|
2441
|
+
padding: '4px 8px',
|
|
2442
|
+
color: 'var(--text-primary)',
|
|
2443
|
+
fontSize: '12px',
|
|
2444
|
+
cursor: 'pointer',
|
|
2445
|
+
display: 'flex',
|
|
2446
|
+
alignItems: 'center',
|
|
2447
|
+
gap: '4px',
|
|
2448
|
+
transition: 'all 0.2s ease',
|
|
2449
|
+
whiteSpace: 'nowrap'
|
|
2450
|
+
}, children: [ActionIcons.view, "Ver Detalhes"] })] }))
|
|
2451
|
+
}
|
|
2452
|
+
]
|
|
2453
|
+
};
|
|
2454
|
+
// Configuração para States
|
|
2455
|
+
const statesTableConfig = {
|
|
2456
|
+
columns: [
|
|
2457
|
+
{
|
|
2458
|
+
key: 'state_id',
|
|
2459
|
+
label: 'ID',
|
|
2460
|
+
width: '80px',
|
|
2461
|
+
render: CellRenderers.id
|
|
2462
|
+
},
|
|
2463
|
+
{
|
|
2464
|
+
key: 'name',
|
|
2465
|
+
label: 'Nome',
|
|
2466
|
+
width: '1fr',
|
|
2467
|
+
render: CellRenderers.name
|
|
2468
|
+
},
|
|
2469
|
+
{
|
|
2470
|
+
key: 'code',
|
|
2471
|
+
label: 'Código',
|
|
2472
|
+
width: '120px',
|
|
2473
|
+
render: CellRenderers.name
|
|
2474
|
+
},
|
|
2475
|
+
{
|
|
2476
|
+
key: 'country_name',
|
|
2477
|
+
label: 'País',
|
|
2478
|
+
width: '140px',
|
|
2479
|
+
render: (value) => CellRenderers.badge(value, 'info')
|
|
2480
|
+
}
|
|
2481
|
+
],
|
|
2482
|
+
actions: [
|
|
2483
|
+
{
|
|
2484
|
+
key: 'edit',
|
|
2485
|
+
label: '✏️',
|
|
2486
|
+
variant: 'secondary',
|
|
2487
|
+
onClick: (item) => console.log('Edit state', item)
|
|
2488
|
+
},
|
|
2489
|
+
{
|
|
2490
|
+
key: 'delete',
|
|
2491
|
+
label: '🗑️',
|
|
2492
|
+
variant: 'danger',
|
|
2493
|
+
onClick: (item) => console.log('Delete state', item)
|
|
2494
|
+
}
|
|
2495
|
+
]
|
|
2496
|
+
};
|
|
2497
|
+
// Configuração para Cities
|
|
2498
|
+
const citiesTableConfig = {
|
|
2499
|
+
columns: [
|
|
2500
|
+
{
|
|
2501
|
+
key: 'city_id',
|
|
2502
|
+
label: 'ID',
|
|
2503
|
+
width: '80px',
|
|
2504
|
+
render: CellRenderers.id
|
|
2505
|
+
},
|
|
2506
|
+
{
|
|
2507
|
+
key: 'name',
|
|
2508
|
+
label: 'Nome',
|
|
2509
|
+
width: '1fr',
|
|
2510
|
+
render: CellRenderers.name
|
|
2511
|
+
},
|
|
2512
|
+
{
|
|
2513
|
+
key: 'population',
|
|
2514
|
+
label: 'População',
|
|
2515
|
+
width: '120px',
|
|
2516
|
+
render: (value) => (jsxRuntimeExports.jsx("div", { style: { color: 'var(--text-primary)', fontSize: '14px' }, children: value ? value.toLocaleString('pt-BR') : '-' }))
|
|
2517
|
+
},
|
|
2518
|
+
{
|
|
2519
|
+
key: 'state_name',
|
|
2520
|
+
label: 'Estado',
|
|
2521
|
+
width: '140px',
|
|
2522
|
+
render: (value) => CellRenderers.badge(value, 'success')
|
|
2523
|
+
},
|
|
2524
|
+
{
|
|
2525
|
+
key: 'country_name',
|
|
2526
|
+
label: 'País',
|
|
2527
|
+
width: '120px',
|
|
2528
|
+
render: (value) => CellRenderers.badge(value, 'info')
|
|
2529
|
+
}
|
|
2530
|
+
],
|
|
2531
|
+
actions: [
|
|
2532
|
+
{
|
|
2533
|
+
key: 'edit',
|
|
2534
|
+
label: '✏️',
|
|
2535
|
+
variant: 'secondary',
|
|
2536
|
+
onClick: (item) => console.log('Edit city', item)
|
|
2537
|
+
},
|
|
2538
|
+
{
|
|
2539
|
+
key: 'delete',
|
|
2540
|
+
label: '🗑️',
|
|
2541
|
+
variant: 'danger',
|
|
2542
|
+
onClick: (item) => console.log('Delete city', item)
|
|
2543
|
+
}
|
|
2544
|
+
]
|
|
2545
|
+
};
|
|
2546
|
+
// Função helper para aplicar configuração baseada no tipo
|
|
2547
|
+
const getTableConfig = (type) => {
|
|
2548
|
+
switch (type) {
|
|
2549
|
+
case 'parameters':
|
|
2550
|
+
return parametersTableConfig;
|
|
2551
|
+
case 'regions':
|
|
2552
|
+
return regionsTableConfig;
|
|
2553
|
+
case 'countries':
|
|
2554
|
+
return countriesTableConfig;
|
|
2555
|
+
case 'states':
|
|
2556
|
+
return statesTableConfig;
|
|
2557
|
+
case 'cities':
|
|
2558
|
+
return citiesTableConfig;
|
|
2559
|
+
case 'audit':
|
|
2560
|
+
return auditLogTableConfig;
|
|
2561
|
+
default:
|
|
2562
|
+
return parametersTableConfig;
|
|
2563
|
+
}
|
|
2564
|
+
};
|
|
2565
|
+
|
|
2566
|
+
/**
|
|
2567
|
+
* FormField - Normalized wrapper for form inputs
|
|
2568
|
+
*
|
|
2569
|
+
* Pattern extracted from AdminUserModal.tsx (backoffice/users)
|
|
2570
|
+
* Provides consistent label, error, and helper text styling
|
|
2571
|
+
*/
|
|
2572
|
+
function FormField({ label, required = false, error, helper, disabled = false, children, className = '' }) {
|
|
2573
|
+
return (jsxRuntimeExports.jsxs("div", { className: `mds-form-field ${className}`, style: { opacity: disabled ? 0.6 : 1 }, children: [jsxRuntimeExports.jsxs("label", { style: {
|
|
2574
|
+
display: 'block',
|
|
2575
|
+
marginBottom: '6px',
|
|
2576
|
+
color: 'var(--mds-color-text-primary, var(--text-primary))',
|
|
2577
|
+
fontSize: '0.9rem',
|
|
2578
|
+
fontWeight: 500
|
|
2579
|
+
}, children: [label, required && (jsxRuntimeExports.jsx("span", { style: { color: 'var(--mds-color-error, #ef4444)', marginLeft: '4px' }, children: "*" }))] }), children, error && (jsxRuntimeExports.jsx("span", { style: {
|
|
2580
|
+
color: 'var(--mds-color-error, #ef4444)',
|
|
2581
|
+
fontSize: '0.8rem',
|
|
2582
|
+
marginTop: '4px',
|
|
2583
|
+
display: 'block'
|
|
2584
|
+
}, children: error })), helper && !error && (jsxRuntimeExports.jsx("span", { style: {
|
|
2585
|
+
color: 'var(--mds-color-text-secondary, var(--text-secondary))',
|
|
2586
|
+
fontSize: '0.75rem',
|
|
2587
|
+
marginTop: '4px',
|
|
2588
|
+
display: 'block'
|
|
2589
|
+
}, children: helper }))] }));
|
|
2590
|
+
}
|
|
2591
|
+
|
|
2592
|
+
const gapValues = {
|
|
2593
|
+
sm: '12px',
|
|
2594
|
+
md: '16px',
|
|
2595
|
+
lg: '24px'
|
|
2596
|
+
};
|
|
2597
|
+
/**
|
|
2598
|
+
* FormGrid - Normalized grid layout for form fields
|
|
2599
|
+
*
|
|
2600
|
+
* Pattern extracted from AdminUserModal.tsx (backoffice/users)
|
|
2601
|
+
* Provides consistent 1 or 2 column layouts with proper gap
|
|
2602
|
+
*/
|
|
2603
|
+
function FormGrid({ columns = 1, gap = 'md', children, className = '' }) {
|
|
2604
|
+
return (jsxRuntimeExports.jsx("div", { className: `mds-form-grid ${className}`, style: {
|
|
2605
|
+
display: 'grid',
|
|
2606
|
+
gridTemplateColumns: columns === 2 ? 'repeat(2, 1fr)' : '1fr',
|
|
2607
|
+
gap: gapValues[gap]
|
|
2608
|
+
}, children: children }));
|
|
2609
|
+
}
|
|
2610
|
+
|
|
2611
|
+
/**
|
|
2612
|
+
* FormSection - Normalized section wrapper for grouping form fields
|
|
2613
|
+
*
|
|
2614
|
+
* Pattern extracted from AdminUserModal.tsx (backoffice/users)
|
|
2615
|
+
* Provides consistent section headers and spacing
|
|
2616
|
+
*/
|
|
2617
|
+
function FormSection({ title, description, children, className = '' }) {
|
|
2618
|
+
return (jsxRuntimeExports.jsxs("div", { className: `mds-form-section ${className}`, style: {
|
|
2619
|
+
marginBottom: '24px'
|
|
2620
|
+
}, children: [title && (jsxRuntimeExports.jsx("h4", { style: {
|
|
2621
|
+
margin: '0 0 8px 0',
|
|
2622
|
+
color: 'var(--mds-color-text-primary, var(--text-primary))',
|
|
2623
|
+
fontSize: '1rem',
|
|
2624
|
+
fontWeight: 600,
|
|
2625
|
+
letterSpacing: '-0.02em'
|
|
2626
|
+
}, children: title })), description && (jsxRuntimeExports.jsx("p", { style: {
|
|
2627
|
+
margin: '0 0 16px 0',
|
|
2628
|
+
color: 'var(--mds-color-text-secondary, var(--text-secondary))',
|
|
2629
|
+
fontSize: '0.85rem',
|
|
2630
|
+
lineHeight: 1.5
|
|
2631
|
+
}, children: description })), jsxRuntimeExports.jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: '16px' }, children: children })] }));
|
|
2632
|
+
}
|
|
2633
|
+
|
|
2634
|
+
const variantColors = {
|
|
2635
|
+
default: {
|
|
2636
|
+
bg: 'rgba(255, 255, 255, 0.03)',
|
|
2637
|
+
border: 'rgba(255, 255, 255, 0.1)',
|
|
2638
|
+
accent: 'var(--mds-color-text-secondary, #888)'
|
|
2639
|
+
},
|
|
2640
|
+
info: {
|
|
2641
|
+
bg: 'rgba(59, 130, 246, 0.1)',
|
|
2642
|
+
border: 'rgba(59, 130, 246, 0.2)',
|
|
2643
|
+
accent: 'var(--mds-color-info, #3b82f6)'
|
|
2644
|
+
},
|
|
2645
|
+
success: {
|
|
2646
|
+
bg: 'rgba(16, 185, 129, 0.1)',
|
|
2647
|
+
border: 'rgba(16, 185, 129, 0.2)',
|
|
2648
|
+
accent: 'var(--mds-color-success, #10b981)'
|
|
2649
|
+
},
|
|
2650
|
+
warning: {
|
|
2651
|
+
bg: 'rgba(245, 158, 11, 0.1)',
|
|
2652
|
+
border: 'rgba(245, 158, 11, 0.2)',
|
|
2653
|
+
accent: 'var(--mds-color-warning, #f59e0b)'
|
|
2654
|
+
},
|
|
2655
|
+
danger: {
|
|
2656
|
+
bg: 'rgba(239, 68, 68, 0.1)',
|
|
2657
|
+
border: 'rgba(239, 68, 68, 0.2)',
|
|
2658
|
+
accent: 'var(--mds-color-error, #ef4444)'
|
|
2659
|
+
}
|
|
2660
|
+
};
|
|
2661
|
+
/**
|
|
2662
|
+
* InfoBox - Normalized info/alert box for read-only information
|
|
2663
|
+
*
|
|
2664
|
+
* Pattern extracted from AdminUserModal.tsx (backoffice/users)
|
|
2665
|
+
* Provides consistent info boxes for alerts, status displays, and read-only data
|
|
2666
|
+
*
|
|
2667
|
+
* @example
|
|
2668
|
+
* // Alert style (with accent)
|
|
2669
|
+
* <InfoBox variant="info" accent>
|
|
2670
|
+
* An invitation email will be sent...
|
|
2671
|
+
* </InfoBox>
|
|
2672
|
+
*
|
|
2673
|
+
* @example
|
|
2674
|
+
* // Status display (default)
|
|
2675
|
+
* <InfoBox title="User Information">
|
|
2676
|
+
* <InfoRow label="Status" value="Active" />
|
|
2677
|
+
* <InfoRow label="Created" value="Jan 1, 2024" />
|
|
2678
|
+
* </InfoBox>
|
|
2679
|
+
*/
|
|
2680
|
+
function InfoBox({ title, variant = 'default', accent = false, copyable = false, children, className = '' }) {
|
|
2681
|
+
const colors = variantColors[variant];
|
|
2682
|
+
const handleCopy = () => {
|
|
2683
|
+
if (!copyable)
|
|
2684
|
+
return;
|
|
2685
|
+
const text = typeof children === 'string' ? children : '';
|
|
2686
|
+
if (text) {
|
|
2687
|
+
navigator.clipboard.writeText(text);
|
|
2688
|
+
}
|
|
2689
|
+
};
|
|
2690
|
+
return (jsxRuntimeExports.jsxs("div", { className: `mds-info-box ${className}`, style: {
|
|
2691
|
+
padding: '12px 16px',
|
|
2692
|
+
backgroundColor: colors.bg,
|
|
2693
|
+
borderRadius: '8px',
|
|
2694
|
+
border: `1px solid ${colors.border}`,
|
|
2695
|
+
borderLeft: accent ? `4px solid ${colors.accent}` : `1px solid ${colors.border}`,
|
|
2696
|
+
cursor: copyable ? 'pointer' : 'default'
|
|
2697
|
+
}, onClick: copyable ? handleCopy : undefined, title: copyable ? 'Click to copy' : undefined, children: [title && (jsxRuntimeExports.jsx("div", { style: {
|
|
2698
|
+
color: 'var(--mds-color-text-secondary, var(--text-secondary))',
|
|
2699
|
+
fontSize: '0.85rem',
|
|
2700
|
+
marginBottom: '8px',
|
|
2701
|
+
fontWeight: 500
|
|
2702
|
+
}, children: title })), jsxRuntimeExports.jsx("div", { style: {
|
|
2703
|
+
color: 'var(--mds-color-text-primary, var(--text-primary))',
|
|
2704
|
+
fontSize: '0.9rem',
|
|
2705
|
+
lineHeight: 1.5
|
|
2706
|
+
}, children: children })] }));
|
|
2707
|
+
}
|
|
2708
|
+
function InfoRow({ label, value, valueColor }) {
|
|
2709
|
+
return (jsxRuntimeExports.jsxs("div", { style: {
|
|
2710
|
+
display: 'flex',
|
|
2711
|
+
justifyContent: 'space-between',
|
|
2712
|
+
fontSize: '0.85rem',
|
|
2713
|
+
padding: '2px 0'
|
|
2714
|
+
}, children: [jsxRuntimeExports.jsxs("span", { style: { color: 'var(--mds-color-text-secondary, var(--text-secondary))' }, children: [label, ":"] }), jsxRuntimeExports.jsx("span", { style: { color: valueColor || 'var(--mds-color-text-primary, var(--text-primary))' }, children: value })] }));
|
|
2715
|
+
}
|
|
2716
|
+
|
|
2717
|
+
/**
|
|
2718
|
+
* Theme-aware styles generator - Liquid Glass pattern
|
|
2719
|
+
*
|
|
2720
|
+
* Light theme: White semi-transparent overlay to keep background bright
|
|
2721
|
+
* Dark theme: Dark overlay for contrast
|
|
2722
|
+
*/
|
|
2723
|
+
function getStyles(isDark) {
|
|
2724
|
+
return {
|
|
2725
|
+
// Overlay behind the modal
|
|
2726
|
+
overlay: {
|
|
2727
|
+
position: 'fixed',
|
|
2728
|
+
inset: 0,
|
|
2729
|
+
zIndex: 9999,
|
|
2730
|
+
display: 'flex',
|
|
2731
|
+
alignItems: 'center',
|
|
2732
|
+
justifyContent: 'center',
|
|
2733
|
+
padding: 20,
|
|
2734
|
+
// Light theme: white overlay to keep brightness
|
|
2735
|
+
// Dark theme: dark overlay for contrast
|
|
2736
|
+
backgroundColor: isDark ? 'rgba(0, 0, 0, 0.6)' : 'rgba(255, 255, 255, 0.4)',
|
|
2737
|
+
backdropFilter: 'blur(8px)',
|
|
2738
|
+
WebkitBackdropFilter: 'blur(8px)',
|
|
2739
|
+
},
|
|
2740
|
+
// Modal card - Liquid Glass
|
|
2741
|
+
card: {
|
|
2742
|
+
position: 'relative',
|
|
2743
|
+
maxWidth: 640,
|
|
2744
|
+
width: '100%',
|
|
2745
|
+
borderRadius: 24,
|
|
2746
|
+
overflow: 'hidden',
|
|
2747
|
+
// Light theme: Liquid Glass transparency
|
|
2748
|
+
// Dark theme: subtle glass effect
|
|
2749
|
+
background: isDark
|
|
2750
|
+
? 'rgba(255, 255, 255, 0.03)'
|
|
2751
|
+
: 'rgba(255, 255, 255, 0.45)',
|
|
2752
|
+
// Liquid Glass: Strong blur + saturation
|
|
2753
|
+
backdropFilter: 'blur(var(--mds-liquid-blur-xl, 24px)) saturate(var(--mds-liquid-saturate-vibrant, 140%))',
|
|
2754
|
+
WebkitBackdropFilter: 'blur(var(--mds-liquid-blur-xl, 24px)) saturate(var(--mds-liquid-saturate-vibrant, 140%))',
|
|
2755
|
+
// Liquid Glass: Subtle border for edge definition
|
|
2756
|
+
border: isDark
|
|
2757
|
+
? '1px solid rgba(255, 255, 255, 0.08)'
|
|
2758
|
+
: '1px solid rgba(255, 255, 255, 0.9)',
|
|
2759
|
+
// Liquid Glass: Layered shadows + inner glow
|
|
2760
|
+
boxShadow: isDark
|
|
2761
|
+
? '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))'
|
|
2762
|
+
: '0 8px 32px rgba(0, 0, 0, 0.08), inset 0 1px 0 rgba(255, 255, 255, 1)',
|
|
2763
|
+
// Liquid Glass: Smooth transition
|
|
2764
|
+
transition: 'var(--mds-liquid-transition, all 0.25s cubic-bezier(0.25, 0.1, 0.25, 1))',
|
|
2765
|
+
},
|
|
2766
|
+
};
|
|
2767
|
+
}
|
|
2768
|
+
function Modal({ open, onClose, closeOnOverlay = true, children, className, style }) {
|
|
2769
|
+
const [mounted, setMounted] = useState(false);
|
|
2770
|
+
const [visible, setVisible] = useState(false);
|
|
2771
|
+
const [renderPortal, setRenderPortal] = useState(false);
|
|
2772
|
+
const [isDarkTheme, setIsDarkTheme] = useState(true);
|
|
2773
|
+
const containerRef = useRef(null);
|
|
2774
|
+
useEffect(() => setMounted(true), []);
|
|
2775
|
+
// Detect theme - EXACT same pattern as ProfileCard.tsx
|
|
2776
|
+
useEffect(() => {
|
|
2777
|
+
const checkTheme = () => {
|
|
2778
|
+
const theme = document.documentElement.getAttribute('data-theme');
|
|
2779
|
+
setIsDarkTheme(theme !== 'light');
|
|
2780
|
+
};
|
|
2781
|
+
checkTheme();
|
|
2782
|
+
// Watch for theme changes
|
|
2783
|
+
const observer = new MutationObserver((mutations) => {
|
|
2784
|
+
mutations.forEach((mutation) => {
|
|
2785
|
+
if (mutation.attributeName === 'data-theme') {
|
|
2786
|
+
checkTheme();
|
|
2787
|
+
}
|
|
2788
|
+
});
|
|
2789
|
+
});
|
|
2790
|
+
observer.observe(document.documentElement, { attributes: true });
|
|
2791
|
+
return () => observer.disconnect();
|
|
2792
|
+
}, []);
|
|
2793
|
+
useEffect(() => {
|
|
2794
|
+
if (!mounted)
|
|
2795
|
+
return;
|
|
2796
|
+
if (open) {
|
|
2797
|
+
setVisible(true);
|
|
2798
|
+
setRenderPortal(true);
|
|
2799
|
+
}
|
|
2800
|
+
else {
|
|
2801
|
+
setVisible(false);
|
|
2802
|
+
const t = setTimeout(() => setRenderPortal(false), 200);
|
|
2803
|
+
return () => clearTimeout(t);
|
|
2804
|
+
}
|
|
2805
|
+
}, [open, mounted]);
|
|
2806
|
+
useEffect(() => {
|
|
2807
|
+
if (!open)
|
|
2808
|
+
return;
|
|
2809
|
+
const onKeyDown = (e) => {
|
|
2810
|
+
if (e.key === 'Escape')
|
|
2811
|
+
onClose();
|
|
2812
|
+
};
|
|
2813
|
+
document.addEventListener('keydown', onKeyDown);
|
|
2814
|
+
return () => document.removeEventListener('keydown', onKeyDown);
|
|
2815
|
+
}, [open, onClose]);
|
|
2816
|
+
if (!mounted || (!renderPortal && !open))
|
|
2817
|
+
return null;
|
|
2818
|
+
// Get theme-aware styles (same pattern as ProfileCard)
|
|
2819
|
+
const styles = getStyles(isDarkTheme);
|
|
2820
|
+
const overlayStyle = {
|
|
2821
|
+
...styles.overlay,
|
|
2822
|
+
opacity: visible ? 1 : 0,
|
|
2823
|
+
transition: 'opacity 200ms ease',
|
|
2824
|
+
};
|
|
2825
|
+
const cardStyle = {
|
|
2826
|
+
...styles.card,
|
|
2827
|
+
transform: visible ? 'scale(1)' : 'scale(0.96)',
|
|
2828
|
+
opacity: visible ? 1 : 0,
|
|
2829
|
+
transition: 'opacity 200ms ease, transform 200ms cubic-bezier(0.4, 0, 0.2, 1)',
|
|
2830
|
+
...style,
|
|
2831
|
+
};
|
|
2832
|
+
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 }) }));
|
|
2833
|
+
return createPortal(content, document.body);
|
|
2834
|
+
}
|
|
2835
|
+
|
|
2836
|
+
const sizeMap$1 = {
|
|
2837
|
+
sm: '400px',
|
|
2838
|
+
md: '480px',
|
|
2839
|
+
lg: '600px',
|
|
2840
|
+
xl: '800px'
|
|
2841
|
+
};
|
|
2842
|
+
/**
|
|
2843
|
+
* FormModal - Normalized template for CRUD modal forms
|
|
2844
|
+
*
|
|
2845
|
+
* Pattern extracted from AdminUserModal.tsx (backoffice/users)
|
|
2846
|
+
* Provides consistent structure for create/edit entity modals
|
|
2847
|
+
*
|
|
2848
|
+
* @example
|
|
2849
|
+
* <FormModal
|
|
2850
|
+
* open={showModal}
|
|
2851
|
+
* onClose={() => setShowModal(false)}
|
|
2852
|
+
* onSubmit={handleSubmit}
|
|
2853
|
+
* title="Edit User"
|
|
2854
|
+
* info="Changes will be saved immediately."
|
|
2855
|
+
* infoVariant="info"
|
|
2856
|
+
* loading={isSaving}
|
|
2857
|
+
* submitText="Save"
|
|
2858
|
+
* >
|
|
2859
|
+
* <FormField label="Name" required error={errors.name}>
|
|
2860
|
+
* <input className="mds-input" value={name} onChange={...} />
|
|
2861
|
+
* </FormField>
|
|
2862
|
+
* </FormModal>
|
|
2863
|
+
*/
|
|
2864
|
+
function FormModal({ open, onClose, onSubmit, title, icon, subtitle, info, infoVariant = 'info', children, submitText = 'Save', cancelText = 'Cancel', loading = false, submitDisabled = false, size = 'md', className = '' }) {
|
|
2865
|
+
const handleSubmit = (e) => {
|
|
2866
|
+
e.preventDefault();
|
|
2867
|
+
onSubmit(e);
|
|
2868
|
+
};
|
|
2869
|
+
return (jsxRuntimeExports.jsxs(Modal, { open: open, onClose: onClose, closeOnOverlay: !loading, className: className, style: {
|
|
2870
|
+
maxWidth: sizeMap$1[size],
|
|
2871
|
+
maxHeight: '90vh',
|
|
2872
|
+
overflowY: 'auto',
|
|
2873
|
+
padding: '24px'
|
|
2874
|
+
}, children: [jsxRuntimeExports.jsxs("div", { style: {
|
|
2875
|
+
display: 'flex',
|
|
2876
|
+
alignItems: 'center',
|
|
2877
|
+
justifyContent: 'space-between',
|
|
2878
|
+
marginBottom: subtitle ? '8px' : '24px'
|
|
2879
|
+
}, children: [jsxRuntimeExports.jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '12px' }, children: [icon && (jsxRuntimeExports.jsx("div", { style: {
|
|
2880
|
+
display: 'flex',
|
|
2881
|
+
alignItems: 'center',
|
|
2882
|
+
justifyContent: 'center',
|
|
2883
|
+
width: 32,
|
|
2884
|
+
height: 32,
|
|
2885
|
+
fontSize: '1.25rem',
|
|
2886
|
+
lineHeight: 0,
|
|
2887
|
+
opacity: 0.5
|
|
2888
|
+
}, children: icon })), jsxRuntimeExports.jsx(Typography, { variant: "h3", color: "primary", style: { margin: 0 }, children: title })] }), jsxRuntimeExports.jsx("button", { type: "button", onClick: onClose, disabled: loading, style: {
|
|
2889
|
+
background: 'none',
|
|
2890
|
+
border: 'none',
|
|
2891
|
+
padding: '8px',
|
|
2892
|
+
cursor: loading ? 'not-allowed' : 'pointer',
|
|
2893
|
+
color: 'var(--mds-color-text-secondary)',
|
|
2894
|
+
opacity: loading ? 0.5 : 1,
|
|
2895
|
+
borderRadius: '6px',
|
|
2896
|
+
display: 'flex',
|
|
2897
|
+
alignItems: 'center',
|
|
2898
|
+
justifyContent: 'center',
|
|
2899
|
+
transition: 'all 0.2s ease'
|
|
2900
|
+
}, onMouseEnter: (e) => {
|
|
2901
|
+
if (!loading)
|
|
2902
|
+
e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.1)';
|
|
2903
|
+
}, onMouseLeave: (e) => {
|
|
2904
|
+
e.currentTarget.style.backgroundColor = 'transparent';
|
|
2905
|
+
}, "aria-label": "Close modal", children: jsxRuntimeExports.jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), jsxRuntimeExports.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) })] }), subtitle && (jsxRuntimeExports.jsx(Typography, { variant: "body", color: "secondary", style: { marginBottom: '24px', fontSize: '0.9rem' }, children: subtitle })), info && (jsxRuntimeExports.jsx("div", { style: { marginBottom: '20px' }, children: jsxRuntimeExports.jsx(InfoBox, { variant: infoVariant, accent: true, children: info }) })), jsxRuntimeExports.jsxs("form", { onSubmit: handleSubmit, style: { display: 'flex', flexDirection: 'column', gap: '16px' }, children: [children, jsxRuntimeExports.jsxs("div", { style: {
|
|
2906
|
+
display: 'flex',
|
|
2907
|
+
gap: '12px',
|
|
2908
|
+
justifyContent: 'flex-end',
|
|
2909
|
+
marginTop: '16px',
|
|
2910
|
+
paddingTop: '16px',
|
|
2911
|
+
borderTop: '1px solid rgba(255, 255, 255, 0.1)'
|
|
2912
|
+
}, children: [jsxRuntimeExports.jsx(Button, { variant: "secondary", size: "sm", type: "button", onClick: onClose, disabled: loading, style: { minWidth: '90px' }, children: cancelText }), jsxRuntimeExports.jsx(Button, { variant: "primary", size: "sm", type: "submit", loading: loading, disabled: loading || submitDisabled, style: { minWidth: '110px' }, children: submitText })] })] })] }));
|
|
2913
|
+
}
|
|
2914
|
+
|
|
2915
|
+
const sizeMap = {
|
|
2916
|
+
sm: '400px',
|
|
2917
|
+
md: '480px',
|
|
2918
|
+
lg: '600px',
|
|
2919
|
+
xl: '800px'
|
|
2920
|
+
};
|
|
2921
|
+
/**
|
|
2922
|
+
* DetailModal - Normalized template for read-only detail modals
|
|
2923
|
+
*
|
|
2924
|
+
* Pattern extracted from GeographyDetailsModal, AuditLogDetailModal (backoffice)
|
|
2925
|
+
* Provides consistent structure for viewing entity details
|
|
2926
|
+
*
|
|
2927
|
+
* @example
|
|
2928
|
+
* <DetailModal
|
|
2929
|
+
* open={showDetails}
|
|
2930
|
+
* onClose={() => setShowDetails(false)}
|
|
2931
|
+
* title="User Details"
|
|
2932
|
+
* subtitle="Created on Jan 1, 2024"
|
|
2933
|
+
* action={{
|
|
2934
|
+
* label: 'Edit',
|
|
2935
|
+
* onClick: handleEdit,
|
|
2936
|
+
* variant: 'primary'
|
|
2937
|
+
* }}
|
|
2938
|
+
* >
|
|
2939
|
+
* <InfoBox title="Basic Information">
|
|
2940
|
+
* <InfoRow label="Name" value={user.name} />
|
|
2941
|
+
* <InfoRow label="Email" value={user.email} />
|
|
2942
|
+
* </InfoBox>
|
|
2943
|
+
* </DetailModal>
|
|
2944
|
+
*/
|
|
2945
|
+
function DetailModal({ open, onClose, title, icon, subtitle, children, closeText = 'Close', action, size = 'md', className = '' }) {
|
|
2946
|
+
return (jsxRuntimeExports.jsxs(Modal, { open: open, onClose: onClose, closeOnOverlay: true, className: className, style: {
|
|
2947
|
+
maxWidth: sizeMap[size],
|
|
2948
|
+
maxHeight: '90vh',
|
|
2949
|
+
overflowY: 'auto',
|
|
2950
|
+
padding: '24px'
|
|
2951
|
+
}, children: [jsxRuntimeExports.jsxs("div", { style: {
|
|
2952
|
+
display: 'flex',
|
|
2953
|
+
alignItems: 'center',
|
|
2954
|
+
justifyContent: 'space-between',
|
|
2955
|
+
marginBottom: subtitle ? '8px' : '24px'
|
|
2956
|
+
}, children: [jsxRuntimeExports.jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '12px' }, children: [icon && (jsxRuntimeExports.jsx("div", { style: {
|
|
2957
|
+
display: 'flex',
|
|
2958
|
+
alignItems: 'center',
|
|
2959
|
+
justifyContent: 'center',
|
|
2960
|
+
width: 32,
|
|
2961
|
+
height: 32,
|
|
2962
|
+
fontSize: '1.25rem',
|
|
2963
|
+
lineHeight: 0,
|
|
2964
|
+
opacity: 0.5
|
|
2965
|
+
}, children: icon })), jsxRuntimeExports.jsx(Typography, { variant: "h3", color: "primary", style: { margin: 0 }, children: title })] }), jsxRuntimeExports.jsx("button", { type: "button", onClick: onClose, style: {
|
|
2966
|
+
background: 'none',
|
|
2967
|
+
border: 'none',
|
|
2968
|
+
padding: '8px',
|
|
2969
|
+
cursor: 'pointer',
|
|
2970
|
+
color: 'var(--mds-color-text-secondary)',
|
|
2971
|
+
borderRadius: '6px',
|
|
2972
|
+
display: 'flex',
|
|
2973
|
+
alignItems: 'center',
|
|
2974
|
+
justifyContent: 'center',
|
|
2975
|
+
transition: 'all 0.2s ease'
|
|
2976
|
+
}, onMouseEnter: (e) => {
|
|
2977
|
+
e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.1)';
|
|
2978
|
+
}, onMouseLeave: (e) => {
|
|
2979
|
+
e.currentTarget.style.backgroundColor = 'transparent';
|
|
2980
|
+
}, "aria-label": "Close modal", children: jsxRuntimeExports.jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), jsxRuntimeExports.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) })] }), subtitle && (jsxRuntimeExports.jsx(Typography, { variant: "body", color: "secondary", style: { marginBottom: '24px', fontSize: '0.9rem' }, children: subtitle })), jsxRuntimeExports.jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: '16px' }, children: children }), jsxRuntimeExports.jsxs("div", { style: {
|
|
2981
|
+
display: 'flex',
|
|
2982
|
+
gap: '12px',
|
|
2983
|
+
justifyContent: 'flex-end',
|
|
2984
|
+
marginTop: '24px',
|
|
2985
|
+
paddingTop: '16px',
|
|
2986
|
+
borderTop: '1px solid rgba(255, 255, 255, 0.1)'
|
|
2987
|
+
}, children: [jsxRuntimeExports.jsx(Button, { variant: "secondary", size: "sm", onClick: onClose, children: closeText }), action && (jsxRuntimeExports.jsx(Button, { variant: action.variant || 'primary', size: "sm", onClick: action.onClick, disabled: action.disabled, children: action.label }))] })] }));
|
|
2988
|
+
}
|
|
2989
|
+
|
|
2990
|
+
function ModalHeader({ title, icon, onClose, closeAriaLabel = 'Fechar', align = 'center' }) {
|
|
2991
|
+
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" }) }));
|
|
2992
|
+
if (align === 'center') {
|
|
2993
|
+
const iconBox = {
|
|
2994
|
+
position: 'absolute',
|
|
2995
|
+
left: 16,
|
|
2996
|
+
top: '50%',
|
|
2997
|
+
transform: 'translateY(-50%)',
|
|
2998
|
+
width: 32,
|
|
2999
|
+
height: 32,
|
|
3000
|
+
display: 'inline-flex',
|
|
3001
|
+
alignItems: 'center',
|
|
3002
|
+
justifyContent: 'center',
|
|
3003
|
+
fontSize: '1.25rem',
|
|
3004
|
+
lineHeight: 0,
|
|
3005
|
+
opacity: 0.5
|
|
3006
|
+
};
|
|
3007
|
+
const closeBox = {
|
|
3008
|
+
position: 'absolute',
|
|
3009
|
+
right: 16,
|
|
3010
|
+
top: '50%',
|
|
3011
|
+
transform: 'translateY(-50%)',
|
|
3012
|
+
width: 32,
|
|
3013
|
+
height: 32,
|
|
3014
|
+
display: 'inline-flex',
|
|
3015
|
+
alignItems: 'center',
|
|
3016
|
+
justifyContent: 'center',
|
|
3017
|
+
background: 'transparent',
|
|
3018
|
+
border: 'none',
|
|
3019
|
+
padding: 0,
|
|
3020
|
+
cursor: 'pointer',
|
|
3021
|
+
lineHeight: 0
|
|
3022
|
+
};
|
|
3023
|
+
return (jsxRuntimeExports.jsxs("div", { className: "mds-modal-header", style: {
|
|
3024
|
+
position: 'relative',
|
|
3025
|
+
padding: '16px 24px',
|
|
3026
|
+
marginBottom: 16,
|
|
3027
|
+
borderBottom: '1px solid var(--border-color)'
|
|
3028
|
+
}, 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 }))] }));
|
|
3029
|
+
}
|
|
3030
|
+
return (jsxRuntimeExports.jsxs("div", { className: "mds-modal-header", style: {
|
|
3031
|
+
display: 'flex',
|
|
3032
|
+
alignItems: 'center',
|
|
3033
|
+
gap: 12,
|
|
3034
|
+
padding: '16px 24px',
|
|
3035
|
+
marginBottom: 16,
|
|
3036
|
+
borderBottom: '1px solid var(--border-color)'
|
|
3037
|
+
}, 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, opacity: 0.5 }, 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 }))] }));
|
|
3038
|
+
}
|
|
3039
|
+
|
|
3040
|
+
function ModalBody({ children, style, className }) {
|
|
3041
|
+
return (jsxRuntimeExports.jsx("div", { className: className, style: { padding: '16px 24px', ...style }, children: children }));
|
|
3042
|
+
}
|
|
3043
|
+
|
|
3044
|
+
function ModalFooter({ children, align = 'end' }) {
|
|
3045
|
+
const justify = align === 'start' ? 'flex-start' : align === 'center' ? 'center' : 'flex-end';
|
|
3046
|
+
return (jsxRuntimeExports.jsx("div", { style: { display: 'flex', gap: 12, justifyContent: justify, borderTop: '1px solid var(--border-color)', padding: '16px 24px', marginTop: 8 }, children: children }));
|
|
3047
|
+
}
|
|
3048
|
+
|
|
3049
|
+
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" }) }));
|
|
3050
|
+
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" }) }));
|
|
3051
|
+
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" }) }));
|
|
3052
|
+
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" }) }));
|
|
3053
|
+
const toneIcon = {
|
|
3054
|
+
warning: IconWarning,
|
|
3055
|
+
danger: IconDanger,
|
|
3056
|
+
info: IconInfo,
|
|
3057
|
+
success: IconSuccess
|
|
3058
|
+
};
|
|
3059
|
+
function ConfirmDialog({ open, onClose, title, description, confirmText = 'Confirmar', cancelText = 'Cancelar', onConfirm, loading = false, tone = 'warning', icon, disableOverlayClose }) {
|
|
3060
|
+
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 })] })] }) }));
|
|
3061
|
+
}
|
|
3062
|
+
|
|
3063
|
+
export { ActionIcons, BrandLogo, Button, CellRenderers, ConfirmDialog, DataTable, DetailModal, FormField, FormGrid, FormModal, FormSection, GlassCard, InfoBox, InfoRow, Modal, ModalBody, ModalFooter, ModalHeader, ProfileCard, Select, TableHeader, TableRow, ThemeToggle, Typography, auditLogTableConfig, citiesTableConfig, cn, countriesTableConfig, getTableConfig, parametersTableConfig, regionsTableConfig, statesTableConfig };
|
|
1492
3064
|
//# sourceMappingURL=index.esm.js.map
|