Announcements
Ported from HyperUI’s Announcements — see Attribution.
Includes a dark: variant — toggle the site theme (top right) to preview it.
class Announcements1Example extends StatelessWidget { const Announcements1Example({super.key});
@override Widget build(BuildContext context) { return Style( 'border-b border-gray-200 bg-gray-100 px-4 py-2 text-gray-900 dark:border-gray-700 dark:bg-gray-800 dark:text-white', child: Style( 'text-center font-medium', children: [ const Text('Lorem, ipsum dolor '), const Style( 'inline-block underline', cursor: SystemMouseCursors.click, child: Text('sit amet consectetur'), ), ], ), ); }}<div class="border-b border-gray-200 bg-gray-100 px-4 py-2 text-gray-900"> <p class="text-center font-medium"> Lorem, ipsum dolor <a href="#" class="inline-block underline"> sit amet consectetur </a> </p></div>Base with dismiss
Section titled “Base with dismiss”Includes a dark: variant — toggle the site theme (top right) to preview it.
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)); }}
class Announcements2Example extends StatelessWidget { const Announcements2Example({super.key});
static const _xMarkSvg = '''<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="M6 18 18 6M6 6l12 12"/></svg>''';
@override Widget build(BuildContext context) { return Style( 'flex items-center justify-between border-b border-gray-200 bg-gray-100 px-4 py-2 text-gray-900 dark:border-gray-700 dark:bg-gray-800 dark:text-white', children: [ const SizedBox.shrink(), Style( 'text-center font-medium', children: [ const Text('Lorem, ipsum dolor '), const Style( 'inline-block underline', cursor: SystemMouseCursors.click, child: Text('sit amet consectetur'), ), ], ), Style( 'rounded border border-gray-300 bg-white p-1.5 shadow-sm transition-colors hover:bg-gray-50 dark:border-gray-600 dark:bg-gray-900 dark:hover:bg-gray-800', child: Style('size-5', child: CurrentColorIcon(_xMarkSvg)), ), ], ); }}<div class="flex items-center justify-between border-b border-gray-200 bg-gray-100 px-4 py-2 text-gray-900"> <span> </span>
<p class="text-center font-medium"> Lorem, ipsum dolor <a href="#" class="inline-block underline"> sit amet consectetur </a> </p>
<button type="button" aria-label="Dismiss" class="rounded border border-gray-300 bg-white p-1.5 shadow-sm transition-colors hover:bg-gray-50" > <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-5" > <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" /> </svg> </button></div>Includes a dark: variant — toggle the site theme (top right) to preview it.
class Announcements3Example extends StatelessWidget { const Announcements3Example({super.key});
@override Widget build(BuildContext context) { return Style( 'fixed inset-x-0 bottom-0 z-auto border-t border-gray-200 bg-gray-100 px-4 py-2 text-gray-900 dark:border-gray-700 dark:bg-gray-800 dark:text-white', child: Style( 'text-center font-medium', children: [ const Text('Lorem, ipsum dolor '), const Style( 'inline-block underline', cursor: SystemMouseCursors.click, child: Text('sit amet consectetur'), ), ], ), ); }}<div class="fixed inset-x-0 bottom-0 z-auto border-t border-gray-200 bg-gray-100 px-4 py-2 text-gray-900"> <p class="text-center font-medium"> Lorem, ipsum dolor <a href="#" class="inline-block underline"> sit amet consectetur </a> </p></div>Fixed with dismiss
Section titled “Fixed with dismiss”Includes a dark: variant — toggle the site theme (top right) to preview it.
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)); }}
class Announcements4Example extends StatelessWidget { const Announcements4Example({super.key});
static const _xMarkSvg = '''<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="M6 18 18 6M6 6l12 12"/></svg>''';
@override Widget build(BuildContext context) { return Style( 'fixed inset-x-0 bottom-0 z-auto flex items-center justify-between border-t border-gray-200 bg-gray-100 px-4 py-2 text-gray-900 dark:border-gray-700 dark:bg-gray-800 dark:text-white', children: [ const SizedBox.shrink(), Style( 'text-center font-medium', children: [ const Text('Lorem, ipsum dolor '), const Style( 'inline-block underline', cursor: SystemMouseCursors.click, child: Text('sit amet consectetur'), ), ], ), Style( 'rounded border border-gray-300 bg-white p-1.5 shadow-sm transition-colors hover:bg-gray-50 dark:border-gray-600 dark:bg-gray-900 dark:hover:bg-gray-800', child: Style('size-5', child: CurrentColorIcon(_xMarkSvg)), ), ], ); }}<div class="fixed inset-x-0 bottom-0 z-auto flex items-center justify-between border-t border-gray-200 bg-gray-100 px-4 py-2 text-gray-900"> <span> </span>
<p class="text-center font-medium"> Lorem, ipsum dolor <a href="#" class="inline-block underline"> sit amet consectetur </a> </p>
<button type="button" aria-label="Dismiss" class="rounded border border-gray-300 bg-white p-1.5 shadow-sm transition-colors hover:bg-gray-50" > <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-5" > <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" /> </svg> </button></div>Floating
Section titled “Floating”Includes a dark: variant — toggle the site theme (top right) to preview it.
class Announcements5Example extends StatelessWidget { const Announcements5Example({super.key});
@override Widget build(BuildContext context) { return Style( 'fixed inset-x-0 bottom-0 z-auto p-4', child: Style( 'rounded border border-gray-200 bg-gray-100 px-4 py-2 text-gray-900 dark:border-gray-700 dark:bg-gray-800 dark:text-white', child: Style( 'text-center font-medium', children: [ const Text('Lorem, ipsum dolor '), const Style( 'inline-block underline', cursor: SystemMouseCursors.click, child: Text('sit amet consectetur'), ), ], ), ), ); }}<div class="fixed inset-x-0 bottom-0 z-auto p-4"> <div class="rounded border border-gray-200 bg-gray-100 px-4 py-2 text-gray-900"> <p class="text-center font-medium"> Lorem, ipsum dolor <a href="#" class="inline-block underline"> sit amet consectetur </a> </p> </div></div>Floating with dismiss
Section titled “Floating with dismiss”Includes a dark: variant — toggle the site theme (top right) to preview it.
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)); }}
class Announcements6Example extends StatelessWidget { const Announcements6Example({super.key});
static const _xMarkSvg = '''<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="M6 18 18 6M6 6l12 12"/></svg>''';
@override Widget build(BuildContext context) { return Style( 'fixed inset-x-0 bottom-0 z-auto p-4', child: Style( 'flex items-center justify-between rounded border border-gray-200 bg-gray-100 px-4 py-2 text-gray-900 dark:border-gray-700 dark:bg-gray-800 dark:text-white', children: [ const SizedBox.shrink(), Style( 'text-center font-medium', children: [ const Text('Lorem, ipsum dolor '), const Style( 'inline-block underline', cursor: SystemMouseCursors.click, child: Text('sit amet consectetur'), ), ], ), Style( 'rounded border border-gray-300 bg-white p-1.5 shadow-sm transition-colors hover:bg-gray-50 dark:border-gray-600 dark:bg-gray-900 dark:hover:bg-gray-800', child: Style('size-5', child: CurrentColorIcon(_xMarkSvg)), ), ], ), ); }}<div class="fixed inset-x-0 bottom-0 z-auto p-4"> <div class="flex items-center justify-between rounded border border-gray-200 bg-gray-100 px-4 py-2 text-gray-900" > <span> </span>
<p class="text-center font-medium"> Lorem, ipsum dolor <a href="#" class="inline-block underline"> sit amet consectetur </a> </p>
<button type="button" aria-label="Dismiss" class="rounded border border-gray-300 bg-white p-1.5 shadow-sm transition-colors hover:bg-gray-50" > <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-5" > <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" /> </svg> </button> </div></div>