From a57ffc841e9a33afcd27be6267e2bf11e2ed9e2a Mon Sep 17 00:00:00 2001 From: David Alejandro <15317732+davidalejandroaguilar@users.noreply.github.com> Date: Tue, 3 Sep 2024 20:52:05 +0900 Subject: [PATCH] Allow adding custom modifiers --- lib/phlexy_ui/base.rb | 1 + lib/phlexy_ui/class_list.rb | 25 ++++++- lib/phlexy_ui/configurable.rb | 24 +++++++ spec/lib/phlexy_ui/card_spec.rb | 120 ++++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+), 3 deletions(-) diff --git a/lib/phlexy_ui/base.rb b/lib/phlexy_ui/base.rb index c0651a2..acf238e 100644 --- a/lib/phlexy_ui/base.rb +++ b/lib/phlexy_ui/base.rb @@ -18,6 +18,7 @@ def generate_classes!( modifiers_map: {} ) ClassList.new( + component: self, component_html_class:, base_modifiers:, options:, diff --git a/lib/phlexy_ui/class_list.rb b/lib/phlexy_ui/class_list.rb index 27c6275..4af0b1e 100644 --- a/lib/phlexy_ui/class_list.rb +++ b/lib/phlexy_ui/class_list.rb @@ -2,7 +2,13 @@ module PhlexyUI class ClassList RESPONSIVE_PREFIXES = %i[sm md lg].freeze - def initialize(component_html_class: nil, base_modifiers: [], options: {}, modifiers_map: {}) + def initialize( + component:, + component_html_class: nil, + base_modifiers: [], + options: {}, + modifiers_map: {} + ) @component_html_class = component_html_class @base_modifiers = base_modifiers @options = options @@ -22,10 +28,17 @@ def to_a attr_reader :component_html_class, :base_modifiers, :options, :modifiers_map - def selected_base_modifiers_classes + def selected_base_modifiers base_modifiers.select { |modifier| modifiers_map.key?(modifier) } end + def selected_custom_modifiers + base_modifiers.select do |modifier| + PhlexyUI.configuration.modifiers.key?(modifier, component:) || + PhlexyUI.configuration.modifiers.key?(modifier) + end + end + def add_component_class(classes) return unless component_html_class @@ -35,7 +48,13 @@ def add_component_class(classes) def add_selected_modifiers_classes(classes) classes.concat( html_classes_for_modifiers( - selected_base_modifiers_classes + selected_base_modifiers + ) + ) + + classes.concat( + html_classes_for_modifiers( + selected_custom_modifiers ) ) end diff --git a/lib/phlexy_ui/configurable.rb b/lib/phlexy_ui/configurable.rb index 150fcee..31e456c 100644 --- a/lib/phlexy_ui/configurable.rb +++ b/lib/phlexy_ui/configurable.rb @@ -10,12 +10,36 @@ def configuration @configuration ||= Configuration.new end + class Modifiers + def initialize + @modifiers = {} + end + + def add(modifier, classes:, component: nil) + @modifiers[component] ||= {} + @modifiers[component][modifier] = classes + end + + def remove(modifier, component: nil) + @modifiers[component] ||= {} + @modifiers[component]&.delete(modifier) + end + + def for(component: nil) + @modifiers[component] || {} + end + end + class Configuration attr_accessor :prefix def initialize @prefix = nil end + + def modifiers + @modifiers ||= Modifiers.new + end end end end diff --git a/spec/lib/phlexy_ui/card_spec.rb b/spec/lib/phlexy_ui/card_spec.rb index 462ca49..8ed4dcf 100644 --- a/spec/lib/phlexy_ui/card_spec.rb +++ b/spec/lib/phlexy_ui/card_spec.rb @@ -107,6 +107,81 @@ end end + describe "custom modifiers" do + context "when there's a custom modifier for the component" do + around do |example| + PhlexyUI.configure do |config| + config.modifiers.add( + :my_modifier, + component: PhlexyUI::Card, + classes: "w-96 shadow-xl" + ) + end + + example.run + + PhlexyUI.configure do |config| + config.modifiers.remove(:my_modifier, component: PhlexyUI::Card) + end + end + + subject(:output) do + render described_class.new(:my_modifier) + end + + it "renders it correctly" do + expected_html = html <<~HTML +
+ HTML + + expect(output).to eq(expected_html) + end + end + + context "when there's a custom modifier without a specific component" do + around do |example| + PhlexyUI.configure do |config| + config.modifiers.add( + :my_modifier, + classes: "w-96 shadow-xl" + ) + end + + example.run + + PhlexyUI.configure do |config| + config.modifiers.remove(:my_modifier) + end + end + + subject(:output) do + render described_class.new(:my_modifier) + end + + it "renders it correctly" do + expected_html = html <<~HTML +
+ HTML + + expect(output).to eq(expected_html) + end + end + + context "when there's no custom modifier" do + subject(:output) do + render described_class.new(:my_modifier) + end + + it "does not render it" do + expected_html = html <<~HTML +
+ HTML + + expect(output).to eq(expected_html) + end + end + end + describe "responsiveness" do %i[sm md lg].each do |viewport| context "when given an :#{viewport} responsive option as a single argument" do @@ -181,6 +256,51 @@ expect(output).to eq(expected_html) end end + + context "when there are custom modifiers" do + around do |example| + PhlexyUI.configure do |config| + config.modifiers.add( + :my_modifier, + component: PhlexyUI::Card, + classes: "w-96 shadow-xl" + ) + + config.modifiers.add( + :my_other_modifier, + classes: "p-4 rounded-box" + ) + end + + example.run + + PhlexyUI.configure do |config| + config.modifiers.remove(:my_modifier, component: PhlexyUI::Card) + config.modifiers.remove(:my_other_modifier) + end + end + + subject(:output) do + render described_class.new( + :my_modifier, + viewport => :my_other_modifier + ) + end + + it "renders it separately with a responsive prefix" do + expected_html = html <<~HTML +