Payment.utils.ts84 lines · main
| 1 | import type { Appearance, CustomFontSource } from '@stripe/stripe-js' |
| 2 | |
| 3 | import { CUSTOM_FONT_BOOK_DATA_URL } from '@/fonts/stripe-fonts' |
| 4 | |
| 5 | /** |
| 6 | * Custom font for Stripe Elements iframes. |
| 7 | * Stripe renders inside an iframe that can't access the parent page's CSS variables or fonts, |
| 8 | * so we pass the font explicitly (Stripe requires https:// or data:// sources). |
| 9 | * Keep using the data URL in all environments for now, since the CDN-hosted font still has |
| 10 | * CORS issues when Stripe loads it from inside its iframe. |
| 11 | */ |
| 12 | const fontSrc = `url(${CUSTOM_FONT_BOOK_DATA_URL})` |
| 13 | |
| 14 | export const STRIPE_ELEMENT_FONTS: CustomFontSource[] = [ |
| 15 | { |
| 16 | family: 'CustomFont', |
| 17 | src: fontSrc, |
| 18 | }, |
| 19 | ] |
| 20 | |
| 21 | export const getStripeElementsAppearanceOptions = ( |
| 22 | resolvedTheme: string | undefined |
| 23 | ): Appearance => { |
| 24 | return { |
| 25 | labels: 'floating', |
| 26 | theme: (resolvedTheme?.includes('dark') ? 'night' : 'flat') as 'night' | 'flat', |
| 27 | variables: { |
| 28 | fontSizeBase: '14px', |
| 29 | colorBackground: resolvedTheme?.includes('dark') |
| 30 | ? 'hsl(0deg 0% 14.1%)' |
| 31 | : 'hsl(0deg 0% 95.3%)', |
| 32 | fontFamily: 'CustomFont, Helvetica Neue, Helvetica, Arial, sans-serif', |
| 33 | }, |
| 34 | rules: { |
| 35 | '.TermsText': { |
| 36 | fontSize: '12px', |
| 37 | }, |
| 38 | '.Label--floating': { |
| 39 | fontSize: '14px', |
| 40 | }, |
| 41 | '.Label--resting': { |
| 42 | fontSize: '14px', |
| 43 | color: 'rgb(137, 137, 137)', |
| 44 | }, |
| 45 | '.Input': { |
| 46 | boxShadow: 'none', |
| 47 | height: '34px', |
| 48 | lineHeight: '16px', |
| 49 | padding: '8px 12px', |
| 50 | }, |
| 51 | '.AccordionItem': { |
| 52 | boxShadow: 'none', |
| 53 | }, |
| 54 | }, |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | export const getAddressElementAppearanceOptions = ( |
| 59 | resolvedTheme: string | undefined |
| 60 | ): Appearance => { |
| 61 | const isDark = resolvedTheme?.includes('dark') |
| 62 | |
| 63 | return { |
| 64 | labels: 'above' as const, |
| 65 | theme: (isDark ? 'night' : 'flat') as 'night' | 'flat', |
| 66 | variables: { |
| 67 | fontSizeBase: '14px', |
| 68 | spacingUnit: '7px', |
| 69 | colorPrimary: isDark ? 'hsl(0deg 0% 32%)' : 'hsl(0deg 0% 55%)', |
| 70 | colorBackground: isDark ? 'hsl(0deg 0% 14.1%)' : 'hsl(0deg 0% 95.3%)', |
| 71 | borderRadius: '4px', |
| 72 | fontFamily: 'CustomFont, Helvetica Neue, Helvetica, Arial, sans-serif', |
| 73 | }, |
| 74 | rules: { |
| 75 | '.Input': { |
| 76 | boxShadow: isDark ? 'none' : 'inset 0 0 0 1px hsl(0deg 0% 80%)', |
| 77 | height: '34px', |
| 78 | lineHeight: '16px', |
| 79 | padding: '8px 12px', |
| 80 | borderWidth: '1px', |
| 81 | }, |
| 82 | }, |
| 83 | } |
| 84 | } |