From 77dd82f6468bd8447eb5480af23a8c21c3298008 Mon Sep 17 00:00:00 2001 From: tkheyfets Date: Mon, 16 Mar 2026 19:33:12 -0400 Subject: [PATCH 1/9] fix: use checkbox instead of toggle for ToS consent in onboarding Replace VToggle with native macOS checkbox (Toggle .checkbox style) for the Terms of Service consent, placed on the leading side of the text as is standard for consent checkboxes. --- .../Onboarding/ImproveExperienceStepView.swift | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift b/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift index 8ccde70fc7a..a87f0ec6bfd 100644 --- a/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift +++ b/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift @@ -69,11 +69,13 @@ struct ImproveExperienceStepView: View { .stroke(VColor.borderBase, lineWidth: 1) ) - // ToS consent toggle - HStack { + // ToS consent checkbox + HStack(alignment: .top, spacing: VSpacing.md) { + Toggle("", isOn: $tosAccepted) + .toggleStyle(.checkbox) + .labelsHidden() + .padding(.top, 2) tosConsentText - Spacer() - VToggle(isOn: $tosAccepted) } .padding(VSpacing.lg) .overlay( From 0ff8eb835c20e2d9df40b17d1433c5c429d18202 Mon Sep 17 00:00:00 2001 From: tkheyfets Date: Mon, 16 Mar 2026 19:37:43 -0400 Subject: [PATCH 2/9] fix: add accessibility label and use VSpacing.xxs token for checkbox padding --- .../Features/Onboarding/ImproveExperienceStepView.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift b/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift index a87f0ec6bfd..db670895784 100644 --- a/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift +++ b/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift @@ -71,10 +71,10 @@ struct ImproveExperienceStepView: View { // ToS consent checkbox HStack(alignment: .top, spacing: VSpacing.md) { - Toggle("", isOn: $tosAccepted) + Toggle("Agree to Terms of Service and Privacy Policy", isOn: $tosAccepted) .toggleStyle(.checkbox) .labelsHidden() - .padding(.top, 2) + .padding(.top, VSpacing.xxs) tosConsentText } .padding(VSpacing.lg) From 57ef9ccdac0120fee8dc1396de39984e5dc0ce35 Mon Sep 17 00:00:00 2001 From: tkheyfets Date: Mon, 16 Mar 2026 19:50:42 -0400 Subject: [PATCH 3/9] fix: style checkbox with V* design tokens, move to right, match section width --- .../ImproveExperienceStepView.swift | 45 ++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift b/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift index db670895784..d6a0e89c1bf 100644 --- a/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift +++ b/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift @@ -70,12 +70,10 @@ struct ImproveExperienceStepView: View { ) // ToS consent checkbox - HStack(alignment: .top, spacing: VSpacing.md) { - Toggle("Agree to Terms of Service and Privacy Policy", isOn: $tosAccepted) - .toggleStyle(.checkbox) - .labelsHidden() - .padding(.top, VSpacing.xxs) + HStack { tosConsentText + Spacer() + VCheckbox(isOn: $tosAccepted) } .padding(VSpacing.lg) .overlay( @@ -152,3 +150,40 @@ struct ImproveExperienceStepView: View { } } } + +// MARK: - Checkbox + +/// A styled checkbox matching the V* component aesthetic: primary-filled with +/// white checkmark when checked, outlined rounded square when unchecked. +private struct VCheckbox: View { + @Binding var isOn: Bool + + private let size: CGFloat = 20 + private let cornerRadius: CGFloat = VRadius.sm + + var body: some View { + Button { + isOn.toggle() + } label: { + ZStack { + if isOn { + RoundedRectangle(cornerRadius: cornerRadius) + .fill(VColor.primaryBase) + .frame(width: size, height: size) + + Image(systemName: "checkmark") + .font(.system(size: 12, weight: .bold)) + .foregroundColor(.white) + } else { + RoundedRectangle(cornerRadius: cornerRadius) + .stroke(VColor.borderBase, lineWidth: 1.5) + .frame(width: size, height: size) + } + } + } + .buttonStyle(.plain) + .animation(VAnimation.fast, value: isOn) + .accessibilityLabel("Agree to Terms of Service and Privacy Policy") + .accessibilityAddTraits(isOn ? .isSelected : []) + } +} From eec66d9a39d266d63ab33dd940db69bc814b520c Mon Sep 17 00:00:00 2001 From: tkheyfets Date: Mon, 16 Mar 2026 19:52:08 -0400 Subject: [PATCH 4/9] fix: move checkbox to left side and make consent label semibold --- .../Features/Onboarding/ImproveExperienceStepView.swift | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift b/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift index d6a0e89c1bf..95c562ac987 100644 --- a/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift +++ b/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift @@ -70,10 +70,9 @@ struct ImproveExperienceStepView: View { ) // ToS consent checkbox - HStack { - tosConsentText - Spacer() + HStack(spacing: VSpacing.md) { VCheckbox(isOn: $tosAccepted) + tosConsentText } .padding(VSpacing.lg) .overlay( @@ -117,7 +116,7 @@ struct ImproveExperienceStepView: View { private var tosConsentText: some View { VStack(alignment: .leading, spacing: VSpacing.xs) { Text(.init("I agree to the [Terms of Service](https://www.vellum.ai/docs/vellum-terms-of-use) and [Privacy Policy](https://www.vellum.ai/docs/privacy-policy)")) - .font(VFont.body) + .font(VFont.bodyBold) .foregroundColor(VColor.contentSecondary) .tint(VColor.primaryBase) .environment(\.openURL, OpenURLAction { url in From 53245e35244c938dc3285ab5c9ecae39e822551f Mon Sep 17 00:00:00 2001 From: tkheyfets Date: Mon, 16 Mar 2026 19:52:39 -0400 Subject: [PATCH 5/9] fix: make ToS section full-width to match other sections --- .../Features/Onboarding/ImproveExperienceStepView.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift b/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift index 95c562ac987..feeba9cfc41 100644 --- a/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift +++ b/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift @@ -74,6 +74,7 @@ struct ImproveExperienceStepView: View { VCheckbox(isOn: $tosAccepted) tosConsentText } + .frame(maxWidth: .infinity, alignment: .leading) .padding(VSpacing.lg) .overlay( RoundedRectangle(cornerRadius: VRadius.lg) From a25f347b7fe3b937bde1aad8bd14ed098ff50c41 Mon Sep 17 00:00:00 2001 From: tkheyfets Date: Mon, 16 Mar 2026 19:53:55 -0400 Subject: [PATCH 6/9] fix: make unchecked checkbox tappable by adding contentShape and clear fill --- .../Onboarding/ImproveExperienceStepView.swift | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift b/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift index feeba9cfc41..bc3e274472a 100644 --- a/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift +++ b/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift @@ -169,17 +169,21 @@ private struct VCheckbox: View { if isOn { RoundedRectangle(cornerRadius: cornerRadius) .fill(VColor.primaryBase) - .frame(width: size, height: size) Image(systemName: "checkmark") .font(.system(size: 12, weight: .bold)) .foregroundColor(.white) } else { RoundedRectangle(cornerRadius: cornerRadius) - .stroke(VColor.borderBase, lineWidth: 1.5) - .frame(width: size, height: size) + .fill(Color.clear) + .overlay( + RoundedRectangle(cornerRadius: cornerRadius) + .stroke(VColor.borderBase, lineWidth: 1.5) + ) } } + .frame(width: size, height: size) + .contentShape(Rectangle()) } .buttonStyle(.plain) .animation(VAnimation.fast, value: isOn) From 9a31454cddacb073981cf72be22731afd0413e9b Mon Sep 17 00:00:00 2001 From: tkheyfets Date: Mon, 16 Mar 2026 19:54:18 -0400 Subject: [PATCH 7/9] fix: revert consent text to regular weight --- .../Features/Onboarding/ImproveExperienceStepView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift b/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift index bc3e274472a..045923cea50 100644 --- a/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift +++ b/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift @@ -117,7 +117,7 @@ struct ImproveExperienceStepView: View { private var tosConsentText: some View { VStack(alignment: .leading, spacing: VSpacing.xs) { Text(.init("I agree to the [Terms of Service](https://www.vellum.ai/docs/vellum-terms-of-use) and [Privacy Policy](https://www.vellum.ai/docs/privacy-policy)")) - .font(VFont.bodyBold) + .font(VFont.body) .foregroundColor(VColor.contentSecondary) .tint(VColor.primaryBase) .environment(\.openURL, OpenURLAction { url in From 49e5d49b8925ed83326799e8244c9260d4b663e5 Mon Sep 17 00:00:00 2001 From: tkheyfets Date: Mon, 16 Mar 2026 20:03:25 -0400 Subject: [PATCH 8/9] fix: use VIconView for checkmark and .isToggle accessibility trait --- .../Features/Onboarding/ImproveExperienceStepView.swift | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift b/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift index 045923cea50..2185404b3bb 100644 --- a/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift +++ b/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift @@ -170,8 +170,7 @@ private struct VCheckbox: View { RoundedRectangle(cornerRadius: cornerRadius) .fill(VColor.primaryBase) - Image(systemName: "checkmark") - .font(.system(size: 12, weight: .bold)) + VIconView(.check, size: 12) .foregroundColor(.white) } else { RoundedRectangle(cornerRadius: cornerRadius) @@ -188,6 +187,6 @@ private struct VCheckbox: View { .buttonStyle(.plain) .animation(VAnimation.fast, value: isOn) .accessibilityLabel("Agree to Terms of Service and Privacy Policy") - .accessibilityAddTraits(isOn ? .isSelected : []) + .accessibilityAddTraits(.isToggle) } } From 04e72dc4f0bb7cf8288a0339d3ca4d6b5b1d3783 Mon Sep 17 00:00:00 2001 From: tkheyfets Date: Mon, 16 Mar 2026 20:07:21 -0400 Subject: [PATCH 9/9] fix: add accessibilityValue to VCheckbox for dynamic state reporting --- .../Features/Onboarding/ImproveExperienceStepView.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift b/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift index 2185404b3bb..7f513254eb9 100644 --- a/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift +++ b/clients/macos/vellum-assistant/Features/Onboarding/ImproveExperienceStepView.swift @@ -187,6 +187,7 @@ private struct VCheckbox: View { .buttonStyle(.plain) .animation(VAnimation.fast, value: isOn) .accessibilityLabel("Agree to Terms of Service and Privacy Policy") + .accessibilityValue(isOn ? "Checked" : "Unchecked") .accessibilityAddTraits(.isToggle) } }