Skip to content
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

Move FluentTheme code to new FluentUI_common module #2139

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 16 additions & 21 deletions MicrosoftFluentUI.podspec
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Constants
common_root = 'Sources/FluentUI_common'
ios_root = 'Sources/FluentUI_iOS'
macos_root = 'Sources/FluentUI_macOS'

Expand All @@ -13,14 +14,22 @@ Pod::Spec.new do |s|
s.homepage = "https://www.microsoft.com/design/fluent/#/"
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { "Microsoft" => "[email protected]"}
s.source = { :git => "https://github.com/microsoft/fluentui-apple.git", :tag => "#{s.version}" }
s.swift_version = "5.9"
s.module_name = 'FluentUI'
s.source = { :git => "https://github.com/microsoft/fluentui-apple.git", :tag => "#{s.version}" }
s.swift_version = "5.9"
s.module_name = 'FluentUI'

s.ios.deployment_target = "16.0"
s.osx.deployment_target = "12.0"

# iOS

s.ios.deployment_target = "16.0"
# Common

s.subspec 'Core_common' do |core_common|
core_common.source_files = ["#{common_root}/#{core_dir}/**/*.{swift,h}"]
end


# iOS

s.subspec 'Avatar_ios' do |avatar_ios|
avatar_ios.platform = :ios
Expand Down Expand Up @@ -111,6 +120,7 @@ Pod::Spec.new do |s|

s.subspec 'Core_ios' do |core_ios|
core_ios.platform = :ios
core_ios.dependency "#{s.name}/Core_common"
core_ios.resource_bundle = { 'FluentUIResources-ios' => ["#{ios_root}/#{resources_dir}/**/*.{storyboard,xib,xcassets,strings,stringsdict}"] }
core_ios.script_phase = { :name => 'Optimize resource bundle',
:script => 'REMOVE_UNUSED_RESOURCES_SCRIPT_PATH=${PODS_TARGET_SRCROOT}/scripts/removeUnusedResourcesFromAssets.swift
Expand Down Expand Up @@ -354,24 +364,15 @@ fi', :execution_position => :before_compile }

# Mac

s.osx.deployment_target = "12"

s.subspec 'Appearance_mac' do |appearance_mac|
appearance_mac.platform = :osx
appearance_mac.source_files = ["#{macos_root}/#{components_dir}/Appearance/**/*.{swift,h}"]
end

s.subspec 'AvatarView_mac' do |avatarview_mac|
avatarview_mac.platform = :osx
avatarview_mac.dependency "#{s.name}/Core_mac"
avatarview_mac.dependency "#{s.name}/DynamicColor_mac"
avatarview_mac.source_files = ["#{macos_root}/#{components_dir}/AvatarView/**/*.{swift,h}"]
end

s.subspec 'BadgeView_mac' do |badgeview_mac|
badgeview_mac.platform = :osx
badgeview_mac.dependency "#{s.name}/Core_mac"
badgeview_mac.dependency "#{s.name}/DynamicColor_mac"
badgeview_mac.source_files = ["#{macos_root}/#{components_dir}/Badge/**/*.{swift,h}"]
end

Expand All @@ -383,23 +384,17 @@ fi', :execution_position => :before_compile }

s.subspec 'Core_mac' do |core_mac|
core_mac.platform = :osx
core_mac.dependency "#{s.name}/Core_common"
core_mac.resource_bundle = { 'FluentUIResources-macos' => ["#{macos_root}/#{resources_dir}/**/*.{storyboard,xib,xcassets,strings,stringsdict}"] }
core_mac.source_files = ["#{macos_root}/#{core_dir}/**/*.{swift,h}"]
end

s.subspec 'DatePicker_mac' do |datepicker_mac|
datepicker_mac.platform = :osx
datepicker_mac.dependency "#{s.name}/Core_mac"
datepicker_mac.dependency "#{s.name}/Appearance_mac"
datepicker_mac.source_files = ["#{macos_root}/#{components_dir}/DatePicker/**/*.{swift,h}"]
end

s.subspec 'DynamicColor_mac' do |dynamiccolor_mac|
dynamiccolor_mac.platform = :osx
dynamiccolor_mac.dependency "#{s.name}/Appearance_mac"
dynamiccolor_mac.source_files = ["#{macos_root}/#{components_dir}/DynamicColor/**/*.{swift,h}"]
end

s.subspec 'Link_mac' do |link_mac|
link_mac.platform = :osx
link_mac.dependency "#{s.name}/Core_mac"
Expand Down
10 changes: 10 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,24 @@ let targets: [Target] = [
),
.target(
name: "FluentUI_ios",
dependencies: [
.target(name: "FluentUI_common")
],
path: "Sources/FluentUI_iOS",
resources: [
.copy("Resources/Version.plist")
]
),
.target(
name: "FluentUI_macos",
dependencies: [
.target(name: "FluentUI_common")
],
path: "Sources/FluentUI_macOS"
),
.target(
name: "FluentUI_common",
path: "Sources/FluentUI_common"
)
]

Expand Down
6 changes: 5 additions & 1 deletion Sources/FluentUI/FluentUI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
// Licensed under the MIT License.
//

#if os(iOS) || os(visionOS)
#if !COCOAPODS
@_exported import FluentUI_common
#endif

#if os(iOS) || os(visionOS) || targetEnvironment(macCatalyst)
@_exported import FluentUI_ios
#elseif os(macOS)
@_exported import FluentUI_macos
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,19 @@ extension Color {
///
/// - Parameter dynamicColor: A dynmic color structure that describes the `Color` to be created.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: Not related to this PR, but there's a typo here. dynmic -> dynamic

init(dynamicColor: DynamicColor) {
if #available(iOS 17, *) {
if #available(iOS 17, macOS 14, *) {
self.init(dynamicColor)
} else {
#if os(macOS)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be a good excuse to rename Color+Extensions.swift to something more descriptive and then introduce something like DynamicColor+UIKit and DynamicColor+AppKit (or similar names)

self.init(nsColor: NSColor(dynamicColor: dynamicColor))
#else
self.init(uiColor: UIColor(dynamicColor: dynamicColor))
#endif // os(macOS)
}
}

var dynamicColor: DynamicColor {
if #available(iOS 17, *) {
if #available(iOS 17, macOS 14, *) {
var lightEnvironment = EnvironmentValues.init()
lightEnvironment.colorScheme = .light

Expand All @@ -58,9 +62,15 @@ extension Color {
return DynamicColor(light: Color(self.resolve(in: lightEnvironment)),
dark: Color(self.resolve(in: darkEnvironment)))
} else {
#if os(macOS)
let nsColor = NSColor(self)
return DynamicColor(light: Color(nsColor.light),
dark: Color(nsColor.dark))
#else
let uiColor = UIColor(self)
return DynamicColor(light: Color(uiColor.light),
dark: Color(uiColor.dark))
#endif // os(macOS)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

#if canImport(AppKit)
import AppKit
import SwiftUI

extension NSColor {

Expand Down Expand Up @@ -51,6 +50,14 @@ extension NSColor {
return resolvedColorValue(appearance: NSAppearance(named: .darkAqua))
}

convenience init(dynamicColor: DynamicColor) {
// Simple closure to return a nil NSColor if the passed-in Color is
// also nil, since the argument to `NSColor.init(_:)` is not optional.
let colorResolver = { $0 != nil ? NSColor($0!) : nil }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since Optional includes support for .map() and .flatMap(), I wonder if you could remove this closure and instead do something like:

self.init(light: NSColor(dynamicColor.light),
          dark: dynamicColor.dark.map { NSColor($0) }

self.init(light: NSColor(dynamicColor.light),
dark: colorResolver(dynamicColor.dark))
}

/// Returns the version of the current color that results from the specified traits as an `NSColor`.
///
/// - Parameter appearance: The user interface appearance to use when resolving the color information.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
// Licensed under the MIT License.
//

#if canImport(UIKit)
import UIKit
import SwiftUI

extension UIColor {

Expand Down Expand Up @@ -139,6 +139,8 @@ extension UIColor {
}

convenience init(dynamicColor: DynamicColor) {
// Simple closure to return a nil UIColor if the passed-in Color is
// also nil, since the argument to `UIColor.init(_:)` is not optional.
let colorResolver = { $0 != nil ? UIColor($0!) : nil }
self.init(light: UIColor(dynamicColor.light),
dark: colorResolver(dynamicColor.dark),
Expand Down Expand Up @@ -172,3 +174,4 @@ extension UIColor {
return resolvedColor
}
}
#endif // canImport(UIKit)
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ public enum ControlTokenValue {
// Use our global "Hot Pink" in debug builds, to help identify unintentional conversions.
return UIColor(GlobalTokens.sharedSwiftUIColor(.hotPink, .primary))
#else
return GlobalTokens.neutralColor(.black)
return UIColor(GlobalTokens.neutralSwiftUIColor(.black))
#endif
}
#endif // os(iOS) || os(visionOS)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,31 @@
import SwiftUI

/// A container that stores a dynamic set of `Color` values.
struct DynamicColor: Hashable {
@objc(MSFDynamicColor)
public final class DynamicColor: NSObject {

/// Creates a custom `ShapeStyle` that stores a dynamic set of `Color` values.
///
/// - Parameter light: The default `Color` for a light context. Required.
/// - Parameter dark: The override `Color` for a dark context. Optional.
/// - Parameter darkElevated: The override `Color` for a dark elevated context. Optional.
init(light: Color,
dark: Color? = nil,
darkElevated: Color? = nil) {
public init(light: Color,
dark: Color? = nil,
darkElevated: Color? = nil) {
self.light = light
self.dark = dark
self.darkElevated = darkElevated
}

let light: Color
let dark: Color?
let darkElevated: Color?
public let light: Color
public let dark: Color?
public let darkElevated: Color?
}

@available(iOS 17, macOS 14, *)
extension DynamicColor: ShapeStyle {
/// Evaluate to a resolved `Color` (in the form of a `ShapeStyle`) given the current `environment`.
func resolve(in environment: EnvironmentValues) -> Color.Resolved {
public func resolve(in environment: EnvironmentValues) -> Color.Resolved {
if environment.colorScheme == .dark {
if environment.isPresented, let darkElevated = darkElevated {
return darkElevated.resolve(in: environment)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ public class LinearGradientInfo: NSObject {
// MARK: - Extensions

extension LinearGradient {
/// Internal property to generate a SwiftUI `LinearGradient` from a gradient info.
init(gradientInfo: LinearGradientInfo) {
/// Generate a SwiftUI `LinearGradient` from a gradient info.
public init(gradientInfo: LinearGradientInfo) {
if let locations = gradientInfo.locations {
// Map the colors and locations together.
let stops: [Gradient.Stop] = zip(gradientInfo.colors, locations).map({ (color, location) in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Licensed under the MIT License.
//

import UIKit
import QuartzCore

/// An animation synchronizer syncs homogeneous layer animations by calculating the appropriate timeOffset
/// of a referenceLayer so that newly added animations can stay in sync with existing animations.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
// Licensed under the MIT License.
//

#if !COCOAPODS
import FluentUI_common
#endif
import SwiftUI
import UIKit

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
// Licensed under the MIT License.
//

#if !COCOAPODS
import FluentUI_common
#endif
import SwiftUI
import UIKit

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
// Licensed under the MIT License.
//

#if !COCOAPODS
import FluentUI_common
#endif
import SwiftUI
import UIKit

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
// Licensed under the MIT License.
//

#if !COCOAPODS
import FluentUI_common
#endif
import SwiftUI
import UIKit

Expand Down
5 changes: 4 additions & 1 deletion Sources/FluentUI_iOS/Components/Avatar/Avatar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
// Licensed under the MIT License.
//

import UIKit
#if !COCOAPODS
import FluentUI_common
#endif
import SwiftUI
import UIKit

/// Properties that can be used to customize the appearance of the Avatar.
@objc public protocol MSFAvatarState {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
// Licensed under the MIT License.
//

import UIKit
#if !COCOAPODS
import FluentUI_common
#endif
import SwiftUI
import UIKit

public extension Avatar {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
// Licensed under the MIT License.
//

import UIKit
#if !COCOAPODS
import FluentUI_common
#endif
import SwiftUI
import UIKit

public enum AvatarToken: Int, TokenSetKey {
/// The radius of the corners of the `Avatar`.
Expand Down
5 changes: 4 additions & 1 deletion Sources/FluentUI_iOS/Components/Avatar/MSFAvatar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
// Licensed under the MIT License.
//

import UIKit
#if !COCOAPODS
import FluentUI_common
#endif
import SwiftUI
import UIKit

/// UIKit wrapper that exposes the SwiftUI Avatar implementation.
@objc open class MSFAvatar: ControlHostingView {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
// Licensed under the MIT License.
//

import UIKit
#if !COCOAPODS
import FluentUI_common
#endif
import SwiftUI
import UIKit

@objc public enum MSFAvatarPresence: Int, CaseIterable {
case none
Expand Down
3 changes: 3 additions & 0 deletions Sources/FluentUI_iOS/Components/Avatar/Persona.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
// Licensed under the MIT License.
//

#if !COCOAPODS
import FluentUI_common
#endif
import UIKit

// MARK: Persona
Expand Down
Loading
Loading