Skip to content
HyperUI for Flutter requires the Style package — this site itself ships no pub package.

Product Cards

Ported from HyperUI’s Product Cards — see Attribution.

const _photoA =
'https://images.unsplash.com/photo-1523381210434-271e8be1f52b?auto=format&fit=crop&q=80&w=1160';
const _photoB =
'https://images.unsplash.com/photo-1523381140794-a1eef18a37c7?auto=format&fit=crop&q=80&w=1160';
class ProductCards1Example extends StatelessWidget {
const ProductCards1Example({super.key});
@override
Widget build(BuildContext context) {
return Style(
'mx-auto max-w-md p-6',
child: Style(
'group block overflow-hidden',
cursor: SystemMouseCursors.click,
children: [
Style(
'relative h-87.5 sm:h-112.5',
children: [
Style(
'absolute inset-0 h-full w-full object-cover opacity-100 group-hover:opacity-0',
child: Image.network(_photoA, fit: BoxFit.cover),
),
Style(
'absolute inset-0 h-full w-full object-cover opacity-0 group-hover:opacity-100',
child: Image.network(_photoB, fit: BoxFit.cover),
),
],
),
Style(
'relative bg-white pt-3',
children: [
const Style(
'text-sm text-gray-700 group-hover:underline group-hover:underline-offset-4',
child: Text('Limited Edition Sports Trainer'),
),
const Style(
'mt-1.5 tracking-wide text-gray-900',
child: Text(r'$189.99'),
),
],
),
],
),
);
}
}

Product with image, title, price and variant count

Section titled “Product with image, title, price and variant count”
const _photoA =
'https://images.unsplash.com/photo-1600185365483-26d7a4cc7519?auto=format&fit=crop&q=80&w=1160';
const _photoB =
'https://images.unsplash.com/photo-1600185365926-3a2ce3cdb9eb?auto=format&fit=crop&q=80&w=1160';
class ProductCards2Example extends StatelessWidget {
const ProductCards2Example({super.key});
@override
Widget build(BuildContext context) {
return Style(
'mx-auto max-w-md p-6',
child: Style(
'group block overflow-hidden',
cursor: SystemMouseCursors.click,
children: [
Style(
'relative h-87.5 sm:h-112.5',
children: [
Style(
'absolute inset-0 h-full w-full object-cover opacity-100 group-hover:opacity-0',
child: Image.network(_photoA, fit: BoxFit.cover),
),
Style(
'absolute inset-0 h-full w-full object-cover opacity-0 group-hover:opacity-100',
child: Image.network(_photoB, fit: BoxFit.cover),
),
],
),
Style(
'relative bg-white pt-3',
children: [
const Style(
'text-sm text-gray-700 group-hover:underline group-hover:underline-offset-4',
child: Text('Limited Edition Sports Trainer'),
),
Style(
'mt-1.5 flex items-center justify-between text-gray-900',
children: const [
Style('tracking-wide', child: Text(r'$189.99')),
Style(
'text-xs tracking-wide uppercase',
child: Text('6 Colors'),
),
],
),
],
),
],
),
);
}
}

Product with image, title, price and description

Section titled “Product with image, title, price and description”
const _photoUrl =
'https://images.unsplash.com/photo-1592921870789-04563d55041c?auto=format&fit=crop&q=80&w=1160';
class ProductCards3Example extends StatelessWidget {
const ProductCards3Example({super.key});
@override
Widget build(BuildContext context) {
return Style(
'mx-auto max-w-md p-6',
child: Style(
'group block',
cursor: SystemMouseCursors.click,
children: [
Style(
'h-87.5 w-full object-cover sm:h-112.5',
child: Image.network(_photoUrl, fit: BoxFit.cover),
),
Style(
'mt-3 flex justify-between text-sm',
children: [
Style.empty(
children: [
const Style(
'text-gray-900 group-hover:underline group-hover:underline-offset-4',
child: Text('Small Headphones'),
),
const Style(
'mt-1.5 text-xs text-pretty text-gray-500',
child: Text(
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quasi nobis, quia '
'soluta quisquam voluptatem nemo.',
),
),
],
),
const Style('text-gray-900', child: Text(r'$299')),
],
),
],
),
);
}
}

Product with rounded image, title and price

Section titled “Product with rounded image, title and price”
const _photoUrl =
'https://images.unsplash.com/photo-1592921870789-04563d55041c?auto=format&fit=crop&q=80&w=1160';
class ProductCards4Example extends StatelessWidget {
const ProductCards4Example({super.key});
@override
Widget build(BuildContext context) {
return Style(
'mx-auto max-w-md p-6',
child: Style(
'group block',
cursor: SystemMouseCursors.click,
children: [
Style(
'aspect-square w-full rounded-sm object-cover',
child: Image.network(_photoUrl, fit: BoxFit.cover),
),
Style(
'mt-3',
children: [
const Style(
'font-medium text-gray-900 group-hover:underline group-hover:underline-offset-4',
child: Text('Simple Watch'),
),
const Style('mt-1 text-sm text-gray-700', child: Text(r'$150')),
],
),
],
),
);
}
}

Product with image, title, price and variant options

Section titled “Product with image, title, price and variant options”
const _photoUrl =
'https://images.unsplash.com/photo-1592921870789-04563d55041c?auto=format&fit=crop&q=80&w=1160';
class ProductCards5Example extends StatelessWidget {
const ProductCards5Example({super.key});
@override
Widget build(BuildContext context) {
return Style(
'mx-auto max-w-md p-6',
child: Style(
'group block',
cursor: SystemMouseCursors.click,
children: [
Style(
'h-87.5 w-full object-cover sm:h-112.5',
child: Image.network(_photoUrl, fit: BoxFit.cover),
),
Style(
'mt-1.5',
children: [
const Style('text-xs text-gray-500', child: Text('Space Grey')),
Style(
'mt-1.5 flex gap-1',
children: [
Style.empty(
children: [
Style.empty(
child: const Style('sr-only', child: Text('Color')),
),
Style(
'flex flex-wrap justify-center gap-1',
children: [
Style.empty(
children: [
const Style('sr-only', child: SizedBox.shrink()),
Style(
'block size-4 cursor-pointer rounded-full bg-[#595759]',
cursor: SystemMouseCursors.click,
child: const Style(
'sr-only',
child: Text('Space Gray'),
),
),
],
),
Style.empty(
children: [
const Style('sr-only', child: SizedBox.shrink()),
Style(
'block size-4 cursor-pointer rounded-full bg-[#d2d3d4]',
cursor: SystemMouseCursors.click,
child: const Style(
'sr-only',
child: Text('Silver'),
),
),
],
),
Style.empty(
children: [
const Style('sr-only', child: SizedBox.shrink()),
Style(
'block size-4 cursor-pointer rounded-full bg-[#d89f97]',
cursor: SystemMouseCursors.click,
child: const Style(
'sr-only',
child: Text('Pink'),
),
),
],
),
Style.empty(
children: [
const Style('sr-only', child: SizedBox.shrink()),
Style(
'block size-4 cursor-pointer rounded-full bg-[#afbfab]',
cursor: SystemMouseCursors.click,
child: const Style(
'sr-only',
child: Text('Pink'),
),
),
],
),
Style.empty(
children: [
const Style('sr-only', child: SizedBox.shrink()),
Style(
'block size-4 cursor-pointer rounded-full bg-[#91a5bb]',
cursor: SystemMouseCursors.click,
child: const Style(
'sr-only',
child: Text('Pink'),
),
),
],
),
],
),
],
),
],
),
Style(
'mt-3 flex justify-between text-sm',
children: const [
Style(
'text-gray-900 group-hover:underline group-hover:underline-offset-4',
child: Text('Small Headphones'),
),
Style('text-gray-900', child: Text(r'$299')),
],
),
],
),
],
),
);
}
}

Product with image, title, price, tag, wishlist and call to action

Section titled “Product with image, title, price, tag, wishlist and call to action”
class CurrentColorIcon extends StatelessWidget
implements StyleReplacedElementWrapper {
const CurrentColorIcon(this.svg, {super.key});
final String svg;
@override
Widget build(BuildContext context) {
final color = IconTheme.of(context).color ?? const Color(0xFF000000);
return SvgPicture.string(svg, theme: SvgTheme(currentColor: color));
}
}
const _photoUrl =
'https://images.unsplash.com/photo-1599481238640-4c1288750d7a?auto=format&fit=crop&q=80&w=1160';
const _heartSvg =
'''<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12z"/></svg>''';
class ProductCards6Example extends StatelessWidget {
const ProductCards6Example({super.key});
@override
Widget build(BuildContext context) {
return Style(
'mx-auto max-w-md p-6',
child: Style(
'group relative block overflow-hidden',
cursor: SystemMouseCursors.click,
children: [
Style(
'absolute end-4 top-4 z-10 rounded-full bg-white p-1.5 text-gray-900 transition hover:text-gray-900/75',
cursor: SystemMouseCursors.click,
children: [
const Style('sr-only', child: Text('Wishlist')),
const Style('size-4', child: CurrentColorIcon(_heartSvg)),
],
),
Style(
'h-64 w-full object-cover transition duration-500 group-hover:scale-105 sm:h-72',
child: Image.network(_photoUrl, fit: BoxFit.cover),
),
Style(
'relative border border-gray-100 bg-white p-6',
children: [
const Style(
'bg-yellow-400 px-3 py-1.5 text-xs font-medium whitespace-nowrap',
display: DisplayType.inline,
child: Text('New'),
),
const Style(
'mt-4 text-lg font-medium text-gray-900',
child: Text('Robot Toy'),
),
const Style(
'mt-1.5 text-sm text-gray-700',
child: Text(r'$14.99'),
),
Style(
'mt-4',
child: Style(
'block w-full rounded-sm bg-yellow-400 p-4 text-sm font-medium transition hover:scale-105',
cursor: SystemMouseCursors.click,
button: true,
child: const Text('Add to Cart'),
),
),
],
),
],
),
);
}
}

Product with image, title, description, offer and call to action

Section titled “Product with image, title, description, offer and call to action”
class ProductCards7Example extends StatelessWidget {
const ProductCards7Example({super.key});
@override
Widget build(BuildContext context) {
return Style(
'mx-auto max-w-md p-6',
child: Style(
'relative block rounded-se-3xl border border-gray-100',
cursor: SystemMouseCursors.click,
children: [
const Style(
'absolute -top-px -right-px rounded-se-3xl rounded-es-3xl bg-rose-600 px-6 py-4 font-medium tracking-widest text-white uppercase',
child: Text('Save 10%'),
),
Style(
'h-80 w-full rounded-se-3xl object-cover',
child: Image.network(
'https://images.unsplash.com/photo-1485955900006-10f4d324d411?auto=format&fit=crop&q=80&w=1160',
fit: BoxFit.cover,
),
),
Style(
'p-4 text-center',
children: [
const Style(
'text-xl font-medium text-gray-900',
display: DisplayType.inline,
child: Text('Aloe Vera'),
),
const Style(
'mt-2 text-pretty text-gray-700',
child: Text(
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Amet officia rem vel '
'voluptatum in eum vitae aliquid at sed dignissimos.',
),
),
const Style(
'mt-4 block rounded-md border border-indigo-900 bg-indigo-900 px-5 py-3 text-sm font-medium tracking-widest text-white uppercase transition-colors hover:bg-white hover:text-indigo-900',
child: Text('Buy now'),
),
],
),
],
),
);
}
}

Product with image, title, price, wishlist and call to actions

Section titled “Product with image, title, price, wishlist and call to actions”
class CurrentColorIcon extends StatelessWidget
implements StyleReplacedElementWrapper {
const CurrentColorIcon(this.svg, {super.key});
final String svg;
@override
Widget build(BuildContext context) {
final color = IconTheme.of(context).color ?? const Color(0xFF000000);
return SvgPicture.string(svg, theme: SvgTheme(currentColor: color));
}
}
const _photoUrl =
'https://images.unsplash.com/photo-1628202926206-c63a34b1618f?auto=format&fit=crop&q=80&w=1160';
const _heartSvg =
'''<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12z"/></svg>''';
class ProductCards8Example extends StatelessWidget {
const ProductCards8Example({super.key});
@override
Widget build(BuildContext context) {
return Style(
'mx-auto max-w-md p-6',
child: Style(
'group relative block overflow-hidden',
cursor: SystemMouseCursors.click,
children: [
Style(
'absolute end-4 top-4 z-10 rounded-full bg-white p-1.5 text-gray-900 transition hover:text-gray-900/75',
cursor: SystemMouseCursors.click,
children: [
const Style('sr-only', child: Text('Wishlist')),
const Style('size-4', child: CurrentColorIcon(_heartSvg)),
],
),
Style(
'h-64 w-full object-cover transition duration-500 group-hover:scale-105 sm:h-72',
child: Image.network(_photoUrl, fit: BoxFit.cover),
),
Style(
'relative border border-gray-100 bg-white p-6',
children: [
Style(
'text-gray-700',
children: const [
Text(r'$49.99 '),
Style('text-gray-600 line-through', child: Text(r'$80')),
],
),
const Style(
'mt-1.5 text-lg font-medium text-gray-900',
child: Text('Wireless Headphones'),
),
const Style(
'mt-1.5 line-clamp-3 text-gray-700',
child: Text(
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore nobis iure '
'obcaecati pariatur. Officiis qui, enim cupiditate aliquam corporis iste.',
),
),
Style(
'mt-4 flex gap-4',
children: [
Style(
'block w-full rounded-sm bg-gray-100 px-4 py-3 text-sm font-medium text-gray-900 transition hover:scale-105',
cursor: SystemMouseCursors.click,
child: const Text('Add to Cart'),
),
Style(
'block w-full rounded-sm bg-gray-900 px-4 py-3 text-sm font-medium text-white transition hover:scale-105',
cursor: SystemMouseCursors.click,
child: const Text('Buy Now'),
),
],
),
],
),
],
),
);
}
}