UNPKG

nextjs-rich-text-editor

Version:

A modern, feature-rich rich text editor for React/Next.js apps with images, tables, and more.

571 lines (490 loc) 10 kB
/* Text Editor Styles - Simplified and Optimized */ .te-container { background: white; border-radius: 12px; box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); border: 1px solid #e5e7eb; overflow: hidden; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", sans-serif; position: relative; } /* Toolbar */ .te-toolbar { background: linear-gradient(to right, #f9fafb, #f3f4f6); border-bottom: 1px solid #e5e7eb; padding: 16px; position: sticky; top: 0; z-index: 100; } .te-toolbar-content { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; } .te-format-select { padding: 8px 12px; border: 1px solid #d1d5db; border-radius: 6px; font-size: 14px; background: white; cursor: pointer; transition: all 0.2s ease; } .te-format-select:focus { outline: none; border-color: #3b82f6; box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1); } .te-toolbar-btn { padding: 8px; border: none; background: transparent; border-radius: 6px; cursor: pointer; transition: all 0.2s ease; color: #374151; display: flex; align-items: center; justify-content: center; } .te-toolbar-btn:hover { background: #f3f4f6; box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); } .te-toolbar-btn-active { background: #dbeafe; color: #1d4ed8; border: 1px solid #bfdbfe; } .te-separator { width: 1px; height: 32px; background: #d1d5db; } /* Color Button */ .te-color-btn-container { position: relative; } .te-color-btn-content { display: flex; align-items: center; } .te-color-indicator { width: 16px; height: 4px; margin-left: 4px; border-radius: 2px; border: 1px solid #d1d5db; } /* Color Picker */ .te-color-picker { position: absolute; top: 100%; left: 0; margin-top: 8px; padding: 12px; background: white; border: 1px solid #e5e7eb; border-radius: 8px; box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); z-index: 20; min-width: 220px; } .te-color-picker-actions { margin-bottom: 12px; padding-bottom: 12px; border-bottom: 1px solid #e5e7eb; display: flex; flex-direction: column; gap: 8px; } .te-color-action-btn { width: 100%; padding: 8px; text-align: left; font-size: 14px; background: transparent; border: 1px solid #e5e7eb; border-radius: 4px; cursor: pointer; transition: all 0.2s ease; } .te-color-action-btn:hover { background: #f9fafb; } .te-custom-color-btn { background: linear-gradient(to right, #fef3c7, #fde68a, #dbeafe); } .te-color-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 8px; } .te-color-swatch { width: 24px; height: 24px; border: 1px solid #d1d5db; border-radius: 4px; cursor: pointer; transition: transform 0.15s ease; } .te-color-swatch:hover { transform: scale(1.1); } /* Link Dialog */ .te-link-dialog-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.5); display: flex; align-items: center; justify-content: center; z-index: 1000; } .te-link-dialog { background: white; border-radius: 12px; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); width: 90%; max-width: 500px; max-height: 90vh; overflow: hidden; } .te-link-dialog-header { display: flex; align-items: center; justify-content: space-between; padding: 20px 24px; border-bottom: 1px solid #e5e7eb; background: #f9fafb; } .te-link-dialog-header h3 { margin: 0; font-size: 18px; font-weight: 600; color: #1f2937; } .te-link-dialog-close { background: none; border: none; font-size: 24px; cursor: pointer; color: #6b7280; padding: 4px; border-radius: 4px; transition: all 0.2s ease; } .te-link-dialog-close:hover { background: #e5e7eb; color: #374151; } .te-link-dialog-content { padding: 24px; } .te-link-dialog-field { margin-bottom: 20px; } .te-link-dialog-field label { display: block; margin-bottom: 8px; font-weight: 500; color: #374151; font-size: 14px; } .te-link-input { width: 100%; padding: 12px 16px; border: 1px solid #d1d5db; border-radius: 8px; font-size: 14px; transition: all 0.2s ease; box-sizing: border-box; } .te-link-input:focus { outline: none; border-color: #3b82f6; box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1); } .te-link-dialog-actions { display: flex; gap: 12px; justify-content: flex-end; padding: 20px 24px; border-top: 1px solid #e5e7eb; background: #f9fafb; } .te-link-btn { padding: 10px 20px; border-radius: 6px; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.2s ease; border: 1px solid transparent; } .te-link-btn-cancel { background: white; color: #374151; border-color: #d1d5db; } .te-link-btn-cancel:hover { background: #f9fafb; } .te-link-btn-insert { background: #3b82f6; color: white; } .te-link-btn-insert:hover:not(:disabled) { background: #2563eb; } .te-link-btn-insert:disabled { background: #9ca3af; cursor: not-allowed; } /* Editor */ .te-editor-container { position: relative; } .te-editor { padding: 24px; outline: none; color: #1f2937; line-height: 1.7; word-wrap: break-word; overflow-wrap: break-word; overflow: auto; } .te-placeholder { position: absolute; top: 24px; left: 24px; color: #9ca3af; pointer-events: none; user-select: none; } /* Content Styles */ .te-editor h1 { font-size: 2.25rem; font-weight: 700; margin: 1.5rem 0 1rem 0; line-height: 1.2; color: #1f2937; } .te-editor h2 { font-size: 1.875rem; font-weight: 600; margin: 1.25rem 0 0.75rem 0; line-height: 1.3; color: #374151; } .te-editor h3 { font-size: 1.5rem; font-weight: 600; margin: 1rem 0 0.5rem 0; line-height: 1.4; color: #4b5563; } .te-editor h4 { font-size: 1.25rem; font-weight: 500; margin: 0.875rem 0 0.5rem 0; line-height: 1.4; color: #6b7280; } .te-editor h5 { font-size: 1.125rem; font-weight: 500; margin: 0.75rem 0 0.25rem 0; line-height: 1.5; color: #6b7280; } .te-editor h6 { font-size: 1rem; font-weight: 500; margin: 0.5rem 0 0.25rem 0; line-height: 1.5; color: #9ca3af; } .te-editor p { margin: 0.75rem 0; line-height: 1.7; } .te-editor ul, .te-editor ol { margin: 1rem 0; padding-left: 2rem; } .te-editor li { margin: 0.5rem 0; line-height: 1.6; } /* Link Styles */ .te-editor a, .te-link { color: #3b82f6 !important; text-decoration: underline !important; cursor: pointer !important; transition: color 0.2s ease !important; } .te-editor a:hover, .te-link:hover { color: #1d4ed8 !important; } /* Table Styles */ .te-table { border-collapse: collapse; width: 100%; margin: 1.5rem 0; border: 2px solid #e5e7eb; border-radius: 8px; overflow: hidden; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); background: white; } .te-table td, .te-table th { border: 1px solid #e5e7eb; padding: 12px 16px; min-width: 120px; text-align: left; } .te-table th { background-color: #f8fafc; font-weight: 600; color: #374151; } .te-table td { background-color: white; color: #1f2937; } .te-table tr:hover td { background-color: #f9fafb; } /* Image Styles */ .te-image-container { margin: 16px 0; text-align: center; } .te-image { max-width: 100%; height: auto; border-radius: 8px; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); transition: all 0.2s ease; } .te-resizable { cursor: pointer; } .te-resizable:hover { transform: scale(1.02); } /* Utility Classes */ .te-hidden { display: none; } .te-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 10; } /* Loading States */ .te-loading { background: #f9fafb; } .te-loading-toolbar { height: 80px; background: #f3f4f6; border-bottom: 1px solid #e5e7eb; } .te-loading-content { padding: 24px; } .te-loading-line { height: 16px; background: #e5e7eb; border-radius: 4px; margin-bottom: 16px; animation: te-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; } .te-loading-line-1 { width: 75%; } .te-loading-line-2 { width: 50%; } .te-loading-line-3 { width: 83%; } @keyframes te-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } /* Responsive Design */ @media (max-width: 768px) { .te-toolbar-content { gap: 8px; } .te-toolbar-btn { padding: 6px; } .te-format-select { padding: 6px 8px; font-size: 12px; } .te-editor { padding: 16px; } .te-placeholder { top: 16px; left: 16px; } .te-link-dialog { width: 95%; margin: 20px; } .te-link-dialog-content { padding: 16px; } .te-link-dialog-actions { padding: 16px; flex-direction: column; } .te-link-btn { width: 100%; } } /* Ensure file inputs are completely hidden */ .te-hidden { display: none !important; visibility: hidden !important; position: absolute !important; left: -9999px !important; width: 0 !important; height: 0 !important; opacity: 0 !important; pointer-events: none !important; } /* Prevent any file inputs from appearing in the editor content */ .te-editor input[type="file"] { display: none !important; } /* Override any global styles that might show file inputs */ .te-container input[type="file"]:not(.te-visible-file-input) { display: none !important; }