Skip to content

Commit

Permalink
Merge pull request #867 from adevinta/component/checkbox_bug_864
Browse files Browse the repository at this point in the history
[CheckboxGroup#864] Fix disable checkbox group issue
  • Loading branch information
aycil-alican authored Apr 16, 2024
2 parents 92cc503 + ea3213e commit f229f23
Show file tree
Hide file tree
Showing 10 changed files with 280 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ public struct CheckboxGroupView: View {
isEnabled: item.isEnabled.wrappedValue,
selectionState: item.selectionState
)
.disabled(!item.isEnabled.wrappedValue)
.accessibilityIdentifier(CheckboxAccessibilityIdentifier.checkboxGroupItem(item.id.wrappedValue))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,20 @@ public final class CheckboxGroupUIView: UIControl {
self.itemsStackView.arrangedSubviews.compactMap { $0 as? CheckboxUIView }
}

/// A Boolean value indicating whether the component is in the enabled state.
public override var isEnabled: Bool {
didSet{
guard isEnabled != oldValue else { return }
if isEnabled {
self.checkboxes.enumerated().forEach { index, item in
item.isEnabled = self.items.indices.contains(index) ? self.items[index].isEnabled : true
}
} else {
self.checkboxes.forEach { $0.isEnabled = false }
}
}
}

// MARK: - Initialization

/// Not implemented. Please use another init.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import SwiftUI
private enum Constants {
static let pressedLineWidth: CGFloat = 4
static let lineWidth: CGFloat = 2
static let size: CGFloat = 20
static let filledSize: CGFloat = 10
static let size: CGFloat = 24
static let filledSize: CGFloat = 12
}
/// RadioButtonView is a single radio button control.
/// Radio buttons are used for selecting a single value from a selection of values.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ import UIKit

// MARK: - Constants
private enum Constants {
static let toggleViewHeight: CGFloat = 28
static let toggleViewSpacing: CGFloat = 4
static let textLabelTopSpacing: CGFloat = 3
static let toggleViewHeight: CGFloat = 32
static let textLabelTopSpacing: CGFloat = 5
static let haloWidth: CGFloat = 4
}

Expand Down
4 changes: 2 additions & 2 deletions core/Sources/Components/Slider/Constant/SliderConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import Foundation

enum SliderConstants {
static let handleSize = CGSize(width: 24, height: 24)
static let activeIndicatorSize = CGSize(width: 32, height: 32)
static let handleSize = CGSize(width: 32, height: 32)
static let activeIndicatorSize = CGSize(width: 40, height: 40)
static let barHeight: CGFloat = 4.0
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ final class CheckboxGroupComponentUIView: ComponentUIView {
self.componentView.title = showGroupTitle ? viewModel.title : ""
}

self.viewModel.$isEnabled.subscribe(in: &self.cancellables) { [weak self] isEnabled in
guard let self = self else { return }
self.componentView.isEnabled = isEnabled
}

self.viewModel.$groupType.subscribe(in: &self.cancellables) { [weak self] type in
guard let self = self else { return }
self.viewModel.groupTypeConfigurationItemViewModel.buttonTitle = type.name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ final class CheckboxGroupComponentUIViewModel: ComponentUIViewModel {
)
}()

lazy var isEnableConfigurationItemViewModel: ComponentsConfigurationItemUIViewModel = {
return .init(
name: "Is Enable",
type: .toggle(isOn: self.isEnabled),
target: (source: self, action: #selector(self.toggleIsEnable))
)
}()

lazy var iconConfigurationItemViewModel: ComponentsConfigurationItemUIViewModel = {
return .init(
name: "Icons",
Expand Down Expand Up @@ -142,6 +150,7 @@ final class CheckboxGroupComponentUIViewModel: ComponentUIViewModel {
@Published var isAlignmentLeft: Bool
@Published var isLayoutVertical: Bool
@Published var showGroupTitle: Bool
@Published var isEnabled: Bool
@Published var icon: [String: UIImage]
@Published var groupType: CheckboxGroupType

Expand All @@ -151,6 +160,7 @@ final class CheckboxGroupComponentUIViewModel: ComponentUIViewModel {
isAlignmentLeft: Bool = true,
isLayoutVertical: Bool = false,
showGroupTitle: Bool = false,
isEnabled: Bool = true,
icon: [String: UIImage] = ["Checkmark": DemoIconography.shared.checkmark.uiImage],
groupType: CheckboxGroupType = .doubleMix
) {
Expand All @@ -159,6 +169,7 @@ final class CheckboxGroupComponentUIViewModel: ComponentUIViewModel {
self.isAlignmentLeft = isAlignmentLeft
self.isLayoutVertical = isLayoutVertical
self.showGroupTitle = showGroupTitle
self.isEnabled = isEnabled
self.icon = icon
self.groupType = groupType
super.init(identifier: "Checkbox Group")
Expand All @@ -169,6 +180,7 @@ final class CheckboxGroupComponentUIViewModel: ComponentUIViewModel {
self.alignmentConfigurationItemViewModel,
self.layoutConfigurationItemViewModel,
self.titleConfigurationItemViewModel,
self.isEnableConfigurationItemViewModel,
self.iconConfigurationItemViewModel,
self.groupTypeConfigurationItemViewModel,
self.itemsSelectionStateConfigurationItemViewModel
Expand Down Expand Up @@ -199,6 +211,10 @@ extension CheckboxGroupComponentUIViewModel {
self.showGroupTitle.toggle()
}

@objc func toggleIsEnable() {
self.isEnabled.toggle()
}

@objc func presentIconSheet() {
self.showIconSheetSubject.send(icons)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
//
// RadioCheckboxUIViewController.swift
// SparkDemo
//
// Created by alican.aycil on 22.03.24.
// Copyright © 2024 Adevinta. All rights reserved.
//

import UIKit
import SparkCore
import Combine

final class RadioCheckboxUIViewController: UIViewController {

private let theme = SparkThemePublisher.shared.theme
private var cancellables = Set<AnyCancellable>()

private lazy var alignment: CheckboxUIView = {
let view = CheckboxUIView(
theme: self.theme,
text: "Alignment: Click to change postion.",
checkedImage: DemoIconography.shared.checkmark.uiImage,
isEnabled: true,
selectionState: .selected,
alignment: .left
)
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()

private lazy var lineView: UIView = {
let view = UIView()
view.backgroundColor = UIColor.lightGray
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()

private lazy var checkboxGroup: CheckboxGroupUIView = {
var items = [
CheckboxGroupItemDefault(title: "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.", id: "1", selectionState: .selected, isEnabled: true),
CheckboxGroupItemDefault(title: "Hello World", id: "2", selectionState: .selected, isEnabled: true)
]
let view = CheckboxGroupUIView(
checkedImage: DemoIconography.shared.checkmark.uiImage,
items: items,
alignment: alignment.isSelected ? CheckboxAlignment.left : CheckboxAlignment.right,
theme: self.theme,
intent: .main,
accessibilityIdentifierPrefix: "Checkbox"
)
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()

private lazy var radioButtonGroup: RadioButtonUIGroupView = {
var items = [
RadioButtonUIItem(id: 0, label: "Hello World"),
RadioButtonUIItem(id: 1, label: "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.")
]
let view = RadioButtonUIGroupView(
theme: self.theme,
intent: .main,
selectedID: 0,
items: items,
labelAlignment: alignment.isSelected ? RadioButtonLabelAlignment.trailing : RadioButtonLabelAlignment.leading,
groupLayout: .vertical
)
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()

override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = "Radio Checkbox UIKit"

self.setupView()
self.subscribe()
}

private func setupView() {
self.view.backgroundColor = UIColor.systemBackground

self.view.addSubview(alignment)
self.view.addSubview(lineView)
self.view.addSubview(checkboxGroup)
self.view.addSubview(radioButtonGroup)

NSLayoutConstraint.activate([

self.alignment.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 16),
self.alignment.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 16),
self.alignment.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -16),

self.lineView.topAnchor.constraint(equalTo: self.alignment.bottomAnchor, constant: 32),
self.lineView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 16),
self.lineView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -16),
self.lineView.heightAnchor.constraint(equalToConstant: 1),

self.checkboxGroup.topAnchor.constraint(equalTo: self.lineView.bottomAnchor, constant: 32),
self.checkboxGroup.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 16),
self.checkboxGroup.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -16),

self.radioButtonGroup.topAnchor.constraint(equalTo: self.checkboxGroup.bottomAnchor, constant: 16),
self.radioButtonGroup.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 16),
self.radioButtonGroup.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -16)
])
}

private func subscribe() {
self.alignment.publisher.subscribe(in: &self.cancellables) { [weak self] isSelected in
self?.radioButtonGroup.labelAlignment = isSelected == .selected ? RadioButtonLabelAlignment.trailing : RadioButtonLabelAlignment.leading
self?.checkboxGroup.alignment = isSelected == .selected ? CheckboxAlignment.left : CheckboxAlignment.right
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//
// RadioCheckboxView.swift
// SparkDemo
//
// Created by alican.aycil on 22.03.24.
// Copyright © 2024 Adevinta. All rights reserved.
//

import Spark
import SparkCore
import SwiftUI

struct RadioCheckboxView: View {

// MARK: - Properties
@State private var theme: Theme = SparkThemePublisher.shared.theme
@State private var alignment: CheckboxAlignment = .left
@State private var selectedIcon = CheckboxListView.Icons.checkedImage
@State private var selectedID: Int? = 0
@State private var items: [any CheckboxGroupItemProtocol] = [
CheckboxGroupItemDefault(title: "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.", id: "1", selectionState: .selected, isEnabled: true),
CheckboxGroupItemDefault(title: "Hello World", id: "2", selectionState: .selected, isEnabled: true)
]
@State private var radioGroupItems: [RadioButtonItem<Int>] = [
RadioButtonItem(id: 0, label: "Hello World"),
RadioButtonItem(id: 1, label: "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.")
]


// MARK: - View
var body: some View {
Component(
name: "Radio Checkbox SwiftUI",
configuration: {

EnumSelector(
title: "Alignment",
dialogTitle: "Select a Alignment",
values: CheckboxAlignment.allCases,
value: self.$alignment
)
},
integration: {
VStack(alignment: .leading) {
CheckboxGroupView(
checkedImage: self.selectedIcon.image,
items: self.$items,
layout: .vertical,
alignment: self.alignment,
theme: self.theme,
intent: .main,
accessibilityIdentifierPrefix: "checkbox-group"
)

RadioButtonGroupView(
theme: self.theme,
intent: .main,
selectedID: self.$selectedID,
items: self.radioGroupItems,
labelAlignment: self.alignment == .left ? .trailing : .leading,
groupLayout: .vertical
)
}
}
)
}
}
Loading

0 comments on commit f229f23

Please sign in to comment.