|
@@ -4,21 +4,23 @@ struct GrammarCheckerView: View {
|
|
|
@StateObject private var viewModel = GrammarCheckerViewModel()
|
|
@StateObject private var viewModel = GrammarCheckerViewModel()
|
|
|
|
|
|
|
|
var body: some View {
|
|
var body: some View {
|
|
|
- VStack(alignment: .leading, spacing: 0) {
|
|
|
|
|
- header
|
|
|
|
|
- .padding(.bottom, 24)
|
|
|
|
|
|
|
+ ScrollView(.vertical, showsIndicators: false) {
|
|
|
|
|
+ VStack(alignment: .leading, spacing: 0) {
|
|
|
|
|
+ header
|
|
|
|
|
+ .padding(.bottom, 28)
|
|
|
|
|
|
|
|
- contentCard
|
|
|
|
|
- .padding(.bottom, 20)
|
|
|
|
|
|
|
+ contentCard
|
|
|
|
|
+ .padding(.bottom, 24)
|
|
|
|
|
|
|
|
- GradientButton(title: "Check Grammar") {
|
|
|
|
|
- viewModel.checkGrammar()
|
|
|
|
|
|
|
+ GradientButton(title: "Check Grammar") {
|
|
|
|
|
+ viewModel.checkGrammar()
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
+ .frame(maxWidth: .infinity, alignment: .topLeading)
|
|
|
|
|
+ .padding(.horizontal, AppTheme.contentPadding)
|
|
|
|
|
+ .padding(.top, 32)
|
|
|
|
|
+ .padding(.bottom, 40)
|
|
|
}
|
|
}
|
|
|
- .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
|
|
|
|
|
- .padding(.horizontal, AppTheme.contentPadding)
|
|
|
|
|
- .padding(.top, 28)
|
|
|
|
|
- .padding(.bottom, 32)
|
|
|
|
|
.onChange(of: viewModel.text) { newValue in
|
|
.onChange(of: viewModel.text) { newValue in
|
|
|
if newValue.count > GrammarCheckerViewModel.maxCharacters {
|
|
if newValue.count > GrammarCheckerViewModel.maxCharacters {
|
|
|
viewModel.text = String(newValue.prefix(GrammarCheckerViewModel.maxCharacters))
|
|
viewModel.text = String(newValue.prefix(GrammarCheckerViewModel.maxCharacters))
|
|
@@ -28,26 +30,26 @@ struct GrammarCheckerView: View {
|
|
|
|
|
|
|
|
private var header: some View {
|
|
private var header: some View {
|
|
|
HStack(alignment: .top) {
|
|
HStack(alignment: .top) {
|
|
|
- VStack(alignment: .leading, spacing: 6) {
|
|
|
|
|
|
|
+ VStack(alignment: .leading, spacing: 8) {
|
|
|
Text("Grammar Checker")
|
|
Text("Grammar Checker")
|
|
|
- .font(.system(size: 28, weight: .bold))
|
|
|
|
|
|
|
+ .font(.system(size: 30, weight: .bold))
|
|
|
.foregroundStyle(AppTheme.textPrimary)
|
|
.foregroundStyle(AppTheme.textPrimary)
|
|
|
|
|
|
|
|
HStack(spacing: 0) {
|
|
HStack(spacing: 0) {
|
|
|
Text("Write ")
|
|
Text("Write ")
|
|
|
.foregroundStyle(AppTheme.textSecondary)
|
|
.foregroundStyle(AppTheme.textSecondary)
|
|
|
Text("better")
|
|
Text("better")
|
|
|
- .font(.system(size: 14, weight: .semibold))
|
|
|
|
|
|
|
+ .fontWeight(.semibold)
|
|
|
.foregroundStyle(AppTheme.teal)
|
|
.foregroundStyle(AppTheme.teal)
|
|
|
Text(". Sound ")
|
|
Text(". Sound ")
|
|
|
.foregroundStyle(AppTheme.textSecondary)
|
|
.foregroundStyle(AppTheme.textSecondary)
|
|
|
Text("smarter")
|
|
Text("smarter")
|
|
|
- .font(.system(size: 14, weight: .semibold))
|
|
|
|
|
|
|
+ .fontWeight(.semibold)
|
|
|
.foregroundStyle(AppTheme.teal)
|
|
.foregroundStyle(AppTheme.teal)
|
|
|
Text(".")
|
|
Text(".")
|
|
|
.foregroundStyle(AppTheme.textSecondary)
|
|
.foregroundStyle(AppTheme.textSecondary)
|
|
|
}
|
|
}
|
|
|
- .font(.system(size: 14))
|
|
|
|
|
|
|
+ .font(.system(size: 15))
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
Spacer()
|
|
Spacer()
|
|
@@ -57,10 +59,10 @@ struct GrammarCheckerView: View {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private var contentCard: some View {
|
|
private var contentCard: some View {
|
|
|
- VStack(alignment: .leading, spacing: 14) {
|
|
|
|
|
|
|
+ VStack(alignment: .leading, spacing: 16) {
|
|
|
HStack(spacing: 8) {
|
|
HStack(spacing: 8) {
|
|
|
- Image(systemName: "pencil.line")
|
|
|
|
|
- .font(.system(size: 13))
|
|
|
|
|
|
|
+ Image(systemName: "doc.text.magnifyingglass")
|
|
|
|
|
+ .font(.system(size: 14))
|
|
|
.foregroundStyle(AppTheme.teal)
|
|
.foregroundStyle(AppTheme.teal)
|
|
|
|
|
|
|
|
Text("Your Content")
|
|
Text("Your Content")
|
|
@@ -72,12 +74,12 @@ struct GrammarCheckerView: View {
|
|
|
ThinCaretTextEditor(text: $viewModel.text)
|
|
ThinCaretTextEditor(text: $viewModel.text)
|
|
|
.font(.system(size: 14))
|
|
.font(.system(size: 14))
|
|
|
.foregroundStyle(AppTheme.textPrimary)
|
|
.foregroundStyle(AppTheme.textPrimary)
|
|
|
- .padding(12)
|
|
|
|
|
- .frame(minHeight: 220)
|
|
|
|
|
|
|
+ .padding(14)
|
|
|
|
|
+ .frame(minHeight: 320)
|
|
|
.background(Color.white)
|
|
.background(Color.white)
|
|
|
- .clipShape(RoundedRectangle(cornerRadius: 10))
|
|
|
|
|
|
|
+ .clipShape(RoundedRectangle(cornerRadius: AppTheme.inputCornerRadius))
|
|
|
.overlay(
|
|
.overlay(
|
|
|
- RoundedRectangle(cornerRadius: 10)
|
|
|
|
|
|
|
+ RoundedRectangle(cornerRadius: AppTheme.inputCornerRadius)
|
|
|
.stroke(AppTheme.inputBorder, lineWidth: 1)
|
|
.stroke(AppTheme.inputBorder, lineWidth: 1)
|
|
|
)
|
|
)
|
|
|
.overlay(alignment: .topLeading) {
|
|
.overlay(alignment: .topLeading) {
|
|
@@ -85,8 +87,8 @@ struct GrammarCheckerView: View {
|
|
|
Text("Type or paste your text here and press the check button...")
|
|
Text("Type or paste your text here and press the check button...")
|
|
|
.font(.system(size: 14))
|
|
.font(.system(size: 14))
|
|
|
.foregroundStyle(AppTheme.textMuted)
|
|
.foregroundStyle(AppTheme.textMuted)
|
|
|
- .padding(.horizontal, 16)
|
|
|
|
|
- .padding(.vertical, 20)
|
|
|
|
|
|
|
+ .padding(.horizontal, 18)
|
|
|
|
|
+ .padding(.vertical, 22)
|
|
|
.allowsHitTesting(false)
|
|
.allowsHitTesting(false)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -94,8 +96,8 @@ struct GrammarCheckerView: View {
|
|
|
Text(viewModel.characterCountLabel)
|
|
Text(viewModel.characterCountLabel)
|
|
|
.font(.system(size: 11))
|
|
.font(.system(size: 11))
|
|
|
.foregroundStyle(AppTheme.textMuted)
|
|
.foregroundStyle(AppTheme.textMuted)
|
|
|
- .padding(.trailing, 14)
|
|
|
|
|
- .padding(.bottom, 10)
|
|
|
|
|
|
|
+ .padding(.trailing, 16)
|
|
|
|
|
+ .padding(.bottom, 12)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
HStack(spacing: 8) {
|
|
HStack(spacing: 8) {
|
|
@@ -103,7 +105,7 @@ struct GrammarCheckerView: View {
|
|
|
viewModel.pasteText()
|
|
viewModel.pasteText()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- ToolbarButton(title: "Upload File", iconName: "arrow.up.doc") {}
|
|
|
|
|
|
|
+ ToolbarButton(title: "Upload File", iconName: "square.and.arrow.up") {}
|
|
|
|
|
|
|
|
HStack(spacing: 6) {
|
|
HStack(spacing: 6) {
|
|
|
Image(systemName: "textformat")
|
|
Image(systemName: "textformat")
|
|
@@ -129,9 +131,9 @@ struct GrammarCheckerView: View {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- .padding(20)
|
|
|
|
|
|
|
+ .padding(22)
|
|
|
.background(AppTheme.cardBackground)
|
|
.background(AppTheme.cardBackground)
|
|
|
.clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius))
|
|
.clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius))
|
|
|
- .shadow(color: AppTheme.cardShadow, radius: 12, y: 4)
|
|
|
|
|
|
|
+ .shadow(color: AppTheme.cardShadow, radius: 16, y: 6)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|