anchor_view_components 0.20.1 → 0.22.0
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/CHANGELOG.md +29 -0
- data/app/assets/builds/anchor-view-components.css +1 -1
- data/app/assets/images/icons/calendar.svg +7 -0
- data/app/assets/images/icons/check.svg +4 -0
- data/app/assets/images/icons/paste-clipboard.svg +5 -0
- data/app/assets/images/icons/search.svg +5 -0
- data/app/assets/stylesheets/components/button.css +1 -1
- data/app/components/anchor/action_menu_component.html.erb +8 -10
- data/app/components/anchor/action_menu_component.rb +15 -6
- data/app/components/anchor/anchor_view_components.ts +2 -0
- data/app/components/anchor/autocomplete_component.html.erb +6 -7
- data/app/components/anchor/autocomplete_component.rb +29 -8
- data/app/components/anchor/badge_component.html.erb +3 -6
- data/app/components/anchor/badge_component.rb +0 -10
- data/app/components/anchor/banner_component.html.erb +1 -7
- data/app/components/anchor/banner_component.rb +0 -10
- data/app/components/anchor/button_component.html.erb +10 -17
- data/app/components/anchor/button_component.rb +14 -21
- data/app/components/anchor/component.rb +22 -5
- data/app/components/anchor/copy_to_clipboard_component.en.yml +2 -0
- data/app/components/anchor/copy_to_clipboard_component.html.erb +21 -0
- data/app/components/anchor/copy_to_clipboard_component.rb +15 -0
- data/app/components/anchor/copy_to_clipboard_controller.ts +34 -0
- data/app/components/anchor/dialog_component.html.erb +3 -4
- data/app/components/anchor/icon_component.html.erb +1 -3
- data/app/components/anchor/icon_component.rb +1 -1
- data/app/components/anchor/loading_indicator_component.html.erb +3 -4
- data/app/components/anchor/logo_component.html.erb +1 -4
- data/app/components/anchor/logo_component.rb +1 -1
- data/app/components/anchor/panel/body_component.html.erb +3 -5
- data/app/components/anchor/panel_component.html.erb +3 -1
- data/app/components/anchor/popover_component.html.erb +3 -7
- data/app/components/anchor/popover_controller.ts +21 -15
- data/app/components/anchor/prose_component.html.erb +5 -4
- data/app/components/anchor/radio_button_collection_component.html.erb +1 -0
- data/app/components/anchor/radio_button_collection_component.rb +35 -0
- data/app/components/anchor/radio_button_component.html.erb +11 -0
- data/app/components/anchor/radio_button_component.rb +105 -0
- data/app/components/anchor/side_nav_component.html.erb +8 -9
- data/app/components/anchor/side_nav_component.rb +4 -1
- data/app/components/anchor/tab_bar/tab_component.html.erb +8 -6
- data/app/components/anchor/tab_bar/tab_component.rb +2 -2
- data/app/components/anchor/tab_bar_component.html.erb +3 -4
- data/app/components/anchor/tab_bar_component.rb +3 -2
- data/app/components/anchor/table_component.rb +1 -1
- data/app/components/anchor/text_component.html.erb +1 -6
- data/app/components/anchor/text_component.rb +5 -14
- data/app/components/anchor/text_field_component.html.erb +19 -1
- data/app/components/anchor/text_field_component.rb +35 -16
- data/app/components/anchor/toast_component.html.erb +5 -8
- data/app/components/anchor/toast_component.rb +8 -12
- data/app/components/anchor/toast_controller.ts +5 -1
- data/app/helpers/anchor/fetch_or_fallback_helper.rb +26 -0
- data/app/helpers/anchor/form_builder.rb +52 -29
- data/app/helpers/anchor/tailwind_constants.rb +0 -37
- data/app/helpers/anchor/view_helper.rb +11 -0
- data/lib/anchor/view_components/engine.rb +0 -1
- data/lib/anchor/view_components/version.rb +1 -1
- data/previews/anchor/copy_to_clipboard_component_preview.rb +7 -0
- data/previews/anchor/forms_preview.rb +45 -0
- data/previews/forms/default.html.erb +6 -4
- data/previews/forms/radio_button_collection.html.erb +51 -0
- data/previews/forms/with_icons.html.erb +10 -0
- metadata +17 -2
@@ -0,0 +1,34 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
2
|
+
|
3
|
+
export default class extends Controller<HTMLDivElement> {
|
4
|
+
static targets = [ "initialIcon", "successIcon"];
|
5
|
+
static classes = [ "hidden" ]
|
6
|
+
|
7
|
+
declare readonly initialIconTarget: SVGElement;
|
8
|
+
declare readonly successIconTarget: SVGElement;
|
9
|
+
declare readonly notificationDelayValue: number;
|
10
|
+
declare readonly hiddenClass: string;
|
11
|
+
declare readonly textToCopyValue: string;
|
12
|
+
declare readonly hasTextToCopyValue: boolean;
|
13
|
+
|
14
|
+
static values = {
|
15
|
+
notificationDelay: { type: Number, default: 1500 },
|
16
|
+
textToCopy: String,
|
17
|
+
};
|
18
|
+
|
19
|
+
copy(): void {
|
20
|
+
if (this.hasTextToCopyValue) {
|
21
|
+
navigator.clipboard.writeText(this.textToCopyValue);
|
22
|
+
}
|
23
|
+
this.toggleIcons();
|
24
|
+
|
25
|
+
setTimeout(() => {
|
26
|
+
this.toggleIcons();
|
27
|
+
}, this.notificationDelayValue);
|
28
|
+
}
|
29
|
+
|
30
|
+
toggleIcons(): void {
|
31
|
+
this.initialIconTarget.classList.toggle(this.hiddenClass);
|
32
|
+
this.successIconTarget.classList.toggle(this.hiddenClass);
|
33
|
+
}
|
34
|
+
}
|
@@ -1,14 +1,13 @@
|
|
1
1
|
<%= show_button if show_button? %>
|
2
2
|
|
3
|
-
<%= tag.dialog(
|
3
|
+
<%= tag.dialog(**merge_options(wrapper_options, {
|
4
4
|
aria: { labelledby: title_id },
|
5
|
-
class:
|
5
|
+
class: "w-[36rem] rounded-lg p-0 bg-white shadow-lg backdrop:bg-grey-100/50",
|
6
6
|
data: {
|
7
7
|
controller: "dialog",
|
8
8
|
testid: title_id,
|
9
9
|
},
|
10
|
-
|
11
|
-
) do %>
|
10
|
+
})) do %>
|
12
11
|
<header class="p-6 flex gap-4 justify-between items-center">
|
13
12
|
<%= render Anchor::TextComponent.new(
|
14
13
|
variant: :heading_2xl,
|
@@ -1,7 +1,6 @@
|
|
1
1
|
<%= tag.span t(".label"), class: "sr-only" %>
|
2
2
|
|
3
|
-
<%= anchor_icon(
|
3
|
+
<%= anchor_icon(**merge_options(wrapper_options,
|
4
|
+
class: class_names(wrapper_options[:class], "text-grey-100 animate-spin"),
|
4
5
|
icon: "loading-indicator",
|
5
|
-
|
6
|
-
data: data,
|
7
|
-
) %>
|
6
|
+
)) %>
|
@@ -4,15 +4,11 @@
|
|
4
4
|
) do %>
|
5
5
|
<%= trigger if trigger? %>
|
6
6
|
|
7
|
-
<%= tag.div(
|
8
|
-
class:
|
9
|
-
"absolute -left-full -top-full m-0 bg-white rounded border border-subdued popover-open:block",
|
10
|
-
classes
|
11
|
-
),
|
7
|
+
<%= tag.div(**merge_options(wrapper_options,
|
8
|
+
class: "absolute -left-full -top-full m-0 bg-white rounded border border-subdued popover-open:block",
|
12
9
|
data: { action: "toggle->popover#positionPopover" },
|
13
|
-
id:,
|
14
10
|
popover: "auto",
|
15
|
-
) do %>
|
11
|
+
)) do %>
|
16
12
|
<%= content %>
|
17
13
|
<% end %>
|
18
14
|
<% end %>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { Controller } from "@hotwired/stimulus";
|
2
|
-
import { computePosition, autoPlacement, offset } from "@floating-ui/dom";
|
2
|
+
import { computePosition, autoPlacement, offset, autoUpdate } from "@floating-ui/dom";
|
3
3
|
|
4
4
|
export default class extends Controller<HTMLDivElement> {
|
5
5
|
static targets = ["button"];
|
@@ -7,20 +7,26 @@ export default class extends Controller<HTMLDivElement> {
|
|
7
7
|
declare readonly buttonTarget: HTMLButtonElement;
|
8
8
|
|
9
9
|
positionPopover = (event: { target: HTMLDivElement }): void => {
|
10
|
+
const trigger = this.buttonTarget
|
10
11
|
const popover = event.target;
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
12
|
+
|
13
|
+
const updatePosition = () => {
|
14
|
+
computePosition(trigger, popover, {
|
15
|
+
placement: "bottom-start",
|
16
|
+
middleware: [
|
17
|
+
autoPlacement({
|
18
|
+
allowedPlacements: ["bottom-start", "bottom-end", "top-start", "top-end"],
|
19
|
+
}),
|
20
|
+
offset(4)
|
21
|
+
],
|
22
|
+
}).then(({ x, y }) => {
|
23
|
+
Object.assign(popover.style, {
|
24
|
+
left: `${x}px`,
|
25
|
+
top: `${y}px`,
|
26
|
+
});
|
27
|
+
})
|
28
|
+
};
|
29
|
+
|
30
|
+
autoUpdate(trigger, popover, updatePosition);
|
25
31
|
};
|
26
32
|
}
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= tag.div content, class: "flex flex-col space-y-2 text-base" %>
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Anchor
|
2
|
+
class RadioButtonCollectionComponent < Component
|
3
|
+
attr_reader :attribute, :descriptions, :form_builder
|
4
|
+
|
5
|
+
def initialize(
|
6
|
+
form_builder:,
|
7
|
+
attribute:,
|
8
|
+
collection:,
|
9
|
+
value_method:,
|
10
|
+
text_method:,
|
11
|
+
**options
|
12
|
+
)
|
13
|
+
@form_builder = form_builder
|
14
|
+
@attribute = attribute
|
15
|
+
@collection = collection
|
16
|
+
@value_method = value_method
|
17
|
+
@text_method = text_method
|
18
|
+
@descriptions = options.delete(:descriptions)
|
19
|
+
|
20
|
+
super
|
21
|
+
|
22
|
+
def options
|
23
|
+
{ class: RadioButtonComponent::INPUT_CLASSES }
|
24
|
+
end
|
25
|
+
|
26
|
+
def radio(radio:)
|
27
|
+
RadioButtonComponent.new(
|
28
|
+
radio:,
|
29
|
+
attribute:,
|
30
|
+
form_builder:
|
31
|
+
)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<div class="flex gap-1 items-start">
|
2
|
+
<%= radio.radio_button(radio_options) %>
|
3
|
+
<% if description.present? %>
|
4
|
+
<div class="flex flex-col gap-1">
|
5
|
+
<%= radio.label %>
|
6
|
+
<%= description_span %>
|
7
|
+
</div>
|
8
|
+
<% else %>
|
9
|
+
<%= tag.div radio.label, class: "self-center" %>
|
10
|
+
<% end %>
|
11
|
+
</div>
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Anchor
|
2
|
+
class RadioButtonComponent < Anchor::Component
|
3
|
+
INPUT_CLASSES = %w(
|
4
|
+
appearance-none
|
5
|
+
w-[18px]
|
6
|
+
m-[3px]
|
7
|
+
aspect-square
|
8
|
+
rounded-full
|
9
|
+
border-2
|
10
|
+
border-grey-60
|
11
|
+
hover:border-grey-80
|
12
|
+
checked:bg-gradient-radial
|
13
|
+
checked:from-blue-50
|
14
|
+
checked:from-[50%]
|
15
|
+
checked:to-transparent
|
16
|
+
checked:to-[54%]
|
17
|
+
checked:border-blue-50
|
18
|
+
checked:hover:from-blue-60
|
19
|
+
checked:hover:from-[50%]
|
20
|
+
checked:hover:to-transparent
|
21
|
+
checked:hover:to-[54%]
|
22
|
+
checked:hover:border-blue-60
|
23
|
+
disabled:border-grey-40
|
24
|
+
disabled:checked:border-grey-40
|
25
|
+
disabled:checked:from-grey-40
|
26
|
+
disabled:checked:from-[50%]
|
27
|
+
disabled:checked:to-transparent
|
28
|
+
disabled:checked:to-[54%]
|
29
|
+
disabled:checked:border-grey-40
|
30
|
+
aria-readonly:border-grey-40
|
31
|
+
aria-readonly:checked:border-grey-40
|
32
|
+
aria-readonly:checked:from-grey-40
|
33
|
+
aria-readonly:checked:from-[50%]
|
34
|
+
aria-readonly:checked:to-transparent
|
35
|
+
aria-readonly:checked:to-[54%]
|
36
|
+
aria-readonly:checked:border-grey-40
|
37
|
+
).freeze
|
38
|
+
|
39
|
+
DESCRIPTION_CLASSES = %w(
|
40
|
+
text-secondary
|
41
|
+
text-sm
|
42
|
+
).freeze
|
43
|
+
|
44
|
+
def initialize(radio:, attribute:, form_builder:)
|
45
|
+
@radio = radio
|
46
|
+
@attribute = attribute
|
47
|
+
@form_builder = form_builder
|
48
|
+
|
49
|
+
super
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
attr_reader :radio, :attribute, :form_builder
|
55
|
+
|
56
|
+
delegate :value, to: :radio
|
57
|
+
|
58
|
+
def aria_description
|
59
|
+
{ describedby: description_id }
|
60
|
+
end
|
61
|
+
|
62
|
+
def description
|
63
|
+
if radio.object.is_a?(Hash)
|
64
|
+
radio.object[:description]
|
65
|
+
elsif radio.object.respond_to?(:description)
|
66
|
+
radio.object.description
|
67
|
+
elsif I18n.exists?(description_translation_scope)
|
68
|
+
human_attribute_description
|
69
|
+
else
|
70
|
+
false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def description_id
|
75
|
+
"#{attribute}-#{value}-description"
|
76
|
+
end
|
77
|
+
|
78
|
+
def description_span
|
79
|
+
tag.span description, id: description_id, class: DESCRIPTION_CLASSES
|
80
|
+
end
|
81
|
+
|
82
|
+
def description_text
|
83
|
+
human_attribute_description
|
84
|
+
end
|
85
|
+
|
86
|
+
def description_translation_scope
|
87
|
+
["activerecord.values", i18n_model_key, description_id.gsub("-", ".")]
|
88
|
+
end
|
89
|
+
|
90
|
+
def human_attribute_description
|
91
|
+
I18n.t description_translation_scope.join(".")
|
92
|
+
end
|
93
|
+
|
94
|
+
def i18n_model_key
|
95
|
+
form_builder.object.class.model_name.i18n_key
|
96
|
+
end
|
97
|
+
|
98
|
+
def radio_options
|
99
|
+
{
|
100
|
+
aria: description.present? && aria_description,
|
101
|
+
data: { testid: "radio-#{attribute}-#{radio.value}".dasherize },
|
102
|
+
}
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -1,20 +1,19 @@
|
|
1
|
-
<%= tag.div(
|
2
|
-
|
1
|
+
<%= tag.div(**merge_options(wrapper_options, {
|
2
|
+
class: "flex min-h-[100dvh] max-h-[100dvh] overflow-hidden",
|
3
3
|
data: {
|
4
4
|
controller: "toggle",
|
5
5
|
toggle_toggle_class: "side-nav-open",
|
6
6
|
toggle_initial_label_value: t(".hide_nav"),
|
7
7
|
toggle_intermediate_label_value: t(".show_nav"),
|
8
|
-
}
|
9
|
-
) do %>
|
10
|
-
<%= tag.header(
|
8
|
+
}
|
9
|
+
})) do %>
|
10
|
+
<%= tag.header(**merge_options(sidebar_options, {
|
11
11
|
class: class_names(
|
12
12
|
"flex flex-shrink-0 w-[15rem] relative",
|
13
13
|
"[.side-nav-open_&]:w-[3.5rem] transition-[width] duration-500",
|
14
|
-
classes
|
15
14
|
),
|
16
|
-
data: { testid: "side-nav" }
|
17
|
-
) do %>
|
15
|
+
data: { testid: "side-nav" },
|
16
|
+
})) do %>
|
18
17
|
<%= tag.div(
|
19
18
|
class: class_names(
|
20
19
|
"bg-teal text-white w-[15rem] flex flex-col divide-y divide-solid divide-white/10 duration-500",
|
@@ -58,7 +57,7 @@
|
|
58
57
|
),
|
59
58
|
data: { toggle_target: "inertify" },
|
60
59
|
) do %>
|
61
|
-
|
60
|
+
<%= render Anchor::ActionMenuComponent.new(classes: "py-4", menu_options: { class: "ml-4 w-[198px]" }) do |c| %>
|
62
61
|
<% c.with_show_button(
|
63
62
|
classes: "text-lg text-white w-full hover:text-white hover:bg-white/[.05] px-6 justify-between rounded-none",
|
64
63
|
full_width: true,
|
@@ -8,18 +8,21 @@ module Anchor
|
|
8
8
|
apps_button_text:,
|
9
9
|
nav_items:,
|
10
10
|
employee:,
|
11
|
+
sidebar_options: {},
|
11
12
|
**kwargs
|
12
13
|
)
|
13
14
|
@apps = apps
|
14
15
|
@apps_button_text = apps_button_text
|
15
16
|
@nav_items = nav_items
|
16
17
|
@employee = employee
|
18
|
+
@sidebar_options = sidebar_options
|
17
19
|
|
18
20
|
super
|
19
21
|
end
|
20
22
|
|
21
23
|
private
|
22
24
|
|
23
|
-
attr_reader :apps, :apps_button_text, :employee, :nav_items
|
25
|
+
attr_reader :apps, :apps_button_text, :employee, :nav_items,
|
26
|
+
:sidebar_options
|
24
27
|
end
|
25
28
|
end
|
@@ -1,11 +1,13 @@
|
|
1
1
|
<%= link_to(
|
2
2
|
content,
|
3
3
|
href,
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
**merge_options(wrapper_options,
|
5
|
+
aria: {
|
6
|
+
current: { page: active }
|
7
|
+
},
|
8
|
+
class: class_names(
|
9
|
+
"inline-block px-5 py-4 text-sm font-semibold relative text-gray-600 hover:text-gray-900",
|
10
|
+
"text-gray-900 after:block after:bg-blue-500 after:h-1 after:absolute after:-bottom-1 after:inset-x-0" => active,
|
11
|
+
)
|
10
12
|
)
|
11
13
|
) %>
|
@@ -1,7 +1,6 @@
|
|
1
|
-
<%= tag.nav(
|
2
|
-
|
3
|
-
|
4
|
-
) do %>
|
1
|
+
<%= tag.nav(**merge_options(wrapper_options,
|
2
|
+
class: "shadow-[inset_0_-1px] shadow-gray-400 pb-1",
|
3
|
+
)) do %>
|
5
4
|
<ul class="flex">
|
6
5
|
<% tabs.each do |tab| %>
|
7
6
|
<%= tag.li tab %>
|
@@ -3,7 +3,7 @@ module Anchor
|
|
3
3
|
TAG_DEFAULT = :p
|
4
4
|
|
5
5
|
VARIANT_DEFAULT = :body_base
|
6
|
-
|
6
|
+
VARIANT_MAPPINGS = {
|
7
7
|
body_lg: "text-lg",
|
8
8
|
body_base: "text-base",
|
9
9
|
body_sm: "text-sm",
|
@@ -16,25 +16,16 @@ module Anchor
|
|
16
16
|
subheading_sm: "text-sm font-bold leading-4 uppercase",
|
17
17
|
subheading_xs: "text-xs font-bold leading-4 uppercase",
|
18
18
|
}.freeze
|
19
|
-
VARIANT_OPTIONS =
|
19
|
+
VARIANT_OPTIONS = VARIANT_MAPPINGS.keys
|
20
20
|
|
21
|
-
def initialize(
|
22
|
-
variant: VARIANT_DEFAULT,
|
23
|
-
tag: TAG_DEFAULT,
|
24
|
-
**kwargs
|
25
|
-
)
|
26
|
-
@variant = VARIANT_MAPPING[
|
27
|
-
fetch_or_fallback(VARIANT_OPTIONS, variant, VARIANT_DEFAULT)
|
28
|
-
]
|
21
|
+
def initialize(tag: TAG_DEFAULT, **kwargs)
|
29
22
|
@tag = tag
|
30
|
-
|
31
|
-
|
32
|
-
super
|
23
|
+
super(**kwargs)
|
33
24
|
end
|
34
25
|
|
35
26
|
private
|
36
27
|
|
37
|
-
attr_reader :
|
28
|
+
attr_reader :tag
|
38
29
|
|
39
30
|
def render?
|
40
31
|
content.present?
|
@@ -1 +1,19 @@
|
|
1
|
-
|
1
|
+
<% if starting_icon? || ending_icon? %>
|
2
|
+
<%= tag.div class: "relative" do %>
|
3
|
+
<%= content %>
|
4
|
+
<% if starting_icon? %>
|
5
|
+
<%= anchor_icon(
|
6
|
+
icon: starting_icon,
|
7
|
+
classes: class_names(ICON_CLASSES, "left-4")
|
8
|
+
) %>
|
9
|
+
<% end %>
|
10
|
+
<% if ending_icon? %>
|
11
|
+
<%= anchor_icon(
|
12
|
+
icon: ending_icon,
|
13
|
+
classes: class_names(ICON_CLASSES, "right-4")
|
14
|
+
) %>
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
17
|
+
<% else %>
|
18
|
+
<%= content %>
|
19
|
+
<% end %>
|
@@ -1,30 +1,49 @@
|
|
1
1
|
module Anchor
|
2
2
|
class TextFieldComponent < Component
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
text-base
|
12
|
-
w-full
|
13
|
-
[&[readonly]]:bg-grey-10
|
14
|
-
[&[readonly]]:border-grey-40
|
15
|
-
[&[readonly]]:shadow-none
|
3
|
+
ICON_CLASSES = %w(
|
4
|
+
absolute
|
5
|
+
h-5
|
6
|
+
w-5
|
7
|
+
top-1/2
|
8
|
+
-translate-y-1/2
|
9
|
+
text-secondary
|
10
|
+
pointer-events-none
|
16
11
|
).freeze
|
17
12
|
|
18
|
-
def initialize(
|
13
|
+
def initialize(
|
14
|
+
form_builder:,
|
15
|
+
attribute:,
|
16
|
+
starting_icon: nil,
|
17
|
+
ending_icon: nil
|
18
|
+
)
|
19
19
|
@form_builder = form_builder
|
20
20
|
@attribute = attribute
|
21
|
-
@
|
21
|
+
@starting_icon = starting_icon
|
22
|
+
@ending_icon = ending_icon
|
22
23
|
|
23
24
|
super
|
24
25
|
end
|
25
26
|
|
27
|
+
attr_reader :starting_icon, :ending_icon
|
28
|
+
|
26
29
|
def options
|
27
|
-
{
|
30
|
+
{
|
31
|
+
class: class_names(
|
32
|
+
TailwindConstants::INPUT,
|
33
|
+
"pl-11" => starting_icon?,
|
34
|
+
"pr-11" => ending_icon?
|
35
|
+
),
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def starting_icon?
|
42
|
+
starting_icon.present?
|
43
|
+
end
|
44
|
+
|
45
|
+
def ending_icon?
|
46
|
+
ending_icon.present?
|
28
47
|
end
|
29
48
|
end
|
30
49
|
end
|
@@ -1,12 +1,9 @@
|
|
1
1
|
<%= tag.div(
|
2
|
-
|
3
|
-
"toast",
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
id: id,
|
8
|
-
popover: "manual",
|
9
|
-
role:,
|
2
|
+
**merge_options(wrapper_options, {
|
3
|
+
class: "toast",
|
4
|
+
data: { controller: "toast", testid: test_id },
|
5
|
+
popover: "manual",
|
6
|
+
})
|
10
7
|
) do %>
|
11
8
|
<% if icon? %>
|
12
9
|
<%= icon %>
|