Files
andros 11b6a4b5b2 Fix Default theme: fixed Org mode/leuven colors instead of adaptive system colors
Default theme now uses colorScheme: .light with the canonical leuven palette
(fniessen/emacs-leuven-theme) so it never changes when switching away from
dark themes: background #FFFFFF, secondaryBackground #F0F0F0 (ol1 heading),
accent #006DAF (link color), codeBackground #FFFFE0 (classic Org src block
yellow), codeBorder #A7A6AA, primaryText #333333, secondaryText #9A9FA4.
2026-05-24 10:28:25 +02:00

157 lines
5.5 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import SwiftUI
struct AppTheme: Identifiable, Equatable {
let id: String
let name: String
let colorScheme: ColorScheme?
let accent: Color
let background: Color
let secondaryBackground: Color
let primaryText: Color
let secondaryText: Color
let codeBackground: Color
let codeBorder: Color
/// highlight.js theme name used for syntax highlighting
let highlightTheme: String
static func == (lhs: AppTheme, rhs: AppTheme) -> Bool { lhs.id == rhs.id }
}
// MARK: - Built-in themes
extension AppTheme {
static let all: [AppTheme] = [.default, .emacs, .dracula, .oneDark, .monokai, .material, .thankfulEyes]
// Default Org mode / leuven palette (fniessen/emacs-leuven-theme)
static let `default` = AppTheme(
id: "default",
name: "Default",
colorScheme: .light,
accent: Color(hex: "#006DAF"), // leuven link color
background: Color(hex: "#FFFFFF"),
secondaryBackground: Color(hex: "#F0F0F0"), // ol1 heading background
primaryText: Color(hex: "#333333"),
secondaryText: Color(hex: "#9A9FA4"), // org-tag foreground
codeBackground: Color(hex: "#FFFFE0"), // leuven code-block background
codeBorder: Color(hex: "#A7A6AA"), // org-block-begin-line underline
highlightTheme: "xcode"
)
// Emacs inspired by modus-vivendi (dark accessibility theme)
static let emacs = AppTheme(
id: "emacs",
name: "Emacs",
colorScheme: .dark,
accent: Color(hex: "#4ac1f7"),
background: Color(hex: "#1c1e1f"),
secondaryBackground: Color(hex: "#252729"),
primaryText: Color(hex: "#dcdccc"),
secondaryText: Color(hex: "#7f9f7f"),
codeBackground: Color(hex: "#0d0e0f"),
codeBorder: Color(hex: "#3a3c3e"),
highlightTheme: "emacs"
)
// Dracula official palette (draculatheme.com)
static let dracula = AppTheme(
id: "dracula",
name: "Dracula",
colorScheme: .dark,
accent: Color(hex: "#bd93f9"),
background: Color(hex: "#282a36"),
secondaryBackground: Color(hex: "#44475a"), // official Selection/Current Line
primaryText: Color(hex: "#f8f8f2"),
secondaryText: Color(hex: "#6272a4"),
codeBackground: Color(hex: "#21222c"),
codeBorder: Color(hex: "#44475a"),
highlightTheme: "dracula"
)
// One Dark Atom / VS Code One Dark Pro palette
static let oneDark = AppTheme(
id: "one_dark",
name: "One Dark",
colorScheme: .dark,
accent: Color(hex: "#61afef"),
background: Color(hex: "#282c34"),
secondaryBackground: Color(hex: "#21252b"), // official sideBar.background
primaryText: Color(hex: "#abb2bf"),
secondaryText: Color(hex: "#5c6370"),
codeBackground: Color(hex: "#21252b"),
codeBorder: Color(hex: "#3e4451"),
highlightTheme: "atom-one-dark"
)
// Monokai TextMate classic (textmate/monokai.tmbundle)
static let monokai = AppTheme(
id: "monokai",
name: "Monokai",
colorScheme: .dark,
accent: Color(hex: "#a6e22e"),
background: Color(hex: "#272822"),
secondaryBackground: Color(hex: "#49483e"), // official line highlight color
primaryText: Color(hex: "#f8f8f2"),
secondaryText: Color(hex: "#75715e"),
codeBackground: Color(hex: "#1e1f1a"),
codeBorder: Color(hex: "#75715e"),
highlightTheme: "monokai"
)
// Material Material Design Dark (Oceanic variant)
static let material = AppTheme(
id: "material",
name: "Material",
colorScheme: .dark,
accent: Color(hex: "#80cbc4"),
background: Color(hex: "#263238"),
secondaryBackground: Color(hex: "#2e3c43"),
primaryText: Color(hex: "#eeffff"),
secondaryText: Color(hex: "#546e7a"),
codeBackground: Color(hex: "#1b2226"),
codeBorder: Color(hex: "#37474f"),
highlightTheme: "atom-one-dark"
)
// Thankful Eyes high-contrast dark teal theme for accessibility (tanrax/thankful-eyes-theme.el)
static let thankfulEyes = AppTheme(
id: "thankful_eyes",
name: "Thankful Eyes",
colorScheme: .dark,
accent: Color(hex: "#a8e1fe"), // font-lock-function-name-face
background: Color(hex: "#122b3b"), // default background
secondaryBackground: Color(hex: "#1c2f3b"), // hl-line / mode-line background
primaryText: Color(hex: "#faf6e4"), // default foreground
secondaryText: Color(hex: "#6c8b9f"), // font-lock-comment-face
codeBackground: Color(hex: "#0d1f2b"), // darker than bg for code blocks
codeBorder: Color(hex: "#4e5d62"), // region/selection color
highlightTheme: "atom-one-dark"
)
}
// MARK: - Hex convenience init
extension Color {
init(hex: String) {
let hex = hex.trimmingCharacters(in: .alphanumerics.inverted)
var value: UInt64 = 0
Scanner(string: hex).scanHexInt64(&value)
let r = Double((value >> 16) & 0xff) / 255
let g = Double((value >> 8) & 0xff) / 255
let b = Double(value & 0xff) / 255
self.init(red: r, green: g, blue: b)
}
}
// MARK: - Environment key
private struct AppThemeKey: EnvironmentKey {
static let defaultValue: AppTheme = .default
}
extension EnvironmentValues {
var appTheme: AppTheme {
get { self[AppThemeKey.self] }
set { self[AppThemeKey.self] = newValue }
}
}