import type { Digit, IsNumericString, LowercaseLetter, ObjectValues, Prettify, } from "./utility"; /** * List of common UI slots available across different contexts. * * These slots are shared between checkout and storefront interfaces, * providing consistent placement options for UI components. * * @constant * * @property {"before_main_content"} BEFORE_MAIN_CONTENT - Before the main content area. * @property {"after_main_content"} AFTER_MAIN_CONTENT - After the main content area. * @property {"modal_content"} MODAL_CONTENT - Content of a modal dialog. * @property {"corner_top_left"} CORNER_TOP_LEFT - Top left corner of the page. * @property {"corner_top_right"} CORNER_TOP_RIGHT - Top right corner of the page. * @property {"corner_bottom_left"} CORNER_BOTTOM_LEFT - Bottom left corner of the page. * @property {"corner_bottom_right"} CORNER_BOTTOM_RIGHT - Bottom right corner of the page. * @property {"edge_top_center"} EDGE_TOP_CENTER - Top edge, horizontally centered. * @property {"edge_bottom_center"} EDGE_BOTTOM_CENTER - Bottom edge, horizontally centered. * @property {"edge_left_center"} EDGE_LEFT_CENTER - Left edge, vertically centered. * @property {"edge_right_center"} EDGE_RIGHT_CENTER - Right edge, vertically centered. * @property {"before_line_items"} BEFORE_LINE_ITEMS - Before the list of items in the cart. * @property {"after_line_items"} AFTER_LINE_ITEMS - After the list of items in the cart. * @property {"after_header"} AFTER_HEADER - After the header. * @property {"drawer_left"} DRAWER_LEFT - Left drawer. * @property {"drawer_right"} DRAWER_RIGHT - Right drawer. * @property {"fullscreen_content"} FULLSCREEN_CONTENT - Fullscreen overlay; accepts a `Video.Root` component. */ export const COMMON_UI_SLOT = { BEFORE_MAIN_CONTENT: "before_main_content", AFTER_MAIN_CONTENT: "after_main_content", MODAL_CONTENT: "modal_content", CORNER_TOP_LEFT: "corner_top_left", CORNER_TOP_RIGHT: "corner_top_right", CORNER_BOTTOM_LEFT: "corner_bottom_left", CORNER_BOTTOM_RIGHT: "corner_bottom_right", EDGE_TOP_CENTER: "edge_top_center", EDGE_BOTTOM_CENTER: "edge_bottom_center", EDGE_LEFT_CENTER: "edge_left_center", EDGE_RIGHT_CENTER: "edge_right_center", BEFORE_LINE_ITEMS: "before_line_items", AFTER_LINE_ITEMS: "after_line_items", AFTER_HEADER: "after_header", DRAWER_LEFT: "drawer_left", DRAWER_RIGHT: "drawer_right", FULLSCREEN_CONTENT: "fullscreen_content", } as const; /** * List of UI slots available in the checkout context. * * These slots provide specific placement options for UI components * during the checkout process, allowing customization of forms, * payment options, and item displays. * * @constant * * @property {"after_contact_form"} AFTER_CONTACT_FORM - After the contact form in checkout. * @property {"after_address_form"} AFTER_ADDRESS_FORM - After the address form in checkout. * @property {"after_billing_form"} AFTER_BILLING_FORM - After the billing form in checkout. * @property {"after_payment_options"} AFTER_PAYMENT_OPTIONS - After the payment options in checkout. * @property {"before_payment_options"} BEFORE_PAYMENT_OPTIONS - Before the payment options in checkout. * @property {"before_address_form"} BEFORE_ADDRESS_FORM - Before the address form in checkout. * @property {"before_billing_form"} BEFORE_BILLING_FORM - Before the billing form in checkout. * @property {"before_contact_form"} BEFORE_CONTACT_FORM - Before the contact form in checkout. * @property {"after_line_items_price"} AFTER_LINE_ITEMS_PRICE - After the price of the line items in checkout. * @property {"before_shipping_form"} BEFORE_SHIPPING_FORM - Before the shipping form in checkout. * @property {"after_shipping_form"} AFTER_SHIPPING_FORM - After the shipping form in checkout. * @property {"after_shipping_description"} AFTER_SHIPPING_DESCRIPTION - After the shipping description in checkout. * @property {"before_order_number"} BEFORE_ORDER_NUMBER - Before the order number in checkout. * @property {"after_order_number"} AFTER_ORDER_NUMBER - After the order number in checkout. * @property {"before_order_summary"} BEFORE_ORDER_SUMMARY - Before the order summary in checkout. * @property {"after_order_summary"} AFTER_ORDER_SUMMARY - After the order summary in checkout. * @property {...typeof COMMON_UI_SLOT} - Includes all common UI slots. */ export const CHECKOUT_UI_SLOT = { ...COMMON_UI_SLOT, AFTER_CONTACT_FORM: "after_contact_form", AFTER_ADDRESS_FORM: "after_address_form", AFTER_BILLING_FORM: "after_billing_form", AFTER_PAYMENT_OPTIONS: "after_payment_options", BEFORE_PAYMENT_OPTIONS: "before_payment_options", BEFORE_ADDRESS_FORM: "before_address_form", BEFORE_BILLING_FORM: "before_billing_form", BEFORE_CONTACT_FORM: "before_contact_form", AFTER_LINE_ITEMS_PRICE: "after_line_items_price", BEFORE_SHIPPING_FORM: "before_shipping_form", AFTER_SHIPPING_FORM: "after_shipping_form", AFTER_SHIPPING_DESCRIPTION: "after_shipping_description", BEFORE_ORDER_NUMBER: "before_order_number", AFTER_ORDER_NUMBER: "after_order_number", BEFORE_ORDER_SUMMARY: "before_order_summary", AFTER_ORDER_SUMMARY: "after_order_summary", } as const; /** * List of UI slots available in the storefront context. * * These slots provide specific placement options for UI components * in product pages and storefronts, allowing customization of * product displays, add to cart buttons, and grid layouts. * * @constant * * @property {"before_quick_buy_add_to_cart"} BEFORE_QUICK_BUY_ADD_TO_CART - Before the quick buy add to cart button. * @property {"before_product_detail_add_to_cart"} BEFORE_PRODUCT_DETAIL_ADD_TO_CART - Before the product detail add to cart button. * @property {"after_product_detail_add_to_cart"} AFTER_PRODUCT_DETAIL_ADD_TO_CART - After the product detail add to cart button. * @property {"before_add_to_cart_pdp"} BEFORE_ADD_TO_CART_PDP - Before the add to cart button on product detail page. Deprecated; use BEFORE_PRODUCT_DETAIL_ADD_TO_CART instead. * @property {"after_add_to_cart_pdp"} AFTER_ADD_TO_CART_PDP - After the add to cart button on product detail page. Deprecated; use AFTER_PRODUCT_DETAIL_ADD_TO_CART instead. * @property {"product_detail_image_top_left"} PRODUCT_DETAIL_IMAGE_TOP_LEFT - Top left corner of product detail images. * @property {"product_detail_image_top_right"} PRODUCT_DETAIL_IMAGE_TOP_RIGHT - Top right corner of product detail images. * @property {"product_detail_image_bottom_left"} PRODUCT_DETAIL_IMAGE_BOTTOM_LEFT - Bottom left corner of product detail images. * @property {"product_detail_image_bottom_right"} PRODUCT_DETAIL_IMAGE_BOTTOM_RIGHT - Bottom right corner of product detail images. * @property {"product_detail_image_top_center"} PRODUCT_DETAIL_IMAGE_TOP_CENTER - Top center of product detail images. * @property {"product_detail_image_center_left"} PRODUCT_DETAIL_IMAGE_CENTER_LEFT - Center left of product detail images. * @property {"product_detail_image_center_right"} PRODUCT_DETAIL_IMAGE_CENTER_RIGHT - Center right of product detail images. * @property {"product_detail_image_bottom_center"} PRODUCT_DETAIL_IMAGE_BOTTOM_CENTER - Bottom center of product detail images. * @property {"product_detail_image_center_center"} PRODUCT_DETAIL_IMAGE_CENTER_CENTER - Center of product detail images. * @property {"after_product_detail_name"} AFTER_PRODUCT_DETAIL_NAME - After the product name in product detail. * @property {"before_product_detail_name"} BEFORE_PRODUCT_DETAIL_NAME - Before the product name in product detail. * @property {"before_product_description"} BEFORE_PRODUCT_DESCRIPTION - Before the product description. * @property {"after_product_description"} AFTER_PRODUCT_DESCRIPTION - After the product description. * @property {"before_product_detail_price"} BEFORE_PRODUCT_DETAIL_PRICE - Before the product detail price. * @property {"after_product_detail_price"} AFTER_PRODUCT_DETAIL_PRICE - After the product detail price. * @property {"before_price_pdp"} BEFORE_PRICE_PDP - Before the price on product detail page. Deprecated; use BEFORE_PRODUCT_DETAIL_PRICE instead. * @property {"after_price_pdp"} AFTER_PRICE_PDP - After the price on product detail page. Deprecated; use AFTER_PRODUCT_DETAIL_PRICE instead. * @property {"after_product_grid_item_name"} AFTER_PRODUCT_GRID_ITEM_NAME - After the product name in grid items. * @property {"before_product_grid_item_name"} BEFORE_PRODUCT_GRID_ITEM_NAME - Before the product name in grid items. * @property {"after_product_grid_item_price"} AFTER_PRODUCT_GRID_ITEM_PRICE - After the product price in grid items. * @property {"before_product_grid_item_price"} BEFORE_PRODUCT_GRID_ITEM_PRICE - Before the product price in grid items. * @property {"product_grid_item_image_top_right"} PRODUCT_GRID_ITEM_IMAGE_TOP_RIGHT - Top right corner of product grid item images. * @property {"product_grid_item_image_top_left"} PRODUCT_GRID_ITEM_IMAGE_TOP_LEFT - Top left corner of product grid item images. * @property {"product_grid_item_image_bottom_right"} PRODUCT_GRID_ITEM_IMAGE_BOTTOM_RIGHT - Bottom right corner of product grid item images. * @property {"product_grid_item_image_bottom_left"} PRODUCT_GRID_ITEM_IMAGE_BOTTOM_LEFT - Bottom left corner of product grid item images. * @property {"product_grid_item_image_top_center"} PRODUCT_GRID_ITEM_IMAGE_TOP_CENTER - Top center of product grid item images. * @property {"product_grid_item_image_center_left"} PRODUCT_GRID_ITEM_IMAGE_CENTER_LEFT - Center left of product grid item images. * @property {"product_grid_item_image_center_right"} PRODUCT_GRID_ITEM_IMAGE_CENTER_RIGHT - Center right of product grid item images. * @property {"product_grid_item_image_bottom_center"} PRODUCT_GRID_ITEM_IMAGE_BOTTOM_CENTER - Bottom center of product grid item images. * @property {"product_grid_item_image_center_center"} PRODUCT_GRID_ITEM_IMAGE_CENTER_CENTER - Center of product grid item images. * @property {"before_go_to_checkout"} BEFORE_GO_TO_CHECKOUT - Before the go to checkout button. * @property {"before_start_checkout_button"} BEFORE_START_CHECKOUT_BUTTON - Before the start checkout button. Deprecated; use BEFORE_GO_TO_CHECKOUT instead. * @property {"after_go_to_checkout"} AFTER_GO_TO_CHECKOUT - After the go to checkout button. * @property {"after_cart_summary"} AFTER_CART_SUMMARY - After the cart summary. * @property {"after_section_newsletter"} AFTER_SECTION_NEWSLETTER - After the newsletter section on the home page. * @property {"before_section_newsletter"} BEFORE_SECTION_NEWSLETTER - Before the newsletter section on the home page. * @property {"before_section_products_sale"} BEFORE_SECTION_PRODUCTS_SALE - Before the products sale section on the home page. * @property {"after_section_products_sale"} AFTER_SECTION_PRODUCTS_SALE - After the products sale section on the home page. * @property {"before_section_products_new"} BEFORE_SECTION_PRODUCTS_NEW - Before the products new section on the home page. * @property {"after_section_products_new"} AFTER_SECTION_PRODUCTS_NEW - After the products new section on the home page. * @property {"before_section_products_featured"} BEFORE_SECTION_PRODUCTS_FEATURED - Before the products featured section on the home page. * @property {"after_section_products_featured"} AFTER_SECTION_PRODUCTS_FEATURED - After the products featured section on the home page. * @property {"before_section_products_promotion"} BEFORE_SECTION_PRODUCTS_PROMOTION - Before the products promotion section on the home page. * @property {"after_section_products_promotion"} AFTER_SECTION_PRODUCTS_PROMOTION - After the products promotion section on the home page. * @property {"before_section_products_best_seller"} BEFORE_SECTION_PRODUCTS_BEST_SELLER - Before the best seller products section on the home page. * @property {"after_section_products_best_seller"} AFTER_SECTION_PRODUCTS_BEST_SELLER - After the best seller products section on the home page. * @property {"before_section_products_recent"} BEFORE_SECTION_PRODUCTS_RECENT - Before the recent products section on the home page. * @property {"after_section_products_recent"} AFTER_SECTION_PRODUCTS_RECENT - After the recent products section on the home page. * @property {"before_section_product_main"} BEFORE_SECTION_PRODUCT_MAIN - Before the main product section on the product detail page. * @property {"after_section_product_main"} AFTER_SECTION_PRODUCT_MAIN - After the main product section on the product detail page. * @property {"before_section_banner_categories"} BEFORE_SECTION_BANNER_CATEGORIES - Before the categories banner section on the home page. * @property {"after_section_banner_categories"} AFTER_SECTION_BANNER_CATEGORIES - After the categories banner section on the home page. * @property {"before_section_banner_promotional"} BEFORE_SECTION_BANNER_PROMOTIONAL - Before the promotional banner section on the home page. * @property {"after_section_banner_promotional"} AFTER_SECTION_BANNER_PROMOTIONAL - After the promotional banner section on the home page. * @property {"before_section_banner_news"} BEFORE_SECTION_BANNER_NEWS - Before the news banner section on the home page. * @property {"after_section_banner_news"} AFTER_SECTION_BANNER_NEWS - After the news banner section on the home page. * @property {"before_product_detail_related_products"} BEFORE_PRODUCT_DETAIL_RELATED_PRODUCTS - Before the related products section on the product detail page. * @property {"after_product_detail_related_products"} AFTER_PRODUCT_DETAIL_RELATED_PRODUCTS - After the related products section on the product detail page. * @property {"before_product_detail_complementary_products"} BEFORE_PRODUCT_DETAIL_COMPLEMENTARY_PRODUCTS - Before the complementary products section on the product detail page. * @property {"after_product_detail_complementary_products"} AFTER_PRODUCT_DETAIL_COMPLEMENTARY_PRODUCTS - After the complementary products section on the product detail page. * @property {"before_line_item"} BEFORE_LINE_ITEM - Before each cart line item. * @property {"cart_line_item_top"} CART_LINE_ITEM_TOP - Top of the cart line item. Deprecated; use BEFORE_LINE_ITEM instead. * @property {"before_footer"} BEFORE_FOOTER - Before the footer. * @property {"inside_footer"} INSIDE_FOOTER - Inside footer content. * @property {"footer_seals"} FOOTER_SEALS - Inside footer seals. * @property {"after_footer"} AFTER_FOOTER - After the footer. * @property {"before_product_detail_payment_options"} BEFORE_PRODUCT_DETAIL_PAYMENT_OPTIONS - Before the payment options accordion on the product detail page. * @property {"after_product_detail_payment_options"} AFTER_PRODUCT_DETAIL_PAYMENT_OPTIONS - After the payment options accordion on the product detail page. * @property {"before_product_detail_shipping_options"} BEFORE_PRODUCT_DETAIL_SHIPPING_OPTIONS - Before the shipping options on the product detail page. * @property {"after_product_detail_shipping_options"} AFTER_PRODUCT_DETAIL_SHIPPING_OPTIONS - After the shipping options on the product detail page. * @property {"before_cart_shipping_options"} BEFORE_CART_SHIPPING_OPTIONS - Before the shipping options on the cart page. * @property {"after_cart_shipping_options"} AFTER_CART_SHIPPING_OPTIONS - After the shipping options on the cart page. * @property {"before_register_form"} BEFORE_REGISTER_FORM - Before the customer registration form on the storefront register page. * @property {"after_register_form"} AFTER_REGISTER_FORM - After the customer registration form on the storefront register page. * @property {"before_register_form_fields"} BEFORE_REGISTER_FORM_FIELDS - Before the fields of the customer registration form on the storefront register page. * @property {"after_register_form_fields"} AFTER_REGISTER_FORM_FIELDS - After the fields of the customer registration form on the storefront register page. * @property {"before_register_form_submit"} BEFORE_REGISTER_FORM_SUBMIT - Before the submit button of the customer registration form on the storefront register page. * @property {"after_register_form_submit"} AFTER_REGISTER_FORM_SUBMIT - After the submit button of the customer registration form on the storefront register page. * @property {...typeof COMMON_UI_SLOT} - Includes all common UI slots. */ export const STOREFRONT_UI_SLOT = { ...COMMON_UI_SLOT, BEFORE_QUICK_BUY_ADD_TO_CART: "before_quick_buy_add_to_cart", BEFORE_PRODUCT_DETAIL_ADD_TO_CART: "before_product_detail_add_to_cart", AFTER_PRODUCT_DETAIL_ADD_TO_CART: "after_product_detail_add_to_cart", /** @deprecated Use BEFORE_PRODUCT_DETAIL_ADD_TO_CART instead. */ BEFORE_ADD_TO_CART_PDP: "before_add_to_cart_pdp", /** @deprecated Use AFTER_PRODUCT_DETAIL_ADD_TO_CART instead. */ AFTER_ADD_TO_CART_PDP: "after_add_to_cart_pdp", PRODUCT_DETAIL_IMAGE_TOP_LEFT: "product_detail_image_top_left", PRODUCT_DETAIL_IMAGE_TOP_RIGHT: "product_detail_image_top_right", PRODUCT_DETAIL_IMAGE_BOTTOM_LEFT: "product_detail_image_bottom_left", PRODUCT_DETAIL_IMAGE_BOTTOM_RIGHT: "product_detail_image_bottom_right", PRODUCT_DETAIL_IMAGE_TOP_CENTER: "product_detail_image_top_center", PRODUCT_DETAIL_IMAGE_CENTER_LEFT: "product_detail_image_center_left", PRODUCT_DETAIL_IMAGE_CENTER_RIGHT: "product_detail_image_center_right", PRODUCT_DETAIL_IMAGE_BOTTOM_CENTER: "product_detail_image_bottom_center", PRODUCT_DETAIL_IMAGE_CENTER_CENTER: "product_detail_image_center_center", AFTER_PRODUCT_DETAIL_NAME: "after_product_detail_name", AFTER_PRODUCT_DESCRIPTION: "after_product_description", BEFORE_PRODUCT_DETAIL_PRICE: "before_product_detail_price", AFTER_PRODUCT_DETAIL_PRICE: "after_product_detail_price", /** @deprecated Use BEFORE_PRODUCT_DETAIL_PRICE instead. */ BEFORE_PRICE_PDP: "before_price_pdp", /** @deprecated Use AFTER_PRODUCT_DETAIL_PRICE instead. */ AFTER_PRICE_PDP: "after_price_pdp", AFTER_PRODUCT_GRID_ITEM_NAME: "after_product_grid_item_name", BEFORE_PRODUCT_GRID_ITEM_NAME: "before_product_grid_item_name", AFTER_PRODUCT_GRID_ITEM_PRICE: "after_product_grid_item_price", BEFORE_PRODUCT_GRID_ITEM_PRICE: "before_product_grid_item_price", PRODUCT_GRID_ITEM_IMAGE_TOP_RIGHT: "product_grid_item_image_top_right", PRODUCT_GRID_ITEM_IMAGE_TOP_LEFT: "product_grid_item_image_top_left", PRODUCT_GRID_ITEM_IMAGE_BOTTOM_RIGHT: "product_grid_item_image_bottom_right", PRODUCT_GRID_ITEM_IMAGE_BOTTOM_LEFT: "product_grid_item_image_bottom_left", PRODUCT_GRID_ITEM_IMAGE_TOP_CENTER: "product_grid_item_image_top_center", PRODUCT_GRID_ITEM_IMAGE_CENTER_LEFT: "product_grid_item_image_center_left", PRODUCT_GRID_ITEM_IMAGE_CENTER_RIGHT: "product_grid_item_image_center_right", PRODUCT_GRID_ITEM_IMAGE_BOTTOM_CENTER: "product_grid_item_image_bottom_center", PRODUCT_GRID_ITEM_IMAGE_CENTER_CENTER: "product_grid_item_image_center_center", BEFORE_GO_TO_CHECKOUT: "before_go_to_checkout", AFTER_GO_TO_CHECKOUT: "after_go_to_checkout", /** @deprecated Use BEFORE_GO_TO_CHECKOUT instead. */ BEFORE_START_CHECKOUT_BUTTON: "before_start_checkout_button", AFTER_CART_SUMMARY: "after_cart_summary", AFTER_SECTION_NEWSLETTER: "after_section_newsletter", BEFORE_FOOTER: "before_footer", INSIDE_FOOTER: "inside_footer", FOOTER_SEALS: "footer_seals", AFTER_FOOTER: "after_footer", BEFORE_SECTION_NEWSLETTER: "before_section_newsletter", BEFORE_SECTION_PRODUCTS_SALE: "before_section_products_sale", AFTER_SECTION_PRODUCTS_SALE: "after_section_products_sale", BEFORE_SECTION_PRODUCTS_NEW: "before_section_products_new", AFTER_SECTION_PRODUCTS_NEW: "after_section_products_new", BEFORE_SECTION_PRODUCTS_FEATURED: "before_section_products_featured", AFTER_SECTION_PRODUCTS_FEATURED: "after_section_products_featured", BEFORE_SECTION_PRODUCTS_PROMOTION: "before_section_products_promotion", AFTER_SECTION_PRODUCTS_PROMOTION: "after_section_products_promotion", BEFORE_SECTION_PRODUCTS_BEST_SELLER: "before_section_products_best_seller", AFTER_SECTION_PRODUCTS_BEST_SELLER: "after_section_products_best_seller", BEFORE_SECTION_PRODUCTS_RECENT: "before_section_products_recent", AFTER_SECTION_PRODUCTS_RECENT: "after_section_products_recent", BEFORE_SECTION_PRODUCT_MAIN: "before_section_product_main", AFTER_SECTION_PRODUCT_MAIN: "after_section_product_main", BEFORE_SECTION_BANNER_CATEGORIES: "before_section_banner_categories", AFTER_SECTION_BANNER_CATEGORIES: "after_section_banner_categories", BEFORE_SECTION_BANNER_PROMOTIONAL: "before_section_banner_promotional", AFTER_SECTION_BANNER_PROMOTIONAL: "after_section_banner_promotional", BEFORE_SECTION_BANNER_NEWS: "before_section_banner_news", AFTER_SECTION_BANNER_NEWS: "after_section_banner_news", BEFORE_PRODUCT_DETAIL_RELATED_PRODUCTS: "before_product_detail_related_products", AFTER_PRODUCT_DETAIL_RELATED_PRODUCTS: "after_product_detail_related_products", BEFORE_PRODUCT_DETAIL_COMPLEMENTARY_PRODUCTS: "before_product_detail_complementary_products", AFTER_PRODUCT_DETAIL_COMPLEMENTARY_PRODUCTS: "after_product_detail_complementary_products", BEFORE_LINE_ITEM: "before_line_item", /** @deprecated Use BEFORE_LINE_ITEM instead. */ CART_LINE_ITEM_TOP: "cart_line_item_top", BEFORE_PRODUCT_DETAIL_NAME: "before_product_detail_name", BEFORE_PRODUCT_DETAIL_PAYMENT_OPTIONS: "before_product_detail_payment_options", AFTER_PRODUCT_DETAIL_PAYMENT_OPTIONS: "after_product_detail_payment_options", BEFORE_PRODUCT_DETAIL_SHIPPING_OPTIONS: "before_product_detail_shipping_options", AFTER_PRODUCT_DETAIL_SHIPPING_OPTIONS: "after_product_detail_shipping_options", BEFORE_CART_SHIPPING_OPTIONS: "before_cart_shipping_options", AFTER_CART_SHIPPING_OPTIONS: "after_cart_shipping_options", BEFORE_REGISTER_FORM: "before_register_form", AFTER_REGISTER_FORM: "after_register_form", BEFORE_REGISTER_FORM_FIELDS: "before_register_form_fields", AFTER_REGISTER_FORM_FIELDS: "after_register_form_fields", BEFORE_REGISTER_FORM_SUBMIT: "before_register_form_submit", AFTER_REGISTER_FORM_SUBMIT: "after_register_form_submit", } as const; /** * Combined list of all available UI slots. * * This object merges all checkout and storefront UI slots, * providing a unified interface for accessing any UI slot. * * @constant * * @property {...typeof CHECKOUT_UI_SLOT} - Includes all checkout UI slots. * @property {...typeof STOREFRONT_UI_SLOT} - Includes all storefront UI slots. */ export const UI_SLOT = { ...CHECKOUT_UI_SLOT, ...STOREFRONT_UI_SLOT, } as const; /** * Represents the possible common UI slots that can be used across different contexts. * These slots are available in both checkout and storefront interfaces. */ export type CommonUISlot = ObjectValues; /** * Represents the possible UI slots that can be used in the checkout context. * Includes all common slots plus checkout-specific slots. */ export type CheckoutUISlot = ObjectValues; /** * Represents the possible UI slots that can be used in the storefront context. * Includes all common slots plus storefront-specific slots. */ export type StorefrontUISlot = ObjectValues; /** * The set of characters allowed in the body of a custom slot name * (i.e. the part after the `custom_` prefix). * * Only lowercase letters, digits and underscores are considered valid, * which also enforces the `lowercase` and `snake_case` conventions. */ type AllowedCustomUISlotChar = LowercaseLetter | Digit | "_"; /** * Recursively checks whether every character of `S` is an * {@link AllowedCustomUISlotChar}. * * Resolves to `true` only when `S` is non-empty and made up exclusively of * lowercase letters, digits and underscores; otherwise resolves to `false`. * * The non-literal `string` type resolves to `true`, since a value that is not * a string literal cannot be validated at the type level and must be accepted. * * @template S - The custom slot body to validate (without the `custom_` prefix). */ type IsValidCustomUISlotBody = string extends S ? true : S extends `${infer Head}${infer Tail}` ? Head extends AllowedCustomUISlotChar ? Tail extends "" ? true : IsValidCustomUISlotBody : false : false; /** * Represents a custom slot defined by the store theme developer. * * A custom slot lets a theme expose its own injection points, following these rules: * * 1. It must always start with the `custom_` prefix. * 2. It must be written in `snake_case`. * 3. It must be entirely lowercase. * 4. Only letters, numbers and `_` are valid characters. * * When used without a type argument (for example, as part of the {@link UISlot} * union) it behaves as the broad ``custom_${string}`` template, matching any * custom slot. When a string literal is provided as `T`, the rules above are * enforced at the type level: valid names resolve to the literal itself, while * invalid ones resolve to `never`. * * @template T - The custom slot name to validate. Defaults to `string`, which * yields the broad ``custom_${string}`` type. * * @example * ```ts * type A = CustomUISlot<"custom_promo_banner">; // "custom_promo_banner" * type B = CustomUISlot<"custom_promoBanner">; // never (not lowercase / snake_case) * type C = CustomUISlot<"custom_promo-banner">; // never (invalid character "-") * type D = CustomUISlot<"promo_banner">; // never (missing "custom_" prefix) * type E = CustomUISlot; // `custom_${string}` * ``` */ export type CustomUISlot = string extends T ? `custom_${string}` : T extends `custom_${infer Body}` ? IsValidCustomUISlotBody extends true ? T : never : never; /** * The prefixes that every dynamic-section slot must start with. * * A dynamic-section slot is created around a theme section that can be added, * removed or reordered by the store owner, exposing an injection point right * `before` or `after` that section. */ type DynamicUISlotPrefix = "before_dynamic_section_" | "after_dynamic_section_"; /** * Validates the body of a dynamic slot (the part after the * {@link DynamicUISlotPrefix}). * * A valid body is any (non-empty) section name followed by a single underscore * and a trailing numeric sequence, e.g. ``single-shelf_1782228052519``. The * name itself is unrestricted, so the numeric suffix is matched against the * part after the *last* underscore. * * @template Body - The dynamic slot body to validate. */ type IsValidDynamicUISlotBody = Body extends `${infer Name}_${infer Rest}` ? Name extends "" ? false : Rest extends `${string}_${string}` ? IsValidDynamicUISlotBody : IsNumericString : false; /** * Represents a slot injected around a dynamic theme section. * * A dynamic slot follows these rules: * * 1. It must start with either the `before_dynamic_section_` or * `after_dynamic_section_` prefix. * 2. The prefix is followed by a section name, which can be any string. * 3. It must always end with an underscore and a numeric sequence (the section * instance id). * * When used without a type argument (for example, as part of the {@link UISlot} * union) it behaves as the broad ``${DynamicUISlotPrefix}${string}`` template, * matching any dynamic slot. When a string literal is provided as `T`, the * rules above are enforced at the type level: valid names resolve to the * literal itself, while invalid ones resolve to `never`. * * @template T - The dynamic slot name to validate. Defaults to `string`, which * yields the broad ``${DynamicUISlotPrefix}${string}`` type. * * @example * ```ts * type A = DynamicUISlot<"before_dynamic_section_single-shelf_1782228052519">; * // => "before_dynamic_section_single-shelf_1782228052519" * type B = DynamicUISlot<"after_dynamic_section_single-shelf_1782228052519">; * // => "after_dynamic_section_single-shelf_1782228052519" * type C = DynamicUISlot<"before_dynamic_section_single-shelf">; // never (no numeric suffix) * type D = DynamicUISlot<"before_dynamic_section_singleShelf_1">; // "before_dynamic_section_singleShelf_1" (name is unrestricted) * type E = DynamicUISlot<"before_dynamic_section_-shelf_1">; // "before_dynamic_section_-shelf_1" (name is unrestricted) * type F = DynamicUISlot; // `${DynamicUISlotPrefix}${string}` * ``` */ export type DynamicUISlot = string extends T ? `${DynamicUISlotPrefix}${string}` : T extends `${DynamicUISlotPrefix}${infer Body}` ? IsValidDynamicUISlotBody extends true ? T : never : never; /** * Represents all possible UI slots where components can be dynamically injected. * This type combines checkout, storefront, common, custom and dynamic UI slots. */ export type UISlot = Prettify< CheckoutUISlot | StorefrontUISlot | CustomUISlot | DynamicUISlot >; /** * Validates a UI slot name provided as a string literal `S`. * * Predefined checkout and storefront slots resolve to themselves. Dynamic slots * (those starting with `before_dynamic_section_` / `after_dynamic_section_`) are * validated against the {@link DynamicUISlot} rules, and custom slots (those * starting with `custom_`) against the {@link CustomUISlot} rules, each * resolving to `S` when valid or `never` when invalid. Any other string * resolves to `never`. * * This is meant to be used to constrain slot arguments so that invalid custom * slot names are rejected at the call site (see {@link NubeSDK.render}). * * @template S - The slot name to validate. */ export type ValidateUISlot = S extends | CheckoutUISlot | StorefrontUISlot ? S : S extends DynamicUISlot ? DynamicUISlot : S extends CustomUISlot ? CustomUISlot : never; /** * Type of a slot argument for APIs such as {@link NubeSDK.render} and * {@link NubeSDK.clearSlot}. * * It keeps the predefined checkout and storefront slots as direct union * members, so editors still offer autocomplete for the fixed slot names, while * validating custom slot names (starting with `custom_`) through the generic * `TSlot` parameter via {@link ValidateUISlot}. * * @template TSlot - The literal type inferred from the slot argument. */ export type UISlotArg = | CheckoutUISlot | StorefrontUISlot | (TSlot & ValidateUISlot);