SkillAgentSearch skills...

ThemeKit

macOS theming library

Install / Use

/learn @luckymarmot/ThemeKit
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<p align="left" style="margin-top: 20px;"> <img src="https://github.com/luckymarmot/ThemeKit/raw/master/Imgs/ThemeKit@2x.png" width="377" height="105" alt="ThemeKit" /> </p>

macOS Swift4 Release MIT CocoaPods Carthage

Summary

ThemeKit is a lightweight theming library completely written in Swift that provides theming capabilities to both Swift and Objective-C macOS applications.

ThemeKit is brought to you with ❤️ by Nuno Grilo and the Paw team.

<p align="left"> <img src="https://github.com/luckymarmot/ThemeKit/raw/master/Imgs/ThemeKit.gif" width="675" height="378" alt="ThemeKit Animated Demo" /> </p>

QuickStart

Table of Contents

Features

  • Written in Swift 4.2
  • Optional configuration, none required
  • Neglected performance impact
  • Automatically theme windows (configurable)
  • Themes:
    • LightTheme (default macOS appearance)
    • DarkTheme
    • SystemTheme (default theme). Dynamically resolves to ThemeManager.lightTheme or ThemeManager.darkTheme, depending on the "System Preferences > General > Appearance".
    • Support for custom themes (Theme)
    • Support for user-defined themes (UserTheme)
  • Theme-aware assets:
    • ThemeColor: colors that dynamically change with the theme
    • ThemeGradient: gradients that dynamically change with the theme
    • ThemeImage: images that dynamically change with the theme
    • Optional override of NSColor named colors (e.g., labelColor) to dynamically change with the theme

Installation

|ThemeKit Version|Swift Version| |----------------|-------------| |1.0.0 | 3.0 | |1.1.0 | 4.0 | |1.2.0 | 4.1 | |1.2.3 | 4.2 |

There are multiple options to include ThemeKit on your project:

  • CocoaPods

    Add to your Podfile:

    use_frameworks!
    target '[YOUR APP TARGET]' do
        pod 'macOSThemeKit', '~> 1.2.0'
    end
    

    When using CocoaPods, the ThemeKit module is named macOSThemeKit:

    import macOSThemeKit
    
  • Carthage

    github "luckymarmot/ThemeKit"
    

    Then import ThemeKit module with:

    import ThemeKit
    
  • Manually

    • Either add ThemeKit.framework on your project, or, manually add source files from the ThemeKit\ folder to your project
    • If importing into a Objective-C project, you will need to include all the Swift related frameworks as well (as reported here)

    Then import ThemeKit module with:

    import ThemeKit
    

Usage

Simple Usage

At its simpler usage, applications can be themed with a single line command:

In Swift:
func applicationWillFinishLaunching(_ notification: Notification) {
	
	/// Apply the dark theme
	ThemeManager.darkTheme.apply()
	
	/// or, the light theme
	//ThemeManager.lightTheme.apply()
	
	/// or, the 'system' theme, which dynamically changes to light or dark, 
	/// respecting *System Preferences > General > Appearance* setting.
	//ThemeManager.systemTheme.apply()
	
}
In Objective-C:
- (void)applicationWillFinishLaunching:(NSNotification *)aNotification {
	
	// Apply the dark theme
	TKDarkTheme *darkTheme = TKThemeManager.darkTheme;
	[[TKThemeManager sharedManager] setTheme:darkTheme];
	
}

Advanced Usage

The following code will define which windows should be automatically themed (WindowThemePolicy) and add support for user themes (UserTheme):

In Swift:
func applicationWillFinishLaunching(_ notification: Notification) {

	/// Define default theme.
	/// Used on first run. Default: `SystemTheme`.
	/// Note: `SystemTheme` is a special theme that resolves to `ThemeManager.lightTheme` or `ThemeManager.darkTheme`,
	/// depending on the macOS preference at 'System Preferences > General > Appearance'.
	ThemeManager.defaultTheme = ThemeManager.lightTheme
	
	/// Define window theme policy.
	ThemeManager.shared.windowThemePolicy = .themeAllWindows
	//ThemeManager.shared.windowThemePolicy = .themeSomeWindows(windowClasses: [MyWindow.self])
	//ThemeManager.shared.windowThemePolicy = .doNotThemeSomeWindows(windowClasses: [NSPanel.self])
	//ThemeManager.shared.windowThemePolicy = .doNotThemeWindows
	    
	/// Enable & configure user themes.
	/// Will use folder `(...)/Application Support/{your_app_bundle_id}/Themes`.
	let applicationSupportURLs = NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true)
	let thisAppSupportURL = URL.init(fileURLWithPath: applicationSupportURLs.first!).appendingPathComponent(Bundle.main.bundleIdentifier!)
	let userThemesFolderURL = thisAppSupportURL.appendingPathComponent("Themes")
	ThemeManager.shared.userThemesFolderURL = userThemesFolderURL
	
	/// Change the default light and dark theme, used when `SystemTheme` is selected.
	//ThemeManager.lightTheme = ThemeManager.shared.theme(withIdentifier: PaperTheme.identifier)!
	//ThemeManager.darkTheme = ThemeManager.shared.theme(withIdentifier: "com.luckymarmot.ThemeKit.PurpleGreen")!
	
	/// Apply last applied theme (or the default theme, if no previous one)
	ThemeManager.shared.applyLastOrDefaultTheme()
	 
}    
In Objective-C:
- (void)applicationWillFinishLaunching:(NSNotification *)aNotification {

    /// Define default theme.
    /// Used on first run. Default: `SystemTheme`.
    /// Note: `SystemTheme` is a special theme that resolves to `ThemeManager.lightTheme` or `ThemeManager.darkTheme`,
    /// depending on the macOS preference at 'System Preferences > General > Appearance'.
    [TKThemeManager setDefaultTheme:TKThemeManager.lightTheme];
    
    /// Define window theme policy.
    [TKThemeManager sharedManager].windowThemePolicy = TKThemeManagerWindowThemePolicyThemeAllWindows;
    //[TKThemeManager sharedManager].windowThemePolicy = TKThemeManagerWindowThemePolicyThemeSomeWindows;
    //[TKThemeManager sharedManager].themableWindowClasses = @[[MyWindow class]];
    //[TKThemeManager sharedManager].windowThemePolicy = TKThemeManagerWindowThemePolicyDoNotThemeSomeWindows;
    //[TKThemeManager sharedManager].notThemableWindowClasses = @[[NSPanel class]];
    //[TKThemeManager sharedManager].windowThemePolicy = TKThemeManagerWindowThemePolicyDoNotThemeWindows;
    
    /// Enable & configure user themes.
    /// Will use folder `(...)/Application Support/{your_app_bundle_id}/Themes`.
    NSArray<NSString*>* applicationSupportURLs = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
    NSURL* thisAppSupportURL = [[NSURL fileURLWithPath:applicationSupportURLs.firstObject] URLByAppendingPathComponent:[NSBundle mainBundle].bundleIdentifier];
    NSURL* userThemesFolderURL = [thisAppSupportURL URLByAppendingPathComponent:@"Themes"];
    [TKThemeManager sharedManager].userThemesFolderURL = userThemesFolderURL;
    
    /// Change the default light and dark theme, used when `SystemTheme` is selected.
    //TKThemeManager.lightTheme = [[TKThemeManager sharedManager] themeWithIdentifier:PaperTheme.identifier];
    //TKThemeManager.darkTheme = [[TKThemeManager sharedManager] themeWithIdentifier:@"com.luckymarmot.ThemeKit.PurpleGreen"];
    
    /// Apply last applied theme (or the default theme, if no previous one)
    [[TKThemeManager sharedManager] applyLastOrDefaultTheme];
    
}

Please check the Demo application source code for a more complete usage example of ThemeKit.

Observing theme changes

ThemeKit provides the following notifications:

  • Notification.Name.willChangeTheme is sent when current theme is about to change
  • Notification.Name.didChangeTheme is sent when current theme did change
  • Notification.Name.didChangeSystemTheme is sent when system theme did change (System Preference > General)

Example:

// Register to be notified of theme changes
NotificationCenter.default.addObserver(self, selector: #selector(changedTheme(_:)), name: .didChangeTheme, object: nil)

@objc
View on GitHub
GitHub Stars885
CategoryDevelopment
Updated18d ago
Forks46

Languages

Swift

Security Score

100/100

Audited on Mar 13, 2026

No findings