Skip to content

Commit

Permalink
feat: Create SegmentedButton
Browse files Browse the repository at this point in the history
  • Loading branch information
hhhello0507 committed Jul 20, 2024
1 parent 4a7da0c commit 8e886a8
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 3 deletions.
81 changes: 81 additions & 0 deletions Source/DDS/Component/Button/SegmentedButton.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import SwiftUI
import Combine

struct SegmentedButton: View {

private let labels: [String]

public init(
labels: [String],
selection: Binding<Int>? = nil
) {
self.labels = labels
self.selection = selection
let selected = selection?.wrappedValue ?? 0
self.selected = selected
self.animatedSelection = selected
}

@Namespace private var animation
@State private var selection: Binding<Int>?
@State private var selected: Int
@State private var animatedSelection: Int

var body: some View {
HStack(spacing: 8) {
ForEach(Array(labels.enumerated()), id: \.offset) { idx, label in
let isSelected = animatedSelection == idx
Button {
if selected != idx {
selected = idx
}
} label: {
Text(label)
.headline(.medium)
.foreground(isSelected ? DodamColor.Label.normal : DodamColor.Label.assistive)
.frame(maxWidth: .infinity)
.padding(.vertical, 6)
}
.background {
if isSelected {
RoundedRectangle(cornerRadius: 10)
.dodamFill(DodamColor.Background.normal)
.matchedGeometryEffect(
id: 0,
in: animation
)
.shadow(
color: .black.opacity(0.1),
radius: 4,
x: 2,
y: 2
)
}
}
.padding(4)
}
}
.frame(maxWidth: .infinity)
.background(DodamColor.Fill.neutral)
.clipShape(.medium)
.onChange(of: selected) { newValue in
selection?.wrappedValue = newValue
withAnimation(.spring(duration: 0.2)) {
animatedSelection = newValue
}
}
.onReceive(Just(selection)) { newValue in
if let newValue {
withAnimation(.spring) {
selected = newValue.wrappedValue
}
}
}
}
}

#Preview {
SegmentedButton(labels: ["외출", "외박"], selection: .constant(0))
.padding(.horizontal, 16)
.registerSUIT()
}
2 changes: 1 addition & 1 deletion Source/DDS/Component/EmptyView/EmptyView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public struct DodamEmptyView: View {
Dodam.icon(icon)
.frame(width: 36, height: 36)
Text(title)
.font(.label(.medium))
.label(.medium)
.foreground(DodamColor.Label.alternative)
}
DodamButton.fullWidth(title: buttonTitle) {
Expand Down
2 changes: 1 addition & 1 deletion Source/DDS/Component/TextField/TextField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public struct DodamTextField: View {
}
}
.frame(height: 41, alignment: .bottomLeading)
.font(.body(.medium))
.body(.medium)
Rectangle()
.frame(height: 1)
}
Expand Down
2 changes: 1 addition & 1 deletion Source/DDS/Component/TopTabView/TopTabView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public struct DodamTopTabView: View {
} label: {
VStack(spacing: 12) {
Text(string)
.font(.headline(.medium))
.headline(.medium)
.foreground(DodamColor.Label.normal)
.opacity(isSelected ? 1 : 0.5)
Group {
Expand Down
10 changes: 10 additions & 0 deletions Source/DDS/Foundation/Typography/Extension/ViewExt.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,51 @@ public extension View {

func title1(_ type: DodamTitle1) -> some View {
self.font(.title1(type))
.lineSpacing(type.lineHeight - 1)
}

func title2(_ type: DodamTitle2) -> some View {
self.font(.title2(type))
.lineSpacing(type.lineHeight - 1)
}

func title3(_ type: DodamTitle3) -> some View {
self.font(.title3(type))
.lineSpacing(type.lineHeight - 1)
}

func heading1(_ type: DodamHeading1) -> some View {
self.font(.heading1(type))
.lineSpacing(type.lineHeight - 1)
}

func heading2(_ type: DodamHeading2) -> some View {
self.font(.heading2(type))
.lineSpacing(type.lineHeight - 1)
}

func headline(_ type: DodamHeadline) -> some View {
self.font(.headline(type))
.lineSpacing(type.lineHeight - 1)
}

func body(_ type: DodamBody) -> some View {
self.font(.body(type))
.lineSpacing(type.lineHeight - 1)
}

func label(_ type: DodamLabel) -> some View {
self.font(.label(type))
.lineSpacing(type.lineHeight - 1)
}

func caption1(_ type: DodamCaption1) -> some View {
self.font(.caption1(type))
.lineSpacing(type.lineHeight - 1)
}

func caption2(_ type: DodamCaption2) -> some View {
self.font(.caption2(type))
.lineSpacing(type.lineHeight - 1)
}
}

0 comments on commit 8e886a8

Please sign in to comment.