## New Feature: Full Screen Slide Preview - Add SlidePreviewModal component for full screen slide preview in SlideEditor - ESC key support and temporary hint for user guidance - Proper aspect ratio handling with theme CSS inheritance - Modal follows existing UI patterns for consistency ## Import Standards Compliance (31 files updated) - Fix all imports to use explicit .tsx/.ts extensions per IMPORT_STANDARDS.md - Eliminate barrel imports in App.tsx for better Vite tree shaking - Add direct imports with explicit paths across entire codebase - Preserve CSS imports and external library imports unchanged ## Code Architecture Improvements - Add comprehensive CSS & Component Architecture Guidelines to CLAUDE.md - Document modal patterns, aspect ratio handling, and CSS reuse principles - Reference all coding standards files for consistent development workflow - Prevent future CSS overcomplication and component duplication ## Performance Optimizations - Enable Vite tree shaking with proper import structure - Improve module resolution speed with explicit extensions - Optimize build performance through direct imports ## Files Changed - 31 TypeScript/React files with import fixes - 2 new SlidePreviewModal files (component + CSS) - Updated project documentation and coding guidelines - Fixed aspect ratio CSS patterns across components 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
122 lines
2.6 KiB
TypeScript
122 lines
2.6 KiB
TypeScript
import React from 'react';
|
||
import { Modal } from './Modal.tsx';
|
||
|
||
interface AlertDialogProps {
|
||
isOpen: boolean;
|
||
onClose: () => void;
|
||
title?: string;
|
||
message: string;
|
||
type?: 'info' | 'warning' | 'error' | 'success';
|
||
confirmText?: string;
|
||
}
|
||
|
||
export const AlertDialog: React.FC<AlertDialogProps> = ({
|
||
isOpen,
|
||
onClose,
|
||
title,
|
||
message,
|
||
type = 'info',
|
||
confirmText = 'OK'
|
||
}) => {
|
||
const getIcon = () => {
|
||
switch (type) {
|
||
case 'error':
|
||
return '❌';
|
||
case 'warning':
|
||
return '⚠️';
|
||
case 'success':
|
||
return '✅';
|
||
default:
|
||
return 'ℹ️';
|
||
}
|
||
};
|
||
|
||
const getTitle = () => {
|
||
if (title) return title;
|
||
|
||
switch (type) {
|
||
case 'error':
|
||
return 'Error';
|
||
case 'warning':
|
||
return 'Warning';
|
||
case 'success':
|
||
return 'Success';
|
||
default:
|
||
return 'Information';
|
||
}
|
||
};
|
||
|
||
return (
|
||
<Modal isOpen={isOpen} onClose={onClose} size="small" title={getTitle()}>
|
||
<div className="alert-dialog">
|
||
<div className="alert-content">
|
||
<div className="alert-icon">{getIcon()}</div>
|
||
<p className="alert-message">{message}</p>
|
||
</div>
|
||
<div className="alert-actions">
|
||
<button
|
||
type="button"
|
||
className="button primary"
|
||
onClick={onClose}
|
||
autoFocus
|
||
>
|
||
{confirmText}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<style jsx>{`
|
||
.alert-dialog {
|
||
text-align: center;
|
||
}
|
||
|
||
.alert-content {
|
||
margin-bottom: 2rem;
|
||
}
|
||
|
||
.alert-icon {
|
||
font-size: 2.5rem;
|
||
margin-bottom: 1rem;
|
||
}
|
||
|
||
.alert-message {
|
||
color: #374151;
|
||
font-size: 1rem;
|
||
line-height: 1.5;
|
||
margin: 0;
|
||
}
|
||
|
||
.alert-actions {
|
||
display: flex;
|
||
justify-content: center;
|
||
gap: 0.75rem;
|
||
}
|
||
|
||
.button {
|
||
padding: 0.75rem 1.5rem;
|
||
border-radius: 0.5rem;
|
||
font-weight: 500;
|
||
font-size: 0.875rem;
|
||
border: none;
|
||
cursor: pointer;
|
||
transition: all 0.2s ease;
|
||
min-width: 80px;
|
||
}
|
||
|
||
.button.primary {
|
||
background: #3b82f6;
|
||
color: white;
|
||
}
|
||
|
||
.button.primary:hover {
|
||
background: #2563eb;
|
||
}
|
||
|
||
.button.primary:focus {
|
||
outline: 2px solid #3b82f6;
|
||
outline-offset: 2px;
|
||
}
|
||
`}</style>
|
||
</Modal>
|
||
);
|
||
}; |