diff --git a/SharedPackages/Onboarding/Package.resolved b/SharedPackages/Onboarding/Package.resolved new file mode 100644 index 00000000000..2bbebca29a1 --- /dev/null +++ b/SharedPackages/Onboarding/Package.resolved @@ -0,0 +1,96 @@ +{ + "originHash" : "c407e31ef7456d9a2d67dc283ee0aabeaf742668e4abdfdcadb651057f08bfe8", + "pins" : [ + { + "identity" : "content-scope-scripts", + "kind" : "remoteSourceControl", + "location" : "https://github.com/duckduckgo/content-scope-scripts.git", + "state" : { + "revision" : "454f3131bbbdc19a4bf5bc1c2aabf1725cc9f5fc", + "version" : "13.41.0" + } + }, + { + "identity" : "duckduckgo-autofill", + "kind" : "remoteSourceControl", + "location" : "https://github.com/duckduckgo/duckduckgo-autofill.git", + "state" : { + "revision" : "c8ce2e7cdcca4226c96350dcd49323298b941592", + "version" : "19.0.0" + } + }, + { + "identity" : "gzipswift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/1024jp/GzipSwift.git", + "state" : { + "revision" : "731037f6cc2be2ec01562f6597c1d0aa3fe6fd05", + "version" : "6.0.1" + } + }, + { + "identity" : "jwt-kit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/vapor/jwt-kit.git", + "state" : { + "revision" : "13e7513b3ba0afa13967daf77af2fb4ad087306c", + "version" : "4.13.5" + } + }, + { + "identity" : "privacy-dashboard", + "kind" : "remoteSourceControl", + "location" : "https://github.com/duckduckgo/privacy-dashboard", + "state" : { + "revision" : "40a8c752fb73a15738899dc0edb5e17e33302a37", + "version" : "9.10.1" + } + }, + { + "identity" : "punycodeswift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/gumob/PunycodeSwift.git", + "state" : { + "revision" : "30a462bdb4398ea835a3585472229e0d74b36ba5", + "version" : "3.0.0" + } + }, + { + "identity" : "swift-asn1", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-asn1.git", + "state" : { + "revision" : "9f542610331815e29cc3821d3b6f488db8715517", + "version" : "1.6.0" + } + }, + { + "identity" : "swift-crypto", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-crypto.git", + "state" : { + "revision" : "95ba0316a9b733e92bb6b071255ff46263bbe7dc", + "version" : "3.15.1" + } + }, + { + "identity" : "sync_crypto", + "kind" : "remoteSourceControl", + "location" : "https://github.com/duckduckgo/sync_crypto", + "state" : { + "revision" : "8dfdea29e325c6611d9b2b556e1d380252d54ba6", + "version" : "0.7.0" + } + }, + { + "identity" : "trackerradarkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/duckduckgo/TrackerRadarKit.git", + "state" : { + "revision" : "6d2db2a50cbd6d0a33d40864953bbef523489b28", + "version" : "3.1.0" + } + } + ], + "version" : 3 +} diff --git a/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/Shared/RebrandedContextualDaxDialogContent.swift b/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/Shared/RebrandedContextualDaxDialogContent.swift index a957e6e6205..bd4a6540192 100644 --- a/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/Shared/RebrandedContextualDaxDialogContent.swift +++ b/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/Shared/RebrandedContextualDaxDialogContent.swift @@ -41,6 +41,8 @@ extension OnboardingRebranding { private let messageTextAlignment: TextAlignment? private let content: Content + @State private var startTypingTitle = false + @State private var startTypingMessage = false @State private var shouldShowContent = false #if os(iOS) @@ -101,27 +103,54 @@ extension OnboardingRebranding { switch orientation { case .verticalStack: VStack(alignment: .leading, spacing: theme.contentSpacing) { - TitleMessageStack(title: title, message: message, titleBodyVerticalSpacing: theme.titleBodyVerticalSpacingVerticalLayout, titleTextAlignment: titleTextAlignment, messageTextAlignment: messageTextAlignment) + TypingTitleMessageStack( + title: title, + message: message, + titleBodyVerticalSpacing: theme.titleBodyVerticalSpacingVerticalLayout, + titleTextAlignment: titleTextAlignment, + messageTextAlignment: messageTextAlignment, + startTypingTitle: $startTypingTitle, + startTypingMessage: $startTypingMessage, + onTypingFinished: animateContentIn + ) content + .visibility(shouldShowContent ? .visible : .invisible) } case let .horizontalStack(alignment): HStack(alignment: alignment) { - TitleMessageStack(title: title, message: message, titleBodyVerticalSpacing: theme.titleBodyVerticalSpacingHorizontalLayout, titleTextAlignment: titleTextAlignment, messageTextAlignment: messageTextAlignment) + TypingTitleMessageStack( + title: title, + message: message, + titleBodyVerticalSpacing: theme.titleBodyVerticalSpacingHorizontalLayout, + titleTextAlignment: titleTextAlignment, + messageTextAlignment: messageTextAlignment, + startTypingTitle: $startTypingTitle, + startTypingMessage: $startTypingMessage, + onTypingFinished: animateContentIn + ) Spacer(minLength: theme.contentSpacing) content + .visibility(shouldShowContent ? .visible : .invisible) } } } - .opacity(shouldShowContent ? 1 : 0) .onAppear { Task { @MainActor in try await Task.sleep(interval: theme.contentFadeInDelay) - withAnimation(.easeIn(duration: theme.contentFadeInDuration)) { - shouldShowContent = true + if title != nil { + startTypingTitle = true + } else { + startTypingMessage = true } } } } + + private func animateContentIn() { + withAnimation(.easeIn(duration: theme.contentFadeInDuration).delay(0.3)) { + shouldShowContent = true + } + } } } @@ -176,7 +205,7 @@ extension OnboardingRebranding.ContextualDaxDialogContent where Content == Empty private extension OnboardingRebranding { - struct TitleMessageStack: View { + struct TypingTitleMessageStack: View { @Environment(\.onboardingTheme) private var theme #if os(iOS) @@ -192,24 +221,59 @@ private extension OnboardingRebranding { var titleTextAlignment: TextAlignment? var messageTextAlignment: TextAlignment? + @Binding var startTypingTitle: Bool + @Binding var startTypingMessage: Bool + let onTypingFinished: () -> Void + var body: some View { VStack(alignment: .leading, spacing: titleBodyVerticalSpacing) { if let title { let titleAlignment = titleTextAlignment ?? theme.contextualOnboardingMetrics.contextualTitleTextAlignment - StyledAttributedText(title) - .font(theme.typography.contextual.title) - .multilineTextAlignment(titleAlignment) - .frame(maxWidth: .infinity, alignment: Alignment(titleAlignment)) + titleTypingView(title, alignment: titleAlignment) } let messageAlignment = messageTextAlignment ?? theme.contextualOnboardingMetrics.contextualBodyTextAlignment - StyledAttributedText(message) - .font(theme.typography.contextual.body) - .multilineTextAlignment(messageAlignment) - .frame(maxWidth: .infinity, alignment: Alignment(messageAlignment)) + messageTypingView(alignment: messageAlignment) } .padding(theme.contextualOnboardingMetrics.titleBodyInset) + } + #if os(iOS) + @ViewBuilder + private func titleTypingView(_ title: AttributedString, alignment: TextAlignment) -> some View { + AnimatableTypingText(NSAttributedString(title), startAnimating: $startTypingTitle, onTypingFinished: { + startTypingMessage = true + }) + .font(theme.typography.contextual.title) + .multilineTextAlignment(alignment) + .frame(maxWidth: .infinity, alignment: Alignment(alignment)) } + + @ViewBuilder + private func messageTypingView(alignment: TextAlignment) -> some View { + AnimatableTypingText(NSAttributedString(message), startAnimating: $startTypingMessage, onTypingFinished: onTypingFinished) + .font(theme.typography.contextual.body) + .multilineTextAlignment(alignment) + .frame(maxWidth: .infinity, alignment: Alignment(alignment)) + } + #else + @ViewBuilder + private func titleTypingView(_ title: NSAttributedString, alignment: TextAlignment) -> some View { + AnimatableTypingText(title, startAnimating: $startTypingTitle, onTypingFinished: { + startTypingMessage = true + }) + .font(theme.typography.contextual.title) + .multilineTextAlignment(alignment) + .frame(maxWidth: .infinity, alignment: Alignment(alignment)) + } + + @ViewBuilder + private func messageTypingView(alignment: TextAlignment) -> some View { + AnimatableTypingText(message, startAnimating: $startTypingMessage, onTypingFinished: onTypingFinished) + .font(theme.typography.contextual.body) + .multilineTextAlignment(alignment) + .frame(maxWidth: .infinity, alignment: Alignment(alignment)) + } + #endif } } diff --git a/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/Shared/Styles/RebrandedOnboardingStyles+CTAButton.swift b/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/Shared/Styles/RebrandedOnboardingStyles+CTAButton.swift new file mode 100644 index 00000000000..53cdfa7a161 --- /dev/null +++ b/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/Shared/Styles/RebrandedOnboardingStyles+CTAButton.swift @@ -0,0 +1,115 @@ +// +// RebrandedOnboardingStyles+CTAButton.swift +// +// Copyright © 2026 DuckDuckGo. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import SwiftUI + +public extension OnboardingRebranding.OnboardingStyles { + + struct CTAButtonStyle: ButtonStyle { + private let backgroundColor: Color + private let pressedBackgroundColor: Color + private let foregroundColor: Color + private let font: Font + private let verticalPadding: CGFloat + private let horizontalPadding: CGFloat + private let cornerRadius: CGFloat + private let minWidth: CGFloat + private let minHeight: CGFloat + + public init( + backgroundColor: Color, + pressedBackgroundColor: Color, + foregroundColor: Color, + font: Font, + verticalPadding: CGFloat = 8, + horizontalPadding: CGFloat = 24, + cornerRadius: CGFloat = 100, + minWidth: CGFloat = 174, + minHeight: CGFloat = 32 + ) { + self.backgroundColor = backgroundColor + self.pressedBackgroundColor = pressedBackgroundColor + self.foregroundColor = foregroundColor + self.font = font + self.verticalPadding = verticalPadding + self.horizontalPadding = horizontalPadding + self.cornerRadius = cornerRadius + self.minWidth = minWidth + self.minHeight = minHeight + } + + public func makeBody(configuration: Configuration) -> some View { + CTAButtonContent( + configuration: configuration, + backgroundColor: backgroundColor, + pressedBackgroundColor: pressedBackgroundColor, + foregroundColor: foregroundColor, + font: font, + verticalPadding: verticalPadding, + horizontalPadding: horizontalPadding, + cornerRadius: cornerRadius, + minWidth: minWidth, + minHeight: minHeight + ) + } + + private struct CTAButtonContent: View { + let configuration: ButtonStyle.Configuration + let backgroundColor: Color + let pressedBackgroundColor: Color + let foregroundColor: Color + let font: Font + let verticalPadding: CGFloat + let horizontalPadding: CGFloat + let cornerRadius: CGFloat + let minWidth: CGFloat + let minHeight: CGFloat + + @State private var isHovered = false + + var body: some View { + configuration.label + .font(font) + .foregroundColor(foregroundColor) + .padding(.vertical, verticalPadding) + .padding(.horizontal, horizontalPadding) + .frame(minWidth: minWidth, minHeight: minHeight) + .background(resolvedBackgroundColor) + .cornerRadius(cornerRadius) + .onHover { hovering in +#if os(macOS) + isHovered = hovering +#endif + } + } + + private var resolvedBackgroundColor: Color { + if configuration.isPressed { + return pressedBackgroundColor + } +#if os(macOS) + if isHovered { + return pressedBackgroundColor + } +#endif + return backgroundColor + } + } + } + +} diff --git a/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/Shared/Styles/RebrandedOnboardingStyles+ListButton.swift b/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/Shared/Styles/RebrandedOnboardingStyles+ListButton.swift index 92c51593f48..d74fbb48bb5 100644 --- a/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/Shared/Styles/RebrandedOnboardingStyles+ListButton.swift +++ b/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/Shared/Styles/RebrandedOnboardingStyles+ListButton.swift @@ -55,12 +55,13 @@ public extension OnboardingRebranding.OnboardingStyles { var body: some View { configuration.label .font(typography.contextual.controlSmall) + .lineSpacing(20 - 15) .fixedSize(horizontal: false, vertical: true) .multilineTextAlignment(.leading) .lineLimit(nil) .foregroundColor(foregroundColor(isPressed: configuration.isPressed, isHovered: isHovered)) - .padding(.vertical, 12) - .padding(.horizontal) + .padding(.vertical, optionsListMetrics.verticalPadding) + .padding(.horizontal, optionsListMetrics.horizontalPadding) .frame(minWidth: 0, maxWidth: optionsListMetrics.itemMaxWidth, minHeight: optionsListMetrics.itemMinHeight) .background(backgroundColor(isPressed: configuration.isPressed, isHovered: isHovered)) .cornerRadius(optionsListMetrics.cornerRadius) @@ -78,11 +79,7 @@ public extension OnboardingRebranding.OnboardingStyles { } private func foregroundColor(isPressed: Bool, isHovered: Bool) -> Color { -#if os(iOS) return colorPalette.optionsListIconColor -#else - return Color(designSystemColor: .accentTextPrimary) -#endif } private func backgroundColor(isPressed: Bool, isHovered: Bool) -> Color { @@ -90,11 +87,11 @@ public extension OnboardingRebranding.OnboardingStyles { return isPressed ? colorPalette.backgroundAccent : .clear #else if isPressed { - return Color(designSystemColor: .controlsFillSecondary) + return colorPalette.optionsListPressedColor } if isHovered { - return Color(designSystemColor: .controlsFillPrimary) + return colorPalette.optionsListHoverColor } return .clear diff --git a/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/Shared/Theme/OnboardingTheme+Colors.swift b/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/Shared/Theme/OnboardingTheme+Colors.swift index 27d9f7b2724..47480c314c6 100644 --- a/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/Shared/Theme/OnboardingTheme+Colors.swift +++ b/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/Shared/Theme/OnboardingTheme+Colors.swift @@ -42,6 +42,10 @@ public extension OnboardingTheme { public let optionsListIconColor: Color /// Text color for contextual onboarding option list rows. public let optionsListTextColor: Color + /// Background color for contextual onboarding option list rows on hover. + public let optionsListHoverColor: Color + /// Background color for contextual onboarding option list rows when pressed. + public let optionsListPressedColor: Color /// Primary button background color. public let primaryButtonBackgroundColor: Color @@ -69,6 +73,8 @@ public extension OnboardingTheme { optionsListBorderColor: Color, optionsListIconColor: Color, optionsListTextColor: Color, + optionsListHoverColor: Color, + optionsListPressedColor: Color, primaryButtonBackgroundColor: Color, primaryButtonPressedColor: Color, primaryButtonTextColor: Color, @@ -86,6 +92,8 @@ public extension OnboardingTheme { self.optionsListBorderColor = optionsListBorderColor self.optionsListIconColor = optionsListIconColor self.optionsListTextColor = optionsListTextColor + self.optionsListHoverColor = optionsListHoverColor + self.optionsListPressedColor = optionsListPressedColor self.primaryButtonBackgroundColor = primaryButtonBackgroundColor self.primaryButtonPressedColor = primaryButtonPressedColor self.primaryButtonTextColor = primaryButtonTextColor @@ -120,6 +128,8 @@ public extension OnboardingTheme { optionsListBorderColor: optionsListBorderColor, optionsListIconColor: optionsListIconColor, optionsListTextColor: optionsListTextColor, + optionsListHoverColor: .clear, + optionsListPressedColor: .clear, primaryButtonBackgroundColor: primaryButtonBackgroundColor, primaryButtonPressedColor: primaryButtonBackgroundColor, primaryButtonTextColor: primaryButtonTextColor, diff --git a/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/Shared/Theme/OnboardingTheme+ContextualFlow.swift b/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/Shared/Theme/OnboardingTheme+ContextualFlow.swift index 048fbac7764..c525d477e66 100644 --- a/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/Shared/Theme/OnboardingTheme+ContextualFlow.swift +++ b/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/Shared/Theme/OnboardingTheme+ContextualFlow.swift @@ -112,6 +112,10 @@ public extension OnboardingTheme.ContextualOnboardingMetrics { public let interItemSpacing: CGFloat? /// Horizontal spacing between icon and text within a row. public let innerContentHorizontalSpacing: CGFloat? + /// Vertical padding inside each option list row. + public let verticalPadding: CGFloat + /// Horizontal padding inside each option list row. + public let horizontalPadding: CGFloat public init( cornerRadius: CGFloat, @@ -121,7 +125,9 @@ public extension OnboardingTheme.ContextualOnboardingMetrics { itemMinHeight: CGFloat, itemMaxWidth: CGFloat? = .infinity, interItemSpacing: CGFloat? = nil, - innerContentHorizontalSpacing: CGFloat? = nil + innerContentHorizontalSpacing: CGFloat? = nil, + verticalPadding: CGFloat = 12, + horizontalPadding: CGFloat = 16 ) { self.cornerRadius = cornerRadius self.borderWidth = borderWidth @@ -131,6 +137,8 @@ public extension OnboardingTheme.ContextualOnboardingMetrics { self.itemMaxWidth = itemMaxWidth self.interItemSpacing = interItemSpacing self.innerContentHorizontalSpacing = innerContentHorizontalSpacing + self.verticalPadding = verticalPadding + self.horizontalPadding = horizontalPadding } } diff --git a/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/macOS/Theme/OnboardingTheme-macOS.swift b/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/macOS/Theme/OnboardingTheme-macOS.swift index f23b901b4a7..7c00566d0a7 100644 --- a/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/macOS/Theme/OnboardingTheme-macOS.swift +++ b/SharedPackages/Onboarding/Sources/Onboarding/Rebranding/macOS/Theme/OnboardingTheme-macOS.swift @@ -27,21 +27,41 @@ public extension OnboardingTheme { let bubbleCornerRadius = 36.0 let borderWidth = 1.5 - let typography = Typography.system + let typography = Typography( + contextualTitle: .system(size: 20, weight: .bold), + contextualBody: .system(size: 16, weight: .regular), + contextualControlSmall: .system(size: 13, weight: .regular) + ) + + let accentPrimary = Color(0x2F95EE) + let bubbleBorder = Color(0xCBEAFF) + + let ctaButtonBackground = Color(0xF05F2B) + let ctaButtonPressed = Color(0xCC3B0A) + + let adaptiveWhite = Color(NSColor(name: nil, dynamicProvider: { appearance in + appearance.name == .darkAqua ? NSColor.windowBackgroundColor : .white + })) let colorPalette = ColorPalette( - background: Color(designSystemColor: .surfaceBackdrop), - bubbleBorder: Color(designSystemColor: .accentAltPrimary), - bubbleBackground: Color(designSystemColor: .surfaceTertiary), + background: adaptiveWhite, + bubbleBorder: bubbleBorder, + bubbleBackground: adaptiveWhite, bubbleShadow: Color.shade(0.03), textPrimary: Color(designSystemColor: .textPrimary), textSecondary: Color(designSystemColor: .textSecondary), - optionsListBorderColor: Color(designSystemColor: .accentPrimary), - optionsListIconColor: Color(designSystemColor: .accentPrimary), - optionsListTextColor: Color(designSystemColor: .textLink), - primaryButtonBackgroundColor: Color(designSystemColor: .buttonsPrimaryDefault), - primaryButtonTextColor: Color(designSystemColor: .buttonsPrimaryText), - backgroundAccent: Color(designSystemColor: .accentPrimary) + optionsListBorderColor: accentPrimary, + optionsListIconColor: accentPrimary, + optionsListTextColor: accentPrimary, + optionsListHoverColor: Color(red: 0x72/255.0, green: 0x95/255.0, blue: 0xF6/255.0).opacity(0.2), + optionsListPressedColor: Color(red: 0x72/255.0, green: 0x95/255.0, blue: 0xF6/255.0).opacity(0.2), + primaryButtonBackgroundColor: ctaButtonBackground, + primaryButtonPressedColor: ctaButtonPressed, + primaryButtonTextColor: .white, + secondaryButtonBackgroundColor: Color(designSystemColor: .buttonsPrimaryDefault), + secondaryButtonPressedColor: Color(designSystemColor: .buttonsPrimaryPressed), + secondaryButtonTextColor: Color(designSystemColor: .buttonsPrimaryText), + backgroundAccent: accentPrimary ) let dismissButtonMetrics = DismissButtonMetrics( @@ -51,18 +71,20 @@ public extension OnboardingTheme { ) let contextualOptionsListMetrics = ContextualOnboardingMetrics.OptionsListMetrics( - cornerRadius: 32, + cornerRadius: 999, borderWidth: 1, borderInset: 0.5, iconSize: CGSize(width: 16, height: 16), - itemMinHeight: 40 + itemMinHeight: 32, + verticalPadding: 6, + horizontalPadding: 12 ) return OnboardingTheme( - typography: .system, + typography: typography, colorPalette: colorPalette, bubbleMetrics: BubbleMetrics( - contentInsets: EdgeInsets(top: 32, leading: 20, bottom: 20, trailing: 20), + contentInsets: EdgeInsets(top: 24, leading: 32, bottom: 24, trailing: 32), cornerRadius: bubbleCornerRadius, borderWidth: borderWidth, shadowRadius: 6.0, @@ -76,9 +98,9 @@ public extension OnboardingTheme { dismissButtonMetrics: dismissButtonMetrics, contextualOnboardingMetrics: OnboardingTheme.ContextualOnboardingMetrics( containerPadding: EdgeInsets(top: 16, leading: 16, bottom: 58, trailing: 16), - contentSpacing: 20, - titleBodyVerticalSpacingVerticalLayout: 10, - titleBodyVerticalSpacingHorizontalLayout: 10, + contentSpacing: 12, + titleBodyVerticalSpacingVerticalLayout: 8, + titleBodyVerticalSpacingHorizontalLayout: 8, titleBodyInset: EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0), contextualTitleTextAlignment: .leading, contextualBodyTextAlignment: .leading, @@ -112,7 +134,14 @@ public extension OnboardingTheme { linearBodyTextAlignment: .center, primaryButtonStyle: OnboardingButtonStyle( id: .primary, - style: AnyButtonStyle(OnboardingPrimaryButtonStyle()) + style: AnyButtonStyle( + OnboardingRebranding.OnboardingStyles.CTAButtonStyle( + backgroundColor: ctaButtonBackground, + pressedBackgroundColor: ctaButtonPressed, + foregroundColor: .white, + font: typography.contextual.body + ) + ) ), dismissButtonStyle: OnboardingButtonStyle( id: .dismiss, diff --git a/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-dark.png b/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-dark.png index 8475354ddf2..962582e49b2 100644 Binary files a/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-dark.png and b/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-dark.png differ diff --git a/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-dark@2x.png b/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-dark@2x.png index 27d33d81572..b6b4d813b56 100644 Binary files a/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-dark@2x.png and b/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-dark@2x.png differ diff --git a/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-dark@3x.png b/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-dark@3x.png index cea271be460..95a049d20ff 100644 Binary files a/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-dark@3x.png and b/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-dark@3x.png differ diff --git a/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-light.png b/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-light.png index 1681731fc22..3d7c695775b 100644 Binary files a/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-light.png and b/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-light.png differ diff --git a/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-light@2x.png b/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-light@2x.png index d91d141ebbf..a61def6d2cb 100644 Binary files a/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-light@2x.png and b/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-light@2x.png differ diff --git a/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-light@3x.png b/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-light@3x.png index 24d8df5e036..c269c060490 100644 Binary files a/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-light@3x.png and b/SharedPackages/Onboarding/Sources/Onboarding/Resources/OnboardingAssets.xcassets/Rebranding/Contextual/contextual-bg-search-done.imageset/contextual-bg-search-done-light@3x.png differ diff --git a/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualDaxDialogsFactory.swift b/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualDaxDialogsFactory.swift index e61c802d5ce..293d401a86f 100644 --- a/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualDaxDialogsFactory.swift +++ b/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualDaxDialogsFactory.swift @@ -21,6 +21,20 @@ import SwiftUI import Onboarding struct RebrandedContextualDaxDialogsFactory: ContextualDaxDialogsFactory { + private enum ContextualPanelMetrics { + static let trySearchPanelHeight: CGFloat = 200 + static let trySearchIllustrationOffsetY: CGFloat = 96 + static let searchDonePanelHeight: CGFloat = 140 + static let searchDoneIllustrationOffsetY: CGFloat = -40 + static let trySitePanelHeight: CGFloat = 240 + static let trySiteIllustrationOffsetY: CGFloat = 40 + static let trackersPanelHeight: CGFloat = 170 + static let trackersIllustrationOffsetY: CGFloat = 0 + static let firePanelHeight: CGFloat = 170 + static let highFivePanelHeight: CGFloat = 170 + static let highFiveIllustrationOffsetY: CGFloat = 0 + } + private let onboardingPixelReporter: OnboardingPixelReporting private let fireCoordinator: FireCoordinator @@ -47,17 +61,98 @@ struct RebrandedContextualDaxDialogsFactory: ContextualDaxDialogsFactory { onboardingPixelReporter.measureLastDialogShown() } - let adjustedView = HStack { + let centeredView = HStack { Spacer() dialogView .frame(maxWidth: 640.0) Spacer() } - .padding() + .padding(.top, 16) + .padding(.bottom, 24) - let viewWithBackground = adjustedView - .background(OnboardingGradient()) - .applyOnboardingTheme(.macOSRebranding2026) + let viewWithBackground: AnyView + switch type { + case .tryASearch: + viewWithBackground = AnyView( + ZStack(alignment: .topLeading) { + ZStack(alignment: .bottomTrailing) { + OnboardingTheme.macOSRebranding2026.colorPalette.background + OnboardingRebrandingImages.Contextual.tryASearchBackground + .offset(y: ContextualPanelMetrics.trySearchIllustrationOffsetY) + } + .frame(height: ContextualPanelMetrics.trySearchPanelHeight) + centeredView + } + .frame(height: ContextualPanelMetrics.trySearchPanelHeight) + .clipped() + .applyOnboardingTheme(.macOSRebranding2026) + ) + case .searchDone: + viewWithBackground = AnyView( + ZStack(alignment: .topLeading) { + ZStack(alignment: .bottomTrailing) { + OnboardingTheme.macOSRebranding2026.colorPalette.background + OnboardingRebrandingImages.Contextual.searchDoneBackground + .offset(y: ContextualPanelMetrics.searchDoneIllustrationOffsetY) + } + centeredView + } + .clipped() + .applyOnboardingTheme(.macOSRebranding2026) + ) + case .tryASite: + viewWithBackground = AnyView( + ZStack(alignment: .topLeading) { + ZStack(alignment: .bottomTrailing) { + OnboardingTheme.macOSRebranding2026.colorPalette.background + OnboardingRebrandingImages.Contextual.tryASiteBackground + .offset(y: ContextualPanelMetrics.trySiteIllustrationOffsetY) + } + .frame(height: ContextualPanelMetrics.trySitePanelHeight) + centeredView + } + .frame(height: ContextualPanelMetrics.trySitePanelHeight) + .clipped() + .applyOnboardingTheme(.macOSRebranding2026) + ) + case .trackers: + viewWithBackground = AnyView( + ZStack(alignment: .topLeading) { + ZStack(alignment: .bottomTrailing) { + OnboardingTheme.macOSRebranding2026.colorPalette.background + OnboardingRebrandingImages.Contextual.trackerBlockedBackground + .offset(y: ContextualPanelMetrics.trackersIllustrationOffsetY) + } + centeredView + } + .clipped() + .applyOnboardingTheme(.macOSRebranding2026) + ) + case .tryFireButton: + viewWithBackground = AnyView( + ZStack(alignment: .topLeading) { + OnboardingGradient() + centeredView + } + .clipped() + .applyOnboardingTheme(.macOSRebranding2026) + ) + case .highFive: + viewWithBackground = AnyView( + ZStack(alignment: .topLeading) { + ZStack(alignment: .bottomTrailing) { + OnboardingTheme.macOSRebranding2026.colorPalette.background + OnboardingRebrandingImages.Contextual.endOfJourneyBackground + .offset(y: ContextualPanelMetrics.highFiveIllustrationOffsetY) + } + .frame(height: ContextualPanelMetrics.highFivePanelHeight) + centeredView + } + .frame(height: ContextualPanelMetrics.highFivePanelHeight) + .clipped() + .applyOnboardingTheme(.macOSRebranding2026) + ) + } #if DEBUG return AnyView( @@ -90,7 +185,14 @@ struct RebrandedContextualDaxDialogsFactory: ContextualDaxDialogsFactory { let suggestedSitesProvider = OnboardingSuggestedSitesProvider(surpriseItemTitle: OnboardingSuggestedSitesProvider.surpriseItemTitle) let viewModel = OnboardingSiteSuggestionsViewModel(title: "", suggestedSitesProvider: suggestedSitesProvider, delegate: delegate) let gotIt = shouldFollowUp ? onGotItPressed : onDismiss - return OnboardingRebranding.OnboardingSearchDoneDialog(shouldFollowUp: shouldFollowUp, viewModel: viewModel, gotItAction: gotIt, onManualDismiss: onDismiss) + return OnboardingRebranding.OnboardingSearchDoneDialog( + shouldFollowUp: shouldFollowUp, + initialPanelHeight: ContextualPanelMetrics.searchDonePanelHeight, + followUpPanelHeight: ContextualPanelMetrics.trySitePanelHeight, + viewModel: viewModel, + gotItAction: gotIt, + onManualDismiss: onDismiss + ) } private func tryASiteDialog(delegate: OnboardingNavigationDelegate, onDismiss: @escaping () -> Void) -> some View { @@ -102,12 +204,24 @@ struct RebrandedContextualDaxDialogsFactory: ContextualDaxDialogsFactory { private func trackersDialog(message: NSAttributedString, shouldFollowUp: Bool, onDismiss: @escaping () -> Void, onGotItPressed: @escaping () -> Void, onFireButtonPressed: @escaping () -> Void) -> some View { let gotIt = shouldFollowUp ? onGotItPressed : onDismiss let viewModel = OnboardingFireButtonDialogViewModel(onboardingPixelReporter: onboardingPixelReporter, fireCoordinator: fireCoordinator, onDismiss: onDismiss, onGotItPressed: onGotItPressed, onFireButtonPressed: onFireButtonPressed) - return OnboardingRebranding.OnboardingTrackersBlockedDialog(shouldFollowUp: true, message: message, blockedTrackersCTAAction: gotIt, viewModel: viewModel, onManualDismiss: onDismiss) + return OnboardingRebranding.OnboardingTrackersBlockedDialog( + shouldFollowUp: shouldFollowUp, + initialPanelHeight: ContextualPanelMetrics.trackersPanelHeight, + followUpPanelHeight: ContextualPanelMetrics.firePanelHeight, + message: message, + blockedTrackersCTAAction: gotIt, + viewModel: viewModel, + onManualDismiss: onDismiss + ) } private func tryFireButtonDialog(onDismiss: @escaping () -> Void, onGotItPressed: @escaping () -> Void, onFireButtonPressed: @escaping () -> Void) -> some View { let viewModel = OnboardingFireButtonDialogViewModel(onboardingPixelReporter: onboardingPixelReporter, fireCoordinator: fireCoordinator, onDismiss: onDismiss, onGotItPressed: onGotItPressed, onFireButtonPressed: onFireButtonPressed) - return OnboardingRebranding.OnboardingFireDialog(viewModel: viewModel, onManualDismiss: onDismiss) + return OnboardingRebranding.OnboardingFireDialog( + viewModel: viewModel, + panelHeight: ContextualPanelMetrics.firePanelHeight, + onManualDismiss: onDismiss + ) } private func highFiveDialog(onDismiss: @escaping () -> Void, onGotItPressed: @escaping () -> Void) -> some View { diff --git a/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+EndOfJourney.swift b/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+EndOfJourney.swift index b12e8b4e7f0..38218457ec9 100644 --- a/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+EndOfJourney.swift +++ b/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+EndOfJourney.swift @@ -24,35 +24,38 @@ import Onboarding extension OnboardingRebranding { struct OnboardingEndOfJourneyDialog: View { - let title = UserText.ContextualOnboarding.onboardingFinalScreenTitle - let message = NSAttributedString(string: UserText.ContextualOnboarding.onboardingFinalScreenMessage) - let cta = UserText.ContextualOnboarding.onboardingFinalScreenButton - let highFiveAction: () -> Void let onManualDismiss: () -> Void var body: some View { - DaxDialogView(logoPosition: .left, onManualDismiss: onManualDismiss) { + OnboardingBubbleView.withDismissButton( + tailPosition: .leading(offset: 0.3, direction: .top), + onDismiss: onManualDismiss + ) { OnboardingEndOfJourneyDialogContent(highFiveAction: highFiveAction) } } } struct OnboardingEndOfJourneyDialogContent: View { - let title = UserText.ContextualOnboarding.onboardingFinalScreenTitle + @Environment(\.onboardingTheme) private var theme + + let title = NSAttributedString(string: UserText.ContextualOnboarding.onboardingFinalScreenTitle) let message = NSAttributedString(string: UserText.ContextualOnboarding.onboardingFinalScreenMessage) let cta = UserText.ContextualOnboarding.onboardingFinalScreenButton let highFiveAction: () -> Void var body: some View { - Onboarding.ContextualDaxDialogContent( + OnboardingRebranding.ContextualDaxDialogContent( orientation: .horizontalStack(alignment: .center), title: title, - titleFont: OnboardingDialogsContants.titleFont, - message: message, - messageFont: OnboardingDialogsContants.messageFont, - customActionView: AnyView(OnboardingPrimaryCTAButton(title: cta, action: highFiveAction)) - ) + message: message + ) { + Button(cta) { + highFiveAction() + } + .buttonStyle(theme.primaryButtonStyle.style) + } } } diff --git a/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+Fire.swift b/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+Fire.swift index cab2bc08173..8781e821b01 100644 --- a/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+Fire.swift +++ b/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+Fire.swift @@ -25,22 +25,23 @@ extension OnboardingRebranding { struct OnboardingFireDialog: View { let viewModel: OnboardingFireButtonDialogViewModel - @State private var showNextScreen: Bool = false + let panelHeight: CGFloat let onManualDismiss: () -> Void var body: some View { - DaxDialogView(logoPosition: .left, onManualDismiss: onManualDismiss) { - if showNextScreen { - OnboardingEndOfJourneyDialogContent(highFiveAction: viewModel.highFive) - } else { - OnboardingFireDialogContent(viewModel: viewModel) - } + OnboardingBubbleView.withDismissButton( + tailPosition: .leading(offset: 0.3, direction: .top), + onDismiss: onManualDismiss + ) { + OnboardingFireDialogContent(viewModel: viewModel) } - .padding() + .frame(height: panelHeight, alignment: .top) } } struct OnboardingFireDialogContent: View { + @Environment(\.onboardingTheme) private var theme + static let firstString = String(format: UserText.ContextualOnboarding.onboardingTryFireButtonTitle, UserText.ContextualOnboarding.onboardingTryFireButtonMessage) private let attributedMessage = NSMutableAttributedString.attributedString( from: Self.firstString, @@ -51,24 +52,16 @@ extension OnboardingRebranding { ) let viewModel: OnboardingFireButtonDialogViewModel - @State private var showNextScreen: Bool = false var body: some View { - if showNextScreen { - OnboardingEndOfJourneyDialogContent(highFiveAction: viewModel.highFive) - } else { - Onboarding.ContextualDaxDialogContent( - orientation: .horizontalStack(alignment: .center), - message: attributedMessage, - messageFont: OnboardingDialogsContants.titleFontNotBold, - customActionView: AnyView(actionView)) - } - } - - @ViewBuilder - private var actionView: some View { - VStack { - OnboardingPrimaryCTAButton(title: UserText.ContextualOnboarding.onboardingTryFireButtonButton, action: viewModel.tryFireButton) + OnboardingRebranding.ContextualDaxDialogContent( + orientation: .horizontalStack(alignment: .center), + message: attributedMessage + ) { + Button(UserText.ContextualOnboarding.onboardingTryFireButtonButton) { + viewModel.tryFireButton() + } + .buttonStyle(theme.primaryButtonStyle.style) } } } diff --git a/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+SearchCompleted.swift b/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+SearchCompleted.swift index a13528404ef..b1174d422a6 100644 --- a/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+SearchCompleted.swift +++ b/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+SearchCompleted.swift @@ -24,44 +24,53 @@ import Onboarding extension OnboardingRebranding { struct OnboardingSearchDoneDialog: View { - let title = UserText.ContextualOnboarding.onboardingFirstSearchDoneTitle + @Environment(\.onboardingTheme) private var theme + + let title = NSAttributedString(string: UserText.ContextualOnboarding.onboardingFirstSearchDoneTitle) let message = NSAttributedString(string: UserText.ContextualOnboarding.onboardingFirstSearchDoneMessage) let cta = UserText.ContextualOnboarding.onboardingGotItButton @State private var showNextScreen: Bool = false let shouldFollowUp: Bool + let initialPanelHeight: CGFloat + let followUpPanelHeight: CGFloat let viewModel: OnboardingSiteSuggestionsViewModel let gotItAction: () -> Void let onManualDismiss: () -> Void + private var panelHeight: CGFloat { + showNextScreen ? followUpPanelHeight : initialPanelHeight + } + var body: some View { - DaxDialogView(logoPosition: .left, onManualDismiss: onManualDismiss) { - VStack { - if showNextScreen { - OnboardingTrySiteDialogContent(viewModel: viewModel) - } else { - Onboarding.ContextualDaxDialogContent( - orientation: .horizontalStack(alignment: .center), - title: title, - titleFont: OnboardingDialogsContants.titleFont, - message: message, - messageFont: OnboardingDialogsContants.messageFont, - customActionView: AnyView( - OnboardingPrimaryCTAButton(title: cta) { - gotItAction() - withAnimation { - if shouldFollowUp { - showNextScreen = true - } - } + OnboardingBubbleView.withDismissButton( + tailPosition: .leading(offset: 0.3, direction: .top), + onDismiss: onManualDismiss + ) { + if showNextScreen { + OnboardingTrySiteDialogContent(viewModel: viewModel) + .transition(.identity) + } else { + OnboardingRebranding.ContextualDaxDialogContent( + orientation: .horizontalStack(alignment: .center), + title: title, + message: message + ) { + Button(cta) { + gotItAction() + if shouldFollowUp { + withAnimation(.easeInOut(duration: 0.3)) { + showNextScreen = true } - ) - ) + } + } + .buttonStyle(theme.primaryButtonStyle.style) } + .transition(.identity) } } - .padding() + .frame(height: panelHeight, alignment: .top) } } diff --git a/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+Trackers.swift b/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+Trackers.swift index 7262f637a28..6186052eade 100644 --- a/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+Trackers.swift +++ b/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+Trackers.swift @@ -24,41 +24,51 @@ import Onboarding extension OnboardingRebranding { struct OnboardingTrackersBlockedDialog: View { + @Environment(\.onboardingTheme) private var theme + let cta = UserText.ContextualOnboarding.onboardingGotItButton @State private var showNextScreen: Bool = false let shouldFollowUp: Bool + let initialPanelHeight: CGFloat + let followUpPanelHeight: CGFloat let message: NSAttributedString let blockedTrackersCTAAction: () -> Void let viewModel: OnboardingFireButtonDialogViewModel let onManualDismiss: () -> Void + private var panelHeight: CGFloat { + showNextScreen ? followUpPanelHeight : initialPanelHeight + } + var body: some View { - DaxDialogView(logoPosition: .left, onManualDismiss: onManualDismiss) { - VStack { - if showNextScreen { - OnboardingFireDialogContent(viewModel: viewModel) - } else { - Onboarding.ContextualDaxDialogContent( - orientation: .horizontalStack(alignment: .center), - message: message, - messageFont: OnboardingDialogsContants.messageFont, - customActionView: AnyView( - OnboardingPrimaryCTAButton(title: cta) { - blockedTrackersCTAAction() - if shouldFollowUp { - withAnimation { - showNextScreen = true - } - } + OnboardingBubbleView.withDismissButton( + tailPosition: .leading(offset: 0.3, direction: .top), + onDismiss: onManualDismiss + ) { + if showNextScreen { + OnboardingFireDialogContent(viewModel: viewModel) + .transition(.identity) + } else { + OnboardingRebranding.ContextualDaxDialogContent( + orientation: .horizontalStack(alignment: .center), + message: message + ) { + Button(cta) { + blockedTrackersCTAAction() + if shouldFollowUp { + withAnimation(.easeInOut(duration: 0.3)) { + showNextScreen = true } - ) - ) + } + } + .buttonStyle(theme.primaryButtonStyle.style) } + .transition(.identity) } } - .padding() + .frame(height: panelHeight, alignment: .top) } } diff --git a/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+TrySearch.swift b/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+TrySearch.swift index 4a2fd8eacef..2db75cea769 100644 --- a/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+TrySearch.swift +++ b/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+TrySearch.swift @@ -24,24 +24,27 @@ import Onboarding extension OnboardingRebranding { struct OnboardingTrySearchDialog: View { - let title = UserText.ContextualOnboarding.onboardingTryASearchTitle + let title = NSAttributedString(string: UserText.ContextualOnboarding.onboardingTryASearchTitle) let message = NSAttributedString(string: UserText.ContextualOnboarding.onboardingTryASearchMessage) let viewModel: OnboardingSearchSuggestionsViewModel let onManualDismiss: () -> Void var body: some View { - DaxDialogView(logoPosition: .left, onManualDismiss: onManualDismiss) { - Onboarding.ContextualDaxDialogContent( + OnboardingBubbleView.withDismissButton( + tailPosition: .leading(offset: 0.3, direction: .top), + onDismiss: onManualDismiss + ) { + OnboardingRebranding.ContextualDaxDialogContent( orientation: .horizontalStack(alignment: .top), title: title, - titleFont: OnboardingDialogsContants.titleFont, - message: message, - messageFont: OnboardingDialogsContants.messageFont, - list: viewModel.itemsList, - listAction: viewModel.listItemPressed - ) + message: message + ) { + OnboardingRebranding.ContextualOnboardingListView( + list: viewModel.itemsList, + action: viewModel.listItemPressed + ) + } } - .padding() } } diff --git a/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+TrySite.swift b/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+TrySite.swift index 7e75580b32d..8549422ffe7 100644 --- a/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+TrySite.swift +++ b/macOS/DuckDuckGo/Onboarding/ContextualOnboarding/Rebranding/RebrandedContextualOnboardingDialogs+TrySite.swift @@ -28,27 +28,31 @@ extension OnboardingRebranding { let onManualDismiss: () -> Void var body: some View { - DaxDialogView(logoPosition: .left, onManualDismiss: onManualDismiss) { + OnboardingBubbleView.withDismissButton( + tailPosition: .leading(offset: 0.3, direction: .top), + onDismiss: onManualDismiss + ) { OnboardingTrySiteDialogContent(viewModel: viewModel) } } } struct OnboardingTrySiteDialogContent: View { - let title = UserText.ContextualOnboarding.onboardingTryASiteTitle + let title = NSAttributedString(string: UserText.ContextualOnboarding.onboardingTryASiteTitle) let message = NSAttributedString(string: UserText.ContextualOnboarding.onboardingTryASiteMessage) let viewModel: OnboardingSiteSuggestionsViewModel var body: some View { - Onboarding.ContextualDaxDialogContent( + OnboardingRebranding.ContextualDaxDialogContent( orientation: .horizontalStack(alignment: .top), title: title, - titleFont: OnboardingDialogsContants.titleFont, - message: message, - messageFont: OnboardingDialogsContants.messageFont, - list: viewModel.itemsList, - listAction: viewModel.listItemPressed - ) + message: message + ) { + OnboardingRebranding.ContextualOnboardingListView( + list: viewModel.itemsList, + action: viewModel.listItemPressed + ) + } } }