Toggle input (TToggle)

VueJs reactive toggle component with configurable classes, variants, and most common events. Friendly with utility-first frameworks like TailwindCSS.

Playground:


Basic example

<t-toggle checked />

Props

PropertyTypeDefault valueDescription
model (v-model)[String, Object, Number, Boolean, Array]undefinedThe element using for the v-model
value[String, Object, Number, Boolean, Array]trueThe value for the element when checked
uncheckedValue[String, Object, Number, Boolean, Array]falseThe value for the element when unchecked
checkedPlaceholderStringundefinedOptional string to show in the unchecked side
uncheckedPlaceholderStringundefinedOptional string to show in the checked side
checkedLabelStringundefinedOptional string to show inside the button when checked
uncheckedLabelStringundefinedOptional string to show inside the button when unchecked
checkedBooleanundefinedUsed to show the toggle as checked when no using a v-model
idStringundefinedHTML attribute
autofocusBooleanundefinedHTML attribute
disabledBooleanundefinedHTML attribute
nameStringundefinedHTML attribute of the hidden input
readonlyBooleanundefinedHTML attribute of the hidden input
requiredBooleanundefinedHTML attribute of the hidden input
tabindex[String, Number]0HTML attribute
classesObject{...} (see below)The default CSS classes
fixedClassesObject{...} (see below)Fixed CSS classes that will be merged with the active set of classes
variantsObjectundefinedThe different variants of classes the component have
variant[String, Object]undefinedThe variant that will be used

Classes and variants format

This component expects an object with classes named after every child element.

The properties in that object are the following:

PropertyDescription
wrapperWrapper of the component
wrapperCheckedWrapper when checked
buttonToggle button
buttonCheckedToggle button when checked
checkedPlaceholderPlaceholder in the unchecked side
uncheckedPlaceholderPlaceholder in the checked side

Default fixed classes

As you may know, the fixed classes are shared and merged with the different variants and default classes. The classes we define here as default are the ones that you usually will need to make this component works correctly so you can only focus on colors, size, etc when creating your theme.

{
  wrapper: 'relative inline-flex flex-shrink-0 cursor-pointer transition-colors ease-in-out duration-200',
  wrapperChecked: 'relative inline-flex flex-shrink-0 cursor-pointer transition-colors ease-in-out duration-200',
  button: 'inline-block absolute transform translate-x-0 transition ease-in-out duration-200',
  buttonChecked: 'inline-block absolute transform translate-x-full transition ease-in-out duration-200',
  checkedPlaceholder: 'inline-block',
  uncheckedPlaceholder: 'inline-block',
};

Default classes

{
  wrapper: 'bg-gray-200 focus:outline-none focus:shadow-outline rounded-full border-2 border-transparent',
  wrapperChecked: 'bg-blue-500 focus:outline-none focus:shadow-outline rounded-full border-2 border-transparent',
  button: 'h-5 w-5 rounded-full bg-white shadow  flex items-center justify-center text-gray-400 text-xs',
  buttonChecked: 'h-5 w-5 rounded-full bg-white shadow  flex items-center justify-center text-blue-500 text-xs',
  checkedPlaceholder: 'rounded-full w-5 h-5 flex items-center justify-center text-gray-500 text-xs',
  uncheckedPlaceholder: 'rounded-full w-5 h-5 flex items-center justify-center text-gray-500 text-xs',
}

Label and placeholders

The labels and placeholder are optional and are useful for adding some extra info to the toggle components, the label placeholder is shown inside the button and the placeholder behind.

Example

A good example is an AM/PM toggle for a time picker

<t-toggle
  value="PM"
  unchecked-value="AM"
  checked-placeholder="AM"
  unchecked-placeholder="PM"
  checked-label="PM"
  unchecked-label="AM"
  :classes="{
    wrapper: 'bg-gray-200 focus:outline-none focus:shadow-outline rounded-sm border-2',
    wrapperChecked: 'bg-gray-200 focus:outline-none focus:shadow-outline rounded-sm border-2',
    button: 'rounded-sm w-6 h-6 bg-white shadow flex items-center justify-center text-gray-800 text-xs',
    buttonChecked: 'rounded-sm w-6 h-6 bg-white shadow flex items-center justify-center text-gray-800 text-xs',
    checkedPlaceholder: 'rounded-sm w-6 h-6 flex items-center justify-center text-gray-500 text-xs',
    uncheckedPlaceholder: 'rounded-sm w-6 h-6 flex items-center justify-center text-gray-500 text-xs'
  }"
/>

Scoped slots

SlotDescription
defaultSet the content inside the option
checkedSet the content in the placeholder of the unchecked side
uncheckedSet the content in the placeholder of the checked side

Default slot

Allows you to add content inside the button

SlottypeDescription
valueStringThe checked value
uncheckedValueStringThe unchecked value
isCheckedBooleanIf the component is checked

Example:

Add an icon according to the checked/unchecked

<t-toggle>
  <template
    slot="default"
    slot-scope="{ isChecked }"
  >
    <span
      class="absolute inset-0 h-full w-full flex items-center justify-center transition-opacity"
      :class="{
        'opacity-100 ease-in duration-200': !isChecked,
        'opacity-0 ease-out duration-100': isChecked,
      }"
    >
      👍
    </span>
    <span
      class=" absolute inset-0 h-full w-full flex items-center justify-center transition-opacity"
      :class="{
        'opacity-100 ease-in duration-200': isChecked,
        'opacity-0 ease-out duration-100': !isChecked,
      }"
    >
      👎
    </span>
  </template>
</t-toggle>

The example above will look like this:

Events

EventArgumentsDescription
inputString (The current value of the toggle)Emitted every time the value of the v-model change
changeString (The current value of the toggle)Emitted every time the value of the v-model change
focusFocusEventEmitted when the toggle is focused
blurFocusEventEmitted when the toggle is blurred