-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c08c077
commit b917733
Showing
4 changed files
with
249 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# frozen_string_literal: true | ||
|
||
module PhlexyUI | ||
class Base < Phlex::HTML | ||
def initialize(*normal_conditions, sm: [], md: [], lg: [], **options) | ||
@normal_conditions = normal_conditions | ||
@sm_conditions = Array(sm) | ||
@md_conditions = Array(md) | ||
@lg_conditions = Array(lg) | ||
@options = options | ||
@data = options.delete(:data) | ||
end | ||
|
||
private | ||
|
||
attr_reader :normal_conditions, | ||
:sm_conditions, | ||
:md_conditions, | ||
:lg_conditions, | ||
:options, | ||
:data | ||
|
||
def classes | ||
[ | ||
prefixed(self.class::BASE_HTML_CLASS), | ||
*html_classes_for_conditions(normal_conditions), | ||
*html_classes_for_conditions(sm_conditions, responsive_prefix: :sm), | ||
*html_classes_for_conditions(md_conditions, responsive_prefix: :md), | ||
*html_classes_for_conditions(lg_conditions, responsive_prefix: :lg) | ||
] | ||
end | ||
|
||
def html_classes_for_conditions(conditions, responsive_prefix: nil) | ||
conditions.map do |condition| | ||
class_name = prefixed self.class::CONDITIONS_CLASSES.fetch(condition) | ||
|
||
responsive_prefix ? "#{responsive_prefix}:#{class_name}" : class_name | ||
end | ||
rescue KeyError => e | ||
raise ArgumentError, "Condition `#{e.key}` is not defined for #{self.class}" | ||
end | ||
|
||
def prefixed(string) | ||
"#{PhlexyUI.configuration.prefix}#{string}" | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# frozen_string_literal: true | ||
|
||
module PhlexyUI | ||
class Button < Base | ||
CONDITIONS_CLASSES = { | ||
# Modifiers | ||
no_animation: "no-animation", | ||
glass: "glass", | ||
ghost: "btn-ghost", | ||
link: "btn-link", | ||
outline: "btn-outline", | ||
active: "btn-active", | ||
disabled: "btn-disabled", | ||
lg: "btn-lg", | ||
md: "btn-md", | ||
sm: "btn-sm", | ||
xs: "btn-xs", | ||
wide: "btn-wide", | ||
block: "btn-block", | ||
circle: "btn-circle", | ||
square: "btn-square", | ||
# Colors | ||
neutral: "btn-neutral", | ||
primary: "btn-primary", | ||
secondary: "btn-secondary", | ||
accent: "btn-accent", | ||
info: "btn-info", | ||
success: "btn-success", | ||
warning: "btn-warning", | ||
error: "btn-error" | ||
}.freeze | ||
|
||
BASE_HTML_CLASS = "btn" | ||
|
||
def view_template(&) | ||
button(class: classes, data:, &) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
require "spec_helper" | ||
|
||
describe PhlexyUI::Button do | ||
subject(:output) { render described_class.new } | ||
|
||
it { is_expected.to eq(%(<button class="btn"></button>)) } | ||
|
||
describe "conditions" do | ||
{ | ||
# Modifiers | ||
no_animation: "no-animation", | ||
glass: "glass", | ||
ghost: "btn-ghost", | ||
link: "btn-link", | ||
outline: "btn-outline", | ||
active: "btn-active", | ||
disabled: "btn-disabled", | ||
lg: "btn-lg", | ||
md: "btn-md", | ||
sm: "btn-sm", | ||
xs: "btn-xs", | ||
wide: "btn-wide", | ||
block: "btn-block", | ||
circle: "btn-circle", | ||
square: "btn-square", | ||
# Colors | ||
neutral: "btn-neutral", | ||
primary: "btn-primary", | ||
secondary: "btn-secondary", | ||
accent: "btn-accent", | ||
info: "btn-info", | ||
success: "btn-success", | ||
warning: "btn-warning", | ||
error: "btn-error" | ||
}.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 | ||
expect(output).to eq(%(<button class="btn #{css}"></button>)) | ||
end | ||
end | ||
end | ||
|
||
context "when condition doesn't exist" do | ||
subject(:output) { render described_class.new(:foo) } | ||
|
||
it "raises an error" do | ||
expect { render described_class.new(:foo) } | ||
.to raise_error( | ||
ArgumentError, | ||
"Condition `foo` is not defined for PhlexyUI::Button" | ||
) | ||
end | ||
end | ||
|
||
context "when given multiple conditions" do | ||
subject(:output) { render described_class.new(:neutral, :primary) } | ||
|
||
it "renders them separately" do | ||
expect(output) | ||
.to eq(%(<button class="btn btn-neutral btn-primary"></button>)) | ||
end | ||
end | ||
end | ||
|
||
describe "data" do | ||
subject(:output) do | ||
render described_class.new(:neutral, data: {foo: "bar"}) | ||
end | ||
|
||
it "renders it correctly" do | ||
expect(output).to eq(%(<button class="btn btn-neutral" data-foo="bar"></button>)) | ||
end | ||
end | ||
|
||
describe "prefix" 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(:neutral) | ||
end | ||
|
||
it "renders it correctly" do | ||
expect(output).to eq(%(<button class="foo-btn foo-btn-neutral"></button>)) | ||
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(:neutral, viewport => :primary) | ||
end | ||
|
||
it "renders it separately with a responsive prefix" do | ||
expect(output) | ||
.to eq(%(<button class="btn btn-neutral #{viewport}:btn-primary"></button>)) | ||
end | ||
end | ||
|
||
context "when given multiple responsive options as an array" do | ||
subject(:output) do | ||
render described_class.new(:neutral, viewport => [:primary, :active]) | ||
end | ||
|
||
it "renders it separately with a responsive prefix" do | ||
expect(output) | ||
.to eq(%(<button class="btn btn-neutral #{viewport}:btn-primary #{viewport}:btn-active"></button>)) | ||
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(:neutral, viewport => [:primary, :active]) | ||
end | ||
|
||
it "renders it separately with a responsive prefix" do | ||
expect(output) | ||
.to eq(%(<button class="foo-btn foo-btn-neutral #{viewport}:foo-btn-primary #{viewport}:foo-btn-active"></button>)) | ||
end | ||
end | ||
end | ||
end | ||
|
||
describe "rendering via Kit" do | ||
subject(:output) do | ||
Button(:neutral) | ||
end | ||
|
||
it "renders it correctly" do | ||
expect(output).to eq(%(<button class="btn btn-neutral"></button>)) | ||
end | ||
end | ||
end |