-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
adds support for color-mode selection #65
base: main
Are you sure you want to change the base?
Conversation
What I'd really like to figure out here is automatic. Bootstrap's implementation here isn't ideal – it seems to rely on some kind of JavaScript, although I admit I haven't looked at it terribly closely. How about I merge this in now, and we can revisit further in the future? |
I fiddled with default being 'auto' which had no effect, but site-wide setting requires being able control the |
I see. Well, I think we should perhaps hold off for the time being – the |
Just wanted to create an issue asking for Dark-mode support, but I understand Bootstrap already handles that somehow? But how does the site dynamically detect the current user preference without JavaScript? I would assume there's some small JavaScript we need to add for the "auto" to work. I'm also not sure how the color mode introduced in this PR could be adjusted by the user as we don't have any cookies storage. Is it stored in the path and multiple variants of the static sites are generated for each color mode, such as For me personally, a simple "auto" mode would be enough, no user-based selection needed. The OS provides that already. |
Hey, what do you think about setting the color scheme in the body when the site is loaded. In auto mode it will detect the users preferences and set it accordingly or if you always want a certain schema set it. To control certain page elements simply setting Body {
...
}
.colorScheme(.auto)
element
.colorScheme(.dark) Here the necessary code: public enum ColorScheme: String, CustomStringConvertible {
case auto, light, dark
public var description: String {
rawValue
}
}
public extension Body {
func colorScheme(_ colorScheme: ColorScheme) -> Self {
var copy = self
switch colorScheme {
case .auto:
copy.items.append(setBasedOnUserPreference())
default:
copy.items.append(setColorSchema(colorScheme))
}
return copy
}
func setColorSchema(_ colorSchema: ColorScheme) -> Script {
Script(code: "document.documentElement.setAttribute('data-bs-theme', '\(colorSchema)');")
}
func setBasedOnUserPreference() -> Script {
Script(code: """
document.addEventListener('DOMContentLoaded', (event) => {
// Function to set the theme based on user preference
function setThemeBasedOnPreference() {
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (prefersDarkScheme) {
document.documentElement.setAttribute('data-bs-theme', 'dark');
} else {
document.documentElement.setAttribute('data-bs-theme', 'light');
}
}
// Set the theme based on user preference when the page loads
setThemeBasedOnPreference();
// Listen for changes to the user's color scheme preference
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', setThemeBasedOnPreference);
});
""")
}
}
public extension PageElement {
func colorScheme(_ colorScheme: ColorScheme) -> Self {
data("bs-theme", "\(colorScheme)")
}
} |
@markstamer Love it! That would be a great addition. I'm still not sure why Bootstrap doesn't adapt automatically; I suspect that might change when they move to v6. |
@jkaunert now that we have the OK from @twostraws do you want to make the change on your branch and we keep going from here? |
when the site is loaded
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can make a change on the original approach and use a script directly instead of a modifier.
return copy | ||
} | ||
|
||
func setColorSchema(_ colorSchema: ColorScheme) -> Script { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we make setColorSchema()
and setBasedOnUserPreference()
private here? They were intended as helpers and only colorSchema(_:)
as an API to be used from outside.
@@ -37,7 +37,7 @@ public struct HTML: PageElement { | |||
/// - Returns: The HTML for this element. | |||
public func render(context: PublishingContext) -> String { | |||
var output = "<!doctype html>" | |||
output += "<html lang=\"\(context.site.language.rawValue)\" data-bs-theme=\"light\"\(attributes.description)>" | |||
output += "<html lang=\"\(context.site.language.rawValue)\" data-bs-theme=\"\(context.site.colorScheme)\"\(attributes.description)>" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change alone will not work for the case auto
since there is no observation taking place without calling the colorSchema
modifier. What about we remove the data-bs-theme
here completely and move the content of the colorSchema
function to a static func on Script
. We could than add a line after body content like this.
output += Script.colorSchema(context.site.colorSchema).render(context: context)
Furthermore we can replace |
Adds support for choosing dark or light mode. implements a new public enum
SiteColorMode: String
and property on Site,colorMode: SiteColorMode
which defaults to.light
to preserve current implementation default mode.