'use client'; import { useDarkMode } from '@/state/darkModeStore'; import { themeTokens } from '@/utils/themeTokens'; import { Box, BoxProps, Divider, DividerProps, Paper } from '@mantine/core'; import React from 'react'; /** * Unified Surface Components * * Komponen container/card dengan styling konsisten * Mendukung dark mode sesuai spesifikasi darkMode.md * * Usage: * import { UnifiedCard, UnifiedDivider } from '@/components/admin/UnifiedSurface'; * * * Title * Content * */ // ============================================================================ // Unified Card Component interface UnifiedCardProps extends BoxProps { withBorder?: boolean; shadow?: 'none' | 'sm' | 'md' | 'lg'; padding?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl'; hoverable?: boolean; children: React.ReactNode; } export function UnifiedCard({ withBorder = true, shadow = 'none', // Sesuai spec: Jangan pakai shadow hitam padding = 'md', hoverable = false, children, style, ...props }: UnifiedCardProps) { const { isDark } = useDarkMode(); const tokens = themeTokens(isDark); const getPadding = () => { switch (padding) { case 'none': return 0; case 'xs': return tokens.spacing.xs; case 'sm': return tokens.spacing.sm; case 'md': return tokens.spacing.md; case 'lg': return tokens.spacing.lg; case 'xl': return tokens.spacing.xl; default: return tokens.spacing.md; } }; const getShadow = () => { if (shadow === 'none') return 'none'; return tokens.shadows[shadow]; }; return ( {children} ); } // ============================================================================ // Unified Card Section Components // ============================================================================ interface UnifiedCardSectionProps { children: React.ReactNode; padding?: 'none' | 'xs' | 'sm' | 'md' | 'lg'; border?: 'none' | 'top' | 'bottom'; style?: React.CSSProperties; } UnifiedCard.Header = function UnifiedCardHeader({ children, padding = 'md', border = 'bottom', style, }: UnifiedCardSectionProps) { const { isDark } = useDarkMode(); const tokens = themeTokens(isDark); const getPadding = () => { switch (padding) { case 'none': return 0; case 'xs': return tokens.spacing.xs; case 'sm': return tokens.spacing.sm; case 'md': return tokens.spacing.md; case 'lg': return tokens.spacing.lg; default: return tokens.spacing.md; } }; const borderBottom = border === 'bottom' ? `1px solid ${tokens.colors.border.soft}` : 'none'; const borderTop = border === 'top' ? `1px solid ${tokens.colors.border.soft}` : 'none'; return ( {children} ); }; UnifiedCard.Body = function UnifiedCardBody({ children, padding = 'md', style, }: UnifiedCardSectionProps) { const { isDark } = useDarkMode(); const tokens = themeTokens(isDark); const getPadding = () => { switch (padding) { case 'none': return 0; case 'xs': return tokens.spacing.xs; case 'sm': return tokens.spacing.sm; case 'md': return tokens.spacing.md; case 'lg': return tokens.spacing.lg; default: return tokens.spacing.md; } }; return ( {children} ); }; UnifiedCard.Footer = function UnifiedCardFooter({ children, padding = 'md', border = 'top', style, }: UnifiedCardSectionProps) { const { isDark } = useDarkMode(); const tokens = themeTokens(isDark); const getPadding = () => { switch (padding) { case 'none': return 0; case 'xs': return tokens.spacing.xs; case 'sm': return tokens.spacing.sm; case 'md': return tokens.spacing.md; case 'lg': return tokens.spacing.lg; default: return tokens.spacing.md; } }; const borderBottom = border === 'bottom' ? `1px solid ${tokens.colors.border.soft}` : 'none'; const borderTop = border === 'top' ? `1px solid ${tokens.colors.border.soft}` : 'none'; return ( {children} ); }; // ============================================================================ // Unified Divider Component // ============================================================================ interface UnifiedDividerProps extends DividerProps { variant?: 'default' | 'soft' | 'strong'; } export function UnifiedDivider({ variant = 'soft', // Default soft sesuai spec my = 'md', ...props }: UnifiedDividerProps) { const { isDark } = useDarkMode(); const tokens = themeTokens(isDark); const getColor = () => { switch (variant) { case 'default': return tokens.colors.border.default; case 'soft': return tokens.colors.border.soft; case 'strong': return tokens.colors.border.strong; default: return tokens.colors.border.soft; } }; return ; } export default UnifiedCard;