From eed184c5e362e9367fd9cdc30be8232b4aaf6f6a Mon Sep 17 00:00:00 2001 From: David Alejandro <15317732+davidalejandroaguilar@users.noreply.github.com> Date: Fri, 2 Aug 2024 16:44:37 +0300 Subject: [PATCH] Add Card component --- lib/phlexy_ui/base.rb | 3 +- lib/phlexy_ui/card.rb | 43 ++++++++ spec/lib/phlexy_ui/card_spec.rb | 167 ++++++++++++++++++++++++++++++++ 3 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 lib/phlexy_ui/card.rb create mode 100644 spec/lib/phlexy_ui/card_spec.rb diff --git a/lib/phlexy_ui/base.rb b/lib/phlexy_ui/base.rb index 13b4d88..37978b8 100644 --- a/lib/phlexy_ui/base.rb +++ b/lib/phlexy_ui/base.rb @@ -18,7 +18,8 @@ def initialize(*normal_conditions, sm: [], md: [], lg: [], **options) :md_conditions, :lg_conditions, :options, - :data + :data, + :as def classes [ diff --git a/lib/phlexy_ui/card.rb b/lib/phlexy_ui/card.rb new file mode 100644 index 0000000..f072cde --- /dev/null +++ b/lib/phlexy_ui/card.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module PhlexyUI + class Card < Base + CONDITIONS_CLASSES = { + # Modifiers + image_full: "image-full", + bordered: "card-bordered", + normal: "card-normal", + compact: "card-compact", + side: "card-side" + }.freeze + + BASE_HTML_CLASS = "card" + + def initialize(*, as: :section, **) + super(*, **) + @as = as + end + + def view_template(&) + public_send(as, class: classes, data: data, &) + end + + def body(**options, &) + classes = ["card-body", options.delete(:class)] + + div(class: classes, **options, &) + end + + def title(**options, &) + classes = ["card-title", options.delete(:class)] + + header(class: classes, **options, &) + end + + def actions(**options, &) + classes = ["card-actions", options.delete(:class)] + + footer(class: classes, **options, &) + end + end +end diff --git a/spec/lib/phlexy_ui/card_spec.rb b/spec/lib/phlexy_ui/card_spec.rb new file mode 100644 index 0000000..ea438dc --- /dev/null +++ b/spec/lib/phlexy_ui/card_spec.rb @@ -0,0 +1,167 @@ +require "spec_helper" + +describe PhlexyUI::Card do + subject(:output) { render described_class.new } + + it "is expected to match the formatted HTML" do + expected_html = html <<~HTML +
+ HTML + + is_expected.to eq(expected_html) + end + + describe "conditions" do + { + # Modifiers + image_full: "image-full", + bordered: "card-bordered", + normal: "card-normal", + compact: "card-compact", + side: "card-side" + }.each do |condition, css| + context "when given :#{condition} condition" do + subject(:output) { render described_class.new(condition) } + + it "renders it apart from the main class" do + expected_html = html <<~HTML +
+ HTML + + expect(output).to eq(expected_html) + end + 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 + subject(:output) do + render described_class.new(:compact, viewport => :bordered) + end + + it "renders it separately with a responsive prefix" do + expected_html = html <<~HTML +
+
+ HTML + + expect(output).to eq(expected_html) + end + end + + context "when given multiple responsive options as an array" do + subject(:output) do + render described_class.new(:compact, viewport => [:normal, :bordered]) + end + + it "renders it separately with a responsive prefix" do + expected_html = html <<~HTML +
+
+ HTML + + expect(output).to eq(expected_html) + end + end + + context "when it's prefixed" do + around do |example| + original_prefix = PhlexyUI.configuration.prefix + + PhlexyUI.configure do |config| + config.prefix = "foo-" + end + + example.run + + PhlexyUI.configure do |config| + config.prefix = original_prefix + end + end + + subject(:output) do + render described_class.new(:compact, viewport => [:normal, :bordered]) + end + + it "renders it separately with a responsive prefix" do + expected_html = html <<~HTML +
+
+ HTML + + expect(output).to eq(expected_html) + end + end + end + end + + describe "passing :as option" do + subject(:output) { render described_class.new(as: :div) } + + it "renders the card as the given tag" do + expected_html = html <<~HTML +
+ HTML + + expect(output).to eq(expected_html) + end + end + + describe "rendering a full card" do + let(:component) do + Class.new(Phlex::HTML) do + def view_template(&) + render PhlexyUI::Card.new(:compact) do |card| + card.body class: "my-body", data: {my: "bodies"}, style: "color: red;" do + card.figure class: "my-figure", data: {my: "figures"} do + card.img src: "image.jpg" + end + + card.title class: "my-title", data: {my: "titles"} do + h1 { "My title" } + end + + card.actions class: "my-actions", data: {my: "actions"} do + div { "My actions" } + end + end + end + end + end + end + + subject(:output) do + render component.new + end + + it "is expected to match the formatted HTML" do + expected_html = html <<~HTML +
+
+
+ +
+
+

My title

+
+ +
+
+ HTML + + is_expected.to eq(expected_html) + end + end +end