Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@matt-livefront
Copy link
Collaborator

@matt-livefront matt-livefront commented Nov 3, 2025

🎟️ Tracking

PM-26063

📔 Objective

Consolidates several view extensions to BitwardenKit:

  • navigationBar(title:titleDisplayMode)
  • Toolbar helpers in View+Toolbar
  • navStackWrapped

⏰ Reminders before review

  • Contributor guidelines followed
  • All formatters and local linters executed and passed
  • Written new unit and / or integration tests where applicable
  • Protected functional changes with optionality (feature flags)
  • Used internationalization (i18n) for all UI strings
  • CI builds passed
  • Communicated to DevOps any deployment requirements
  • Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team

🦮 Reviewer guidelines

  • 👍 (:+1:) or similar for great changes
  • 📝 (:memo:) or ℹ️ (:information_source:) for notes or general info
  • ❓ (:question:) for questions
  • 🤔 (:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion
  • 🎨 (:art:) for suggestions / improvements
  • ❌ (:x:) or ⚠️ (:warning:) for more significant problems or concerns needing attention
  • 🌱 (:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt
  • ⛏ (:pick:) for minor or nitpick changes

@matt-livefront matt-livefront requested a review from a team as a code owner November 3, 2025 15:59
@claude
Copy link

claude bot commented Nov 3, 2025

Claude finished @matt-livefront's task —— View job


Code Review: View Extensions Consolidation to BitwardenKit

  • Analyze PR changes and file modifications
  • Review architecture compliance
  • Check code style and documentation
  • Verify security considerations
  • Provide comprehensive feedback

Summary of Changes

This PR consolidates several view extensions from AuthenticatorShared and BitwardenShared into BitwardenKit:

  1. NavigationBarViewModifier - Moved to BitwardenKit with public extension
  2. View+Toolbar - Moved and enhanced with iOS 26 adaptations
  3. navStackWrapped - Moved to BitwardenKit as a public computed property

Net Effect: -229 / +65 lines (good consolidation reducing duplication)


Critical Issues

1. ⚠️ Breaking Behavior Change in cancelToolbarButton

Location: BitwardenKit/UI/Platform/Application/Extensions/View+Toolbar.swift:29-39

The new implementation changes behavior significantly:

Before (AuthenticatorShared):

func cancelToolbarButton(action: @escaping () -> Void) -> some View {
    toolbarButton(asset: SharedAsset.Icons.close16, label: Localizations.cancel, action: action)
        .accessibilityIdentifier("CancelButton")
}

After (BitwardenKit):

func cancelToolbarButton(hidden: Bool = false, action: @escaping () -> Void) -> some View {
    if #available(iOS 26, *) {
        return Button(role: .cancel, action: action)  // System-styled button
            .hidden(hidden)
            .accessibilityIdentifier("CancelButton")
            .accessibilityLabel(Localizations.cancel)
    }
    return toolbarButton(Localizations.cancel, action: action)  // Text button instead of icon
        .hidden(hidden)
        .accessibilityIdentifier("CancelButton")
}

Problems:

  • Visual inconsistency: The original used an icon (SharedAsset.Icons.close16), but the new version uses text label on iOS <26
  • iOS 26 behavior: System roles may render differently than custom styled buttons, potentially breaking UI consistency
  • Authenticator impact: Since AuthenticatorShared code was deleted, any views using this button will see visual changes

Usage sites affected (found 7+ usages):

  • GeneratorView.swift:48
  • AddEditSendItemView.swift:51
  • SetMasterPasswordView.swift:98
  • TwoFactorAuthView.swift:51
  • VaultUnlockView.swift:42
  • And others...

Recommendation: Either:

  1. Keep the original icon-based implementation for consistency, OR
  2. Document this as an intentional visual change in the PR description, OR
  3. Add a migration period where both styles are available

2. ⚠️ Similar Issue with closeToolbarButton

Location: BitwardenKit/UI/Platform/Application/Extensions/View+Toolbar.swift:46-54

Same problem as above - changed from icon-based to system role button on iOS 26.

Usage sites affected (found 5+ usages):

  • PasswordHistoryListView.swift:34
  • ProfileSwitcherSheet.swift:25
  • ImportLoginsSuccessView.swift:57
  • ViewItemView.swift:65
  • And others...

3. ❌ Missing Public Initializer Documentation

Location: BitwardenKit/UI/Platform/Application/Appearance/Modifiers/NavigationBarViewModifier.swift:16-27

The NavigationBarViewModifier struct is now public but the initializer lacks a DocC comment:

public init(title: String, navigationBarTitleDisplayMode: NavigationBarItem.TitleDisplayMode) {
    self.title = title
    self.navigationBarTitleDisplayMode = navigationBarTitleDisplayMode
}

Per CLAUDE.md: "Everything in the code requires DocC documentation"

Recommendation: Add DocC comment to the public initializer.


Suggested Improvements

4. 🎨 Inconsistent Access Control on toolbarButton(asset:label:action:)

Location: BitwardenKit/UI/Platform/Application/Extensions/View+Toolbar.swift:131

This helper function is used by addToolbarButton but doesn't have explicit access control:

func toolbarButton(asset: SharedImageAsset, label: String, action: @escaping () -> Void) -> some View {

Recommendation: Since this is in a public extension, clarify whether this should be public or keep it internal. The pattern elsewhere in the file shows other toolbarButton variants are public, so this should likely be too.


5. 🎨 Missing Tests for Moved Code

Search Results: No test files found for:

  • NavigationBarViewModifierTests.swift
  • View+ToolbarTests.swift

While the functionality is likely covered by snapshot tests (48+ files reference these extensions), there are no unit tests specifically for these extensions after the move.

Recommendation: Consider adding unit tests for the toolbar button helpers, especially given the new iOS 26 behavior branches.


6. 📝 Type Alias Inconsistency

Location: BitwardenKit/UI/Platform/Application/Extensions/View+Toolbar.swift:131

Changed from ImageAsset to SharedImageAsset - this is correct, but worth documenting:

Before (BitwardenShared):

func toolbarButton(asset: ImageAsset, label: String, action: @escaping () -> Void)

After (BitwardenKit):

func toolbarButton(asset: SharedImageAsset, label: String, action: @escaping () -> Void)

This change is correct since BitwardenKit uses BitwardenResources.SharedImageAsset, but it's a subtle API change.


7. 🎨 navStackWrapped Duplication Removed Well

The removal of duplicate navStackWrapped implementations from:

  • AuthenticatorShared/UI/Platform/Application/Extensions/View.swift
  • BitwardenShared/UI/Vault/VaultItemCoordinator.swift (weird location!)

And consolidation to BitwardenKit/UI/Platform/Application/Extensions/View.swift is excellent cleanup. The VaultItemCoordinator location was particularly odd.


Good Practices Observed

✅ Proper use of public access control for BitwardenKit APIs
✅ Consistent DocC documentation on most public APIs
✅ Good consolidation reducing code duplication (229 deletions!)
✅ Maintained backward compatibility for existing call sites
✅ iOS 26 forward-compatibility considerations


Action Items for Author

  1. CRITICAL: Review and address the cancelToolbarButton and closeToolbarButton behavior changes:

    • Verify the visual change from icon to text label is intentional
    • Test on iOS 26 to ensure system button roles look acceptable
    • Consider whether AuthenticatorShared views need migration
  2. REQUIRED: Add DocC comment to NavigationBarViewModifier.init (line 24)

  3. RECOMMENDED: Clarify access control on toolbarButton(asset:label:action:) (line 131)

  4. OPTIONAL: Add unit tests for the new iOS 26 conditional logic in toolbar buttons

  5. VERIFICATION: Build and run both Bitwarden Password Manager and Authenticator apps to verify no visual regressions


Architecture Compliance

✅ Follows target structure (BitwardenKit for shared components)
✅ Proper dependency injection not applicable (view extensions)
⚠️ Documentation requirement partially met (missing init DocC)
✅ Consistent with existing patterns


@github-actions
Copy link
Contributor

github-actions bot commented Nov 3, 2025

Logo
Checkmarx One – Scan Summary & Details00c03a1d-767d-4579-976a-0215cfae24a0

Great job! No new security vulnerabilities introduced in this pull request

@codecov
Copy link

codecov bot commented Nov 3, 2025

Codecov Report

❌ Patch coverage is 68.00000% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.94%. Comparing base (ea01caa) to head (243b511).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...nKit/UI/Platform/Application/Extensions/View.swift 0.00% 8 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2094      +/-   ##
==========================================
- Coverage   85.29%   82.94%   -2.35%     
==========================================
  Files        1695     1973     +278     
  Lines      144592   160775   +16183     
==========================================
+ Hits       123323   133358   +10035     
- Misses      21269    27417    +6148     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@matt-livefront matt-livefront merged commit 7a9aa82 into main Nov 3, 2025
16 checks passed
@matt-livefront matt-livefront deleted the matt/PM-26063-view-extensions branch November 3, 2025 17:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants