anchor_view_components 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +61 -0
- data/app/assets/builds/anchor-view-components.css +1 -0
- data/app/assets/stylesheets/anchor-view-components.tailwind.css +8 -0
- data/app/assets/stylesheets/components/button.css +29 -0
- data/app/assets/stylesheets/components/toast.css +21 -0
- data/app/components/anchor/action_menu_component.html.erb +19 -0
- data/app/components/anchor/action_menu_component.rb +23 -0
- data/app/components/anchor/action_menu_controller.ts +21 -0
- data/app/components/anchor/anchor_view_components.ts +13 -0
- data/app/components/anchor/autocomplete_component.en.yml +3 -0
- data/app/components/anchor/autocomplete_component.html.erb +36 -0
- data/app/components/anchor/autocomplete_component.rb +42 -0
- data/app/components/anchor/autocomplete_controller.ts +37 -0
- data/app/components/anchor/badge_component.html.erb +8 -0
- data/app/components/anchor/badge_component.rb +27 -0
- data/app/components/anchor/banner_component.html.erb +9 -0
- data/app/components/anchor/banner_component.rb +28 -0
- data/app/components/anchor/breadcrumbs/item_component.html.erb +16 -0
- data/app/components/anchor/breadcrumbs/item_component.rb +15 -0
- data/app/components/anchor/breadcrumbs_component.html.erb +10 -0
- data/app/components/anchor/breadcrumbs_component.rb +17 -0
- data/app/components/anchor/button_component.html.erb +22 -0
- data/app/components/anchor/button_component.rb +76 -0
- data/app/components/anchor/component.rb +21 -0
- data/app/components/anchor/dialog_component.html.erb +42 -0
- data/app/components/anchor/dialog_component.rb +25 -0
- data/app/components/anchor/dialog_controller.ts +15 -0
- data/app/components/anchor/icon_component.html.erb +6 -0
- data/app/components/anchor/icon_component.rb +9 -0
- data/app/components/anchor/loading_indicator_component.html.erb +6 -0
- data/app/components/anchor/loading_indicator_component.rb +23 -0
- data/app/components/anchor/panel/body_component.html.erb +8 -0
- data/app/components/anchor/panel/body_component.rb +6 -0
- data/app/components/anchor/panel/footer_component.html.erb +9 -0
- data/app/components/anchor/panel/footer_component.rb +17 -0
- data/app/components/anchor/panel/header_component.html.erb +9 -0
- data/app/components/anchor/panel/header_component.rb +15 -0
- data/app/components/anchor/panel_component.html.erb +8 -0
- data/app/components/anchor/panel_component.rb +20 -0
- data/app/components/anchor/prose_component.html.erb +3 -0
- data/app/components/anchor/prose_component.rb +9 -0
- data/app/components/anchor/tab_bar/tab_component.html.erb +11 -0
- data/app/components/anchor/tab_bar/tab_component.rb +12 -0
- data/app/components/anchor/tab_bar_component.html.erb +10 -0
- data/app/components/anchor/tab_bar_component.rb +17 -0
- data/app/components/anchor/text_component.html.erb +8 -0
- data/app/components/anchor/text_component.rb +43 -0
- data/app/components/anchor/toast_component.html.erb +28 -0
- data/app/components/anchor/toast_component.rb +32 -0
- data/app/components/anchor/toast_controller.ts +21 -0
- data/app/helpers/anchor/fetch_or_fallback_helper.rb +20 -0
- data/app/helpers/anchor/view_helper.rb +35 -0
- data/lib/anchor/view_components/engine.rb +23 -0
- data/lib/anchor/view_components/version.rb +5 -0
- data/lib/anchor/view_components.rb +8 -0
- data/previews/anchor/action_menu_component_preview.rb +22 -0
- data/previews/anchor/badge_component_preview.rb +40 -0
- data/previews/anchor/banner_component_preview.rb +41 -0
- data/previews/anchor/banner_preview/with_banner.html.erb +11 -0
- data/previews/anchor/breadcrumbs_component_preview.rb +15 -0
- data/previews/anchor/button_component_preview.rb +81 -0
- data/previews/anchor/dialog_component_preview.rb +19 -0
- data/previews/anchor/dialog_preview/with_footer.html.erb +16 -0
- data/previews/anchor/icon_component_preview.rb +7 -0
- data/previews/anchor/loading_indicator_component_preview.rb +26 -0
- data/previews/anchor/panel_component_preview.rb +48 -0
- data/previews/anchor/tab_bar_component_preview.rb +15 -0
- data/previews/anchor/table_preview/default.html.erb +35 -0
- data/previews/anchor/text_component_preview.rb +76 -0
- data/previews/anchor/toast_component_preview.rb +34 -0
- metadata +156 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
module Anchor
|
2
|
+
class Component < ViewComponent::Base
|
3
|
+
include FetchOrFallbackHelper
|
4
|
+
include ViewHelper
|
5
|
+
|
6
|
+
def self.generate_id(base_name: name.demodulize.underscore.dasherize)
|
7
|
+
"#{base_name}-#{SecureRandom.uuid}"
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(classes: nil, data: {}, **kwargs)
|
11
|
+
@classes = classes
|
12
|
+
@data = data
|
13
|
+
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
attr_reader :classes
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<%= tag.div(
|
2
|
+
class: "contents",
|
3
|
+
data: { controller: "dialog" },
|
4
|
+
) do %>
|
5
|
+
<%= show_button if show_button? %>
|
6
|
+
|
7
|
+
<%= tag.dialog(
|
8
|
+
aria: { labelledby: title_id },
|
9
|
+
class: "w-[36rem] rounded-lg p-0 bg-white shadow-lg backdrop:bg-grey-100/50",
|
10
|
+
data: { dialog_target: "dialog" },
|
11
|
+
) do %>
|
12
|
+
<header class="p-6 flex gap-4 justify-between items-center">
|
13
|
+
<%= render Anchor::TextComponent.new(
|
14
|
+
variant: :heading_2xl,
|
15
|
+
tag: :h1,
|
16
|
+
id: title_id,
|
17
|
+
).with_content(@title) %>
|
18
|
+
|
19
|
+
<form class="contents" method="dialog">
|
20
|
+
<%= tag.button(
|
21
|
+
aria: { label: "Close" },
|
22
|
+
class: "text-grey-50 hover:text-grey-70",
|
23
|
+
data: { action: "dialog#close" },
|
24
|
+
) do %>
|
25
|
+
<%= render Anchor::IconComponent.new(icon: "cancel") %>
|
26
|
+
<% end %>
|
27
|
+
</form>
|
28
|
+
</header>
|
29
|
+
|
30
|
+
<div class="px-6 pb-6">
|
31
|
+
<%= render(Anchor::TextComponent.new(
|
32
|
+
variant: :body_base,
|
33
|
+
).with_content(body)) %>
|
34
|
+
</div>
|
35
|
+
|
36
|
+
<% if footer? %>
|
37
|
+
<footer class="sticky bottom-0 bg-white px-6 pb-6 flex gap-2 justify-end">
|
38
|
+
<%= footer %>
|
39
|
+
</footer>
|
40
|
+
<% end %>
|
41
|
+
<% end %>
|
42
|
+
<% end %>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Anchor
|
2
|
+
class DialogComponent < Component
|
3
|
+
renders_one :show_button, -> do
|
4
|
+
ButtonComponent.new(data: { action: "dialog#showModal" })
|
5
|
+
end
|
6
|
+
renders_one :body
|
7
|
+
renders_one :footer
|
8
|
+
|
9
|
+
def initialize(title:)
|
10
|
+
@title = title
|
11
|
+
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def render?
|
18
|
+
body?
|
19
|
+
end
|
20
|
+
|
21
|
+
def title_id
|
22
|
+
@title.parameterize
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
2
|
+
|
3
|
+
export default class extends Controller<HTMLDivElement> {
|
4
|
+
static targets = ["dialog"];
|
5
|
+
|
6
|
+
declare readonly dialogTarget: HTMLDialogElement;
|
7
|
+
|
8
|
+
showModal(): void {
|
9
|
+
this.dialogTarget.showModal();
|
10
|
+
}
|
11
|
+
|
12
|
+
close(): void {
|
13
|
+
this.dialogTarget.close();
|
14
|
+
}
|
15
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Anchor
|
2
|
+
class LoadingIndicatorComponent < Component
|
3
|
+
VARIANT_MAPPING = {
|
4
|
+
sm: "w-4 h-4 border-[1.5px]",
|
5
|
+
md: "w-6 h-6 border-2",
|
6
|
+
lg: "w-12 h-12 border-4",
|
7
|
+
}.freeze
|
8
|
+
VARIANT_DEFAULT = :md
|
9
|
+
VARIANT_OPTIONS = VARIANT_MAPPING.keys
|
10
|
+
|
11
|
+
def initialize(variant: VARIANT_DEFAULT, **kwargs)
|
12
|
+
@variant = VARIANT_MAPPING[
|
13
|
+
fetch_or_fallback(VARIANT_OPTIONS, variant, VARIANT_DEFAULT)
|
14
|
+
]
|
15
|
+
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
attr_reader :variant
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Anchor
|
2
|
+
module Panel
|
3
|
+
class FooterComponent < Component
|
4
|
+
renders_one :supporting_text
|
5
|
+
|
6
|
+
renders_one :primary_action, ->(form:, label:, **kwargs) do
|
7
|
+
ButtonComponent.new(
|
8
|
+
form:,
|
9
|
+
variant: :primary,
|
10
|
+
size: :small,
|
11
|
+
type: :submit,
|
12
|
+
**kwargs
|
13
|
+
).with_content(label)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Anchor
|
2
|
+
class PanelComponent < Component
|
3
|
+
renders_one :header, -> do
|
4
|
+
Panel::HeaderComponent.new(active: active?)
|
5
|
+
end
|
6
|
+
|
7
|
+
renders_one :body, Panel::BodyComponent
|
8
|
+
renders_one :footer, Panel::FooterComponent
|
9
|
+
|
10
|
+
def initialize(active: false)
|
11
|
+
@active = active
|
12
|
+
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def active?
|
17
|
+
@active == true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<%= link_to(
|
2
|
+
content,
|
3
|
+
@href,
|
4
|
+
aria: {
|
5
|
+
current: { page: @active }
|
6
|
+
},
|
7
|
+
class: class_names(
|
8
|
+
"inline-block px-5 py-4 text-sm font-semibold relative text-gray-600 hover:text-gray-900",
|
9
|
+
"text-gray-900 after:block after:bg-blue-500 after:h-1 after:absolute after:-bottom-1 after:inset-x-0" => @active,
|
10
|
+
)
|
11
|
+
) %>
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Anchor
|
2
|
+
class TextComponent < Component
|
3
|
+
TAG_DEFAULT = :div
|
4
|
+
|
5
|
+
VARIANT_DEFAULT = :body_base
|
6
|
+
VARIANT_MAPPING = {
|
7
|
+
body_lg: "text-lg",
|
8
|
+
body_base: "text-base",
|
9
|
+
body_sm: "text-sm",
|
10
|
+
heading_base: "text-base font-semibold",
|
11
|
+
heading_lg: "text-lg font-semibold",
|
12
|
+
heading_xl: "text-xl font-semibold",
|
13
|
+
heading_2xl: "text-2xl font-semibold",
|
14
|
+
heading_3xl: "text-3xl font-semibold",
|
15
|
+
heading_4xl: "text-4xl font-semibold",
|
16
|
+
subheading_sm: "text-sm font-bold leading-4 uppercase",
|
17
|
+
subheading_xs: "text-xs font-bold leading-4 uppercase",
|
18
|
+
}.freeze
|
19
|
+
VARIANT_OPTIONS = VARIANT_MAPPING.keys
|
20
|
+
|
21
|
+
def initialize(
|
22
|
+
variant: VARIANT_DEFAULT,
|
23
|
+
tag: TAG_DEFAULT,
|
24
|
+
id: nil,
|
25
|
+
**kwargs
|
26
|
+
)
|
27
|
+
@variant = VARIANT_MAPPING[
|
28
|
+
fetch_or_fallback(VARIANT_OPTIONS, variant, VARIANT_DEFAULT)
|
29
|
+
]
|
30
|
+
|
31
|
+
@tag = tag
|
32
|
+
@id = id
|
33
|
+
|
34
|
+
super
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def render?
|
40
|
+
content.present?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<%= tag.div(
|
2
|
+
class: class_names(
|
3
|
+
"toast",
|
4
|
+
@variant,
|
5
|
+
),
|
6
|
+
data: { controller: "toast" },
|
7
|
+
id: @id,
|
8
|
+
popover: "manual",
|
9
|
+
) do %>
|
10
|
+
<% if icon? %>
|
11
|
+
<%= icon %>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<%= render Anchor::TextComponent.new(
|
15
|
+
variant: :heading_base,
|
16
|
+
tag: :span,
|
17
|
+
).with_content(content) %>
|
18
|
+
|
19
|
+
<%= tag.button(
|
20
|
+
aria: { label: "Close" },
|
21
|
+
class: "!ml-10",
|
22
|
+
type: "button",
|
23
|
+
popovertarget: @id,
|
24
|
+
popovertargetaction: "hide",
|
25
|
+
) do %>
|
26
|
+
<%= render Anchor::IconComponent.new(icon: "cancel") %>
|
27
|
+
<% end %>
|
28
|
+
<% end %>
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Anchor
|
2
|
+
class ToastComponent < Component
|
3
|
+
renders_one :icon, ->(icon:) do
|
4
|
+
Anchor::IconComponent.new(icon:, classes: "opacity-70")
|
5
|
+
end
|
6
|
+
|
7
|
+
VARIANT_DEFAULT = :notice
|
8
|
+
VARIANT_MAPPINGS = {
|
9
|
+
VARIANT_DEFAULT => "bg-gray-900 text-white",
|
10
|
+
:success => "bg-green-700 text-white",
|
11
|
+
:error => "bg-red-700 text-white",
|
12
|
+
# TODO: Figma doesn’t provide a yellow ‘alert’ style
|
13
|
+
:alert => "bg-yellow-600 text-white",
|
14
|
+
}.freeze
|
15
|
+
VARIANT_OPTIONS = VARIANT_MAPPINGS.keys
|
16
|
+
|
17
|
+
def initialize(variant: VARIANT_DEFAULT)
|
18
|
+
@variant = VARIANT_MAPPINGS[
|
19
|
+
fetch_or_fallback(VARIANT_OPTIONS, variant, VARIANT_DEFAULT)
|
20
|
+
]
|
21
|
+
@id = self.class.generate_id
|
22
|
+
|
23
|
+
super
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def render?
|
29
|
+
content.present?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
2
|
+
|
3
|
+
export default class extends Controller<HTMLDivElement> {
|
4
|
+
static values = {
|
5
|
+
hideDelay: { type: Number, default: 3000 },
|
6
|
+
showDelay: { type: Number, default: 200 },
|
7
|
+
};
|
8
|
+
|
9
|
+
declare hideDelayValue: number
|
10
|
+
declare showDelayValue: number
|
11
|
+
|
12
|
+
initialize = (): void => {
|
13
|
+
setTimeout(() => {
|
14
|
+
this.element.showPopover();
|
15
|
+
}, this.showDelayValue);
|
16
|
+
|
17
|
+
setTimeout(() => {
|
18
|
+
this.element.hidePopover();
|
19
|
+
}, this.hideDelayValue);
|
20
|
+
}
|
21
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Anchor
|
2
|
+
module FetchOrFallbackHelper
|
3
|
+
def fetch_or_fallback(allowed_values, given_value, fallback = nil)
|
4
|
+
if allowed_values.include?(given_value)
|
5
|
+
given_value
|
6
|
+
else
|
7
|
+
unless Rails.env.production?
|
8
|
+
raise ArgumentError, <<~MSG
|
9
|
+
fetch_or_fallback was called with an invalid value.
|
10
|
+
Expected one of: #{allowed_values.inspect}
|
11
|
+
Got: #{given_value.inspect}
|
12
|
+
This will not raise in production, but will instead fallback to: #{fallback.inspect}
|
13
|
+
MSG
|
14
|
+
end
|
15
|
+
|
16
|
+
fallback
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Anchor
|
2
|
+
module ViewHelper
|
3
|
+
Anchor::TextComponent::VARIANT_OPTIONS.each do |variant_option|
|
4
|
+
define_method "text_#{variant_option}" do
|
5
|
+
|content = nil, *args, **kwargs, &block|
|
6
|
+
|
7
|
+
if block.present?
|
8
|
+
render(
|
9
|
+
Anchor::TextComponent.new(
|
10
|
+
*args,
|
11
|
+
variant: variant_option,
|
12
|
+
**kwargs
|
13
|
+
),
|
14
|
+
&block
|
15
|
+
)
|
16
|
+
else
|
17
|
+
render Anchor::TextComponent.new(
|
18
|
+
*args,
|
19
|
+
variant: variant_option,
|
20
|
+
**kwargs
|
21
|
+
).with_content(content)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def text_prose(content = nil, *args, **kwargs, &block)
|
27
|
+
if block.present?
|
28
|
+
render(Anchor::ProseComponent.new(*args, **kwargs), &block)
|
29
|
+
else
|
30
|
+
render Anchor::ProseComponent.new(*args, **kwargs)
|
31
|
+
.with_content(content)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "rails/engine"
|
2
|
+
require "inline_svg"
|
3
|
+
|
4
|
+
module Anchor
|
5
|
+
module ViewComponents
|
6
|
+
class Engine < ::Rails::Engine
|
7
|
+
isolate_namespace Anchor::ViewComponents
|
8
|
+
|
9
|
+
config.autoload_paths = %W[
|
10
|
+
#{root}/app/components
|
11
|
+
#{root}/app/helpers
|
12
|
+
]
|
13
|
+
|
14
|
+
initializer "anchor_view_components.assets" do |app|
|
15
|
+
if app.config.respond_to?(:assets)
|
16
|
+
app.config.assets.precompile += %w[
|
17
|
+
anchor-view-components.css
|
18
|
+
]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Anchor
|
2
|
+
class ActionMenuComponentPreview < ViewComponent::Preview
|
3
|
+
include ActionView::Helpers::UrlHelper
|
4
|
+
|
5
|
+
def playground
|
6
|
+
render Anchor::ActionMenuComponent.new do |c|
|
7
|
+
c.with_show_button do |button|
|
8
|
+
button.with_ending_icon(icon: "nav-arrow-down")
|
9
|
+
"Actions"
|
10
|
+
end
|
11
|
+
|
12
|
+
c.with_item do
|
13
|
+
link_to("Edit", "#")
|
14
|
+
end
|
15
|
+
|
16
|
+
c.with_item do
|
17
|
+
link_to("Delete", "#")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Anchor
|
2
|
+
class BadgeComponentPreview < ViewComponent::Preview
|
3
|
+
# @param content text "Labels should be one to two words"
|
4
|
+
# @param variant select {{ Anchor::BadgeComponent::VARIANT_OPTIONS }}
|
5
|
+
def playground(
|
6
|
+
content: "Label",
|
7
|
+
variant: Anchor::BadgeComponent::VARIANT_DEFAULT
|
8
|
+
)
|
9
|
+
render(Anchor::BadgeComponent.new(variant:).with_content(content))
|
10
|
+
end
|
11
|
+
|
12
|
+
# @!group Variants
|
13
|
+
|
14
|
+
def neutral
|
15
|
+
render(Anchor::BadgeComponent.new.with_content("Label"))
|
16
|
+
end
|
17
|
+
|
18
|
+
def informational
|
19
|
+
render(Anchor::BadgeComponent.new(variant: :informational)
|
20
|
+
.with_content("Label"))
|
21
|
+
end
|
22
|
+
|
23
|
+
def success
|
24
|
+
render(Anchor::BadgeComponent.new(variant: :success)
|
25
|
+
.with_content("Label"))
|
26
|
+
end
|
27
|
+
|
28
|
+
def critical
|
29
|
+
render(Anchor::BadgeComponent.new(variant: :critical)
|
30
|
+
.with_content("Label"))
|
31
|
+
end
|
32
|
+
|
33
|
+
def warning
|
34
|
+
render(Anchor::BadgeComponent.new(variant: :warning)
|
35
|
+
.with_content("Label"))
|
36
|
+
end
|
37
|
+
|
38
|
+
# @!endgroup
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Anchor
|
2
|
+
class BannerComponentPreview < ViewComponent::Preview
|
3
|
+
# @param content text
|
4
|
+
# @param variant select {{ Anchor::BannerComponent::VARIANT_OPTIONS }}
|
5
|
+
def playground(
|
6
|
+
content: "Content",
|
7
|
+
variant: Anchor::BannerComponent::VARIANT_DEFAULT
|
8
|
+
)
|
9
|
+
render(Anchor::BannerComponent.new(variant:)
|
10
|
+
.with_content(content))
|
11
|
+
end
|
12
|
+
|
13
|
+
# @!group Variants
|
14
|
+
|
15
|
+
def neutral
|
16
|
+
render(Anchor::BannerComponent.new.with_content("Content"))
|
17
|
+
end
|
18
|
+
|
19
|
+
def informational
|
20
|
+
render(Anchor::BannerComponent.new(variant: :informational)
|
21
|
+
.with_content("Content"))
|
22
|
+
end
|
23
|
+
|
24
|
+
def success
|
25
|
+
render(Anchor::BannerComponent.new(variant: :success)
|
26
|
+
.with_content("Content"))
|
27
|
+
end
|
28
|
+
|
29
|
+
def critical
|
30
|
+
render(Anchor::BannerComponent.new(variant: :critical)
|
31
|
+
.with_content("Content"))
|
32
|
+
end
|
33
|
+
|
34
|
+
def warning
|
35
|
+
render(Anchor::BannerComponent.new(variant: :warning)
|
36
|
+
.with_content("Content"))
|
37
|
+
end
|
38
|
+
|
39
|
+
# @!endgroup
|
40
|
+
end
|
41
|
+
end
|