sheen

Frosted glass for Flutter: a design system with one-accent theming, spring motion and 80+ widgets. It is built on package:flutter/widgets.dart, so it works under MaterialApp, CupertinoApp or a plain WidgetsApp.

pub package pub points License: MIT CI

Glass toolbar, segmented control, chips, an action bar and the tab bar over a photo A sheet with switches over a page The same glass in the dark theme with a pink accent

Live demo · API docs · Example · Changelog

Why sheen

  • Glass that is cheap to draw. Every glass surface under a SheenScope shares one copy of the backdrop (BackdropGroup), so a screen full of glass blurs once, not once per button. No shaders, no platform views.
  • Accessible by default. Reduce Motion turns springs into fades; high contrast and reduceTransparency turn glass opaque; text grows to 200 % without overflowing; every widget mirrors in right-to-left languages; icon-only buttons require a label.
  • One accent recolours everything. Prominent glass, primary buttons, selection, switches, sliders and links follow SheenThemeData.light(accent: ...); in the dark theme, accent text is lifted until it reads on the dark ground.
  • No Material required. Widgets build on the widgets layer and bring their own theme, strings and routes (sheets, menus, alerts). Text inputs use Flutter's TextField and work under any app.
  • More than glass. Pages with large titles, sheets with detents, a date-range picker, one-time-code and password fields, toasts, skeletons, empty states, a steps line, rolling digits, and a travel library with hotel cards, prices and map pins, and a music library with a player, a mini player, song rows and synced lyrics.

Install

flutter pub add sheen

Quick start

Put a SheenScope above your screens, then build with Sheen* widgets and read the theme with context.sheen:

import 'package:flutter/material.dart';
import 'package:sheen/sheen.dart';

void main() => runApp(
  MaterialApp(
    builder: (context, child) => SheenScope(child: child!),
    home: const HomePage(),
  ),
);

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) => SheenPage(
    title: 'Hello',
    children: [
      SheenGlass(
        padding: const EdgeInsets.all(16),
        child: Text('Frosted glass', style: context.sheen.type.headline),
      ),
      const SizedBox(height: 16),
      SheenPrimaryButton(label: 'Continue', expand: true, onPressed: () {}),
    ],
  );
}

SheenScope follows the system's light or dark setting and provides the theme, the fallback words widgets use (Cancel, Done, Search...), Reduce Motion, the shared backdrop and the status bar style.

Theming

SheenScope(
  theme: SheenThemeData.light(accent: const Color(0xFF087F5B)),
  darkTheme: SheenThemeData.dark(accent: const Color(0xFF20C997)),
  strings: const SheenStrings(cancel: 'Annuler', done: 'OK', search: 'Rechercher'),
  reduceTransparency: settings.reduceTransparency,
  child: child,
)
  • Change single colours with copyWith: SheenThemeData.light().copyWith(colors: SheenColors.light().copyWith(background: ...)).
  • Use your font: theme.copyWith(type: SheenType.material.withFamily('Inter')).
  • Give part of a screen another look with a nested SheenTheme.
  • Flutter has no system "Reduce Transparency" flag yet, so pass your app's setting to reduceTransparency; high contrast mode turns glass opaque by itself.

Widgets

Category Widgets
Foundation SheenScope, SheenTheme, SheenThemeData, SheenColors, SheenType, SheenStrings, SheenTone, SheenIcon + SheenIcons (82 glyphs), spacing, radii and layout widths
Glass SheenGlass (regular, clear, prominent), SheenLens
Motion SheenPressable, SheenEntrance, SheenPhotoHero, SheenRollingDigits, SheenMotion springs
Buttons SheenPrimaryButton, SheenSecondaryButton, SheenFloatingButton, SheenTextLink, SheenIconButton, SheenButtonGroup
Navigation SheenTabBar (with press-and-slide), SheenTopTabBar, SheenToolbar, SheenSearchBar, SheenActionBar, SheenStepsLine
Inputs SheenTextField, SheenPasswordField, SheenSearchField, SheenCodeField, SheenSwitch, SheenSlider, SheenStepper
Selection SheenChip, SheenChipRow, SheenSegmentedControl, SheenDateRangePicker, SheenDateRangeCalendar, SheenRangeHistogram, SheenChoiceList, showSheenChoiceSheet, SheenPullDownLink, showSheenMenu
Sheets showSheenSheet, showSheenCustomSheet, SheenSheetBody, showSheenDateSheet, showSheenDocumentSheet, SheenFormSheet
Feedback showSheenAlert, SheenToast, SheenActionBanner, SheenStatusPill, SheenStatusNotice, SheenStatusScreen, SheenEmptyState, SheenSkeleton, SheenProgressBar, SheenProgressRing, SheenSpinner, SheenProgressCapsule, SheenCountdownPill, SheenBadge, SheenSuccessCheck
Content SheenCard, SheenListGroup, SheenListRow, SheenAccordion, SheenKeyValueCard, SheenCardSwiper, SheenPhotoPager, SheenAvatar, SheenStarRating, SheenScoreBar
Layout SheenPage, SheenSectionLabel, SheenSectionNote, SheenScrollEdge, SheenEdgeFade
Travel SheenHotelCard, SheenPremiumCard, SheenCityTile, SheenPriceBlock, SheenCancellationLine, SheenScoreBadge, SheenDealBadge, SheenWasPrice, SheenTripCard, SheenItinerary, SheenPricePin, renderSheenPricePin (map marker bitmaps)
Music SheenArtwork, SheenArtworkGlow, SheenMiniPlayer, SheenSeekBar, SheenTransportControls, SheenTrackRow, SheenArtworkTile, SheenShelf, SheenLyricsView, SheenReorderList, SheenBandSlider, SheenPlayingBars, SheenMusicScope

Every widget has a page in the gallery; most have a code example in their API docs.

Text fields, search, one-time code Chips, segmented control and a date range Progress, skeletons, banners and badges Hotel card, featured stays and map pins The music widgets: a player over the cover's glow, the seek bar, controls and the mini player Hotel and featured cards on a deal: a badge on the photo and the price before the deal struck through

Travel library

Booking widgets live in a second library so apps that do not need them never see them:

import 'package:sheen/travel.dart';

A stay on a deal gets a badge on its photo, the price before the deal struck through and a line about when it ends. Pass the struck price only when it is the same stay without the deal (a like-for-like saving):

SheenHotelCard(
  name: 'Palace Downtown',
  total: 'AED 1,186.01',
  wasTotal: 'AED 1,210.21',        // struck through, under the total
  wasLabel: 'was AED 1,210.21',    // what a screen reader says
  deal: '−15%',                    // the badge on the photo
  dealNote: 'Ends Sun 18 Oct',
  photoCount: 3,
  photoBuilder: (context, i) => Image.network(photos[i], fit: BoxFit.cover),
  noPhotoLabel: 'No photo',
  saveLabel: 'Save',
  onTap: openHotel,
)

Prices, dates and labels are always yours, formatted and translated; the widgets only lay them out.

Music library

Player widgets live in a third library:

import 'package:sheen/music.dart';

SheenMiniPlayer above the tab bar, SheenSeekBar and SheenTransportControls over SheenArtworkGlow (the cover blurred behind the glass), SheenTrackRow with a save button that fills as the song is stored, SheenShelf of covers, SheenLyricsView, SheenReorderList for a queue and SheenBandSlider for an equaliser. For long audio (audiobooks, podcasts): SheenTransportControls with "back 15 / forward 30" SheenSkipButtons, chapter marks on SheenSeekBar, SheenSpeedPicker, SheenChapterList, SheenResumeCard, SheenTagRow and book covers (SheenArtwork(book: true)). See doc/music.md.

Platforms

Pure Dart and Flutter, with no platform code: iOS, Android, web, macOS, Windows and Linux (checked on the iOS simulator and in widget tests). The blur is a BackdropFilter, so it costs more on the web (the live demo shows it honestly) and over platform views such as Google Maps on Android, where a glass bar over the map makes Flutter compose the map view; keep glass over maps to bars and pins.

FAQ

Do I need MaterialApp? No. Any app works; with a plain WidgetsApp, add navigatorObservers: [HeroController()] if you use SheenPhotoHero.

Can I mix sheen with Material or Cupertino widgets? Yes. sheen reads only its own theme.

How do I translate the built-in words? Pass SheenStrings to SheenScope. Every widget that shows text also takes it as a parameter.

Which Flutter version? 3.41 or newer.

Contributing

Issues and pull requests are welcome. Run flutter analyze and flutter test before sending a change. After a visual change, run flutter test --update-goldens test/goldens and look at the images: goldens/ci/ (text drawn as blocks, checked in CI) and, on macOS, goldens/macos/ (real text; antialiasing differs between macOS versions, so CI does not compare them). Icons are SVG files in tool/icons/; dart run tool/gen_icons.dart regenerates SheenIcons. After changing public API docs, run dart doc --output tool/out/api and then dart run tool/gen_llms.dart to refresh llms.txt, the one-page summary for AI coding assistants.

Authors

sheen is made and owned by:

See AUTHORS.

License

MIT, © the sheen authors. See LICENSE.

Libraries

music
Music widgets built on sheen: covers, the mini player, a seek bar, transport controls, song rows, shelves, synced lyrics, a reorderable queue, equaliser bands, and the controls of long audio (books, podcasts): skip buttons, speed, chapters and a resume card.
sheen
sheen: a glass design system for Flutter.
social
Chat and sharing widgets built on sheen: people with their presence, chat rows and friend requests, message bubbles, cards for shared music, reactions, a composer, a typing indicator, a friend picker and a listen-together banner.
travel
Booking widgets for travel apps, built on sheen: hotel cards, prices, map pins and scores.