From a96bff24337b6e7ba2f16db58498704dee4bdae6 Mon Sep 17 00:00:00 2001 From: Toomas Vahter Date: Fri, 10 Apr 2026 12:49:16 +0300 Subject: [PATCH 1/3] Add docs to color tokens --- .../Appearance+ColorPalette.swift | 265 ++++++++++++++---- 1 file changed, 211 insertions(+), 54 deletions(-) diff --git a/Sources/StreamChatCommonUI/Appearance+ColorPalette.swift b/Sources/StreamChatCommonUI/Appearance+ColorPalette.swift index 078a83acfd..da0c9853dd 100644 --- a/Sources/StreamChatCommonUI/Appearance+ColorPalette.swift +++ b/Sources/StreamChatCommonUI/Appearance+ColorPalette.swift @@ -8,124 +8,276 @@ import UIKit public extension Appearance { @MainActor final class ColorPalette { - public lazy var accentError: UIColor = UIColor(light: .red500, dark: .red400) - public lazy var accentNeutral: UIColor = chrome500 + // MARK: - Accent + + /// The main brand color. Used for interactive elements, buttons, links, and primary actions. + /// Override this to apply your brand color across the SDK. public lazy var accentPrimary: UIColor = UIColor(light: brand500, dark: brand400) + /// Indicates a positive or completed state. Used for confirmations and success feedback. public lazy var accentSuccess: UIColor = UIColor(light: .green400, dark: .green300) - public lazy var avatarBackgroundDefault: UIColor = avatarPaletteBackground1 - public lazy var avatarPaletteBackground1: UIColor = UIColor(light: .blue150, dark: .blue600) - public lazy var avatarPaletteText1: UIColor = UIColor(light: .blue900, dark: .blue100) - public lazy var avatarTextDefault: UIColor = avatarPaletteText1 + /// Indicates a failure or destructive state. Used for failed messages, validation errors, and deletions. + public lazy var accentError: UIColor = UIColor(light: .red500, dark: .red400) + /// A mid-tone gray for de-emphasized UI elements. + public lazy var accentNeutral: UIColor = chrome500 + + // MARK: - Background + + /// The outermost application background. Sits behind all surfaces. public lazy var backgroundCoreApp: UIColor = chrome0 + /// The base layer. Always white, used as the reference point for the elevation scale. public lazy var backgroundCoreElevation0: UIColor = chrome0 + /// Slightly raised surfaces. Used for content containers like the message list and channel list. public lazy var backgroundCoreElevation1: UIColor = UIColor(light: chrome0, dark: chrome50) + /// Floating and modal surfaces. Used for popovers, dropdowns, and dialogs. public lazy var backgroundCoreElevation2: UIColor = UIColor(light: chrome0, dark: chrome100) + /// Used for badge counts that float above other UI elements. public lazy var backgroundCoreElevation3: UIColor = UIColor(light: chrome0, dark: chrome200) - public lazy var backgroundCoreHighlight: UIColor = UIColor(light: .yellow50, dark: .yellow800) + /// Background for sectioned content areas. Used for grouped containers and distinct content regions. + public lazy var backgroundCoreSurfaceDefault: UIColor = chrome100 + /// A slightly receded background. Used for secondary containers or to create soft visual separation. + public lazy var backgroundCoreSurfaceSubtle: UIColor = chrome50 + /// Background for contained, card-style elements. Matches the surface in light mode but lifts slightly in dark mode. + public lazy var backgroundCoreSurfaceCard: UIColor = UIColor(light: chrome50, dark: chrome100) + /// A more prominent background. Used for elements that need to stand out from the main surface. + public lazy var backgroundCoreSurfaceStrong: UIColor = chrome150 + /// The opposite of the primary surface. Used for tooltips, snackbars, and high-contrast floating elements. public lazy var backgroundCoreInverse: UIColor = chrome1000 + /// Background for elements placed on an accent-colored surface. Ensures legibility against brand colors. public lazy var backgroundCoreOnAccent: UIColor = UIColor(light: chrome0, dark: chrome1000) - public lazy var backgroundCoreOverlayDark: UIColor = UIColor(light: UIColor(hex: 0x1a1b2540), dark: UIColor(hex: 0x00000080)) + /// A tint for drawing attention to content. Used for highlights and pinned messages. + public lazy var backgroundCoreHighlight: UIColor = UIColor(light: .yellow50, dark: .yellow800) + /// A light semi-transparent layer. Used to lighten surfaces and for hover states on dark backgrounds. public lazy var backgroundCoreOverlayLight: UIColor = UIColor(light: UIColor(hex: 0xffffffbf), dark: UIColor(hex: 0x000000bf)) + /// A dark semi-transparent layer. Used for image overlays. + public lazy var backgroundCoreOverlayDark: UIColor = UIColor(light: UIColor(hex: 0x1a1b2540), dark: UIColor(hex: 0x00000080)) + /// A heavy semi-transparent layer. Used behind sheets, drawers, and modals to separate them from content. public lazy var backgroundCoreScrim: UIColor = UIColor(light: UIColor(hex: 0x1a1b2580), dark: UIColor(hex: 0x000000bf)) - public lazy var backgroundCoreSurfaceCard: UIColor = UIColor(light: chrome50, dark: chrome100) - public lazy var backgroundCoreSurfaceDefault: UIColor = chrome100 - public lazy var backgroundCoreSurfaceStrong: UIColor = chrome150 - public lazy var backgroundCoreSurfaceSubtle: UIColor = chrome50 - public lazy var backgroundUtilityDisabled: UIColor = chrome100 + /// A slightly stronger overlay applied during an active press or tap. Provides tactile feedback on interactive elements. public lazy var backgroundUtilityPressed: UIColor = UIColor(light: UIColor(hex: 0x1a1b2526), dark: UIColor(hex: 0xffffff33)) + /// Indicates an active or selected state. Used for selected messages, active list items, and toggled controls. public lazy var backgroundUtilitySelected: UIColor = UIColor(light: UIColor(hex: 0x1a1b2533), dark: UIColor(hex: 0xffffff40)) + /// Background for non-interactive elements. Flattens the element visually to signal unavailability. + public lazy var backgroundUtilityDisabled: UIColor = chrome100 + + // MARK: - Text + + /// Main body text. Used for message content, titles, and any text that carries primary meaning. + public lazy var textPrimary: UIColor = chrome900 + /// Supporting metadata text. Used for timestamps, subtitles, and secondary labels. + public lazy var textSecondary: UIColor = chrome700 + /// De-emphasized text. Used for hints, placeholders, and lowest-priority supporting information. + public lazy var textTertiary: UIColor = chrome500 + /// Text on inverse-colored surfaces. Flips between light and dark to maintain legibility when the background inverts. + public lazy var textOnInverse: UIColor = chrome0 + /// Text on accent-colored surfaces. Stays white in both light and dark mode since the accent background does not invert. + public lazy var textOnAccent: UIColor = UIColor(light: chrome0, dark: chrome1000) + /// Text for non-interactive or unavailable states. Communicates that an element cannot be interacted with. + public lazy var textDisabled: UIColor = chrome300 + /// Hyperlinks and inline actions. Uses the brand color to signal interactivity within text content. + public lazy var textLink: UIColor = UIColor(light: brand500, dark: brand600) + + // MARK: - Border + + /// Standard border for surfaces and containers. Used for input fields, cards, and dividers on neutral backgrounds. + public lazy var borderCoreDefault: UIColor = UIColor(light: chrome150, dark: chrome200) + /// A lighter border for minimal separation. Used where a full-strength border would feel too heavy. + public lazy var borderCoreSubtle: UIColor = chrome100 + /// An emphatic border for elements that need clear definition. Used for focused containers and prominent dividers. + public lazy var borderCoreStrong: UIColor = chrome300 + /// Border on inverse-colored surfaces. Stays legible when the background flips between light and dark mode. + public lazy var borderCoreInverse: UIColor = chrome0 + /// Border on inverse-colored surfaces used as a separator element. + public lazy var borderCoreOnInverse: UIColor = chrome0 + /// Border on accent-colored surfaces. Stays white in both light and dark mode since the accent background does not invert. + public lazy var borderCoreOnAccent: UIColor = UIColor(light: chrome0, dark: chrome1000) + /// A very light transparent border. Used as a frame treatment on images and media attachments. + public lazy var borderCoreOpacitySubtle: UIColor = UIColor(light: UIColor(hex: 0x1a1b251a), dark: UIColor(hex: 0xffffff33)) + /// A stronger transparent border for elements on colored or dark backgrounds. Used for waveform bars and similar treatments. + public lazy var borderCoreOpacityStrong: UIColor = UIColor(light: UIColor(hex: 0x1a1b2540), dark: UIColor(hex: 0xffffff40)) + /// Border for non-interactive elements. Matches the disabled surface to visually flatten the element. + public lazy var borderUtilityDisabled: UIColor = chrome100 + /// Border for disabled elements on elevated surfaces. Stays visually distinct from the surface without drawing attention. + public lazy var borderUtilityDisabledOnSurface: UIColor = chrome150 + + // MARK: - Avatar + + /// Default avatar background color. + public lazy var avatarBackgroundDefault: UIColor = avatarPaletteBackground1 + /// First palette option for avatar backgrounds. + public lazy var avatarPaletteBackground1: UIColor = UIColor(light: .blue150, dark: .blue600) + /// Text color paired with the first avatar palette background. + public lazy var avatarPaletteText1: UIColor = UIColor(light: .blue900, dark: .blue100) + /// Default text color for avatar initials. + public lazy var avatarTextDefault: UIColor = avatarPaletteText1 + + // MARK: - Badge + + /// Background for the default badge variant. public lazy var badgeBackgroundDefault: UIColor = backgroundCoreElevation3 + /// Background for error badges indicating failures or critical counts. public lazy var badgeBackgroundError: UIColor = accentError + /// Background for badges on light surfaces requiring high contrast. public lazy var badgeBackgroundInverse: UIColor = chrome1000 + /// Background for neutral, informational badges. public lazy var badgeBackgroundNeutral: UIColor = accentNeutral + /// Background for badges overlaid on media or images. public lazy var badgeBackgroundOverlay: UIColor = UIColor(hex: 0x000000bf) + /// Background for primary-styled badges. public lazy var badgeBackgroundPrimary: UIColor = accentPrimary + /// Border color for badges. public lazy var badgeBorder: UIColor = borderCoreOnInverse + /// Text color for badges on default backgrounds. public lazy var badgeText: UIColor = textPrimary + /// Text color for badges on accent-colored backgrounds. public lazy var badgeTextOnAccent: UIColor = textOnAccent + /// Text color for badges on inverse backgrounds. public lazy var badgeTextOnInverse: UIColor = textOnInverse - public lazy var borderCoreDefault: UIColor = UIColor(light: chrome150, dark: chrome200) - public lazy var borderCoreInverse: UIColor = chrome0 - public lazy var borderCoreOnAccent: UIColor = UIColor(light: chrome0, dark: chrome1000) - public lazy var borderCoreOnInverse: UIColor = chrome0 - public lazy var borderCoreOpacityStrong: UIColor = UIColor(light: UIColor(hex: 0x1a1b2540), dark: UIColor(hex: 0xffffff40)) - public lazy var borderCoreOpacitySubtle: UIColor = UIColor(light: UIColor(hex: 0x1a1b251a), dark: UIColor(hex: 0xffffff33)) - public lazy var borderCoreStrong: UIColor = chrome300 - public lazy var borderCoreSubtle: UIColor = chrome100 - public lazy var borderUtilityDisabled: UIColor = chrome100 - public lazy var borderUtilityDisabledOnSurface: UIColor = chrome150 - public lazy var buttonDestructiveBackground: UIColor = accentError - public lazy var buttonDestructiveBackgroundLiquidGlass: UIColor = backgroundCoreElevation0 - public lazy var buttonDestructiveBorder: UIColor = accentError - public lazy var buttonDestructiveText: UIColor = accentError - public lazy var buttonDestructiveTextOnAccent: UIColor = textOnAccent + + // MARK: - Button + + /// Background for primary action buttons. public lazy var buttonPrimaryBackground: UIColor = accentPrimary + /// Background for primary buttons with Liquid Glass material. public lazy var buttonPrimaryBackgroundLiquidGlass: UIColor = .baseTransparent0 + /// Border for primary action buttons. public lazy var buttonPrimaryBorder: UIColor = brand200 + /// Text color for outlined primary buttons. public lazy var buttonPrimaryText: UIColor = accentPrimary + /// Text color for filled primary buttons. public lazy var buttonPrimaryTextOnAccent: UIColor = textOnAccent + /// Background for secondary action buttons. public lazy var buttonSecondaryBackground: UIColor = backgroundCoreSurfaceDefault + /// Background for secondary buttons with Liquid Glass material. public lazy var buttonSecondaryBackgroundLiquidGlass: UIColor = backgroundCoreElevation0 + /// Border for secondary action buttons. public lazy var buttonSecondaryBorder: UIColor = borderCoreDefault + /// Text color for secondary buttons. public lazy var buttonSecondaryText: UIColor = textPrimary + /// Text color for filled secondary buttons. public lazy var buttonSecondaryTextOnAccent: UIColor = textPrimary - public lazy var chatBackgroundAttachmentIncoming: UIColor = backgroundCoreSurfaceStrong - public lazy var chatBackgroundAttachmentOutgoing: UIColor = brand150 + /// Background for destructive action buttons. + public lazy var buttonDestructiveBackground: UIColor = accentError + /// Background for destructive buttons with Liquid Glass material. + public lazy var buttonDestructiveBackgroundLiquidGlass: UIColor = backgroundCoreElevation0 + /// Border for destructive action buttons. + public lazy var buttonDestructiveBorder: UIColor = accentError + /// Text color for outlined destructive buttons. + public lazy var buttonDestructiveText: UIColor = accentError + /// Text color for filled destructive buttons. + public lazy var buttonDestructiveTextOnAccent: UIColor = textOnAccent + + // MARK: - Chat + + /// Bubble background for incoming messages. public lazy var chatBackgroundIncoming: UIColor = backgroundCoreSurfaceDefault + /// Bubble background for outgoing messages. public lazy var chatBackgroundOutgoing: UIColor = brand100 + /// Background for attachment previews in incoming messages. + public lazy var chatBackgroundAttachmentIncoming: UIColor = backgroundCoreSurfaceStrong + /// Background for attachment previews in outgoing messages. + public lazy var chatBackgroundAttachmentOutgoing: UIColor = brand150 + /// Border for incoming message bubbles. public lazy var chatBorderIncoming: UIColor = borderCoreSubtle + /// Border for outgoing message bubbles. + public lazy var chatBorderOutgoing: UIColor = brand100 + /// Border for elements inside incoming message bubbles. public lazy var chatBorderOnChatIncoming: UIColor = borderCoreStrong + /// Border for elements inside outgoing message bubbles. public lazy var chatBorderOnChatOutgoing: UIColor = brand300 - public lazy var chatBorderOutgoing: UIColor = brand100 - public lazy var chatPollProgressFillIncoming: UIColor = controlProgressBarFill - public lazy var chatPollProgressFillOutgoing: UIColor = accentPrimary - public lazy var chatPollProgressTrackIncoming: UIColor = controlProgressBarTrack - public lazy var chatPollProgressTrackOutgoing: UIColor = brand200 - public lazy var chatReplyIndicatorIncoming: UIColor = chrome400 - public lazy var chatReplyIndicatorOutgoing: UIColor = brand400 + /// Text color for incoming messages. public lazy var chatTextIncoming: UIColor = textPrimary - public lazy var chatTextLink: UIColor = textLink + /// Text color for outgoing messages. public lazy var chatTextOutgoing: UIColor = brand900 + /// Link text color within chat messages. + public lazy var chatTextLink: UIColor = textLink + /// Text color for system messages. public lazy var chatTextSystem: UIColor = textSecondary + /// Text color for message timestamps. public lazy var chatTextTimestamp: UIColor = textTertiary + /// Text color for the typing indicator. public lazy var chatTextTypingIndicator: UIColor = chatTextIncoming + /// Text color for usernames in chat. public lazy var chatTextUsername: UIColor = textSecondary + /// Reply thread indicator color for incoming messages. + public lazy var chatReplyIndicatorIncoming: UIColor = chrome400 + /// Reply thread indicator color for outgoing messages. + public lazy var chatReplyIndicatorOutgoing: UIColor = brand400 + /// Poll progress bar fill color in incoming messages. + public lazy var chatPollProgressFillIncoming: UIColor = controlProgressBarFill + /// Poll progress bar fill color in outgoing messages. + public lazy var chatPollProgressFillOutgoing: UIColor = accentPrimary + /// Poll progress bar track color in incoming messages. + public lazy var chatPollProgressTrackIncoming: UIColor = controlProgressBarTrack + /// Poll progress bar track color in outgoing messages. + public lazy var chatPollProgressTrackOutgoing: UIColor = brand200 + + // MARK: - Control + + /// Border for checkbox controls. public lazy var controlCheckboxBorder: UIColor = borderCoreDefault + /// Text color for chip controls. public lazy var controlChipText: UIColor = textPrimary + /// Background for the active playback scrubber thumb. public lazy var controlPlaybackThumbBackgroundActive: UIColor = accentPrimary + /// Background for the default playback scrubber thumb. public lazy var controlPlaybackThumbBackgroundDefault: UIColor = backgroundCoreOnAccent + /// Border for the active playback scrubber thumb. public lazy var controlPlaybackThumbBorderActive: UIColor = borderCoreOnAccent + /// Border for the default playback scrubber thumb. public lazy var controlPlaybackThumbBorderDefault: UIColor = borderCoreOpacityStrong + /// Background for the play button overlay. public lazy var controlPlayButtonBackground: UIColor = UIColor(hex: 0x000000bf) + /// Icon color for the play button overlay. public lazy var controlPlayButtonIcon: UIColor = textOnAccent + /// Fill color for progress bars. public lazy var controlProgressBarFill: UIColor = accentNeutral + /// Track color for progress bars. public lazy var controlProgressBarTrack: UIColor = backgroundCoreSurfaceStrong + /// Background for selected radio buttons and checkmarks. public lazy var controlRadioCheckBackgroundSelected: UIColor = accentPrimary + /// Border for radio buttons and checkmarks. public lazy var controlRadioCheckBorder: UIColor = borderCoreDefault + /// Icon color for the check indicator in radio buttons and checkmarks. public lazy var controlRadioCheckIcon: UIColor = textOnAccent + /// Background for the remove/delete control. public lazy var controlRemoveControlBackground: UIColor = backgroundCoreInverse + /// Border for the remove/delete control. public lazy var controlRemoveControlBorder: UIColor = borderCoreOnInverse + /// Icon color for the remove/delete control. public lazy var controlRemoveControlIcon: UIColor = textOnInverse + + // MARK: - Input + + /// Send button icon color when the input is empty or disabled. public lazy var inputSendIconDisabled: UIColor = textDisabled + /// Default text color for input fields. public lazy var inputTextDefault: UIColor = textPrimary + /// Icon color within input fields. public lazy var inputTextIcon: UIColor = textTertiary + /// Placeholder text color for input fields. public lazy var inputTextPlaceholder: UIColor = textTertiary + + // MARK: - Presence + + /// Background for the offline presence indicator. public lazy var presenceBackgroundOffline: UIColor = accentNeutral + /// Background for the online presence indicator. public lazy var presenceBackgroundOnline: UIColor = accentSuccess + /// Border for presence indicator dots. public lazy var presenceBorder: UIColor = borderCoreInverse + + // MARK: - Reaction + + /// Background for reaction pills. public lazy var reactionBackground: UIColor = backgroundCoreElevation3 + /// Border for reaction pills. public lazy var reactionBorder: UIColor = borderCoreDefault + /// Text color for reaction counts. public lazy var reactionText: UIColor = textPrimary - public lazy var textDisabled: UIColor = chrome300 - public lazy var textLink: UIColor = UIColor(light: brand500, dark: brand600) - public lazy var textOnAccent: UIColor = UIColor(light: chrome0, dark: chrome1000) - public lazy var textOnInverse: UIColor = chrome0 - public lazy var textPrimary: UIColor = chrome900 - public lazy var textSecondary: UIColor = chrome700 - public lazy var textTertiary: UIColor = chrome500 - - // MARK: - SwiftUI SDK + // MARK: - Navigation (SwiftUI SDK only) + + /// Title text color in the navigation bar. public lazy var navigationBarTitle: UIColor = textPrimary { didSet { StreamConcurrency.onMain { [navigationBarTitle] in @@ -135,18 +287,23 @@ public extension Appearance { } } } - + + /// Subtitle text color in the navigation bar. public lazy var navigationBarSubtitle: UIColor = textTertiary + /// Background color for the navigation bar. Defaults to system appearance when `nil`. public var navigationBarBackground: UIColor? + /// Tint color for navigation bar buttons and icons. public lazy var navigationBarTintColor: UIColor = accentPrimary + /// Color for navigation bar glyph elements. public lazy var navigationBarGlyph: UIColor = .baseWhite - // MARK: - UIKit SDK - + // MARK: - Utilities + + /// Returns a highlighted variant of the given color. Used for tap/press states in UIKit views. public var highlightedColorForColor: @Sendable (UIColor) -> UIColor = { $0.withAlphaComponent(0.5) } - + // MARK: - Internal - + var brand100: UIColor { UIColor(light: .blue100, dark: .blue800) } var brand150: UIColor { UIColor(light: .blue150, dark: .blue700) } var brand200: UIColor { UIColor(light: .blue200, dark: .blue600) } @@ -186,13 +343,13 @@ extension UIColor { let a = CGFloat(hex & 0xff) / 255.0 self.init(red: r, green: g, blue: b, alpha: a) } - + convenience init(light: UIColor, dark: UIColor) { self.init { trait in return trait.userInterfaceStyle == .dark ? dark : light } } - + static let baseBlack: UIColor = UIColor(hex: 0x000000ff) static let baseTransparent0: UIColor = UIColor(hex: 0xffffff00) static let baseTransparentBlack10: UIColor = UIColor(hex: 0x0000001a) From 03dd4ae29bae26fe0b3b41c20ad5e3b84495c587 Mon Sep 17 00:00:00 2001 From: Toomas Vahter Date: Fri, 10 Apr 2026 14:49:27 +0300 Subject: [PATCH 2/3] Slight comment change --- Sources/StreamChatCommonUI/Appearance+ColorPalette.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/StreamChatCommonUI/Appearance+ColorPalette.swift b/Sources/StreamChatCommonUI/Appearance+ColorPalette.swift index da0c9853dd..65a184400e 100644 --- a/Sources/StreamChatCommonUI/Appearance+ColorPalette.swift +++ b/Sources/StreamChatCommonUI/Appearance+ColorPalette.swift @@ -24,7 +24,7 @@ public extension Appearance { /// The outermost application background. Sits behind all surfaces. public lazy var backgroundCoreApp: UIColor = chrome0 - /// The base layer. Always white, used as the reference point for the elevation scale. + /// The base layer. Used as the reference point for the elevation scale. public lazy var backgroundCoreElevation0: UIColor = chrome0 /// Slightly raised surfaces. Used for content containers like the message list and channel list. public lazy var backgroundCoreElevation1: UIColor = UIColor(light: chrome0, dark: chrome50) From ba71393a34c7e7cd6351ddf3cd4ef38e5e3cf36f Mon Sep 17 00:00:00 2001 From: Toomas Vahter Date: Fri, 10 Apr 2026 14:57:58 +0300 Subject: [PATCH 3/3] Add UIKit only mention --- Sources/StreamChatCommonUI/Appearance+ColorPalette.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/StreamChatCommonUI/Appearance+ColorPalette.swift b/Sources/StreamChatCommonUI/Appearance+ColorPalette.swift index 65a184400e..245352a27c 100644 --- a/Sources/StreamChatCommonUI/Appearance+ColorPalette.swift +++ b/Sources/StreamChatCommonUI/Appearance+ColorPalette.swift @@ -297,7 +297,7 @@ public extension Appearance { /// Color for navigation bar glyph elements. public lazy var navigationBarGlyph: UIColor = .baseWhite - // MARK: - Utilities + // MARK: - Utilities (UIKit SDK only) /// Returns a highlighted variant of the given color. Used for tap/press states in UIKit views. public var highlightedColorForColor: @Sendable (UIColor) -> UIColor = { $0.withAlphaComponent(0.5) }