Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 12 additions & 21 deletions apps/frontend/src/app/app.css
Original file line number Diff line number Diff line change
@@ -1,29 +1,20 @@
.editor-container {
margin-top: 2rem;
width: 100%;
max-width: 800px;
}
/* App-specific utilities - using Tailwind apply directive for complex styles */

.editor-container h3 {
color: var(--gray-900);
margin-bottom: 1rem;
font-size: 1.5rem;
font-weight: 500;
/* App container styles */
.app-container {
@apply h-full min-h-screen bg-gradient-to-br from-gray-900 via-slate-900 to-gray-800;
}

.content {
flex-direction: column !important;
max-width: 1200px !important;
align-items: flex-start !important;
.editor-layout {
@apply max-w-7xl mx-auto w-full h-full flex flex-col;
}

.left-side {
width: 100% !important;
max-width: none !important;
/* Custom focus styles for better accessibility */
.focus-ring {
@apply focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus:ring-offset-gray-900;
}

@media screen and (max-width: 650px) {
.editor-container {
width: 100%;
}
/* Smooth transitions for interactive elements */
.transition-smooth {
@apply transition-all duration-200 ease-in-out;
}
6 changes: 5 additions & 1 deletion apps/frontend/src/app/app.html
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
<router-outlet />
<div class="app-container">
<div class="editor-layout">
<router-outlet />
</div>
</div>
109 changes: 44 additions & 65 deletions apps/frontend/src/app/components/editor/editor.component.css
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
/* Editor Container Styles */
.editor-container {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* Monaco Editor Custom Styles */
:host ::ng-deep .monaco-editor {
padding-top: 10px;
}

/* Monaco Editor Deep Styling */
:host ::ng-deep .monaco-editor .margin {
background-color: #1f2937;
}
Expand All @@ -16,76 +7,64 @@
background-color: #111827;
}

/* Loading Animation */
@keyframes spin {
to {
transform: rotate(360deg);
}
:host ::ng-deep .monaco-editor .current-line {
background-color: rgba(59, 130, 246, 0.1) !important;
}

.animate-spin {
animation: spin 1s linear infinite;
/* Custom Button Ripple Effect */
.btn-ripple {
@apply relative overflow-hidden transform-gpu;
}

/* Button Hover Effects */
button {
position: relative;
overflow: hidden;
.btn-ripple::before {
content: '';
@apply absolute top-1/2 left-1/2 w-0 h-0 rounded-full bg-white/10 transform -translate-x-1/2 -translate-y-1/2 transition-all duration-500;
}

button::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
transform: translate(-50%, -50%);
transition: width 0.6s, height 0.6s;
.btn-ripple:hover::before {
@apply w-72 h-72;
}

button:hover::before {
width: 300px;
height: 300px;
/* Enhanced Editor Header */
.editor-header-gradient {
@apply bg-gradient-to-r from-gray-800 via-gray-800/95 to-gray-800 backdrop-blur-sm;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
}

/* Responsive Design */
@media (max-width: 768px) {
.editor-header {
padding: 1rem;
}

.editor-header h2 {
font-size: 1rem;
}

.editor-header p {
display: none;
}

button span {
display: none;
}

button {
padding: 0.5rem 1rem;
/* Status bar enhancements */
.status-bar-glass {
@apply backdrop-blur-md bg-gray-800/80 border-t border-gray-700/50;
box-shadow: 0 -4px 6px -1px rgba(0, 0, 0, 0.1);
}

/* Loading state enhancements */
.loading-backdrop {
@apply absolute inset-0 bg-gray-900/20 backdrop-blur-sm flex items-center justify-center z-10;
}

/* Responsive button text hiding */
@media (min-width: 768px) {
.btn-text-hidden {
@apply hidden;
}
}

/* Accessibility */
button:focus {
outline: 2px solid #3b82f6;
outline-offset: 2px;
.btn-text-shown {
@apply block;
}

@media (min-width: 768px) {
.btn-text-shown {
@apply inline;
}
}

button:focus:not(:focus-visible) {
outline: none;
/* Focus ring for accessibility */
.focus-ring-editor {
@apply focus:outline-none focus:ring-2 focus:ring-blue-400 focus:ring-offset-2 focus:ring-offset-gray-900 rounded-lg;
}

/* Editor Footer */
.editor-footer {
backdrop-filter: blur(10px);
background-color: rgba(31, 41, 55, 0.95);
/* Code syntax highlighting enhancements */
.code-highlight {
@apply font-mono text-sm leading-relaxed;
}
71 changes: 49 additions & 22 deletions apps/frontend/src/app/components/editor/editor.component.html
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
<div class="editor-container h-screen flex flex-col bg-gray-900">
<div class="editor-container h-screen flex flex-col relative bg-gray-900">
<!-- Header with title and actions -->
<div class="editor-header bg-gray-800 px-6 py-4 border-b border-gray-700">
<div class="editor-header editor-header-gradient px-4 sm:px-6 py-4 border-b border-gray-700/50">
<div class="flex items-center justify-between">
<div>
<h2 class="text-xl font-semibold text-white">Soroban Smart Contract Editor</h2>
<p class="text-sm text-gray-400 mt-1">Write and test your Rust smart contracts</p>
<div class="flex items-center space-x-4">
<div class="hidden sm:flex w-10 h-10 bg-gradient-to-br from-blue-500 to-purple-600 rounded-lg items-center justify-center">
<svg class="w-6 h-6 text-white" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/>
</svg>
</div>
<div>
<h2 class="text-xl sm:text-2xl font-bold text-white tracking-tight">Soroban Smart Contract Editor</h2>
<p class="text-sm text-gray-300 mt-1 hidden sm:block">Write and test your Rust smart contracts</p>
</div>
</div>

<div class="flex gap-3" role="toolbar" aria-label="Editor actions">
<div class="flex gap-2 sm:gap-3" role="toolbar" aria-label="Editor actions">
<button
(click)="onCompile()"
[disabled]="isLoading || !code.trim()"
class="px-6 py-2 bg-blue-500 text-white font-medium rounded-lg hover:bg-blue-600 disabled:bg-gray-600 disabled:cursor-not-allowed transition-colors duration-200 flex items-center gap-2"
[class.opacity-50]="isLoading"
class="btn-ripple focus-ring-editor px-4 sm:px-6 py-2 bg-gradient-to-r from-blue-500 to-blue-600 hover:from-blue-600 hover:to-blue-700 text-white font-medium rounded-lg disabled:from-gray-600 disabled:to-gray-600 disabled:cursor-not-allowed transition-all duration-200 flex items-center gap-2 shadow-lg hover:shadow-xl transform hover:scale-105 active:scale-95"
[class.opacity-75]="isLoading"
[class.animate-pulse]="isLoading"
aria-label="Compile Rust smart contract"
[attr.aria-busy]="isLoading"
>
Expand All @@ -23,14 +31,15 @@ <h2 class="text-xl font-semibold text-white">Soroban Smart Contract Editor</h2>
<svg *ngIf="!isLoading" class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
</svg>
<span>{{ isLoading ? 'Compiling...' : 'Compile' }}</span>
<span class="btn-text-shown">{{ isLoading ? 'Compiling...' : 'Compile' }}</span>
</button>

<button
(click)="onTest()"
[disabled]="isLoading || !code.trim()"
class="px-6 py-2 bg-green-500 text-white font-medium rounded-lg hover:bg-green-600 disabled:bg-gray-600 disabled:cursor-not-allowed transition-colors duration-200 flex items-center gap-2"
[class.opacity-50]="isLoading"
class="btn-ripple focus-ring-editor px-4 sm:px-6 py-2 bg-gradient-to-r from-green-500 to-green-600 hover:from-green-600 hover:to-green-700 text-white font-medium rounded-lg disabled:from-gray-600 disabled:to-gray-600 disabled:cursor-not-allowed transition-all duration-200 flex items-center gap-2 shadow-lg hover:shadow-xl transform hover:scale-105 active:scale-95"
[class.opacity-75]="isLoading"
[class.animate-pulse]="isLoading"
aria-label="Test Rust smart contract"
[attr.aria-busy]="isLoading"
>
Expand All @@ -41,7 +50,7 @@ <h2 class="text-xl font-semibold text-white">Soroban Smart Contract Editor</h2>
<svg *ngIf="!isLoading" class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<span>{{ isLoading ? 'Testing...' : 'Test' }}</span>
<span class="btn-text-shown">{{ isLoading ? 'Testing...' : 'Test' }}</span>
</button>
</div>
</div>
Expand All @@ -51,29 +60,47 @@ <h2 class="text-xl font-semibold text-white">Soroban Smart Contract Editor</h2>
<div class="flex-1 overflow-hidden" role="main" aria-label="Code editor">
<ngx-monaco-editor
*ngIf="isBrowser"
class="h-full"
class="h-full w-full"
[(ngModel)]="code"
[options]="editorOptions"
></ngx-monaco-editor>
<div *ngIf="!isBrowser" class="h-full flex items-center justify-center bg-gray-800 text-gray-400">
Loading editor...
<div *ngIf="!isBrowser" class="h-full w-full flex flex-col items-center justify-center bg-gray-800 text-gray-400">
<svg class="animate-spin h-8 w-8 text-blue-500 mx-auto mb-4" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
<p class="text-sm font-medium">Loading editor...</p>
</div>
</div>

<!-- Status bar -->
<div class="editor-footer bg-gray-800 px-6 py-2 border-t border-gray-700" role="status" aria-live="polite" aria-label="Editor status">
<div class="editor-footer status-bar-glass px-4 sm:px-6 py-3" role="status" aria-live="polite" aria-label="Editor status">
<div class="flex items-center justify-between text-sm">
<div class="flex items-center gap-4 text-gray-400">
<span class="flex items-center gap-1">
<div class="flex items-center gap-4 sm:gap-6 text-gray-300">
<span class="flex items-center gap-2 bg-orange-500/20 text-orange-300 px-2 py-1 rounded-md">
<svg class="h-4 w-4" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M12.316 3.051a1 1 0 01.633 1.265l-4 12a1 1 0 11-1.898-.632l4-12a1 1 0 011.265-.633zM5.707 6.293a1 1 0 010 1.414L3.414 10l2.293 2.293a1 1 0 11-1.414 1.414l-3-3a1 1 0 010-1.414l3-3a1 1 0 011.414 0zm8.586 0a1 1 0 011.414 0l3 3a1 1 0 010 1.414l-3 3a1 1 0 11-1.414-1.414L16.586 10l-2.293-2.293a1 1 0 010-1.414z" clip-rule="evenodd"></path>
</svg>
Rust
<span class="font-medium">Rust</span>
</span>
<span class="flex items-center gap-1 text-gray-400">
<svg class="h-3 w-3" fill="currentColor" viewBox="0 0 20 20">
<path d="M4 4a2 2 0 00-2 2v8a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2H4z"/>
</svg>
UTF-8
</span>
<span>UTF-8</span>
</div>
<div class="text-gray-400">
<span *ngIf="code">{{ code.split('\n').length }} lines</span>
<div class="flex items-center gap-4 text-gray-300">
<span *ngIf="code" class="flex items-center gap-1 bg-gray-700/50 px-2 py-1 rounded-md">
<svg class="h-3 w-3" fill="currentColor" viewBox="0 0 20 20">
<path d="M3 4a1 1 0 011-1h12a1 1 0 011 1v2a1 1 0 01-1 1H4a1 1 0 01-1-1V4zM3 10a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H4a1 1 0 01-1-1v-6zM14 9a1 1 0 00-1 1v6a1 1 0 001 1h2a1 1 0 001-1v-6a1 1 0 00-1-1h-2z"/>
</svg>
<span class="font-mono text-xs">{{ code.split('\n').length }} lines</span>
</span>
<span class="hidden sm:flex items-center gap-1 text-xs text-gray-500">
<div class="w-2 h-2 bg-green-500 rounded-full animate-pulse"></div>
Ready
</span>
</div>
</div>
</div>
Expand Down
8 changes: 5 additions & 3 deletions apps/frontend/src/index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
<!doctype html>
<html lang="en">
<html lang="en" class="h-full">
<head>
<meta charset="utf-8">
<title>Online Soroban Compiler 📟 - Scaffold Rust</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="Scaffold-Rust-Logo.jpg">
<meta name="description" content="Online Soroban smart contract compiler and editor for Rust development">
<meta name="theme-color" content="#111827">
</head>
<body>
<app-root></app-root>
<body class="h-full bg-gray-900 text-gray-100 font-inter antialiased">
<app-root class="h-full block"></app-root>
</body>
</html>
Loading
Loading