A bit of feedback…

A small bit of feedback… that’s often what a mobile user is looking for. Haptic feedback – a quick device vibration – is great. It’s subtle, quick, doesn’t interrupt, but gives an actual *feeling* that something happened. And… on iOS, it’s harder to do without building a full ‘native mobile app’. iOS Safari doesn’t support the ‘vibrate’ method. Apple does do some things quite well, but holding off on browser support for this has just been… annoying.

Some time ago Apple introduced a ‘toggle switch’ attribute on the ‘checkbox’ input type. And clicking it… provides small haptic feedback. And this morning I found a small React hook that will trigger this for you.

I created a similar version for Vue 3

import { ref, computed, onMounted, onUnmounted } from 'vue'

const HAPTIC_DURATION = 10

function detectIOS(): boolean {
  return /iPad|iPhone|iPod/.test(navigator.userAgent) && !(window as any).MSStream
}

export function useHaptic(duration = HAPTIC_DURATION) {
  const inputRef = ref<HTMLInputElement | null>(null)
  const labelRef = ref<HTMLLabelElement | null>(null)
  const isIOS = computed(() => detectIOS())

  onMounted(() => {
    const input = document.createElement('input')
    input.type = 'checkbox'
    input.id = 'haptic-switch'
    input.setAttribute('switch', '')
    input.style.display = 'none'
    document.body.appendChild(input)
    inputRef.value = input

    const label = document.createElement('label')
    label.htmlFor = 'haptic-switch'
    label.style.display = 'none'
    document.body.appendChild(label)
    labelRef.value = label
  })

  onUnmounted(() => {
    if (inputRef.value) document.body.removeChild(inputRef.value)
    if (labelRef.value) document.body.removeChild(labelRef.value)
  })

  function triggerHaptic() {
    if (!isIOS.value && navigator?.vibrate) {
      navigator.vibrate(duration)
    } else {
      labelRef.value?.click()
    }
  }

  return { triggerHaptic }
}

Which can then be used as so…

<script setup lang="ts">
import { useHaptic } from '@/composables/useHaptic';

const { triggerHaptic } = useHaptic();
....

function handleClick(type: string) {
    triggerHaptic();
// other code here
}
...

Simple, and it works just fine.

Maybe in 2027 we’ll get the ability to provide haptic feedback in regular web apps natively without hacks?

Similar Posts

  • Bad I9 PDF form

    Have been needing to programmatically fill out an I9 PDF, retrieved from gov site. Should be fairly straightforward, right? Well… the field names are… a mess. Field names like topmostSubform[0].Page1[0].U\.S\._Social_Security_Number__Last_4_numbers_[0]topmostSubform[0].Page1[0].expiration_date__if_applicable__mm_dd_yyyy[0] topmostSubform[0].Page2[0].Employers_Business_or_Organization_Address_Street_Number_and_Name[0] and so on make it pretty… not straightforward to create a usable key/value combination to search and replace. But… today, I noticed it got…

  • Onboarding freelancers

    Maari Casey over at uncompany had a recent LinkedIn post about planning for freelancers. She made some good points, but I think skipped one, and it’s not just relevant for freelancers. Even well before an organization might need extra work – be it freelance or employee – companies need to have a plan for onboarding….

  • Laravel down migrations

    I get an email newsletter from Martin Joo every week or so. The newsletters generally have some useful tips around the Laravel framework or sometimes just general development tips. I’ve learned a couple of neat tricks here and there, and will continue to receive. This morning I received an email with a Laravel ‘tip’ regarding…

Leave a Reply

Your email address will not be published. Required fields are marked *