mirror of
https://github.com/compiler-explorer/compiler-explorer.git
synced 2025-12-27 10:33:59 -05:00
## Summary This PR completes Phase 2 of the SCSS migration to prepare for Dart Sass 3.0.0 compatibility. This phase focused on converting the complex conditional theme system from deprecated `@import` statements to modern `@use` statements. ## What Changed ### 🎯 Major Achievements - **Eliminated 43+ SCSS deprecation warnings** (down from 45+ to only 2 remaining) - **96% reduction** in deprecation warnings - **Converted all SCSS-to-SCSS imports** from `@import` to `@use` - **Modernized all color functions**: `lighten()`, `darken()`, `adjust-color()`, `transparentize()`, `opacify()` → `color.scale()` and `color.adjust()` - **Implemented CSS custom properties** for theme variable sharing - **Fixed theme isolation** - themes now properly scope their styles ### 🔧 Technical Changes - Added `@use` statements for all theme files at top of `explorer.scss` - Wrapped all theme file contents in `html[data-theme='...']` selectors - Added CSS custom properties (`:root { --lighter: #{$lighter}; }`) for theme variables - Scoped custom golden-layout themes within their respective theme selectors - Removed all conditional `@import` statements for SCSS files ### 📁 Files Modified - `static/styles/explorer.scss` - Added theme `@use` statements, removed conditional imports - `static/styles/themes/pink-theme.scss` - Scoped all styles, added CSS custom properties - `static/styles/themes/one-dark-theme.scss` - Scoped all styles, added CSS custom properties - `static/styles/themes/dark-theme.scss` - Scoped all styles - `static/styles/themes/default-theme.scss` - Scoped all styles - `static/styles/themes/custom-golden-layout-themes/pink.scss` - Scoped to pink theme - `static/styles/themes/custom-golden-layout-themes/one-dark.scss` - Scoped to one-dark theme ## Remaining Issues (Phase 3) ⚠️ **2 deprecation warnings remain** - these will eventually break in Dart Sass 3.0.0: ``` Line 1161: @import '~golden-layout/src/css/goldenlayout-light-theme'; Line 1168: @import '~golden-layout/src/css/goldenlayout-dark-theme'; ``` These are external CSS imports from the golden-layout library that cannot be converted to `@use` because: 1. They're CSS files, not SCSS files 2. They use webpack's `~` syntax for node_modules resolution 3. They're conditionally imported based on theme **Phase 3 will need to address these** by either: - Converting to regular CSS `@import` at top level - Using webpack's CSS importing mechanism - Including CSS files directly in HTML - Finding alternative golden-layout integration approach ## Testing - ✅ Webpack build succeeds with only 2 expected warnings - ✅ Visual testing confirms themes work correctly - ✅ Pink theme now shows proper light golden-layout theme (was showing dark before) - ✅ All theme styles properly isolated - no global style conflicts - ✅ CSS custom properties working for theme variables ## Build Output Current warnings (only external CSS imports remain): ``` WARNING: Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0 Line 1161: @import '~golden-layout/src/css/goldenlayout-light-theme'; Line 1168: @import '~golden-layout/src/css/goldenlayout-dark-theme'; ``` All other webpack warnings are performance-related (bundle sizes), not SCSS deprecations. ## Migration Progress - ✅ **Phase 1**: Basic color function and simple import conversions (merged) - ✅ **Phase 2**: Complex conditional theme system conversion (this PR) - 🔄 **Phase 3**: External CSS import resolution (future work) This PR makes Compiler Explorer's SCSS mostly compatible with Dart Sass 3.0.0, with only 2 external library imports remaining to be addressed. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
252 lines
6.8 KiB
SCSS
252 lines
6.8 KiB
SCSS
// based on pink.scss
|
|
|
|
$lightest: #444b53;
|
|
$lighter: #3d424d;
|
|
$light: #2c313c;
|
|
$base: #282c34;
|
|
$dark: #21252b;
|
|
$darker: #1e1f22;
|
|
|
|
// Color variables (appears count calculates by raw css)
|
|
$color0: $dark; // Appears 7 times
|
|
$color1: $base; // Appears 3 times
|
|
$color2: #e06c75; // Appears 2 times
|
|
$color3: #98c379; // Appears 2 times
|
|
|
|
$color4: #d19a66; // Appears 1 time
|
|
$color5: #61afef; // Appears 1 time
|
|
$color6: #c678dd; // Appears 1 time
|
|
$color7: #56b6c2; // Appears 1 time
|
|
$color8: #abb2bf; // Appears 1 time
|
|
$color9: #5c6370; // Appears 1 time
|
|
$color10: #e06c75; // Appears 2 time
|
|
|
|
// ".lm_dragging" is applied to BODY tag during Drag and is also directly applied to the root of the object being dragged
|
|
|
|
html[data-theme='one-dark'] {
|
|
|
|
// Entire GoldenLayout Container, if a background is set, it is visible as color of "pane header" and "splitters" (if these latest has opacity very low)
|
|
.lm_goldenlayout {
|
|
background: $color0;
|
|
}
|
|
|
|
// Single Pane content (area in which final dragged content is contained)
|
|
.lm_content {
|
|
background: $base;
|
|
}
|
|
|
|
// Single Pane content during Drag (style of moving window following mouse)
|
|
.lm_dragProxy {
|
|
.lm_content {
|
|
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.9);
|
|
}
|
|
}
|
|
|
|
// Placeholder Container of target position
|
|
.lm_dropTargetIndicator {
|
|
box-shadow: inset 0 0 30px $color0;
|
|
outline: 1px dashed $color4;
|
|
transition: all 200ms ease;
|
|
|
|
// Inner Placeholder
|
|
.lm_inner {
|
|
background: $color0;
|
|
opacity: 0.2;
|
|
}
|
|
}
|
|
|
|
// Separator line (handle to change pane size)
|
|
.lm_splitter {
|
|
background: $color9;
|
|
opacity: 0.001;
|
|
transition: opacity 200ms ease;
|
|
|
|
&:hover, // When hovered by mouse...
|
|
&.lm_dragging {
|
|
background: $lighter;
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
// Pane Header (container of Tabs for each pane)
|
|
.lm_header {
|
|
border-top: 2px solid $dark !important;
|
|
height: 30px !important;
|
|
user-select: none;
|
|
|
|
&.lm_selectable {
|
|
cursor: pointer;
|
|
}
|
|
|
|
// Single Tab container. A single Tab is set for each pane, a group of Tabs are contained in ".lm_header"
|
|
.lm_tab {
|
|
height: 26px !important;
|
|
font-family: Arial, sans-serif;
|
|
font-size: 12px;
|
|
color: $color8;
|
|
background: $base;
|
|
margin-top: 0;
|
|
margin-right: 0;
|
|
padding-top: 0px;
|
|
padding-bottom: 0px;
|
|
|
|
.lm_title {
|
|
padding-top: 5px;
|
|
}
|
|
|
|
// Close Tab Icon
|
|
.lm_close_tab {
|
|
width: 11px;
|
|
height: 11px;
|
|
background-position: center center;
|
|
background-repeat: no-repeat;
|
|
top: 8px;
|
|
right: 6px;
|
|
opacity: 0.4;
|
|
|
|
&:hover {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
// Modify Tab Icon
|
|
.lm_modify_tab_title {
|
|
width: 11px;
|
|
height: 11px;
|
|
background-position: center center;
|
|
background-repeat: no-repeat;
|
|
top: 8px;
|
|
opacity: 0.4;
|
|
|
|
&:hover {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
&:hover {
|
|
opacity: 1;
|
|
border-bottom: 3px solid $lighter;
|
|
}
|
|
|
|
border-bottom: 3px solid $base;
|
|
// If Tab is active, so if it's in foreground
|
|
&.lm_active {
|
|
border-bottom: 3px solid $color5;
|
|
}
|
|
}
|
|
}
|
|
|
|
.lm_dragProxy.lm_bottom,
|
|
.lm_stack.lm_bottom {
|
|
.lm_header .lm_tab {
|
|
box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3);
|
|
&.lm_active {
|
|
box-shadow: 0 2px 2px $color0;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If Pane Header (container of Tabs for each pane) is selected (used only if addition of new Contents is made "by selection" and not "by drag")
|
|
.lm_selected {
|
|
.lm_header {
|
|
background-color: $dark;
|
|
}
|
|
}
|
|
|
|
.lm_tab {
|
|
&:hover, // If Tab is hovered
|
|
&.lm_active // If Tab is active, so if it's in foreground
|
|
{
|
|
background: $lighter;
|
|
}
|
|
}
|
|
|
|
// Dropdown arrow for additional tabs when too many to be displayed
|
|
.lm_header .lm_controls .lm_tabdropdown:before {
|
|
color: #f2f2f2;
|
|
margin-top: 3px;
|
|
}
|
|
|
|
// Pane controls (popout, maximize, minimize, close)
|
|
.lm_controls {
|
|
// All Pane controls shares these
|
|
> li {
|
|
position: relative;
|
|
background-position: center center;
|
|
background-repeat: no-repeat;
|
|
opacity: 0.4;
|
|
transition: opacity 300ms ease;
|
|
|
|
&:hover {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
// Icon to PopOut Pane, so move it to a different Browser Window
|
|
.lm_popout {
|
|
top: 6px;
|
|
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAANUlEQVR4nI2QMQoAMAwCz5L/f9mOzZIaN0E9UDyZhaaQz6atgBHgambEJ5wBKoS0WaIvfT+6K2MIECN19MAAAAAASUVORK5CYII=);
|
|
}
|
|
|
|
// Icon to Maximize Pane, so it will fill the entire GoldenLayout Container
|
|
.lm_maximise {
|
|
top: 6px;
|
|
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAIklEQVR4nGNkYGD4z0AAMBFSAAOETPpPlEmDUREjAxHhBABPvAQLFv3qngAAAABJRU5ErkJggg==);
|
|
}
|
|
|
|
// Icon to Close Pane and so remove it from GoldenLayout Container
|
|
.lm_close {
|
|
top: 6px;
|
|
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAKUlEQVR4nGNgYGD4z4Af/Mdg4FKASwCnDf8JKSBoAtEmEXQTQd8RDCcA6+4Q8OvIgasAAAAASUVORK5CYII=);
|
|
}
|
|
}
|
|
|
|
// If a specific Pane is maximized
|
|
.lm_maximised {
|
|
// Pane Header (container of Tabs for each pane) can have different style when is Maximized
|
|
.lm_header {
|
|
background-color: $color0;
|
|
}
|
|
|
|
// Pane controls are different in Maximized Mode, especially the old Icon "Maximise" that now has a different meaning, so "Minimize" (even if CSS Class did not change)
|
|
.lm_controls {
|
|
.lm_maximise {
|
|
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAJklEQVR4nGP8//8/AyHARFDFUFbEwsDAwMDIyIgzHP7//89IlEkApSkHEScJTKoAAAAASUVORK5CYII=);
|
|
}
|
|
}
|
|
}
|
|
|
|
.lm_transition_indicator {
|
|
background-color: $color0;
|
|
border: 1px dashed $color9;
|
|
}
|
|
|
|
// If a specific Pane is Popped Out, so move it to a different Browser Window, Icon to restore original position is:
|
|
.lm_popin {
|
|
cursor: pointer;
|
|
|
|
// Background of Icon
|
|
.lm_bg {
|
|
background: $color10;
|
|
opacity: 0.3;
|
|
}
|
|
|
|
// Icon to Restore original position in Golden Layout Container
|
|
.lm_icon {
|
|
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAJCAYAAADpeqZqAAAAWklEQVR4nJWOyw3AIAxDHcQC7L8jbwT3AlJBfNp3SiI7dtRaLSlKKeoA1oEsKSQZCEluexw8Tm3ohk+E7bnOUHUGcNh+HwbBygw4AZ7FN/Lt84p0l+yTflV8AKQyLdcCRJi/AAAAAElFTkSuQmCC);
|
|
background-position: center center;
|
|
background-repeat: no-repeat;
|
|
border-left: 1px solid $color2;
|
|
border-top: 1px solid $color2;
|
|
opacity: 0.7;
|
|
}
|
|
|
|
&:hover {
|
|
.lm_icon {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
} // End html[data-theme='one-dark']
|