diff --git a/Projects/Feature/Home/Sources/Goal/AddGoalListView.swift b/Projects/Feature/Home/Sources/Goal/AddGoalListView.swift index 05484ae2..84c76c50 100644 --- a/Projects/Feature/Home/Sources/Goal/AddGoalListView.swift +++ b/Projects/Feature/Home/Sources/Goal/AddGoalListView.swift @@ -27,7 +27,6 @@ struct AddGoalListView: View { .padding(.horizontal, 20) categoryListView } - .padding(.top, 28) } } @@ -71,6 +70,5 @@ private extension AddGoalListView { action: { action(item) } ) ) - .onTapGesture { action(item) } } } diff --git a/Projects/Feature/MakeGoal/Sources/MakeGoalReducer+Impl.swift b/Projects/Feature/MakeGoal/Sources/MakeGoalReducer+Impl.swift index b1c21309..0cfa6d8f 100644 --- a/Projects/Feature/MakeGoal/Sources/MakeGoalReducer+Impl.swift +++ b/Projects/Feature/MakeGoal/Sources/MakeGoalReducer+Impl.swift @@ -191,6 +191,10 @@ extension MakeGoalReducer { case .completeButtonTapped: guard !state.isLoading else { return .none } + guard !state.completeButtonDisabled else { + return .send(.showToast(.warning(message: "목표 이름은 14글자 이내로 입력해 주세요!"))) + } + state.isLoading = true let endDateString: String? = state.isEndDateOn ? TXCalendarUtil.apiDateString(for: state.endDate) diff --git a/Projects/Feature/MakeGoal/Sources/MakeGoalView.swift b/Projects/Feature/MakeGoal/Sources/MakeGoalView.swift index 93fe2afc..263b8d4d 100644 --- a/Projects/Feature/MakeGoal/Sources/MakeGoalView.swift +++ b/Projects/Feature/MakeGoal/Sources/MakeGoalView.swift @@ -80,7 +80,7 @@ public struct MakeGoalView: View { } } ) - .txToast(item: $store.toast) + .txToast(item: $store.toast, customPadding: 70) } } @@ -100,14 +100,15 @@ private extension MakeGoalView { var emojiCircle: some View { store.selectedEmoji.image .resizable() - .frame(width: 56, height: 56) - .padding(26) + .frame(width: 64, height: 64) + .padding(22) .background(Color.Gray.gray50, in: .circle) .insideBorder( Color.Gray.gray500, shape: .circle, lineWidth: LineWidth.m ) + .onTapGesture { store.send(.emojiButtonTapped) } .overlay(alignment: .bottomTrailing) { TXCircleButton( config: .init( @@ -115,10 +116,7 @@ private extension MakeGoalView { frameSize: .init(width: 28, height: 28), imageSize: .init(width: 16, height: 16), colorStyle: .white - ), - action: { - store.send(.emojiButtonTapped) - } + ), action: { } ) .insideBorder( Color.Gray.gray500, @@ -195,7 +193,8 @@ private extension MakeGoalView { valueText(store.startDateText) dropDownButton { store.send(.startDateTapped) } } - .padding(.vertical, 21.5) + .frame(height: 32) + .padding(.vertical, 16) } var endDateToggleRow: some View { @@ -206,7 +205,8 @@ private extension MakeGoalView { TXToggleSwitch(isOn: $store.isEndDateOn) } - .padding(.vertical, 17) + .frame(height: 32) + .padding(.vertical, 16) } var endDateRow: some View { @@ -230,13 +230,13 @@ private extension MakeGoalView { ) { store.send(.completeButtonTapped) } - .disabled(store.completeButtonDisabled) } var divider: some View { Color.Gray.gray500 .frame(height: 1) .padding(.horizontal, -16) + .padding(.vertical, -1) } func dropDownButton(_ action: @escaping () -> Void) -> some View { @@ -268,12 +268,11 @@ private extension MakeGoalView { TXRoundedRectangleButton(config: .long(text: "완료", colorStyle: .black)) { store.send(.periodSheetCompleteTapped) } - .padding(.top, 40) - .padding(.horizontal, 20) .padding(.vertical, 8) + .padding(.top, 32) + .padding(.horizontal, 20) } - .padding(.top, 36) - .padding(.bottom, 16) + .padding(.top, 8) } var periodTabButtons: some View { @@ -281,7 +280,8 @@ private extension MakeGoalView { TXRoundedRectangleButton( config: .small( text: store.weeklyPeriodText, - colorStyle: store.selectedPeriod == .weekly ? .black : .white + colorStyle: store.selectedPeriod == .weekly ? .black : .white, + font: .b2_14r ) ) { store.send(.periodSheetWeeklyTapped) @@ -333,12 +333,16 @@ private extension MakeGoalView { Text("\(store.periodCount)") .typography(.h2_24r) .foregroundStyle(Color.Gray.gray500) + .frame(width: 33) + .padding(.leading, 22) Text("번") .typography(.t2_16b) .foregroundStyle(Color.Gray.gray300) + .padding(.trailing, 17) } - .frame(width: 96, height: 58) + .padding(.vertical, 12) + .frame(width: 96) .insideBorder( Color.Gray.gray300, shape: RoundedRectangle(cornerRadius: 12), diff --git a/Projects/Feature/Onboarding/Sources/Connect/OnboardingConnectView.swift b/Projects/Feature/Onboarding/Sources/Connect/OnboardingConnectView.swift index 6cc31234..9c6efc9d 100644 --- a/Projects/Feature/Onboarding/Sources/Connect/OnboardingConnectView.swift +++ b/Projects/Feature/Onboarding/Sources/Connect/OnboardingConnectView.swift @@ -241,7 +241,6 @@ private extension OnboardingConnectView { .clipShape(RoundedRectangle(cornerRadius: Radius.s)) .padding(.horizontal, 30) } - .padding(.top, 28) .padding(.bottom, Spacing.spacing7) } diff --git a/Projects/Shared/DesignSystem/Sources/Components/Button/RoundedRectangle/Single/TXRoundedRectangleButton+Configuration.swift b/Projects/Shared/DesignSystem/Sources/Components/Button/RoundedRectangle/Single/TXRoundedRectangleButton+Configuration.swift index 7896015c..9e0f8b08 100644 --- a/Projects/Shared/DesignSystem/Sources/Components/Button/RoundedRectangle/Single/TXRoundedRectangleButton+Configuration.swift +++ b/Projects/Shared/DesignSystem/Sources/Components/Button/RoundedRectangle/Single/TXRoundedRectangleButton+Configuration.swift @@ -10,11 +10,12 @@ import SwiftUI public extension TXRoundedRectangleButton.Configuration { static func small( text: String, - colorStyle: ColorStyle + colorStyle: ColorStyle, + font: TypographyToken = .b1_14b ) -> Self { .init( text: text, - font: .b1_14b, + font: font, colorStyle: colorStyle, fixedFrame: false, radius: Radius.xs, diff --git a/Projects/Shared/DesignSystem/Sources/Components/Calendar/BottomSheet/TXCalendarBottomSheet.swift b/Projects/Shared/DesignSystem/Sources/Components/Calendar/BottomSheet/TXCalendarBottomSheet.swift index cb32f2a9..e3d14e0b 100644 --- a/Projects/Shared/DesignSystem/Sources/Components/Calendar/BottomSheet/TXCalendarBottomSheet.swift +++ b/Projects/Shared/DesignSystem/Sources/Components/Calendar/BottomSheet/TXCalendarBottomSheet.swift @@ -106,7 +106,6 @@ public struct TXCalendarBottomSheet: View { } } } - .padding(.top, Spacing.spacing10) .padding(.bottom, 40) // 버튼 영역 diff --git a/Projects/Shared/DesignSystem/Sources/Components/Card/Goal/GoalEditCardView+Configuration.swift b/Projects/Shared/DesignSystem/Sources/Components/Card/Goal/GoalEditCardView+Configuration.swift index f76c0152..b0705b46 100644 --- a/Projects/Shared/DesignSystem/Sources/Components/Card/Goal/GoalEditCardView+Configuration.swift +++ b/Projects/Shared/DesignSystem/Sources/Components/Card/Goal/GoalEditCardView+Configuration.swift @@ -38,7 +38,7 @@ extension GoalEditCardView.Configuration { rowContentSpacing: 28, titleWidth: 48, contentPadding: 16, - cardCornerRadius: 16, + cardCornerRadius: 12, contentBackgroundColor: Color.Gray.gray50, borderColor: Color.Gray.gray500, borderWidth: LineWidth.m, diff --git a/Projects/Shared/DesignSystem/Sources/Components/Card/Goal/GoalEditCardView.swift b/Projects/Shared/DesignSystem/Sources/Components/Card/Goal/GoalEditCardView.swift index 85f9ba37..a84bca72 100644 --- a/Projects/Shared/DesignSystem/Sources/Components/Card/Goal/GoalEditCardView.swift +++ b/Projects/Shared/DesignSystem/Sources/Components/Card/Goal/GoalEditCardView.swift @@ -82,10 +82,11 @@ public struct GoalEditCardView: View { CardHeaderView( config: config.headerConfig ) - - Color.Gray.gray500 - .frame(height: 1) - .frame(maxWidth: .infinity) + .insideRectEdgeBorder( + width: LineWidth.m, + edges: [.bottom], + color: Color.Gray.gray500 + ) VStack(alignment: .leading, spacing: config.rowSpacing) { rowView(title: "반복 주기", value: config.item.repeatCycle) diff --git a/Projects/Shared/DesignSystem/Sources/Components/Card/Header/CardHeaderView+Configuration.swift b/Projects/Shared/DesignSystem/Sources/Components/Card/Header/CardHeaderView+Configuration.swift index 0e6cacd9..95645af0 100644 --- a/Projects/Shared/DesignSystem/Sources/Components/Card/Header/CardHeaderView+Configuration.swift +++ b/Projects/Shared/DesignSystem/Sources/Components/Card/Header/CardHeaderView+Configuration.swift @@ -160,7 +160,8 @@ extension CardHeaderView.Configuration { radius: Radius.s, borderColor: Color.Gray.gray500, borderWidth: LineWidth.m, - titleTypography: .t2_16b + titleTypography: .t2_16b, + onHeaderTapped: action ) } diff --git a/Projects/Shared/DesignSystem/Sources/Components/Card/Header/CardHeaderView.swift b/Projects/Shared/DesignSystem/Sources/Components/Card/Header/CardHeaderView.swift index 4a09c525..4a2e2c17 100644 --- a/Projects/Shared/DesignSystem/Sources/Components/Card/Header/CardHeaderView.swift +++ b/Projects/Shared/DesignSystem/Sources/Components/Card/Header/CardHeaderView.swift @@ -78,14 +78,14 @@ private extension CardHeaderView { .typography(config.titleTypography) } .frame(maxWidth: .infinity, alignment: .leading) - .onTapGesture { - config.onHeaderTapped?() - } - + rightContent } .padding(config.padding) .background(Color.Common.white) + .onTapGesture { + config.onHeaderTapped?() + } .insideRectEdgeBorder( width: config.borderWidth, edges: config.insideBorderEdges, @@ -103,11 +103,12 @@ private extension CardHeaderView { action: action ) - case let .goalAdd(action): - TXCircleButton(config: .rightArrow()) { - action() - } - + case .goalAdd: + TXCircleButton( + config: .rightArrow(), + action: { config.onHeaderTapped?() } + ) + case let .goalEdit(action): Button(action: action) { Image.Icon.Symbol.meatball diff --git a/Projects/Shared/DesignSystem/Sources/Components/Dropdown/TXDropdown.swift b/Projects/Shared/DesignSystem/Sources/Components/Dropdown/TXDropdown.swift index dde7168d..b9fd3de2 100644 --- a/Projects/Shared/DesignSystem/Sources/Components/Dropdown/TXDropdown.swift +++ b/Projects/Shared/DesignSystem/Sources/Components/Dropdown/TXDropdown.swift @@ -70,13 +70,10 @@ public struct TXDropdown: View { Button { onSelect(item) } label: { - dropdownItem(item) - } - - if index != config.items.indices.last { - Rectangle() - .frame(height: config.borderWidth) - .foregroundStyle(config.dividerColor) + dropdownItem( + item, + showsBottomDivider: index != config.items.indices.last + ) } } } @@ -101,12 +98,20 @@ public struct TXDropdown: View { // MARK: - SubViews private extension TXDropdown { - func dropdownItem(_ item: TXDropdownItem) -> some View { + func dropdownItem( + _ item: TXDropdownItem, + showsBottomDivider: Bool + ) -> some View { Text(item.title) .typography(config.textTypography) .foregroundStyle(config.textColor) .frame(maxWidth: .infinity, maxHeight: config.itemHeight, alignment: .leading) .padding(.leading, config.leadingPadding) + .insideRectEdgeBorder( + width: config.borderWidth, + edges: showsBottomDivider ? [.bottom] : [], + color: config.dividerColor + ) } } diff --git a/Projects/Shared/DesignSystem/Sources/Components/Modal/Content/TXSelectIconModalContent.swift b/Projects/Shared/DesignSystem/Sources/Components/Modal/Content/TXSelectIconModalContent.swift index eabcbebe..263d6cf1 100644 --- a/Projects/Shared/DesignSystem/Sources/Components/Modal/Content/TXSelectIconModalContent.swift +++ b/Projects/Shared/DesignSystem/Sources/Components/Modal/Content/TXSelectIconModalContent.swift @@ -72,7 +72,7 @@ public struct TXGridButtonModalContent: View { VStack(spacing: 0) { Text(config.title) .typography(.t1_18eb) - .padding(.top, Spacing.spacing9) + .padding(.top, Spacing.spacing10) LazyVGrid( columns: Array( diff --git a/Projects/Shared/DesignSystem/Sources/Components/Modal/TXModalView.swift b/Projects/Shared/DesignSystem/Sources/Components/Modal/TXModalView.swift index 99b4f706..e408d5d8 100644 --- a/Projects/Shared/DesignSystem/Sources/Components/Modal/TXModalView.swift +++ b/Projects/Shared/DesignSystem/Sources/Components/Modal/TXModalView.swift @@ -81,7 +81,7 @@ private extension TXModalView { onAction(.confirm) } ) - .padding(.vertical, Spacing.spacing5) + .padding(.top, Spacing.spacing6) case let .gridButton(config): TXRoundedRectangleButton( @@ -92,11 +92,10 @@ private extension TXModalView { ) { onAction(.confirm) } - .padding(.horizontal, Spacing.spacing8) + .padding([.horizontal, .top], Spacing.spacing8) .padding(.vertical, Spacing.spacing5) } } - .padding(.top, Spacing.spacing9) .padding(.bottom, Spacing.spacing6) } } diff --git a/Projects/Shared/DesignSystem/Sources/Components/Tab/Group/TXTabGroup.swift b/Projects/Shared/DesignSystem/Sources/Components/Tab/Group/TXTabGroup.swift index 54af398f..b7524808 100644 --- a/Projects/Shared/DesignSystem/Sources/Components/Tab/Group/TXTabGroup.swift +++ b/Projects/Shared/DesignSystem/Sources/Components/Tab/Group/TXTabGroup.swift @@ -69,7 +69,8 @@ private extension TXTabGroup { text: item, colorStyle: selectedItem == item ? config.selectedColorStyle - : config.unselectedColorStyle + : config.unselectedColorStyle, + font: .b2_14r ) ) { selectedItem = item diff --git a/Projects/Shared/DesignSystem/Sources/Components/TextField/TXTextField.swift b/Projects/Shared/DesignSystem/Sources/Components/TextField/TXTextField.swift index a1f2b5ba..7642331a 100644 --- a/Projects/Shared/DesignSystem/Sources/Components/TextField/TXTextField.swift +++ b/Projects/Shared/DesignSystem/Sources/Components/TextField/TXTextField.swift @@ -69,13 +69,14 @@ public struct TXTextField: View { } public var body: some View { - VStack(alignment: .leading, spacing: subText != nil ? Spacing.spacing5 : 0) { - container - - if let subText { - subTextView(config: subText) + container + .overlay(alignment: .topLeading) { + if let subText, isFocused?.wrappedValue == true { + subTextView(config: subText) + .padding(.top, 52 + Spacing.spacing5) + .allowsHitTesting(false) + } } - } } } @@ -87,7 +88,7 @@ private extension TXTextField { Spacer() - if !text.isEmpty { + if !text.isEmpty && isFocused?.wrappedValue == true { clearButton } } @@ -108,11 +109,13 @@ private extension TXTextField { if let isFocused { TextField("", text: $text) + .typography(.t2_16b) .focused(isFocused) .submitLabel(submitLabel) .tint(tintColor) } else { TextField("", text: $text) + .typography(.t2_16b) .submitLabel(submitLabel) .tint(tintColor) } diff --git a/Projects/Shared/DesignSystem/Sources/Modifiers/View+TxBottomSheet.swift b/Projects/Shared/DesignSystem/Sources/Modifiers/View+TxBottomSheet.swift index 30e8b056..5d91cb73 100644 --- a/Projects/Shared/DesignSystem/Sources/Modifiers/View+TxBottomSheet.swift +++ b/Projects/Shared/DesignSystem/Sources/Modifiers/View+TxBottomSheet.swift @@ -51,6 +51,7 @@ private struct TXBottomSheetModifier: ViewModifier { @State private var dimmedOpacity: CGFloat = 0 @State private var contentHeight: CGFloat = 0 private let animationDuration: TimeInterval = 0.2 + private let dragAreaHeight: CGFloat = 28 func body(content: Content) -> some View { content @@ -82,35 +83,35 @@ private struct TXBottomSheetModifier: ViewModifier { // MARK: - SubViews { private extension TXBottomSheetModifier { var sheetView: some View { - sheetContent() - .padding(.bottom, TXSafeArea.inset(.bottom)) - .frame(maxWidth: .infinity, alignment: .bottom) - .background(Color.Common.white) - .clipShape( - UnevenRoundedRectangle(cornerRadii: .init(topLeading: Radius.m, topTrailing: Radius.m)) - ) - .background { - GeometryReader { proxy in - Color.clear - .onAppear { - updateContentHeight(proxy.size.height) - } - .onChange(of: proxy.size.height) { - updateContentHeight(proxy.size.height) - } - } - } - .overlay(alignment: .top) { - dragContainer + VStack(spacing: 0) { + dragContainer + sheetContent() + } + .padding(.bottom, TXSafeArea.inset(.bottom)) + .frame(maxWidth: .infinity, alignment: .bottom) + .background(Color.Common.white) + .clipShape( + UnevenRoundedRectangle(cornerRadii: .init(topLeading: Radius.m, topTrailing: Radius.m)) + ) + .background { + GeometryReader { proxy in + Color.clear + .onAppear { + updateContentHeight(proxy.size.height) + } + .onChange(of: proxy.size.height) { + updateContentHeight(proxy.size.height) + } } - .offset(y: sheetOffset) - .toolbar(.hidden, for: .tabBar) + } + .offset(y: sheetOffset) + .toolbar(.hidden, for: .tabBar) } var dragContainer: some View { ZStack { Color.clear - .frame(maxWidth: .infinity, maxHeight: 28) + .frame(maxWidth: .infinity, minHeight: dragAreaHeight, maxHeight: dragAreaHeight) .contentShape(.rect) if showDragIndicator {