import AdalongWidget from './adalongWidget'; import { Level } from './debug'; import React = require('react'); declare global { interface Window { adalongWidgetAPI: AdalongWidgetAPI; } } /** * Object added to the global scope to easily access all the * instanciated widgets */ export interface AdalongWidgetAPI { widgets: AdalongWidget[]; } export interface DOMEvent { originalEvent: React.BaseSyntheticEvent['nativeEvent']; } export interface PostEvent { post: IMedia; } export interface MediaPosition { position: number; } export interface ProductEvent { product: string; } export type Direction = 'left' | 'right'; export interface CarouselScrollEvent { position: number; direction: Direction; } export interface PostNavigationEvent { direction: Direction; } export interface MinContentEvent { required: number; current: number; } /** * Give information about the widget layout */ export interface LayoutEvent { layout: ISettings['type']; } export interface EventMap { widgetLoaded: { elapsedSeconds?: number; posts: IMedia[]; } & LayoutEvent; /** * The widget has been displayed to the user * This event is emitted only once when the widget * became visible in the viewport for at least 0.5 seconds */ widgetViewed: LayoutEvent; widgetLoadingFailed: {}; thumbnailLoaded: PostEvent & DOMEvent; thumbnailUnavailable: PostEvent & DOMEvent; thumbnailHover: PostEvent & DOMEvent; thumbnailClicked: PostEvent & DOMEvent & MediaPosition; /** * Open the original post by clicking on the username */ originalPostOpened: PostEvent & DOMEvent; shopThisLook: PostEvent & DOMEvent & ProductEvent; postOpened: PostEvent; postClosed: PostEvent; postNavigation: PostNavigationEvent; videoPlayed: PostEvent & DOMEvent; carouselArrowClicked: CarouselScrollEvent & DOMEvent; carouselNativeScroll: CarouselScrollEvent & DOMEvent; minContentNotReached: MinContentEvent; minContentReached: MinContentEvent; } export type EventMapKeys = keyof EventMap; export type EventCallbacks = Array>; export type EventCallback = (event: T) => void; export interface IWidgetEvents { /** * Add a callback to listen to an event * Previously added callbacks won't be overwritten */ onEvent(eventName: EventName, callback: EventCallback): void; /** * Remove a callback previously listening to an event */ offEvent(eventName: EventName, callback?: EventCallback): void; hasSubscribed(eventName: EventMapKeys): boolean; } export interface IDebug { level?: Level; apiUrl?: string; } export interface ISettings { /** * Define the widget layout type */ type: 'carousel' | 'wall' | 'mosaic'; /** * Control the number of content in carousel and wall layouts * or the first content size in pixel in mosaix layouts */ content_size: number; /** * Indicate if the widget should be limited to content for which * you have rights */ rights_agreed: boolean; /** * Show only medias that are diffusion enabled */ diffusion?: boolean; /** * Randomize the content order */ random: boolean; /** * Display the owner name on the content */ display_name: boolean; /** * Display the products link the post view */ shop_this_look: boolean; /** * Maximum number of content to display */ max_media: number | null; /** * Minimum number of content to have to display the widget * If this constraint is not is not respected, * an minContentNotReached event will be emitted */ min_media_to_display: number; /** * Widget localization * Value doesn't come from Widget but it's from Widget Settings */ localization?: string; /** * Shop this look maximum product columns * Set the maximum number of columns you want your products to have. * By default, the maximum number of columns is set to 2. */ shop_this_look_max_columns?: number; } export interface Config { /** * Key that should be unique on the page to represent the widget * Can be used to find the widget in the AdalongWidgetAPI */ id?: string; /** * Class prefix for css styling * Default to adl-wdgt */ classPrefix?: string; /** * Function to customize the query parameters in "shop this look" urls * It should return an object with parameter names as keys */ shopThisLookHandler?: ShopThisLookHandler; /** * Function that should return a React element to be rendered in place * of the default Shop This Look. */ displayCustomShopThisLook?: DisplayCustomShopThisLook; /** * Custom text to display as title of the "Shop this look" section. * Defaults to 'SHOP THE LOOK' */ shopThisLookText?: string; /** * Custom text to display as the undertitle of the "More like this" section (similar linked products). * Defaults to 'MORE LIKE THIS' */ moreLikeThisText?: string; /** * Shop this look custom product buttons * This optional function can be used to generate custom buttons on the shopthislook products. */ getCustomProductButtons?: GetCustomProductButtons; /** * This variable forces the display of carousel arrows in mobile mode * when it is set to true (where native scrolling would be the default behavior). */ displayMobileCarouselArrows?: boolean; /** * This variable let the user hide the left and right arrows in carousel mode */ hideArrows?: boolean; } export interface Sources { productIds?: string[]; collectionIds?: string[]; } export interface IProduct { catalog_id: string; company_id: string; description: string; id: string; image_link: string; link: string; price?: number; currency?: string; title: string; updated_at: string; variant_name?: string; } export interface IMedia { id: string; type: 'image' | 'video' | 'text'; caption: string; source: 'instagram' | 'twitter'; username?: string; post: string; image?: string; video?: string; thumbnail?: string; products?: IProduct[]; productsLinked: { exact?: string[]; similar?: string[]; }; postIndex: number; } export interface IContent { medias: IMedia[]; } export interface IData { settings: ISettings; content: IContent; } export interface ImageSize { w: number; h: number; } export type ShopThisLookHandler = (source: { media: IMedia; product: IProduct; }, targetUrl: string) => void; export type DisplayCustomShopThisLook = (props: { react: typeof React; products?: IProduct[]; media: IMedia; isMobile: boolean; }) => JSX.Element; /** * */ export type CustomProductButtonProps = { onClick: () => void; }; export type CustomProductButton = (props: CustomProductButtonProps) => JSX.Element; export type CustomProductButtons = { topRight?: CustomProductButton; bottomRight?: CustomProductButton; topLeft?: CustomProductButton; bottomLeft?: CustomProductButton; }; export type GetCustomProductButtons = (react: typeof React, product: IProduct, media: IMedia) => CustomProductButtons;