Skip to content
HyperUI for Flutter requires the Style package — this site itself ships no pub package.

Toggles

Ported from HyperUI’s Toggles — see Attribution.

Includes a dark: variant — toggle the site theme (top right) to preview it.

class Toggles1Example extends StatefulWidget {
const Toggles1Example({super.key});
@override
State<Toggles1Example> createState() => _Toggles1ExampleState();
}
class _Toggles1ExampleState extends State<Toggles1Example> {
var _checked = false;
@override
Widget build(BuildContext context) {
return Style(
'flex justify-center p-6',
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => setState(() => _checked = !_checked),
child: Style(
'relative block h-8 w-14 rounded-full bg-gray-300 transition-colors [-webkit-tap-highlight-color:transparent] has-checked:bg-green-500 dark:bg-gray-600 dark:has-checked:bg-green-600',
cursor: SystemMouseCursors.click,
children: [
Style('peer sr-only', checked: _checked, child: const SizedBox.shrink()),
const Style(
'absolute inset-y-0 start-0 m-1 size-6 rounded-full bg-white transition-[inset-inline-start] peer-checked:start-6 dark:bg-gray-900',
),
],
),
),
);
}
}
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 Toggles2Example extends StatefulWidget {
const Toggles2Example({super.key});
static const _xSvg =
'''<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>''';
static const _checkSvg =
'''<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="m4.5 12.75 6 6 9-13.5"/></svg>''';
@override
State<Toggles2Example> createState() => _Toggles2ExampleState();
}
class _Toggles2ExampleState extends State<Toggles2Example> {
var _checked = false;
@override
Widget build(BuildContext context) {
return Style(
'flex justify-center p-6',
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => setState(() => _checked = !_checked),
child: Style(
'group relative block h-8 w-14 rounded-full bg-gray-300 transition-colors [-webkit-tap-highlight-color:transparent] has-checked:bg-green-500',
cursor: SystemMouseCursors.click,
children: [
Style('peer sr-only', checked: _checked, child: const SizedBox.shrink()),
Style(
'absolute inset-y-0 start-0 m-1 grid size-6 place-content-center rounded-full bg-white text-gray-700 transition-[inset-inline-start] peer-checked:start-6 peer-checked:*:first:hidden *:last:hidden peer-checked:*:last:block',
children: [
Style('size-4', child: CurrentColorIcon(Toggles2Example._xSvg)),
Style('size-4', child: CurrentColorIcon(Toggles2Example._checkSvg)),
],
),
],
),
),
);
}
}

Includes a dark: variant — toggle the site theme (top right) to preview it.

class Toggles3Example extends StatefulWidget {
const Toggles3Example({super.key});
@override
State<Toggles3Example> createState() => _Toggles3ExampleState();
}
class _Toggles3ExampleState extends State<Toggles3Example> {
var _checked = false;
@override
Widget build(BuildContext context) {
return Style(
'flex justify-center p-6',
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => setState(() => _checked = !_checked),
child: Style(
'relative block h-8 w-12 [-webkit-tap-highlight-color:transparent]',
cursor: SystemMouseCursors.click,
children: [
Style('peer sr-only', checked: _checked, child: const SizedBox.shrink()),
const Style('absolute inset-0 m-auto h-2 rounded-full bg-gray-300 dark:bg-gray-600'),
const Style(
'absolute inset-y-0 start-0 m-auto size-6 rounded-full bg-gray-500 transition-[inset-inline-start] peer-checked:start-6 peer-checked:*:scale-0 dark:bg-gray-400',
child: Style(
'absolute inset-0 m-auto size-4 rounded-full bg-gray-200 transition-transform dark:bg-gray-700',
),
),
],
),
),
);
}
}

Includes a dark: variant — toggle the site theme (top right) to preview it.

class Toggles4Example extends StatefulWidget {
const Toggles4Example({super.key});
@override
State<Toggles4Example> createState() => _Toggles4ExampleState();
}
class _Toggles4ExampleState extends State<Toggles4Example> {
var _checked = false;
@override
Widget build(BuildContext context) {
return Style(
'flex justify-center p-6',
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => setState(() => _checked = !_checked),
child: Style(
'relative block h-8 w-14 rounded-full bg-gray-300 transition-colors [-webkit-tap-highlight-color:transparent] has-checked:bg-blue-500 dark:bg-gray-600 dark:has-checked:bg-blue-600',
cursor: SystemMouseCursors.click,
children: [
Style('peer sr-only', checked: _checked, child: const SizedBox.shrink()),
const Style(
'absolute inset-y-0 start-0 m-1 size-6 rounded-full bg-gray-300 ring-[6px] ring-white transition-all ring-inset peer-checked:start-8 peer-checked:w-2 peer-checked:bg-white peer-checked:ring-transparent dark:bg-gray-600 dark:ring-gray-900 dark:peer-checked:bg-gray-900',
),
],
),
),
);
}
}