@primer-io/primer-js 0.3.11 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -191,6 +191,7 @@ declare enum EventTypes {
191
191
  BLUR = "blur",
192
192
  CLICK = "click",
193
193
  CLOSE = "close",
194
+ ENTER = "enter",
194
195
  CONFIRMED_KLARNA_CATEGORY = "CONFIRMED_KLARNA_CATEGORY",
195
196
  CONFIRMED_KLARNA_CATEGORY_ERROR = "CONFIRMED_KLARNA_CATEGORY_ERROR",
196
197
  KLARNA_SESSION_UPDATE = "KLARNA_SESSION_UPDATE",
@@ -231,6 +232,9 @@ export interface ClientSessionAddress {
231
232
  countryCode?: string;
232
233
  postalCode?: string;
233
234
  }
235
+ export type NullableAddress = {
236
+ [K in keyof ClientSessionAddress]?: ClientSessionAddress[K] | null;
237
+ };
234
238
  export interface ClientSession {
235
239
  orderId?: string;
236
240
  currencyCode?: string;
@@ -313,7 +317,7 @@ export interface InputMetadata {
313
317
  touched: boolean;
314
318
  submitted: boolean;
315
319
  }
316
- export interface PaymentMethodConfig {
320
+ export interface PaymentMethodConfig<T = Record<string, unknown>> {
317
321
  id: string;
318
322
  type: PaymentMethodType;
319
323
  name: string;
@@ -326,9 +330,9 @@ export interface PaymentMethodConfig {
326
330
  light: string;
327
331
  };
328
332
  borderWidth: {
329
- colored: number;
330
- dark: number;
331
- light: number;
333
+ colored: number | string;
334
+ dark: number | string;
335
+ light: number | string;
332
336
  };
333
337
  cornerRadius: number;
334
338
  iconPositionRelativeToText?: "START" | "END";
@@ -348,7 +352,7 @@ export interface PaymentMethodConfig {
348
352
  height: number;
349
353
  };
350
354
  };
351
- options: {
355
+ options: T extends Record<string, unknown> ? T : {
352
356
  captureVaultedCardCvv?: boolean;
353
357
  clientId?: string;
354
358
  threeDSecureToken?: string;
@@ -653,6 +657,21 @@ export interface IAssetsManager {
653
657
  displayName?: string;
654
658
  } | null>;
655
659
  }
660
+ export interface CheckoutModuleConfig {
661
+ type: string;
662
+ options?: Record<string, unknown>;
663
+ }
664
+ export interface ClientConfiguration {
665
+ binDataUrl: string;
666
+ checkoutModules?: CheckoutModuleConfig[];
667
+ clientSession: ClientSession;
668
+ coreUrl: string;
669
+ env: string;
670
+ paymentMethods: PaymentMethodConfig[];
671
+ pciUrl: string;
672
+ primerAccountId: string;
673
+ settleOnAuth?: boolean;
674
+ }
656
675
  export interface HeadlessSDKUtilities {
657
676
  getCardNetworkAsset(network: string): {
658
677
  cardUrl: string;
@@ -674,6 +693,7 @@ export interface HeadlessSDKUtilities {
674
693
  goatCdnUrl: string;
675
694
  } | undefined>;
676
695
  getPaymentMethodConfiguration(paymentMethodType: PaymentMethodType): PaymentMethodConfig | undefined;
696
+ setBillingAddress(address: NullableAddress): Promise<void>;
677
697
  }
678
698
  export interface CardPaymentMethodManagerOptions {
679
699
  onCardMetadataChange?: (metadata: {
@@ -768,6 +788,7 @@ export interface PrimerHeadlessCheckout {
768
788
  getAssetsManager(): IAssetsManager;
769
789
  start: () => Promise<void>;
770
790
  refreshClientSession(): Promise<boolean>;
791
+ getConfiguration(): ClientConfiguration;
771
792
  teardown?: () => void;
772
793
  }
773
794
  export interface HeadlessUniversalCheckoutOptions {
@@ -1023,6 +1044,12 @@ export interface PrimerCheckoutOptions {
1023
1044
  */
1024
1045
  useBuiltInButton?: boolean;
1025
1046
  };
1047
+ /**
1048
+ * Enable SDK Core engine (recommended)
1049
+ *
1050
+ * @default true
1051
+ * @remarks Set to false to use legacy SDK engine
1052
+ */
1026
1053
  sdkCore?: boolean;
1027
1054
  disabledPayments?: boolean;
1028
1055
  }
@@ -1216,6 +1243,7 @@ declare class PrimerEventsController implements ReactiveController {
1216
1243
  export type AnalyticsContextType = AnalyticsUtils | null;
1217
1244
  export type EventsContextType = PrimerEventsController | null;
1218
1245
  export type HeadlessUtilsContextType = HeadlessSDKUtilities | null;
1246
+ export type ConfigurationContextType = ClientConfiguration | null;
1219
1247
  export type KlarnaCategoriesContextType = {
1220
1248
  categories: KlarnaPaymentMethodCategory[];
1221
1249
  isLoading: boolean;
@@ -1355,6 +1383,7 @@ declare class SDKContextController implements ReactiveController {
1355
1383
  private vaultManagerCvvProvider;
1356
1384
  private clientOptionsContext;
1357
1385
  private headlessUtilsProvider;
1386
+ private configurationProvider;
1358
1387
  private klarnaCategoriesProvider;
1359
1388
  private computedStylesProvider;
1360
1389
  private analyticsProvider;
@@ -1381,6 +1410,8 @@ declare class SDKContextController implements ReactiveController {
1381
1410
  setKlarnaCategories(value: KlarnaCategoriesContextType): void;
1382
1411
  setClientOptions(value: PrimerCheckoutOptions | null): void;
1383
1412
  setHeadlessUtils(value: HeadlessUtilsContextType): void;
1413
+ setConfiguration(value: ConfigurationContextType): void;
1414
+ getConfiguration(): ConfigurationContextType | undefined;
1384
1415
  setAnalyticsUtils(value: AnalyticsContextType): void;
1385
1416
  getAnalyticsUtils(): AnalyticsContextType | undefined;
1386
1417
  setComputedStyles(value: CSSStyleDeclaration): void;
@@ -1987,6 +2018,61 @@ declare global {
1987
2018
  "primer-input": InputComponent;
1988
2019
  }
1989
2020
  }
2021
+ export interface SelectOption {
2022
+ value: string;
2023
+ label: string;
2024
+ }
2025
+ /**
2026
+ * A native select dropdown component
2027
+ *
2028
+ * @element primer-select
2029
+ *
2030
+ * @fires change - Fired when selection changes
2031
+ * @fires input - Fired when input value changes
2032
+ * @fires focus - Fired when select receives focus
2033
+ * @fires blur - Fired when select loses focus
2034
+ */
2035
+ declare class SelectComponent extends LitElement {
2036
+ static styles: import("lit").CSSResult[];
2037
+ /**
2038
+ * The name attribute for the select element
2039
+ */
2040
+ name: string;
2041
+ /**
2042
+ * The id attribute for the select element
2043
+ */
2044
+ id: string;
2045
+ /**
2046
+ * The current value of the select
2047
+ */
2048
+ value: string;
2049
+ /**
2050
+ * Whether the select is disabled
2051
+ */
2052
+ disabled: boolean;
2053
+ /**
2054
+ * Whether the select is in an error state
2055
+ */
2056
+ hasError: boolean;
2057
+ /**
2058
+ * Placeholder text for the select
2059
+ */
2060
+ placeholder: string;
2061
+ /**
2062
+ * Array of options for the select
2063
+ */
2064
+ options: SelectOption[];
2065
+ private handleChange;
2066
+ private handleFocus;
2067
+ private handleBlur;
2068
+ private renderSelectOptions;
2069
+ render(): import("lit-html").TemplateResult<1>;
2070
+ }
2071
+ declare global {
2072
+ interface HTMLElementTagNameMap {
2073
+ "primer-select": SelectComponent;
2074
+ }
2075
+ }
1990
2076
  /**
1991
2077
  * Event detail interface for expanded-changed event
1992
2078
  */
@@ -2191,6 +2277,86 @@ declare global {
2191
2277
  }
2192
2278
  }
2193
2279
  export type PaymentMethodsContextType = InitializedPayments | null;
2280
+ /**
2281
+ * Google Pay component with shadow root rendering for full-width button support.
2282
+ *
2283
+ * Google Pay requires special rendering logic:
2284
+ * - Renders directly to shadow root (not button container)
2285
+ * - Does NOT render .native-button-container div
2286
+ * - Passes shadowRoot: true in render options
2287
+ * - Requires retry logic for async button rendering
2288
+ */
2289
+ declare class GooglePayComponent extends LitElement {
2290
+ static styles: import("lit").CSSResult[];
2291
+ paymentMethod: InitializedPaymentMethod | undefined;
2292
+ paymentManagers: InitializedManagersMap;
2293
+ disabled: boolean;
2294
+ private loadManagerTask;
2295
+ private renderButtonTask;
2296
+ constructor();
2297
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
2298
+ protected updated(changedProperties: PropertyValues): void;
2299
+ render(): symbol;
2300
+ }
2301
+ declare global {
2302
+ interface HTMLElementTagNameMap {
2303
+ "primer-google-pay": GooglePayComponent;
2304
+ }
2305
+ }
2306
+ /**
2307
+ * Apple Pay component with standard button container rendering.
2308
+ *
2309
+ * Apple Pay uses the standard button container approach:
2310
+ * - Renders to a button container div (not shadow root)
2311
+ * - Passes buttonHeight in render options
2312
+ * - Uses updateOverlayForContainer for disabled state
2313
+ * - Simpler than Google Pay's shadow root approach
2314
+ */
2315
+ declare class ApplePayComponent extends LitElement {
2316
+ static styles: import("lit").CSSResult[];
2317
+ paymentMethod: InitializedPaymentMethod | undefined;
2318
+ paymentManagers: InitializedManagersMap;
2319
+ disabled: boolean;
2320
+ private buttonContainerRef;
2321
+ private loadManagerTask;
2322
+ private renderButtonTask;
2323
+ constructor();
2324
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
2325
+ protected updated(changedProperties: PropertyValues): void;
2326
+ render(): import("lit-html").TemplateResult<1>;
2327
+ }
2328
+ declare global {
2329
+ interface HTMLElementTagNameMap {
2330
+ "primer-apple-pay": ApplePayComponent;
2331
+ }
2332
+ }
2333
+ /**
2334
+ * PayPal component with standard button container rendering.
2335
+ *
2336
+ * PayPal uses the standard button container approach:
2337
+ * - Renders to a button container div (not shadow root)
2338
+ * - Passes buttonHeight in render options with PayPal SDK constraints (25-55px)
2339
+ * - Uses updateOverlayForContainer for disabled state
2340
+ * - Warns if height exceeds maximum allowed by PayPal SDK
2341
+ */
2342
+ declare class PayPalComponent extends LitElement {
2343
+ static styles: import("lit").CSSResult[];
2344
+ paymentMethod: InitializedPaymentMethod | undefined;
2345
+ paymentManagers: InitializedManagersMap;
2346
+ disabled: boolean;
2347
+ private buttonContainerRef;
2348
+ private loadManagerTask;
2349
+ private renderButtonTask;
2350
+ constructor();
2351
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
2352
+ protected updated(changedProperties: PropertyValues): void;
2353
+ render(): import("lit-html").TemplateResult<1>;
2354
+ }
2355
+ declare global {
2356
+ interface HTMLElementTagNameMap {
2357
+ "primer-paypal": PayPalComponent;
2358
+ }
2359
+ }
2194
2360
  declare class PaymentMethodComponent extends LitElement {
2195
2361
  static styles: import("lit").CSSResult[];
2196
2362
  type: PaymentMethodType | undefined;
@@ -2337,6 +2503,158 @@ declare global {
2337
2503
  "primer-redirect-payment": RedirectPaymentComponent;
2338
2504
  }
2339
2505
  }
2506
+ /**
2507
+ * BillingAddressComponent provides a form for collecting billing address information.
2508
+ *
2509
+ * Configuration is exclusively server-side via SDK Core's checkoutModules. Field visibility
2510
+ * is determined by the BILLING_ADDRESS module in the client session configuration.
2511
+ *
2512
+ * @element primer-billing-address
2513
+ *
2514
+ * @fires primer-billing-address-change - Fired when form data changes
2515
+ * @fires primer-billing-address-submit - Fired when form is submitted
2516
+ */
2517
+ declare class BillingAddressComponent extends LitElement {
2518
+ static styles: import("lit").CSSResult[];
2519
+ /**
2520
+ * Configuration from SDK Core containing checkoutModules configuration
2521
+ */
2522
+ configuration: ConfigurationContextType;
2523
+ /**
2524
+ * Headless SDK utilities for API methods like setBillingAddress
2525
+ */
2526
+ headlessUtils: HeadlessUtilsContextType;
2527
+ /**
2528
+ * Form data state
2529
+ */
2530
+ private formData;
2531
+ /**
2532
+ * Validation errors state
2533
+ */
2534
+ private errors;
2535
+ /**
2536
+ * Tracks which fields have been touched (blurred after focus)
2537
+ */
2538
+ private touchedFields;
2539
+ /**
2540
+ * Tracks which fields are dirty (have had input)
2541
+ */
2542
+ private dirtyFields;
2543
+ /**
2544
+ * Tracks which field is currently focused
2545
+ */
2546
+ private focusedField;
2547
+ /**
2548
+ * Tracks whether the form has been submitted
2549
+ * Errors only show after submit or after field blur
2550
+ */
2551
+ private submitted;
2552
+ /**
2553
+ * List of countries for the select dropdown
2554
+ * Initialize with empty array, will be populated in connectedCallback
2555
+ */
2556
+ private countryOptions;
2557
+ /**
2558
+ * Initialization task that waits for context availability
2559
+ *
2560
+ * Purpose: Ensures configuration and headlessUtils contexts are ready before
2561
+ * attempting field configuration extraction and country initialization
2562
+ *
2563
+ * Lifecycle:
2564
+ * - Task runs when this.configuration or this.headlessUtils changes
2565
+ * - Stays pending (returns initialState) until both contexts are available
2566
+ * - Completes when field config is extracted and countries initialized
2567
+ *
2568
+ * Phase 2: Infrastructure setup with stub methods
2569
+ * Phase 3: Will extract field configuration from checkoutModules
2570
+ * Phase 4: Will coordinate country initialization with Task lifecycle
2571
+ */
2572
+ private _initializationTask;
2573
+ /**
2574
+ * Initialize countries list
2575
+ */
2576
+ connectedCallback(): void;
2577
+ /**
2578
+ * Extract billing address field configuration from SDK Core checkoutModules
2579
+ * @param configuration - Configuration context from SDK Core
2580
+ * @returns Field configuration object
2581
+ */
2582
+ private extractFieldConfig;
2583
+ /**
2584
+ * Initialize country options with two-phase loading:
2585
+ * 1. Synchronously load English countries first
2586
+ * 2. Asynchronously load locale-specific countries
2587
+ *
2588
+ * This preserves the existing behavior where users see English countries
2589
+ * immediately, then see localized names if available.
2590
+ */
2591
+ private initializeCountryOptions;
2592
+ /**
2593
+ * Get billing address field configuration from SDK Core checkoutModules.
2594
+ *
2595
+ * This getter is used during rendering after the initialization task completes.
2596
+ * Configuration is determined by server-side checkoutModules configuration.
2597
+ * If not present, defaults to all fields disabled (form hidden).
2598
+ */
2599
+ private get fieldConfig();
2600
+ /**
2601
+ * Default field configuration (all fields disabled).
2602
+ * When no configuration is provided, the form is hidden.
2603
+ * This matches the legacy SDK behavior where billing address is opt-in.
2604
+ */
2605
+ private get defaultFieldConfig();
2606
+ /**
2607
+ * Check if the form should be visible
2608
+ * According to legacy SDK: form is hidden if postalCode is false
2609
+ */
2610
+ private get shouldShowForm();
2611
+ /**
2612
+ * Handle input change events
2613
+ */
2614
+ private handleInput;
2615
+ /**
2616
+ * Handle focus events
2617
+ */
2618
+ private handleFocus;
2619
+ /**
2620
+ * Handle blur events for validation
2621
+ */
2622
+ private handleBlur;
2623
+ /**
2624
+ * Validate a single field
2625
+ */
2626
+ private validateField;
2627
+ /**
2628
+ * Validate all enabled fields
2629
+ */
2630
+ private validateForm;
2631
+ /**
2632
+ * Public method to validate billing address fields
2633
+ * Called by the parent form (card-form) when submitting
2634
+ * Returns true if billing address is valid
2635
+ * Note: Does NOT call setBillingAddress API - that happens after card validation
2636
+ */
2637
+ validateForSubmission(): Promise<boolean>;
2638
+ /**
2639
+ * Public method to submit billing address to SDK Core
2640
+ * Called by parent form ONLY after both card and billing address validation pass
2641
+ *
2642
+ * Note: headlessUtils is guaranteed to be available when this method is called,
2643
+ * as the component only renders (and becomes interactive) after initialization task completes.
2644
+ */
2645
+ submitToSDK(): Promise<boolean>;
2646
+ /**
2647
+ * Check if field should show error
2648
+ * Matches card input behavior: show errors after submit OR after field is dirty AND touched
2649
+ */
2650
+ private shouldShowError;
2651
+ render(): symbol | import("lit-html").TemplateResult<1> | undefined;
2652
+ }
2653
+ declare global {
2654
+ interface HTMLElementTagNameMap {
2655
+ "primer-billing-address": BillingAddressComponent;
2656
+ }
2657
+ }
2340
2658
  /**
2341
2659
  * Interface for secure htmlContent access
2342
2660
  */
@@ -2824,6 +3142,11 @@ declare class CardFormComponent extends LitElement {
2824
3142
  */
2825
3143
  private hasAssignedContent;
2826
3144
  private selectedCardNetwork;
3145
+ /**
3146
+ * Form-level error message to display
3147
+ * @private
3148
+ */
3149
+ private formErrorMessage;
2827
3150
  /**
2828
3151
  * Flag to track if PAYMENT_METHOD_SELECTION event has been sent
2829
3152
  * @private
@@ -3278,7 +3601,7 @@ declare class CardFormSubmitComponent extends LitElement {
3278
3601
  */
3279
3602
  get buttonText(): string;
3280
3603
  set buttonText(value: string);
3281
- headlessInstance: HeadlessUtilsContextType;
3604
+ headlessUtils: HeadlessUtilsContextType;
3282
3605
  clientOptions: ClientOptionsContextType;
3283
3606
  sdkState: SdkStateContextType;
3284
3607
  cardFormContext: CardFormContext | null;
@@ -3435,45 +3758,6 @@ declare global {
3435
3758
  "primer-show-other-payments": ShowOtherPaymentsComponent;
3436
3759
  }
3437
3760
  }
3438
- /**
3439
- * Component for rendering native payment buttons (Apple Pay, Google Pay, PayPal)
3440
- * with proper height calculations based on design system variables.
3441
- */
3442
- declare class NativePaymentComponent extends LitElement {
3443
- static styles: import("lit").CSSResult[];
3444
- paymentMethod: InitializedPaymentMethod | undefined;
3445
- paymentManagers: InitializedManagersMap;
3446
- computedStyles: CSSStyleDeclaration | null;
3447
- disabled: boolean;
3448
- private _buttonId;
3449
- private loadManagerTask;
3450
- private nativeButtonTask;
3451
- constructor();
3452
- attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
3453
- /**
3454
- * Calculates the button height by reading the computed height from the element.
3455
- * The CSS already calculates the correct height using CSS variables,
3456
- * so we just read the browser's computed value (which handles rem/em/% conversions).
3457
- */
3458
- private calculateButtonHeight;
3459
- /**
3460
- * Creates render options with appropriate styles based on payment method type
3461
- */
3462
- private createRenderOptions;
3463
- protected updated(changedProperties: PropertyValues): void;
3464
- /**
3465
- * Updates the disabled overlay based on the current disabled state
3466
- */
3467
- private updateDisabledOverlay;
3468
- private updateGooglePayOverlay;
3469
- private updateRegularOverlay;
3470
- render(): symbol | import("lit-html").TemplateResult<1> | undefined;
3471
- }
3472
- declare global {
3473
- interface HTMLElementTagNameMap {
3474
- "primer-native-payment": NativePaymentComponent;
3475
- }
3476
- }
3477
3761
  declare class PrimerCheckoutCompleteComponent extends LitElement {
3478
3762
  render(): import("lit-html").TemplateResult<1>;
3479
3763
  }
@@ -3546,6 +3830,8 @@ export declare function loadPrimer(): void;
3546
3830
 
3547
3831
  export {
3548
3832
  AchPaymentComponent as AchPayment,
3833
+ ApplePayComponent as ApplePay,
3834
+ BillingAddressComponent as BillingAddress,
3549
3835
  ButtonComponent as Button,
3550
3836
  CardFormComponent as CardForm,
3551
3837
  CardFormSubmitComponent as CardFormSubmit,
@@ -3555,6 +3841,7 @@ export {
3555
3841
  DynamicPaymentComponent as DynamicPayment,
3556
3842
  ErrorMessageComponent as ErrorMessage,
3557
3843
  ErrorMessageContainerComponent as ErrorMessageContainer,
3844
+ GooglePayComponent as GooglePay,
3558
3845
  InputCardExpiryComponent as CardFormExpiry,
3559
3846
  InputCardHolderNameComponent as CardFormName,
3560
3847
  InputCardNumberComponent as CardFormCardNumber,
@@ -3563,7 +3850,7 @@ export {
3563
3850
  InputErrorComponent as CardFormError,
3564
3851
  InputLabelComponent as InputLabel,
3565
3852
  InputWrapperComponent as InputWrapper,
3566
- NativePaymentComponent as NativePayment,
3853
+ PayPalComponent as PayPal,
3567
3854
  PaymentMethodComponent as PaymentMethod,
3568
3855
  PaymentMethodContainerComponent as PaymentMethodContainer,
3569
3856
  PortalComponent as Portal,
@@ -3574,6 +3861,7 @@ export {
3574
3861
  PrimerKlarnaComponent as PrimerKlarna,
3575
3862
  PrimerMainComponent as PrimerMain,
3576
3863
  RedirectPaymentComponent as RedirectPayment,
3864
+ SelectComponent as Select,
3577
3865
  ShowOtherPaymentsComponent as ShowOtherPayments,
3578
3866
  SpinnerComponent as Spinner,
3579
3867
  VaultCvvInputComponent as VaultCvvInput,