ariadne_view_components 0.0.80.3 → 0.0.82

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/app/assets/javascripts/ariadne_view_components.js +14 -14
  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 +5 -1
  11. data/app/components/ariadne/form/checkbox/component.html.erb +21 -5
  12. data/app/components/ariadne/form/checkbox/component.rb +36 -0
  13. data/app/components/ariadne/form/group/component.html.erb +0 -2
  14. data/app/components/ariadne/form/group/component.rb +4 -1
  15. data/app/components/ariadne/form/text_field/component.rb +26 -23
  16. data/app/components/ariadne/ui/badge/component.rb +12 -17
  17. data/app/components/ariadne/ui/button/component.rb +1 -0
  18. data/app/components/ariadne/ui/combobox/component.html.erb +5 -17
  19. data/app/components/ariadne/ui/combobox/component.rb +8 -28
  20. data/app/components/ariadne/ui/combobox/component.ts +24 -39
  21. data/app/components/ariadne/ui/dialog/component.rb +18 -2
  22. data/app/components/ariadne/ui/flash/component.html.erb +11 -11
  23. data/app/components/ariadne/ui/flash/component.rb +30 -12
  24. data/app/components/ariadne/ui/link/component.rb +21 -5
  25. data/app/components/ariadne/ui/list/component.html.erb +28 -4
  26. data/app/components/ariadne/ui/list/component.rb +119 -1
  27. data/app/components/ariadne/ui/list/component.ts +57 -0
  28. data/app/components/ariadne/ui/popover/component.html.erb +4 -4
  29. data/app/components/ariadne/ui/popover/component.rb +3 -1
  30. data/app/components/ariadne/ui/popover/component.ts +1 -1
  31. data/app/components/ariadne/ui/typography/component.rb +19 -0
  32. data/app/frontend/ariadne/stimulus_app.ts +2 -2
  33. data/app/frontend/controllers/{autosubmittable_controller.ts → form_autosubmit_controller.ts} +1 -2
  34. data/app/lib/ariadne/view_component/style_variants.rb +50 -0
  35. data/lib/ariadne/forms/dsl/badge.rb +2 -2
  36. data/lib/ariadne/forms/dsl/button_input.rb +2 -1
  37. data/lib/ariadne/forms/dsl/clipboard_copy_button.rb +34 -0
  38. data/lib/ariadne/forms/dsl/input_methods.rb +4 -0
  39. data/lib/ariadne/view_components/version.rb +1 -1
  40. metadata +5 -9
  41. data/app/components/ariadne/ui/combobox/item/component.html.erb +0 -9
  42. data/app/components/ariadne/ui/combobox/item/component.rb +0 -61
  43. data/app/components/ariadne/ui/combobox/option/component.html.erb +0 -11
  44. data/app/components/ariadne/ui/combobox/option/component.rb +0 -44
  45. data/app/components/ariadne/ui/list/item/component.html.erb +0 -16
  46. data/app/components/ariadne/ui/list/item/component.rb +0 -17
@@ -1,13 +1,14 @@
1
1
  import {type Placement, autoUpdate, computePosition, flip, offset, shift, size} from '@floating-ui/dom'
2
+ import DetailsMenuElement from '@github/details-menu-element'
2
3
  import {controllerFactory} from '@utils/createController'
3
4
  import {useClickOutside, useMutation} from 'stimulus-use'
4
5
 
5
6
  export default class ComboboxController extends controllerFactory<HTMLDetailsElement>()({
6
7
  targets: {
7
- anchor: null,
8
- options: null,
9
- popover: null,
10
- searchInput: HTMLInputElement,
8
+ wrapper: HTMLDetailsElement,
9
+ button: HTMLElement,
10
+ popover: DetailsMenuElement,
11
+ options: HTMLDivElement,
11
12
  },
12
13
  values: {
13
14
  clamped: Boolean,
@@ -15,35 +16,8 @@ export default class ComboboxController extends controllerFactory<HTMLDetailsEle
15
16
  },
16
17
  }) {
17
18
  private changedIds = new Set<string>()
18
- private clickHandlers: Array<() => void> = []
19
- labels: Array<{el: HTMLLabelElement; searchString: string}>
20
19
  unsubAutoUpdate: (() => void) | undefined
21
20
 
22
- private setupClickHandlers() {
23
- const cb = () => this.toggle()
24
-
25
- for (const fn of this.clickHandlers) {
26
- fn()
27
- }
28
- this.clickHandlers = []
29
-
30
- for (const el of this.anchorTarget.querySelectorAll('button, [tabindex]:not([tabindex="-1"])')) {
31
- el.addEventListener('click', cb)
32
- this.clickHandlers.push(() => el.removeEventListener('click', cb))
33
- }
34
- }
35
-
36
- checkboxClicked(e: Event) {
37
- const target = e.target as HTMLInputElement
38
- const value = target.value
39
- if (this.changedIds.has(value)) {
40
- this.changedIds.delete(value)
41
- } else {
42
- this.changedIds.add(value)
43
- }
44
- this.dispatch('clicked', {detail: value})
45
- }
46
-
47
21
  clickOutside() {
48
22
  this.element.open = false
49
23
  this.setupAutoUpdate()
@@ -51,7 +25,6 @@ export default class ComboboxController extends controllerFactory<HTMLDetailsEle
51
25
  }
52
26
 
53
27
  close() {
54
- if (this.hasSearchInputTarget) this.searchInputTarget.value = ''
55
28
  if (this.changedIds.size > 0) {
56
29
  this.dispatch('changed')
57
30
  this.changedIds.clear()
@@ -62,13 +35,28 @@ export default class ComboboxController extends controllerFactory<HTMLDetailsEle
62
35
  useClickOutside(this)
63
36
  useMutation(this, {childList: true, subtree: true})
64
37
  this.setupAutoUpdate()
65
- this.setupClickHandlers()
38
+ this.setupForm()
66
39
  }
67
40
 
68
41
  disconnect() {
69
42
  this.unsubAutoUpdate?.()
70
43
  }
71
44
 
45
+ setupForm(): void {
46
+ // https://github.com/github/details-menu-element?tab=readme-ov-file#markup
47
+ for (const checkbox of this.popoverTarget.querySelectorAll('input[type="checkbox"]')) {
48
+ checkbox.addEventListener('change', (e: {target: HTMLInputElement}) => {
49
+ const value = e.target as HTMLInputElement
50
+ if (this.changedIds.has(value)) {
51
+ this.changedIds.delete(value)
52
+ } else {
53
+ this.changedIds.add(value)
54
+ }
55
+ this.dispatch('clicked', {detail: value})
56
+ })
57
+ }
58
+ }
59
+
72
60
  setupAutoUpdate(): void {
73
61
  if (!this.element.open) {
74
62
  this.unsubAutoUpdate?.()
@@ -77,19 +65,16 @@ export default class ComboboxController extends controllerFactory<HTMLDetailsEle
77
65
 
78
66
  const updatePopoverPosition = (): void => {
79
67
  const options = this.optionsTarget
80
- const searchInput = this.hasSearchInputTarget ? this.searchInputTarget : null
81
68
  const shouldClamp = this.clampedValue
82
69
 
83
- void computePosition(this.anchorTarget, this.popoverTarget, {
70
+ void computePosition(this.buttonTarget, this.popoverTarget, {
84
71
  middleware: [
85
72
  offset(6),
86
73
  flip(),
87
74
  shift({padding: 6}),
88
75
  size({
89
76
  apply({availableHeight}) {
90
- const inputHeight = searchInput ? searchInput.getBoundingClientRect().height : 0
91
-
92
- let maxHeight = availableHeight - inputHeight - 6
77
+ let maxHeight = availableHeight - 6
93
78
  if (shouldClamp && maxHeight > 400) maxHeight = 400
94
79
 
95
80
  Object.assign(options.style, {
@@ -109,7 +94,7 @@ export default class ComboboxController extends controllerFactory<HTMLDetailsEle
109
94
  }
110
95
 
111
96
  updatePopoverPosition()
112
- this.unsubAutoUpdate = autoUpdate(this.anchorTarget, this.popoverTarget, updatePopoverPosition)
97
+ this.unsubAutoUpdate = autoUpdate(this.buttonTarget, this.popoverTarget, updatePopoverPosition)
113
98
  }
114
99
 
115
100
  toggle(): void {
@@ -8,6 +8,7 @@ module Ariadne
8
8
  option :title
9
9
  option :trigger_close_label
10
10
  option :description, optional: true
11
+ option :width, default: proc { :base }
11
12
 
12
13
  renders_one :trigger
13
14
  renders_one :footer
@@ -18,8 +19,6 @@ module Ariadne
18
19
  base do
19
20
  [
20
21
  "ariadne-fixed",
21
- "ariadne-w-96",
22
- "ariadne-max-w-[90vw]",
23
22
  "ariadne-max-h-[90-vh]",
24
23
  "ariadne-shadow-xl",
25
24
  "ariadne-rounded-2xl",
@@ -31,6 +30,23 @@ module Ariadne
31
30
  "backdrop:dark:ariadne-bg-zinc-100/20",
32
31
  ]
33
32
  end
33
+ variants do
34
+ width do
35
+ base do
36
+ [
37
+ "ariadne-w-96",
38
+ "ariadne-max-w-[90vw]",
39
+ ]
40
+ end
41
+
42
+ wide do
43
+ [
44
+ "ariadne-w-3/5",
45
+ "ariadne-max-w-[90vw]",
46
+ ]
47
+ end
48
+ end
49
+ end
34
50
  end
35
51
  end
36
52
  end
@@ -1,18 +1,18 @@
1
1
  <div class="<%= html_attrs[:class] %>" <%= html_attributes %>>
2
- <div class="ariadne-p-4">
2
+ <div class="ariadne-p-4">
3
3
  <div class="ariadne-flex ariadne-items-start">
4
- <div class="ariadne-flex-shrink-0 <%= style(:text, type:) %>">
4
+ <div class="ariadne-flex-shrink-0 <%= style(:text, type:) %>">
5
5
  <%= icon %>
6
- </div>
7
- <div class="ariadne-ml-3 ariadne-w-0 ariadne-flex-1 ariadne-pt-0.5 <%= style(:text, type:) %>">
8
- <p class="ariadne-text-sm ariadne-font-semibold "><%= title %></p>
9
- <p class="ariadne-mt-1 ariadne-text-sm "><%= message %></p>
10
- </div>
11
- <div class="ariadne-ml-4 ariadne-flex ariadne-flex-shrink-0 ">
6
+ </div>
7
+ <div class="ariadne-ml-3 ariadne-w-0 ariadne-flex-1 ariadne-pt-0.5 <%= style(:text, type:) %>">
8
+ <p class="ariadne-text-sm ariadne-font-semibold" data-flash-target="title"><%= title %></p>
9
+ <p class="ariadne-mt-1 ariadne-text-sm" data-flash-target="message"><%= message %></p>
10
+ </div>
11
+ <div class="ariadne-ml-4 ariadne-flex ariadne-flex-shrink-0 ">
12
12
  <% if dismissable? %>
13
- <%= render Ariadne::UI::Button::Component.new(theme: :nude, html_attrs: { class: style(:dismissable, type:), aria: { label: "close_label" }, data: { action: "click->#{stimulus_name}#hide" } }).as_icon(icon: "x-mark", variant: :outline) %>
13
+ <%= render Ariadne::UI::Button::Component.new(theme: :nude, html_attrs: { class: style(:dismissable, type:), aria: { label: "close_label" }, data: { action: "click->#{stimulus_name}#hide" } }).as_icon(icon: "x-mark", variant: :outline) %>
14
14
  <% end %>
15
+ </div>
15
16
  </div>
16
- </div>
17
- </div>
17
+ </div>
18
18
  </div>
@@ -9,20 +9,25 @@ module Ariadne
9
9
  option :dismissible, default: proc { false }
10
10
  option :title
11
11
  option :message
12
+ option :persist, default: proc { false }
13
+ option :width, default: proc { :base }
12
14
 
13
15
  accepts_html_attributes do |html_attrs|
14
- html_attrs[:data] = {
15
- controller: "flash",
16
- transition_enter: "ariadne-transform ariadne-ease-out ariadne-duration-300 ariadne-transition-all",
17
- transition_enter_start: "ariadne-translate-y-2 ariadne-opacity-0 sm:ariadne-translate-y-0 sm:ariadne-translate-x-2",
18
- transition_enter_end: "ariadne-translate-y-0 ariadne-opacity-100 sm:ariadne-translate-x-0",
19
- transition_leave: "ariadne-transition-all ariadne-ease-in ariadne-duration-100",
20
- transition_leave_start: "ariadne-opacity-100",
21
- transition_leave_end: "ariadne-opacity-0",
22
- }
16
+ unless persist
17
+ html_attrs[:data] = {
18
+ controller: "flash",
19
+ transition_enter: "ariadne-transform ariadne-ease-out ariadne-duration-300 ariadne-transition-all",
20
+ transition_enter_start: "ariadne-translate-y-2 ariadne-opacity-0 sm:ariadne-translate-y-0 sm:ariadne-translate-x-2",
21
+ transition_enter_end: "ariadne-translate-y-0 ariadne-opacity-100 sm:ariadne-translate-x-0",
22
+ transition_leave: "ariadne-transition-all ariadne-ease-in ariadne-duration-100",
23
+ transition_leave_start: "ariadne-opacity-100",
24
+ transition_leave_end: "ariadne-opacity-0",
25
+ }
26
+ end
27
+
23
28
  html_attrs[:class] = Ariadne::ViewComponents.tailwind_merger.merge([
24
29
  html_attrs[:class],
25
- style(type:),
30
+ style(type:, width:),
26
31
  ])
27
32
  end
28
33
 
@@ -36,8 +41,6 @@ module Ariadne
36
41
  base do
37
42
  [
38
43
  "ariadne-pointer-events-auto",
39
- "ariadne-w-full",
40
- "ariadne-max-w-sm",
41
44
  "ariadne-overflow-hidden",
42
45
  "ariadne-rounded-lg",
43
46
  "ariadne-shadow-lg",
@@ -49,6 +52,21 @@ module Ariadne
49
52
  end
50
53
 
51
54
  variants do
55
+ width do
56
+ base do
57
+ [
58
+ "ariadne-w-full",
59
+ "ariadne-max-w-sm",
60
+ ]
61
+ end
62
+
63
+ full do
64
+ [
65
+ "ariadne-w-full",
66
+ ]
67
+ end
68
+ end
69
+
52
70
  type do
53
71
  danger do
54
72
  [
@@ -32,20 +32,36 @@ module Ariadne
32
32
  theme do
33
33
  base do
34
34
  [
35
+ "ariadne-text-indigo-600",
36
+ "dark:ariadne-text-indigo-400",
37
+
35
38
  "[&>svg]:ariadne-text-zinc-400",
36
39
  "[&>svg]:dark:ariadne-text-zinc-600",
37
- "hover:ariadne-text-indigo-600",
38
- "dark:hover:ariadne-text-indigo-400",
40
+
41
+ "hover:ariadne-text-indigo-500",
42
+ "dark:hover:ariadne-text-indigo-300",
43
+ "hover:ariadne-border-indigo-500",
44
+ "dark:hover:ariadne-border-indigo-300",
45
+ "focus:ariadne-text-indigo-500",
46
+ "dark:focus:ariadne-text-indigo-300",
47
+ "focus:!ariadne-border-transparent",
48
+ "active:ariadne-bg-indigo-700/10",
49
+ "active:dark:ariadne-bg-indigo-300/10",
50
+ ]
51
+ end
52
+
53
+ nude do
54
+ [
39
55
  "hover:ariadne-border-indigo-600",
40
56
  "dark:hover:ariadne-border-indigo-400",
41
- "focus:ariadne-text-indigo-600",
42
- "dark:focus:ariadne-text-indigo-400",
57
+ "focus:ariadne-text-indigo-500",
58
+ "dark:focus:ariadne-text-indigo-300",
43
59
  "focus:!ariadne-border-transparent",
44
60
  "active:ariadne-bg-indigo-700/10",
45
61
  "active:dark:ariadne-bg-indigo-300/10",
46
62
  ]
47
63
  end
48
- nude { "" }
64
+
49
65
  thick { "ariadne-font-semibold" }
50
66
  end
51
67
  size do
@@ -1,6 +1,30 @@
1
-
2
- <ol class="ariadne-divide-y ariadne-divide-zinc-100 dark:ariadne-divide-zinc-800">
1
+ <div class="<%= html_attrs[:class] %>" <%= html_attributes %>>
2
+ <% if filter_field? %>
3
+ <div class="ariadne-pb-1.5 ariadne-px-1">
4
+ <%= render filter_field %>
5
+ </div>
6
+ <% end %>
7
+ <div class="<%= style(:items) %>">
8
+ <% links.each do |link| %>
9
+ <div class="" role="menuitem"><%= link %></div>
10
+ <% end %>
11
+ <% checkboxes.each do |checkbox| %>
12
+ <div
13
+ class="<%= style(:item) %>"
14
+ data-<%= stimulus_name %>-target="searchString">
15
+ <div class="ariadne-truncate" role="menuitemcheckbox"><%= checkbox %></div>
16
+ </div>
17
+ <% end %>
3
18
  <% items.each do |item| %>
4
- <li><%= item %></li>
19
+ <div
20
+ <%= 'role="menuitem"' if as_menu %>
21
+ class="<%= style(:item) %>"
22
+ data-<%= stimulus_name %>-target="searchString">
23
+ <div class="ariadne-relative ariadne-flex ariadne-cursor-default ariadne-select-none ariadne-items-center ariadne-rounded-sm ariadne-px-2 ariadne-py-1.5 ariadne-text-sm ariadne-outline-none ariadne-data-[disabled=true]:pointer-events-none ariadne-data-[selected=true]:bg-accent ariadne-data-[selected=true]:text-accent-foreground data-[disabled=true]:ariadne-opacity-50"><%= item %></div>
24
+ </div>
5
25
  <% end %>
6
- </ol>
26
+ <div class="ariadne-text-center ariadne-hidden" data-<%= stimulus_name %>-target="emptyRoot">
27
+ <span class="ariadne-py-3 ariadne-text-md ariadne-text-zinc-600 dark:ariadne-text-zinc-400"><%= @empty_placeholder %> </span>
28
+ </div>
29
+ </div>
30
+ </div>
@@ -5,7 +5,125 @@ module Ariadne
5
5
  module UI
6
6
  module List
7
7
  class Component < Ariadne::BaseComponent
8
- renders_many :items, Ariadne::UI::List::Item::Component
8
+ option :as_menu, default: proc { false }
9
+
10
+ option :size, default: proc { :md }
11
+
12
+ renders_one :filter_field, lambda { |**options|
13
+ raise ArgumentError, "Must provide text for `empty_placeholder`" if options[:empty_placeholder].blank?
14
+
15
+ @empty_placeholder = options.delete(:empty_placeholder)
16
+
17
+ options.delete(:size)
18
+ options[:theme] = :nude
19
+ options[:width] = :full
20
+ options[:name] = "search"
21
+ options[:label] = ""
22
+
23
+ options[:html_attrs] ||= {}
24
+ options[:html_attrs].merge!({
25
+ autocomplete: "off",
26
+ autofocus: true,
27
+ type: "search",
28
+ data: {
29
+ "#{stimulus_name}-target": "input",
30
+ action: "#{stimulus_name}#handleInput",
31
+ },
32
+ })
33
+
34
+ Ariadne::Form::TextField::Component.new(**options)
35
+ }
36
+
37
+ renders_many :checkboxes, Ariadne::Form::Checkbox::Component
38
+ renders_many :radio_buttons, Ariadne::Form::RadioButton::Component
39
+ renders_many :links, lambda { |**options|
40
+ options[:theme] = :nude
41
+ options[:"data-#{stimulus_name}-target"] = "searchString"
42
+
43
+ options[:html_attrs] ||= {}
44
+ options[:html_attrs][:class] ||= ""
45
+ options[:html_attrs][:class] = [
46
+ "ariadne-truncate",
47
+ "ariadne-border-b-0",
48
+ "ariadne-flex",
49
+ "ariadne-gap-0.5",
50
+ "ariadne-items-center",
51
+ "ariadne-ps-2",
52
+ "ariadne-pe-1",
53
+ "ariadne-rounded",
54
+ "!ariadne-ring-0",
55
+ "hover:ariadne-bg-zinc-100",
56
+ "hover:dark:ariadne-bg-zinc-800",
57
+ "focus-within:ariadne-bg-zinc-100",
58
+ "focus-within:dark:ariadne-bg-zinc-800",
59
+ "ariadne-cursor-pointer",
60
+ options[:html_attrs][:class],
61
+ ]
62
+
63
+ Ariadne::UI::Link::Component.new(**options)
64
+ }
65
+
66
+ renders_many :items, BaseComponent::ACCEPT_ANYTHING
67
+
68
+ accepts_html_attributes do |html_attrs|
69
+ html_attrs[:class] = Ariadne::ViewComponents.tailwind_merger.merge([style, html_attrs[:class]].join(" "))
70
+ html_attrs[:data] = {
71
+ controller: stimulus_name,
72
+ }
73
+ end
74
+
75
+ style do
76
+ base do
77
+ [
78
+ "ariadne-overflow-y-auto",
79
+ ]
80
+ end
81
+
82
+ variants do
83
+ size do
84
+ sm { "ariadne-w-36" }
85
+ md { "ariadne-w-52" }
86
+ lg { "ariadne-w-96" }
87
+ full { "ariadne-w-full" }
88
+ end
89
+ end
90
+ end
91
+
92
+ style :items do
93
+ base do
94
+ [
95
+ "ariadne-flex",
96
+ "ariadne-flex-col",
97
+ "ariadne-grow",
98
+ ]
99
+ end
100
+ end
101
+
102
+ style :item do
103
+ base do
104
+ [
105
+ # "ariadne-gap-0.5",
106
+ "ariadne-items-center",
107
+ "ariadne-rounded",
108
+ "!ariadne-ring-0",
109
+ "hover:ariadne-bg-zinc-100",
110
+ "hover:dark:ariadne-bg-zinc-800",
111
+ "focus-within:ariadne-bg-zinc-100",
112
+ "focus-within:dark:ariadne-bg-zinc-800",
113
+ "ariadne-cursor-default",
114
+ "ariadne-select-none",
115
+ "ariadne-items-center",
116
+ "ariadne-rounded-sm",
117
+ "ariadne-px-2",
118
+ # "ariadne-py-1.5",
119
+ "ariadne-text-sm",
120
+ "ariadne-outline-none",
121
+ "ariadne-transition-colors",
122
+ "disabled:ariadne-pointer-events-none",
123
+ "disabled:ariadne-opacity-50",
124
+ ]
125
+ end
126
+ end
9
127
  end
10
128
  end
11
129
  end
@@ -0,0 +1,57 @@
1
+ import {controllerFactory} from '@utils/createController'
2
+ import {useIntersection} from 'stimulus-use'
3
+
4
+ export default class InputFilterController extends controllerFactory()({
5
+ targets: {
6
+ emptyRoot: null,
7
+ input: HTMLInputElement,
8
+ searchString: null,
9
+ },
10
+ }) {
11
+ private items: {el: HTMLElement; searchString: string}[]
12
+
13
+ private handleNewQuery(query: string) {
14
+ let foundSomething = false
15
+
16
+ for (const {el, searchString} of this.items) {
17
+ const contains = searchString.includes(query.trim().toLowerCase())
18
+
19
+ if (!foundSomething && contains) foundSomething = true
20
+
21
+ if (contains) {
22
+ el.classList.remove('ariadne-hidden')
23
+ } else {
24
+ el.classList.add('ariadne-hidden')
25
+ }
26
+ }
27
+
28
+ if (foundSomething) {
29
+ this.emptyRootTarget.classList.add('ariadne-hidden')
30
+ } else {
31
+ this.emptyRootTarget.classList.remove('ariadne-hidden')
32
+ }
33
+ }
34
+
35
+ connect() {
36
+ this.items = this.searchStringTargets.map((el: HTMLElement) => {
37
+ return {
38
+ el,
39
+ searchString: (el.textContent ?? '').trim().toLowerCase(),
40
+ }
41
+ })
42
+ useIntersection(this)
43
+ }
44
+
45
+ appear(entry, observer) {
46
+ this.reset()
47
+ }
48
+
49
+ handleInput() {
50
+ if (this.hasSearchStringTarget) this.handleNewQuery(this.inputTarget.value)
51
+ }
52
+
53
+ reset() {
54
+ this.handleNewQuery('')
55
+ if (this.hasInputTarget) this.inputTarget.value = ''
56
+ }
57
+ }
@@ -1,6 +1,6 @@
1
1
  <div data-controller="<%= @stimulus_controllers %>">
2
- <%= button %>
3
- <div class="<%= html_attrs[:class] %>" <%= html_attributes %>>
4
- <%= content %>
5
- </div>
2
+ <%= button %>
3
+ <div class="<%= html_attrs[:class] %>" <%= html_attributes %>>
4
+ <%= content %>
5
+ </div>
6
6
  </div>
@@ -28,7 +28,7 @@ module Ariadne
28
28
 
29
29
  options[:html_attrs][:data] ||= {}
30
30
  options[:html_attrs][:data] = {
31
- "#{stimulus_name}-target" => ["toggle", html_attrs.fetch(:data, {}).fetch(:target, nil)].compact.join(" "),
31
+ "#{stimulus_name}-target" => ["button", html_attrs.fetch(:data, {}).fetch(:target, nil)].compact.join(" "),
32
32
  }.merge(options[:html_attrs][:data])
33
33
 
34
34
  Ariadne::UI::Button::Component.new(**options)
@@ -38,6 +38,8 @@ module Ariadne
38
38
  html_attrs[:id] ||= target_id
39
39
  html_attrs[:popover] = ""
40
40
 
41
+ html_attrs[:class] = Ariadne::ViewComponents.tailwind_merger.merge([style, html_attrs[:class]].join(" "))
42
+
41
43
  # requires CSS Anchor Positioning
42
44
  # as a `style` to account for future feature where the popover can be moved
43
45
  # html_attrs[:style] = "inset: unset; top: anchor(--popover-#{target_id} bottom); right: anchor(--popover-#{target_id} left, -1rem);"
@@ -24,7 +24,7 @@ export default class PopoverController extends controllerFactory()({
24
24
  placement: this.placementValue,
25
25
  middleware: [offset(5), flip(), shift({padding: 5})],
26
26
  }).then(({x, y}) => {
27
- Object.assign(this.target.style, {
27
+ Object.assign(this.buttonTarget.style, {
28
28
  left: `${x}px`,
29
29
  top: `${y}px`,
30
30
  })
@@ -25,8 +25,12 @@ module Ariadne
25
25
  :h3
26
26
  when :ann
27
27
  :h4
28
+ when :label
29
+ :h5
28
30
  when :lede
29
31
  :p
32
+ when :text
33
+ :p
30
34
  when :code
31
35
  :code
32
36
  else
@@ -110,6 +114,18 @@ module Ariadne
110
114
  ]
111
115
  end
112
116
 
117
+ label do
118
+ [
119
+ "ariadne-justify-between",
120
+ "ariadne-whitespace-nowrap",
121
+ "ariadne-text-sm",
122
+ "ariadne-font-medium",
123
+ "ariadne-uppercase",
124
+ "ariadne-text-zinc-600",
125
+ "dark:ariadne-text-zinc-400",
126
+ ]
127
+ end
128
+
113
129
  code do
114
130
  [
115
131
  "ariadne-relative",
@@ -128,6 +144,9 @@ module Ariadne
128
144
  "ariadne-text-muted-foreground",
129
145
  ]
130
146
  end
147
+
148
+ text do
149
+ end
131
150
  end
132
151
  end
133
152
  end
@@ -40,8 +40,8 @@ for (const [path, module] of Object.entries(controllerModules)) {
40
40
  const dirs = path.split('/')
41
41
 
42
42
  // Dropping ../controllers to end up
43
- // with something like "ariadne-component-name"
44
- const name = dirs.slice(2, dirs.length).join('-').replace('.ts', '').replaceAll('_', '-').toLocaleLowerCase()
43
+ // with something like "ariadne-controllername"
44
+ const name = dirs[dirs.length - 1].replace('_controller.ts', '').replaceAll('_', '-').toLocaleLowerCase()
45
45
 
46
46
  application.register(
47
47
  // @tag stimulus-id
@@ -2,8 +2,7 @@ import {Controller} from '@hotwired/stimulus'
2
2
 
3
3
  import {useDebounce} from 'stimulus-use'
4
4
 
5
- // can't use controllerFactory because it seems to conflict with `useDebounce`
6
- export default class AutoSubmittableController extends Controller<HTMLFormElement> {
5
+ export default class FormAutosubmitController extends Controller<HTMLFormElement> {
7
6
  static debounces = ['save']
8
7
  static targets = ['form']
9
8
  declare readonly formTarget: HTMLFormElement