Skip to content

Conversation

@mauricioabreu
Copy link
Contributor

@mauricioabreu mauricioabreu commented Nov 18, 2025

Description

This PR updates the styling of the action buttons related to Billing subscriptions.

Previously, these actions were hidden behind a three-dots menu, which made them hard to find.

Now, the buttons are visible outside of the menu, making them much easier to spot.

Screenshot 2025-11-20 at 15 50 04

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

  • New Features

    • Subscription cards now show a dedicated actions row with explicit buttons (Switch plan, Re-subscribe, Cancel) instead of a condensed menu.
    • New appearance keys to style subscription action and cancel buttons.
  • Bug Fixes / Improvements

    • Actions relocated out of the pricing area for clearer layout and direct interactions.
    • Action buttons now support destructive styling for cancel flows and consistent localization.
  • Chores

    • Tests updated to exercise inline action controls and confirmation dialogs.

✏️ Tip: You can customize this high-level summary in your review settings.

@changeset-bot
Copy link

changeset-bot bot commented Nov 18, 2025

🦋 Changeset detected

Latest commit: 9da5e48

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
Name Type
@clerk/clerk-js Patch
@clerk/shared Patch
@clerk/chrome-extension Patch
@clerk/clerk-expo Patch
@clerk/agent-toolkit Patch
@clerk/astro Patch
@clerk/backend Patch
@clerk/elements Patch
@clerk/expo-passkeys Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/nextjs Patch
@clerk/nuxt Patch
@clerk/react-router Patch
@clerk/clerk-react Patch
@clerk/remix Patch
@clerk/tanstack-react-start Patch
@clerk/testing Patch
@clerk/themes Patch
@clerk/types Patch
@clerk/vue Patch
@clerk/localizations Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented Nov 18, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
clerk-js-sandbox Ready Ready Preview Comment Nov 20, 2025 7:18pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 18, 2025

Walkthrough

Replaced the three‑dots menu with inline action buttons rendered in a dedicated actions row in SubscriptionDetails; added two new appearance keys and corresponding ElementsConfig fields; updated unit and integration tests to interact with inline controls instead of a dropdown.

Changes

Cohort / File(s) Summary
Subscription details UI
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx
Removed ThreeDotsMenu; moved action rendering out of the pricing area into a separate actions container; rendered per-action Button elements with descriptors, variants, localization keys, and click handlers.
Appearance descriptors
packages/clerk-js/src/ui/customizables/elementDescriptors.ts
Added subscriptionDetailsActionButton and subscriptionDetailsCancelButton to APPEARANCE_KEYS.
Types: appearance config
packages/shared/src/types/appearance.ts
Added subscriptionDetailsActionButton: WithOptions and subscriptionDetailsCancelButton: WithOptions to ElementsConfig.
Tests / Integration
integration/tests/pricing-table.test.ts, packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx
Removed menu/ellipsis interactions; updated tests to target inline action buttons and drawer/confirmation dialogs directly; simplified cancellation/resubscribe flows.
Changeset
.changeset/curvy-pianos-wait.md
New changeset patching @clerk/clerk-js and @clerk/shared with description "Make subscription actions more visible with inline buttons".
Bundlewatch
packages/clerk-js/bundlewatch.config.json
Increased maxSize threshold for UI-common legacy bundle from 120.1KB to 122KB.

Sequence Diagram(s)

sequenceDiagram
  participant UI as SubscriptionCard (UI)
  participant Guard as BillingPermissionGuard
  participant Hooks as BillingHooks
  participant Checkout as CheckoutService
  participant API as BillingAPI

  rect rgba(235,245,255,0.6)
  UI->>Guard: render (permission check)
  Guard-->>UI: allowed / denied
  end

  alt Click inline "Switch Plan"
    UI->>Hooks: handleSwitchPlan(planId)
    Hooks->>Checkout: startCheckout(planId)
    Checkout-->>UI: redirect / checkout flow
  else Click inline "Cancel"
    UI->>Hooks: handleCancelSubscription(subId)
    Hooks->>API: cancelSubscription(subId)
    API-->>UI: success / failure
  else Click inline "Resubscribe"
    UI->>Hooks: handleResubscribe(planId)
    Hooks->>Checkout: startCheckout(planId)
    Checkout-->>UI: redirect / checkout flow
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review layout and accessibility in packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx.
  • Verify APPEARANCE_KEYS additions align with ElementsConfig in packages/shared/src/types/appearance.ts.
  • Confirm tests and integration updates use robust selectors and localization keys.

Poem

🐇 I hopped from dots to buttons bright,
A tidy row now ends each card by night.
Cancel, switch, resubscribe in view,
Click, confirm — the flow is new.
Tiny paws applaud the change, just right.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: making subscription actions more visible by replacing a three-dots menu with inline buttons.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch mauricio-antunes/bill-1339-make-it-easier-to-cancel-a-subscription

Comment @coderabbitai help to get the list of available commands and usage tips.

@mauricioabreu mauricioabreu force-pushed the mauricio-antunes/bill-1339-make-it-easier-to-cancel-a-subscription branch 2 times, most recently from 23edb7d to ba8adcc Compare November 18, 2025 21:40
@mauricioabreu mauricioabreu marked this pull request as ready for review November 18, 2025 21:46
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx (1)

400-487: Handlers/permissions and explicit buttons are clean; consider tightening switchability condition

The new action handlers (handleSwitchPlan, handleCancelSubscription, handleResubscribe) are well-factored, have accurate hook dependencies, and reuse the existing checkout + revalidation flow correctly. The canManageBilling guard also cleanly prevents rendering or usage by users without billing permissions, and the new Flex layout with subscriptionDetailsActionButton/subscriptionDetailsCancelButton descriptors fits the appearance model nicely.

One behavioral nuance to consider: isSwitchable currently ignores canceledAt, so a canceled, non-free subscription that’s still in status !== 'past_due' could surface both “Switch plan” and “Re-subscribe” buttons simultaneously. If that’s not desired UX, you might want to gate switching on an active (or at least non‑canceled) subscription, e.g.:

-  const isSwitchable =
-    ((subscription.planPeriod === 'month' && Boolean(subscription.plan.annualMonthlyFee)) ||
-      subscription.planPeriod === 'annual') &&
-    subscription.status !== 'past_due';
+  const isSwitchable =
+    subscription.canceledAt === null &&
+    ((subscription.planPeriod === 'month' && Boolean(subscription.plan.annualMonthlyFee)) ||
+      subscription.planPeriod === 'annual') &&
+    subscription.status !== 'past_due';
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between edbd18c and ba8adcc.

📒 Files selected for processing (3)
  • packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx (2 hunks)
  • packages/clerk-js/src/ui/customizables/elementDescriptors.ts (1 hunks)
  • packages/shared/src/types/appearance.ts (1 hunks)
🔇 Additional comments (3)
packages/clerk-js/src/ui/customizables/elementDescriptors.ts (1)

502-510: New subscription details button descriptors are correctly wired

subscriptionDetailsActionButton and subscriptionDetailsCancelButton are added consistently with the other subscription details keys and will be type-checked against ElementsConfig, so the descriptor map stays in sync with the appearance surface.

packages/shared/src/types/appearance.ts (1)

637-645: ElementsConfig extensions for subscription buttons look consistent

subscriptionDetailsActionButton and subscriptionDetailsCancelButton are added with the same WithOptions shape as the surrounding subscription card entries and match the descriptor keys, so theme authors can now independently style the primary and destructive actions.

packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx (1)

609-610: SubscriptionCardActions placement within the card looks appropriate

Rendering SubscriptionCardActions as the final section of the card after the detail rows keeps the structure consistent (header, details, actions) and aligns with the new border-separated actions row styling.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx (1)

459-486: Actions bar composition is solid; consider a more stable key (optional)

The Flex-based actions row with its own descriptor, border, and spacing cleanly separates actions from the card body and uses the new appearance descriptors for primary vs destructive buttons correctly. Since the action set is small and order is fixed, key={index} is acceptable, but if actions ever become dynamic, consider a more stable key source (e.g., an explicit id on each action) to avoid potential React reconciliation quirks.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ba8adcc and 6ea4298.

📒 Files selected for processing (1)
  • packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx (2)
packages/clerk-js/src/ui/customizables/index.ts (1)
  • Flex (16-16)
packages/clerk-js/src/ui/customizables/elementDescriptors.ts (1)
  • descriptors (581-581)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: Build Packages
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (3)
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx (3)

24-24: Context import usage looks correct and cohesive

Importing SubscriberTypeContext, usePlansContext, useSubscriberTypeContext, and useSubscription from the shared ../../contexts entry keeps all subscription-related context coming from a single module and matches their usage throughout this file. No changes needed here.


399-412: Switch-plan action labels and checkout wiring look consistent

The new labels billing.switchToAnnual / billing.switchToMonthly correctly branch on subscription.planPeriod and keep the action semantics clear while the checkout call flips the period as expected (month → annual, annual → month) and passes the current planId and for scope. As long as the new i18n keys exist in the billing namespace, this logic is solid.


608-610: Placing SubscriptionCardActions at the bottom of the card aligns with the details layout

Rendering SubscriptionCardActions after the status-specific DetailRows ensures the action bar is consistently at the bottom of each card and leverages the internal is* guards so empty action sets result in no footer UI. This composition reads clearly and doesn’t introduce new edge cases.

@mauricioabreu mauricioabreu changed the title feat(clerk-js,shared): make it easier to cancel a subscription feat(clerk-js,shared): Make it easier to cancel a subscription Nov 18, 2025
@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 18, 2025

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7255

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7255

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7255

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7255

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7255

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7255

@clerk/elements

npm i https://pkg.pr.new/@clerk/elements@7255

@clerk/clerk-expo

npm i https://pkg.pr.new/@clerk/clerk-expo@7255

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7255

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7255

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7255

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7255

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7255

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7255

@clerk/clerk-react

npm i https://pkg.pr.new/@clerk/clerk-react@7255

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7255

@clerk/remix

npm i https://pkg.pr.new/@clerk/remix@7255

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7255

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7255

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7255

@clerk/themes

npm i https://pkg.pr.new/@clerk/themes@7255

@clerk/types

npm i https://pkg.pr.new/@clerk/types@7255

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7255

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7255

commit: 9da5e48

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx (1)

36-1232: Consider adding explicit assertion for menu removal.

While the tests thoroughly validate the new inline button UI, consider adding an explicit assertion in one or more test cases to verify that the three-dots menu button is no longer present. This would provide clearer documentation that the menu-based UI was intentionally removed.

Example assertion you could add to any test case:

 await waitFor(() => {
   expect(getByText('Switch to annual')).toBeVisible();
   expect(getByText('Cancel subscription')).toBeVisible();
+  expect(queryByRole('button', { name: /open menu/i })).toBeNull();
 });
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7e29661 and 228e609.

📒 Files selected for processing (2)
  • integration/tests/pricing-table.test.ts (0 hunks)
  • packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx (5 hunks)
💤 Files with no reviewable changes (1)
  • integration/tests/pricing-table.test.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (33)
  • GitHub Check: Integration Tests (nextjs, chrome, 16)
  • GitHub Check: Integration Tests (custom, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome, 16)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (billing, chrome, RQ)
  • GitHub Check: Integration Tests (billing, chrome)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 15, RQ)
  • GitHub Check: Integration Tests (machine, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome, 15)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (sessions:staging, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 14)
  • GitHub Check: Integration Tests (expo-web, chrome)
  • GitHub Check: Integration Tests (localhost, chrome)
  • GitHub Check: Integration Tests (handshake, chrome)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (handshake:staging, chrome)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Integration Tests (generic, chrome)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Integration Tests (elements, chrome)
  • GitHub Check: Unit Tests (22, **)
  • GitHub Check: Publish with pkg-pr-new
  • GitHub Check: Static analysis
  • GitHub Check: Unit Tests (22, shared, clerk-js, RQ)
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (5)
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx (5)

134-136: LGTM - Inline button text assertions updated correctly.

The test now validates the simplified button text for inline actions, which aligns with the new UI design where subscription actions are directly visible rather than hidden in a menu.


237-239: LGTM - Consistent inline button validation.

The annual subscription test correctly mirrors the monthly subscription pattern, validating simplified action button text.


314-317: LGTM - Good defensive test for free subscription actions.

These assertions properly verify that free subscriptions don't display cancel or switch action buttons, which is the expected behavior.


467-470: LGTM - Proper action button count verification.

The test correctly verifies that "Cancel subscription" appears exactly once for the active subscription, while also checking for the "Switch to monthly" option. The count assertion is a good practice to prevent duplicate inline actions.


1121-1124: LGTM - Free trial action button properly validated.

The test correctly verifies that free trial subscriptions show the specific "Cancel free trial" button text, which appropriately distinguishes free trials from regular subscriptions.

@mauricioabreu mauricioabreu force-pushed the mauricio-antunes/bill-1339-make-it-easier-to-cancel-a-subscription branch from 228e609 to 516676b Compare November 19, 2025 03:04
@mauricioabreu mauricioabreu changed the title feat(clerk-js,shared): Make it easier to cancel a subscription feat(clerk-js,shared): Make subscription actions more visible with inline buttons Nov 19, 2025
This PR updates the styling of the action buttons related to Billing subscriptions.

Previously, these actions were hidden behind a three-dots menu, which made them hard to find.

Now, the buttons are visible outside of the menu, making them much easier to spot.
@mauricioabreu mauricioabreu force-pushed the mauricio-antunes/bill-1339-make-it-easier-to-cancel-a-subscription branch from adc060d to a04513e Compare November 19, 2025 03:18
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx (2)

697-714: Consider more explicit button selection.

Using getAllByText with array indexing [0] and [length-1] works but is somewhat fragile—it assumes DOM order and could break if additional buttons with the same text appear.

Consider adding data-testid attributes or using getByRole('button', { name: /cancel subscription/i }) with container scoping to distinguish between the inline trigger and the confirmation dialog button more explicitly.

Example approach:

-const cancelButtons = getAllByText('Cancel subscription');
-await userEvent.click(cancelButtons[0]);
+const cancelButton = getByRole('button', { name: /^Cancel subscription$/i });
+await userEvent.click(cancelButton);

Then use a scoped query for the dialog:

-const allCancelButtons = getAllByText('Cancel subscription');
-await userEvent.click(allCancelButtons[allCancelButtons.length - 1]);
+const dialog = getByRole('dialog');
+const confirmButton = within(dialog).getByRole('button', { name: /^Cancel subscription$/i });
+await userEvent.click(confirmButton);

1217-1235: Same array-indexing pattern for free trial cancellation.

The same fragility concern applies here as in the regular subscription cancellation test (lines 697-714). Consider using role-based queries with container scoping for more robust button selection.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between adc060d and a04513e.

📒 Files selected for processing (6)
  • .changeset/curvy-pianos-wait.md (1 hunks)
  • integration/tests/pricing-table.test.ts (2 hunks)
  • packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx (18 hunks)
  • packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx (4 hunks)
  • packages/clerk-js/src/ui/customizables/elementDescriptors.ts (1 hunks)
  • packages/shared/src/types/appearance.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • integration/tests/pricing-table.test.ts
  • packages/clerk-js/src/ui/customizables/elementDescriptors.ts
  • .changeset/curvy-pianos-wait.md
  • packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (29)
  • GitHub Check: Integration Tests (nextjs, chrome, 14)
  • GitHub Check: Integration Tests (nextjs, chrome, 15, RQ)
  • GitHub Check: Integration Tests (quickstart, chrome, 15)
  • GitHub Check: Integration Tests (nextjs, chrome, 16)
  • GitHub Check: Integration Tests (handshake, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome, 16)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Integration Tests (billing, chrome, RQ)
  • GitHub Check: Integration Tests (billing, chrome)
  • GitHub Check: Integration Tests (machine, chrome)
  • GitHub Check: Integration Tests (custom, chrome)
  • GitHub Check: Integration Tests (handshake:staging, chrome)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (expo-web, chrome)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Integration Tests (localhost, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (generic, chrome)
  • GitHub Check: Integration Tests (sessions:staging, chrome)
  • GitHub Check: Integration Tests (elements, chrome)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Unit Tests (22, shared, clerk-js, RQ)
  • GitHub Check: Unit Tests (22, **)
  • GitHub Check: Publish with pkg-pr-new
  • GitHub Check: Static analysis
🔇 Additional comments (4)
packages/shared/src/types/appearance.ts (1)

644-645: LGTM! Clean addition of new appearance keys.

The new subscriptionDetailsActionButton and subscriptionDetailsCancelButton fields follow the existing ElementsConfig pattern and are properly grouped with related subscription detail keys.

packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx (3)

134-135: Inline button assertions correctly updated.

The tests now properly verify that action buttons ("Switch to annual", "Switch to monthly", "Cancel subscription") are rendered inline rather than hidden behind a menu.

Also applies to: 237-238


315-316: Correct verification that free plans have no action buttons.

Properly confirms that free plans do not display cancel or switch actions inline.


467-469: Inline action buttons correctly verified across scenarios.

Tests properly validate that "Switch to monthly", "Resubscribe", "Cancel subscription", and "Cancel free trial" buttons appear inline as expected.

Also applies to: 1126-1129

price: normalizeFormatted(subscription.plan.fee.amountFormatted),
currency: subscription.plan.fee.currencySymbol,
}),
? localizationKeys('billing.switchToAnnual')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we keep the labels that include the prices ? Originally we didn't had them, and the based of feedback we added them.

If we are deciding to remove them, we should mark those localization keys as deprecated and remove them in the next major, since they are not longer used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restored prices in switch plans buttons via b507f9a

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx (1)

473-500: Consider using stable identifiers instead of array index as React keys

The inline action layout and use of subscriptionDetailsCardActions / subscriptionDetails(Action|Cancel)Button descriptors look good and match the intent of surfacing actions more clearly.

One improvement: key={index} on the mapped actions can lead to subtle UI/state issues if the set of actions changes over time (e.g. when a subscription becomes cancellable or re‑subscribable). Prefer a stable key derived from the action type, for example by adding a type: 'switch' | 'cancel' | 'reSubscribe' field when constructing the actions array and using that as the key.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a04513e and b507f9a.

📒 Files selected for processing (2)
  • packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx (16 hunks)
  • packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/clerk-js/src/ui/components/SubscriptionDetails/tests/SubscriptionDetails.test.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx (2)
packages/clerk-js/src/ui/customizables/index.ts (1)
  • Flex (16-16)
packages/clerk-js/src/ui/customizables/elementDescriptors.ts (1)
  • descriptors (581-581)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: Build Packages
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (1)
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx (1)

623-624: LGTM on rendering actions as a dedicated footer row

Placing <SubscriptionCardActions> at the bottom of the card, separated from pricing and details, makes the available actions much more discoverable while reusing the shared cancellation flow. No issues spotted here.

@mauricioabreu mauricioabreu merged commit d8f59a6 into main Nov 21, 2025
49 checks passed
@mauricioabreu mauricioabreu deleted the mauricio-antunes/bill-1339-make-it-easier-to-cancel-a-subscription branch November 21, 2025 10:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants