# Types: Review to VariantPickerProps (/themes/sdk/reference/product/types-3)

```ts
import { … } from '@poltura/theme-sdk/product';
```

## `Review` [#review]

A published review of a product.

<TypeTable type={{"id":{"description":"The review's id.","type":"string","required":true},"productId":{"description":"The product the review is about.","type":"string","required":true},"author":{"description":"The reviewer's display name.","type":"string","required":true},"rating":{"description":"The star rating, from 1 to 5.","type":"number","required":true},"title":{"description":"The review's title.","type":"string","required":true},"body":{"description":"The review's text.","type":"string","required":true},"verifiedPurchase":{"description":"Whether the reviewer bought the product from the store.","type":"boolean","required":true},"storeReply":{"description":"The store's public reply under the review; the review itself is always the customer's.","type":"{ readonly body: string; readonly createdAt: string | null; } | null","required":false},"createdAt":{"description":"When the review was written, as an ISO 8601 instant.","type":"string","required":true},"source":{"description":"Where the review was written: in this store, or imported from another platform; absent reads as `store`.","type":"'store' | 'imported'","required":false},"sourceLabel":{"description":"An imported review's source line in the page language (\"Imported from Trustpilot\"), shown in place of the verified mark; else null.","type":"string | null","required":false}}} />

## `ReviewPage` [#reviewpage]

One page of a product's reviews with its score.

<TypeTable type={{"reviews":{"description":"The reviews on this page, newest first.","type":"readonly Review[]","required":true},"stats":{"description":"The product's review score over every review.","type":"RatingStats","required":true},"page":{"description":"The page number, from 1.","type":"number","required":true},"pageCount":{"description":"How many pages there are.","type":"number","required":true},"policy":{"description":"How the store checks reviews before they appear, which the review block states.","type":"ReviewPolicy","required":false}}} />

## `ReviewPolicy` [#reviewpolicy]

How the store checks reviews, from its own settings.

<TypeTable type={{"checked":{"description":"Which reviews wait for the store's check: every one, the unverified, the verified or none.","type":"'all' | 'unverified' | 'verified' | 'none'","required":true},"checkedBelowRating":{"description":"Reviews under this many stars also wait for a check; null when no rating rule is set.","type":"number | null","required":true},"imported":{"description":"Some reviews were imported from another platform, unchecked by the store.","type":"boolean","required":false},"rewarded":{"description":"Writing a review can earn loyalty points, whatever the rating.","type":"boolean","required":false},"statement":{"description":"The store's review statement in the page language, one sentence each, to show under the score as `RatingSummary` does.","type":"readonly string[]","required":false}}} />

## `Spec` [#spec]

One row of a product's specification table.

<TypeTable type={{"handle":{"description":"The attribute's stable key, for styling or picking one row.","type":"string","required":true},"label":{"description":"The attribute's name in the page language.","type":"string","required":true},"values":{"description":"The raw values, one per entry.","type":"readonly string[]","required":true},"items":{"description":"The values with their icons, one per entry of `values`, in the same order.","type":"readonly SpecValue[]","required":true},"display":{"description":"The values formatted for display, with units and the locale's numbers.","type":"string","required":true},"unit":{"description":"The unit the values are in, or null.","type":"string | null","required":true}}} />

## `SpecGroup` [#specgroup]

A titled section of a product's specification table.

<TypeTable type={{"id":{"description":"The group's id, or null for the ungrouped rows.","type":"string | null","required":true},"label":{"description":"The group's title, or null for the ungrouped rows, which come first.","type":"string | null","required":true},"specs":{"description":"The group's rows.","type":"readonly Spec[]","required":true}}} />

## `SpecValue` [#specvalue]

One value of a spec as the shopper reads it.

<TypeTable type={{"label":{"description":"The value's text in the page language.","type":"string","required":true},"icon":{"description":"The icon shown beside the label, as `ContentIcon` draws it (a platform logo such as `logo:steam`, a content icon or an uploaded SVG), or null.","type":"IconValue | null","required":true}}} />

## `Swatch` [#swatch]

The swatch a variant option value shows instead of a text button.

<TypeTable type={{"color":{"description":"The swatch colour as `#rrggbb`, or null when it is an image.","type":"string | null","required":true},"color2":{"description":"A second colour for a split swatch, or null.","type":"string | null","required":true},"image":{"description":"A pattern or photo swatch, or null when it is a colour.","type":"MediaImageRef | null","required":true}}} />

## `UnavailableReason` [#unavailablereason]

Why a variant cannot be bought right now.

```ts
type UnavailableReason = 'outOfStock' | 'preorderFull' | 'paused' | 'restricted'
```

## `Variant` [#variant]

One buyable version of a product, such as the red one in size M.

<TypeTable type={{"id":{"description":"The variant's id; pass it to the cart.","type":"string","required":true},"title":{"description":"The variant's title, such as \"Red / M\".","type":"string","required":true},"sku":{"description":"The stock keeping unit, or null.","type":"string | null","required":true},"options":{"description":"The chosen value id per option id.","type":"Readonly<Record<string, string>>","required":true},"price":{"description":"The variant's price.","type":"PriceView","required":true},"availability":{"description":"Whether and how the variant can be bought.","type":"Availability","required":true},"imageIds":{"description":"Ids of the product images that show this variant, first one leading.","type":"readonly string[]","required":true},"unitPricing":{"description":"The variant's contents and unit-price base, or null when it has no measured contents.","type":"UnitPricing | null","required":true}}} />

## `VariantPickerValue` [#variantpickervalue]

One value of an option in the variant picker, with what choosing it would lead to.

<TypeTable type={{"id":{"description":"The value's id.","type":"string","required":true},"label":{"description":"The value in the page language.","type":"string","required":true},"swatch":{"description":"The value's swatch, or null when it has none.","type":"Swatch | null","required":true},"selected":{"description":"Whether the value is the current choice.","type":"boolean","required":true},"selectable":{"description":"Whether choosing it can still lead to a variant that can be bought.","type":"boolean","required":true},"availability":{"description":"The availability of the variant this value completes with the other choices, or null when none does.","type":"Availability | null","required":true}}} />

## `VariantPickerOption` [#variantpickeroption]

One option of the variant picker, such as colour or size.

<TypeTable type={{"id":{"description":"The option's id.","type":"string","required":true},"title":{"description":"The option's name in the page language.","type":"string","required":true},"display":{"description":"How the merchant asked the values to be shown.","type":"ProductOptionDisplay","required":true},"values":{"description":"The values, in the merchant's order.","type":"readonly VariantPickerValue[]","required":true}}} />

## `VariantPickerState` [#variantpickerstate]

The variant picker's state: the options with their values, the current choice and the variant it picks.

<TypeTable type={{"options":{"description":"The options that pick a variant; empty for a single-variant product or outside a product.","type":"readonly VariantPickerOption[]","required":true},"select":{"description":"Chooses a value of an option.","type":"(optionId: string, valueId: string) => void","required":true},"selected":{"description":"The chosen value id per option id.","type":"Readonly<Record<string, string>>","required":true},"variant":{"description":"The variant the choice picks, or null while the choice matches none.","type":"Variant | null","required":true}}} />

## `VariantPickerClasses` [#variantpickerclasses]

Class names for the pieces of [`VariantPicker`](/themes/sdk/reference/product/defaults-1#variantpicker) and [`VariantOption`](/themes/sdk/reference/product/parts-1#variantoption).

<TypeTable type={{"option":{"description":"Each option, its name and values together.","type":"string","required":false},"title":{"description":"Each option's name.","type":"string","required":false},"values":{"description":"The row or dropdown holding an option's values.","type":"string","required":false},"value":{"description":"Each value; set by {@link VariantPicker}.","type":"string","required":false}}} />

## `VariantPickerProps` [#variantpickerprops]

Props of [`VariantPicker`](/themes/sdk/reference/product/defaults-1#variantpicker).

<TypeTable type={{"display":{"description":"`dropdown` shows every option as a dropdown; `auto` follows each option's own display.","type":"'auto' | 'dropdown'","required":false},"showTitles":{"description":"Shows each option's name above its values; on by default.","type":"boolean","required":false},"boxed":{"description":"Draws the picker in a card box.","type":"boolean","required":false},"classes":{"description":"Classes added to the pieces.","type":"VariantPickerClasses","required":false},"className":{"description":"Classes added to the picker.","type":"string","required":false}}} />
