```dart import 'package:flutter/material.dart'; class ProductCard extends StatelessWidget { const ProductCard({ super.key, required this.title, required this.price, required this.imageUrl, required this.onAddToCart, }); final String title; final double price; final String imageUrl; final VoidCallback onAddToCart; @override Widget build(BuildContext context) { final theme = Theme.of(context); return Card( clipBehavior: Clip.antiAlias, child: Padding( padding: const EdgeInsets.all(12), child: C...
Scanned 9/5/2026
Install to Claude Code
npx -y skills add HoangNguyen0403/agent-skills-standard --skill flutter-widgets --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Flutter Widgets?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/hoangnguyen0403-flutter-widgets-agent-skills-standard)More formats (shields.io, HTML) on the badges page.
```dart
import 'package:flutter/material.dart';
class ProductCard extends StatelessWidget {
const ProductCard({
super.key,
required this.title,
required this.price,
required this.imageUrl,
required this.onAddToCart,
});
final String title;
final double price;
final String imageUrl;
final VoidCallback onAddToCart;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Card(
clipBehavior: Clip.antiAlias,
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_ProductImage(imageUrl: imageUrl, title: title),
const SizedBox(height: 12),
_ProductDetails(title: title, price: price),
const SizedBox(height: 12),
SizedBox(
width: double.infinity,
child: ElevatedButton.icon(
onPressed: onAddToCart,
icon: const Icon(Icons.add_shopping_cart),
label: Text(
'Add to cart',
style: theme.textTheme.labelLarge,
),
),
),
],
),
),
);
}
}
class _ProductImage extends StatelessWidget {
const _ProductImage({
required this.imageUrl,
required this.title,
});
final String imageUrl;
final String title;
@override
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: 4 / 3,
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Image.network(
imageUrl,
fit: BoxFit.cover,
errorBuilder: (_, __, ___) => ColoredBox(
color: Theme.of(context).colorScheme.surfaceContainerHighest,
child: const Center(child: Icon(Icons.broken_image_outlined)),
),
),
),
);
}
}
class _ProductDetails extends StatelessWidget {
const _ProductDetails({
required this.title,
required this.price,
});
final String title;
final double price;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: theme.textTheme.titleMedium,
),
const SizedBox(height: 4),
Text(
'\$${price.toStringAsFixed(2)}',
style: theme.textTheme.titleSmall?.copyWith(
color: theme.colorScheme.primary,
fontWeight: FontWeight.w700,
),
),
],
);
}
}
```
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!