diff --git a/ios/FluentUI.Demo/FluentUI.Demo/Demos/ListItemDemoController.swift b/ios/FluentUI.Demo/FluentUI.Demo/Demos/ListItemDemoController.swift index 0b9a3a9a4..193363bbb 100644 --- a/ios/FluentUI.Demo/FluentUI.Demo/Demos/ListItemDemoController.swift +++ b/ios/FluentUI.Demo/FluentUI.Demo/Demos/ListItemDemoController.swift @@ -36,53 +36,3 @@ class ListItemDemoController: DemoController { var hostingController: ListItemDemoControllerSwiftUI? } - -extension ListItemDemoController: DemoAppearanceDelegate { - func themeWideOverrideDidChange(isOverrideEnabled: Bool) { - guard let fluentTheme = self.view.window?.fluentTheme else { - return - } - - fluentTheme.register(tokenSetType: ListItemTokenSet.self, - tokenSet: isOverrideEnabled ? themeWideOverrideListItemTokens : nil) - } - - func perControlOverrideDidChange(isOverrideEnabled: Bool) { - guard let fluentTheme = self.view.window?.fluentTheme else { - return - } - - fluentTheme.register(tokenSetType: ListItemTokenSet.self, - tokenSet: isOverrideEnabled ? perControlOverrideListItemTokens : nil) - } - - func isThemeWideOverrideApplied() -> Bool { - return self.view.window?.fluentTheme.tokens(for: ListItemTokenSet.self) != nil - } - - // MARK: - Custom tokens - private var themeWideOverrideListItemTokens: [ListItemTokenSet.Tokens: ControlTokenValue] { - return [ - .cellBackgroundGroupedColor: .uiColor { - // "Berry" - return UIColor(light: GlobalTokens.sharedColor(.berry, .tint50), - dark: GlobalTokens.sharedColor(.berry, .shade40)) - } - ] - } - - private var perControlOverrideListItemTokens: [ListItemTokenSet.Tokens: ControlTokenValue] { - return [ - .cellBackgroundGroupedColor: .uiColor { - // "Brass" - return UIColor(light: GlobalTokens.sharedColor(.brass, .tint50), - dark: GlobalTokens.sharedColor(.brass, .shade40)) - }, - .accessoryDisclosureIndicatorColor: .uiColor { - // "Forest" - return UIColor(light: GlobalTokens.sharedColor(.forest, .tint10), - dark: GlobalTokens.sharedColor(.forest, .shade40)) - } - ] - } -} diff --git a/ios/FluentUI.Demo/FluentUI.Demo/Demos/ListItemDemoController_SwiftUI.swift b/ios/FluentUI.Demo/FluentUI.Demo/Demos/ListItemDemoController_SwiftUI.swift index e6e6a5a5a..8379d36dc 100644 --- a/ios/FluentUI.Demo/FluentUI.Demo/Demos/ListItemDemoController_SwiftUI.swift +++ b/ios/FluentUI.Demo/FluentUI.Demo/Demos/ListItemDemoController_SwiftUI.swift @@ -35,16 +35,17 @@ struct ListItemDemoView: View { @State var showTrailingContent: Bool = true @State var isTappable: Bool = true @State var isDisabled: Bool = false + @State var renderStandalone: Bool = false + @State var overrideTokens: Bool = false @State var accessoryType: ListItemAccessoryType = .none @State var leadingContentSize: ListItemLeadingContentSize = .default @State var backgroundStyle: ListItemBackgroundStyleType = .grouped + @State var listStyle: FluentListStyle = .plain @State var titleLineLimit: Int = 1 @State var subtitleLineLimit: Int = 1 @State var footerLineLimit: Int = 1 @State var trailingContentFocusableElementCount: Int = 0 @State var trailingContentToggleEnabled: Bool = true - @State var renderStandalone: Bool = false - @State var listStyle: FluentListStyle = .plain public var body: some View { @@ -80,6 +81,7 @@ struct ListItemDemoView: View { FluentUIDemoToggle(titleKey: "Tappable", isOn: $isTappable) FluentUIDemoToggle(titleKey: "Disabled", isOn: $isDisabled) FluentUIDemoToggle(titleKey: "Render standalone", isOn: $renderStandalone) + FluentUIDemoToggle(titleKey: "Override tokens", isOn: $overrideTokens) } @ViewBuilder @@ -148,58 +150,59 @@ struct ListItemDemoView: View { @ViewBuilder var listItem: some View { - ListItem(title: title, - subtitle: showSubtitle ? subtitle : "", - footer: showFooter ? footer : "", - leadingContent: { - if showLeadingContent { - leadingContent - } - }, - trailingContent: { - if showTrailingContent { - switch trailingContentFocusableElementCount { - case 0: - Text("Spreadsheet") - case 1: - Toggle("", isOn: $trailingContentToggleEnabled) - default: - HStack { - Button { - showingSecondaryAlert = true - } label: { - Text("Button 1") - } - Button { - showingSecondaryAlert = true - } label: { - Text("Button 2") - } - } - } - } - }, - action: !isTappable ? nil : { - showingPrimaryAlert = true - } - ) - .backgroundStyleType(backgroundStyle) - .accessoryType(accessoryType) - .leadingContentSize(leadingContentSize) - .titleLineLimit(titleLineLimit) - .subtitleLineLimit(subtitleLineLimit) - .footerLineLimit(footerLineLimit) - .combineTrailingContentAccessibilityElement(trailingContentFocusableElementCount < 2) - .onAccessoryTapped { - showingSecondaryAlert = true - } - .disabled(isDisabled) - .alert("List Item tapped", isPresented: $showingPrimaryAlert) { - Button("OK", role: .cancel) { } - } - .alert("Detail button tapped", isPresented: $showingSecondaryAlert) { - Button("OK", role: .cancel) { } - } + var listItem = ListItem(title: title, + subtitle: showSubtitle ? subtitle : "", + footer: showFooter ? footer : "", + leadingContent: { + if showLeadingContent { + leadingContent + } + }, + trailingContent: { + if showTrailingContent { + switch trailingContentFocusableElementCount { + case 0: + Text("Spreadsheet") + case 1: + Toggle("", isOn: $trailingContentToggleEnabled) + default: + HStack { + Button { + showingSecondaryAlert = true + } label: { + Text("Button 1") + } + Button { + showingSecondaryAlert = true + } label: { + Text("Button 2") + } + } + } + } + }, + action: !isTappable ? nil : { + showingPrimaryAlert = true + }) + .backgroundStyleType(backgroundStyle) + .accessoryType(accessoryType) + .leadingContentSize(leadingContentSize) + .titleLineLimit(titleLineLimit) + .subtitleLineLimit(subtitleLineLimit) + .footerLineLimit(footerLineLimit) + .combineTrailingContentAccessibilityElement(trailingContentFocusableElementCount < 2) + .onAccessoryTapped { + showingSecondaryAlert = true + } + listItem + .overrideTokens($overrideTokens.wrappedValue ? listItemTokenOverrides : [:]) + .disabled(isDisabled) + .alert("List Item tapped", isPresented: $showingPrimaryAlert) { + Button("OK", role: .cancel) { } + } + .alert("Detail button tapped", isPresented: $showingSecondaryAlert) { + Button("OK", role: .cancel) { } + } } @ViewBuilder @@ -223,6 +226,22 @@ struct ListItemDemoView: View { return content } + + private var listItemTokenOverrides: [ListItemToken: ControlTokenValue] { + return [ + .titleColor: .uiColor { + GlobalTokens.sharedColor(.red, .primary) + }, + .cellBackgroundGroupedColor: .uiColor { + UIColor(light: GlobalTokens.sharedColor(.brass, .tint50), + dark: GlobalTokens.sharedColor(.brass, .shade40)) + }, + .accessoryDisclosureIndicatorColor: .uiColor { + UIColor(light: GlobalTokens.sharedColor(.forest, .tint10), + dark: GlobalTokens.sharedColor(.forest, .shade40)) + } + ] + } } struct UIViewWrapper: UIViewRepresentable { diff --git a/ios/FluentUI/List/ListItem.swift b/ios/FluentUI/List/ListItem.swift index e4de99d77..bc9e37752 100644 --- a/ios/FluentUI/List/ListItem.swift +++ b/ios/FluentUI/List/ListItem.swift @@ -9,6 +9,7 @@ public typealias ListItemAccessoryType = TableViewCellAccessoryType public typealias ListItemBackgroundStyleType = TableViewCellBackgroundStyleType public typealias ListItemLeadingContentSize = MSFTableViewCellCustomViewSize public typealias ListItemTokenSet = TableViewCellTokenSet +public typealias ListItemToken = TableViewCellToken /// View that represents an item in a List. public struct ListItem Self { + tokenOverrides = overrides + return self + } +} diff --git a/ios/FluentUI/List/ListItemModifiers.swift b/ios/FluentUI/List/ListItemModifiers.swift index 343ae5f42..de1e858ad 100644 --- a/ios/FluentUI/List/ListItemModifiers.swift +++ b/ios/FluentUI/List/ListItemModifiers.swift @@ -64,7 +64,7 @@ public extension ListItem { /// - Returns: The modified `ListItem` with the property set. func leadingContentSize(_ size: ListItemLeadingContentSize) -> ListItem { var listItem = self - listItem.tokenSet = ListItemTokenSet(customViewSize: { size }) + listItem.leadingContentSize = size return listItem }