-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[CAT-202] SelectButton, SelectListButton (#24)
- Loading branch information
1 parent
44ce8ef
commit 6560bbd
Showing
11 changed files
with
361 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
146 changes: 146 additions & 0 deletions
146
Projects/Shared/DesignSystem/Sources/Component/Button/Detail/SelectButtonDetail.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
// | ||
// SelectButtonDetail.swift | ||
// DesignSystem | ||
// | ||
// Created by devMinseok on 8/13/24. | ||
// Copyright © 2024 PomoNyang. All rights reserved. | ||
// | ||
|
||
import SwiftUI | ||
|
||
extension Button where Label == SelectButtonDetail<Text, Text, Image?, Image?> { | ||
public init( | ||
title: LocalizedStringKey, | ||
subtitle: LocalizedStringKey, | ||
leftIcon: Image? = nil, | ||
rightIcon: Image? = nil, | ||
action: @escaping () -> Void | ||
) { | ||
self.init(action: action) { | ||
SelectButtonDetail { | ||
Text(title) | ||
} subtitle: { | ||
Text(subtitle) | ||
} leftIcon: { | ||
leftIcon | ||
} rightIcon: { | ||
rightIcon | ||
} | ||
} | ||
} | ||
} | ||
|
||
public struct SelectButtonDetail<Title: View, Subtitle: View, LeftIcon: View, RightIcon: View>: View { | ||
@Environment(\.selectButtonDetailStyle) private var style | ||
private let title: Title | ||
private let subtitle: Subtitle | ||
private let leftIcon: LeftIcon | ||
private let rightIcon: RightIcon | ||
|
||
init( | ||
@ViewBuilder title: () -> Title, | ||
@ViewBuilder subtitle: () -> Subtitle, | ||
@ViewBuilder leftIcon: () -> LeftIcon, | ||
@ViewBuilder rightIcon: () -> RightIcon | ||
) { | ||
self.title = title() | ||
self.subtitle = subtitle() | ||
self.leftIcon = leftIcon() | ||
self.rightIcon = rightIcon() | ||
} | ||
|
||
public var body: some View { | ||
let configuration = SelectButtonDetailConfiguration( | ||
title: title, | ||
subtitle: subtitle, | ||
leftIcon: leftIcon, | ||
rightIcon: rightIcon | ||
) | ||
AnyView(style.resolve(configuration: configuration)) | ||
} | ||
} | ||
|
||
struct SelectButtonDetailConfiguration { | ||
struct Title: View { | ||
let body: AnyView | ||
} | ||
|
||
struct Subtitle: View { | ||
let body: AnyView | ||
} | ||
|
||
struct LeftIcon: View { | ||
let body: AnyView | ||
} | ||
|
||
struct RightIcon: View { | ||
let body: AnyView | ||
} | ||
|
||
let title: Title | ||
let subtitle: Subtitle | ||
let leftIcon: LeftIcon | ||
let rightIcon: RightIcon | ||
|
||
fileprivate init( | ||
title: some View, | ||
subtitle: some View, | ||
leftIcon: some View, | ||
rightIcon: some View | ||
) { | ||
self.title = Title(body: AnyView(title)) | ||
self.subtitle = Subtitle(body: AnyView(subtitle)) | ||
self.leftIcon = LeftIcon(body: AnyView(leftIcon)) | ||
self.rightIcon = RightIcon(body: AnyView(rightIcon)) | ||
} | ||
} | ||
|
||
protocol SelectButtonDetailStyle: DynamicProperty { | ||
typealias Configuration = SelectButtonDetailConfiguration | ||
associatedtype Body: View | ||
|
||
@ViewBuilder func makeBody(configuration: Configuration) -> Body | ||
} | ||
|
||
extension SelectButtonDetailStyle { | ||
fileprivate func resolve(configuration: Configuration) -> some View { | ||
SelectButtonResolvedDetailStyle(style: self, configuration: configuration) | ||
} | ||
} | ||
|
||
private struct SelectButtonResolvedDetailStyle<Style: SelectButtonDetailStyle>: View { | ||
let style: Style | ||
let configuration: Style.Configuration | ||
|
||
var body: some View { | ||
style.makeBody(configuration: configuration) | ||
} | ||
} | ||
|
||
struct SelectButtonDetailStyleKey: EnvironmentKey { | ||
static var defaultValue: any SelectButtonDetailStyle = DefaultSelectButtonDetailStyle() | ||
} | ||
|
||
extension EnvironmentValues { | ||
fileprivate var selectButtonDetailStyle: any SelectButtonDetailStyle { | ||
get { self[SelectButtonDetailStyleKey.self] } | ||
set { self[SelectButtonDetailStyleKey.self] = newValue } | ||
} | ||
} | ||
|
||
extension View { | ||
func selectButtonDetailStyle(_ style: some SelectButtonDetailStyle) -> some View { | ||
environment(\.selectButtonDetailStyle, style) | ||
} | ||
} | ||
|
||
struct DefaultSelectButtonDetailStyle: SelectButtonDetailStyle { | ||
func makeBody(configuration: Configuration) -> some View { | ||
HStack { | ||
configuration.title | ||
configuration.subtitle | ||
configuration.leftIcon | ||
configuration.rightIcon | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 91 additions & 0 deletions
91
Projects/Shared/DesignSystem/Sources/Component/Button/Select/SelectButtonStyle.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// | ||
// SelectButtonStyle.swift | ||
// DesignSystem | ||
// | ||
// Created by devMinseok on 8/13/24. | ||
// Copyright © 2024 PomoNyang. All rights reserved. | ||
// | ||
|
||
import SwiftUI | ||
|
||
public struct SelectButtonStyle: ButtonStyle { | ||
@Environment(\.isEnabled) var isEnabled | ||
let isSelected: Bool | ||
|
||
public init(isSelected: Bool) { | ||
self.isSelected = isSelected | ||
} | ||
|
||
public func makeBody(configuration: Configuration) -> some View { | ||
configuration.label | ||
.selectButtonDetailStyle( | ||
SelectButtonDetailStyleImpl( | ||
isSelected: isSelected, | ||
isDisabled: !isEnabled | ||
) | ||
) | ||
} | ||
} | ||
|
||
extension ButtonStyle where Self == SelectButtonStyle { | ||
public static func select( | ||
isSelected: Bool | ||
) -> Self { | ||
return SelectButtonStyle(isSelected: isSelected) | ||
} | ||
} | ||
|
||
struct SelectButtonDetailStyleImpl: SelectButtonDetailStyle { | ||
let isSelected: Bool | ||
let isDisabled: Bool | ||
|
||
func makeBody(configuration: Configuration) -> some View { | ||
VStack(spacing: Alias.Spacing.xSmall) { | ||
HStack(spacing: Alias.Spacing.xSmall) { | ||
configuration.leftIcon | ||
configuration.subtitle | ||
.font(Typography.subBodyR) | ||
.foregroundStyle(getSubtitleForegourndColor()) | ||
configuration.rightIcon | ||
} | ||
configuration.title | ||
.font(Typography.header5) | ||
.foregroundStyle(getTitleForegourndColor()) | ||
} | ||
.padding(.vertical, 16) | ||
.frame(maxWidth: .infinity) | ||
.background( | ||
RoundedRectangle(cornerRadius: Alias.BorderRadius.small) | ||
.fill(getBackgroundColor()) | ||
.strokeBorder(isSelected ? Alias.Color.Background.accent1 : .clear, lineWidth: 1) | ||
) | ||
} | ||
|
||
func getTitleForegourndColor() -> Color { | ||
if isDisabled { | ||
return Alias.Color.Text.disabled | ||
} else { | ||
if isSelected { | ||
return Alias.Color.Text.primary | ||
} else { | ||
return Alias.Color.Text.secondary | ||
} | ||
} | ||
} | ||
|
||
func getSubtitleForegourndColor() -> Color { | ||
if isDisabled { | ||
return Alias.Color.Text.disabled | ||
} else { | ||
return Alias.Color.Text.tertiary | ||
} | ||
} | ||
|
||
func getBackgroundColor() -> Color { | ||
if isSelected { | ||
return Alias.Color.Background.accent2 | ||
} else { | ||
return Alias.Color.Background.secondary | ||
} | ||
} | ||
} |
Oops, something went wrong.