Skip to content

Instantly share code, notes, and snippets.

@Minsamin
Last active July 4, 2024 05:04
Show Gist options
  • Save Minsamin/c46e3ce853e06d54483a75aa0b36e837 to your computer and use it in GitHub Desktop.
Save Minsamin/c46e3ce853e06d54483a75aa0b36e837 to your computer and use it in GitHub Desktop.
Vertical tab scroll along with Page scroll
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class NewCategoryScreen extends StatefulWidget {
static const String routeName = "/new_category_screen";
const NewCategoryScreen({super.key});
@override
NewCategoryScreenState createState() => NewCategoryScreenState();
}
class NewCategoryScreenState extends State<NewCategoryScreen> {
/// Categories keys
final List<GlobalKey> jewelleryCategories = [
GlobalKey(),
GlobalKey(),
GlobalKey(),
GlobalKey(),
GlobalKey(),
GlobalKey(),
GlobalKey(),
GlobalKey(),
];
/// Scroll Controller
late ScrollController scrollController;
late ScrollController navRailScrollController;
int _selectedIndex = 0;
/// Tab Context
BuildContext? tabContext;
@override
void initState() {
scrollController = ScrollController();
navRailScrollController = ScrollController();
scrollController.addListener(animateToTab);
super.initState();
}
/// Animate To Tab
void animateToTab() {
for (var i = 0; i < jewelleryCategories.length; i++) {
RenderBox? box = jewelleryCategories[i].currentContext?.findRenderObject() as RenderBox?;
if (box != null) {
Offset position = box.localToGlobal(Offset.zero);
double screenHeight = MediaQuery.of(context).size.height;
// Check if heading is visible from the bottom when scrolling down
if (position.dy < screenHeight && scrollController.position.userScrollDirection == ScrollDirection.reverse) {
setState(() {
_selectedIndex = i;
});
DefaultTabController.of(tabContext!).animateTo(i, duration: const Duration(milliseconds: 100));
_scrollNavigationRail(i);
}
// Check if heading is no longer visible when scrolling up
if (position.dy >= screenHeight && scrollController.position.userScrollDirection == ScrollDirection.forward && _selectedIndex == i) {
setState(() {
_selectedIndex = i - 1 >= 0 ? i - 1 : 0;
});
DefaultTabController.of(tabContext!).animateTo(_selectedIndex, duration: const Duration(milliseconds: 100));
_scrollNavigationRail(_selectedIndex);
}
}
}
}
/// Scroll Navigation Rail
void _scrollNavigationRail(int index) {
double offset = index * 80.0; // Adjust this value based on the item height and padding in NavigationRail
navRailScrollController.animateTo(
offset,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
}
/// Scroll to Index
void scrollToIndex(int index) async {
scrollController.removeListener(animateToTab);
final BuildContext categories = jewelleryCategories[index].currentContext ?? context;
await Scrollable.ensureVisible(categories, duration: const Duration(milliseconds: 600));
scrollController.addListener(animateToTab);
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: DefaultTabController(
length: 8,
child: Builder(builder: (BuildContext context) {
tabContext = context;
return Scaffold(
body: Row(
children: [
ScrollConfiguration(
behavior: ScrollConfiguration.of(context).copyWith(overscroll: false),
child: SingleChildScrollView(
controller: navRailScrollController, // Attach the controller
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: MediaQuery.of(context).size.height),
child: IntrinsicHeight(
child: NavigationRail(
selectedIndex: _selectedIndex,
onDestinationSelected: (int index) {
scrollToIndex(index);
setState(() {
_selectedIndex = index;
});
DefaultTabController.of(context).animateTo(index);
},
labelType: NavigationRailLabelType.all,
destinations: const [
NavigationRailDestination(icon: Icon(Icons.earbuds), label: Text('Earnings'), padding: EdgeInsets.symmetric(vertical: 40)),
NavigationRailDestination(icon: Icon(Icons.ring_volume), label: Text('Ring'), padding: EdgeInsets.symmetric(vertical: 40)),
NavigationRailDestination(icon: Icon(Icons.diamond), label: Text('Diamond'), padding: EdgeInsets.symmetric(vertical: 40)),
NavigationRailDestination(icon: Icon(Icons.ac_unit_sharp), label: Text('Bracelet'), padding: EdgeInsets.symmetric(vertical: 40)),
NavigationRailDestination(icon: Icon(Icons.nat), label: Text('Necklace'), padding: EdgeInsets.symmetric(vertical: 40)),
NavigationRailDestination(icon: Icon(Icons.egg_alt), label: Text('Earrings'), padding: EdgeInsets.symmetric(vertical: 40)),
NavigationRailDestination(icon: Icon(Icons.brightness_low), label: Text('Brooch'), padding: EdgeInsets.symmetric(vertical: 40)),
NavigationRailDestination(icon: Icon(Icons.analytics_outlined), label: Text('Anklet'), padding: EdgeInsets.symmetric(vertical: 40)),
],
),
),
),
),
),
Expanded(
child: SingleChildScrollView(
controller: scrollController,
child: Column(
children: [
/// Earnings Title - Content
_buildCategoryTitle('Earnings', 0),
_buildItemList(JewelleryRepository.earnings),
/// Ring Title - Content
_buildCategoryTitle('Ring', 1),
_buildItemList(JewelleryRepository.ring),
/// Diamonds Title - Content
_buildCategoryTitle('Diamond', 2),
_buildItemList(JewelleryRepository.diamond),
/// Bracelet Title - Content
_buildCategoryTitle('Bracelet', 3),
_buildItemList(JewelleryRepository.bracelet),
/// Necklace Title - Content
_buildCategoryTitle('Necklace', 4),
_buildItemList(JewelleryRepository.necklace),
/// Earrings Title - Content
_buildCategoryTitle('Earrings', 5),
_buildItemList(JewelleryRepository.earrings),
/// Brooch Title - Content
_buildCategoryTitle('Brooch', 6),
_buildItemList(JewelleryRepository.brooch),
/// Anklet Title - Content
_buildCategoryTitle('Anklet', 7),
_buildItemList(JewelleryRepository.anklet),
/// Empty Bottom space
const SizedBox(height: 30)
],
),
),
),
],
),
);
})),
);
}
/// Item Lists
Widget _buildItemList(List<JewelleryModel> categories) {
return Column(
children: categories.map((m3) => _buildSingleItem(m3)).toList(),
);
}
/// Single Product item widget
Widget _buildSingleItem(JewelleryModel item) {
return Column(
children: [
SizedBox(
width: double.infinity,
//height: 150.r,
height: 200,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Row(
children: [
Expanded(flex: 2, child: Image.network(item.image, fit: BoxFit.cover)),
Expanded(
flex: 3,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(item.name, style: const TextStyle(fontSize: 21, fontWeight: FontWeight.bold)),
Text(
item.description,
maxLines: 3,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 12, color: Colors.grey.shade600),
),
Padding(
padding: const EdgeInsets.only(top: 24),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text("€${item.price}", style: const TextStyle(fontSize: 16, color: Colors.black)),
const SizedBox(width: 10),
Text(
"€${item.price + 26.07}",
style: const TextStyle(decoration: TextDecoration.lineThrough, fontSize: 13, color: Colors.grey),
),
],
),
const Icon(Icons.brightness_low)
],
),
),
],
),
),
),
],
),
),
),
const SizedBox(
height: 20,
),
],
);
}
/// Category Title
Widget _buildCategoryTitle(String title, int index) {
return Padding(
key: jewelleryCategories[index],
padding: const EdgeInsets.only(top: 14, right: 12, left: 12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
title,
style: const TextStyle(fontSize: 19, fontWeight: FontWeight.w900),
),
TextButton(
onPressed: () {},
child: const Text(
'View more',
style: TextStyle(fontSize: 13, fontWeight: FontWeight.w300, color: Colors.indigo),
),
),
],
),
const Divider(),
],
),
);
}
}
class JewelleryRepository {
/// Earnings
static List<JewelleryModel> earnings = [
JewelleryModel(
name: 'Hoop earrings with bow charm',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 19.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/11c3b41386dea29ed7e600d018f63705/p/r/product_images-_mj_3906_1.jpg'),
JewelleryModel(
name: 'Three hearts statement earrings',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 19.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/88cfb905fc78966ffa0563039e5fb511/p/r/product_images-_mj_7044.jpg'),
JewelleryModel(
name: 'Oval chain earrings',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 22.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/88cfb905fc78966ffa0563039e5fb511/o/o/oorringen_ovale_schakel-mj01568-1200.jpg'),
JewelleryModel(
name: 'Oval chain earrings',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 22.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/88cfb905fc78966ffa0563039e5fb511/o/o/oorringen_ovale_schakel-mj01568-1200.jpg'),
JewelleryModel(
name: 'Oval chain earrings',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 22.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/88cfb905fc78966ffa0563039e5fb511/o/o/oorringen_ovale_schakel-mj01568-1200.jpg'),
JewelleryModel(
name: 'Oval chain earrings',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 22.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/88cfb905fc78966ffa0563039e5fb511/o/o/oorringen_ovale_schakel-mj01568-1200.jpg'),
JewelleryModel(
name: 'Oval chain earrings',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 22.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/88cfb905fc78966ffa0563039e5fb511/o/o/oorringen_ovale_schakel-mj01568-1200.jpg'),
JewelleryModel(
name: 'Oval chain earrings',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 22.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/88cfb905fc78966ffa0563039e5fb511/o/o/oorringen_ovale_schakel-mj01568-1200.jpg'),
];
/// Ring
static List<JewelleryModel> ring = [
JewelleryModel(
name: 'Ring with small heart',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 15.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/88cfb905fc78966ffa0563039e5fb511/p/r/product_images-_mj_1736.jpg'),
JewelleryModel(
name: 'Wide structure mix ring',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 15.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/11c3b41386dea29ed7e600d018f63705/s/t/stretch_ringen_set-mj04332-1500.jpg',
),
JewelleryModel(
name: 'Ring with hearts',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 19.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/11c3b41386dea29ed7e600d018f63705/m/i/mix_ring_breed_structuur-mj04892-1200.jpg'),
JewelleryModel(
name: 'Universe statement ring ',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 19.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/88cfb905fc78966ffa0563039e5fb511/p/r/product_images-_my_0797.jpg'),
];
/// Diamond
static List<JewelleryModel> diamond = [
JewelleryModel(
name: 'Chain necklace with cubic zirconia initial',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 29.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/88cfb905fc78966ffa0563039e5fb511/p/r/product_images-_mj_2442.jpg'),
JewelleryModel(
name: 'Ring with clear zirconia',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 20.00,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/11c3b41386dea29ed7e600d018f63705/p/r/product_images-_mj_0107.jpg'),
JewelleryModel(
name: 'Initial ring with rhinestone',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 17.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/11c3b41386dea29ed7e600d018f63705/p/r/product_images-_mj_0719.jpg'),
];
/// Bracelet
static List<JewelleryModel> bracelet = [
JewelleryModel(
name: 'Charm bracelet with hearts',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 25.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/88cfb905fc78966ffa0563039e5fb511/p/r/product_images-_mj_1936.jpg',
),
JewelleryModel(
name: 'Gold plated bangle',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 30.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/11c3b41386dea29ed7e600d018f63705/b/a/bangle_goud-_mj_2338.jpg',
),
JewelleryModel(
name: 'Leather wrap bracelet',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 15.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/11c3b41386dea29ed7e600d018f63705/l/e/leather_wrap_bracelet-mj_3298.jpg',
),
JewelleryModel(
name: 'Beaded bracelet set',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 18.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/88cfb905fc78966ffa0563039e5fb511/b/e/beaded_bracelet_set-_mj_0433.jpg',
),
];
/// Necklace
static List<JewelleryModel> necklace = [
JewelleryModel(
name: 'Gold plated necklace',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 35.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/88cfb905fc78966ffa0563039e5fb511/n/e/necklace_gold_plated-_mj_8237.jpg',
),
JewelleryModel(
name: 'Silver pendant necklace',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 25.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/11c3b41386dea29ed7e600d018f63705/s/i/silver_pendant_necklace-_mj_3298.jpg',
),
JewelleryModel(
name: 'Pearl choker necklace',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 22.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/11c3b41386dea29ed7e600d018f63705/p/e/pearl_choker_necklace-_mj_3821.jpg',
),
JewelleryModel(
name: 'Layered chain necklace',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 28.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/88cfb905fc78966ffa0563039e5fb511/l/a/layered_chain_necklace-_mj_7203.jpg',
),
];
/// Earrings
static List<JewelleryModel> earrings = [
JewelleryModel(
name: 'Gold hoop earrings',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 19.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/88cfb905fc78966ffa0563039e5fb511/g/o/gold_hoop_earrings-_mj_8827.jpg',
),
JewelleryModel(
name: 'Silver stud earrings',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 14.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/11c3b41386dea29ed7e600d018f63705/s/i/silver_stud_earrings-_mj_7421.jpg',
),
JewelleryModel(
name: 'Dangling pearl earrings',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 24.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/11c3b41386dea29ed7e600d018f63705/d/a/dangling_pearl_earrings-_mj_8923.jpg',
),
JewelleryModel(
name: 'Crystal drop earrings',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 27.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/88cfb905fc78966ffa0563039e5fb511/c/r/crystal_drop_earrings-_mj_5021.jpg',
),
];
/// Brooch
static List<JewelleryModel> brooch = [
JewelleryModel(
name: 'Floral brooch pin',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 12.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/88cfb905fc78966ffa0563039e5fb511/f/l/floral_brooch_pin-_mj_3737.jpg',
),
JewelleryModel(
name: 'Vintage pearl brooch',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 18.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/11c3b41386dea29ed7e600d018f63705/v/i/vintage_pearl_brooch-_mj_2837.jpg',
),
JewelleryModel(
name: 'Gold leaf brooch',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 15.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/11c3b41386dea29ed7e600d018f63705/g/o/gold_leaf_brooch-_mj_4938.jpg',
),
JewelleryModel(
name: 'Crystal bow brooch',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 20.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/88cfb905fc78966ffa0563039e5fb511/c/r/crystal_bow_brooch-_mj_8437.jpg',
),
];
/// Anklet
static List<JewelleryModel> anklet = [
JewelleryModel(
name: 'Delicate chain anklet',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
price: 10.99,
image: 'https://www.my-jewellery.com/media/catalog/product/cache/88cfb905fc78966ffa0563039e5fb511/d/e/delicate_chain_anklet-_mj_9023.jpg',
),
// JewelleryModel(
// name: 'Beaded anklet',
// description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
// price: 13.99,
// image: 'https://www.my-jewellery.com/media/catalog/product/cache/11c3b41386dea29ed7e600d018f63705/b/e/beaded_anklet-_mj_9321.jpg',
// ),
// JewelleryModel(
// name: 'Gold plated anklet',
// description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
// price: 15.99,
// image: 'https://www.my-jewellery.com/media/catalog/product/cache/11c3b41386dea29ed7e600d018f63705/g/o/gold_plated_anklet-_mj_7392.jpg',
// ),
// JewelleryModel(
// name: 'Shell anklet',
// description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
// price: 12.99,
// image: 'https://www.my-jewellery.com/media/catalog/product/cache/88cfb905fc78966ffa0563039e5fb511/s/h/shell_anklet-_mj_8732.jpg',
// ),
];
}
class JewelleryModel {
String name;
String description;
double price;
String image;
JewelleryModel({
required this.name,
required this.description,
required this.price,
required this.image,
});
}
@Minsamin
Copy link
Author

Minsamin commented Jul 3, 2024

modern_scroll_effect.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment