serenay_ecommerce_widgets 1.5.1
serenay_ecommerce_widgets: ^1.5.1 copied to clipboard
Server-driven UI for Flutter e-commerce apps: render home and category screens (banners, product carousels, grids, flash sales, stories) from backend JSON.
1.5.1 #
No code changes. Widgets and params are unchanged from 1.5.0.
- pub.dev: new topics
server-driven-ui,json-uianddynamic-ui(uidropped); the description now leads with server-driven UI. llms.txtandllms-full.txton the docs site, so AI assistants can read every widget's schema: https://serenayyazilim.github.io/serenay-ecommerce-widgets/llms.txt- Claude Code plugin with a
serenay-ecommerce-widgetsskill. It teaches Claude the package API and how to write screen JSON. Install:/plugin install serenay-ecommerce-widgets --marketplace serenayyazilim/serenay-ecommerce-widgets
1.5.0 #
- New widgets:
BRANDS— brand logo tiles as a scrolling row or a grid.BANNERGRID— banner mosaic (left_big,right_big,top_big,grid).ANNOUNCEMENTBAR— thin message strip; alistrotates everyintervalseconds.
- More layout/style params on existing widgets. All optional; defaults keep
the 1.4.4 look:
CAROUSEL—item_width,height,item_spacing,padding_horizontal,padding_vertical,bg_color.GRID/PRODUCTCARD—spacing,run_spacing,padding_horizontal,padding_vertical,bg_color.STORY—size,ring_width,ring_colors,spacing,padding_horizontal,show_title,title_size,title_color,bg_color.CATEGORYMENU—image_size,item_width,radius,fit,image_bg_color,spacing,padding_horizontal,title_size,title_color,max_lines,height,bg_color.IMAGELIST—spacing,padding_horizontal,padding_vertical,radius,bg_color.VIDEOLIST—radius,bg_color,overlay_color,overlay_opacity.FLASHSALE—color_start,color_end,animate,text_color,title_size,subtitle_size,show_icon,show_border,border_color,radius,padding_horizontal,padding_vertical, inlineitem_width/height/item_spacing, modalcolumns.MIXEDCAROUSEL—autoplay,viewport_fraction,page_spacing,radius,image_radius,inner_padding,title_size,description_size.
- Color params accept
#RRGGBB,RRGGBBor#AARRGGBB. GRID/PRODUCTCARD:columns: 0(or negative) now falls back to the theme default instead of crashing.
1.4.4 #
IMAGECAROUSELgains optional layout params; all default to the previous hardcoded values, so existing layouts are unchanged:item_margin_horizontal— px on each side of every item (default5).item_width_offset— px subtracted from each item width (default: the margin).padding_horizontal/padding_vertical— outer padding as a fraction of width, likeSLIDER.radius— image corner radius in px.item_countnow accepts decimals (e.g.2.5for a peek);0or negative falls back to2.
1.4.3 #
- Fix:
IMAGELISTimages were cropped. Each cell now ignoresheight_percentand defaults tofit_width(natural aspect ratio), matching the legacy SerBuilder IMAGELIST. An explicit per-itemfitstill wins.
1.4.2 #
- Fix: string params (
goto,url,title,name,filter, ...) no longer crash withtype 'int' is not a subtype of type 'String?'when the backend sends them as numbers; everyas String?cast on widget/item params is now?.toString().
1.4.1 #
SLIDERandCAROUSELgain twoparamsfields for autoplay:"autoplay"(0/1, realbool, or"true"/"false"; default off) and"autoplay_interval"(seconds between auto-advances, default5).SLIDERauto-advances pages;CAROUSELauto-scrolls its product row. Both pause permanently the first time the user drags manually, and never start with fewer than two items. Adds a newparseBoolhelper tocore/utils/param_parsing.dart.MIXEDCAROUSEL(already always auto-playing) gains the same"autoplay_interval"field instead of a hardcoded 5 seconds.- All three widgets' autoplay timer/drag-detection logic now share one
AutoplayController(core/utils/autoplay_controller.dart) instead of three near-identical copies, andautoplay_intervalis clamped to a minimum of 1 second to guard against a runaway timer if the backend sends0or a negative value. - Backward compatible: both fields are optional and default to the previous (no autoplay) behavior.
1.4.0 #
-
Add six new catalog widgets, all backed by inline
params(no new fetch callbacks) except RECOMMENDEDFORYOU:QNA— a vertical Q&A list (params.listof question/answer/author/ date).URGENCY— a low-stock/countdown banner ("Only 3 left in stock!"), reusing COUPON/ABANDONEDCART'send_timecontract.RECOMMENDEDFORYOU— a titled product row using the same product-query contract as CAROUSEL.SOCIALPROOF— a "N people bought this recently" banner that cycles through a list of recent purchases.SIZEGUIDE— a button that opens a measurement-table dialog built fromparams.headers/params.rows.TRUSTBADGES— a static row of reassurance icons (shipping, secure payment, returns, support, guarantee).
Adds
EcommerceWidgetTheme.qnaTitleLabel,.urgencyStockLabel,.recommendedForYouTitleLabel,.socialProofLabeland.sizeGuideButtonLabel. Ships withdoc/widgets/usage pages and widget tests for each.
1.3.4 #
- Add a new catalog widget,
REVIEWS: a horizontally-scrolling row of customer review cards (author, star rating, comment, optional "Verified Purchase" badge) with an optional average-rating/review-count header. Reads its entries straight fromparams.list, same inline-list contract asCATEGORYMENU— no fetch callback required. AddsEcommerceWidgetTheme.reviewsTitleLabeland.reviewsVerifiedLabel. Ships with adoc/widgets/usage page and widget tests.
1.3.3 #
- Add a new catalog widget,
ABANDONEDCART: a "you left items in your cart" card using the same product-query contract asBUNDLE/CAROUSEL, showing a horizontally-scrolling row of the cart's products under an optional reservation countdown ("end_time", same contract asCOUPON) and a CTA button that resolves through the shared action contract back to the cart/ checkout screen. Hides itself when the product list is empty or onceend_timehas passed. AddsEcommerceWidgetTheme.abandonedCartTitleLabel,.abandonedCartReservedLabeland.abandonedCartCtaLabel. Ships with adoc/widgets/usage page and widget tests.
1.3.2 #
FLASHSALEgains a"display_mode"paramsfield:"modal"(default, previous behavior — tapping the bar opens a bottom sheet grid) or"inline"(products are fetched eagerly and rendered as a horizontally-scrolling row directly beneath the bar, carousel-style; the bar is no longer tappable in this mode).- Backward compatible:
display_modeis optional and defaults to the previous"modal"behavior. - Fix
BUNDLE: its product row divided available width evenly across every item (Row+Expanded), so a handful of products — or a long/discounted price — could squeeze a tile narrow enough to overflow (MiniProductTile's price row). It's now a horizontally-scrolling strip of fixed-width tiles, matchingCAROUSEL's pattern, andMiniProductTile's price line wraps instead of overflowing when a host reuses it in a narrow space.
1.3.1 #
SLIDERgains twoparamsfields to control per-page layout instead of hardcoding it:"viewport_fraction"(default0.8, passed to thePageController) and"item_padding_horizontal"(default5, the horizontal padding around each slide). Setviewport_fraction: 1.0anditem_padding_horizontal: 0for a full-bleed, edge-to-edge slide.- Backward compatible: both fields are optional and default to the previous hardcoded values.
1.3.0 #
- Add a
"fit"paramsfield (values"cover","contain","fill","fit_width","fit_height","scale_down","none", backed by a newparseBoxFithelper) so a backend can control how each image/video scales, instead of every widget hardcodingBoxFit.cover/contain. Wired intoSLIDER,IMAGE(andIMAGELISTthrough it),IMAGECAROUSEL(plus a separatebg_fitfor its background image),SEARCH,MODAL,TIMEIMAGE,MIXEDCAROUSEL's"image"pages, andVIDEOLIST. - Add a
"aspect_ratio"paramsfield toTIMEIMAGE(default16/9, previously hardcoded). - Fix
GRIDandPRODUCTCARDsilently ignoring a"columns"param sent as a numeric string (e.g."3") instead of a JSON number — both now parse it the same way every other numeric param does. - All additions are backward compatible:
fit/aspect_ratioare optional and default to the previous hardcoded behavior.
1.2.0 #
- Add six new catalog widgets:
RATING(star rating + review count, the first consumer of the previously-unusedEcommerceWidgetTheme. ratingFilledColor/ratingEmptyColor/starSize),BUNDLE("frequently bought together" product row backed byProductQuery.isBundleProduct),COUPON(copyable code with an expiry countdown),CATEGORYMENU(circular icon + label grid),LOYALTYPROGRESS(reward progress bar) andCOMPARISON(side-by-side product spec table). Each ships with adoc/widgets/usage page, a widget test, and a demo entry inexample/lib/main.dart. AddsEcommerceWidgetTheme.bundleTitleLabel,.addAllToCartLabel,.couponCopyLabeland.couponCopiedLabel. - Fix
WidgetCallbacks.imageErrorBuilderbeing defined but never wired up:CatalogNetworkImagenow actually uses it (across every widget that loads a network image) instead of always falling back to its own fixed placeholder icon. - Add
WidgetCallbacks.formatPriceto let a host app replace the built-in"<amount> <symbol>"price text with its own locale/currency formatting;RichProductCard,OldProductCardandMiniProductTilenow call it when set and fall back to the previous hardcoded formatting otherwise. - Add
WidgetCallbacks.productCardBuilderto let a host app replace the product card CAROUSEL, PRODUCTCARD and FLASHSALE render entirely, without forking the package (GRID keeps its ownOldProductCarddesign). - Add
WidgetCatalog.registerBuilder/.unregisterBuilderso a host app can render a widget for a backendtypethis package doesn't ship yet, instead of it silently falling back toUnknownWidget's empty 1px box.WidgetEntrynow keeps the raw wire-formattypestring (rawType) so registered builders can key off it. - Add a
"columns"paramsfield (falling back to the newEcommerceWidgetTheme.gridColumns, default2) toGridWidgetandProductCardWidget, so a backend can request a 3- or 4-column grid on a given screen without a package update. - Add
EcommerceWidgetTheme.favoriteAnimationDuration,.flashSaleBorderDurationand.storyAutoAdvanceDurationso a host app can tune (or shorten, for reduced-motion) the favorite "pop", the flash sale countdown border loop and the story auto-advance timer, which were previously hardcoded.StoryWidgetnow also accepts an optionaltheme. - All additions are backward compatible: every new parameter and callback is optional and defaults to the previous behavior.
1.1.6 #
- Add widget catalog demo videos (converted to animated WebP, ~450KB/1.1MB)
to the root and
doc/widgets/READMEs, so both GitHub and pub.dev show a preview of the widgets in action. - Fix
TimeImageWidget(TIMEIMAGE):_parseColorusedint.parseinstead oftryParse, so a malformed backendtitle_colorhex crashed the widget — every sibling color parser already degrades gracefully instead. - Fix theme leaks in
RichProductCard/OldProductCard's variant/measure bottom sheets,SearchWidget's bar, and three "not logged in" price buttons: they hardcodedColors.white/Colors.greyinstead of readingEcommerceWidgetTheme, so a host app's rebrand left them visibly off-theme. - Fix
FastRegisterWidget(FASTREGISTER) ignoring the theme entirely (hardcodedColors.green): its border/header/text accent now reads from the newEcommerceWidgetTheme.fastRegisterAccentColor(defaults to WhatsApp green, so the default look is unchanged). Its WhatsApplaunchUrlcall is now awaited and checked — a failure (e.g. WhatsApp isn't installed) shows a snackbar via the newtheme.fastRegisterLaunchFailedLabelinstead of silently doing nothing. - Deduplicate the inline muted/looping video player used by
OldProductCard(GRID) andVideoListWidget(VIDEOLIST) into a single sharedMutedLoopVideowidget, which now also falls back to a placeholder icon instead of a permanent black box when the video URL fails to load — matchingCatalogNetworkImage's existing graceful-degradation pattern. - Add
ModalWidget.resetShown()(now exported) to clear the "already shown this session" record for theurl+type+idcombo — useful on logout, or between widget tests that assert modal behavior. - Add
Semantics/tooltiplabels to previously unlabeled icon-only buttons (FavoriteButton, MODAL/variant-sheet/measure-sheet close buttons, the STORY close button) so screen readers announce them.FavoriteButtonalso gains asemanticLabelparameter (defaults to'Favorite'). - Add widget tests for TIMEIMAGE's color-parse fix, the SEARCH/FASTREGISTER
theme fixes,
ModalWidget.resetShown(), and smoke coverage for MIXEDCAROUSEL, STORY, SLIDER, VISITEDPRODUCTS and GRID, which previously had none.
1.1.5 #
- Add
GridWidget(GRID) its own card design,OldProductCard— ported from the source app instead of sharingRichProductCardwith CAROUSEL/ PRODUCTCARD/FLASHSALE: a taller image, inline.mp4variant video, a left-edge discount ribbon, a pre-order banner (ProductCardData.preOrder), and a size/package-tier picker (ProductCardData.measureOptions, now typed asProductMeasureOptioninstead of rawdynamic). AddsEcommerceWidgetTheme.preOrderLabeland.quickAddLabel. - Fix
GridWidgetandProductCardWidget(PRODUCTCARD): both used aGridViewwith a fixedchildAspectRatio, which didn't match their card's real content height — GRID's cards overflowed at the bottom, PRODUCTCARD's rows had extra dead space below each card. Both now lay out withWrap, sized to the actual card height. - Fix
MixedCarouselWidget(MIXEDCAROUSEL): a page's mini 2x2 product grid could need more vertical space than the page's height allowed (depending onheight_percentand the amount of title/description text), clipping the bottom row of cards. The page height now grows to fit the grid instead of cutting it off. - Fix
ModalWidgetandSliderWidget's zoom-image dialog:showDialogdefaults to the app's rootNavigator, so the popup/barrier always covered the entire app regardless of where the widget was mounted. Both now passuseRootNavigator: false, matchingshowModalBottomSheet's existing default, so the dialog is scoped to the nearestNavigatorinstead — host apps with nested navigators (e.g. a per-tabNavigator) will now see the dialog confined to that navigator's bounds rather than covering the whole app. - Redesign
SearchWidget's floating search bar: a rounded, shadowed pill bar with a leading search icon and a rounded,theme.primaryColorbutton, replacing the flush white bar and squaresecondaryColorbutton. The bar height, button height and shared corner radius are now overridable per-instance viaparams:bar_height,button_height,radius.
1.1.4 #
- Fix
ModalWidget: it was missing the circular white "X" close button, the dimmed barrier and the max-height constraint that the original design used, so the popup image had no way to be dismissed without tapping it.ModalWidgetalso never accepted anEcommerceWidgetTheme, unlike every other catalog widget — it now takestheme(wired automatically throughWidgetCatalog.getScreen(theme:)) and the close button's background/icon colors followtheme.surfaceColor/theme.textPrimaryColorinstead of being hardcoded white/black. - Fix
SliderWidget: slides rendered full-bleed instead of the original carousel's "peek" effect (adjacent slides partially visible at the edges);PageController(viewportFraction: 0.8)restores it. - Fix
StoryWidget: the swipe-up CTA at the bottom of a story was a small outlined button instead of the original full-width, translucent-black bar with an up-chevron above the text. - Fix
FastRegisterWidget: the WhatsApp header used a generic chat icon; replaced with a dependency-free WhatsApp-style glyph. - Fix
MixedCarouselWidget:item_type: "image"pages silently droppedtitle/description— they now render inside the same colored card shell asproductspages, matching the original design.- The mini product grid's photos weren't square (no
imageSizewas passed toMiniProductTile), so thumbnails rendered at the source image's aspect ratio instead of a uniform square like every other product card.
- Fix a crash ("Looking up a deactivated widget's ancestor is unsafe")
that could happen in
FlashSaleWidgetandFavoriteButton: both built theirAnimationControllers via a lazylate finalfield initializer, which — ifbuild()never touched the field before the widget was disposed (e.g. an already-expired flash sale short-circuits its ownbuild()) — ran thevsynclookup duringdispose()against a deactivated element. Controllers are now created eagerly ininitState(). - Fix
SearchWidget's background imageBoxFit: it usedcoverinstead of the originalfitWidth, cropping the image differently than the source design.
1.1.3 #
- Add the remaining hardcoded, non-backend UI strings to
EcommerceWidgetThemeso host apps can localize/re-brand them, matchingviewPricesLabel:notAvailableForSaleLabel,addToCartLabel,variantColorLabel,recentlyViewedLabel,searchHintLabel,searchButtonLabel,flashSaleTitleLabel,flashSaleTimeUpLabel, and the FASTREGISTER card'sfastRegisterHeaderLabel,fastRegisterSendLabel,fastRegisterTitleLabel,fastRegisterSubtitleLabel,fastRegisterStep1Label,fastRegisterStep2Label,fastRegisterStep3Label(FASTREGISTER now also acceptsthemeviaWidgetCatalog.getScreen).
1.1.2 #
- Add
EcommerceWidgetTheme.viewPricesLabelso host apps can localize/ override the "View Prices" text shown instead of a hidden price when the viewer is logged out (RichProductCard,MiniProductTile). - Fix:
MiniProductTile(MIXEDCAROUSEL's mini 2x2 product grid) rendered with no card background, unlike every other product card in the catalog. It now wraps its content in atheme.surfaceColorcard, matchingRichProductCard.
1.1.1 #
- Fix: numeric
params(height,height_percent,radius,padding,padding_horizontal,padding_vertical,bottom,limit,page,item_count,fontsize_title,fontsize_subtitle, plusprice,price_old,package_qty,qty_in_packageon product data) crashed with aTypeCastExceptionwhen a backend sent them as numeric strings (e.g."20") instead of JSON numbers. All catalog widgets and contracts now parse these tolerantly, matching the numbers-or-numeric-strings behavior most backends actually send.
1.1.0 #
- Add
EcommerceWidgetTheme: an optionalthemeparameter onWidgetCatalog.getScreenthat lets a host app override the colors, text styles, radii and spacing used across the catalog (product cards, badges, buttons, flash sale, search, text, visited products) instead of the package's built-in look. Omitting it keeps the previous defaults. - Export the standalone building blocks the catalog composes internally —
AddToCartButton,FavoriteButton,DiscountBadge,QuantityPicker,RichProductCard— so they can be used directly outsideWidgetCatalog.
1.0.0 #
- Initial release: a backend-driven dynamic widget system for e-commerce home/category screens.
- Supported widget types: TEXT, IMAGE, SLIDER, DIVIDER, CAROUSEL, GRID, IMAGECAROUSEL, IMAGELIST, VIDEOLIST, FASTREGISTER, STORY, VISITEDPRODUCTS, TIMEIMAGE, YOUTUBE, SEARCH, PRODUCTCARD, FLASHSALE, MODAL, MIXEDCAROUSEL.