Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
4 changes: 4 additions & 0 deletions Demos/FluentUIDemo/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import SwiftUI
import FluentUI

struct ContentView: View {
@Environment(\.fluentTheme) var fluentTheme: FluentTheme

#if os(macOS)
// Until we have a SwiftUI button on macOS, this will have to do.
private struct ButtonRepresentable: NSViewRepresentable {
Expand Down Expand Up @@ -38,5 +40,7 @@ struct ContentView: View {
#endif
}
.padding()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(fluentTheme.swiftUIColor(.background1))
}
}
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" => "fluentuinativeowners@microsoft.com"}
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 @@ -112,6 +121,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 @@ -355,24 +365,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 @@ -384,23 +385,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
2 changes: 1 addition & 1 deletion Sources/FluentUI/FluentUI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Licensed under the MIT License.
//

#if os(iOS) || os(visionOS)
#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 @@ -38,17 +38,21 @@ extension Color {

/// Creates a custom `Color` from a prebuilt `DynamicColor` structure.
///
/// - Parameter dynamicColor: A dynmic color structure that describes the `Color` to be created.
/// - Parameter dynamicColor: A dynamic color structure that describes the `Color` to be created.
init(dynamicColor: DynamicColor) {
if #available(iOS 17, *) {
if #available(iOS 17, macOS 14, *) {
self.init(dynamicColor)
} else {
#if os(macOS)
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,11 @@ extension NSColor {
return resolvedColorValue(appearance: NSAppearance(named: .darkAqua))
}

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

/// 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,10 +139,9 @@ extension UIColor {
}

convenience init(dynamicColor: DynamicColor) {
let colorResolver = { $0 != nil ? UIColor($0!) : nil }
self.init(light: UIColor(dynamicColor.light),
dark: colorResolver(dynamicColor.dark),
darkElevated: colorResolver(dynamicColor.darkElevated))
dark: dynamicColor.dark.map { UIColor($0) },
darkElevated: dynamicColor.darkElevated.map { UIColor($0) })
}

/// Returns the version of the current color that results from the specified traits as a `ColorValue`.
Expand Down Expand Up @@ -172,3 +171,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 canImport(FluentUI_common)
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 canImport(FluentUI_common)
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 canImport(FluentUI_common)
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 canImport(FluentUI_common)
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 canImport(FluentUI_common)
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 canImport(FluentUI_common)
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 canImport(FluentUI_common)
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 canImport(FluentUI_common)
import FluentUI_common
#endif
import SwiftUI
import UIKit

/// UIKit wrapper that exposes the SwiftUI Avatar implementation.
@objc open class MSFAvatar: ControlHostingView {
Expand Down
Loading
Loading