'use client' import React from 'react' import { observer } from 'mobx-react-lite' import * as RadioGroupPrimitive from "@radix-ui/react-radio-group" import { Image, Label, RadioGroup, ScrollArea } from '@hanzo/ui/primitives' import { cn } from '@hanzo/ui/util' import type { Dimensions } from '@hanzo/ui/types' import type { ItemSelectorProps, LineItem } from '../../types' import { accessItemOptions, formatCurrencyValue } from '../../util' import QuantityIndicator from './quantity-indicator' const DEFAULT_CONSTRAINT = {h: 36, w: 72} // // Apple suggest 42px for clickability const ImageRadioGroupItem = React.forwardRef< React.ElementRef, Omit, 'value' | 'id'> & { item: LineItem, constrainTo: Dimensions } >(({ item, constrainTo, className, ...props }, ref) => { const img = item.optionImg ? item.optionImg : item.img return ( {img ? ( ) : ( // placeholder so things align
)} ) }) ImageRadioGroupItem.displayName = 'ImageRadioGroupItem' const ButtonItemSelector: React.FC = observer(({ items, selectedItemRef: itemRef, selectSku, clx='', itemClx='', soleItemClx='', scrollable=false, mobile=false, options={} }) => { const { showPrice, showQuantity, showFamilyInOption, buttonType, horizButtons, showButtonIfOnlyOne } = accessItemOptions(options) const showImage = buttonType !== 'text' const showText = buttonType !== 'image' const showBoth = buttonType === 'image-and-text' const labelAndPrice = (item : LineItem) => ( (showFamilyInOption ? (item.familyTitle + ', ' + item.optionLabel) : item.optionLabel) + (showPrice ? ((showFamilyInOption ? ': ' : ', ') + formatCurrencyValue(item.price)) : '') ) const Item: React.FC<{ item: LineItem selected: boolean }> = observer(({ item, selected }) => { const textClx = (selected) ? 'text-accent' : 'text-muted' const cursorClx = (selected) ? 'hover:cursor-default' : 'hover:cursor-pointer' const justifyClx = (showBoth) ? '' : 'justify-center' // If no image, the Label must fill the entire button since it has to be // clickable all the way to the border const paddingClx = (showImage) ? (scrollable ? 'px-4 py-2' : 'px-2 py-2' ) : '' let bgClx = '' let borderClx = '' if (scrollable) { borderClx += (selected) ? 'border-foreground border ' : 'border-b border-muted-2 ' } else if (!showImage) { borderClx += 'border rounded-lg ' borderClx += (selected) ? 'border-foreground ' : 'border-muted-2 ' bgClx += 'hover:bg-level-2' } const outerClx = ['h-10 flex items-center', justifyClx, paddingClx, bgClx, borderClx] return (
) }) return showButtonIfOnlyOne || items.length > 1 ? ( {scrollable ? ( {items.map((item) => ( ))} ) : (<> {items.map((item) => ( ))} )} ) : (
{labelAndPrice(items[0])}
{showQuantity && ( )}
) }) export default ButtonItemSelector