backpack 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitlab-ci.yml +2 -2
- data/README.md +11 -1
- data/demo/.yarnrc.yml +4 -0
- data/demo/Gemfile.lock +2 -2
- data/demo/app/views/layouts/backpack.html.erb +2 -4
- data/demo/config/initializers/phlex.rb +9 -0
- data/demo/yarn.lock +1101 -1101
- data/lib/backpack/{components/concerns/classes.rb → classes.rb} +1 -1
- data/lib/backpack/cli.rb +39 -0
- data/lib/backpack/components/badge.rb +1 -1
- data/lib/backpack/components/base.rb +1 -1
- data/lib/backpack/components/breadcrumb.rb +2 -2
- data/lib/backpack/components/button.rb +1 -1
- data/lib/backpack/components/favicon.rb +1 -1
- data/lib/backpack/components/heading.rb +1 -1
- data/lib/backpack/components/icon.rb +1 -1
- data/lib/backpack/components/icon_button/icon_button.css +183 -0
- data/lib/backpack/components/icon_button/icon_button.js +1 -0
- data/lib/backpack/components/icon_button.rb +32 -0
- data/lib/backpack/components/icon_sprite.rb +1 -1
- data/lib/backpack/components/quotation.rb +1 -1
- data/lib/backpack/components/rich_text.rb +1 -1
- data/lib/backpack/components/skip_links.rb +1 -1
- data/lib/backpack/components.rb +2 -4
- data/lib/backpack/{components/concerns/identifier.rb → identifier.rb} +5 -1
- data/lib/backpack/version.rb +1 -1
- data/lib/backpack.rb +7 -4
- data/spec/cli/import_spec.rb +51 -0
- data/spec/components/badge_spec.rb +3 -3
- data/spec/components/breadcrumb_spec.rb +10 -4
- data/spec/components/button_spec.rb +7 -7
- data/spec/components/favicon_spec.rb +5 -3
- data/spec/components/heading_spec.rb +3 -3
- data/spec/components/icon_button_spec.rb +58 -0
- data/spec/components/icon_spec.rb +3 -3
- data/spec/components/icon_sprite_spec.rb +3 -3
- data/spec/components/previews/badge_preview/overview.html.erb +2 -2
- data/spec/components/previews/badge_preview.rb +3 -1
- data/spec/components/previews/breadcrumb_preview.rb +3 -1
- data/spec/components/previews/button_preview/overview.html.erb +3 -3
- data/spec/components/previews/button_preview.rb +2 -1
- data/spec/components/previews/heading_preview.rb +3 -1
- data/spec/components/previews/icon_button_preview/overview.html.erb +48 -0
- data/spec/components/previews/icon_button_preview.rb +14 -0
- data/spec/components/previews/icon_preview.rb +3 -1
- data/spec/components/previews/quotation_preview/overview.html.erb +2 -2
- data/spec/components/previews/quotation_preview.rb +3 -1
- data/spec/components/previews/rich_text_preview.rb +5 -1
- data/spec/components/previews/skip_links_preview.rb +3 -1
- data/spec/components/quotation_spec.rb +7 -5
- data/spec/components/rich_text_spec.rb +3 -3
- data/spec/components/skip_links_spec.rb +10 -5
- data/spec/spec_helper.rb +2 -1
- data/spec/support/cli_helpers.rb +5 -0
- data/spec/support/components.rb +8 -0
- data/{lib/backpack → spec/support}/spec_helpers.rb +1 -1
- metadata +70 -12
- data/spec/components/previews/backpack/preview.rb +0 -3
- /data/lib/backpack/{components/concerns/attributes.rb → attributes.rb} +0 -0
data/lib/backpack/cli.rb
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require "thor"
|
|
2
|
+
require "backpack"
|
|
3
|
+
|
|
4
|
+
module Backpack
|
|
5
|
+
class CLI < Thor
|
|
6
|
+
include Thor::Actions
|
|
7
|
+
|
|
8
|
+
desc "import", "Import Backpack in the current project"
|
|
9
|
+
|
|
10
|
+
source_root File.expand_path(__dir__)
|
|
11
|
+
|
|
12
|
+
def import
|
|
13
|
+
say ascii_art, :green
|
|
14
|
+
|
|
15
|
+
directory "stylesheets", "app/assets/stylesheets", recursive: true
|
|
16
|
+
directory "components", "app/components", recursive: true
|
|
17
|
+
|
|
18
|
+
copy_file "attributes.rb", "lib/backpack/attributes.rb"
|
|
19
|
+
copy_file "classes.rb", "lib/backpack/classes.rb"
|
|
20
|
+
copy_file "identifier.rb", "lib/backpack/identifier.rb"
|
|
21
|
+
copy_file "tokens.rb", "lib/backpack/tokens.rb"
|
|
22
|
+
|
|
23
|
+
directory "../../spec/components", "spec/components", recursive: true do |content|
|
|
24
|
+
content.gsub("require 'spec_helper'", "require 'rails_helper'")
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def ascii_art
|
|
31
|
+
<<~ASCII
|
|
32
|
+
┌┐ ┌─┐┌─┐┬┌─┌─┐┌─┐┌─┐┬┌─
|
|
33
|
+
├┴┐├─┤│ ├┴┐├─┘├─┤│ ├┴┐
|
|
34
|
+
└─┘┴ ┴└─┘┴ ┴┴ ┴ ┴└─┘┴ ┴
|
|
35
|
+
|
|
36
|
+
ASCII
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
class
|
|
3
|
+
class Components::Badge < Components::Base
|
|
4
4
|
prop :variant, _Union(:solid, :soft, :surface, :outline), default: :solid
|
|
5
5
|
prop :color, Backpack::Tokens::OptionalColor
|
|
6
6
|
prop :size, Backpack::Tokens::Size, default: 2
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
class
|
|
4
|
-
class Item <
|
|
3
|
+
class Components::Breadcrumb < Components::Base
|
|
4
|
+
class Item < Components::Base
|
|
5
5
|
prop :href, HTMLAttribute, default: ""
|
|
6
6
|
prop :breadcrumb, Breadcrumb
|
|
7
7
|
prop :last, _Boolean, default: false
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
class
|
|
3
|
+
class Components::Heading < Components::Base
|
|
4
4
|
prop :level, _Union(1, 2, 3, 4, 5), default: 1
|
|
5
5
|
prop :tag, _Union(:h1, :h2, :h3, :h4, :h5, :h6), default: -> { :"h#{@level}" }
|
|
6
6
|
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
appearance: none;
|
|
3
|
+
border: none;
|
|
4
|
+
border-radius: var(--radius-full);
|
|
5
|
+
cursor: pointer;
|
|
6
|
+
display: inline-flex;
|
|
7
|
+
justify-content: center;
|
|
8
|
+
text-decoration: none;
|
|
9
|
+
transition:
|
|
10
|
+
background-color 0.2s ease-in-out,
|
|
11
|
+
color 0.2s ease-in-out;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* solid */
|
|
15
|
+
.variant-solid {
|
|
16
|
+
background-color: var(--accent-9);
|
|
17
|
+
color: var(--accent-1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@media (hover: hover) {
|
|
21
|
+
.variant-solid:hover {
|
|
22
|
+
background-color: var(--accent-10);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.variant-solid:active {
|
|
27
|
+
background-color: var(--accent-12);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.variant-solid:focus {
|
|
31
|
+
outline: 0.3rem solid var(--accent-8);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.variant-solid:disabled {
|
|
35
|
+
background-color: var(--slate-5);
|
|
36
|
+
border: none;
|
|
37
|
+
color: var(--slate-9);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* soft */
|
|
41
|
+
.variant-soft {
|
|
42
|
+
background-color: var(--accent-5);
|
|
43
|
+
color: var(--accent-9);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@media (hover: hover) {
|
|
47
|
+
.variant-soft:hover {
|
|
48
|
+
background-color: var(--accent-6);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.variant-soft:active {
|
|
53
|
+
background-color: var(--accent-7);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.variant-soft:focus {
|
|
57
|
+
background-color: var(--accent-5);
|
|
58
|
+
outline: 0.2rem solid var(--accent-9);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.variant-soft:disabled {
|
|
62
|
+
background-color: var(--slate-4);
|
|
63
|
+
border: none;
|
|
64
|
+
color: var(--slate-9);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* surface */
|
|
68
|
+
.variant-surface {
|
|
69
|
+
background-color: var(--accent-3);
|
|
70
|
+
box-shadow: inset 0 0 0 1px var(--accent-9);
|
|
71
|
+
color: var(--accent-9);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@media (hover: hover) {
|
|
75
|
+
.variant-surface:hover {
|
|
76
|
+
background-color: var(--accent-4);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.variant-surface:active {
|
|
81
|
+
background-color: var(--accent-5);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.variant-surface:focus {
|
|
85
|
+
outline: 0.2rem solid var(--accent-9);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.variant-surface:disabled {
|
|
89
|
+
background-color: var(--slate-3);
|
|
90
|
+
box-shadow: inset 0 0 0 1px var(--slate-8);
|
|
91
|
+
color: var(--slate-9);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/* outline */
|
|
95
|
+
.variant-outline {
|
|
96
|
+
background-color: transparent;
|
|
97
|
+
box-shadow: inset 0 0 0 1px var(--accent-9);
|
|
98
|
+
color: var(--accent-9);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@media (hover: hover) {
|
|
102
|
+
.variant-outline:hover {
|
|
103
|
+
background-color: var(--accent-3);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.variant-outline:active {
|
|
108
|
+
background-color: var(--accent-4);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.variant-outline:focus {
|
|
112
|
+
outline: 0.2rem solid var(--accent-9);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.variant-outline:disabled {
|
|
116
|
+
background-color: transparent;
|
|
117
|
+
box-shadow: inset 0 0 0 1px var(--slate-8);
|
|
118
|
+
color: var(--slate-8);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/* ghost */
|
|
122
|
+
.variant-ghost {
|
|
123
|
+
color: var(--accent-9);
|
|
124
|
+
background-color: transparent;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
@media (hover: hover) {
|
|
128
|
+
.variant-ghost:hover {
|
|
129
|
+
background-color: var(--accent-4);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.variant-ghost:active {
|
|
134
|
+
background-color: var(--accent-5);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.variant-ghost:focus {
|
|
138
|
+
outline: 0.2rem solid var(--accent-9);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.variant-ghost:disabled {
|
|
142
|
+
background-color: transparent;
|
|
143
|
+
color: var(--slate-8);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/* size */
|
|
147
|
+
.size-1 {
|
|
148
|
+
--icon-size: 1.8rem;
|
|
149
|
+
padding: var(--space-4);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.size-2 {
|
|
153
|
+
--icon-size: 2rem;
|
|
154
|
+
padding: var(--space-5);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.size-3 {
|
|
158
|
+
--icon-size: 2.4rem;
|
|
159
|
+
padding: var(--space-5);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/* States */
|
|
163
|
+
.root:disabled {
|
|
164
|
+
cursor: not-allowed;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
@media (max-width: 576px) {
|
|
168
|
+
.root {
|
|
169
|
+
line-height: 1;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.size-1 {
|
|
173
|
+
--icon-size: 1.6rem;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.size-2 {
|
|
177
|
+
--icon-size: 1.8rem;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.size-3 {
|
|
181
|
+
--icon-size: 2rem;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "./icon_button.css";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Components::IconButton < Components::Base
|
|
4
|
+
prop :href, HTMLAttribute, predicate: :private
|
|
5
|
+
prop :label, MandatoryHTMLAttribute
|
|
6
|
+
prop :icon, _Union(Symbol, String)
|
|
7
|
+
prop :variant, Backpack::Tokens::Variant, default: :solid
|
|
8
|
+
prop :color, Backpack::Tokens::OptionalColor
|
|
9
|
+
prop :size, Backpack::Tokens::Size, default: 2
|
|
10
|
+
|
|
11
|
+
def view_template
|
|
12
|
+
if href?
|
|
13
|
+
a(href: @href, **root_attributes) { render_icon }
|
|
14
|
+
else
|
|
15
|
+
button(**root_attributes) { render_icon }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def render_icon
|
|
22
|
+
Icon(@icon, class: "#{root_class}-icon", label: @label)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def variant_props
|
|
26
|
+
%i[variant size]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def extra_root_attributes
|
|
30
|
+
{ data_accent_color: @color }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'rails-html-sanitizer'
|
|
4
4
|
|
|
5
|
-
class
|
|
5
|
+
class Components::IconSprite < Components::Base
|
|
6
6
|
ICON_PATHS = [
|
|
7
7
|
Rails.root&.join("app/assets/icons"),
|
|
8
8
|
Rails.root&.join("node_modules/lucide-static/icons"),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
class
|
|
3
|
+
class Components::Quotation < Components::Base
|
|
4
4
|
prop :cite, _String?, predicate: :private
|
|
5
5
|
prop :size, _Union(1, 2, 3, 4, 5, 6), default: 2
|
|
6
6
|
prop :weight, Backpack::Tokens::Weight, default: :regular
|
data/lib/backpack/components.rb
CHANGED
|
@@ -5,9 +5,13 @@ module Backpack::Identifier
|
|
|
5
5
|
|
|
6
6
|
class_methods do
|
|
7
7
|
def identifier
|
|
8
|
-
|
|
8
|
+
(name.split("::") - %w[Components Backpack]).join("/")
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
+
def identifier
|
|
13
|
+
self.class.identifier.parameterize
|
|
14
|
+
end
|
|
15
|
+
|
|
12
16
|
delegate :identifier, to: :class
|
|
13
17
|
end
|
data/lib/backpack/version.rb
CHANGED
data/lib/backpack.rb
CHANGED
|
@@ -6,11 +6,14 @@ require 'date'
|
|
|
6
6
|
require 'literal'
|
|
7
7
|
require 'phlex-rails'
|
|
8
8
|
require 'rails'
|
|
9
|
-
require 'zeitwerk'
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
require 'backpack/cli'
|
|
11
|
+
|
|
12
|
+
require 'backpack/attributes'
|
|
13
|
+
require 'backpack/classes'
|
|
14
|
+
require 'backpack/identifier'
|
|
15
|
+
require 'backpack/tokens'
|
|
16
|
+
require 'backpack/components'
|
|
14
17
|
|
|
15
18
|
module Backpack
|
|
16
19
|
class Error < StandardError; end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Backpack::CLI, type: :cli do
|
|
4
|
+
sandbox_dir = "sandbox"
|
|
5
|
+
|
|
6
|
+
around do |example|
|
|
7
|
+
FileUtils.mkdir(sandbox_dir) unless File.exist?(sandbox_dir)
|
|
8
|
+
within_dir(sandbox_dir) do
|
|
9
|
+
example.run
|
|
10
|
+
end
|
|
11
|
+
ensure
|
|
12
|
+
FileUtils.rm_rf(sandbox_dir)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe "import" do
|
|
16
|
+
let(:command) { `ruby ../bin/backpack import` }
|
|
17
|
+
let(:output) { command.chomp }
|
|
18
|
+
|
|
19
|
+
it "outputs ascii art and the list of created files" do
|
|
20
|
+
expect(output).to include(described_class.new.send(:ascii_art))
|
|
21
|
+
expect(output).to include("create app/assets/stylesheets/application.css")
|
|
22
|
+
expect(output).to include("create app/components/base.rb")
|
|
23
|
+
expect(output).to include("create app/components/button.rb")
|
|
24
|
+
expect(output).to include("create app/components/button/button.js")
|
|
25
|
+
expect(output).to include("create app/components/button/button.css")
|
|
26
|
+
expect(output).to include("create lib/backpack/attributes.rb")
|
|
27
|
+
expect(output).to include("create lib/backpack/classes.rb")
|
|
28
|
+
expect(output).to include("create lib/backpack/identifier.rb")
|
|
29
|
+
expect(output).to include("create lib/backpack/tokens.rb")
|
|
30
|
+
expect(output).to include("create spec/components/button_spec.rb")
|
|
31
|
+
expect(output).to include("create spec/components/previews/button_preview.rb")
|
|
32
|
+
expect(output).to include("create spec/components/previews/button_preview/overview.html.erb")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "copies the folders" do
|
|
36
|
+
command
|
|
37
|
+
expect(File.directory?("app/assets/stylesheets")).to be true
|
|
38
|
+
expect(File.directory?("app/components")).to be true
|
|
39
|
+
expect(File.directory?("spec/components")).to be true
|
|
40
|
+
expect(File.directory?("spec/components/previews")).to be true
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "copies the lib files" do
|
|
44
|
+
command
|
|
45
|
+
expect(File.exist?("lib/backpack/attributes.rb")).to be true
|
|
46
|
+
expect(File.exist?("lib/backpack/classes.rb")).to be true
|
|
47
|
+
expect(File.exist?("lib/backpack/identifier.rb")).to be true
|
|
48
|
+
expect(File.exist?("lib/backpack/tokens.rb")).to be true
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
|
-
describe
|
|
3
|
+
describe Components::Badge, type: :component do
|
|
4
|
+
subject(:output) { render_fragment(component) }
|
|
5
|
+
|
|
4
6
|
let(:component) { described_class.new(**params) { text } }
|
|
5
7
|
let(:params) { {} }
|
|
6
8
|
let(:text) { "Badge" }
|
|
7
9
|
|
|
8
|
-
subject(:output) { render_fragment(component) }
|
|
9
|
-
|
|
10
10
|
it "renders the element with the default styling" do
|
|
11
11
|
expect(output).to have_css(
|
|
12
12
|
".Badge.Badge-variant-solid", text:
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
|
-
describe
|
|
3
|
+
describe Components::Breadcrumb, type: :component do
|
|
4
|
+
subject(:output) { render_fragment(component) }
|
|
5
|
+
|
|
4
6
|
let(:component) { described_class.new(**params) }
|
|
5
7
|
let(:params) { {} }
|
|
6
8
|
|
|
7
|
-
subject(:output) { render_fragment(component) }
|
|
8
|
-
|
|
9
9
|
context "without items" do
|
|
10
10
|
it "renders nothing" do
|
|
11
11
|
expect(output).to eq_html('')
|
|
@@ -25,9 +25,15 @@ describe Backpack::Components::Breadcrumb, type: :component do
|
|
|
25
25
|
expect(output).to have_css("nav.Breadcrumb[role='navigation'][aria-label='Breadcrumb']")
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
it "renders
|
|
28
|
+
it "renders first item" do
|
|
29
29
|
expect(output).to have_css("li:nth-child(1) a[href='/']", text: "Home")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "renders second item" do
|
|
30
33
|
expect(output).to have_css("li:nth-child(2) a[href='/sections']", text: "Sections")
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "renders third item" do
|
|
31
37
|
expect(output).to have_css("li:nth-child(3) a[href='']", text: "Articles")
|
|
32
38
|
end
|
|
33
39
|
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
|
-
describe
|
|
3
|
+
describe Components::Button, type: :component do
|
|
4
|
+
subject(:output) { render_fragment(component) }
|
|
5
|
+
|
|
4
6
|
let(:component) { described_class.new(**params) { text } }
|
|
5
7
|
let(:params) { {} }
|
|
6
8
|
let(:text) { "Label" }
|
|
7
9
|
|
|
8
|
-
subject(:output) { render_fragment(component) }
|
|
9
|
-
|
|
10
10
|
it "renders a button element with the default styling" do
|
|
11
11
|
expect(output).to have_css(
|
|
12
12
|
"button.Button.Button-variant-solid.Button-size-2", text:
|
|
13
13
|
)
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
it "doesn't render
|
|
17
|
-
expect(output).
|
|
16
|
+
it "doesn't render the icon" do
|
|
17
|
+
expect(output).not_to have_css("button.Button svg.Icon")
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
context "with a href" do
|
|
@@ -54,7 +54,7 @@ describe Backpack::Components::Button, type: :component do
|
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
context "with an icon before the text" do
|
|
57
|
-
let(:icon) { render(
|
|
57
|
+
let(:icon) { render(Components::Icon.new("user")) }
|
|
58
58
|
let(:component) do
|
|
59
59
|
described_class.new(**params) do
|
|
60
60
|
icon
|
|
@@ -74,7 +74,7 @@ describe Backpack::Components::Button, type: :component do
|
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
context "with an icon after the text" do
|
|
77
|
-
let(:icon) { render(
|
|
77
|
+
let(:icon) { render(Components::Icon.new("user")) }
|
|
78
78
|
let(:component) do
|
|
79
79
|
described_class.new(**params) do
|
|
80
80
|
text
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
|
-
describe
|
|
3
|
+
describe Components::Favicon, type: :component do
|
|
4
|
+
subject(:output) { render_fragment(component) }
|
|
5
|
+
|
|
4
6
|
let(:component) { described_class.new(**params) }
|
|
5
7
|
let(:params) { {} }
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
# rubocop:disable RSpec/ExampleLength
|
|
9
10
|
it "renders the links" do
|
|
10
11
|
expect(output).to eq_html <<~HTML
|
|
11
12
|
<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96">
|
|
@@ -15,6 +16,7 @@ describe Backpack::Components::Favicon, type: :component do
|
|
|
15
16
|
<link rel="manifest" href="/site.webmanifest">
|
|
16
17
|
HTML
|
|
17
18
|
end
|
|
19
|
+
# rubocop:enable RSpec/ExampleLength
|
|
18
20
|
|
|
19
21
|
context "with application name" do
|
|
20
22
|
let(:params) { { application_name: "My App" } }
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
|
-
describe
|
|
3
|
+
describe Components::Heading, type: :component do
|
|
4
|
+
subject(:output) { render_fragment(component) }
|
|
5
|
+
|
|
4
6
|
let(:component) { described_class.new(**params) { text } }
|
|
5
7
|
let(:params) { {} }
|
|
6
8
|
let(:text) { "Heading" }
|
|
7
9
|
|
|
8
|
-
subject(:output) { render_fragment(component) }
|
|
9
|
-
|
|
10
10
|
it "renders a level 1 heading by default" do
|
|
11
11
|
expect(output).to have_css("h1.Heading.Heading-1", text:)
|
|
12
12
|
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Components::IconButton, type: :component do
|
|
4
|
+
subject(:output) { render_fragment(component) }
|
|
5
|
+
|
|
6
|
+
let(:component) { described_class.new(**params) }
|
|
7
|
+
let(:params) { { icon: :user, label: "User" } }
|
|
8
|
+
|
|
9
|
+
it "renders a button element with the default styling" do
|
|
10
|
+
expect(output).to have_css(
|
|
11
|
+
"button.IconButton.IconButton-variant-solid.IconButton-size-2"
|
|
12
|
+
)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "renders the icon" do
|
|
16
|
+
expect(output).to have_css("button.IconButton svg.Icon.IconButton-icon[data-icon-key='user']")
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context "with a href" do
|
|
20
|
+
let(:params) { { icon: :user, label: "User", href: "/path" } }
|
|
21
|
+
|
|
22
|
+
it "renders a link element using the same styling classes" do
|
|
23
|
+
expect(output).to have_css(
|
|
24
|
+
"a.IconButton.IconButton-variant-solid.IconButton-size-2[href='/path']"
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context "with variant options" do
|
|
30
|
+
let(:params) { { icon: :user, label: "User", variant: :outline, color: :red, size: 1 } }
|
|
31
|
+
|
|
32
|
+
it "updates the variant modifiers in the class list" do
|
|
33
|
+
expect(output).to have_css(
|
|
34
|
+
"button.IconButton.IconButton-variant-outline.IconButton-size-1"
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context "with HTML attributes" do
|
|
40
|
+
let(:params) do
|
|
41
|
+
{ icon: :user, label: "User", class: "custom", data: { test: "value" }, aria: { label: "Open menu" } }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "merges custom attributes with the generated ones" do
|
|
45
|
+
expect(output).to have_css(
|
|
46
|
+
"button.IconButton.IconButton-variant-solid.IconButton-size-2.custom[data-test='value'][aria-label='Open menu']"
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
context "with a color option" do
|
|
52
|
+
let(:params) { { icon: :user, label: "User", color: :red } }
|
|
53
|
+
|
|
54
|
+
it "sets the data-accent-color attribute" do
|
|
55
|
+
expect(output).to have_css("button.IconButton[data-accent-color='red']")
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|