diff --git a/.changeset/long-owls-yawn.md b/.changeset/long-owls-yawn.md new file mode 100644 index 00000000000..a845151cc84 --- /dev/null +++ b/.changeset/long-owls-yawn.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/nice-apes-vanish.md b/.changeset/nice-apes-vanish.md new file mode 100644 index 00000000000..9883f3f7cfb --- /dev/null +++ b/.changeset/nice-apes-vanish.md @@ -0,0 +1,5 @@ +--- +'@clerk/types': minor +--- + +[Billing Beta] Remove CommerceProduct. diff --git a/.typedoc/__tests__/__snapshots__/file-structure.test.ts.snap b/.typedoc/__tests__/__snapshots__/file-structure.test.ts.snap index 2202b67a81c..d91b3a1c8b0 100644 --- a/.typedoc/__tests__/__snapshots__/file-structure.test.ts.snap +++ b/.typedoc/__tests__/__snapshots__/file-structure.test.ts.snap @@ -45,8 +45,6 @@ exports[`Typedoc output > should have a deliberate file structure 1`] = ` "types/commerce-payment-status.mdx", "types/commerce-plan-json.mdx", "types/commerce-plan-resource.mdx", - "types/commerce-product-json.mdx", - "types/commerce-product-resource.mdx", "types/commerce-statement-group-json.mdx", "types/commerce-statement-group.mdx", "types/commerce-statement-json.mdx", diff --git a/packages/clerk-js/src/core/resources/CommerceProduct.ts b/packages/clerk-js/src/core/resources/CommerceProduct.ts deleted file mode 100644 index d36da43bf18..00000000000 --- a/packages/clerk-js/src/core/resources/CommerceProduct.ts +++ /dev/null @@ -1,30 +0,0 @@ -import type { CommerceProductJSON, CommerceProductResource } from '@clerk/types'; - -import { BaseResource, CommercePlan } from './internal'; - -export class CommerceProduct extends BaseResource implements CommerceProductResource { - id!: string; - slug!: string; - currency!: string; - isDefault!: boolean; - plans!: CommercePlan[]; - - constructor(data: CommerceProductJSON) { - super(); - this.fromJSON(data); - } - - protected fromJSON(data: CommerceProductJSON | null): this { - if (!data) { - return this; - } - - this.id = data.id; - this.slug = data.slug; - this.currency = data.currency; - this.isDefault = data.is_default; - this.plans = data.plans.map(plan => new CommercePlan(plan)); - - return this; - } -} diff --git a/packages/clerk-js/src/core/resources/internal.ts b/packages/clerk-js/src/core/resources/internal.ts index 15655efc2f3..d668bae4768 100644 --- a/packages/clerk-js/src/core/resources/internal.ts +++ b/packages/clerk-js/src/core/resources/internal.ts @@ -10,7 +10,6 @@ export * from './CommerceStatement'; export * from './CommercePayment'; export * from './CommercePaymentSource'; export * from './CommercePlan'; -export * from './CommerceProduct'; export * from './CommerceSubscription'; export * from './DeletedObject'; export * from './DisplayConfig'; diff --git a/packages/clerk-js/src/ui/common/BlockButtons.tsx b/packages/clerk-js/src/ui/common/BlockButtons.tsx deleted file mode 100644 index 1275f59b3b4..00000000000 --- a/packages/clerk-js/src/ui/common/BlockButtons.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { descriptors, Icon } from '../customizables'; -import { ArrowBlockButton } from '../elements/ArrowBlockButton'; -import { Plus } from '../icons'; -import type { PropsOfComponent } from '../styledSystem'; - -type BlockButtonProps = PropsOfComponent; - -export const BlockButton = (props: BlockButtonProps) => { - const { id, ...rest } = props; - return ( - - ); -}; - -export const AddBlockButton = (props: BlockButtonProps) => { - const { leftIcon, ...rest } = props; - return ( - ({ justifyContent: 'flex-start', gap: theme.space.$2 })} - leftIcon={ - ({ - width: theme.sizes.$2x5, - height: theme.sizes.$2x5, - })} - /> - } - > - {props.children} - - ); -}; diff --git a/packages/clerk-js/src/ui/common/index.ts b/packages/clerk-js/src/ui/common/index.ts index bea7cf9e442..e1a892faa43 100644 --- a/packages/clerk-js/src/ui/common/index.ts +++ b/packages/clerk-js/src/ui/common/index.ts @@ -1,4 +1,3 @@ -export * from './BlockButtons'; export * from './CalloutWithAction'; export * from './constants'; export * from './EmailLinkStatusCard'; diff --git a/packages/clerk-js/src/ui/components/UserProfile/UserProfileBlockButtons.tsx b/packages/clerk-js/src/ui/components/UserProfile/UserProfileBlockButtons.tsx deleted file mode 100644 index 37ef9b97279..00000000000 --- a/packages/clerk-js/src/ui/components/UserProfile/UserProfileBlockButtons.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from '../../common/BlockButtons'; diff --git a/packages/clerk-js/src/ui/elements/AvatarUploader.tsx b/packages/clerk-js/src/ui/elements/AvatarUploader.tsx index 4f1fa9a3eed..b2d54600c4a 100644 --- a/packages/clerk-js/src/ui/elements/AvatarUploader.tsx +++ b/packages/clerk-js/src/ui/elements/AvatarUploader.tsx @@ -13,7 +13,7 @@ export type AvatarUploaderProps = { avatarPreviewPlaceholder?: React.ReactElement | null; }; -export const fileToBase64 = (file: File): Promise => { +const fileToBase64 = (file: File): Promise => { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(file); diff --git a/packages/clerk-js/src/ui/elements/BlockWithTrailingComponent.tsx b/packages/clerk-js/src/ui/elements/BlockWithTrailingComponent.tsx deleted file mode 100644 index 027a431071b..00000000000 --- a/packages/clerk-js/src/ui/elements/BlockWithTrailingComponent.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import React from 'react'; - -import type { LocalizationKey } from '../customizables'; -import { Box, Flex, Text } from '../customizables'; -import type { ElementDescriptor, ElementId } from '../customizables/elementDescriptors'; -import type { PropsOfComponent } from '../styledSystem'; - -type BlockWithTrailingComponentProps = PropsOfComponent & { - badge?: React.ReactElement; - trailingComponent?: React.ReactElement; - textElementDescriptor?: ElementDescriptor; - textElementId?: ElementId; - textLocalizationKey?: LocalizationKey; -}; - -export const BlockWithTrailingComponent = (props: BlockWithTrailingComponentProps) => { - const { - isLoading, - children, - trailingComponent, - textElementDescriptor, - textElementId, - textLocalizationKey, - badge, - ...rest - } = props; - - return ( - [ - { - borderRadius: theme.radii.$md, - display: 'inline-flex', - alignItems: 'center', - gap: theme.space.$4, - position: 'relative', - justifyContent: 'flex-start', - borderColor: theme.colors.$borderAlpha200, - }, - props.sx, - ]} - > - - - {children} - - {badge} - - {trailingComponent} - - ); -}; diff --git a/packages/clerk-js/src/ui/elements/Disclosure.tsx b/packages/clerk-js/src/ui/elements/Disclosure.tsx deleted file mode 100644 index ad88e6b8130..00000000000 --- a/packages/clerk-js/src/ui/elements/Disclosure.tsx +++ /dev/null @@ -1,190 +0,0 @@ -import * as React from 'react'; - -import type { LocalizationKey } from '../customizables'; -import { Box, descriptors, Icon, SimpleButton, Span, useAppearance } from '../customizables'; -import { usePrefersReducedMotion } from '../hooks'; -import { ChevronDown } from '../icons'; -import type { ThemableCssProp } from '../styledSystem'; -import { common } from '../styledSystem'; -import { colors } from '../utils/colors'; - -/* ------------------------------------------------------------------------------------------------- - * Disclosure Context - * -----------------------------------------------------------------------------------------------*/ - -interface DisclosureContextValue { - isOpen: boolean; - onToggle: () => void; - id: string; -} - -const DisclosureContext = React.createContext(undefined); - -/* ------------------------------------------------------------------------------------------------- - * Disclosure.Root - * -----------------------------------------------------------------------------------------------*/ - -interface RootProps { - children: React.ReactNode; - defaultOpen?: boolean; - open?: boolean; - onOpenChange?: (open: boolean) => void; -} - -const Root = React.forwardRef( - ({ children, defaultOpen = false, open: controlledOpen, onOpenChange }, ref) => { - const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen); - const isControlled = controlledOpen !== undefined; - const isOpen = isControlled ? controlledOpen : uncontrolledOpen; - const id = React.useId(); - - const onToggle = React.useCallback(() => { - if (isControlled) { - onOpenChange?.(!isOpen); - } else { - setUncontrolledOpen(!isOpen); - } - }, [isControlled, isOpen, onOpenChange]); - - return ( - - ({ - width: '100%', - borderRadius: t.radii.$lg, - boxShadow: `inset 0 0 0 1px ${t.colors.$borderAlpha100}`, - backgroundColor: t.colors.$colorBackground, - isolation: 'isolate', - })} - > - {children} - - - ); - }, -); - -Root.displayName = 'Disclosure.Root'; - -/* ------------------------------------------------------------------------------------------------- - * Disclosure.Trigger - * -----------------------------------------------------------------------------------------------*/ - -interface TriggerProps { - text: string | LocalizationKey; -} - -const Trigger = React.forwardRef(({ text }, ref) => { - const context = React.useContext(DisclosureContext); - if (!context) { - throw new Error('Disclosure.Trigger must be used within Disclosure.Root'); - } - - return ( - ({ - width: '100%', - fontSize: t.fontSizes.$md, - justifyContent: 'space-between', - padding: t.sizes.$3, - color: t.colors.$colorForeground, - borderRadius: t.radii.$lg, - zIndex: 2, - })} - > - - - - ); -}); - -Trigger.displayName = 'Disclosure.Trigger'; - -/* ------------------------------------------------------------------------------------------------- - * Disclosure.Content - * -----------------------------------------------------------------------------------------------*/ - -interface ContentProps { - children: React.ReactNode; -} - -const Content = React.forwardRef(({ children }, ref) => { - const context = React.useContext(DisclosureContext); - const prefersReducedMotion = usePrefersReducedMotion(); - const { animations: layoutAnimations } = useAppearance().parsedLayout; - if (!context) { - throw new Error('Disclosure.Content must be used within Disclosure.Root'); - } - const { isOpen, id } = context; - const isMotionSafe = !prefersReducedMotion && layoutAnimations === true; - const animation: ThemableCssProp = t => ({ - transition: isMotionSafe - ? `grid-template-rows ${t.transitionDuration.$slower} ${t.transitionTiming.$slowBezier}` - : 'none', - }); - - return ( - ({ - display: 'grid', - gridTemplateRows: isOpen ? '1fr' : '0fr', - zIndex: 1, - }), - animation, - ]} - // @ts-ignore - Needed until React 19 support - inert={isOpen ? undefined : 'true'} - > - - ({ - padding: t.space.$3, - borderRadius: t.radii.$lg, - borderWidth: t.borderWidths.$normal, - borderStyle: t.borderStyles.$solid, - borderColor: t.colors.$borderAlpha100, - background: common.mergedColorsBackground( - colors.setAlpha(t.colors.$colorBackground, 1), - t.colors.$neutralAlpha50, - ), - })} - > - {children} - - - - ); -}); - -Content.displayName = 'Disclosure.Content'; - -export const Disclosure = { - Root, - Trigger, - Content, -}; diff --git a/packages/clerk-js/src/ui/elements/FormControl.tsx b/packages/clerk-js/src/ui/elements/FormControl.tsx index cb9e107b7ff..83ff6826dd5 100644 --- a/packages/clerk-js/src/ui/elements/FormControl.tsx +++ b/packages/clerk-js/src/ui/elements/FormControl.tsx @@ -17,7 +17,7 @@ import type { ThemableCssProp } from '../styledSystem'; import { animations } from '../styledSystem'; import type { FeedbackType, useFormControlFeedback } from '../utils/useFormControl'; -export function useFormTextAnimation() { +function useFormTextAnimation() { const prefersReducedMotion = usePrefersReducedMotion(); const { animations: appearanceAnimations } = useAppearance().parsedLayout; @@ -48,7 +48,7 @@ export function useFormTextAnimation() { }; } -export const useCalculateErrorTextHeight = ({ feedback }: { feedback: string }) => { +const useCalculateErrorTextHeight = ({ feedback }: { feedback: string }) => { const [height, setHeight] = useState(0); const calculateHeight = useCallback( diff --git a/packages/clerk-js/src/ui/elements/NavigateToFlowStartButton.tsx b/packages/clerk-js/src/ui/elements/NavigateToFlowStartButton.tsx deleted file mode 100644 index 3bd0fa85845..00000000000 --- a/packages/clerk-js/src/ui/elements/NavigateToFlowStartButton.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { Button } from '../customizables'; -import { useNavigateToFlowStart } from '../hooks'; -import type { PropsOfComponent } from '../styledSystem'; - -type NavigateToFlowStartButtonProps = PropsOfComponent; - -export const NavigateToFlowStartButton = (props: NavigateToFlowStartButtonProps) => { - const { navigateToFlowStart } = useNavigateToFlowStart(); - return ( - - ); -}; diff --git a/packages/clerk-js/src/ui/hooks/index.ts b/packages/clerk-js/src/ui/hooks/index.ts index 1e2606a873a..b456a3dd943 100644 --- a/packages/clerk-js/src/ui/hooks/index.ts +++ b/packages/clerk-js/src/ui/hooks/index.ts @@ -1,7 +1,6 @@ export * from './useClerkModalStateParams'; export * from './useClipboard'; export * from './useDebounce'; -export * from './useDelayedVisibility'; export * from './useDirection'; export * from './useEmailLink'; export * from './useEnabledThirdPartyProviders'; @@ -14,7 +13,6 @@ export * from './usePassword'; export * from './usePasswordComplexity'; export * from './usePopover'; export * from './usePrefersReducedMotion'; -export * from './useResizeObserver'; export * from './useSafeState'; export * from './useScrollLock'; export * from './useSearchInput'; diff --git a/packages/clerk-js/src/ui/hooks/useDelayedVisibility.ts b/packages/clerk-js/src/ui/hooks/useDelayedVisibility.ts deleted file mode 100644 index 62713780bd3..00000000000 --- a/packages/clerk-js/src/ui/hooks/useDelayedVisibility.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { useEffect, useState } from 'react'; - -/** - * Utility hook for delaying mounting of components for enter and exit animations. - * Delays to update the state when is switched from/to undefined. - * Immediate change for in-between changes - */ -export function useDelayedVisibility(valueToDelay: T, delayInMs: number) { - const [isVisible, setVisible] = useState(undefined); - - useEffect(() => { - let timeoutId: ReturnType; - - if (valueToDelay && !isVisible) { - // First time that valueToDelay has truthy value means we want to display it - timeoutId = setTimeout(() => setVisible(valueToDelay), delayInMs); - } else if (!valueToDelay && isVisible) { - // valueToDelay has already a truthy value and becomes falsy means we want to hide it - timeoutId = setTimeout(() => setVisible(undefined), delayInMs); - } else { - // it is already displayed, and we want immediate updates to that value - setVisible(valueToDelay); - } - return () => clearTimeout(timeoutId); - }, [valueToDelay, delayInMs, isVisible]); - - return isVisible; -} - -export function useFieldMessageVisibility(fieldMessage: T, delayInMs: number) { - return useDelayedVisibility(fieldMessage, delayInMs); -} diff --git a/packages/clerk-js/src/ui/hooks/useFetch.ts b/packages/clerk-js/src/ui/hooks/useFetch.ts index ab4a957813e..7abe9207c49 100644 --- a/packages/clerk-js/src/ui/hooks/useFetch.ts +++ b/packages/clerk-js/src/ui/hooks/useFetch.ts @@ -33,7 +33,7 @@ export const clearFetchCache = () => { const serialize = (key: unknown) => (typeof key === 'string' ? key : JSON.stringify(key)); -export const useCache = ( +const useCache = ( key: K, serializer = serialize, ): { diff --git a/packages/clerk-js/src/ui/hooks/useResizeObserver.ts b/packages/clerk-js/src/ui/hooks/useResizeObserver.ts deleted file mode 100644 index f861ea78e52..00000000000 --- a/packages/clerk-js/src/ui/hooks/useResizeObserver.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { useEffect, useMemo, useRef, useState } from 'react'; - -type ObserverRect = Omit; - -export function useResizeObserver() { - const frameID = useRef(0); - const ref = useRef(null); - - const [rect, setRect] = useState({ - x: 0, - y: 0, - width: 0, - height: 0, - top: 0, - left: 0, - bottom: 0, - right: 0, - }); - - const observer = useMemo( - () => - typeof window !== 'undefined' - ? new ResizeObserver((entries: any) => { - const entry = entries[0]; - - if (entry) { - cancelAnimationFrame(frameID.current); - - frameID.current = requestAnimationFrame(() => { - if (ref.current) { - setRect(ref.current.getBoundingClientRect()); - } - }); - } - }) - : null, - [], - ); - - useEffect(() => { - if (ref.current) { - observer?.observe(ref.current); - } - - return () => { - observer?.disconnect(); - - if (frameID.current) { - cancelAnimationFrame(frameID.current); - } - }; - - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [ref.current]); - - return [ref, rect] as const; -} diff --git a/packages/clerk-js/src/ui/hooks/useScrollLock.ts b/packages/clerk-js/src/ui/hooks/useScrollLock.ts index 3b3549380fc..0c637d32c7f 100644 --- a/packages/clerk-js/src/ui/hooks/useScrollLock.ts +++ b/packages/clerk-js/src/ui/hooks/useScrollLock.ts @@ -3,7 +3,7 @@ // Copyright (c) Floating UI contributors // SPDX-License-Identifier: MIT // Avoid Chrome DevTools blue warning. -export function getPlatform(): string { +function getPlatform(): string { const uaData = (navigator as any).userAgentData as { platform: string } | undefined; if (uaData?.platform) { diff --git a/packages/clerk-js/src/utils/componentGuards.ts b/packages/clerk-js/src/utils/componentGuards.ts index afdb2d476b0..a6491c1f3b1 100644 --- a/packages/clerk-js/src/utils/componentGuards.ts +++ b/packages/clerk-js/src/utils/componentGuards.ts @@ -34,14 +34,6 @@ export const disabledAllBillingFeatures: ComponentGuard = (_, environment) => { return disabledUserBillingFeature(_, environment) && disabledOrganizationBillingFeature(_, environment); }; -export const hasPaidOrgPlans: ComponentGuard = (_, environment) => { - return environment?.commerceSettings.billing.organization.hasPaidPlans || false; -}; - -export const hasPaidUserPlans: ComponentGuard = (_, environment) => { - return environment?.commerceSettings.billing.user.hasPaidPlans || false; -}; - export const disabledAPIKeysFeature: ComponentGuard = (_, environment) => { return !environment?.apiKeysSettings?.enabled; }; diff --git a/packages/clerk-js/src/utils/passwords/strength.ts b/packages/clerk-js/src/utils/passwords/strength.ts index 737fcbcb697..083a99c022f 100644 --- a/packages/clerk-js/src/utils/passwords/strength.ts +++ b/packages/clerk-js/src/utils/passwords/strength.ts @@ -2,7 +2,7 @@ import type { PasswordSettingsData, ZxcvbnResult } from '@clerk/types'; import type { zxcvbnFN } from '../zxcvbn'; -export type PasswordStrength = +type PasswordStrength = | { state: 'excellent'; result: ZxcvbnResult; diff --git a/packages/clerk-js/src/utils/runtime.ts b/packages/clerk-js/src/utils/runtime.ts index 34a53ff2dcb..f8b0b18bfc0 100644 --- a/packages/clerk-js/src/utils/runtime.ts +++ b/packages/clerk-js/src/utils/runtime.ts @@ -6,10 +6,6 @@ export function inActiveBrowserTab() { return inBrowser() && globalThis.document.hasFocus(); } -export function usesHttps() { - return inBrowser() && window.location.protocol === 'https:'; -} - export function inIframe() { if (!inBrowser()) return false; @@ -27,7 +23,3 @@ export function inCrossOriginIframe() { // frameElement: if the document into which it's embedded has a different origin, the value is null instead. return inIframe() && !window.frameElement; } - -export function inSecureCrossOriginIframe() { - return inCrossOriginIframe() && usesHttps(); -} diff --git a/packages/clerk-js/src/utils/url.ts b/packages/clerk-js/src/utils/url.ts index afb29279331..38949715511 100644 --- a/packages/clerk-js/src/utils/url.ts +++ b/packages/clerk-js/src/utils/url.ts @@ -202,11 +202,6 @@ export const trimLeadingSlash = (path: string): string => { return (path || '').replace(/^\/+/, ''); }; -export const stripSameOrigin = (url: URL, baseUrl: URL): string => { - const sameOrigin = baseUrl.origin === url.origin; - return sameOrigin ? stripOrigin(url) : `${url}`; -}; - export const hasExternalAccountSignUpError = (signUp: SignUpResource): boolean => { const { externalAccount } = signUp.verifications; return !!externalAccount.error; diff --git a/packages/types/src/commerce.ts b/packages/types/src/commerce.ts index 104105dd861..0495f9dd135 100644 --- a/packages/types/src/commerce.ts +++ b/packages/types/src/commerce.ts @@ -192,54 +192,6 @@ export interface CommercePaymentSourceMethods { ) => Promise>; } -/** - * @experimental This is an experimental API for the Billing feature that is available under a public beta, and the API is subject to change. - * It is advised to pin the SDK version and the clerk-js version to a specific version to avoid breaking changes. - * @example - * ```tsx - * - * ``` - */ -export interface CommerceProductResource extends ClerkResource { - id: string; - /** - * @experimental This is an experimental API for the Billing feature that is available under a public beta, and the API is subject to change. - * It is advised to pin the SDK version and the clerk-js version to a specific version to avoid breaking changes. - * @example - * ```tsx - * - * ``` - */ - slug: string | null; - /** - * @experimental This is an experimental API for the Billing feature that is available under a public beta, and the API is subject to change. - * It is advised to pin the SDK version and the clerk-js version to a specific version to avoid breaking changes. - * @example - * ```tsx - * - * ``` - */ - currency: string; - /** - * @experimental This is an experimental API for the Billing feature that is available under a public beta, and the API is subject to change. - * It is advised to pin the SDK version and the clerk-js version to a specific version to avoid breaking changes. - * @example - * ```tsx - * - * ``` - */ - isDefault: boolean; - /** - * @experimental This is an experimental API for the Billing feature that is available under a public beta, and the API is subject to change. - * It is advised to pin the SDK version and the clerk-js version to a specific version to avoid breaking changes. - * @example - * ```tsx - * - * ``` - */ - plans: CommercePlanResource[]; -} - /** * @experimental This is an experimental API for the Billing feature that is available under a public beta, and the API is subject to change. * It is advised to pin the SDK version and the clerk-js version to a specific version to avoid breaking changes. diff --git a/packages/types/src/json.ts b/packages/types/src/json.ts index 29fa042ab7e..d34c0a0b8f7 100644 --- a/packages/types/src/json.ts +++ b/packages/types/src/json.ts @@ -658,23 +658,6 @@ export interface CommercePlanJSON extends ClerkResourceJSON { free_trial_enabled?: boolean; } -/** - * @experimental This is an experimental API for the Billing feature that is available under a public beta, and the API is subject to change. - * It is advised to pin the SDK version and the clerk-js version to a specific version to avoid breaking changes. - * @example - * ```tsx - * - * ``` - */ -export interface CommerceProductJSON extends ClerkResourceJSON { - object: 'commerce_product'; - id: string; - slug: string; - currency: string; - is_default: boolean; - plans: CommercePlanJSON[]; -} - /** * @experimental This is an experimental API for the Billing feature that is available under a public beta, and the API is subject to change. * It is advised to pin the SDK version and the clerk-js version to a specific version to avoid breaking changes.