import { Component } from 'vue'; import { GraphQLClient, Product, Contact, Customer, Cart, CartMainItem, CartChildItemInput } from '@propeller-commerce/propeller-sdk-v2'; export interface ProductCardProps { /** The product object to display */ product: Product; /** Currency symbol to display. Defaults to '€'. */ currency?: string; /** Show the product name. Defaults to true. */ showName?: boolean; /** Show the product image. Defaults to true. */ showImage?: boolean; /** Show the product short description. Defaults to false. */ showShortDescription?: boolean; /** Show the product SKU. Defaults to true. */ showSku?: boolean; /** Show the product manufacturer. Defaults to false. */ showManufacturer?: boolean; /** * Show the stock / availability widget below the product name. * Uses the embedded `ItemStock` component driven by `product.inventory`. * Defaults to false. */ showStock?: boolean; /** * Show only the availability indicator (Available / Not available) inside ItemStock. * Only relevant when `showStock` is true. * Defaults to true. */ showAvailability?: boolean; /** * Show the price below the product name. * Defaults to true. */ showPrice?: boolean; /** * Show the AddToCart component. * Defaults to true. */ allowAddToCart?: boolean; /** * Label overrides forwarded to the embedded ItemStock component. * Keys: inStock, outOfStock, lowStock, available, notAvailable, pieces */ stockLabels?: Record; /** Translated labels forwarded to the embedded `` display. * See `ProductPriceProps.labels` for slugs (inclTax, exclTax, loginToSeePrices). */ priceLabels?: Record; /** * Attribute codes/names to look up and display as badge overlays on the product image. * Each code is resolved against `product.attributes.items[].attributeDescription.code` * (or `.name`). Attributes with no matching value are silently omitted. * Example: ['new', 'sale'] */ imageLabels?: string[]; /** * Attribute codes/names to look up and display as extra text rows below the product name. * Resolved the same way as `imageLabels`. * Example: ['brand', 'color'] */ textLabels?: string[]; /** * Override any UI string. * Available keys: addToFavorites, removeFromFavorites */ labels?: Record; /** Renders a heart-icon toggle button on the product image. Defaults to false. */ enableAddFavorite?: boolean; /** * Called whenever the favourite state is toggled. * The second argument indicates the new state: `true` = added, `false` = removed. */ onToggleFavorite?: (product: Product, isFavorite: boolean) => void; /** * Called when the product name or image is clicked. * When provided, the default `` navigation is prevented so the consumer * can use framework-specific routing (e.g. Next.js `router.push`). */ onProductClick?: (product: Product) => void; /** * When true, tax-inclusive price (net) is the leading price. * When false, tax-exclusive price (gross) is shown. * Defaults to false. */ includeTax?: boolean; /** Number of grid columns — when 1 the card renders as a compact horizontal row. */ columns?: number; /** Extra CSS class applied to the root element. */ className?: string; /** * URL pattern controlling which segments appear in product links. * Tokens: page → 'product', id → productId, slug → slug value. * Examples: 'page/id/slug' (default) | 'page/slug' | 'page/id' * Defaults to 'page/id/slug' when omitted. */ urlPattern?: string; /** Initialised Propeller SDK GraphQL client (required by embedded AddToCart). Resolved from PropellerProvider when omitted. */ graphqlClient?: GraphQLClient; /** Authenticated user — used for cart creation / lookup. Resolved from PropellerProvider when omitted. */ user?: Contact | Customer | null; /** * Portal access mode — `'open'` / `'semi-closed'` / `'closed'`. Resolved from * PropellerProvider when omitted. In `'semi-closed'` the card hides price and * stock from anonymous visitors and offers a log-in action in place of * add-to-cart; signed-in users are unaffected. */ portalMode?: string; /** * Invoked when an anonymous visitor clicks the log-in action that replaces * add-to-cart in a semi-closed portal. The host owns navigation. */ onLoginClick?: () => void; /** ID of an existing cart to add items to. */ cartId?: string; /** Config object providing imageSearchFiltersGrid and imageVariantFiltersSmall. */ configuration?: any; /** Cluster ID for configurable products. */ clusterId?: number; /** Product IDs of selected cluster child options. */ childItems?: number[]; /** Free-text notes attached to the cart item. */ notes?: string; /** Custom unit price override. Omit to use calculated price. */ price?: number; /** * When true and no cartId is available, the embedded AddToCart automatically * looks up or creates a cart. Always pair with onCartCreated. */ createCart?: boolean; /** Called after a new cart is created internally by AddToCart. */ onCartCreated?: (cart: Cart) => void; /** * Fully replaces the internal CartService.addItemToCart call inside AddToCart. * Must return a Cart object. */ onAddToCart?: (product: Product, clusterId?: number, quantity?: number, childItems?: CartChildItemInput[], notes?: string, price?: number, showModal?: boolean) => Cart; /** Called after every successful add-to-cart. Receives the updated cart and the added item. */ afterAddToCart?: (cart: Cart, item?: CartMainItem) => void; /** * When true the embedded AddToCart shows a modal after a successful add * instead of the default toast notification. Defaults to false. */ showModal?: boolean; /** * Renders − and + buttons beside the quantity input in AddToCart. * Defaults to true. */ allowIncrDecr?: boolean; /** Validate stock before adding to cart. Defaults to false. */ enableStockValidation?: boolean; /** Language code forwarded to CartService operations. Defaults to 'NL'. */ language?: string; /** * Active company ID from the company switcher. * When provided, overrides the user's default company for cart creation and lookup. */ companyId?: number; /** Called when the user clicks "Proceed to checkout" inside the AddToCart modal. */ onProceedToCheckout?: () => void; /** Called when the user clicks "Request a Quote" inside the AddToCart modal. */ onRequestQuoteClick?: (cart: Cart) => void; /** Label overrides for UI strings * * available labels: * - outOfStock * - noCartId * - errorAdding * - addedToCart * - modalTitle * - quantity * - continueShopping * - proceedToCheckout * - requestQuoteButton * - add * - adding */ addToCartLabels?: Record; priceComponent?: Component; stockComponent?: Component; addToCartComponent?: Component; imageComponent?: Component; badgesComponent?: Component; favoriteComponent?: Component; /** * Render arbitrary content directly below the product name (and above the * short description / price), in both the grid and row layouts. Receives the * product as a prop so hosts can surface extra info — e.g. package * descriptions, custom badges — without forking the card. Consumers can also * use the `#belowName` scoped slot directly; this prop is the cascadable * (grid-wide) equivalent. */ belowNameComponent?: Component; } interface ProductCardState { isFavorite: boolean; getProductName: () => string; getProductSku: () => string; getProductImageUrl: () => string; getProductPrice: () => string; getProductUrl: () => string; getProductShortDescription: () => string; getProductManufacturer: () => string; getLabel: (key: string, fallback: string) => string; getAttributeValue: (code: string) => string; handleProductClick: (e: any) => void; handleToggleFavorite: (e: any) => void; isRow: () => boolean; computedImageLabels: () => string[]; computedTextLabels: () => { name: string; value: string; }[]; } declare function handleNavigate(): void; declare function handleProductClick(e: any): ReturnType; declare function handleToggleFavorite(e: any): ReturnType; declare function __VLS_template(): { attrs: Partial<{}>; slots: { image?(_: { product: Product; language: string | undefined; imageUrl: string; imageSearchFilters: any; imageVariantFilters: any; onNavigate: typeof handleNavigate; }): any; badges?(_: { product: Product; imageLabels: string[]; labels: Record | undefined; }): any; favorite?(_: { product: Product; isFavorite: boolean; toggle: typeof handleToggleFavorite; labels: Record | undefined; }): any; sku?(_: { product: Product; sku: string; }): any; sku?(_: { product: Product; sku: string; }): any; name?(_: { product: Product; productUrl: string; handleProductClick: typeof handleProductClick; linkable: boolean; name: string; onNavigate: typeof handleNavigate; }): any; name?(_: { product: Product; productUrl: string; handleProductClick: typeof handleProductClick; linkable: boolean; name: string; onNavigate: typeof handleNavigate; }): any; belowName?(_: { product: Product; }): any; belowName?(_: { product: Product; }): any; textLabels?(_: { product: Product; values: { name: string; value: string; }[]; }): any; textLabels?(_: { product: Product; values: { name: string; value: string; }[]; }): any; manufacturer?(_: { product: Product; manufacturer: string; }): any; manufacturer?(_: { product: Product; manufacturer: string; }): any; shortDescription?(_: { product: Product; text: string; }): any; shortDescription?(_: { product: Product; text: string; }): any; stock?(_: { product: Product; inventory: import('@propeller-commerce/propeller-sdk-v2').ProductInventory | undefined; showAvailability: boolean; labels: Record | undefined; }): any; stock?(_: { product: Product; inventory: import('@propeller-commerce/propeller-sdk-v2').ProductInventory | undefined; showAvailability: boolean; labels: Record | undefined; }): any; stock?(_: { product: Product; inventory: import('@propeller-commerce/propeller-sdk-v2').ProductInventory | undefined; showAvailability: boolean; labels: Record | undefined; }): any; price?(_: { product: Product; price: import('@propeller-commerce/propeller-sdk-v2').ProductPrice; includeTax: boolean; currency: string | undefined; labels: Record | undefined; }): any; price?(_: { product: Product; price: import('@propeller-commerce/propeller-sdk-v2').ProductPrice; includeTax: boolean; currency: string | undefined; labels: Record | undefined; }): any; price?(_: { product: Product; price: import('@propeller-commerce/propeller-sdk-v2').ProductPrice; includeTax: boolean; currency: string | undefined; labels: Record | undefined; }): any; addToCart?(_: { product: Product; cartId: string | undefined; labels: Record | undefined; }): any; addToCart?(_: { product: Product; cartId: string | undefined; labels: Record | undefined; }): any; }; refs: {}; rootEl: HTMLDivElement; }; type __VLS_TemplateResult = ReturnType; declare const __VLS_component: import('vue').DefineComponent & Readonly<{}>, { showPrice: boolean; showStock: boolean; showAvailability: boolean; enableAddFavorite: boolean; allowAddToCart: boolean; allowIncrDecr: boolean; showSku: boolean; showName: boolean; showImage: boolean; showShortDescription: boolean; showManufacturer: boolean; }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>; declare const _default: __VLS_WithTemplateSlots; export default _default; type __VLS_WithTemplateSlots = T & { new (): { $slots: S; }; };