ariadne_view_components 0.0.93.2 → 0.0.94
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 +7 -0
- data/README.md +13 -4
- data/app/assets/javascripts/ariadne_view_components.js +14 -14
- data/app/assets/javascripts/ariadne_view_components.js.br +0 -0
- data/app/assets/javascripts/ariadne_view_components.js.gz +0 -0
- data/app/assets/javascripts/ariadne_view_components.js.map +1 -1
- data/app/assets/stylesheets/ariadne_view_components.css +1 -1
- data/app/assets/stylesheets/ariadne_view_components.css.br +0 -0
- data/app/assets/stylesheets/ariadne_view_components.css.gz +0 -0
- data/app/components/ariadne/base_component.rb +25 -22
- data/app/components/ariadne/behaviors/tooltipable.rb +12 -12
- data/app/components/ariadne/form/checkbox/component.rb +2 -2
- data/app/components/ariadne/form/group/component.rb +1 -1
- data/app/components/ariadne/form/radio_button/component.rb +2 -2
- data/app/components/ariadne/form/select/component.rb +1 -1
- data/app/components/ariadne/form/text_field/component.html.erb +2 -2
- data/app/components/ariadne/form/text_field/component.rb +14 -7
- data/app/components/ariadne/form/toggle/component.rb +2 -2
- data/app/components/ariadne/form/toggle_group/component.rb +1 -1
- data/app/components/ariadne/form/toggle_group/option/component.rb +1 -1
- data/app/components/ariadne/layout/grid/component.rb +1 -1
- data/app/components/ariadne/layout/grid/item/component.rb +2 -2
- data/app/components/ariadne/layout/label_block/component.rb +1 -1
- data/app/components/ariadne/layout/narrow/component.rb +1 -1
- data/app/components/ariadne/ui/accordion/component.rb +3 -1
- data/app/components/ariadne/ui/accordion/item/component.html.erb +10 -10
- data/app/components/ariadne/ui/accordion/item/component.rb +12 -3
- data/app/components/ariadne/ui/avatar/component.html.erb +9 -7
- data/app/components/ariadne/ui/avatar/component.rb +55 -7
- data/app/components/ariadne/ui/badge/component.rb +35 -16
- data/app/components/ariadne/ui/banner/component.html.erb +23 -0
- data/app/components/ariadne/ui/banner/component.rb +226 -0
- data/app/components/ariadne/ui/banner/component.ts +46 -0
- data/app/components/ariadne/ui/blankslate/component.html.erb +2 -2
- data/app/components/ariadne/ui/blankslate/component.rb +12 -1
- data/app/components/ariadne/ui/button/component.rb +35 -24
- data/app/components/ariadne/ui/card/body/component.rb +1 -1
- data/app/components/ariadne/ui/card/component.rb +11 -7
- data/app/components/ariadne/ui/card/footer/component.rb +1 -1
- data/app/components/ariadne/ui/card/header/component.html.erb +2 -2
- data/app/components/ariadne/ui/card/header/component.rb +25 -16
- data/app/components/ariadne/ui/clipboard_copy/component.html.erb +1 -0
- data/app/components/ariadne/ui/clipboard_copy/component.rb +17 -21
- data/app/components/ariadne/ui/clipboard_copy/component.ts +15 -0
- data/app/components/ariadne/ui/color_dot/component.html.erb +5 -5
- data/app/components/ariadne/ui/color_dot/component.rb +19 -4
- data/app/components/ariadne/ui/combobox/component.html.erb +1 -1
- data/app/components/ariadne/ui/combobox/component.rb +54 -23
- data/app/components/ariadne/ui/combobox/component.ts +2 -0
- data/app/components/ariadne/ui/dialog/body/component.html.erb +3 -0
- data/app/components/ariadne/ui/dialog/body/component.rb +28 -0
- data/app/components/ariadne/ui/dialog/component.html.erb +25 -24
- data/app/components/ariadne/ui/dialog/component.rb +87 -18
- data/app/components/ariadne/ui/dialog/component.ts +5 -1
- data/app/components/ariadne/ui/dialog/footer/component.html.erb +3 -0
- data/app/components/ariadne/ui/dialog/footer/component.rb +34 -0
- data/app/components/ariadne/ui/heroicon/component.rb +21 -21
- data/app/components/ariadne/ui/image/component.rb +11 -23
- data/app/components/ariadne/ui/link/component.html.erb +1 -3
- data/app/components/ariadne/ui/link/component.rb +17 -4
- data/app/components/ariadne/ui/list/component.html.erb +5 -9
- data/app/components/ariadne/ui/list/component.rb +31 -7
- data/app/components/ariadne/ui/list/item/component.rb +6 -5
- data/app/components/ariadne/ui/pagination/component.rb +1 -2
- data/app/components/ariadne/ui/popover/component.html.erb +1 -1
- data/app/components/ariadne/ui/popover/component.rb +31 -26
- data/app/components/ariadne/ui/relative_time/component.html.erb +1 -0
- data/app/components/ariadne/ui/{time_ago → relative_time}/component.rb +15 -15
- data/app/components/ariadne/ui/{time_ago → relative_time}/component.ts +1 -1
- data/app/components/ariadne/ui/shortcut/component.html.erb +0 -1
- data/app/components/ariadne/ui/shortcut/component.rb +31 -5
- data/app/components/ariadne/ui/shortcut/component.ts +1 -1
- data/app/components/ariadne/ui/skeleton/component.rb +2 -8
- data/app/components/ariadne/ui/stats_panel/component.html.erb +3 -3
- data/app/components/ariadne/ui/stats_panel/component.rb +25 -1
- data/app/components/ariadne/ui/stats_panel/item/component.html.erb +3 -3
- data/app/components/ariadne/ui/stats_panel/item/component.rb +6 -6
- data/app/components/ariadne/ui/table/cell/component.rb +1 -1
- data/app/components/ariadne/ui/table/row/component.rb +1 -1
- data/app/components/ariadne/ui/typography/component.rb +3 -1
- data/app/frontend/controllers/tooltip_controller.ts +8 -3
- data/app/frontend/stylesheets/ariadne_view_components.css +1 -0
- data/app/frontend/stylesheets/theme.css +88 -0
- data/app/frontend/utils/createController.ts +9 -0
- data/app/helpers/ariadne/color_helper.rb +158 -0
- data/app/helpers/ariadne/form_helper.rb +1 -0
- data/app/helpers/ariadne/size_helper.rb +7 -0
- data/app/lib/ariadne/attributes_helper.rb +4 -4
- data/app/lib/ariadne/view_component/style_variants.rb +1 -1
- data/app/lib/ariadne/view_helper.rb +0 -6
- data/lib/ariadne/accessibility.rb +64 -0
- data/lib/ariadne/forms/dsl/form_object.rb +5 -1
- data/lib/ariadne/forms/dsl/input.rb +1 -1
- data/lib/ariadne/static/generate_arguments.rb +54 -0
- data/lib/ariadne/static/generate_audited_at.rb +17 -0
- data/lib/ariadne/static/generate_constants.rb +19 -0
- data/lib/ariadne/static/generate_previews.rb +53 -0
- data/lib/ariadne/static/generate_statuses.rb +17 -0
- data/lib/ariadne/static/generate_structure.rb +279 -0
- data/lib/ariadne/static.rb +68 -0
- data/lib/ariadne/view_components/constants.rb +2 -2
- data/lib/ariadne/view_components/version.rb +1 -1
- data/lib/ariadne/view_components.rb +0 -51
- data/lib/ariadne/yard/component_manifest.rb +81 -81
- data/lib/ariadne/yard/component_ref.rb +1 -1
- data/lib/ariadne/yard/docs_helper.rb +24 -16
- data/lib/ariadne/yard/dry_initializer/common_handler.rb +103 -0
- data/lib/ariadne/yard/dry_initializer/option_handler.rb +38 -0
- data/lib/ariadne/yard/dry_initializer/param_handler.rb +57 -0
- data/lib/ariadne/yard/registry.rb +2 -5
- data/lib/ariadne/yard/{info_arch_docs_helper.rb → structure_docs_helper.rb} +5 -5
- data/lib/ariadne/yard.rb +20 -8
- data/lib/rubocop/config/default.yml +0 -3
- metadata +34 -37
- data/app/components/ariadne/behaviors/captionable.rb +0 -55
- data/app/components/ariadne/turbo/frame/component.html.erb +0 -3
- data/app/components/ariadne/turbo/frame/component.rb +0 -16
- data/app/components/ariadne/turbo/stream_action/component.html.erb +0 -4
- data/app/components/ariadne/turbo/stream_action/component.rb +0 -25
- data/app/components/ariadne/ui/data_table/component.html.erb +0 -1
- data/app/components/ariadne/ui/data_table/component.rb +0 -11
- data/app/components/ariadne/ui/flash/component.html.erb +0 -18
- data/app/components/ariadne/ui/flash/component.rb +0 -151
- data/app/components/ariadne/ui/flash/component.ts +0 -56
- data/app/components/ariadne/ui/overlay/component.html.erb +0 -12
- data/app/components/ariadne/ui/overlay/component.rb +0 -54
- data/app/components/ariadne/ui/overlay/component.ts +0 -92
- data/app/components/ariadne/ui/time_ago/component.html.erb +0 -1
- data/lib/ariadne/view_components/commands.rb +0 -90
- data/lib/ariadne/view_components/statuses.rb +0 -14
- data/lib/ariadne/view_components/upstream.rb +0 -19
- data/lib/ariadne/yard/lookbook_pages_backend.rb +0 -235
- data/lib/rubocop/cop/ariadne/no_tag_memoize.rb +0 -44
- data/static/arguments.yml +0 -879
- data/static/assets/view-components.svg +0 -18
- data/static/classes.yml +0 -211
- data/static/constants.json +0 -743
- data/static/statuses.json +0 -58
- data/static/tailwindcss.yml +0 -727
- /data/app/components/ariadne/ui/{time_ago → relative_time}/en.yml +0 -0
@@ -0,0 +1,226 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Ariadne
|
5
|
+
module UI
|
6
|
+
module Banner
|
7
|
+
# Use this component to draw attention to important information.
|
8
|
+
#
|
9
|
+
# ### Events
|
10
|
+
#
|
11
|
+
# |Name |Type |Bubbles |Cancelable |
|
12
|
+
# |:---------|:-------------------|:-------|:----------|
|
13
|
+
# |`dismiss` |`CustomEvent<void>` |No |No |
|
14
|
+
#
|
15
|
+
#
|
16
|
+
# @accessibility
|
17
|
+
# ### Improve discoverability with a heading and landmark
|
18
|
+
# Banners are made visually prominent with icons and colors to immediately draw attention.
|
19
|
+
#
|
20
|
+
# To ensure the Banner is also easily discoverable for assistive technology users, you must provide a heading inside of the Banner that describes the purpose of the Banner.
|
21
|
+
class Component < Ariadne::BaseComponent
|
22
|
+
# @param [Boolean] dismissible Whether the component can be dismissed with an "x" button.
|
23
|
+
option :dismissible, default: -> { false }
|
24
|
+
# @param [String] dismiss_label The aria-label text of the dismiss "x" button
|
25
|
+
option :dismiss_label, optional: true
|
26
|
+
|
27
|
+
DEFAULT_SCHEME = :default
|
28
|
+
VALID_SCHEMES = [DEFAULT_SCHEME, :danger, :warning, :info, :success].freeze
|
29
|
+
|
30
|
+
# @param [Symbol] scheme (:default) The scheme design to use. <%= one_of(Ariadne::UI::Banner::Component::VALID_SCHEMES) %>
|
31
|
+
option :scheme, default: -> { DEFAULT_SCHEME }
|
32
|
+
|
33
|
+
# @param [Symbol] width (:base) Indicates the width of the button. Can be either `:base` or `:full`.
|
34
|
+
option :width, default: proc { :base }
|
35
|
+
|
36
|
+
# @param [Boolean, String] autohide (false) Autohides the banner after a set amount of time. If `true`, uses the default timeout;
|
37
|
+
# otherwise, provide a value to use.
|
38
|
+
option :autohide, default: -> { false }
|
39
|
+
|
40
|
+
# @param [String] title A header announcing the banner.
|
41
|
+
option :title
|
42
|
+
|
43
|
+
# Content that will render on the right-hand side of the component.
|
44
|
+
#
|
45
|
+
# To render a button, call the `with_action_button` method, which accepts the arguments accepted by <%= link_to_component(Ariadne::UI::Button::Component) %>.
|
46
|
+
#
|
47
|
+
# To render custom content, call the `with_action_content` method and pass a block that returns HTML.
|
48
|
+
renders_one :action, types: {
|
49
|
+
button: Ariadne::UI::Button::Component,
|
50
|
+
content: Ariadne::BaseComponent::ACCEPT_ANYTHING,
|
51
|
+
}
|
52
|
+
|
53
|
+
# @param [Symbol] heroicon The name of a <%= link_to_heroicons %> icon to show on the left-hand side of the component. If no icon is provided, one will be chosen based on the scheme.
|
54
|
+
renders_one :heroicon, Ariadne::UI::Heroicon::Component
|
55
|
+
|
56
|
+
def icon
|
57
|
+
heroicon || infer_icon
|
58
|
+
end
|
59
|
+
|
60
|
+
accepts_html_attributes do |html_attrs|
|
61
|
+
autohide_value = if @autohide == true
|
62
|
+
4000
|
63
|
+
else
|
64
|
+
@autohide.presence || 0
|
65
|
+
end
|
66
|
+
|
67
|
+
component_data_attrs = {
|
68
|
+
controller: stimulus_name,
|
69
|
+
"#{stimulus_name}-target": "banner",
|
70
|
+
"#{stimulus_name}-autohide-value": autohide_value,
|
71
|
+
}
|
72
|
+
html_attrs[:data] = merge_data_attributes(html_attrs, component_data_attrs)
|
73
|
+
|
74
|
+
html_attrs[:class] = merge_tailwind_classes([
|
75
|
+
style(scheme:, width:),
|
76
|
+
html_attrs[:class],
|
77
|
+
])
|
78
|
+
end
|
79
|
+
|
80
|
+
def before_render
|
81
|
+
raise ArgumentError, "Requires `dismiss_label`" if dismissible && dismiss_label.nil?
|
82
|
+
|
83
|
+
@header_id = self.class.generate_id
|
84
|
+
end
|
85
|
+
|
86
|
+
def heroicon_or_default
|
87
|
+
if heroicon?
|
88
|
+
heroicon
|
89
|
+
else
|
90
|
+
icon = case scheme
|
91
|
+
when :danger
|
92
|
+
:"exclamation-circle"
|
93
|
+
when :warning
|
94
|
+
:"exclamation-triangle"
|
95
|
+
when :info
|
96
|
+
:"information-circle"
|
97
|
+
when :success
|
98
|
+
:"check-circle"
|
99
|
+
else
|
100
|
+
:"chat-bubble-bottom-center"
|
101
|
+
end
|
102
|
+
|
103
|
+
Ariadne::UI::Heroicon::Component.new(icon: icon, variant: :outline)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
style do
|
108
|
+
base do
|
109
|
+
[
|
110
|
+
"ariadne-border",
|
111
|
+
"ariadne-pointer-events-auto",
|
112
|
+
"ariadne-overflow-hidden",
|
113
|
+
"ariadne-rounded-lg",
|
114
|
+
"ariadne-shadow-lg",
|
115
|
+
"ariadne-ring-1",
|
116
|
+
"ariadne-ring-slate-950",
|
117
|
+
"ariadne-ring-opacity-5",
|
118
|
+
"ariadne-z-50",
|
119
|
+
]
|
120
|
+
end
|
121
|
+
|
122
|
+
variants do
|
123
|
+
width do
|
124
|
+
base do
|
125
|
+
[
|
126
|
+
"ariadne-w-full",
|
127
|
+
"ariadne-max-w-lg",
|
128
|
+
]
|
129
|
+
end
|
130
|
+
|
131
|
+
full do
|
132
|
+
[
|
133
|
+
"ariadne-w-full",
|
134
|
+
]
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
scheme do
|
139
|
+
default do
|
140
|
+
[]
|
141
|
+
end
|
142
|
+
danger do
|
143
|
+
[
|
144
|
+
"ariadne-border-danger",
|
145
|
+
"ariadne-bg-red-50",
|
146
|
+
]
|
147
|
+
end
|
148
|
+
warning do
|
149
|
+
[
|
150
|
+
"ariadne-border-warning",
|
151
|
+
"ariadne-bg-yellow-50",
|
152
|
+
]
|
153
|
+
end
|
154
|
+
info do
|
155
|
+
[
|
156
|
+
"ariadne-border-info",
|
157
|
+
"ariadne-bg-blue-50",
|
158
|
+
]
|
159
|
+
end
|
160
|
+
success do
|
161
|
+
[
|
162
|
+
"ariadne-border-success",
|
163
|
+
"ariadne-bg-green-50",
|
164
|
+
]
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
style(:text) do
|
171
|
+
variants do
|
172
|
+
scheme do
|
173
|
+
danger do
|
174
|
+
[
|
175
|
+
"ariadne-text-red-700",
|
176
|
+
]
|
177
|
+
end
|
178
|
+
warning do
|
179
|
+
[
|
180
|
+
"ariadne-text-yellow-700",
|
181
|
+
]
|
182
|
+
end
|
183
|
+
info do
|
184
|
+
[
|
185
|
+
"ariadne-text-blue-700",
|
186
|
+
]
|
187
|
+
end
|
188
|
+
success do
|
189
|
+
[
|
190
|
+
"ariadne-text-green-700",
|
191
|
+
]
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
style(:dismissable) do
|
198
|
+
variants do
|
199
|
+
scheme do
|
200
|
+
danger do
|
201
|
+
[
|
202
|
+
"ariadne-text-red-700",
|
203
|
+
]
|
204
|
+
end
|
205
|
+
warning do
|
206
|
+
[
|
207
|
+
"ariadne-text-yellow-700",
|
208
|
+
]
|
209
|
+
end
|
210
|
+
info do
|
211
|
+
[
|
212
|
+
"ariadne-text-blue-700",
|
213
|
+
]
|
214
|
+
end
|
215
|
+
success do
|
216
|
+
[
|
217
|
+
"ariadne-text-green-700",
|
218
|
+
]
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import {controllerFactory} from '@utils/createController'
|
2
|
+
|
3
|
+
export default class Controller extends controllerFactory()({
|
4
|
+
targets: {
|
5
|
+
banner: HTMLDivElement,
|
6
|
+
},
|
7
|
+
values: {
|
8
|
+
open: Boolean,
|
9
|
+
autohide: {
|
10
|
+
default: 4000,
|
11
|
+
type: Number,
|
12
|
+
},
|
13
|
+
},
|
14
|
+
}) {
|
15
|
+
connect() {
|
16
|
+
if (this.autohideValue != 0) {
|
17
|
+
const noop = (): void => {};
|
18
|
+
|
19
|
+
// Set a timer for it to be removed from the dom automatically
|
20
|
+
setTimeout(() => {
|
21
|
+
this.hide().then(noop).catch(noop);
|
22
|
+
}, this.autohideValue);
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
dismiss() {
|
27
|
+
this.remove();
|
28
|
+
// this.hide()
|
29
|
+
|
30
|
+
this.dispatchEvent(this.bannerTarget, 'ariadne-banner:dismiss')
|
31
|
+
}
|
32
|
+
|
33
|
+
show() {
|
34
|
+
this.bannerTarget.style.setProperty('display', 'initial')
|
35
|
+
}
|
36
|
+
|
37
|
+
remove() {
|
38
|
+
const parentElement = this.bannerTarget.parentElement
|
39
|
+
if (!parentElement) return
|
40
|
+
|
41
|
+
parentElement.removeChild(this.bannerTarget)
|
42
|
+
}
|
43
|
+
hide() {
|
44
|
+
this.bannerTarget.style.setProperty('display', 'none')
|
45
|
+
}
|
46
|
+
}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<div class="ariadne-grow ariadne-flex ariadne-flex-col ariadne-justify-center ariadne-items-center ariadne-gap-1">
|
2
|
-
<%=
|
2
|
+
<%= visual_heroicon %>
|
3
3
|
<div class="ariadne-pt-5">
|
4
|
-
|
4
|
+
<%= render(Ariadne::UI::Typography::Component.new(type: :ann)) { title } %>
|
5
5
|
</div>
|
6
6
|
<div class="ariadne-space-y-2">
|
7
7
|
<%= render(Ariadne::UI::Typography::Component.new(type: :lede)) { description } %>
|
@@ -4,11 +4,22 @@
|
|
4
4
|
module Ariadne
|
5
5
|
module UI
|
6
6
|
module Blankslate
|
7
|
+
# Blankslate is used as placeholder to tell users why content is missing.
|
7
8
|
class Component < Ariadne::BaseComponent
|
9
|
+
# @param [String] title The blank slate's title.
|
8
10
|
option :title
|
11
|
+
# @param [String] description A description of why content is missing.
|
9
12
|
option :description, optional: true
|
10
13
|
|
11
|
-
|
14
|
+
# Optional visual that appears at the center of the blankslate.
|
15
|
+
#
|
16
|
+
# Use:
|
17
|
+
#
|
18
|
+
# - `visual_heroicon` for a <%= link_to_component(Ariadne::UI::Heroicon::Component) %>.
|
19
|
+
#
|
20
|
+
# @param options [Hash] Same arguments as <%= link_to_component(Ariadne::UI::Heroicon::Component) %>.
|
21
|
+
|
22
|
+
renders_one :visual_heroicon, Ariadne::UI::Heroicon::Component
|
12
23
|
end
|
13
24
|
end
|
14
25
|
end
|
@@ -4,19 +4,38 @@
|
|
4
4
|
module Ariadne
|
5
5
|
module UI
|
6
6
|
module Button
|
7
|
+
# Used to initiate actions on a page or form.
|
8
|
+
#
|
9
|
+
# You can call `as_icon` to render a button with only an icon.
|
10
|
+
#
|
11
|
+
# @accessibility If `as_icon` is called, you must provide an `aria-label` or `aria-description` to the button.
|
12
|
+
#
|
13
|
+
# @behaviors <%= link_to_component(Ariadne::Behaviors::Tooltipable) %>
|
7
14
|
class Component < Ariadne::BaseComponent
|
8
15
|
attr_reader :icon_only
|
9
16
|
|
10
|
-
include Ariadne::Behaviors::Captionable
|
11
17
|
include Ariadne::Behaviors::Tooltipable
|
12
18
|
|
13
|
-
|
14
|
-
option :
|
19
|
+
# @param [Symbol] as (:button) One of `:button` or :link. Indicates how to render the button: as a `button` or `a` tag.
|
20
|
+
option :as, default: -> { :button }
|
15
21
|
|
22
|
+
# @param [Symbol] href If `as: == :link`, this indicates where the `a` should go.
|
23
|
+
option :href, default: -> { nil }
|
24
|
+
|
25
|
+
# @param [String] type (button) Indicates the button's type, e.g. `submit`.
|
16
26
|
option :type, default: proc { "button" }
|
17
|
-
|
18
|
-
|
19
|
-
|
27
|
+
|
28
|
+
DEFAULT_SCHEME = :primary
|
29
|
+
SCHEME_OPTIONS = [DEFAULT_SCHEME, :secondary, :nude, :danger].freeze
|
30
|
+
|
31
|
+
# @param [Symbol] scheme (:primary) Indicates the button's scheme. <%= one_of(Ariadne::UI::Button::Component::SCHEME_OPTIONS) %>
|
32
|
+
option :scheme, default: proc { DEFAULT_SCHEME }
|
33
|
+
|
34
|
+
DEFAULT_SIZE = :md
|
35
|
+
# @param [Symbol] size (Ariadne::UI::Button::DEFAULT_SIZE) Indicates the button's size. <%= one_of(Ariadne::SizeHelper::VALID_SIZES) %>
|
36
|
+
option :size, default: proc { DEFAULT_SIZE }
|
37
|
+
|
38
|
+
# @param [Symbol] width (:narrow) Indicates the width of the button. Can be either `:narrow` or `:full`.
|
20
39
|
option :width, default: proc { :narrow }
|
21
40
|
|
22
41
|
# Leading visuals appear to the left of the button text.
|
@@ -24,11 +43,10 @@ module Ariadne
|
|
24
43
|
# Use:
|
25
44
|
#
|
26
45
|
# - `leading_visual_heroicon` for a <%= link_to_component(Ariadne::UI::Heroicon::Component) %>.
|
46
|
+
#
|
47
|
+
# @param options [Hash] Same arguments as the chosen visual.
|
27
48
|
renders_one :leading_visual, types: {
|
28
|
-
heroicon:
|
29
|
-
options[:size] = @size
|
30
|
-
Ariadne::UI::Heroicon::Component.new(**options)
|
31
|
-
},
|
49
|
+
heroicon: Ariadne::UI::Heroicon::Component,
|
32
50
|
}
|
33
51
|
|
34
52
|
# Trailing visuals appear to the right of the button text.
|
@@ -36,15 +54,14 @@ module Ariadne
|
|
36
54
|
# Use:
|
37
55
|
#
|
38
56
|
# - `trailing_visual_heroicon` for a <%= link_to_component(Ariadne::UI::Heroicon::Component) %>.
|
57
|
+
#
|
58
|
+
# @param options [Hash] Same arguments as the chosen visual.
|
39
59
|
renders_one :trailing_visual, types: {
|
40
|
-
heroicon:
|
41
|
-
options[:size] = @size
|
42
|
-
Ariadne::UI::Heroicon::Component.new(**options)
|
43
|
-
},
|
60
|
+
heroicon: Ariadne::UI::Heroicon::Component,
|
44
61
|
}
|
45
62
|
|
46
63
|
accepts_html_attributes do |html_attrs|
|
47
|
-
html_attrs[:class] =
|
64
|
+
html_attrs[:class] = merge_tailwind_classes([style(scheme:, size:, icon_only:, width:), html_attrs[:class]].join(" "))
|
48
65
|
|
49
66
|
if link?
|
50
67
|
raise ArgumentError, "Button needs an `href` defined when using `as: :link`" if href.blank?
|
@@ -57,10 +74,6 @@ module Ariadne
|
|
57
74
|
end
|
58
75
|
end
|
59
76
|
|
60
|
-
def initialize(**options)
|
61
|
-
super
|
62
|
-
end
|
63
|
-
|
64
77
|
def as_icon(**options)
|
65
78
|
validate_aria_label!(html_attrs)
|
66
79
|
|
@@ -109,17 +122,15 @@ module Ariadne
|
|
109
122
|
end
|
110
123
|
|
111
124
|
variants do
|
112
|
-
|
125
|
+
scheme do
|
113
126
|
primary do
|
114
127
|
[
|
115
128
|
"ariadne-bg-primary",
|
116
129
|
"ariadne-text-primary-foreground",
|
117
130
|
|
118
|
-
"hover:ariadne-bg-primary
|
119
|
-
"active:ariadne-bg-primary-active",
|
131
|
+
"hover:enabled:ariadne-bg-primary/90",
|
120
132
|
|
121
|
-
"disabled:ariadne-
|
122
|
-
"disabled:ariadne-text-primary-disabled-foreground-dark",
|
133
|
+
"disabled:ariadne-opacity-50",
|
123
134
|
]
|
124
135
|
end
|
125
136
|
|
@@ -7,7 +7,7 @@ module Ariadne
|
|
7
7
|
module Body
|
8
8
|
class Component < Ariadne::BaseComponent
|
9
9
|
accepts_html_attributes do |html_attrs|
|
10
|
-
html_attrs[:class] =
|
10
|
+
html_attrs[:class] = merge_tailwind_classes([style, html_attrs[:class]].join(" "))
|
11
11
|
end
|
12
12
|
|
13
13
|
style do
|
@@ -5,26 +5,30 @@ module Ariadne
|
|
5
5
|
module UI
|
6
6
|
module Card
|
7
7
|
class Component < Ariadne::BaseComponent
|
8
|
-
|
8
|
+
# @param [String] href If provided, renders the entire card as a link.
|
9
|
+
option :href, optional: true
|
9
10
|
|
11
|
+
# Represent the card's header.
|
10
12
|
renders_one :header, Ariadne::UI::Card::Header::Component
|
11
13
|
|
12
14
|
accepts_html_attributes do |html_attrs|
|
13
|
-
html_attrs[:class] =
|
15
|
+
html_attrs[:class] = merge_tailwind_classes([style(link: href.present? ? :yes : :no), html_attrs[:class]].join(" "))
|
14
16
|
end
|
15
17
|
|
18
|
+
# The card's body.
|
16
19
|
renders_one :body, Ariadne::UI::Card::Body::Component
|
20
|
+
|
21
|
+
# Represent the card's footer
|
17
22
|
renders_one :footer, Ariadne::UI::Card::Footer::Component
|
18
23
|
|
19
24
|
style do
|
20
25
|
base do
|
21
26
|
[
|
22
|
-
"ariadne-rounded-
|
27
|
+
"ariadne-rounded-xl",
|
23
28
|
"ariadne-border",
|
24
|
-
"ariadne-bg-
|
25
|
-
"
|
26
|
-
"ariadne-
|
27
|
-
"dark:ariadne-text-content-dark",
|
29
|
+
"ariadne-bg-card",
|
30
|
+
"ariadne-text-card-foreground",
|
31
|
+
"ariadne-shadow",
|
28
32
|
]
|
29
33
|
end
|
30
34
|
|
@@ -7,7 +7,7 @@ module Ariadne
|
|
7
7
|
module Footer
|
8
8
|
class Component < Ariadne::BaseComponent
|
9
9
|
accepts_html_attributes do |html_attrs|
|
10
|
-
html_attrs[:class] =
|
10
|
+
html_attrs[:class] = merge_tailwind_classes([style, html_attrs[:class]].join(" "))
|
11
11
|
end
|
12
12
|
|
13
13
|
style do
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<div class="<%= html_attrs[:class] %>" <%= html_attributes %>>
|
2
|
-
<%= title %>
|
2
|
+
<span class="<%= style(:title) %>"><%= title %></span>
|
3
3
|
<% if description %>
|
4
|
-
<%= description %>
|
4
|
+
<span class="<%= style(:description) %>"><%= description %></span>
|
5
5
|
<% end %>
|
6
6
|
</div>
|
@@ -5,26 +5,16 @@ module Ariadne
|
|
5
5
|
module UI
|
6
6
|
module Card
|
7
7
|
module Header
|
8
|
+
# The header of a card.
|
8
9
|
class Component < Ariadne::BaseComponent
|
9
|
-
|
10
|
-
|
11
|
-
options[:html_attrs] ||= {}
|
12
|
-
options[:html_attrs][:class] ||= ""
|
13
|
-
options[:html_attrs][:class] = [
|
14
|
-
"ariadne-grow",
|
15
|
-
"ariadne-leading-none",
|
16
|
-
options[:html_attrs][:class],
|
17
|
-
]
|
18
|
-
Ariadne::UI::Typography::Component.new(**options)
|
19
|
-
}
|
10
|
+
# @param [String] title If provided, serves as the title of the card.
|
11
|
+
option :title, optional: true
|
20
12
|
|
21
|
-
|
22
|
-
|
23
|
-
Ariadne::UI::Typography::Component.new(**options)
|
24
|
-
}
|
13
|
+
# @param [String] description If provided, serves as the description of the card.
|
14
|
+
option :description, optional: true
|
25
15
|
|
26
16
|
accepts_html_attributes do |html_attrs|
|
27
|
-
html_attrs[:class] =
|
17
|
+
html_attrs[:class] = merge_tailwind_classes([style, html_attrs[:class]].join(" "))
|
28
18
|
end
|
29
19
|
|
30
20
|
style do
|
@@ -37,6 +27,25 @@ module Ariadne
|
|
37
27
|
]
|
38
28
|
end
|
39
29
|
end
|
30
|
+
|
31
|
+
style(:title) do
|
32
|
+
base do
|
33
|
+
[
|
34
|
+
"ariadne-font-semibold",
|
35
|
+
"ariadne-leading-none",
|
36
|
+
"ariadne-tracking-tight",
|
37
|
+
]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
style(:description) do
|
42
|
+
base do
|
43
|
+
[
|
44
|
+
"araidne-text-sm",
|
45
|
+
"ariadne-text-muted-foreground",
|
46
|
+
]
|
47
|
+
end
|
48
|
+
end
|
40
49
|
end
|
41
50
|
end
|
42
51
|
end
|
@@ -6,3 +6,4 @@
|
|
6
6
|
<%= render Ariadne::UI::Heroicon::Component.new(icon: :check, variant: HeroiconsHelper::Icon::VARIANT_OUTLINE, html_attrs: { class: "ariadne-text-green-600 ariadne-hidden", data: { "ariadne-ui-clipboard-copy-target" => "confirmed" }}) %>
|
7
7
|
<% end %>
|
8
8
|
</clipboard-copy>
|
9
|
+
<div aria-live="polite" aria-atomic="true" class="ariadne-sr-only" data-clipboard-copy-feedback></div>
|
@@ -4,28 +4,24 @@
|
|
4
4
|
module Ariadne
|
5
5
|
module UI
|
6
6
|
module ClipboardCopy
|
7
|
-
# Use
|
8
|
-
#
|
9
|
-
# @example Default
|
10
|
-
# <%= render(Ariadne::UI::ClipboardCopy::Component.new(value: "Text to copy", aria_label: "Copy text to the system clipboard" )) %>
|
11
|
-
#
|
12
|
-
# @example With text instead of icons
|
13
|
-
# <%= render(Ariadne::UI::ClipboardCopy::Component.new(value: "Text to copy", aria_label: "Copy text to the system clipboard" )) do %>
|
14
|
-
# Click to copy!
|
15
|
-
# <% end %>
|
16
|
-
#
|
17
|
-
# @example Copying from an element
|
18
|
-
# <%= render(Ariadne::UI::ClipboardCopy::Component.new(for_id: "blob-path", aria_label: "Copy text to the system clipboard" )) %>
|
19
|
-
# <div id="blob-path">src/index.js</div>
|
7
|
+
# Use this to copy element text content or input values to the clipboard.
|
20
8
|
#
|
21
9
|
# @accessibility
|
22
|
-
# Always set an accessible label to help the user interact with the component.
|
23
|
-
|
24
|
-
|
10
|
+
# Always set an accessible label (through `aria-label`) to help the user interact with the component.
|
11
|
+
#
|
12
|
+
# This component has a built-in `aria-live` region that announces "Copied!" when the copy element is pressed.
|
13
|
+
class Component < Ariadne::BaseComponent
|
14
|
+
# @param [String] value Text to copy when the component is clicked.
|
25
15
|
option :value, optional: true
|
26
|
-
# @param
|
16
|
+
# @param [String] for If `value` is not provided, the element with this id will be copied.
|
27
17
|
option :for, optional: true
|
28
18
|
|
19
|
+
DEFAULT_SIZE = :md
|
20
|
+
# @param [Symbol] size (Ariadne::UI::ClipboardCopy::DEFAULT_SIZE) Indicates the button's size. <%= one_of(Ariadne::SizeHelper::VALID_SIZES) %>
|
21
|
+
option :size, default: proc { DEFAULT_SIZE }
|
22
|
+
|
23
|
+
include Ariadne::Behaviors::Tooltipable
|
24
|
+
|
29
25
|
def initialize(**options)
|
30
26
|
super
|
31
27
|
validate!
|
@@ -37,7 +33,7 @@ module Ariadne
|
|
37
33
|
html_attrs[:value] = @value if @value.present?
|
38
34
|
html_attrs[:for] = @for if @for.present?
|
39
35
|
|
40
|
-
html_attrs[:class] =
|
36
|
+
html_attrs[:class] = merge_tailwind_classes([style(size:), html_attrs[:class]].join(" "))
|
41
37
|
|
42
38
|
html_attrs[:data]["#{stimulus_name}-hidden-class-value"] = "ariadne-hidden"
|
43
39
|
html_attrs[:data]["#{stimulus_name}-show-class-value"] = "ariadne-inline-block"
|
@@ -86,9 +82,6 @@ module Ariadne
|
|
86
82
|
"[&>svg]:ariadne-size-4",
|
87
83
|
]
|
88
84
|
end
|
89
|
-
base do
|
90
|
-
["ariadne-gap-1", "ariadne-text-base", "ariadne-rounded-md"]
|
91
|
-
end
|
92
85
|
md do
|
93
86
|
[
|
94
87
|
"ariadne-gap-1",
|
@@ -100,6 +93,9 @@ module Ariadne
|
|
100
93
|
lg do
|
101
94
|
["ariadne-gap-1", "ariadne-text-lg", "ariadne-rounded-lg"]
|
102
95
|
end
|
96
|
+
xl do
|
97
|
+
["ariadne-gap-1", "ariadne-text-xl", "ariadne-rounded-xl"]
|
98
|
+
end
|
103
99
|
end
|
104
100
|
end
|
105
101
|
end
|
@@ -23,12 +23,27 @@ export default class ClipboardCopyController extends controllerFactory<HTMLDetai
|
|
23
23
|
copy(event: Event) {
|
24
24
|
const target = event.target as HTMLElement
|
25
25
|
const currentTimeout = this.clipboardCopyElementTimers.get(target)
|
26
|
+
const clipboardCopyLiveRegion = target.parentNode?.querySelector<HTMLElement>('[data-clipboard-copy-feedback]')
|
27
|
+
const copiedAnnouncement = 'Copied!'
|
26
28
|
|
27
29
|
if (currentTimeout) {
|
28
30
|
clearTimeout(currentTimeout)
|
29
31
|
this.clipboardCopyElementTimers.delete(target)
|
30
32
|
} else {
|
31
33
|
this.showConfirm()
|
34
|
+
|
35
|
+
if (clipboardCopyLiveRegion) {
|
36
|
+
if (clipboardCopyLiveRegion.textContent === copiedAnnouncement) {
|
37
|
+
/* This is a hack due to the way the aria live API works.
|
38
|
+
A screen reader will not read a live region again
|
39
|
+
if the text is the same. Adding a space character tells
|
40
|
+
the browser that the live region has updated,
|
41
|
+
which will cause it to read again, but with no audible difference. */
|
42
|
+
clipboardCopyLiveRegion.textContent = `${copiedAnnouncement}\u00A0`
|
43
|
+
} else {
|
44
|
+
clipboardCopyLiveRegion.textContent = copiedAnnouncement
|
45
|
+
}
|
46
|
+
}
|
32
47
|
}
|
33
48
|
|
34
49
|
this.clipboardCopyElementTimers.set(
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<span class="<%= style(size:) %>">
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
<span class="ariadne-px-0.5 ariadne-p-1 ariadne-shrink-0">
|
3
|
+
<svg class="<%= style(:svg, size:) %>" viewBox="0 0 1 1" xmlns="http://www.w3.org/2000/svg">
|
4
|
+
<circle cx="0.5" cy="0.5" r="0.5" fill="#<%= color %>" />
|
5
|
+
</svg>
|
6
6
|
</span>
|
7
|
-
</span>
|
7
|
+
</span>
|