Welcome! Please hold on...

0 %
Kashif Sohail
Sr. Frontend Developer
  • Residence:
    Pakistan
  • City:
    Karachi
  • Age:
    26
Magento 1x 2x
Wordpress
Laravel
Angular
React
English
Urdu
  • Bootstrap, Tailwind
  • Sass, Less, Css
  • Webpack
  • GIT knowledge
0

No products in the cart.

How to make Storybook Interactions respect user motion preferences

December 13, 2024

[ad_1]

Recently when I was browsing my company StorybookI came across something that appeared to be broken: a flickering component that appeared to be re-rendered repeatedly. The open source tool that helps designers, developers and others create and use reusable components was behaving strangely. As I dug deeper, I realized I was seeing the unintended consequences of this Storybook Interactions add-onwhich allows developers to simulate user interactions within a story in action.

Storybook Interactions can be a powerful tool that allows developers to quickly simulate and test user behavior. However, if you’re unfamiliar with interactions – especially if you just want to explore the available components – the simulated tests bouncing around on the screen can seem confusing.

This can be particularly confusing for users who have this prefers-reduced-motion Setting activated in your operating system. When these users encounter a story that includes an interaction, their preferences are ignored and they have no option to disable or enable it. Instead, the storybook interaction will play immediately upon page load regardless. These rapid screen movements can cause users to become disoriented or, in some cases, even trigger a seizure.

Currently, Storybook does not have built-in functionality to turn interactions on or off. Until this feature can be integrated, I hope this blog provides you with an alternative way to make your work environment more inclusive. Now let’s start creating an add-on that takes into account the user’s movement preferences and allows users to turn interactions on and off.

Goals

  1. User with prefers-reduced-motion enabled MUST Interactions are disabled by default.
  2. User with prefers-reduced-motion enabled MUST have a way to turn the feature on or off without changing their operating system user settings.
  3. All users SHOULD You have the option to turn the feature on or off without changing your user settings.

Let’s get started

Step 1: Create a Storybook add-on

Storybook allows developers to create custom add-ons. In this case, we’ll create one that allows users to turn interactions on or off taking into account the prefers-reduced-motion Attitude.

Add the following code to a file in your project .storybook Folder:

import React, 
  const disableInteractions = window?.localStorage?.getItem(INTERACTION_STORAGE_KEY)
  return disableInteractions === 'false'  from 'react'

import  from '@storybook/components'
import 
  const disableInteractions = window?.localStorage?.getItem(INTERACTION_STORAGE_KEY)
  return disableInteractions === 'false'  from '@storybook/icons'

export const ADDON_ID = 'toggle-interaction'
export const TOOL_ID = `$
  const disableInteractions = window?.localStorage?.getItem(INTERACTION_STORAGE_KEY)
  return disableInteractions === 'false' /tool`

export const INTERACTION_STORAGE_KEY = 'disableInteractions'

export const InteractionToggle = () => {
  const [disableInteractions, setDisableInteractions] = React.useState(
       window?.localStorage.getItem(INTERACTION_STORAGE_KEY) === 'true',
  )

  useEffect(() => {
    const reducedMotion = matchMedia('(prefers-reduced-motion)')

    if (window?.localStorage.getItem(INTERACTION_STORAGE_KEY) === null && reducedMotion.matches) {
      window?.localStorage?.setItem(INTERACTION_STORAGE_KEY, 'true')
      setDisableInteractions(true)
    }
  }, [])

  const toggleMyTool = useCallback(() => {
    window?.localStorage?.setItem(INTERACTION_STORAGE_KEY, `${!disableInteractions}`)
    setDisableInteractions(!disableInteractions)
      // Refreshes the page to cause the interaction to stop/start
      window.location.reload()
}, [disableInteractions, setDisableInteractions])

  return (
    
      {disableInteractions ?  : }
      Interactions
    
  )
}

Code Breakdown

This add-on stores user preferences for interactions with window.localStorage. When the add-on loads for the first time, it checks whether the setting is already set and if so, it defaults to the user’s setting.

const [disableInteractions, setDisableInteractions] = React.useState(
       window?.localStorage.getItem(INTERACTION_STORAGE_KEY) === 'true',
  )

The useEffect Hook checks whether a user’s motion settings are set to prefers-reduced-motion and ensures that interactions are disabled if the user has not already set a preference in Storybook.

useEffect(() => {
    const reducedMotion = matchMedia('(prefers-reduced-motion)')

    if (window?.localStorage.getItem(INTERACTION_STORAGE_KEY) === null && reducedMotion.matches) {
      window?.localStorage?.setItem(INTERACTION_STORAGE_KEY, 'true')
      setDisableInteractions(true)
    }
  }, [])

When a user clicks the toggle button, the settings are updated and the page refreshes to reflect the changes.

const toggleMyTool = useCallback(() => {
    window?.localStorage?.setItem(INTERACTION_STORAGE_KEY, `${!disableInteractions}`)
    setDisableInteractions(!disableInteractions)
      // Refreshes the page to cause the interaction to stop/start
      window.location.reload()
  }, [disableInteractions, setDisableInteractions])

Step 2: Register your new add-on with Storybook

In yours .storybook/manager File, register your new addon:

addons.register(ADDON_ID, () => {
  addons.add(TOOL_ID, {
    title: 'toggle interaction',
    type: types.TOOL as any,
    match: ({ viewMode, tabId }) => viewMode === 'story' && !tabId,
    render: () => ,
  })
})

This adds the toggle button to the Storybook toolbar, allowing users to change their Storybook interaction settings.

Step 3: Add functions to check user settings

Finally, create a function that checks whether interactions should be played and add it to your interaction stories:

import {INTERACTION_STORAGE_KEY} from './.storybook/src/InteractionToggle'

export const shouldInteractionPlay = () => {
  const disableInteractions = window?.localStorage?.getItem(INTERACTION_STORAGE_KEY)
  return disableInteractions === 'false' || disableInteractions === null
}


 export const SomeComponentStory = {
  render: SomeComponent,
  play: async ({context}) => {
    if (shouldInteractionPlay()) {
...
    }
  })
 }

Summary

With this custom add-on, you can ensure your workspace remains accessible to motion-sensitive users while benefiting from Storybook’s interactions. For those with prefers-reduced-motion When enabled, motion is disabled by default and all users can turn interactions on or off.

Written by

[ad_2]

Source link

Posted in TechnologyTags:
Write a comment