ariadne_view_components 0.0.84 → 0.0.86

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/app/assets/javascripts/ariadne_view_components.js +7 -7
  4. data/app/assets/javascripts/ariadne_view_components.js.br +0 -0
  5. data/app/assets/javascripts/ariadne_view_components.js.gz +0 -0
  6. data/app/assets/javascripts/ariadne_view_components.js.map +1 -1
  7. data/app/assets/stylesheets/ariadne_view_components.css +1 -1
  8. data/app/assets/stylesheets/ariadne_view_components.css.br +0 -0
  9. data/app/assets/stylesheets/ariadne_view_components.css.gz +0 -0
  10. data/app/components/ariadne/base_component.rb +15 -5
  11. data/app/components/ariadne/form/base_component.rb +1 -1
  12. data/app/components/ariadne/form/checkbox/component.html.erb +1 -1
  13. data/app/components/ariadne/form/checkbox/component.rb +15 -3
  14. data/app/components/ariadne/form/radio_button/component.html.erb +1 -3
  15. data/app/components/ariadne/form/select/component.html.erb +4 -2
  16. data/app/components/ariadne/form/select/component.rb +50 -2
  17. data/app/components/ariadne/form/toggle_group/component.html.erb +7 -0
  18. data/app/components/ariadne/form/toggle_group/component.rb +35 -0
  19. data/app/components/ariadne/form/toggle_group/option/component.html.erb +8 -0
  20. data/app/components/ariadne/form/toggle_group/option/component.rb +46 -0
  21. data/app/components/ariadne/layout/label_block/component.html.erb +12 -0
  22. data/app/components/ariadne/layout/label_block/component.rb +39 -0
  23. data/app/components/ariadne/layout/nav_bar/component.rb +4 -4
  24. data/app/components/ariadne/layout/section_block/component.html.erb +4 -0
  25. data/app/components/ariadne/layout/section_block/component.rb +12 -0
  26. data/app/components/ariadne/layout/section_block/header/component.html.erb +4 -0
  27. data/app/components/ariadne/layout/section_block/header/component.rb +14 -0
  28. data/app/components/ariadne/ui/avatar/component.html.erb +7 -0
  29. data/app/components/ariadne/ui/avatar/component.rb +54 -0
  30. data/app/components/ariadne/ui/badge/component.rb +8 -0
  31. data/app/components/ariadne/ui/card/body/component.html.erb +3 -0
  32. data/app/components/ariadne/ui/card/body/component.rb +25 -0
  33. data/app/components/ariadne/ui/card/component.html.erb +2 -6
  34. data/app/components/ariadne/ui/card/component.rb +1 -0
  35. data/app/components/ariadne/ui/combobox/component.rb +2 -0
  36. data/app/components/ariadne/ui/list/component.html.erb +2 -2
  37. data/app/components/ariadne/ui/list/component.rb +4 -3
  38. data/app/components/ariadne/ui/pagination/component.html.erb +29 -0
  39. data/app/components/ariadne/ui/pagination/component.rb +30 -0
  40. data/app/components/ariadne/ui/stats_panel/component.html.erb +7 -0
  41. data/app/components/ariadne/ui/stats_panel/component.rb +12 -0
  42. data/app/components/ariadne/ui/stats_panel/item/component.html.erb +4 -0
  43. data/app/components/ariadne/ui/stats_panel/item/component.rb +27 -0
  44. data/app/components/ariadne/ui/time_ago/component.html.erb +1 -0
  45. data/app/components/ariadne/ui/time_ago/component.rb +155 -0
  46. data/app/components/ariadne/ui/time_ago/en.yml +12 -0
  47. data/app/components/ariadne/ui/toggle/component.html.erb +7 -0
  48. data/app/components/ariadne/ui/toggle/component.rb +124 -0
  49. data/app/components/ariadne/ui/toggle/component.ts +133 -0
  50. data/app/lib/ariadne/fetch_or_fallback_helper.rb +23 -0
  51. data/lib/ariadne/view_components/engine.rb +4 -0
  52. data/lib/ariadne/view_components/version.rb +1 -1
  53. 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
@@ -3,6 +3,6 @@
3
3
  # :nocov:
4
4
  module Ariadne
5
5
  module ViewComponents
6
- VERSION = "0.0.84"
6
+ VERSION = "0.0.86"
7
7
  end
8
8
  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.84
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-07-12 00:00:00.000000000 Z
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