diff --git a/.changeset/major-turtles-shout.md b/.changeset/major-turtles-shout.md new file mode 100644 index 00000000..00d6a4d5 --- /dev/null +++ b/.changeset/major-turtles-shout.md @@ -0,0 +1,9 @@ +--- +"@godaddy/localizations": patch +"@godaddy/react": patch +--- + +- Add filtering by `productIds` and `categoryIds` to ProductGrid +- Add `productId` prop to ProductCard for single product rendering +- Add pagination support to ProductGrid with `enablePagination` prop +- Add translations for pagination controls \ No newline at end of file diff --git a/examples/nextjs/app/store/products.tsx b/examples/nextjs/app/store/products.tsx index 48a01459..dadce850 100644 --- a/examples/nextjs/app/store/products.tsx +++ b/examples/nextjs/app/store/products.tsx @@ -1,6 +1,6 @@ 'use client'; -import { ProductGrid } from '@godaddy/react'; +import { ProductGrid, ProductSearch } from '@godaddy/react'; import { useCart } from './layout'; export default function ProductsPage() { @@ -8,7 +8,11 @@ export default function ProductsPage() { return (
+
+ +
`/store/product/${sku}`} onAddToCartSuccess={openCart} /> diff --git a/examples/nextjs/package.json b/examples/nextjs/package.json index ba69a659..7dec0734 100644 --- a/examples/nextjs/package.json +++ b/examples/nextjs/package.json @@ -15,7 +15,7 @@ "@tanstack/react-query": "^5.66.0", "@tanstack/react-query-devtools": "^5.76.1", "lucide-react": "^0.475.0", - "next": "16.0.1", + "next": "16.0.7", "react": "19.2.0", "react-dom": "19.2.0", "zod": "^3.24.1" diff --git a/packages/localizations/src/deDe.ts b/packages/localizations/src/deDe.ts index 185dc2a9..9c186fa8 100644 --- a/packages/localizations/src/deDe.ts +++ b/packages/localizations/src/deDe.ts @@ -384,5 +384,8 @@ export const deDe = { remove: 'Entfernen', removing: 'Wird entfernt...', checkout: 'Zur Kasse', + itemsPerPage: 'Artikel pro Seite:', + search: 'Suchen', + searchPlaceholder: 'Produkte suchen...', }, }; diff --git a/packages/localizations/src/enIe.ts b/packages/localizations/src/enIe.ts index b53fda8c..8e3baf6f 100644 --- a/packages/localizations/src/enIe.ts +++ b/packages/localizations/src/enIe.ts @@ -361,5 +361,8 @@ export const enIe = { remove: 'Remove', removing: 'Removing...', checkout: 'Checkout', + itemsPerPage: 'Items per page:', + search: 'Search', + searchPlaceholder: 'Search products...', }, }; diff --git a/packages/localizations/src/enUs.ts b/packages/localizations/src/enUs.ts index c7a7f8f1..2458daa0 100644 --- a/packages/localizations/src/enUs.ts +++ b/packages/localizations/src/enUs.ts @@ -361,5 +361,8 @@ export const enUs = { remove: 'Remove', removing: 'Removing...', checkout: 'Checkout', + itemsPerPage: 'Items per page:', + search: 'Search', + searchPlaceholder: 'Search products...', }, }; diff --git a/packages/localizations/src/esAr.ts b/packages/localizations/src/esAr.ts index 1386d8cc..c55877dd 100644 --- a/packages/localizations/src/esAr.ts +++ b/packages/localizations/src/esAr.ts @@ -367,5 +367,8 @@ export const esAr = { remove: 'Eliminar', removing: 'Eliminando...', checkout: 'Pagar', + itemsPerPage: 'Artículos por página:', + search: 'Buscar', + searchPlaceholder: 'Buscar productos...', }, }; diff --git a/packages/localizations/src/esCl.ts b/packages/localizations/src/esCl.ts index 62512931..100aa97b 100644 --- a/packages/localizations/src/esCl.ts +++ b/packages/localizations/src/esCl.ts @@ -369,5 +369,8 @@ export const esCl = { remove: 'Eliminar', removing: 'Eliminando...', checkout: 'Pagar', + itemsPerPage: 'Artículos por página:', + search: 'Buscar', + searchPlaceholder: 'Buscar productos...', }, }; diff --git a/packages/localizations/src/esCo.ts b/packages/localizations/src/esCo.ts index 29ac90fc..5c34644b 100644 --- a/packages/localizations/src/esCo.ts +++ b/packages/localizations/src/esCo.ts @@ -367,5 +367,8 @@ export const esCo = { remove: 'Eliminar', removing: 'Eliminando...', checkout: 'Pagar', + itemsPerPage: 'Artículos por página:', + search: 'Buscar', + searchPlaceholder: 'Buscar productos...', }, }; diff --git a/packages/localizations/src/esEs.ts b/packages/localizations/src/esEs.ts index 5b5780ad..a2220308 100644 --- a/packages/localizations/src/esEs.ts +++ b/packages/localizations/src/esEs.ts @@ -372,5 +372,8 @@ export const esEs = { remove: 'Eliminar', removing: 'Eliminando...', checkout: 'Pagar', + itemsPerPage: 'Artículos por página:', + search: 'Buscar', + searchPlaceholder: 'Buscar productos...', }, }; diff --git a/packages/localizations/src/esMx.ts b/packages/localizations/src/esMx.ts index c03d4cbd..c484e103 100644 --- a/packages/localizations/src/esMx.ts +++ b/packages/localizations/src/esMx.ts @@ -368,5 +368,8 @@ export const esMx = { remove: 'Eliminar', removing: 'Eliminando...', checkout: 'Pagar', + itemsPerPage: 'Artículos por página:', + search: 'Buscar', + searchPlaceholder: 'Buscar productos...', }, }; diff --git a/packages/localizations/src/esPe.ts b/packages/localizations/src/esPe.ts index 36ba50cf..ccae27f8 100644 --- a/packages/localizations/src/esPe.ts +++ b/packages/localizations/src/esPe.ts @@ -367,5 +367,8 @@ export const esPe = { remove: 'Eliminar', removing: 'Eliminando...', checkout: 'Pagar', + itemsPerPage: 'Artículos por página:', + search: 'Buscar', + searchPlaceholder: 'Buscar productos...', }, }; diff --git a/packages/localizations/src/esUs.ts b/packages/localizations/src/esUs.ts index 1a937cd4..da390efe 100644 --- a/packages/localizations/src/esUs.ts +++ b/packages/localizations/src/esUs.ts @@ -367,5 +367,8 @@ export const esUs = { remove: 'Eliminar', removing: 'Eliminando...', checkout: 'Pagar', + itemsPerPage: 'Artículos por página:', + search: 'Buscar', + searchPlaceholder: 'Buscar productos...', }, }; diff --git a/packages/localizations/src/frCa.ts b/packages/localizations/src/frCa.ts index a0ffb957..26edeb97 100644 --- a/packages/localizations/src/frCa.ts +++ b/packages/localizations/src/frCa.ts @@ -384,5 +384,8 @@ export const frCa = { remove: 'Supprimer', removing: 'Suppression...', checkout: 'Commander', + itemsPerPage: 'Articles par page :', + search: 'Rechercher', + searchPlaceholder: 'Rechercher des produits...', }, }; diff --git a/packages/localizations/src/frFr.ts b/packages/localizations/src/frFr.ts index da188eb8..13abdf5f 100644 --- a/packages/localizations/src/frFr.ts +++ b/packages/localizations/src/frFr.ts @@ -385,5 +385,8 @@ export const frFr = { remove: 'Supprimer', removing: 'Suppression...', checkout: 'Commander', + itemsPerPage: 'Articles par page :', + search: 'Rechercher', + searchPlaceholder: 'Rechercher des produits...', }, }; diff --git a/packages/localizations/src/idId.ts b/packages/localizations/src/idId.ts index 9bb8fe49..280aac48 100644 --- a/packages/localizations/src/idId.ts +++ b/packages/localizations/src/idId.ts @@ -360,5 +360,8 @@ export const idId = { remove: 'Hapus', removing: 'Menghapus...', checkout: 'Checkout', + itemsPerPage: 'Item per halaman:', + search: 'Cari', + searchPlaceholder: 'Cari produk...', }, }; diff --git a/packages/localizations/src/itIt.ts b/packages/localizations/src/itIt.ts index 41ee362d..20fb884a 100644 --- a/packages/localizations/src/itIt.ts +++ b/packages/localizations/src/itIt.ts @@ -384,5 +384,8 @@ export const itIt = { remove: 'Rimuovi', removing: 'Rimozione...', checkout: 'Acquista', + itemsPerPage: 'Articoli per pagina:', + search: 'Cerca', + searchPlaceholder: 'Cerca prodotti...', }, }; diff --git a/packages/localizations/src/ptBr.ts b/packages/localizations/src/ptBr.ts index a439ed70..64a36964 100644 --- a/packages/localizations/src/ptBr.ts +++ b/packages/localizations/src/ptBr.ts @@ -365,5 +365,8 @@ export const ptBr = { remove: 'Remover', removing: 'Removendo...', checkout: 'Finalizar compra', + itemsPerPage: 'Itens por página:', + search: 'Pesquisar', + searchPlaceholder: 'Pesquisar produtos...', }, }; diff --git a/packages/localizations/src/qaPs.ts b/packages/localizations/src/qaPs.ts index 21a13abe..2b320271 100644 --- a/packages/localizations/src/qaPs.ts +++ b/packages/localizations/src/qaPs.ts @@ -369,5 +369,8 @@ export const qaPs = { remove: '[Remove]', removing: '[Removing...]', checkout: '[Checkout]', + itemsPerPage: '[Items per page:]', + search: '[Search]', + searchPlaceholder: '[Search products...]', }, }; diff --git a/packages/localizations/src/trTr.ts b/packages/localizations/src/trTr.ts index ad43f753..14cfdfa1 100644 --- a/packages/localizations/src/trTr.ts +++ b/packages/localizations/src/trTr.ts @@ -360,5 +360,8 @@ export const trTr = { remove: 'Kaldır', removing: 'Kaldırılıyor...', checkout: 'Ödeme yap', + itemsPerPage: 'Sayfa başına öğe:', + search: 'Ara', + searchPlaceholder: 'Ürün ara...', }, }; diff --git a/packages/localizations/src/viVn.ts b/packages/localizations/src/viVn.ts index 5ecd5377..436c37ca 100644 --- a/packages/localizations/src/viVn.ts +++ b/packages/localizations/src/viVn.ts @@ -361,5 +361,8 @@ export const viVn = { remove: 'Xóa', removing: 'Đang xóa...', checkout: 'Thanh toán', + itemsPerPage: 'Mục trên mỗi trang:', + search: 'Tìm kiếm', + searchPlaceholder: 'Tìm kiếm sản phẩm...', }, }; diff --git a/packages/localizations/src/zhCn.ts b/packages/localizations/src/zhCn.ts index b09702a8..6cf7c1d9 100644 --- a/packages/localizations/src/zhCn.ts +++ b/packages/localizations/src/zhCn.ts @@ -348,5 +348,8 @@ export const zhCn = { remove: '删除', removing: '正在删除...', checkout: '结账', + itemsPerPage: '每页项目数:', + search: '搜索', + searchPlaceholder: '搜索产品...', }, }; diff --git a/packages/localizations/src/zhSg.ts b/packages/localizations/src/zhSg.ts index 0283ee41..1aaa6d12 100644 --- a/packages/localizations/src/zhSg.ts +++ b/packages/localizations/src/zhSg.ts @@ -348,5 +348,8 @@ export const zhSg = { remove: '删除', removing: '正在删除...', checkout: '结账', + itemsPerPage: '每页项目数:', + search: '搜索', + searchPlaceholder: '搜索产品...', }, }; diff --git a/packages/react/biome.json b/packages/react/biome.json index 1867c26d..a15c0d49 100644 --- a/packages/react/biome.json +++ b/packages/react/biome.json @@ -2,7 +2,11 @@ "$schema": "https://biomejs.dev/schemas/2.3.2/schema.json", "extends": ["biome-config-godaddy/biome.json"], "files": { - "includes": ["**/*", "!!**/src/globals.css"] + "includes": [ + "**/*", + "!!**/src/globals.css", + "!!**/src/globals-tailwind.css" + ] }, "linter": { "rules": { diff --git a/packages/react/package.json b/packages/react/package.json index 1142d9a5..e40e918c 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -67,7 +67,7 @@ "@radix-ui/react-scroll-area": "^1.2.3", "@radix-ui/react-select": "^2.1.6", "@radix-ui/react-separator": "^1.1.2", - "@radix-ui/react-slot": "^1.1.2", + "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-switch": "^1.1.3", "@radix-ui/react-toast": "^1.2.6", "@radix-ui/react-toggle": "^1.1.2", diff --git a/packages/react/src/components/checkout/payment/month-year-mask.tsx b/packages/react/src/components/checkout/payment/month-year-mask.tsx index c8608109..fb8dab1c 100644 --- a/packages/react/src/components/checkout/payment/month-year-mask.tsx +++ b/packages/react/src/components/checkout/payment/month-year-mask.tsx @@ -1,4 +1,3 @@ -// @ts-expect-error const matcher = /(?\d{0,2})(?\s?\/?\s?)(?\d{0,2})/; export function monthYearMask({ value }: { value?: string }) { if (typeof value !== 'string') { diff --git a/packages/react/src/components/storefront/cart.tsx b/packages/react/src/components/storefront/cart.tsx index 9d0472ff..a5021d53 100644 --- a/packages/react/src/components/storefront/cart.tsx +++ b/packages/react/src/components/storefront/cart.tsx @@ -2,7 +2,6 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { Loader2, ShoppingCart } from 'lucide-react'; -import { useEffect, useState } from 'react'; import type { Product } from '@/components/checkout/line-items/line-items'; import { CartLineItems } from '@/components/storefront/cart-line-items'; import { CartTotals } from '@/components/storefront/cart-totals'; @@ -33,11 +32,8 @@ export function Cart({ }: CartProps) { const context = useGoDaddyContext(); const queryClient = useQueryClient(); - const [cartOrderId, setCartOrderId] = useState(null); - - useEffect(() => { - setCartOrderId(getCartOrderId()); - }, []); + // Read cart order ID fresh on every render + const cartOrderId = getCartOrderId(); // Fetch cart order const { @@ -147,7 +143,8 @@ export function Cart({ {!isLoading && error && (

- {t.storefront.failedToLoadCart} {(error as Error).message} + {t.storefront.failedToLoadCart}{' '} + {error instanceof Error ? error.message : String(error)}

+ )} + {showSearchIcon && ( + + )} +
+ + + )} + /> + {showButton && ( + + )} + + + ); +} + +export type { ProductSearchProps }; diff --git a/packages/react/src/components/ui/link.tsx b/packages/react/src/components/ui/link.tsx index b0062e7a..f20ee791 100644 --- a/packages/react/src/components/ui/link.tsx +++ b/packages/react/src/components/ui/link.tsx @@ -27,6 +27,7 @@ export const RouterLink = React.forwardRef< const { Link } = useGoDaddyContext(); const LinkComponent = Link || DefaultLink; + // @ts-expect-error - LinkComponent type inference is tricky with ref return ; }); RouterLink.displayName = 'RouterLink'; diff --git a/packages/react/src/components/ui/pagination.tsx b/packages/react/src/components/ui/pagination.tsx new file mode 100644 index 00000000..f011c127 --- /dev/null +++ b/packages/react/src/components/ui/pagination.tsx @@ -0,0 +1,135 @@ +import { + ChevronLeftIcon, + ChevronRightIcon, + MoreHorizontalIcon, +} from 'lucide-react'; +import * as React from 'react'; +import { Button, buttonVariants } from '@/components/ui/button'; +import { useGoDaddyContext } from '@/godaddy-provider'; +import { cn } from '@/lib/utils'; + +function Pagination({ className, ...props }: React.ComponentProps<'nav'>) { + const { t } = useGoDaddyContext(); + + return ( +