ariadne_view_components 0.0.84 → 0.0.86
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/app/assets/javascripts/ariadne_view_components.js +7 -7
- 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 +15 -5
- data/app/components/ariadne/form/base_component.rb +1 -1
- data/app/components/ariadne/form/checkbox/component.html.erb +1 -1
- data/app/components/ariadne/form/checkbox/component.rb +15 -3
- data/app/components/ariadne/form/radio_button/component.html.erb +1 -3
- data/app/components/ariadne/form/select/component.html.erb +4 -2
- data/app/components/ariadne/form/select/component.rb +50 -2
- data/app/components/ariadne/form/toggle_group/component.html.erb +7 -0
- data/app/components/ariadne/form/toggle_group/component.rb +35 -0
- data/app/components/ariadne/form/toggle_group/option/component.html.erb +8 -0
- data/app/components/ariadne/form/toggle_group/option/component.rb +46 -0
- data/app/components/ariadne/layout/label_block/component.html.erb +12 -0
- data/app/components/ariadne/layout/label_block/component.rb +39 -0
- data/app/components/ariadne/layout/nav_bar/component.rb +4 -4
- data/app/components/ariadne/layout/section_block/component.html.erb +4 -0
- data/app/components/ariadne/layout/section_block/component.rb +12 -0
- data/app/components/ariadne/layout/section_block/header/component.html.erb +4 -0
- data/app/components/ariadne/layout/section_block/header/component.rb +14 -0
- data/app/components/ariadne/ui/avatar/component.html.erb +7 -0
- data/app/components/ariadne/ui/avatar/component.rb +54 -0
- data/app/components/ariadne/ui/badge/component.rb +8 -0
- data/app/components/ariadne/ui/card/body/component.html.erb +3 -0
- data/app/components/ariadne/ui/card/body/component.rb +25 -0
- data/app/components/ariadne/ui/card/component.html.erb +2 -6
- data/app/components/ariadne/ui/card/component.rb +1 -0
- data/app/components/ariadne/ui/combobox/component.rb +2 -0
- data/app/components/ariadne/ui/list/component.html.erb +2 -2
- data/app/components/ariadne/ui/list/component.rb +4 -3
- data/app/components/ariadne/ui/pagination/component.html.erb +29 -0
- data/app/components/ariadne/ui/pagination/component.rb +30 -0
- data/app/components/ariadne/ui/stats_panel/component.html.erb +7 -0
- data/app/components/ariadne/ui/stats_panel/component.rb +12 -0
- data/app/components/ariadne/ui/stats_panel/item/component.html.erb +4 -0
- data/app/components/ariadne/ui/stats_panel/item/component.rb +27 -0
- data/app/components/ariadne/ui/time_ago/component.html.erb +1 -0
- data/app/components/ariadne/ui/time_ago/component.rb +155 -0
- data/app/components/ariadne/ui/time_ago/en.yml +12 -0
- data/app/components/ariadne/ui/toggle/component.html.erb +7 -0
- data/app/components/ariadne/ui/toggle/component.rb +124 -0
- data/app/components/ariadne/ui/toggle/component.ts +133 -0
- data/app/lib/ariadne/fetch_or_fallback_helper.rb +23 -0
- data/lib/ariadne/view_components/engine.rb +4 -0
- data/lib/ariadne/view_components/version.rb +1 -1
- metadata +28 -2
@@ -0,0 +1,124 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Ariadne
|
5
|
+
module UI
|
6
|
+
module Toggle
|
7
|
+
class Component < Ariadne::BaseComponent
|
8
|
+
option :size, default: proc { :md }
|
9
|
+
option :reversed, default: proc { false }
|
10
|
+
|
11
|
+
# @param form_url [String] The URL to POST to when the toggle switch is toggled. If `nil`, the toggle switch will not make any requests.
|
12
|
+
# @param csrf_token [String] A CSRF token that will be sent to the server as "authenticity_token" when the toggle switch is toggled. Unused if `src` is `nil`.
|
13
|
+
# @param checked [Boolean] Whether the toggle switch is on or off.
|
14
|
+
# @param enabled [Boolean] Whether or not the toggle switch responds to user input.
|
15
|
+
option :form_url, default: proc { nil }
|
16
|
+
option :form_method, default: proc { :post }
|
17
|
+
option :checked, default: proc { false }
|
18
|
+
option :enabled, default: proc { true }
|
19
|
+
|
20
|
+
accepts_html_attributes do |html_attrs|
|
21
|
+
html_attrs[:class] = Ariadne::ViewComponents.tailwind_merger.merge([style(size:), html_attrs[:class]].join(" "))
|
22
|
+
|
23
|
+
if @checked
|
24
|
+
html_attrs[:checked] = @checked
|
25
|
+
html_attrs["aria-pressed"] = @checked
|
26
|
+
end
|
27
|
+
|
28
|
+
html_attrs[:data] ||= {}
|
29
|
+
html_attrs[:data] = {
|
30
|
+
controller: "#{stimulus_name} #{html_attrs[:data].delete(:controller)}".strip,
|
31
|
+
"#{stimulus_name}-target": "toggle",
|
32
|
+
action: "click->#{stimulus_name}#toggle #{html_attrs[:data].delete(:action)}".strip,
|
33
|
+
}.merge(html_attrs[:data])
|
34
|
+
end
|
35
|
+
|
36
|
+
def before_render
|
37
|
+
@label_id = ::Ariadne::ViewHelper.generate_id
|
38
|
+
|
39
|
+
if @form_url.present?
|
40
|
+
csrf_token = view_context.form_authenticity_token(
|
41
|
+
form_options: {
|
42
|
+
method: @form_method,
|
43
|
+
action: @form_url,
|
44
|
+
},
|
45
|
+
)
|
46
|
+
|
47
|
+
form_values = {
|
48
|
+
"#{stimulus_name}-csrf-token-value": csrf_token,
|
49
|
+
"#{stimulus_name}-form-method-value": @form_method,
|
50
|
+
"#{stimulus_name}-form-url-value": @form_url,
|
51
|
+
}
|
52
|
+
html_attrs[:data] = html_attrs[:data].merge(form_values)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
style do
|
57
|
+
base do
|
58
|
+
[
|
59
|
+
"ariadne-peer",
|
60
|
+
"ariadne-relative",
|
61
|
+
"ariadne-rounded-full",
|
62
|
+
"peer-focus:ariadne-ring-2",
|
63
|
+
"ariadne-bg-zinc-200",
|
64
|
+
"dark:ariadne-bg-zinc-700",
|
65
|
+
"peer-checked:ariadne-bg-indigo-500",
|
66
|
+
|
67
|
+
"after:ariadne-absolute",
|
68
|
+
"after:ariadne-content-['']",
|
69
|
+
"after:ariadne-start-0.5",
|
70
|
+
"after:ariadne-top-0.5",
|
71
|
+
"after:ariadne-rounded-full",
|
72
|
+
"after:ariadne-transition-all",
|
73
|
+
"after:ariadne-bg-white",
|
74
|
+
"peer-checked:after:ariadne-translate-x-full",
|
75
|
+
]
|
76
|
+
end
|
77
|
+
|
78
|
+
variants do
|
79
|
+
size do
|
80
|
+
sm do
|
81
|
+
[
|
82
|
+
"ariadne-w-7",
|
83
|
+
"ariadne-h-4",
|
84
|
+
"after:ariadne-h-3",
|
85
|
+
"after:ariadne-w-3",
|
86
|
+
]
|
87
|
+
end
|
88
|
+
md do
|
89
|
+
[
|
90
|
+
"ariadne-w-9",
|
91
|
+
"ariadne-h-5",
|
92
|
+
"after:ariadne-h-4",
|
93
|
+
"after:ariadne-w-4",
|
94
|
+
]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
style(:label) do
|
101
|
+
base do
|
102
|
+
[
|
103
|
+
"ariadne-relative",
|
104
|
+
"ariadne-inline-flex",
|
105
|
+
"ariadne-gap-3",
|
106
|
+
"ariadne-items-center",
|
107
|
+
"ariadne-cursor-pointer",
|
108
|
+
]
|
109
|
+
end
|
110
|
+
|
111
|
+
variants do
|
112
|
+
reversed do
|
113
|
+
yes do
|
114
|
+
["ariadne-flex-row-reverse"]
|
115
|
+
end
|
116
|
+
no do
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
import {controllerFactory} from '@utils/createController'
|
2
|
+
|
3
|
+
export default class ToggleController extends controllerFactory<HTMLInputElement>()({
|
4
|
+
targets: {
|
5
|
+
toggle: HTMLInputElement,
|
6
|
+
},
|
7
|
+
values: {
|
8
|
+
formMethod: String,
|
9
|
+
formUrl: String,
|
10
|
+
csrfToken: String,
|
11
|
+
},
|
12
|
+
}) {
|
13
|
+
connect() {
|
14
|
+
this.toggling = false
|
15
|
+
}
|
16
|
+
|
17
|
+
requiresFormSubmit(): boolean {
|
18
|
+
return this.formUrlValue != null
|
19
|
+
}
|
20
|
+
|
21
|
+
async toggle() {
|
22
|
+
if (this.toggling) return
|
23
|
+
|
24
|
+
this.toggling = true
|
25
|
+
|
26
|
+
if (this.isDisabled()) {
|
27
|
+
return
|
28
|
+
}
|
29
|
+
|
30
|
+
if (!this.requiresFormSubmit()) {
|
31
|
+
this.performToggle()
|
32
|
+
this.toggling = false
|
33
|
+
return
|
34
|
+
}
|
35
|
+
|
36
|
+
// toggle immediately to tell screen readers the switch was clicked
|
37
|
+
this.performToggle()
|
38
|
+
|
39
|
+
try {
|
40
|
+
await this.submitForm()
|
41
|
+
} catch (error) {
|
42
|
+
if (error instanceof Error) {
|
43
|
+
// because we toggle immediately when the switch is clicked, toggle back to the
|
44
|
+
// old state on failure
|
45
|
+
// this.setErrorState(error.message || 'An error occurred, please try again.')
|
46
|
+
this.performToggle()
|
47
|
+
}
|
48
|
+
|
49
|
+
return
|
50
|
+
} finally {
|
51
|
+
this.toggling = false
|
52
|
+
}
|
53
|
+
|
54
|
+
// this.setSuccessState()
|
55
|
+
}
|
56
|
+
|
57
|
+
performToggle(): void {
|
58
|
+
if (this.isOn()) {
|
59
|
+
this.turnOff()
|
60
|
+
} else {
|
61
|
+
this.turnOn()
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
turnOn(): void {
|
66
|
+
if (this.isDisabled()) {
|
67
|
+
return
|
68
|
+
}
|
69
|
+
|
70
|
+
this.toggleTarget.setAttribute('aria-pressed', 'true')
|
71
|
+
}
|
72
|
+
|
73
|
+
turnOff(): void {
|
74
|
+
if (this.isDisabled()) {
|
75
|
+
return
|
76
|
+
}
|
77
|
+
|
78
|
+
this.toggleTarget.setAttribute('aria-pressed', 'false')
|
79
|
+
}
|
80
|
+
|
81
|
+
isOn(): boolean {
|
82
|
+
return this.toggleTarget.getAttribute('aria-pressed') === 'true'
|
83
|
+
}
|
84
|
+
|
85
|
+
isOff(): boolean {
|
86
|
+
return !this.isOn()
|
87
|
+
}
|
88
|
+
|
89
|
+
isDisabled(): boolean {
|
90
|
+
return this.toggleTarget.getAttribute('disabled') != null
|
91
|
+
}
|
92
|
+
|
93
|
+
private async submitForm() {
|
94
|
+
const body = new FormData()
|
95
|
+
|
96
|
+
const csrfToken = this.documentCsrfToken() || this.csrfTokenValue
|
97
|
+
if (csrfToken) {
|
98
|
+
body.append(this.csrfField(), csrfToken)
|
99
|
+
}
|
100
|
+
|
101
|
+
body.append(this.toggleTarget.name, this.isOn() ? 'true' : 'false')
|
102
|
+
|
103
|
+
if (!this.formUrlValue) throw new Error('invalid src')
|
104
|
+
|
105
|
+
let response
|
106
|
+
|
107
|
+
try {
|
108
|
+
response = await fetch(this.formUrlValue, {
|
109
|
+
credentials: 'same-origin',
|
110
|
+
method: this.formMethodValue,
|
111
|
+
headers: {
|
112
|
+
'Requested-With': 'XMLHttpRequest',
|
113
|
+
},
|
114
|
+
body,
|
115
|
+
})
|
116
|
+
} catch (error) {
|
117
|
+
throw new Error('A network error occurred, please try again.')
|
118
|
+
}
|
119
|
+
|
120
|
+
if (!response.ok) {
|
121
|
+
throw new Error(await response.text())
|
122
|
+
}
|
123
|
+
}
|
124
|
+
|
125
|
+
// the authenticity token is passed into the element and is not generated in js land
|
126
|
+
private csrfField(): string {
|
127
|
+
return this.toggleTarget.getAttribute('csrf-field') || 'authenticity_token'
|
128
|
+
}
|
129
|
+
private documentCsrfToken(): string | null {
|
130
|
+
const meta = document.querySelector('meta[name=csrf-token]')
|
131
|
+
return meta && meta.getAttribute('content')
|
132
|
+
}
|
133
|
+
}
|
@@ -26,6 +26,29 @@ module Ariadne
|
|
26
26
|
|
27
27
|
INTEGER_TYPES = Set.new(["Integer"]).freeze
|
28
28
|
|
29
|
+
def fetch_or_fallback(allowed_values, given_value, fallback = nil, deprecated_values: nil)
|
30
|
+
if allowed_values.include?(given_value)
|
31
|
+
given_value
|
32
|
+
elsif deprecated_values&.include?(given_value)
|
33
|
+
::Ariadne::ViewComponents.deprecation.warn("#{given_value} is deprecated and will be removed in a future version.") unless Rails.env.production? || silence_deprecations?
|
34
|
+
|
35
|
+
given_value
|
36
|
+
else
|
37
|
+
if fallback_raises && ENV["RAILS_ENV"] != "production"
|
38
|
+
raise InvalidValueError, <<~MSG
|
39
|
+
fetch_or_fallback was called with an invalid value.
|
40
|
+
|
41
|
+
Expected one of: #{allowed_values.inspect}
|
42
|
+
Got: #{given_value.inspect}
|
43
|
+
|
44
|
+
This will not raise in production, but will instead fallback to: #{fallback.inspect}
|
45
|
+
MSG
|
46
|
+
end
|
47
|
+
|
48
|
+
fallback
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
29
52
|
def fetch_or_raise(allowed_values, given_value, against: nil)
|
30
53
|
if !allowed_values.is_a?(Array) && !allowed_values.is_a?(Set)
|
31
54
|
raise ArgumentError, "allowed_values must be an array or a set; it was #{allowed_values.class}"
|
@@ -61,6 +61,10 @@ module Ariadne
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
+
initializer "i18n.load_path" do
|
65
|
+
config.i18n.load_path.concat(Dir[Engine.root.join.join("app", "components", "**", "*.yml")])
|
66
|
+
end
|
67
|
+
|
64
68
|
config.after_initialize do |_app|
|
65
69
|
Ariadne::ViewComponents.tailwind_merger = TailwindMerge::Merger.new(config: { prefix: "ariadne-" })
|
66
70
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ariadne_view_components
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.86
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Garen J. Torikian
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-08-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tailwind_merge
|
@@ -157,17 +157,27 @@ files:
|
|
157
157
|
- app/components/ariadne/form/separator/component.rb
|
158
158
|
- app/components/ariadne/form/text_field/component.html.erb
|
159
159
|
- app/components/ariadne/form/text_field/component.rb
|
160
|
+
- app/components/ariadne/form/toggle_group/component.html.erb
|
161
|
+
- app/components/ariadne/form/toggle_group/component.rb
|
162
|
+
- app/components/ariadne/form/toggle_group/option/component.html.erb
|
163
|
+
- app/components/ariadne/form/toggle_group/option/component.rb
|
160
164
|
- app/components/ariadne/form/validation_message/component.html.erb
|
161
165
|
- app/components/ariadne/form/validation_message/component.rb
|
162
166
|
- app/components/ariadne/layout/grid/component.html.erb
|
163
167
|
- app/components/ariadne/layout/grid/component.rb
|
164
168
|
- app/components/ariadne/layout/grid/item/component.html.erb
|
165
169
|
- app/components/ariadne/layout/grid/item/component.rb
|
170
|
+
- app/components/ariadne/layout/label_block/component.html.erb
|
171
|
+
- app/components/ariadne/layout/label_block/component.rb
|
166
172
|
- app/components/ariadne/layout/narrow/component.html.erb
|
167
173
|
- app/components/ariadne/layout/narrow/component.rb
|
168
174
|
- app/components/ariadne/layout/nav_bar/component.css
|
169
175
|
- app/components/ariadne/layout/nav_bar/component.html.erb
|
170
176
|
- app/components/ariadne/layout/nav_bar/component.rb
|
177
|
+
- app/components/ariadne/layout/section_block/component.html.erb
|
178
|
+
- app/components/ariadne/layout/section_block/component.rb
|
179
|
+
- app/components/ariadne/layout/section_block/header/component.html.erb
|
180
|
+
- app/components/ariadne/layout/section_block/header/component.rb
|
171
181
|
- app/components/ariadne/layout/two_panel/component.html.erb
|
172
182
|
- app/components/ariadne/layout/two_panel/component.rb
|
173
183
|
- app/components/ariadne/layout/wide/component.html.erb
|
@@ -181,12 +191,16 @@ files:
|
|
181
191
|
- app/components/ariadne/ui/accordion/component.ts
|
182
192
|
- app/components/ariadne/ui/accordion/item/component.html.erb
|
183
193
|
- app/components/ariadne/ui/accordion/item/component.rb
|
194
|
+
- app/components/ariadne/ui/avatar/component.html.erb
|
195
|
+
- app/components/ariadne/ui/avatar/component.rb
|
184
196
|
- app/components/ariadne/ui/badge/component.html.erb
|
185
197
|
- app/components/ariadne/ui/badge/component.rb
|
186
198
|
- app/components/ariadne/ui/blankslate/component.html.erb
|
187
199
|
- app/components/ariadne/ui/blankslate/component.rb
|
188
200
|
- app/components/ariadne/ui/button/component.html.erb
|
189
201
|
- app/components/ariadne/ui/button/component.rb
|
202
|
+
- app/components/ariadne/ui/card/body/component.html.erb
|
203
|
+
- app/components/ariadne/ui/card/body/component.rb
|
190
204
|
- app/components/ariadne/ui/card/component.html.erb
|
191
205
|
- app/components/ariadne/ui/card/component.rb
|
192
206
|
- app/components/ariadne/ui/card/footer/component.html.erb
|
@@ -220,11 +234,17 @@ files:
|
|
220
234
|
- app/components/ariadne/ui/overlay/component.html.erb
|
221
235
|
- app/components/ariadne/ui/overlay/component.rb
|
222
236
|
- app/components/ariadne/ui/overlay/component.ts
|
237
|
+
- app/components/ariadne/ui/pagination/component.html.erb
|
238
|
+
- app/components/ariadne/ui/pagination/component.rb
|
223
239
|
- app/components/ariadne/ui/popover/component.html.erb
|
224
240
|
- app/components/ariadne/ui/popover/component.rb
|
225
241
|
- app/components/ariadne/ui/popover/component.ts
|
226
242
|
- app/components/ariadne/ui/skeleton/component.html.erb
|
227
243
|
- app/components/ariadne/ui/skeleton/component.rb
|
244
|
+
- app/components/ariadne/ui/stats_panel/component.html.erb
|
245
|
+
- app/components/ariadne/ui/stats_panel/component.rb
|
246
|
+
- app/components/ariadne/ui/stats_panel/item/component.html.erb
|
247
|
+
- app/components/ariadne/ui/stats_panel/item/component.rb
|
228
248
|
- app/components/ariadne/ui/table/cell/component.html.erb
|
229
249
|
- app/components/ariadne/ui/table/cell/component.rb
|
230
250
|
- app/components/ariadne/ui/table/component.html.erb
|
@@ -235,6 +255,12 @@ files:
|
|
235
255
|
- app/components/ariadne/ui/table/header/component.rb
|
236
256
|
- app/components/ariadne/ui/table/row/component.html.erb
|
237
257
|
- app/components/ariadne/ui/table/row/component.rb
|
258
|
+
- app/components/ariadne/ui/time_ago/component.html.erb
|
259
|
+
- app/components/ariadne/ui/time_ago/component.rb
|
260
|
+
- app/components/ariadne/ui/time_ago/en.yml
|
261
|
+
- app/components/ariadne/ui/toggle/component.html.erb
|
262
|
+
- app/components/ariadne/ui/toggle/component.rb
|
263
|
+
- app/components/ariadne/ui/toggle/component.ts
|
238
264
|
- app/components/ariadne/ui/typography/component.html.erb
|
239
265
|
- app/components/ariadne/ui/typography/component.rb
|
240
266
|
- app/frontend/ariadne/index.ts
|