Flutter Eye Test Card with Snellen Acuity Chart

A vision check card for health and optician apps, built with Wind in Flutter. A real Snellen letter chart shrinks line by line from 20/200 to 20/15, the 20/20 line is highlighted as the last line read, and acuity tiles summarise each eye above a book-an-exam action.

Anılcan Çakır by Anılcan Çakır 119 views 0 stars 4 weeks ago Rev 1
Flutter Eye Test Card with Snellen Acuity Chart preview
main.dart
WDiv(
  className: 'flex flex-col w-[340px] rounded-3xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 p-5',
  children: [
    WDiv(
      className: 'flex flex-row items-center justify-between w-full',
      children: [
        WDiv(
          className: 'flex flex-row items-center gap-3',
          children: [
            WDiv(
              className: 'flex flex-row items-center justify-center w-10 h-10 rounded-xl bg-teal-600 dark:bg-teal-500',
              child: WIcon(
                Icons.visibility,
                className: 'text-xl text-white'
              )
            ),
            WDiv(
              className: 'flex flex-col',
              children: [
                WText(
                  'Vision check',
                  className: 'text-base font-bold text-gray-900 dark:text-white'
                ),
                WText(
                  'Right eye, Snellen chart',
                  className: 'text-xs text-gray-500 dark:text-gray-400'
                ),
              ]
            ),
          ]
        ),
        WDiv(
          className: 'rounded-full bg-emerald-100 dark:bg-emerald-900 px-3 py-1',
          child: WText(
            '20/20',
            className: 'text-xs font-bold text-emerald-700 dark:text-emerald-300'
          )
        ),
      ]
    ),
    WDiv(
      className: 'flex flex-col w-full gap-1 mt-4 rounded-2xl bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 py-3',
      children: [
        WDiv(
          className: 'flex flex-row items-center w-full',
          children: [
            WText(
              '20/200',
              className: 'w-[44px] pl-2 text-[10px] font-semibold text-gray-400 dark:text-gray-500'
            ),
            WDiv(
              className: 'flex flex-row items-center justify-center w-[196px]',
              child: WText(
                'E',
                className: 'text-[38px] font-black tracking-wider text-gray-900 dark:text-white'
              )
            ),
            WDiv(
              className: 'flex flex-row items-center justify-end w-[30px] pr-2',
              child: WIcon(
                Icons.check,
                className: 'text-xs text-gray-300 dark:text-gray-600'
              )
            ),
          ]
        ),
        WDiv(
          className: 'flex flex-row items-center w-full',
          children: [
            WText(
              '20/100',
              className: 'w-[44px] pl-2 text-[10px] font-semibold text-gray-400 dark:text-gray-500'
            ),
            WDiv(
              className: 'flex flex-row items-center justify-center w-[196px]',
              child: WText(
                'F P',
                className: 'text-[27px] font-black tracking-wider text-gray-900 dark:text-white'
              )
            ),
            WDiv(
              className: 'flex flex-row items-center justify-end w-[30px] pr-2',
              child: WIcon(
                Icons.check,
                className: 'text-xs text-gray-300 dark:text-gray-600'
              )
            ),
          ]
        ),
        WDiv(
          className: 'flex flex-row items-center w-full',
          children: [
            WText(
              '20/70',
              className: 'w-[44px] pl-2 text-[10px] font-semibold text-gray-400 dark:text-gray-500'
            ),
            WDiv(
              className: 'flex flex-row items-center justify-center w-[196px]',
              child: WText(
                'T O Z',
                className: 'text-[21px] font-black tracking-wider text-gray-900 dark:text-white'
              )
            ),
            WDiv(
              className: 'flex flex-row items-center justify-end w-[30px] pr-2',
              child: WIcon(
                Icons.check,
                className: 'text-xs text-gray-300 dark:text-gray-600'
              )
            ),
          ]
        ),
        WDiv(
          className: 'flex flex-row items-center w-full',
          children: [
            WText(
              '20/50',
              className: 'w-[44px] pl-2 text-[10px] font-semibold text-gray-400 dark:text-gray-500'
            ),
            WDiv(
              className: 'flex flex-row items-center justify-center w-[196px]',
              child: WText(
                'L P E D',
                className: 'text-[17px] font-black tracking-wider text-gray-900 dark:text-white'
              )
            ),
            WDiv(
              className: 'flex flex-row items-center justify-end w-[30px] pr-2',
              child: WIcon(
                Icons.check,
                className: 'text-xs text-gray-300 dark:text-gray-600'
              )
            ),
          ]
        ),
        WDiv(
          className: 'flex flex-row items-center w-full',
          children: [
            WText(
              '20/40',
              className: 'w-[44px] pl-2 text-[10px] font-semibold text-gray-400 dark:text-gray-500'
            ),
            WDiv(
              className: 'flex flex-row items-center justify-center w-[196px]',
              child: WText(
                'P E C F D',
                className: 'text-[14px] font-black tracking-wider text-gray-900 dark:text-white'
              )
            ),
            WDiv(
              className: 'flex flex-row items-center justify-end w-[30px] pr-2',
              child: WIcon(
                Icons.check,
                className: 'text-xs text-gray-300 dark:text-gray-600'
              )
            ),
          ]
        ),
        WDiv(
          className: 'flex flex-row items-center w-full',
          children: [
            WText(
              '20/30',
              className: 'w-[44px] pl-2 text-[10px] font-semibold text-gray-400 dark:text-gray-500'
            ),
            WDiv(
              className: 'flex flex-row items-center justify-center w-[196px]',
              child: WText(
                'E D F C Z P',
                className: 'text-[12px] font-black tracking-wider text-gray-900 dark:text-white'
              )
            ),
            WDiv(
              className: 'flex flex-row items-center justify-end w-[30px] pr-2',
              child: WIcon(
                Icons.check,
                className: 'text-xs text-gray-300 dark:text-gray-600'
              )
            ),
          ]
        ),
        WDiv(
          className: 'flex flex-row items-center w-full',
          children: [
            WText(
              '20/25',
              className: 'w-[44px] pl-2 text-[10px] font-semibold text-gray-400 dark:text-gray-500'
            ),
            WDiv(
              className: 'flex flex-row items-center justify-center w-[196px]',
              child: WText(
                'F E L O P Z D',
                className: 'text-[11px] font-black tracking-wider text-gray-900 dark:text-white'
              )
            ),
            WDiv(
              className: 'flex flex-row items-center justify-end w-[30px] pr-2',
              child: WIcon(
                Icons.check,
                className: 'text-xs text-gray-300 dark:text-gray-600'
              )
            ),
          ]
        ),
        WDiv(
          className: 'flex flex-row items-center w-full py-1 rounded-lg bg-emerald-100 dark:bg-emerald-900',
          children: [
            WText(
              '20/20',
              className: 'w-[44px] pl-2 text-[10px] font-bold text-emerald-700 dark:text-emerald-300'
            ),
            WDiv(
              className: 'flex flex-row items-center justify-center w-[196px]',
              child: WText(
                'D E F P O T E C',
                className: 'text-[10px] font-black tracking-wider text-gray-900 dark:text-white'
              )
            ),
            WDiv(
              className: 'flex flex-row items-center justify-end w-[30px] pr-2',
              child: WIcon(
                Icons.check,
                className: 'text-sm text-emerald-600 dark:text-emerald-400'
              )
            ),
          ]
        ),
        WDiv(
          className: 'flex flex-row items-center w-full py-1',
          children: [
            WText(
              '20/15',
              className: 'w-[44px] pl-2 text-[10px] font-semibold text-gray-300 dark:text-gray-600'
            ),
            WDiv(
              className: 'flex flex-row items-center justify-center w-[196px]',
              child: WText(
                'L E F O D P C T',
                className: 'text-[9px] font-black tracking-wider text-gray-300 dark:text-gray-600'
              )
            ),
            WDiv(
              className: 'flex flex-row items-center justify-end w-[30px] pr-2',
              child: WIcon(
                Icons.close,
                className: 'text-sm text-rose-400 dark:text-rose-500'
              )
            ),
          ]
        ),
      ]
    ),
    WDiv(
      className: 'flex flex-row items-center justify-between w-full mt-3',
      children: [
        WText(
          'Read 8 of 9 lines',
          className: 'text-xs font-semibold text-gray-700 dark:text-gray-300'
        ),
        WText(
          'Missed 3 letters on 20/15',
          className: 'text-xs text-gray-500 dark:text-gray-400'
        ),
      ]
    ),
    WDiv(
      className: 'flex flex-row gap-2 w-full mt-4',
      children: [
        WDiv(
          className: 'flex flex-col w-[94px] rounded-2xl bg-gray-50 dark:bg-gray-800 p-3',
          children: [
            WText(
              '20/20',
              className: 'text-lg font-bold text-gray-900 dark:text-white'
            ),
            WText(
              'RIGHT',
              className: 'text-[9px] font-bold tracking-widest text-gray-400 dark:text-gray-500'
            ),
          ]
        ),
        WDiv(
          className: 'flex flex-col w-[94px] rounded-2xl bg-gray-50 dark:bg-gray-800 p-3',
          children: [
            WText(
              '20/25',
              className: 'text-lg font-bold text-amber-600 dark:text-amber-400'
            ),
            WText(
              'LEFT',
              className: 'text-[9px] font-bold tracking-widest text-gray-400 dark:text-gray-500'
            ),
          ]
        ),
        WDiv(
          className: 'flex flex-col w-[94px] rounded-2xl bg-gray-50 dark:bg-gray-800 p-3',
          children: [
            WText(
              '20/20',
              className: 'text-lg font-bold text-gray-900 dark:text-white'
            ),
            WText(
              'BOTH',
              className: 'text-[9px] font-bold tracking-widest text-gray-400 dark:text-gray-500'
            ),
          ]
        ),
      ]
    ),
    WDiv(
      className: 'w-full mt-4',
      child: WButton(
        className: 'w-full rounded-2xl bg-teal-600 dark:bg-teal-500 py-3',
        child: WDiv(
          className: 'flex flex-row items-center justify-center gap-2',
          children: [
            WIcon(
              Icons.calendar_today,
              className: 'text-base text-white'
            ),
            WText(
              'Book an eye exam',
              className: 'text-sm font-semibold text-white'
            ),
          ]
        )
      )
    ),
  ],
)
Stats
Views
119
Stars
0
Revisions
1
Size
11,241 chars
Created
Sep 23, 2026