Menu
render Switch.new
Add the component to your project
Run the following command in your terminal
bundle exec essence add switch
Add the following code and libraries into your project
# frozen_string_literal: true
# A switch component that can be toggled on and off.
#
# ==== Examples
#
# render Switch.new
#
# ==== Documentation
#
# https://essence.primevise.com/components/switch
#
class Components::Switch < Components::Essence
attr_reader :checked
def initialize(checked: false, **attributes)
@checked = checked
super(**attributes)
end
def view_template(&)
button(**attributes) do
span(class: "sr-only") { "Use setting" }
lever
yield if block_given?
end
end
def lever(**mattributes) = span(**m(**mattributes))
def hidden_input(**mattributes) = input(**m(**mattributes))
private
def component_classes
{
_: {
_: "relative inline-flex h-6 w-10 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:ring-2 focus:ring-gray-950/5 focus:outline-hidden"
},
lever: {
_: "pointer-events-none inline-block size-5 translate-x-0 transform rounded-full bg-white ring-0 transition duration-200 ease-in-out"
}
}.freeze
end
def component_attributes
{
_: {
type: "button",
role: "switch",
aria_checked: false,
data: {
controller: "essence--switch",
action: "click->essence--switch#toggle",
essence__switch_checked_value: checked.to_s,
essence__switch_active_class: "bg-emerald-500",
essence__switch_inactive_class: "bg-gray-950/10",
essence__switch_active_lever_class: "translate-x-4",
essence__switch_inactive_lever_class: "translate-x-0"
}
},
lever: {
aria_hidden: "true",
data: { essence__switch_target: "lever" }
},
hidden_input: {
type: "hidden",
name: "enabled",
value: false,
data: { essence__switch_target: "input" }
}
}.freeze
end
end
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["input", "lever"];
static classes = ["active", "inactive", "activeLever", "inactiveLever"];
static values = {
checked: {
type: Boolean,
default: false,
},
};
toggle = () => (this.checkedValue = !this.checkedValue);
checkedValueChanged(state, _) {
this.element.ariaChecked = this.element.ariaChecked == state;
if (this.hasInputTarget) this.inputTarget.value = state;
this.element.classList.toggle(...this.activeClasses, state);
this.element.classList.toggle(...this.inactiveClasses, !state);
this.leverTarget.classList.toggle(...this.activeLeverClasses, state);
this.leverTarget.classList.toggle(...this.inactiveLeverClasses, !state);
}
}