diff --git a/.changeset/cold-parks-push.md b/.changeset/cold-parks-push.md new file mode 100644 index 00000000000..469a530e50f --- /dev/null +++ b/.changeset/cold-parks-push.md @@ -0,0 +1,5 @@ +--- +'@clerk/vue': minor +--- + +Expose billing buttons as experimental diff --git a/integration/templates/vue-vite/src/router.ts b/integration/templates/vue-vite/src/router.ts index c598b2b0bff..31fc822e18e 100644 --- a/integration/templates/vue-vite/src/router.ts +++ b/integration/templates/vue-vite/src/router.ts @@ -47,6 +47,22 @@ const routes = [ path: '/user', component: () => import('./views/Profile.vue'), }, + // Billing button routes + { + name: 'CheckoutBtn', + path: '/billing/checkout-btn', + component: () => import('./views/billing/CheckoutBtn.vue'), + }, + { + name: 'PlanDetailsBtn', + path: '/billing/plan-details-btn', + component: () => import('./views/billing/PlanDetailsBtn.vue'), + }, + { + name: 'SubscriptionDetailsBtn', + path: '/billing/subscription-details-btn', + component: () => import('./views/billing/SubscriptionDetailsBtn.vue'), + }, ]; const router = createRouter({ diff --git a/integration/templates/vue-vite/src/views/billing/CheckoutBtn.vue b/integration/templates/vue-vite/src/views/billing/CheckoutBtn.vue new file mode 100644 index 00000000000..39c23365733 --- /dev/null +++ b/integration/templates/vue-vite/src/views/billing/CheckoutBtn.vue @@ -0,0 +1,17 @@ + + + diff --git a/integration/templates/vue-vite/src/views/billing/PlanDetailsBtn.vue b/integration/templates/vue-vite/src/views/billing/PlanDetailsBtn.vue new file mode 100644 index 00000000000..cc51a1035bc --- /dev/null +++ b/integration/templates/vue-vite/src/views/billing/PlanDetailsBtn.vue @@ -0,0 +1,9 @@ + + + diff --git a/integration/templates/vue-vite/src/views/billing/SubscriptionDetailsBtn.vue b/integration/templates/vue-vite/src/views/billing/SubscriptionDetailsBtn.vue new file mode 100644 index 00000000000..5ff010ab10c --- /dev/null +++ b/integration/templates/vue-vite/src/views/billing/SubscriptionDetailsBtn.vue @@ -0,0 +1,9 @@ + + + diff --git a/integration/tests/pricing-table.test.ts b/integration/tests/pricing-table.test.ts index 22b845f3deb..c8e25fdb64c 100644 --- a/integration/tests/pricing-table.test.ts +++ b/integration/tests/pricing-table.test.ts @@ -32,9 +32,8 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withBilling] })('pricing tabl }); test('renders pricing details of a specific plan', async ({ page, context }) => { - if (!app.name.includes('next')) { - return; - } + test.skip(app.name.includes('astro'), 'Still working on it'); + const u = createTestUtils({ app, page, context }); await u.po.page.goToRelative('/billing/plan-details-btn'); @@ -83,9 +82,7 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withBilling] })('pricing tabl page, context, }) => { - if (!app.name.includes('next')) { - return; - } + test.skip(app.name.includes('astro'), 'Still working on it'); const u = createTestUtils({ app, page, context }); await u.po.signIn.goTo(); await u.po.signIn.signInWithEmailAndInstantPassword({ email: fakeUser.email, password: fakeUser.password }); @@ -100,9 +97,7 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withBilling] })('pricing tabl }); test('when signed in, clicking checkout button open checkout drawer', async ({ page, context }) => { - if (!app.name.includes('next')) { - return; - } + test.skip(app.name.includes('astro'), 'Still working on it'); const u = createTestUtils({ app, page, context }); await u.po.signIn.goTo(); await u.po.signIn.signInWithEmailAndInstantPassword({ email: fakeUser.email, password: fakeUser.password }); @@ -137,9 +132,7 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withBilling] })('pricing tabl }); test('opens subscription details drawer', async ({ page, context }) => { - if (!app.name.includes('next')) { - return; - } + test.skip(app.name.includes('astro'), 'Still working on it'); const u = createTestUtils({ app, page, context }); await u.po.signIn.goTo(); await u.po.signIn.signInWithEmailAndInstantPassword({ email: fakeUser.email, password: fakeUser.password }); diff --git a/packages/vue/package.json b/packages/vue/package.json index 7409c069246..05295f89542 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -30,6 +30,10 @@ "types": "./dist/index.d.ts", "default": "./dist/index.js" }, + "./experimental": { + "types": "./dist/experimental.d.ts", + "default": "./dist/experimental.js" + }, "./internal": { "types": "./dist/internal.d.ts", "default": "./dist/internal.js" diff --git a/packages/vue/src/components/CheckoutButton.vue b/packages/vue/src/components/CheckoutButton.vue new file mode 100644 index 00000000000..c056d943c4e --- /dev/null +++ b/packages/vue/src/components/CheckoutButton.vue @@ -0,0 +1,53 @@ + + + diff --git a/packages/vue/src/components/PlanDetailsButton.vue b/packages/vue/src/components/PlanDetailsButton.vue new file mode 100644 index 00000000000..ba094c41412 --- /dev/null +++ b/packages/vue/src/components/PlanDetailsButton.vue @@ -0,0 +1,40 @@ + + + diff --git a/packages/vue/src/components/SubscriptionDetailsButton.vue b/packages/vue/src/components/SubscriptionDetailsButton.vue new file mode 100644 index 00000000000..5dec21240ac --- /dev/null +++ b/packages/vue/src/components/SubscriptionDetailsButton.vue @@ -0,0 +1,50 @@ + + + diff --git a/packages/vue/src/experimental.ts b/packages/vue/src/experimental.ts new file mode 100644 index 00000000000..18816459452 --- /dev/null +++ b/packages/vue/src/experimental.ts @@ -0,0 +1,41 @@ +/** + * @experimental + * These components and their prop types are unstable and may change in future releases. + * They are part of Clerk's Billing feature which is available under public beta. + */ +export { default as SubscriptionDetailsButton } from './components/SubscriptionDetailsButton.vue'; + +/** + * @experimental + * These components and their prop types are unstable and may change in future releases. + * They are part of Clerk's Billing feature which is available under public beta. + */ +export { default as CheckoutButton } from './components/CheckoutButton.vue'; + +/** + * @experimental + * These components and their prop types are unstable and may change in future releases. + * They are part of Clerk's Billing feature which is available under public beta. + */ +export { default as PlanDetailsButton } from './components/PlanDetailsButton.vue'; + +export type { + /** + * @experimental + * These components and their prop types are unstable and may change in future releases. + * They are part of Clerk's Billing feature which is available under public beta. + */ + __experimental_SubscriptionDetailsButtonProps as SubscriptionDetailsButtonProps, + /** + * @experimental + * These components and their prop types are unstable and may change in future releases. + * They are part of Clerk's Billing feature which is available under public beta. + */ + __experimental_CheckoutButtonProps as CheckoutButtonProps, + /** + * @experimental + * These components and their prop types are unstable and may change in future releases. + * They are part of Clerk's Billing feature which is available under public beta. + */ + __experimental_PlanDetailsButtonProps as PlanDetailsButtonProps, +} from '@clerk/types'; diff --git a/packages/vue/src/utils/childrenUtils.ts b/packages/vue/src/utils/childrenUtils.ts index 55b76b61c14..9cacf87b0db 100644 --- a/packages/vue/src/utils/childrenUtils.ts +++ b/packages/vue/src/utils/childrenUtils.ts @@ -3,7 +3,14 @@ import { h, Text, type VNode } from 'vue'; import { errorThrower } from '../errors/errorThrower'; import { multipleChildrenInButtonComponent } from '../errors/messages'; -type ButtonName = 'SignInButton' | 'SignUpButton' | 'SignOutButton' | 'SignInWithMetamaskButton'; +type ButtonName = + | 'SignInButton' + | 'SignUpButton' + | 'SignOutButton' + | 'SignInWithMetamaskButton' + | 'SubscriptionDetailsButton' + | 'CheckoutButton' + | 'PlanDetailsButton'; export const normalizeWithDefaultValue = (slotContent: VNode[] | undefined, defaultValue: string) => { // Render a button with the default value if no slot content is provided diff --git a/packages/vue/tsup.config.ts b/packages/vue/tsup.config.ts index c5c1a246a46..fe7ddaac46c 100644 --- a/packages/vue/tsup.config.ts +++ b/packages/vue/tsup.config.ts @@ -9,7 +9,7 @@ type EsbuildPlugin = NonNullable[number]; export default defineConfig(() => { return { clean: true, - entry: ['./src/index.ts', './src/internal.ts', './src/errors.ts'], + entry: ['./src/index.ts', './src/experimental.ts', './src/internal.ts', './src/errors.ts'], format: ['esm'], bundle: true, sourcemap: true, @@ -17,13 +17,13 @@ export default defineConfig(() => { dts: false, esbuildPlugins: [ // Adds .vue files support - vuePlugin() as EsbuildPlugin, + vuePlugin(), // Automatically generates runtime props from TypeScript types/interfaces for all // control and UI components, adding them to Vue components during build via // Object.defineProperty autoPropsPlugin({ include: ['**/*.ts'], - }) as EsbuildPlugin, + }), ], define: { PACKAGE_NAME: `"${name}"`,