From b89508b0332305788c1f021ac224113df882a783 Mon Sep 17 00:00:00 2001
From: Fletcher Alderton <109054210+Fletcher-Alderton@users.noreply.github.com>
Date: Fri, 6 Jun 2025 19:38:50 +1000
Subject: [PATCH] Add support for default clear theme and adjusted the
background handling to support it.
- Introduced a new built-in theme: `defaultClear`.
- Updated background handling in `SwiftDown` and `SwiftDownEditor` to account for transparent backgrounds that checks for the word clear in the color fields of the json and if true dosent draw the background.
- Added info about the clear theme to the README.
---
README.md | 4 ++
.../Resources/Themes/default-clear.json | 71 +++++++++++++++++++
Sources/SwiftDown/SwiftDown.swift | 7 +-
Sources/SwiftDown/SwiftDownEditor.swift | 1 +
Sources/SwiftDown/Theme.swift | 8 ++-
5 files changed, 88 insertions(+), 3 deletions(-)
create mode 100644 Sources/SwiftDown/Resources/Themes/default-clear.json
diff --git a/README.md b/README.md
index fe2d911..9f8d115 100644
--- a/README.md
+++ b/README.md
@@ -52,6 +52,10 @@ struct ContentView: View {
+#### Default Clear (same as light except the background is transperent)
+
+
+
### 🧑🎨 Custom themes
SwiftDown supports theming by using config `.json` files as [this one](./Sources/SwiftDown/Resources/Themes/default-dark.json)
diff --git a/Sources/SwiftDown/Resources/Themes/default-clear.json b/Sources/SwiftDown/Resources/Themes/default-clear.json
new file mode 100644
index 0000000..020dc18
--- /dev/null
+++ b/Sources/SwiftDown/Resources/Themes/default-clear.json
@@ -0,0 +1,71 @@
+{
+ "name": "Default Light",
+ "author": {
+ "name": "Quentin Eude",
+ "email": "quentineude@gmail.com"
+ },
+ "version": "1.0",
+ "variables": {
+ "boldFont": "not implemented yet"
+ },
+ "editor": {
+ "comment": "When a color is set to clear, the background is disabled making it transparent",
+ "backgroundColor": "clear",
+ "tintColor": "#1D1F21",
+ "cursorColor": "#1D1F21"
+ },
+ "styles": {
+ "h1": {
+ "color": "#C96667",
+ "size": 23
+ },
+ "h2": {
+ "color": "#C96667",
+ "size": 20
+ },
+ "h3": {
+ "color": "#C96667",
+ "size": 18
+ },
+ "h4": {
+ "color": "#C96667"
+ },
+ "h5": {
+ "color": "#C96667"
+ },
+ "h6": {
+ "color": "#C96667"
+ },
+ "body": {
+ "font": "Menlo-Regular",
+ "size": 15,
+ "color": "#252628"
+ },
+ "bold": {
+ "font": "Menlo-Bold",
+ "color": "#DC9364"
+ },
+ "italic": {
+ "font": "Menlo-Italic",
+ "color": "#B195BA"
+ },
+ "link": {
+ "color": "#a66bff"
+ },
+ "image": {
+ "color": "#a66bff"
+ },
+ "inlineCode": {
+ "color": "#A3A5A8"
+ },
+ "codeBlock": {
+ "color": "#A3A5A8"
+ },
+ "blockQuote": {
+ "color": "#1CBD47"
+ },
+ "list": {
+ "color": "#A3A5A8"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Sources/SwiftDown/SwiftDown.swift b/Sources/SwiftDown/SwiftDown.swift
index 5af58e2..d72c17d 100644
--- a/Sources/SwiftDown/SwiftDown.swift
+++ b/Sources/SwiftDown/SwiftDown.swift
@@ -18,6 +18,7 @@
self.init(frame: frame, textContainer: nil)
self.storage.theme = theme
self.backgroundColor = theme.backgroundColor
+ self.isOpaque = theme.backgroundColor.cgColor.alpha == 1.0
self.tintColor = theme.tintColor
self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
if hasKeyboardToolbar {
@@ -62,6 +63,8 @@
convenience init(frame: CGRect, theme: Theme) {
self.init(frame: frame, textContainer: nil)
self.storage.theme = theme
+ let isClear = theme.backgroundColor.alphaComponent == 0
+ self.drawsBackground = !isClear
self.backgroundColor = theme.backgroundColor
}
@@ -120,7 +123,7 @@
// MARK: - ScrollView setup
private lazy var scrollView: NSScrollView = {
let scrollView = NSScrollView()
- scrollView.drawsBackground = true
+ scrollView.drawsBackground = false
scrollView.borderType = .noBorder
scrollView.hasVerticalScroller = true
scrollView.hasHorizontalRuler = false
@@ -143,7 +146,7 @@
textView.storage.applyBody = { Theme.applyBody(with: self.theme) }
textView.storage.theme = theme
textView.autoresizingMask = .width
- textView.drawsBackground = true
+ textView.drawsBackground = theme.backgroundColor.alphaComponent > 0
textView.isEditable = self.isEditable
textView.isHorizontallyResizable = false
textView.isVerticallyResizable = true
diff --git a/Sources/SwiftDown/SwiftDownEditor.swift b/Sources/SwiftDown/SwiftDownEditor.swift
index cf35ed2..ab83cbd 100644
--- a/Sources/SwiftDown/SwiftDownEditor.swift
+++ b/Sources/SwiftDown/SwiftDownEditor.swift
@@ -57,6 +57,7 @@ public struct SwiftDownEditor: UIViewRepresentable {
swiftDown.textContainerInset = UIEdgeInsets(
top: insetsSize, left: insetsSize, bottom: insetsSize, right: insetsSize)
swiftDown.backgroundColor = theme.backgroundColor
+ swiftDown.isOpaque = theme.backgroundColor.cgColor.alpha == 1.0
swiftDown.tintColor = theme.tintColor
swiftDown.textColor = theme.tintColor
swiftDown.text = text
diff --git a/Sources/SwiftDown/Theme.swift b/Sources/SwiftDown/Theme.swift
index e3592f1..cdf09da 100644
--- a/Sources/SwiftDown/Theme.swift
+++ b/Sources/SwiftDown/Theme.swift
@@ -16,6 +16,7 @@ public struct Theme {
public enum BuiltIn: String {
case defaultDark = "default-dark"
case defaultLight = "default-light"
+ case defaultClear = "default-clear"
public func theme() -> Theme {
return Theme(self.rawValue)
@@ -118,7 +119,12 @@ public struct Theme {
attributes.forEach { key, value in
switch EditorConfigProperty.from(rawValue: key) {
case .backgroundColor:
- backgroundColor = UniversalColor(hexString: value)
+ // allow "clear" keyword for transparent background
+ if value.lowercased() == "clear" {
+ backgroundColor = UniversalColor.clear
+ } else {
+ backgroundColor = UniversalColor(hexString: value)
+ }
case .tintColor:
tintColor = UniversalColor(hexString: value)
case .cursorColor: