<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: innrVoice</title>
    <description>The latest articles on DEV Community by innrVoice (@innrvoice).</description>
    <link>https://dev.to/innrvoice</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1181133%2F5ffab7b4-25d9-429f-bc09-b807b578ee0a.png</url>
      <title>DEV Community: innrVoice</title>
      <link>https://dev.to/innrvoice</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/innrvoice"/>
    <language>en</language>
    <item>
      <title>Multi-option Switch/Toggle component for React</title>
      <dc:creator>innrVoice</dc:creator>
      <pubDate>Tue, 10 Oct 2023 03:53:40 +0000</pubDate>
      <link>https://dev.to/innrvoice/multi-option-switchtoggle-component-for-react-4ef4</link>
      <guid>https://dev.to/innrvoice/multi-option-switchtoggle-component-for-react-4ef4</guid>
      <description>&lt;p&gt;We all got accustomed to the switch UI button element thanks to IOS and Android. They look a bit different but convey a simple idea of switching between two states like “on” and “off”.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;But what if I need more than one option to switch between?&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;This simple idea motivated me to start coding my own take at Switch component for React. I came up with some new concepts like handling switch dragging with snap to option, supporting mobile touch events and options for UI customisation while I was writing my shiny code 😎.&lt;/p&gt;

&lt;p&gt;So after some time a new npm library was born…&lt;/p&gt;

&lt;h2&gt;
  
  
  react-custom-switcher
&lt;/h2&gt;

&lt;p&gt;“Multi-option Switch/Toggle component for React with dragging, snap and customisable UI” as I wrote it in the docs.&lt;/p&gt;

&lt;p&gt;Library exposes the &lt;strong&gt;CustomSwitcher&lt;/strong&gt; React component that lets you easily create something like this:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/react-custom-switcher-examples-lps566"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Or you can experiment more and come up with something like this:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/react-custom-switcher-extended-customisation-demo-6h5ygd"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;You can think up a lot of different use cases for such a component: to rate something, to switch between tabs or images, or select some needed setting.&lt;/p&gt;

&lt;p&gt;In order to create switchers like this, you need to know how to use the &lt;strong&gt;CustomSwitcher&lt;/strong&gt;…&lt;/p&gt;

&lt;h2&gt;
  
  
  The API
&lt;/h2&gt;

&lt;p&gt;CustomSwitcher component accepts a list of props corresponding to &lt;strong&gt;ICustomSwitcherProps&lt;/strong&gt; interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ICustomSwitcherProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;OptionValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CustomSwitcherOption&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;OptionValue&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;OptionValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;containerWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;CustomSwitcherVariant&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;switchSize&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;dragEnabled&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;scaleWhileDrag&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cssOverrides&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;CSSOverrides&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;currentValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;OptionValue&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lets look at them one by one.&lt;/p&gt;

&lt;h3&gt;
  
  
  options
&lt;/h3&gt;

&lt;p&gt;(&lt;strong&gt;required&lt;/strong&gt;, type: &lt;em&gt;CustomerSwitcherOption[]&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;Required array of options to switch between. Every option is array should have a shape corresponding to &lt;strong&gt;CustomSwitcherOption&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;CustomSwitcherOption&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;OptionValue&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;OptionValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;label&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  value
&lt;/h3&gt;

&lt;p&gt;(&lt;strong&gt;required&lt;/strong&gt;, type: &lt;em&gt;OptionValue&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;A value from options where switch will be set by default. You can use it as a controlled value.&lt;/p&gt;

&lt;h3&gt;
  
  
  containerWidth
&lt;/h3&gt;

&lt;p&gt;(&lt;strong&gt;required&lt;/strong&gt;, type: &lt;em&gt;number&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftpastej4qclctbdaspi7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftpastej4qclctbdaspi7.png" alt="containerWidth explained" width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Width of the container where all the options will be rendered.&lt;/p&gt;

&lt;h3&gt;
  
  
  variant
&lt;/h3&gt;

&lt;p&gt;(&lt;strong&gt;optional&lt;/strong&gt;, defaults to &lt;em&gt;’primary’&lt;/em&gt;, type: &lt;em&gt;CustomSwitcherVariant&lt;/em&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;CustomSwitcherVariant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secondary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are only two basic variants of CustomSwitcher UI. All the customisations are based on one of those variants.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The anatomy of primary variant&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2sobrp4ugmmmmg61mqnm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2sobrp4ugmmmmg61mqnm.png" alt="Primary variant explained" width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Primary variant has all the elements like switch, division line, divisions and options labels at the bottom.&lt;/p&gt;

&lt;p&gt;Switch is filled and background color is transitioned in case optional &lt;strong&gt;color&lt;/strong&gt; properties were provided in &lt;strong&gt;options&lt;/strong&gt; array.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The anatomy of secondary variant&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faon909f0tf1taruqgq9a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faon909f0tf1taruqgq9a.png" alt="Secondary variant explained" width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Secondary variant has only main switch and labels at the center of divisions areas. Divisions and division line elements are hidden but this can be overridden by &lt;strong&gt;cssOverrides&lt;/strong&gt; prop (see below).&lt;/p&gt;

&lt;p&gt;Switch element is transparent but has a border. Border color is transitioned in case optional &lt;strong&gt;color&lt;/strong&gt; properties were provided in &lt;strong&gt;options&lt;/strong&gt; array.&lt;/p&gt;

&lt;h3&gt;
  
  
  switchSize
&lt;/h3&gt;

&lt;p&gt;(&lt;strong&gt;optional&lt;/strong&gt;, type: &lt;em&gt;number&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq9trp92jz6v7boeumag6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq9trp92jz6v7boeumag6.png" alt="switchSize explained" width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As is.&lt;/p&gt;

&lt;h3&gt;
  
  
  dragEnabled
&lt;/h3&gt;

&lt;p&gt;(&lt;strong&gt;optional&lt;/strong&gt;, defaults to &lt;em&gt;true&lt;/em&gt;, type: &lt;em&gt;boolean&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;You can disable dragging and it can be useful in some cases, for example when using value as a controlled value.&lt;/p&gt;

&lt;h3&gt;
  
  
  disabled
&lt;/h3&gt;

&lt;p&gt;(&lt;strong&gt;optional&lt;/strong&gt;, defaults to &lt;em&gt;false&lt;/em&gt;, type: &lt;em&gt;boolean&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;In case you need to disable interaction with CustomSwitcher.&lt;/p&gt;

&lt;h3&gt;
  
  
  scaleWhileDrag
&lt;/h3&gt;

&lt;p&gt;(&lt;strong&gt;optional&lt;/strong&gt;, defaults to &lt;em&gt;true&lt;/em&gt;, type: &lt;em&gt;boolean | number&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;You can turn off scaling of switch element while dragging by providing false. Or you can define a custom scale by providing a number, e.g 1.5 will mean a 150% switch size while dragging like when using CSS scale property.&lt;/p&gt;

&lt;h3&gt;
  
  
  cssOverrides
&lt;/h3&gt;

&lt;p&gt;(&lt;strong&gt;optional&lt;/strong&gt;, type: &lt;em&gt;CSSOverrides&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;You can pass an object of CSS overrides corresponding to this shape:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;CSSOverrides&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cursorDefault&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;CSSProperties&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cursor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="nl"&gt;cursorGrab&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;CSSProperties&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cursor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="nl"&gt;cursorGrabbing&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;CSSProperties&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cursor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="nl"&gt;cursorDisabled&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;CSSProperties&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cursor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="nl"&gt;switch&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;CSSProperties&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;switchDisabled&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;CSSProperties&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;division&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;CSSProperties&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;divisionLine&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;CSSProperties&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;label&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;CSSProperties&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this you can add and/or modify existing CSS properties of different elements and some behaviours.&lt;/p&gt;

&lt;h3&gt;
  
  
  callback
&lt;/h3&gt;

&lt;p&gt;(&lt;strong&gt;required&lt;/strong&gt;, type: &lt;em&gt;(currentValue: OptionValue) =&amp;gt; unknown&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;A callback which is fired when user selects an option either by using drag or just clicking on needed option.&lt;/p&gt;

&lt;h2&gt;
  
  
  Last words
&lt;/h2&gt;

&lt;p&gt;I hope you enjoyed the ride and that some of you might find react-custom-switcher npm library useful.&lt;/p&gt;

&lt;p&gt;And a couple of useful links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/innrvoice/react-custom-switcher" rel="noopener noreferrer"&gt;react-custom-switcher on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/react-custom-switcher" rel="noopener noreferrer"&gt;react-custom-switcher on npm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codesandbox.io/examples/package/react-custom-switcher" rel="noopener noreferrer"&gt;all react-custom-switcher examples on codesandbox&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you!&lt;/p&gt;

</description>
      <category>javascriptlibraries</category>
      <category>react</category>
      <category>ui</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
