ariadne_view_components 0.0.93.2 → 0.0.94
Sign up to get free protection for your applications and to get access to all the features.
- 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>
|