286 lines
6.9 KiB
Svelte
286 lines
6.9 KiB
Svelte
<script lang="ts">
|
|
import { getAppContext } from '../../contexts/app-context';
|
|
|
|
const { editorSettings } = getAppContext();
|
|
|
|
let settings = $state($editorSettings);
|
|
|
|
$effect(() => {
|
|
settings = $editorSettings;
|
|
});
|
|
|
|
function updateSetting(key: keyof typeof settings, value: any) {
|
|
editorSettings.updatePartial({ [key]: value });
|
|
}
|
|
</script>
|
|
|
|
<div class="editor-settings">
|
|
<div class="setting">
|
|
<span class="label-text">Theme</span>
|
|
<div class="theme-toggle">
|
|
<button
|
|
class="theme-option"
|
|
class:active={settings.theme === 'dark'}
|
|
onclick={() => updateSetting('theme', 'dark')}
|
|
>
|
|
Dark
|
|
</button>
|
|
<button
|
|
class="theme-option"
|
|
class:active={settings.theme === 'light'}
|
|
onclick={() => updateSetting('theme', 'light')}
|
|
>
|
|
Light
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="setting">
|
|
<label>
|
|
<span class="label-text">Font Size: {settings.fontSize}px</span>
|
|
<input
|
|
type="range"
|
|
min="10"
|
|
max="24"
|
|
step="1"
|
|
value={settings.fontSize}
|
|
oninput={(e) => updateSetting('fontSize', parseInt(e.currentTarget.value))}
|
|
/>
|
|
</label>
|
|
</div>
|
|
|
|
<div class="setting">
|
|
<label>
|
|
<span class="label-text">Font Family</span>
|
|
<select
|
|
value={settings.fontFamily}
|
|
onchange={(e) => updateSetting('fontFamily', e.currentTarget.value)}
|
|
>
|
|
<option value="'Roboto Mono', Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace">Roboto Mono</option>
|
|
<option value="'JetBrains Mono', 'Roboto Mono', Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace">JetBrains Mono</option>
|
|
<option value="'Fira Code', 'Roboto Mono', Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace">Fira Code</option>
|
|
<option value="Monaco, 'Roboto Mono', Consolas, 'Liberation Mono', 'Courier New', monospace">Monaco</option>
|
|
<option value="Consolas, 'Roboto Mono', Monaco, 'Liberation Mono', 'Courier New', monospace">Consolas</option>
|
|
<option value="'Courier New', 'Roboto Mono', Monaco, Consolas, monospace">Courier New</option>
|
|
</select>
|
|
</label>
|
|
</div>
|
|
|
|
<div class="setting">
|
|
<label>
|
|
<span class="label-text">Tab Size: {settings.tabSize}</span>
|
|
<input
|
|
type="range"
|
|
min="2"
|
|
max="8"
|
|
step="2"
|
|
value={settings.tabSize}
|
|
oninput={(e) => updateSetting('tabSize', parseInt(e.currentTarget.value))}
|
|
/>
|
|
</label>
|
|
</div>
|
|
|
|
<div class="checkboxes">
|
|
<label class="checkbox-label">
|
|
<input
|
|
type="checkbox"
|
|
checked={settings.vimMode}
|
|
onchange={(e) => updateSetting('vimMode', e.currentTarget.checked)}
|
|
/>
|
|
<span>Vim mode</span>
|
|
</label>
|
|
|
|
<label class="checkbox-label">
|
|
<input
|
|
type="checkbox"
|
|
checked={settings.showLineNumbers}
|
|
onchange={(e) => updateSetting('showLineNumbers', e.currentTarget.checked)}
|
|
/>
|
|
<span>Display line numbers</span>
|
|
</label>
|
|
|
|
<label class="checkbox-label">
|
|
<input
|
|
type="checkbox"
|
|
checked={settings.enableLineWrapping}
|
|
onchange={(e) => updateSetting('enableLineWrapping', e.currentTarget.checked)}
|
|
/>
|
|
<span>Enable line wrapping</span>
|
|
</label>
|
|
|
|
<label class="checkbox-label">
|
|
<input
|
|
type="checkbox"
|
|
checked={settings.enableHoverTooltips}
|
|
onchange={(e) => updateSetting('enableHoverTooltips', e.currentTarget.checked)}
|
|
/>
|
|
<span>Enable hover tooltips</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.editor-settings {
|
|
padding: var(--space-sm);
|
|
color: var(--color-text-primary);
|
|
}
|
|
|
|
.setting {
|
|
margin-bottom: var(--space-lg);
|
|
}
|
|
|
|
label {
|
|
display: block;
|
|
}
|
|
|
|
.label-text {
|
|
display: block;
|
|
font-size: var(--font-sm);
|
|
font-weight: 500;
|
|
color: var(--color-text-secondary);
|
|
margin-bottom: var(--space-xs);
|
|
}
|
|
|
|
.theme-toggle {
|
|
display: flex;
|
|
gap: 0;
|
|
border: 1px solid var(--color-border-default);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.theme-option {
|
|
flex: 1;
|
|
padding: var(--space-sm) var(--space-lg);
|
|
background-color: transparent;
|
|
color: var(--color-text-secondary);
|
|
border: none;
|
|
cursor: pointer;
|
|
font-size: var(--font-sm);
|
|
font-weight: 500;
|
|
transition: all var(--transition-base);
|
|
border-right: 1px solid var(--color-border-default);
|
|
}
|
|
|
|
.theme-option:last-child {
|
|
border-right: none;
|
|
}
|
|
|
|
.theme-option:hover:not(.active) {
|
|
background-color: var(--color-hover-overlay);
|
|
color: var(--color-text-primary);
|
|
}
|
|
|
|
.theme-option.active {
|
|
background-color: var(--color-accent-primary);
|
|
color: white;
|
|
}
|
|
|
|
input[type="range"] {
|
|
width: 100%;
|
|
height: 8px;
|
|
background: #4b5563;
|
|
appearance: none;
|
|
cursor: pointer;
|
|
}
|
|
|
|
input[type="range"]::-webkit-slider-thumb {
|
|
appearance: none;
|
|
width: 12px;
|
|
height: 12px;
|
|
background: var(--color-accent-primary);
|
|
cursor: pointer;
|
|
}
|
|
|
|
input[type="range"]::-moz-range-thumb {
|
|
width: 12px;
|
|
height: 12px;
|
|
background: var(--color-accent-primary);
|
|
cursor: pointer;
|
|
border: none;
|
|
}
|
|
|
|
input[type="range"]:hover {
|
|
background: #6b7280;
|
|
}
|
|
|
|
input[type="range"]::-webkit-slider-thumb:hover {
|
|
background: var(--color-accent-primary-hover);
|
|
}
|
|
|
|
input[type="range"]::-moz-range-thumb:hover {
|
|
background: var(--color-accent-primary-hover);
|
|
}
|
|
|
|
select {
|
|
width: 100%;
|
|
background-color: var(--color-bg-base);
|
|
color: var(--color-text-primary);
|
|
border: 1px solid #555;
|
|
padding: 0.4rem;
|
|
font-size: var(--font-sm);
|
|
cursor: pointer;
|
|
}
|
|
|
|
select:hover {
|
|
border-color: var(--color-accent-primary);
|
|
}
|
|
|
|
select:focus {
|
|
outline: none;
|
|
border-color: var(--color-accent-primary);
|
|
}
|
|
|
|
.checkboxes {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.checkbox-label {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-sm);
|
|
font-size: var(--font-sm);
|
|
font-weight: 500;
|
|
color: var(--color-text-secondary);
|
|
cursor: pointer;
|
|
}
|
|
|
|
input[type="checkbox"] {
|
|
appearance: none;
|
|
width: 16px;
|
|
height: 16px;
|
|
background-color: #4b5563;
|
|
border: 1px solid #6b7280;
|
|
cursor: pointer;
|
|
transition: all var(--transition-base);
|
|
}
|
|
|
|
input[type="checkbox"]:hover {
|
|
background-color: #6b7280;
|
|
border-color: #9ca3af;
|
|
}
|
|
|
|
input[type="checkbox"]:checked {
|
|
background-color: var(--color-accent-primary);
|
|
border-color: var(--color-accent-primary);
|
|
}
|
|
|
|
input[type="checkbox"]:checked:hover {
|
|
background-color: var(--color-accent-primary-hover);
|
|
border-color: var(--color-accent-primary-hover);
|
|
}
|
|
|
|
input[type="checkbox"]:checked::before {
|
|
content: '✓';
|
|
color: white;
|
|
font-size: 12px;
|
|
font-weight: bold;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
</style>
|