Pagination
Ported from HyperUI’s Pagination — see Attribution.
Navigation
Section titled “Navigation”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)); }}
const _prevChevronSvg = '''<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>''';
const _nextChevronSvg = '''<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"/></svg>''';
class Pagination1Example extends StatelessWidget { const Pagination1Example({super.key});
@override Widget build(BuildContext context) { return Style( 'flex justify-center p-6', child: Style( 'flex justify-center gap-1 text-gray-900 dark:text-white', children: [ Style( 'grid size-8 place-content-center rounded border border-gray-200 transition-colors hover:bg-gray-50 rtl:rotate-180 dark:border-gray-700 dark:hover:bg-gray-800', cursor: SystemMouseCursors.click, child: Style('size-4', child: CurrentColorIcon(_prevChevronSvg)), ), const Style( 'block size-8 rounded border border-gray-200 text-center text-sm/8 font-medium transition-colors hover:bg-gray-50 dark:border-gray-700 dark:hover:bg-gray-800', cursor: SystemMouseCursors.click, child: Text('1'), ), const Style( 'block size-8 rounded border border-indigo-600 bg-indigo-600 text-center text-sm/8 font-medium text-white', child: Text('2'), ), for (final page in const ['3', '4']) Style('block size-8 rounded border border-gray-200 text-center text-sm/8 font-medium transition-colors hover:bg-gray-50 dark:border-gray-700 dark:hover:bg-gray-800', cursor: SystemMouseCursors.click, child: Text(page)), Style( 'grid size-8 place-content-center rounded border border-gray-200 transition-colors hover:bg-gray-50 rtl:rotate-180 dark:border-gray-700 dark:hover:bg-gray-800', cursor: SystemMouseCursors.click, child: Style('size-4', child: CurrentColorIcon(_nextChevronSvg)), ), ], ), ); }}<nav aria-label="Pagination"> <ul class="flex justify-center gap-1 text-gray-900"> <li> <a href="#" class="grid size-8 place-content-center rounded border border-gray-200 transition-colors hover:bg-gray-50 rtl:rotate-180" aria-label="Previous page" > <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 20 20" fill="currentColor" > <path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" /> </svg> </a> </li>
<li> <a href="#" class="block size-8 rounded border border-gray-200 text-center text-sm/8 font-medium transition-colors hover:bg-gray-50" > 1 </a> </li>
<li class="block size-8 rounded border border-indigo-600 bg-indigo-600 text-center text-sm/8 font-medium text-white" aria-current="page" > 2 </li>
<li> <a href="#" class="block size-8 rounded border border-gray-200 text-center text-sm/8 font-medium transition-colors hover:bg-gray-50" > 3 </a> </li>
<li> <a href="#" class="block size-8 rounded border border-gray-200 text-center text-sm/8 font-medium transition-colors hover:bg-gray-50" > 4 </a> </li>
<li> <a href="#" class="grid size-8 place-content-center rounded border border-gray-200 transition-colors hover:bg-gray-50 rtl:rotate-180" aria-label="Next page" > <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 20 20" fill="currentColor" > <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" /> </svg> </a> </li> </ul></nav>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)); }}
const _prevChevronSvg = '''<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>''';
const _nextChevronSvg = '''<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"/></svg>''';
class Pagination2Example extends StatelessWidget { const Pagination2Example({super.key});
@override Widget build(BuildContext context) { final isSmUp = MediaQuery.sizeOf(context).width >= 640; final fontSize = isSmUp ? 14.0 : 16.0; final lineHeight = isSmUp ? 20.0 : 24.0; final baseStyle = Theme.of(context).textTheme.bodyLarge ?? const TextStyle();
return Style( 'flex justify-center p-6', child: Style( 'flex justify-center gap-1 text-gray-900 dark:text-white', children: [ Style( 'grid size-8 place-content-center rounded border border-gray-200 transition-colors hover:bg-gray-50 rtl:rotate-180 dark:border-gray-700 dark:hover:bg-gray-800', cursor: SystemMouseCursors.click, child: Style('size-4', child: CurrentColorIcon(_prevChevronSvg)), ), const Style('sr-only', child: Text('Page')), Style( 'h-8 w-16 rounded border-gray-300 sm:text-sm dark:border-gray-600 dark:bg-gray-900 dark:text-white', child: TextFormField( initialValue: '2', keyboardType: TextInputType.number, style: baseStyle.copyWith(fontSize: fontSize, height: lineHeight / fontSize), ), ), Style( 'grid size-8 place-content-center rounded border border-gray-200 transition-colors hover:bg-gray-50 rtl:rotate-180 dark:border-gray-700 dark:hover:bg-gray-800', cursor: SystemMouseCursors.click, child: Style('size-4', child: CurrentColorIcon(_nextChevronSvg)), ), ], ), ); }}<nav aria-label="Pagination"> <ul class="flex justify-center gap-1 text-gray-900"> <li> <a href="#" class="grid size-8 place-content-center rounded border border-gray-200 transition-colors hover:bg-gray-50 rtl:rotate-180" aria-label="Previous page" > <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 20 20" fill="currentColor" > <path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" /> </svg> </a> </li>
<li> <label for="Page"> <span class="sr-only"> Page </span>
<input type="number" id="Page" value="2" class="h-8 w-16 rounded border-gray-300 sm:text-sm" /> </label> </li>
<li> <a href="#" class="grid size-8 place-content-center rounded border border-gray-200 transition-colors hover:bg-gray-50 rtl:rotate-180" aria-label="Next page" > <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 20 20" fill="currentColor" > <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" /> </svg> </a> </li> </ul></nav>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)); }}
const _prevChevronSvg = '''<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>''';
const _nextChevronSvg = '''<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"/></svg>''';
class Pagination3Example extends StatelessWidget { const Pagination3Example({super.key});
@override Widget build(BuildContext context) { return Style( 'flex justify-center p-6', child: Style( 'flex justify-center gap-3 text-gray-900 dark:text-white', children: [ Style( 'grid size-8 place-content-center rounded border border-gray-200 transition-colors hover:bg-gray-50 rtl:rotate-180 dark:border-gray-700 dark:hover:bg-gray-800', cursor: SystemMouseCursors.click, child: Style('size-4', child: CurrentColorIcon(_prevChevronSvg)), ), const Style( 'text-sm/8 font-medium tracking-widest', child: Text('2/12'), ), Style( 'grid size-8 place-content-center rounded border border-gray-200 transition-colors hover:bg-gray-50 rtl:rotate-180 dark:border-gray-700 dark:hover:bg-gray-800', cursor: SystemMouseCursors.click, child: Style('size-4', child: CurrentColorIcon(_nextChevronSvg)), ), ], ), ); }}<nav aria-label="Pagination"> <ul class="flex justify-center gap-3 text-gray-900"> <li> <a href="#" class="grid size-8 place-content-center rounded border border-gray-200 transition-colors hover:bg-gray-50 rtl:rotate-180" aria-label="Previous page" > <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 20 20" fill="currentColor" > <path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" /> </svg> </a> </li>
<li class="text-sm/8 font-medium tracking-widest">2/12</li>
<li> <a href="#" class="grid size-8 place-content-center rounded border border-gray-200 transition-colors hover:bg-gray-50 rtl:rotate-180" aria-label="Next page" > <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 20 20" fill="currentColor" > <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" /> </svg> </a> </li> </ul></nav>