UNPKG

react-dialog-confirm

Version:

A modern, accessible React modal component library with multiple variants, animations, and enhanced features. Perfect for alerts, confirmations, and custom dialogs.

533 lines (450 loc) 10.2 kB
:root { /* Colors */ --black: #000000; --white: #ffffff; --gray-50: #f9fafb; --gray-100: #f3f4f6; --gray-200: #e5e7eb; --gray-300: #d1d5db; --gray-400: #9ca3af; --gray-500: #6b7280; --gray-600: #4b5563; --gray-700: #374151; --gray-800: #1f2937; --gray-900: #111827; /* Primary Colors */ --primary-50: #eff6ff; --primary-100: #dbeafe; --primary-500: #3b82f6; --primary-600: #2563eb; --primary-700: #1d4ed8; /* Success Colors */ --success-500: #10b981; --success-600: #059669; /* Warning Colors */ --warning-500: #f59e0b; --warning-600: #d97706; /* Error Colors */ --error-500: #ef4444; --error-600: #dc2626; /* Info Colors */ --info-500: #06b6d4; --info-600: #0891b2; /* Shadows */ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05); --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); --shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / 0.25); /* Border Radius */ --radius-sm: 0.25rem; --radius-md: 0.375rem; --radius-lg: 0.5rem; --radius-xl: 0.75rem; --radius-2xl: 1rem; /* Transitions */ --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1); --transition-normal: 200ms cubic-bezier(0.4, 0, 0.2, 1); --transition-slow: 300ms cubic-bezier(0.4, 0, 0.2, 1); } /* Base Modal Container */ .dialog--container { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 50; overflow-y: auto; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; display: flex; align-items: center; justify-content: center; padding: 1rem; } /* Size Variants - Make them more specific */ .dialog--container.dialog--sm .dialog--panel { max-width: 24rem; width: 100%; } .dialog--container.dialog--sm .dialog--card { padding: 1.25rem; } .dialog--container.dialog--sm .dialog--card--title { font-size: 1.125rem; } .dialog--container.dialog--sm .dialog--card--description { font-size: 0.8125rem; } .dialog--container.dialog--md .dialog--panel { max-width: 28rem; width: 100%; } .dialog--container.dialog--md .dialog--card { padding: 1.5rem; } .dialog--container.dialog--lg .dialog--panel { max-width: 32rem; width: 100%; } .dialog--container.dialog--lg .dialog--card { padding: 2rem; } .dialog--container.dialog--lg .dialog--card--title { font-size: 1.5rem; } .dialog--container.dialog--lg .dialog--card--description { font-size: 1rem; } .dialog--container.dialog--xl .dialog--panel { max-width: 36rem; width: 100%; } .dialog--container.dialog--xl .dialog--card { padding: 2.5rem; } .dialog--container.dialog--xl .dialog--card--title { font-size: 1.75rem; } .dialog--container.dialog--xl .dialog--card--description { font-size: 1.125rem; } .dialog--container.dialog--full .dialog--panel { max-width: 90vw; max-height: 90vh; width: 100%; } .dialog--container.dialog--full .dialog--card { padding: 3rem; } .dialog--container.dialog--full .dialog--card--title { font-size: 2rem; } .dialog--container.dialog--full .dialog--card--description { font-size: 1.25rem; } /* Position Variants */ .dialog--center .dialog--layout { align-items: center; justify-content: center; } .dialog--top .dialog--layout { align-items: flex-start; padding-top: 2rem; } .dialog--bottom .dialog--layout { align-items: flex-end; padding-bottom: 2rem; } .dialog--left .dialog--layout { justify-content: flex-start; padding-left: 2rem; } .dialog--right .dialog--layout { justify-content: flex-end; padding-right: 2rem; } /* Backdrop Variants */ .dialog--blur .dialog--overlay { backdrop-filter: blur(4px); background-color: rgba(0, 0, 0, 0.3); } .dialog--transparent .dialog--overlay { background-color: transparent; } .dialog--solid .dialog--overlay { background-color: rgba(0, 0, 0, 0.5); } /* Layout */ .dialog--layout { min-height: 100vh; width: 100%; display: flex; align-items: center; justify-content: center; position: relative; } /* Overlay */ .dialog--overlay { position: fixed; top: 0; right: 0; bottom: 0; left: 0; background-color: rgba(0, 0, 0, 0.5); transition: opacity var(--transition-normal); } /* Panel */ .dialog--panel { width: 100%; max-width: 28rem; background-color: var(--white); border-radius: var(--radius-xl); box-shadow: var(--shadow-2xl); overflow: hidden; transform: scale(0.95); opacity: 0; animation: modalEnter 0.3s cubic-bezier(0.16, 1, 0.3, 1) forwards; position: relative; z-index: 10; } /* Ensure panel is visible when modal is open */ .dialog--container:not(.dialog--out) .dialog--panel { opacity: 1; transform: scale(1); } /* Ensure panel is visible when modal is open (but don't override size) */ .dialog--container:not(.dialog--out) .dialog--panel { opacity: 1; transform: scale(1); } /* Only apply exit animation when closing */ .dialog--container.dialog--out .dialog--panel { animation: modalExit 0.3s cubic-bezier(0.16, 1, 0.3, 1) forwards; } /* Card */ .dialog--card { position: relative; padding: 1.5rem; background-color: var(--white); border-radius: var(--radius-xl); } /* Close Button */ .remover { cursor: pointer; position: absolute; top: 1rem; right: 1rem; width: 2rem; height: 2rem; border-radius: var(--radius-md); display: flex; align-items: center; justify-content: center; background-color: var(--gray-100); color: var(--gray-600); transition: all var(--transition-fast); z-index: 20; } .remover:hover { background-color: var(--gray-200); color: var(--gray-800); transform: scale(1.05); } .remover:disabled { opacity: 0.5; cursor: not-allowed; } .remover svg { width: 1.25rem; height: 1.25rem; } /* Icon */ .dialog--card--icon { width: 100%; display: flex; justify-content: center; margin-bottom: 1.5rem; } .dialog--card--icon svg { width: 3rem; height: 3rem; } /* Title */ .dialog--card--title { text-align: center; color: var(--gray-900); font-size: 1.25rem; line-height: 1.75rem; font-weight: 600; margin-bottom: 0.75rem; letter-spacing: -0.025em; } /* Description */ .dialog--card--description { margin-bottom: 1.5rem; font-size: 0.875rem; line-height: 1.5rem; color: var(--gray-600); text-align: center; font-weight: 400; } /* Button Container */ .dialog--card--button-container { display: flex; align-items: center; justify-content: center; gap: 0.75rem; width: 100%; position: relative; } /* Buttons */ .dialog--button { border-radius: var(--radius-lg); color: var(--white); padding: 0.75rem 1.5rem; cursor: pointer; border: none; font-size: 0.875rem; font-weight: 500; transition: all var(--transition-fast); min-width: 5rem; display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; } .dialog--button:focus { outline: 2px solid var(--primary-500); outline-offset: 2px; } .dialog--button:disabled { opacity: 0.6; cursor: not-allowed; transform: none !important; } /* Confirm Button */ .dialog--button-confirm { background-color: var(--primary-600); color: var(--white); } .dialog--button-confirm:hover:not(:disabled) { background-color: var(--primary-700); transform: translateY(-1px); box-shadow: var(--shadow-md); } .dialog--button-confirm:active:not(:disabled) { transform: translateY(0); } /* Cancel Button */ .dialog--button-cancel { background-color: var(--gray-100); color: var(--gray-700); } .dialog--button-cancel:hover:not(:disabled) { background-color: var(--gray-200); color: var(--gray-800); transform: translateY(-1px); } .dialog--button-cancel:active:not(:disabled) { transform: translateY(0); } /* Loading Spinner */ .dialog--loading { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 30; } .dialog--spinner { width: 1.5rem; height: 1.5rem; border: 2px solid var(--gray-200); border-top: 2px solid var(--primary-600); border-radius: 50%; animation: spin 1s linear infinite; } /* Exit Animation */ .dialog--out .dialog--panel { animation: modalExit var(--transition-slow) cubic-bezier(0.16, 1, 0.3, 1) forwards; } .dialog--out .dialog--overlay { opacity: 0; } /* Animations */ @keyframes modalEnter { 0% { transform: scale(0.95); opacity: 0; } 100% { transform: scale(1); opacity: 1; } } @keyframes modalExit { 0% { transform: scale(1); opacity: 1; } 100% { transform: scale(0.95); opacity: 0; } } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } /* Responsive Design */ @media (max-width: 640px) { .dialog--container { padding: 0.5rem; } .dialog--card { padding: 1rem; } .dialog--card--title { font-size: 1.125rem; } .dialog--card--button-container { flex-direction: column; gap: 0.5rem; } .dialog--button { width: 100%; justify-content: center; } .dialog--full .dialog--panel { max-width: 95vw; max-height: 95vh; } } /* Dark Mode Support */ @media (prefers-color-scheme: dark) { .dialog--card { background-color: var(--gray-800); color: var(--gray-100); } .dialog--card--title { color: var(--gray-100); } .dialog--card--description { color: var(--gray-300); } .dialog--button-cancel { background-color: var(--gray-700); color: var(--gray-200); } .dialog--button-cancel:hover:not(:disabled) { background-color: var(--gray-600); color: var(--gray-100); } .remover { background-color: var(--gray-700); color: var(--gray-300); } .remover:hover { background-color: var(--gray-600); color: var(--gray-100); } } /* Focus Management */ .dialog--panel:focus { outline: none; } /* Accessibility */ @media (prefers-reduced-motion: reduce) { .dialog--panel, .dialog--overlay, .dialog--button, .remover { animation: none; transition: none; } }