chromium/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_new_tab_button.swift

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import UIKit
import ios_chrome_browser_ui_tab_switcher_tab_strip_ui_swift_constants

/// UIView that contains an `UIButton` that opens a new tab.
class TabStripNewTabButton: UIView {
  private let button: UIButton = UIButton(type: .custom)

  /// Delegate that informs the receiver of actions on the new tab button.
  public var delegate: TabStripNewTabButtonDelegate?

  /// View used for by the `layoutGuideCenter`.
  public var layoutGuideView: UIView { return button }

  /// `IPHHighlighted` state of the button.
  public var IPHHighlighted: Bool = false {
    didSet {
      button.configuration?.baseForegroundColor =
        IPHHighlighted ? UIColor.init(named: kSolidWhiteColor) : UIColor(named: kTextSecondaryColor)
      button.backgroundColor =
        IPHHighlighted
        ? UIColor(named: kBlueColor) : UIColor(named: kGroupedSecondaryBackgroundColor)
    }
  }

  /// `true` if the user is in incognito.
  public var isIncognito: Bool {
    didSet {
      self.updateAccessibilityIdentifier()
    }
  }

  override init(frame: CGRect) {
    isIncognito = false

    super.init(frame: frame)
    translatesAutoresizingMaskIntoConstraints = false

    configureButton()
    addSubview(button)
    button.accessibilityIdentifier = TabStripConstants.NewTabButton.accessibilityIdentifier

    if TabStripFeaturesUtils.isTabStripV2 {
      NSLayoutConstraint.activate([
        button.leadingAnchor.constraint(
          equalTo: self.leadingAnchor, constant: TabStripConstants.NewTabButton.leadingInset),
        button.topAnchor.constraint(
          equalTo: self.topAnchor, constant: TabStripConstants.NewTabButton.topInset),
        button.widthAnchor.constraint(equalToConstant: TabStripConstants.NewTabButton.diameter),
        button.heightAnchor.constraint(equalTo: button.widthAnchor),
      ])
    } else {
      NSLayoutConstraint.activate([
        button.leadingAnchor.constraint(
          equalTo: self.leadingAnchor, constant: TabStripConstants.NewTabButton.leadingInset),
        button.trailingAnchor.constraint(
          equalTo: self.trailingAnchor, constant: -TabStripConstants.NewTabButton.trailingInset),
        button.topAnchor.constraint(
          equalTo: self.topAnchor, constant: TabStripConstants.NewTabButton.topInset),
        button.bottomAnchor.constraint(
          equalTo: self.bottomAnchor, constant: -TabStripConstants.NewTabButton.bottomInset),
      ])
    }
  }

  required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }

  // MARK: - Private

  /// Called when the `button` has been tapped.
  @objc func buttonTapped() {
    delegate?.newTabButtonTapped()
  }

  /// Configures the `UIButton`.
  private func configureButton() {
    let symbolSize =
      TabStripFeaturesUtils.isTabStripV2
      ? TabStripConstants.NewTabButton.symbolBiggerPointSize
      : TabStripConstants.NewTabButton.symbolPointSize
    let closeSymbol = DefaultSymbolWithPointSize(
      kPlusSymbol, symbolSize)

    var configuration = UIButton.Configuration.borderless()
    configuration.contentInsets = .zero

    configuration.image = closeSymbol
    configuration.baseForegroundColor = TabStripHelper.newTabButtonSymbolColor
    button.configuration = configuration
    button.imageView?.contentMode = .center
    if TabStripFeaturesUtils.isTabStripV2 {
      button.layer.cornerRadius = TabStripConstants.NewTabButton.diameter / 2.0
    } else {
      button.layer.cornerRadius = TabStripConstants.NewTabButton.legacyCornerRadius
    }
    if !TabStripFeaturesUtils.isTabStripNTBNoBackgroundEnabled
      && !TabStripFeaturesUtils.isTabStripBlackBackgroundEnabled
    {
      button.backgroundColor = UIColor(named: kGroupedSecondaryBackgroundColor)
    }

    button.translatesAutoresizingMaskIntoConstraints = false
    button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
    button.isPointerInteractionEnabled = true
    if #available(iOS 17.0, *) {
      button.hoverStyle = .init(effect: .lift, shape: .circle)
    }
  }

  /// Updates the `accessibilityLabel` according to the current state of
  /// `isIncognito`.
  private func updateAccessibilityIdentifier() {
    button.accessibilityLabel = L10nUtils.stringWithFixup(
      messageId: isIncognito
        ? IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_TAB
        : IDS_IOS_TOOLS_MENU_NEW_TAB)
  }
}