import type { TranslationOverrides } from "@swishapp/i18n"; import type { PlacementSpec } from "../dom/create-placement"; import { IntentOptions } from "../intents/intents"; import { CountryCode, LanguageCode } from "../storefront-api/types/storefront.types"; import { Intent, StorefrontApiOptions } from "../swish"; import type { Product, ProductVariant } from "../types"; import type { ContentBlockSectionParsed, DrawerSectionParsed, HomeSectionParsed, ListDetailPageSectionParsed, ListDetailSectionParsed, ListsSectionParsed, NotificationsSectionParsed, OrderDetailSectionParsed, OrdersSectionParsed, ProductDetailSectionParsed, ProfileSectionParsed, SavesSectionParsed, UiOptionsParsed } from "./schemas"; export interface SwishOptions { auth: AuthOptions; storefront: StorefrontApiOptions; context: StorefrontContext; features: FeaturesOptions; intents: IntentOptions; metafields: MetafieldOptions; placements: PlacementSpec[]; transforms: TransformOptionsResolved; translations?: TranslationOverrides; ui: UiOptionsParsed; } export interface AuthOptions { tokenUrl: string; } export type SignInRequirement = "none" | "save" | "view"; export interface FeaturesOptions { signInRequirement: SignInRequirement; } export interface StorefrontContext { customer: { id: string | null; email: string | null; firstName: string | null; lastName: string | null; b2b: boolean | null; tags?: string[] | null; }; localization: { country: CountryCode; language: LanguageCode; market: string; }; myshopifyDomain: string; shopName?: string; moneyFormat?: string; newCustomerAccounts: boolean; routes: { accountUrl: string; rootUrl: string; listDetailPagePath: string; }; } export interface MetafieldOptions { product: `${string}.${string}`[]; productVariant: `${string}.${string}`[]; } export type Badge = { id: string; label: string; style?: Record; }; export interface TransformOptions { productTitle?: (args: { product: Product; }) => string; productDescription?: (args: { product: Product; }) => string; productBadges?: (args: { product: Product; variant?: ProductVariant; defaultBadges: (string | Badge)[]; }) => (string | Badge)[]; productPrice?: (args: { product: Product; variant?: ProductVariant; }) => string | false | undefined; addToCartButton?: (args: { product: Product; }) => boolean; linkToProductPage?: (args: { product: Product; }) => boolean; variantTitle?: (args: { variant: ProductVariant; }) => string; optionValues?: (args: { option: NonNullable["options"][number]; optionValues: NonNullable["options"][number]["optionValues"]; }) => NonNullable["options"][number]["optionValues"]; combinedListingParent?: (args: { product: Product; }) => boolean | string; hideOption?: (args: { option: NonNullable["options"][number]; product: Product; }) => boolean; recommendations?: (args: { product: Product; defaultRecommendations: Pick[]; }) => Pick[] | Promise[]>; } export type TransformOptionsResolved = Required; export type UiOptions = UiOptionsParsed; export interface UiDesignOptions { sizes?: { buttonHeight?: number | string; iconButtonSize?: number | string; formInputHeight?: number | string; iconSize?: number | string; imageCardAspectRatio?: string; imageSliderAspectRatio?: string; thumbnailAspectRatio?: string; imageFit?: "cover" | "contain"; }; rounding?: { borderRadiusScale?: number | string; badgeBorderRadius?: string; buttonBorderRadius?: string; iconButtonBorderRadius?: string; dialogBorderRadius?: string; formInputBorderRadius?: string; imageCardBorderRadius?: string; imageSliderBorderRadius?: string; thumbnailBorderRadius?: string; }; colors?: { backgroundRgb?: string; textColorRgb?: string; textColorDangerRgb?: string; headingColorRgb?: string; primaryButtonBackgroundRgb?: string; primaryButtonColorRgb?: string; neutralButtonBackgroundRgb?: string; neutralButtonColorRgb?: string; dangerButtonBackgroundRgb?: string; dangerButtonColorRgb?: string; statusDotBackgroundRgb?: string; badgeBackgroundRgb?: string; badgeColorRgb?: string; overlayBackground?: string; }; typography?: { headingFontFamily?: string; headingTextTransform?: string; headingFontSize?: number | string; headingLetterSpacing?: number | string; headingLineHeight?: number | string; headingFontWeight?: number | string; textFontFamily?: string; textTextTransform?: string; textFontSize?: number | string; textLetterSpacing?: number | string; textLineHeight?: number | string; textLineHeightParagraph?: number | string; textFontWeight?: number | string; buttonFontFamily?: string; buttonTextTransform?: string; buttonFontSize?: number | string; buttonLetterSpacing?: number | string; buttonLineHeight?: number | string; buttonFontWeight?: number | string; badgeFontFamily?: string; badgeTextTransform?: string; badgeFontSize?: number | string; badgeLetterSpacing?: number | string; badgeLineHeight?: number | string; badgeFontWeight?: number | string; }; productCard?: { productCardTitleFontSize?: number | string; productCardTitleFontWeight?: number | string; productCardTitleColor?: string; }; navigation?: { navHeight?: number | string; navBackground?: string; navShadow?: string; navLabelFontSize?: number | string; navLabelTextTransform?: string; navLabelLetterSpacing?: number | string; navActiveIndicatorColor?: string; }; optionPill?: { optionPillHeight?: number | string; optionPillBorderRadius?: string; optionPillBackground?: string; optionPillBorderColor?: string; optionPillFontSize?: number | string; optionPillPadding?: number | string; optionPillSelectedBackground?: string; optionPillSelectedColor?: string; optionPillSelectedBorderColor?: string; }; drawer?: { drawerWidth?: number | string; drawerMobileTopOffset?: number | string; }; imageSlider?: { imageSliderDotColorSelected?: string; }; saveButtonOnImage?: { saveButtonOnImageIconFill?: string; saveButtonOnImageIconColor?: string; saveButtonOnImageBackground?: string; saveButtonOnImageSavedIconFill?: string; saveButtonOnImageSavedIconColor?: string; saveButtonOnImageSavedBackground?: string; saveButtonOnImageBackgroundSize?: number | string; saveButtonOnImageIconSize?: number | string; saveButtonOnImageIconThickness?: number | string; }; saveButtonOnPage?: { saveButtonOnPageIconFill?: string; saveButtonOnPageColor?: string; saveButtonOnPageBackground?: string; saveButtonOnPageSavedIconFill?: string; saveButtonOnPageSavedColor?: string; saveButtonOnPageSavedBackground?: string; saveButtonOnPageIconSize?: number | string; saveButtonOnPageIconThickness?: number | string; }; } export interface ViewSection { type: TType; hidden?: boolean; design?: Record; options?: Record; } export type DrawerSection = DrawerSectionParsed; export type HomeSection = HomeSectionParsed; export type ContentBlockSection = ContentBlockSectionParsed; export type SavesSection = SavesSectionParsed; export type ListsSection = ListsSectionParsed; export type ListDetailSection = ListDetailSectionParsed; export type ListDetailPageSection = ListDetailPageSectionParsed; export type OrdersSection = OrdersSectionParsed; export type OrderDetailSection = OrderDetailSectionParsed; export type ProductDetailSection = ProductDetailSectionParsed; export type ProfileSection = ProfileSectionParsed; export type NotificationsSection = NotificationsSectionParsed; export interface DrawerLogoInput { url?: string; altText?: string; } export interface FooterMenuItemInput { id: string; enabled: boolean; intent: Intent; } export type DrawerSectionInput = (ViewSection<"drawer-header"> & { options?: { title?: string; logo?: DrawerLogoInput; useCloseButton?: boolean; accountButton?: boolean; /** "profile" | "shopify" | a URL. See DrawerHeaderSectionSchema. */ accountButtonUrl?: string; notificationButton?: boolean; }; }) | (ViewSection<"drawer-footer"> & { options?: { displayType?: "floating" | "docked"; showIcons?: boolean; showText?: boolean; /** Multiplier on the footer menu label size. 1 = theme default. */ fontScale?: number; items?: FooterMenuItemInput[]; }; }); export interface MiniMenuItemInput { title: string; url: string; } export type SimpleHomeSectionType = "notifications" | "recently-viewed" | "saved-from-cart" | "saved-items" | "lists"; export type SignInSectionInput = ViewSection<"sign-in"> & { options?: { message?: string; }; }; export type ContentBlockSectionInput = ViewSection<"content-block"> & { title?: string; body?: string; image?: { url: string; width?: number; height?: number; }; link?: { url: string; target?: "_self" | "_blank"; }; visibleTo?: { audience?: "all" | "signed-in" | "signed-out"; customerTags?: string[]; }; }; export type HomeSectionInput = SignInSectionInput | ViewSection | (ViewSection<"mini-menu"> & { items?: MiniMenuItemInput[]; }) | ContentBlockSectionInput | (ViewSection<"featured-collection"> & { handle: string; }); export type SavesSectionInput = SignInSectionInput | (ViewSection<"lists-section"> & { options?: { display?: "myLists" | "forYouLists"; layout?: "list" | "slider"; }; }) | (ViewSection<"all-items-grid"> & { options?: { layout?: "gallery" | "card"; showVendor?: boolean; showSaveButton?: boolean; showQuickBuyButton?: boolean; showBuyButton?: boolean; showVariantTitle?: boolean; enableVariantChange?: boolean; showVariantOptionNames?: boolean; hideCompareAtPrice?: boolean; }; }) | ContentBlockSectionInput; export type ListsSectionInput = SignInSectionInput | (ViewSection<"lists-grid"> & { options?: { displayType?: "list" | "slider"; }; }) | ContentBlockSectionInput; export type ListDetailPageSectionInput = ViewSection<"list-items-grid"> & { options?: { layout?: "gallery" | "card"; showVendor?: boolean; desktopColumns?: number; showBuyButton?: boolean; showQuickBuyButton?: boolean; showVariantTitle?: boolean; showVariantOptionNames?: boolean; enableVariantChange?: boolean; hideCompareAtPrice?: boolean; linkToProductPage?: boolean; }; }; export type ListDetailSectionInput = ViewSection<"list-items-grid"> & { options?: { layout?: "gallery" | "card"; showVendor?: boolean; showBuyButton?: boolean; showQuickBuyButton?: boolean; showVariantTitle?: boolean; showVariantOptionNames?: boolean; enableVariantChange?: boolean; hideCompareAtPrice?: boolean; linkToProductPage?: boolean; }; }; export type OrdersSectionInput = ViewSection<"orders-list">; export type OrderDetailSectionInput = ViewSection<"order-info"> | ViewSection<"order-items"> | ViewSection<"order-actions">; export type VariantSelectDisplay = "pills" | "rows"; export type ProductDetailSectionInput = (ViewSection<"image-slider"> & { options?: { flush?: boolean; loop?: boolean; }; }) | (ViewSection<"product-info"> & { options?: { variantSelectDisplayType?: VariantSelectDisplay; hideSingleValueOptions?: boolean; descriptionMaxLines?: number; }; }) | ViewSection<"buy-buttons"> | (ViewSection<"complementary-products"> & { options?: { showQuickBuyButton?: boolean; showSaveButton?: boolean; }; }) | (ViewSection<"related-products"> & { options?: { showQuickBuyButton?: boolean; showSaveButton?: boolean; }; }); export type ProfileSectionInput = ViewSection<"profile-form">; export type NotificationsSectionInput = ViewSection<"notifications-list">; export interface DrawerOptions { design?: Record; options?: { position?: "left" | "right"; }; sections: DrawerSection[]; } export interface HomeViewOptions { sections: HomeSection[]; } export interface SavesViewOptions { sections: SavesSection[]; } export interface ListsViewOptions { sections: ListsSection[]; } export interface ListDetailViewOptions { sections: ListDetailSection[]; } export interface ListDetailPageViewOptions { sections: ListDetailPageSection[]; } export interface OrdersViewOptions { sections: OrdersSection[]; } export interface OrderDetailViewOptions { sections: OrderDetailSection[]; } export interface ProductDetailViewOptions { sections: ProductDetailSection[]; } export interface ProfileViewOptions { sections: ProfileSection[]; } export interface NotificationsViewOptions { sections: NotificationsSection[]; } export type ViewSectionMap = { drawer: DrawerSection; home: HomeSection; saves: SavesSection; lists: ListsSection; listDetail: ListDetailSection; listDetailPage: ListDetailPageSection; orders: OrdersSection; orderDetail: OrderDetailSection; productDetail: ProductDetailSection; profile: ProfileSection; notifications: NotificationsSection; };