Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

πŸ”€ :: DesignSystem SMSSelectionControls μ œμž‘ #37

Merged
merged 17 commits into from
May 22, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 12 additions & 29 deletions Projects/Core/DesignSystem/Demo/Sources/DemoView.swift
Original file line number Diff line number Diff line change
@@ -1,44 +1,27 @@
import DesignSystem
import SwiftUI

struct DemoView: View {
@State var isPresentedBottomSheet = false
var body: some View {
public struct DemoView: View {
@State var isOn = true
@State var selection: Int? = 0

public var body: some View {
VStack {
Group {
CTAButton(text: "CTA Default", style: .default) {
withAnimation {
isPresentedBottomSheet = true
RadioComponent(selection: $selection) {
ForEach(0..<4) { index in
HStack {
SMSSelectionControls(tag: index)
.radioTag(index)
Text("asdfasdf")
}
}
}
}
.padding(8)

NavigationLink {
AView()
} label: {
Text("A")
}
}
.smsBottomSheet(isShowing: $isPresentedBottomSheet) {
RoundedRectangle(cornerRadius: 8)
.fill(Color.sms(.neutral(.n20)))
.frame(maxWidth: .infinity)
.frame(height: 500)
.padding(.horizontal)
}
}
}

struct AView: View {
@Environment(\.dismiss) var dismiss

var body: some View {
Text("A")
.smsBackButton(dismiss: dismiss)
}
}

struct DemoView_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import SwiftUI

public struct RadioComponent<T: Hashable, Content: View>: View {
private let value: RadioValue<T>
private let content: () -> Content

public init(
selection: Binding<T?>,
@ViewBuilder _ content: @escaping () -> Content,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

content 이 친ꡬ label이 μ™œ _ 인거죠?

onTapReceive: ((T?) -> Void)? = nil
) {
self.value = RadioValue(selection: selection, onTapReceive: onTapReceive)
self.content = content
}

public var body: some View {
content()
.environmentObject(value)
}
}

final class RadioValue<T: Hashable>: ObservableObject {
typealias TapReceiveAction = (T?) -> Void

@Binding var selection: T?
var onTapReceive: (TapReceiveAction)?

init(selection: Binding<T?>, onTapReceive: (TapReceiveAction)? = nil) {
_selection = selection
self.onTapReceive = onTapReceive
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import SwiftUI

public struct RadioTag<T: Hashable>: ViewModifier {
@EnvironmentObject private var value: RadioValue<T>
private var tag: T?

init(_ tag: T?) {
self.tag = tag
}

public func body(content: Content) -> some View {
Button {
value.selection = tag
value.onTapReceive?(tag)
} label: {
content
}
.buttonStyle(CustomButtonStyle.init(isOn: tag == value.selection))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CustomButtonStyle 이거 μ™œ 혼자 λ”°λ‘œ λ†€μ•„μš”?

}
}

extension View {
public func radioTag<T: Hashable>(_ tag: T?) -> some View {
self.modifier(RadioTag(tag))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import SwiftUI

public struct SMSSelectionControls<T: Hashable>: View {
@EnvironmentObject private var value: RadioValue<T>
private var tag: T?

public init(tag: T?) {
self.tag = tag
}

public var body: some View {
ZStack {
Circle()
.stroke(tag == value.selection ? Color.sms(.primary(.p2)) : Color.sms(.neutral(.n20)), lineWidth: 2)
.frame(width: 20, height: 20)

Circle()
.fill(tag == value.selection ? Color.sms(.primary(.p2)) : .clear)
.frame(width: 12, height: 12)
}
}
}

struct CustomButtonStyle: ButtonStyle {
var isOn: Bool

init(isOn: Bool) {
self.isOn = isOn
}

@ViewBuilder
func makeBody(configuration: Configuration) -> some View {
Circle()
.fill(self.isOn && configuration.isPressed ? Color.sms(.neutral(.n20)) : Color.clear)
.overlay {
configuration.label
}
.frame(width: 32, height: 32)
}
}