Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions lib/phlexy_ui/theme_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# frozen_string_literal: true

module PhlexyUI
# @component html class="theme-controller"
# Theme controller changes the theme when checkbox/radio is checked
# Supports common patterns: swap, toggle, dropdown, radio buttons
class ThemeController < Base
register_modifiers(
# "sm:swap"
# "md:swap"
# "lg:swap"
swap: "swap",
# "sm:swap sm:swap-rotate"
# "md:swap md:swap-rotate"
# "lg:swap lg:swap-rotate"
swap_rotate: "swap swap-rotate",
# "sm:swap sm:swap-flip"
# "md:swap md:swap-flip"
# "lg:swap lg:swap-flip"
swap_flip: "swap swap-flip",
# "sm:toggle"
# "md:toggle"
# "lg:toggle"
toggle: "toggle"
)

def initialize(*, theme_value: nil, checked: false, as: :input, **)
super(*, **)
@theme_value = theme_value
@checked = checked
@as = as
end

def view_template(&block)
input_classes = generate_classes!(
# "theme-controller"
component_html_class: :"theme-controller",
modifiers_map: {},
base_modifiers: [],
options: {}
)

attrs = {type: :checkbox, class: input_classes}
attrs[:value] = theme_value if theme_value
attrs[:checked] = true if checked
attrs.merge!(options)

if block
# If block given, wrap in label with modifier classes (swap, toggle, etc.)
wrapper_classes = generate_classes!(
component_html_class: nil,
modifiers_map: modifiers,
base_modifiers:,
options: {}
)

label(class: wrapper_classes) do
public_send(as, **attrs)
whitespace
block.call
whitespace
end
else
# Just render the input
public_send(as, **attrs)
end
end

private

attr_reader :theme_value, :checked
end
end
74 changes: 74 additions & 0 deletions spec/lib/phlexy_ui/theme_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
require "spec_helper"

describe PhlexyUI::ThemeController do
subject(:output) { render described_class.new }

it "is expected to match the formatted HTML" do
expected_html = html <<~HTML
<input type="checkbox" class="theme-controller">
HTML

is_expected.to eq(expected_html)
end

describe "with theme_value" do
subject(:output) do
render described_class.new(theme_value: "dark")
end

it "renders with value attribute" do
expected_html = html <<~HTML
<input type="checkbox" class="theme-controller" value="dark">
HTML

expect(output).to eq(expected_html)
end
end

describe "with checked" do
subject(:output) do
render described_class.new(theme_value: "dark", checked: true)
end

it "renders as checked" do
expected_html = html <<~HTML
<input type="checkbox" class="theme-controller" value="dark" checked>
HTML

expect(output).to eq(expected_html)
end
end

describe "with block for swap pattern" do
subject(:output) do
render described_class.new(:swap_rotate, theme_value: "dark") do
"🌞 🌙"
end
end

it "wraps in label with icons" do
expected_html = html <<~HTML
<label class="swap swap-rotate">
<input type="checkbox" class="theme-controller" value="dark">
🌞 🌙
</label>
HTML

expect(output).to eq(expected_html)
end
end

describe "data" do
subject(:output) do
render described_class.new(data: {foo: "bar"})
end

it "renders it correctly" do
expected_html = html <<~HTML
<input type="checkbox" class="theme-controller" data-foo="bar">
HTML

expect(output).to eq(expected_html)
end
end
end