@ozdemircibaris/react-image-editor
Version:
Professional React image editor component with blur, crop, shapes, drawing, and undo/redo functionality. Built with Fabric.js and modern React patterns.
3 lines (2 loc) • 20 kB
TypeScript
export declare const imageEditorStyles = "\n/* Image Editor Styles - Dark Mode Theme */\n.image-editor-container {\n width: 100%;\n height: 100vh;\n display: flex;\n flex-direction: column;\n background: linear-gradient(135deg, #111827 0%, #1f2937 50%, #000000 100%);\n color: white;\n overflow: hidden; /* Scroll bar'\u0131 engelle */\n}\n\n/* Ensure custom background classes can override the default gradient */\n.image-editor-container[class*=\"bg-\"] {\n background: inherit !important;\n}\n\n.image-editor-container[class*=\"bg-red-\"] {\n background-color: inherit !important;\n background-image: none !important;\n}\n\n.image-editor-container[class*=\"bg-blue-\"] {\n background-color: inherit !important;\n background-image: none !important;\n}\n\n.image-editor-container[class*=\"bg-green-\"] {\n background-color: inherit !important;\n background-image: none !important;\n}\n\n.image-editor-container[class*=\"bg-yellow-\"] {\n background-color: inherit !important;\n background-image: none !important;\n}\n\n.image-editor-container[class*=\"bg-purple-\"] {\n background-color: inherit !important;\n background-image: none !important;\n}\n\n.image-editor-container[class*=\"bg-pink-\"] {\n background-color: inherit !important;\n background-image: none !important;\n}\n\n.image-editor-container[class*=\"bg-gray-\"] {\n background-color: inherit !important;\n background-image: none !important;\n}\n\n.image-editor-header {\n background: rgba(17, 24, 39, 0.5);\n backdrop-filter: blur(8px);\n border-bottom: 1px solid #374151;\n padding: 1rem 1.5rem;\n margin: 0;\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n\n.image-editor-header-left {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n}\n\n.image-editor-header-button {\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #d1d5db;\n transition: all 0.2s ease;\n}\n\n.image-editor-header-button:hover {\n color: #3b82f6;\n transform: scale(1.05);\n}\n\n.image-editor-title {\n color: white;\n font-size: 0.875rem;\n font-weight: 600;\n background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n}\n\n.image-editor-actions {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n}\n\n.image-editor-button {\n padding: 0.5rem 1rem;\n border-radius: 0.5rem;\n font-weight: 500;\n transition: all 0.2s ease;\n border: none;\n cursor: pointer;\n transform: translateY(0);\n}\n\n.image-editor-button-primary {\n background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);\n color: white;\n box-shadow: 0 4px 14px 0 rgba(59, 130, 246, 0.25);\n}\n\n.image-editor-button-primary:hover {\n background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%);\n transform: translateY(-1px);\n box-shadow: 0 6px 20px 0 rgba(59, 130, 246, 0.35);\n}\n\n.image-editor-button-secondary {\n background: rgba(75, 85, 99, 0.5);\n color: white;\n border: 1px solid #374151;\n}\n\n.image-editor-button-secondary:hover {\n background: rgba(75, 85, 99, 0.7);\n border-color: #4b5563;\n}\n\n.image-editor-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n}\n\n/* Toolbar Styles */\n.toolbar {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.5rem 0;\n}\n\n.toolbar-button {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 2.5rem;\n height: 2.5rem;\n border-radius: 0.5rem;\n transition: all 0.2s ease;\n color: #d1d5db;\n border: 1px solid transparent;\n cursor: pointer;\n background: rgba(31, 41, 55, 0.5);\n backdrop-filter: blur(4px);\n}\n\n.toolbar-button:hover {\n background: rgba(59, 130, 246, 0.1);\n border-color: #3b82f6;\n color: #3b82f6;\n transform: scale(1.05);\n}\n\n.toolbar-button.active {\n background: rgba(59, 130, 246, 0.2);\n border-color: #3b82f6;\n color: #3b82f6;\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);\n}\n\n.toolbar-button:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n transform: none;\n}\n\n.toolbar-button.delete-button {\n background: rgba(220, 38, 38, 0.1);\n border-color: rgba(220, 38, 38, 0.3);\n color: #ef4444;\n}\n\n.toolbar-button.delete-button:hover {\n background: rgba(220, 38, 38, 0.2);\n border-color: #ef4444;\n color: #fca5a5;\n transform: scale(1.05);\n}\n\n.toolbar-divider {\n width: 1px;\n height: 2rem;\n background: linear-gradient(180deg, transparent 0%, #374151 50%, transparent 100%);\n margin: 0 0.5rem;\n}\n\n/* Color Palette */\n.color-palette {\n padding: 0.75rem;\n background: rgba(31, 41, 55, 0.8);\n backdrop-filter: blur(8px);\n border-radius: 0.75rem;\n border: 1px solid #374151;\n box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.3);\n}\n\n.color-palette-grid {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n max-width: 12rem;\n}\n\n.color-button {\n width: 1.5rem;\n height: 1.5rem;\n border-radius: 0.375rem;\n border: 2px solid;\n transition: all 0.2s ease;\n cursor: pointer;\n position: relative;\n overflow: hidden;\n}\n\n.color-button::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, transparent 100%);\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.color-button:hover::before {\n opacity: 1;\n}\n\n.color-button.active {\n border-color: #3b82f6;\n transform: scale(1.15);\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3);\n}\n\n.color-button:not(.active) {\n border-color: rgba(255, 255, 255, 0.2);\n}\n\n/* Width Slider */\n.width-slider {\n padding: 0.75rem;\n background: rgba(31, 41, 55, 0.8);\n backdrop-filter: blur(8px);\n border-radius: 0.75rem;\n border: 1px solid #374151;\n min-width: 24rem;\n}\n\n.width-slider-content {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n}\n\n.width-slider-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: #d1d5db;\n}\n\n.width-slider-input {\n flex: 1;\n}\n\n.width-slider-value {\n font-size: 0.875rem;\n color: #9ca3af;\n width: 2rem;\n text-align: center;\n}\n\n/* Canvas Container */\n.canvas-container {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgba(31, 41, 55, 0.3);\n padding: 1rem;\n position: relative;\n}\n\n.canvas-container::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: radial-gradient(circle at center, rgba(59, 130, 246, 0.05) 0%, transparent 70%);\n pointer-events: none;\n}\n\n.canvas-wrapper {\n background: rgba(17, 24, 39, 0.5);\n backdrop-filter: blur(8px);\n border-radius: 1rem;\n border: 1px solid #374151;\n box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);\n overflow: hidden;\n max-width: calc(100vw - 200px);\n max-height: calc(100vh - 200px);\n position: relative;\n}\n\n.canvas-wrapper::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: linear-gradient(135deg, rgba(59, 130, 246, 0.1) 0%, rgba(139, 92, 246, 0.1) 100%);\n pointer-events: none;\n border-radius: 1rem;\n}\n\n.canvas-element {\n display: block;\n border-radius: 1rem;\n width: 100%;\n height: 100%;\n background: transparent;\n}\n\n/* Crop Mode */\n.crop-mode {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem;\n background: rgba(17, 24, 39, 0.8);\n backdrop-filter: blur(8px);\n border-bottom: 1px solid #374151;\n border-top: 1px solid #374151;\n}\n\n.crop-mode-text {\n color: #d1d5db;\n font-weight: 500;\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n}\n\n.crop-mode-actions {\n display: flex;\n gap: 0.5rem;\n margin-left: auto;\n}\n\n.crop-button {\n padding: 0.5rem 1rem;\n border-radius: 0.5rem;\n font-weight: 500;\n transition: all 0.2s ease;\n border: none;\n cursor: pointer;\n transform: translateY(0);\n}\n\n.crop-button-apply {\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n color: white;\n box-shadow: 0 4px 14px 0 rgba(16, 185, 129, 0.25);\n}\n\n.crop-button-apply:hover {\n background: linear-gradient(135deg, #059669 0%, #047857 100%);\n transform: translateY(-1px);\n box-shadow: 0 6px 20px 0 rgba(16, 185, 129, 0.35);\n}\n\n.crop-button-cancel {\n background: rgba(75, 85, 99, 0.5);\n color: white;\n border: 1px solid #374151;\n}\n\n.crop-button-cancel:hover {\n background: rgba(75, 85, 99, 0.7);\n border-color: #4b5563;\n}\n\n/* Utility Classes */\n.text-white {\n color: white;\n}\n\n.text-gray-300 {\n color: #d1d5db;\n}\n\n.text-gray-400 {\n color: #9ca3af;\n}\n\n.text-blue-400 {\n color: #60a5fa;\n}\n\n.text-yellow-400 {\n color: #fbbf24;\n}\n\n.bg-transparent {\n background-color: transparent;\n}\n\n.bg-gray-800/50 {\n background-color: rgba(31, 41, 55, 0.5);\n}\n\n.bg-gray-900/50 {\n background-color: rgba(17, 24, 39, 0.5);\n}\n\n.rounded-3xl {\n border-radius: 1.5rem;\n}\n\n.shadow-lg {\n box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3);\n}\n\n.shadow-2xl {\n box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);\n}\n\n.overflow-hidden {\n overflow: hidden;\n}\n\n.backdrop-blur-sm {\n backdrop-filter: blur(4px);\n}\n\n.backdrop-blur-md {\n backdrop-filter: blur(8px);\n}\n\n.flex {\n display: flex;\n}\n\n.flex-col {\n flex-direction: column;\n}\n\n.items-center {\n align-items: center;\n}\n\n.justify-center {\n justify-content: center;\n}\n\n.justify-between {\n justify-content: space-between;\n}\n\n.gap-2 {\n gap: 0.5rem;\n}\n\n.gap-3 {\n gap: 0.75rem;\n}\n\n.p-4 {\n padding: 1rem;\n}\n\n.px-6 {\n padding-left: 1.5rem;\n padding-right: 1.5rem;\n}\n\n.py-4 {\n padding-top: 1rem;\n padding-bottom: 1rem;\n}\n\n.m-2 {\n margin: 0.5rem;\n}\n\n.w-full {\n width: 100%;\n}\n\n.h-screen {\n height: 100vh;\n}\n\n.min-w-96 {\n min-width: 24rem;\n}\n\n.max-w-48 {\n max-width: 12rem;\n}\n\n.w-10 {\n width: 2.5rem;\n}\n\n.h-10 {\n height: 2.5rem;\n}\n\n.w-6 {\n width: 1.5rem;\n}\n\n.h-6 {\n height: 1.5rem;\n}\n\n.w-px {\n width: 1px;\n}\n\n.h-8 {\n height: 2rem;\n}\n\n.w-8 {\n width: 2rem;\n}\n\n.rounded-lg {\n border-radius: 0.5rem;\n}\n\n.transition-colors {\n transition: color 0.2s ease, background-color 0.2s ease;\n}\n\n.transition-all {\n transition: all 0.2s ease;\n}\n\n.opacity-50 {\n opacity: 0.5;\n}\n\n.cursor-pointer {\n cursor: pointer;\n}\n\n.cursor-not-allowed {\n cursor: not-allowed;\n}\n\n.inline-block {\n display: inline-block;\n}\n\n.text-sm {\n font-size: 0.875rem;\n}\n\n.font-medium {\n font-weight: 500;\n}\n\n.font-semibold {\n font-weight: 600;\n}\n\n.border-2 {\n border-width: 2px;\n}\n\n.border-gray-700 {\n border-color: #374151;\n}\n\n.border-white\\/10 {\n border-color: rgba(255, 255, 255, 0.1);\n}\n\n.border-white\\/20 {\n border-color: rgba(255, 255, 255, 0.2);\n}\n\n.scale-110 {\n transform: scale(1.1);\n}\n\n.scale-105 {\n transform: scale(1.05);\n}\n\n/* HeroUI Overrides for Dark Mode */\n.heroui-slider {\n flex: 1;\n}\n\n.heroui-slider-track {\n background-color: #374151;\n}\n\n.heroui-slider-filler {\n background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);\n}\n\n.heroui-slider-thumb {\n background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);\n border-color: #3b82f6;\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);\n}\n\n/* Glassmorphism Effects */\n.glass-effect {\n background: rgba(31, 41, 55, 0.5);\n backdrop-filter: blur(8px);\n border: 1px solid rgba(255, 255, 255, 0.1);\n}\n\n.glass-effect-strong {\n background: rgba(17, 24, 39, 0.9);\n backdrop-filter: blur(12px);\n border: 1px solid rgba(55, 65, 81, 0.7);\n box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.6);\n}\n\n/* Utility: remove default focus outlines where undesired */\n.no-focus-ring:focus {\n outline: none !important;\n box-shadow: none !important;\n}\n.no-focus-ring:focus-visible {\n outline: none !important;\n box-shadow: none !important;\n}\n\n/* Gradient Text Effects */\n.gradient-text-blue {\n background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n}\n\n.gradient-text-green {\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n}\n\n/* Hover Effects */\n.hover-lift {\n transition: all 0.2s ease;\n}\n\n.hover-lift:hover {\n transform: translateY(-2px);\n box-shadow: 0 8px 25px -5px rgba(0, 0, 0, 0.3);\n}\n\n/* Focus States */\n.focus-ring {\n outline: none;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.3);\n}\n\n/* Animation Classes */\n@keyframes fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.animate-fade-in {\n animation: fadeIn 0.3s ease-out;\n}\n\n@keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.7; }\n}\n\n.animate-pulse {\n animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n}\n\n/* Zoom Button Styles */\n.zoom-button {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n border: 1px solid rgba(255, 255, 255, 0.08);\n cursor: pointer;\n transition: all 0.2s ease;\n font-weight: 600;\n font-size: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.zoom-button:hover {\n transform: scale(1.1);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\n}\n\n/* Default styles - only apply when no custom className is provided */\n.zoom-button.zoom-in:not([style*=\"background\"]) {\n background: #3b82f6;\n color: white;\n border-color: rgba(59, 130, 246, 0.35);\n}\n\n.zoom-button.zoom-in:not([style*=\"background\"]):hover {\n background: #2563eb;\n}\n\n.zoom-button.zoom-out:not([style*=\"background\"]) {\n background: #1f2937;\n color: #d1d5db;\n border-color: rgba(255, 255, 255, 0.08);\n}\n\n.zoom-button.zoom-out:not([style*=\"background\"]):hover {\n background: #374151;\n color: #f3f4f6;\n}\n\n/* Ensure custom className props always override default styles */\n.zoom-button[class*=\"bg-\"] {\n background: inherit !important;\n}\n\n.zoom-button[class*=\"text-\"] {\n color: inherit !important;\n}\n\n.zoom-button[class*=\"border-\"] {\n border-color: inherit !important;\n}\n\n/* Customization Override Classes */\n.image-editor-container.custom-theme {\n background: var(--custom-background, linear-gradient(135deg, #111827 0%, #1f2937 50%, #000000 100%));\n}\n\n.toolbar.custom-toolbar {\n background: var(--custom-toolbar-bg, rgba(31, 41, 55, 0.5));\n border: var(--custom-toolbar-border, 1px solid #374151);\n}\n\n.toolbar-button.custom-button {\n background: var(--custom-button-bg, rgba(31, 41, 55, 0.5));\n border-color: var(--custom-button-border, transparent);\n color: var(--custom-button-color, #d1d5db);\n}\n\n.toolbar-button.custom-button:hover {\n background: var(--custom-button-hover-bg, rgba(59, 130, 246, 0.1));\n border-color: var(--custom-button-hover-border, #3b82f6);\n color: var(--custom-button-hover-color, #3b82f6);\n}\n\n.image-editor-button.custom-save-button {\n background: var(--custom-save-bg, linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%));\n color: var(--custom-save-color, white);\n border: var(--custom-save-border, none);\n}\n\n.image-editor-button.custom-cancel-button {\n background: var(--custom-cancel-bg, rgba(75, 85, 99, 0.5));\n color: var(--custom-cancel-color, white);\n border: var(--custom-cancel-border, 1px solid #374151);\n}\n\n.zoom-button.custom-zoom-button {\n background: var(--custom-zoom-bg, rgba(31, 41, 55, 0.9));\n color: var(--custom-zoom-color, #d1d5db);\n border: var(--custom-zoom-border, 1px solid rgba(255, 255, 255, 0.08));\n}\n\n.zoom-button.custom-zoom-button:hover {\n background: var(--custom-zoom-hover-bg, rgba(55, 65, 81, 0.9));\n transform: var(--custom-zoom-hover-transform, scale(1.1));\n}\n\n/* Save and Cancel Button Specific Styles */\n.image-editor-actions .image-editor-button {\n /* Ensure custom classes can override default styles */\n transition: all 0.2s ease;\n}\n\n.image-editor-actions .image-editor-button-primary {\n /* Default save button styles */\n background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);\n color: white;\n box-shadow: 0 4px 14px 0 rgba(59, 130, 246, 0.25);\n}\n\n.image-editor-actions .image-editor-button-primary:hover {\n background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%);\n transform: translateY(-1px);\n box-shadow: 0 6px 20px 0 rgba(59, 130, 246, 0.35);\n}\n\n.image-editor-actions .image-editor-button-secondary {\n /* Default cancel button styles */\n background: rgba(75, 85, 99, 0.5);\n color: white;\n border: 1px solid #374151;\n}\n\n.image-editor-actions .image-editor-button-secondary:hover {\n background: rgba(75, 85, 99, 0.7);\n border-color: #4b5563;\n}\n\n/* Ensure custom className props can override with !important if needed */\n.image-editor-actions .image-editor-button[class*=\"bg-\"] {\n background: inherit !important;\n}\n\n.image-editor-actions .image-editor-button[class*=\"text-\"] {\n color: inherit !important;\n}\n\n.image-editor-actions .image-editor-button[class*=\"border-\"] {\n border: inherit !important;\n}\n\n/* ===== MOBILE RESPONSIVE STYLES ===== */\n\n/* Mobile: 320px - 768px */\n@media (max-width: 768px) {\n /* Container mobile height */\n .image-editor-container {\n height: 100vh;\n min-height: 100vh;\n max-height: 100vh;\n }\n \n /* Toolbar mobile layout - sadece gerekli yerlerde alt alta */\n .toolbar {\n flex-wrap: wrap; /* Wrap yap ama column yapma */\n gap: 0.5rem;\n padding: 0.5rem;\n justify-content: center;\n }\n \n .toolbar-button {\n width: 2.75rem; /* \u00C7ok b\u00FCy\u00FCtme */\n height: 2.75rem;\n }\n \n /* Header mobile layout - sadece \u00E7ok dar ekranlarda */\n .image-editor-header {\n flex-direction: row; /* Yan yana b\u0131rak */\n gap: 0.5rem; /* Daha az gap */\n padding: 0.75rem; /* Daha az padding */\n flex-wrap: wrap; /* Gerekirse wrap yap */\n }\n \n .image-editor-actions {\n gap: 0.5rem;\n }\n \n .image-editor-button {\n padding: 0.5rem 1rem; /* Daha k\u00FC\u00E7\u00FCk padding */\n font-size: 0.85rem;\n }\n \n /* Canvas mobile size */\n .canvas-container {\n padding: 0.5rem; /* Desktop'taki 1rem'i mobile'da azalt */\n }\n \n .canvas-wrapper {\n max-width: calc(100vw - 8px) !important; /* Desktop'taki 200px'i override et */\n max-height: calc(100vh - 80px) !important; /* Desktop'taki 200px'i override et */\n margin: 0 4px !important;\n }\n \n /* Zoom buttons mobile */\n .zoom-button {\n width: 36px; /* Daha k\u00FC\u00E7\u00FCk */\n height: 36px;\n font-size: 16px;\n }\n \n /* Color palette mobile */\n .color-palette {\n min-width: 220px;\n padding: 0.5rem;\n }\n \n /* Width slider mobile */\n .width-slider {\n min-width: 220px;\n padding: 0.5rem;\n }\n \n /* Crop mode mobile */\n .crop-mode {\n padding: 0.5rem;\n gap: 0.5rem;\n }\n \n /* Space hint mobile */\n .canvas-wrapper .animate-fade-in {\n display: none; /* Mobile'da space hint'i gizle */\n }\n}\n\n/* Tablet: 768px - 1024px */\n@media (min-width: 768px) and (max-width: 1024px) {\n .toolbar {\n flex-wrap: wrap;\n justify-content: center;\n gap: 0.75rem;\n }\n \n .toolbar-button {\n width: 2.75rem;\n height: 2.75rem;\n }\n \n .canvas-wrapper {\n max-width: calc(100vw - 100px);\n max-height: calc(100vh - 180px);\n }\n}\n\n/* Large screens: 1024px+ */\n@media (min-width: 1024px) {\n .toolbar {\n flex-direction: row;\n gap: 0.75rem;\n padding: 0.5rem 0;\n }\n \n .image-editor-header {\n flex-direction: row;\n gap: 0;\n padding: 1rem 1.5rem;\n }\n}\n";
export declare const injectStyles: () => void;