Buttons
Ported from HyperUI’s Buttons — see Attribution.
Solid and bordered
Section titled “Solid and bordered”Includes a dark: variant — toggle the site theme (top right) to preview it.
class Buttons1Example extends StatelessWidget { const Buttons1Example({super.key});
@override Widget build(BuildContext context) { return Style( 'flex flex-wrap justify-center gap-4 p-6', children: const [ Style( 'inline-flex items-center justify-center rounded-full border border-indigo-600 bg-indigo-600 px-6 py-3 text-sm font-semibold text-white shadow-sm transition-colors hover:bg-indigo-700 focus-visible:ring-4 focus-visible:ring-indigo-200 focus-visible:outline-none dark:border-indigo-300 dark:bg-indigo-300 dark:text-gray-900 dark:hover:bg-indigo-200 dark:focus-visible:ring-indigo-700', cursor: SystemMouseCursors.click, child: Text('Get started'), ), Style( 'inline-flex items-center justify-center rounded-full border border-slate-300 bg-white px-6 py-3 text-sm font-semibold text-slate-700 shadow-sm transition-colors hover:border-slate-400 hover:bg-slate-50 hover:text-slate-900 focus-visible:ring-4 focus-visible:ring-slate-200 focus-visible:outline-none dark:border-slate-600 dark:bg-gray-900 dark:text-slate-200 dark:hover:border-slate-500 dark:hover:bg-slate-800 dark:hover:text-slate-50 dark:focus-visible:ring-slate-700', cursor: SystemMouseCursors.click, child: Text('Learn more'), ), ], ); }}<a class="inline-flex items-center justify-center rounded-full border border-indigo-600 bg-indigo-600 px-6 py-3 text-sm font-semibold text-white shadow-sm transition-colors hover:bg-indigo-700 focus-visible:ring-4 focus-visible:ring-indigo-200 focus-visible:outline-none" href="#"> Get started</a>
<a class="inline-flex items-center justify-center rounded-full border border-slate-300 bg-white px-6 py-3 text-sm font-semibold text-slate-700 shadow-sm transition-colors hover:border-slate-400 hover:bg-slate-50 hover:text-slate-900 focus-visible:ring-4 focus-visible:ring-slate-200 focus-visible:outline-none" href="#"> Learn more</a>Solid and bordered with icon
Section titled “Solid and bordered with icon”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 Buttons2Example extends StatelessWidget { const Buttons2Example({super.key});
static const _arrowRightSvg = '''<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="M17.25 8.25 21 12m0 0-3.75 3.75M21 12H3"/></svg>''';
@override Widget build(BuildContext context) { return Style( 'flex flex-wrap justify-center gap-4 p-6', children: [ Style( 'inline-flex items-center gap-2 rounded-full border border-indigo-600 bg-indigo-600 px-6 py-3 text-sm font-semibold text-white shadow-sm transition-colors hover:bg-indigo-700 focus-visible:ring-4 focus-visible:ring-indigo-200 focus-visible:outline-none dark:border-indigo-300 dark:bg-indigo-300 dark:text-gray-900 dark:hover:bg-indigo-200 dark:focus-visible:ring-indigo-700', cursor: SystemMouseCursors.click, children: [ const Text('Start free'), Style( 'size-4 rtl:rotate-180', child: CurrentColorIcon(_arrowRightSvg), ), ], ), Style( 'inline-flex items-center gap-2 rounded-full border border-indigo-600 px-6 py-3 text-sm font-semibold text-indigo-600 transition-colors hover:bg-indigo-50 focus-visible:ring-4 focus-visible:ring-indigo-200 focus-visible:outline-none dark:border-indigo-300 dark:text-indigo-300 dark:hover:bg-indigo-800 dark:focus-visible:ring-indigo-700', cursor: SystemMouseCursors.click, children: [ Style( 'size-4 rtl:rotate-180', child: CurrentColorIcon(_arrowRightSvg), ), const Text('See options'), ], ), ], ); }}<a class="inline-flex items-center gap-2 rounded-full border border-indigo-600 bg-indigo-600 px-6 py-3 text-sm font-semibold text-white shadow-sm transition-colors hover:bg-indigo-700 focus-visible:ring-4 focus-visible:ring-indigo-200 focus-visible:outline-none" href="#"> <span>Start free</span>
<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-4 rtl:rotate-180" > <path stroke-linecap="round" stroke-linejoin="round" d="M17.25 8.25 21 12m0 0-3.75 3.75M21 12H3" /> </svg></a>
<a class="inline-flex items-center gap-2 rounded-full border border-indigo-600 px-6 py-3 text-sm font-semibold text-indigo-600 transition-colors hover:bg-indigo-50 focus-visible:ring-4 focus-visible:ring-indigo-200 focus-visible:outline-none" href="#"> <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-4 rtl:rotate-180" > <path stroke-linecap="round" stroke-linejoin="round" d="M17.25 8.25 21 12m0 0-3.75 3.75M21 12H3" /> </svg>
<span>See options</span></a>Icon only, solid and bordered
Section titled “Icon only, solid and bordered”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 Buttons3Example extends StatelessWidget { const Buttons3Example({super.key});
static const _plusSvg = '''<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="M12 4.5v15m7.5-7.5h-15"/></svg>''';
@override Widget build(BuildContext context) { return Style( 'flex flex-wrap justify-center gap-4 p-6', children: [ Style( 'inline-flex size-12 items-center justify-center rounded-full border border-indigo-600 bg-indigo-600 text-white shadow-sm transition-colors hover:bg-indigo-700 focus-visible:ring-4 focus-visible:ring-indigo-200 focus-visible:outline-none dark:border-indigo-300 dark:bg-indigo-300 dark:text-gray-900 dark:hover:bg-indigo-200 dark:focus-visible:ring-indigo-700', cursor: SystemMouseCursors.click, children: [ const Style('sr-only', child: Text('Add to cart')), Style('size-5', child: CurrentColorIcon(_plusSvg)), ], ), Style( 'inline-flex size-12 items-center justify-center rounded-full border border-slate-300 bg-white text-slate-600 shadow-sm transition-colors hover:border-slate-400 hover:bg-slate-50 hover:text-slate-900 focus-visible:ring-4 focus-visible:ring-slate-200 focus-visible:outline-none dark:border-slate-600 dark:bg-gray-900 dark:text-slate-300 dark:hover:border-slate-500 dark:hover:bg-slate-800 dark:hover:text-slate-50 dark:focus-visible:ring-slate-700', cursor: SystemMouseCursors.click, children: [ const Style('sr-only', child: Text('Add to cart')), Style('size-5', child: CurrentColorIcon(_plusSvg)), ], ), ], ); }}<a class="inline-flex size-12 items-center justify-center rounded-full border border-indigo-600 bg-indigo-600 text-white shadow-sm transition-colors hover:bg-indigo-700 focus-visible:ring-4 focus-visible:ring-indigo-200 focus-visible:outline-none" href="#"> <span class="sr-only">Add to cart</span>
<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="M12 4.5v15m7.5-7.5h-15" /> </svg></a>
<a class="inline-flex size-12 items-center justify-center rounded-full border border-slate-300 bg-white text-slate-600 shadow-sm transition-colors hover:border-slate-400 hover:bg-slate-50 hover:text-slate-900 focus-visible:ring-4 focus-visible:ring-slate-200 focus-visible:outline-none" href="#"> <span class="sr-only">Add to cart</span>
<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="M12 4.5v15m7.5-7.5h-15" /> </svg></a>CTA with icon bubble
Section titled “CTA with icon bubble”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 Buttons4Example extends StatelessWidget { const Buttons4Example({super.key});
static const _arrowRightSvg = '''<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="M17.25 8.25 21 12m0 0-3.75 3.75M21 12H3"/></svg>''';
@override Widget build(BuildContext context) { return Style( 'flex flex-wrap justify-center gap-4 p-6', children: [ Style( 'group inline-flex items-center gap-4 rounded-full border border-indigo-600 bg-indigo-600 px-5 py-3 text-sm font-semibold text-white shadow-sm transition-colors hover:bg-indigo-700 focus-visible:ring-4 focus-visible:ring-indigo-200 focus-visible:outline-none dark:border-indigo-300 dark:bg-indigo-300 dark:text-gray-900 dark:hover:bg-indigo-200 dark:focus-visible:ring-indigo-700', cursor: SystemMouseCursors.click, children: [ const Text('Learn more'), Style( 'grid size-8 shrink-0 place-items-center rounded-full bg-white/15 transition-transform group-hover:translate-x-0.5 dark:bg-gray-900/15', child: Style( 'size-4 rtl:rotate-180', child: CurrentColorIcon(_arrowRightSvg), ), ), ], ), Style( 'group inline-flex items-center gap-4 rounded-full border border-slate-300 bg-white px-5 py-3 text-sm font-semibold text-slate-700 shadow-sm transition-colors hover:border-slate-400 hover:bg-slate-50 hover:text-slate-900 focus-visible:ring-4 focus-visible:ring-slate-200 focus-visible:outline-none dark:border-slate-600 dark:bg-gray-900 dark:text-slate-200 dark:hover:border-slate-500 dark:hover:bg-slate-800 dark:hover:text-slate-50 dark:focus-visible:ring-slate-700', cursor: SystemMouseCursors.click, children: [ const Text('View pricing'), Style( 'size-4 text-slate-400 transition-transform group-hover:translate-x-0.5 group-hover:text-slate-600 rtl:rotate-180 dark:text-slate-500 dark:group-hover:text-slate-300', child: CurrentColorIcon(_arrowRightSvg), ), ], ), ], ); }}<a class="group inline-flex items-center gap-4 rounded-full border border-indigo-600 bg-indigo-600 px-5 py-3 text-sm font-semibold text-white shadow-sm transition-colors hover:bg-indigo-700 focus-visible:ring-4 focus-visible:ring-indigo-200 focus-visible:outline-none" href="#"> <span>Learn more</span>
<span class="grid size-8 shrink-0 place-items-center rounded-full bg-white/15 transition-transform group-hover:translate-x-0.5" > <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-4 rtl:rotate-180" > <path stroke-linecap="round" stroke-linejoin="round" d="M17.25 8.25 21 12m0 0-3.75 3.75M21 12H3" /> </svg> </span></a>
<a class="group inline-flex items-center gap-4 rounded-full border border-slate-300 bg-white px-5 py-3 text-sm font-semibold text-slate-700 shadow-sm transition-colors hover:border-slate-400 hover:bg-slate-50 hover:text-slate-900 focus-visible:ring-4 focus-visible:ring-slate-200 focus-visible:outline-none" href="#"> <span>View pricing</span>
<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-4 text-slate-400 transition-transform group-hover:translate-x-0.5 group-hover:text-slate-600 rtl:rotate-180" > <path stroke-linecap="round" stroke-linejoin="round" d="M17.25 8.25 21 12m0 0-3.75 3.75M21 12H3" /> </svg></a>Quiet text and underline buttons
Section titled “Quiet text and underline buttons”Includes a dark: variant — toggle the site theme (top right) to preview it.
class Buttons5Example extends StatelessWidget { const Buttons5Example({super.key});
@override Widget build(BuildContext context) { return Style( 'flex flex-wrap justify-center gap-4 p-6', children: const [ Style( 'inline-flex items-center justify-center rounded-full px-4 py-2 text-sm font-semibold text-indigo-600 underline decoration-slate-300 decoration-2 underline-offset-4 transition-colors hover:text-indigo-700 hover:decoration-indigo-500 focus-visible:ring-4 focus-visible:ring-indigo-200 focus-visible:outline-none dark:text-indigo-300 dark:decoration-slate-600 dark:hover:text-indigo-200 dark:hover:decoration-indigo-400 dark:focus-visible:ring-indigo-700', cursor: SystemMouseCursors.click, child: Text('View details'), ), Style( 'inline-flex items-center justify-center rounded-full px-4 py-2 text-sm font-semibold text-slate-700 transition-colors hover:bg-slate-100 hover:text-slate-900 focus-visible:ring-4 focus-visible:ring-slate-200 focus-visible:outline-none dark:text-slate-200 dark:hover:bg-slate-800 dark:hover:text-slate-50 dark:focus-visible:ring-slate-700', cursor: SystemMouseCursors.click, child: Text('Save draft'), ), ], ); }}<a class="inline-flex items-center justify-center rounded-full px-4 py-2 text-sm font-semibold text-indigo-600 underline decoration-slate-300 decoration-2 underline-offset-4 transition-colors hover:text-indigo-700 hover:decoration-indigo-500 focus-visible:ring-4 focus-visible:ring-indigo-200 focus-visible:outline-none" href="#"> View details</a>
<a class="inline-flex items-center justify-center rounded-full px-4 py-2 text-sm font-semibold text-slate-700 transition-colors hover:bg-slate-100 hover:text-slate-900 focus-visible:ring-4 focus-visible:ring-slate-200 focus-visible:outline-none" href="#"> Save draft</a>