ariadne_view_components 0.0.13-x86_64-darwin → 0.0.14-x86_64-darwin

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/ariadne_view_components.js +2 -2
  3. data/app/assets/javascripts/ariadne_view_components.js.map +1 -1
  4. data/app/assets/javascripts/comment-component.d.ts +1 -2
  5. data/app/assets/stylesheets/ariadne_view_components.css +1 -0
  6. data/app/assets/stylesheets/dropdown.css +46 -0
  7. data/app/assets/stylesheets/tooltip-component.css +8 -8
  8. data/app/components/ariadne/ariadne.ts +0 -2
  9. data/app/components/ariadne/avatar_component.rb +81 -0
  10. data/app/components/ariadne/avatar_stack_component.html.erb +12 -0
  11. data/app/components/ariadne/avatar_stack_component.rb +75 -0
  12. data/app/components/ariadne/base_button.rb +13 -4
  13. data/app/components/ariadne/blankslate_component.rb +4 -4
  14. data/app/components/ariadne/button_component.html.erb +1 -1
  15. data/app/components/ariadne/button_component.rb +9 -3
  16. data/app/components/ariadne/comment-component.ts +32 -50
  17. data/app/components/ariadne/comment_component.html.erb +32 -10
  18. data/app/components/ariadne/comment_component.rb +17 -5
  19. data/app/components/ariadne/details_component.html.erb +4 -0
  20. data/app/components/ariadne/details_component.rb +80 -0
  21. data/app/components/ariadne/dropdown/menu_component.html.erb +20 -0
  22. data/app/components/ariadne/dropdown/menu_component.rb +101 -0
  23. data/app/components/ariadne/dropdown/menu_component.ts +1 -0
  24. data/app/components/ariadne/dropdown_component.html.erb +8 -0
  25. data/app/components/ariadne/dropdown_component.rb +172 -0
  26. data/app/components/ariadne/flex_component.rb +1 -1
  27. data/app/components/ariadne/footer_component.html.erb +1 -1
  28. data/app/components/ariadne/header_component.rb +2 -2
  29. data/app/components/ariadne/heroicon_component.rb +6 -4
  30. data/app/components/ariadne/inline_flex_component.html.erb +1 -0
  31. data/app/components/ariadne/inline_flex_component.rb +8 -1
  32. data/app/components/ariadne/link_component.rb +2 -2
  33. data/app/components/ariadne/list_component.html.erb +2 -9
  34. data/app/components/ariadne/list_component.rb +11 -15
  35. data/app/components/ariadne/main_component.rb +1 -1
  36. data/app/components/ariadne/pill_component.rb +19 -5
  37. data/app/components/ariadne/rich-text-area-component.ts +4 -4
  38. data/app/components/ariadne/rich_text_area_component.html.erb +1 -1
  39. data/app/components/ariadne/rich_text_area_component.rb +1 -1
  40. data/app/components/ariadne/slideover_component.html.erb +1 -1
  41. data/app/components/ariadne/tab-container-component.ts +21 -21
  42. data/app/components/ariadne/tab_component.rb +4 -7
  43. data/app/components/ariadne/tab_container_component.rb +8 -2
  44. data/app/components/ariadne/tab_nav_component.html.erb +1 -1
  45. data/app/components/ariadne/tab_nav_component.rb +1 -1
  46. data/app/components/ariadne/table_nav_component.html.erb +52 -0
  47. data/app/components/ariadne/table_nav_component.rb +338 -0
  48. data/app/components/ariadne/tooltip_component.html.erb +1 -1
  49. data/app/components/ariadne/tooltip_component.rb +4 -4
  50. data/app/lib/ariadne/action_view_extensions/form_helper.rb +21 -7
  51. data/app/lib/ariadne/form_builder.rb +2 -2
  52. data/lib/ariadne/view_components/version.rb +1 -1
  53. data/lib/tasks/docs.rake +19 -3
  54. data/static/arguments.yml +103 -11
  55. data/static/audited_at.json +15 -7
  56. data/static/classes.yml +49 -45
  57. data/static/constants.json +179 -51
  58. data/static/statuses.json +15 -7
  59. data/tailwind.config.js +25 -1
  60. metadata +15 -4
  61. data/app/components/ariadne/table_component.html.erb +0 -17
  62. data/app/components/ariadne/table_component.rb +0 -281
@@ -7,7 +7,6 @@ export default class CommentComponent extends Controller {
7
7
  SELECTED_TAB_CLASSES: string[];
8
8
  PUBLIC_BACKGROUND_COLOR: string;
9
9
  INTERNAL_BACKGROUND_COLOR: string;
10
- connect(): void;
11
10
  toggleTab(): void;
12
- toggleBackgrounds(tab: HTMLButtonElement): void;
11
+ toggleBackgrounds(tab: HTMLButtonElement, publicComment: boolean): void;
13
12
  }
@@ -4,3 +4,4 @@
4
4
 
5
5
  @import 'tooltip-component.css';
6
6
  @import 'prosemirror.css';
7
+ @import 'dropdown.css';
@@ -0,0 +1,46 @@
1
+ .ariadne__details-reset > summary {
2
+ list-style: none;
3
+ transition: 80ms cubic-bezier(0.33, 1, 0.68, 1);
4
+ transition-property: color, background-color, box-shadow, border-color;
5
+ }
6
+
7
+ .ariadne__details-reset > summary:focus {
8
+ outline: 2px solid var(--color-accent-fg);
9
+ outline-offset: -2px;
10
+ box-shadow: none;
11
+ }
12
+
13
+ .ariadne__details-reset > summary:focus:not(:focus-visible) {
14
+ outline: solid 1px transparent;
15
+ }
16
+
17
+ .ariadne__details-reset > summary:focus-visible {
18
+ outline: 2px solid var(--color-accent-fg);
19
+ outline-offset: -2px;
20
+ box-shadow: none;
21
+ }
22
+
23
+ .ariadne__details-reset > summary.btn-primary:focus {
24
+ outline: 2px solid var(--color-accent-fg);
25
+ outline-offset: -2px;
26
+ box-shadow: inset 0 0 0 3px var(--color-fg-on-emphasis);
27
+ }
28
+
29
+ .ariadne__details-reset > summary.btn-primary:focus:not(:focus-visible) {
30
+ outline: solid 1px transparent;
31
+ box-shadow: none;
32
+ }
33
+
34
+ .ariadne__details-reset > summary.btn-primary:focus-visible {
35
+ outline: 2px solid var(--color-accent-fg);
36
+ outline-offset: -2px;
37
+ box-shadow: inset 0 0 0 3px var(--color-fg-on-emphasis);
38
+ }
39
+
40
+ .ariadne__details-reset > summary::before {
41
+ display: none;
42
+ }
43
+
44
+ .ariadne__details-reset > summary::-webkit-details-marker {
45
+ display: none;
46
+ }
@@ -1,34 +1,34 @@
1
- .tooltip-arrow,
2
- .tooltip-arrow::before {
1
+ .ariadne-tooltip-arrow,
2
+ .ariadne-tooltip-arrow::before {
3
3
  position: absolute;
4
4
  width: 8px;
5
5
  height: 8px;
6
6
  background: inherit;
7
7
  }
8
8
 
9
- .tooltip-arrow {
9
+ .ariadne-tooltip-arrow {
10
10
  visibility: hidden;
11
11
  }
12
12
 
13
- tooltip[data-tooltip-show] .tooltip-arrow::before {
13
+ tooltip[data-tooltip-show] .ariadne-tooltip-arrow::before {
14
14
  visibility: visible;
15
15
  content: '';
16
16
  transform: rotate(45deg);
17
17
  }
18
18
 
19
- tooltip[data-popper-placement^='top'][data-tooltip-show] > .tooltip-arrow {
19
+ tooltip[data-popper-placement^='top'][data-tooltip-show] > .ariadne-tooltip-arrow {
20
20
  bottom: -4px;
21
21
  }
22
22
 
23
- tooltip[data-popper-placement^='bottom'] > .tooltip-arrow {
23
+ tooltip[data-popper-placement^='bottom'] > .ariadne-tooltip-arrow {
24
24
  top: -4px;
25
25
  }
26
26
 
27
- tooltip[data-popper-placement^='left'] > .tooltip-arrow {
27
+ tooltip[data-popper-placement^='left'] > .ariadne-tooltip-arrow {
28
28
  right: -4px;
29
29
  }
30
30
 
31
- tooltip[data-popper-placement^='right'] > .tooltip-arrow {
31
+ tooltip[data-popper-placement^='right'] > .ariadne-tooltip-arrow {
32
32
  left: -4px;
33
33
  }
34
34
 
@@ -3,7 +3,6 @@ import {Application} from '@hotwired/stimulus'
3
3
  import AriadneForm from './ariadne-form'
4
4
 
5
5
  import ClipboardCopyComponent from './clipboard-copy-component'
6
- import CommentComponent from './comment-component'
7
6
  import RichTextAreaComponent from './rich-text-area-component'
8
7
  import SlideoverComponent from './slideover-component'
9
8
  import TabNavComponent from './tab-nav-component'
@@ -16,7 +15,6 @@ const application = Application.start()
16
15
 
17
16
  application.register('clipboard-copy-component', ClipboardCopyComponent)
18
17
  application.register('ariadne-form', AriadneForm)
19
- application.register('comment-component', CommentComponent)
20
18
  application.register('rich-text-area-component', RichTextAreaComponent)
21
19
  application.register('slideover-component', SlideoverComponent)
22
20
  application.register('tab-nav-component', TabNavComponent)
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ariadne
4
+ # `Avatar` can be used to represent users.
5
+ #
6
+ # - Use the default circle avatar for users, and the square shape
7
+ # for or any other non-human avatars.
8
+ # - By default, `Avatar` will render a static `<img>`. To have `Avatar` function as a link, set the `href` which will wrap the `<img>` in a `<a>`.
9
+ # - Set `size` to update the height and width of the `Avatar` in pixels.
10
+ # - To stack multiple avatars together, use <%= link_to_component(Ariadne::AvatarStackComponent) %>.
11
+ #
12
+ # @accessibility
13
+ # Images should have text alternatives that describe the information or function represented.
14
+ # If the avatar functions as a link, provide alt text that helps convey the function. For instance,
15
+ # if `Avatar` is a link to a user profile, the alt attribute should be `@kittenuser profile`
16
+ # rather than `@kittenuser`.
17
+ # [Learn more about best image practices (WAI Images)](https://www.w3.org/WAI/tutorials/images/)
18
+ class AvatarComponent < Ariadne::Component
19
+ DEFAULT_SIZE = 20
20
+ SMALL_THRESHOLD = 24
21
+
22
+ DEFAULT_SHAPE = :circle
23
+ SHAPE_OPTIONS = [DEFAULT_SHAPE, :square].freeze
24
+
25
+ SIZE_OPTIONS = [16, DEFAULT_SIZE, SMALL_THRESHOLD, 32, 40, 48, 80].freeze
26
+
27
+ DEFAULT_CLASSES = "ariadne-inline-block ariadne-rounded-full ariadne-ring-2 ariadne-ring-white"
28
+
29
+ # @example Default
30
+ # <%= render(Ariadne::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser")) %>
31
+ #
32
+ # @example Square
33
+ # <%= render(Ariadne::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", shape: :square)) %>
34
+ #
35
+ # @example Link
36
+ # <%= render(Ariadne::AvatarComponent.new(href: "#", src: "http://placekitten.com/200/200", alt: "@kittenuser profile")) %>
37
+ #
38
+ # @example With size
39
+ # <%= render(Ariadne::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", size: 16)) %>
40
+ # <%= render(Ariadne::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", size: 20)) %>
41
+ # <%= render(Ariadne::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", size: 24)) %>
42
+ # <%= render(Ariadne::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", size: 32)) %>
43
+ # <%= render(Ariadne::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", size: 40)) %>
44
+ # <%= render(Ariadne::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", size: 48)) %>
45
+ # <%= render(Ariadne::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", size: 80)) %>
46
+ #
47
+ # @param src [String] The source url of the avatar image.
48
+ # @param alt [String] Passed through to alt on img tag.
49
+ # @param size [Integer] <%= one_of(Ariadne::AvatarComponent::SIZE_OPTIONS) %>
50
+ # @param shape [Symbol] Shape of the avatar. <%= one_of(Ariadne::AvatarComponent::SHAPE_OPTIONS) %>
51
+ # @param href [String] The URL to link to. If used, component will be wrapped by an `<a>` tag.
52
+ # @param classes [String] <%= link_to_classes_docs %>
53
+ # @param attributes [Hash] <%= link_to_attributes_docs %>
54
+ def initialize(src:, alt:, size: DEFAULT_SIZE, shape: DEFAULT_SHAPE, href: nil, classes: "", attributes: {})
55
+ @tag = :img
56
+ @href = href
57
+
58
+ @classes = class_names(
59
+ DEFAULT_CLASSES,
60
+ classes,
61
+ )
62
+
63
+ @attributes = attributes
64
+ @attributes[:src] = src
65
+ @attributes[:alt] = alt
66
+ @attributes[:size] = fetch_or_raise(SIZE_OPTIONS, size)
67
+ @attributes[:height] = @attributes[:size]
68
+ @attributes[:width] = @attributes[:size]
69
+ end
70
+
71
+ def call
72
+ if @href
73
+ render(Ariadne::LinkComponent.new(href: @href, classes: @classes, attributes: @attributes)) do
74
+ render(Ariadne::BaseComponent.new(tag: @tag)) { content }
75
+ end
76
+ else
77
+ render(Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes)) { content }
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,12 @@
1
+ <%= render Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes) do %>
2
+ <%if tooltipped? %>
3
+ <%= tooltip.to_s %>
4
+ <% avatars.each_with_index do |avatar, i| %>
5
+ <%= avatar %>
6
+ <% end %>
7
+ <% else %>
8
+ <% avatars.each_with_index do |avatar, i| %>
9
+ <%= avatar %>
10
+ <% end %>
11
+ <% end %>
12
+ <% end %>
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ariadne
4
+ # Use `AvatarStack` to stack multiple avatars together.
5
+ class AvatarStackComponent < Ariadne::Component
6
+ ALIGN_DEFAULT = :left
7
+ ALIGN_OPTIONS = [ALIGN_DEFAULT, :right].freeze
8
+
9
+ DEFAULT_TAG = :div
10
+ TAG_OPTIONS = [DEFAULT_TAG, :span].freeze
11
+
12
+ DEFAULT_BODY_TAG = :div
13
+ BODY_TAG_OPTIONS = [DEFAULT_BODY_TAG, :span].freeze
14
+
15
+ # `Tooltip` that appears on mouse hover or keyboard focus over the stack.
16
+ #
17
+ # @param tag [Symbol, String] The rendered tag name
18
+ # @param text [String] The text content of the tooltip. This should be brief and no longer than a sentence.
19
+ # @param direction [Symbol] <%= one_of(Ariadne::TooltipComponent::VALID_PLACEMENTS) %>
20
+ # @param classes [String] <%= link_to_classes_docs %>
21
+ # @param attributes [Hash] Same arguments as <%= link_to_component(Ariadne::TooltipComponent) %>.
22
+ renders_one :tooltip, lambda { |tag: Ariadne::TooltipComponent::DEFAULT_TAG, text:, direction: Ariadne::TooltipComponent::DEFAULT_PLACEMENT, classes: "", attributes: {}|
23
+ raise ArgumentError, "Avatar stacks with a tooltip must have a unique `id` set." if @id.blank?
24
+
25
+ Ariadne::TooltipComponent.new(for_id: @id, tag: tag, text: text, direction: direction, type: :label, classes: classes, attributes: attributes)
26
+ }
27
+
28
+ # Required list of stacked avatars.
29
+ #
30
+ # @param classes [String] <%= link_to_classes_docs %>
31
+ # @param attributes [Hash] <%= link_to_attributes_docs %>
32
+ renders_many :avatars, "Ariadne::AvatarComponent"
33
+
34
+ DEFAULT_CLASSES = "ariadne-flex ariadne--space-x-2 ariadne-overflow-hidden"
35
+
36
+ # @example Default
37
+ # <%= render(Ariadne::AvatarStackComponent.new) do |c| %>
38
+ # <% c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
39
+ # <% c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
40
+ # <% c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
41
+ # <% end %>
42
+ #
43
+ # @example Align right
44
+ # <%= render(Ariadne::AvatarStackComponent.new(align: :right)) do |c| %>
45
+ # <% c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
46
+ # <% c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
47
+ # <% c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
48
+ # <% end %>
49
+ #
50
+ # @param tag [Symbol] <%= one_of(Ariadne::AvatarStackComponent::TAG_OPTIONS) %>
51
+ # @param align [Symbol] <%= one_of(Ariadne::AvatarStackComponent::ALIGN_OPTIONS) %>
52
+ # @param classes [String] <%= link_to_classes_docs %>
53
+ # @param attributes [Hash] <%= link_to_attributes_docs %>
54
+ def initialize(tag: DEFAULT_TAG, align: ALIGN_DEFAULT, classes: "", attributes: {})
55
+ @tag = check_incoming_tag(DEFAULT_TAG, tag)
56
+ @align = fetch_or_raise(ALIGN_OPTIONS, align)
57
+ @classes = class_names(
58
+ DEFAULT_CLASSES,
59
+ classes,
60
+ )
61
+
62
+ @attributes = attributes
63
+ @attributes[:id] ||= "avatar-stack-#{SecureRandom.hex(4)}"
64
+ @id = @attributes[:id]
65
+ end
66
+
67
+ def render?
68
+ avatars.any?
69
+ end
70
+
71
+ def tooltipped?
72
+ tooltip.present?
73
+ end
74
+ end
75
+ end
@@ -8,7 +8,7 @@ module Ariadne
8
8
 
9
9
  DEFAULT_TYPE = :button
10
10
  TYPE_SUBMIT = :submit
11
- TYPE_OPTIONS = [DEFAULT_TYPE, :reset, TYPE_SUBMIT].freeze
11
+ VALID_TYPES = [DEFAULT_TYPE, :reset, TYPE_SUBMIT].freeze
12
12
 
13
13
  SIZE_CLASS_MAPPINGS = {
14
14
  xs: "ariadne-px-2.5 ariadne-py-1.5 ariadne-text-xs ariadne-font-medium ariadne-rounded",
@@ -20,6 +20,7 @@ module Ariadne
20
20
  VALID_SIZES = SIZE_CLASS_MAPPINGS.keys.freeze
21
21
 
22
22
  DEFAULT_CLASSES = "ariadne-inline-flex ariadne-items-center ariadne-border ariadne-shadow-sm focus:ariadne-outline-none focus:ariadne-ring-2 focus:ariadne-ring-offset-2"
23
+ DEFAULT_NUDE_CLASSES = "ariadne-inline-flex focus:ariadne-outline-none focus:ariadne-ring-2 focus:ariadne-ring-offset-2"
23
24
 
24
25
  DEFAULT_SIZE = :md
25
26
 
@@ -31,7 +32,7 @@ module Ariadne
31
32
  # <%= render(Ariadne::BaseButton.new(size: :xl)) { "I am an extra large button!" } %>
32
33
  #
33
34
  # @param tag [Symbol] <%= one_of(Ariadne::BaseButton::TAG_OPTIONS) %>
34
- # @param type [Symbol] <%= one_of(Ariadne::BaseButton::TYPE_OPTIONS) %>
35
+ # @param type [Symbol] <%= one_of(Ariadne::BaseButton::VALID_TYPES) %>
35
36
  # @param size [Symbol] <%= one_of(Ariadne::BaseButton::VALID_SIZES) %>
36
37
  # @param classes [String] <%= link_to_classes_docs %>
37
38
  # @param attributes [Hash] <%= link_to_attributes_docs %>
@@ -46,14 +47,22 @@ module Ariadne
46
47
  @tag = fetch_or_raise(TAG_OPTIONS, tag)
47
48
  @size = fetch_or_raise(VALID_SIZES, size)
48
49
 
49
- @attributes[:type] = fetch_or_raise(TYPE_OPTIONS, type) if button?
50
- @classes = class_names(DEFAULT_CLASSES, SIZE_CLASS_MAPPINGS[@size], classes)
50
+ if button?
51
+ @attributes[:type] = fetch_or_raise(VALID_TYPES, type)
52
+ @classes = class_names(DEFAULT_CLASSES, SIZE_CLASS_MAPPINGS[@size], classes)
53
+ else
54
+ @classes = class_names(DEFAULT_NUDE_CLASSES, SIZE_CLASS_MAPPINGS[@size], classes)
55
+ end
51
56
  end
52
57
 
53
58
  def call
54
59
  render(Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes)) { content }
55
60
  end
56
61
 
62
+ private def link?(type)
63
+ type == :link
64
+ end
65
+
57
66
  private def button?
58
67
  @tag == :button
59
68
  end
@@ -50,7 +50,7 @@ module Ariadne
50
50
  # @param tag [Symbol, String] <%= one_of(Ariadne::HeadingComponent::TAG_OPTIONS) %>
51
51
  # @param classes [String] <%= link_to_classes_docs %>
52
52
  # @param attributes [Hash] Same arguments as <%= link_to_component(Ariadne::HeroiconComponent) %>.
53
- DEFAULT_HEADING_CLASSES = "text-3xl font-extrabold tracking-tight text-gray-900 sm:text-4xl"
53
+ DEFAULT_HEADING_CLASSES = "ariadne-text-3xl ariadne-font-extrabold ariadne-tracking-tight ariadne-text-gray-900 sm:ariadne-text-4xl"
54
54
  renders_one :heading, lambda { |tag: :h1, classes: "", attributes: {}|
55
55
  actual_classes = class_names(DEFAULT_HEADING_CLASSES, classes)
56
56
 
@@ -107,7 +107,7 @@ module Ariadne
107
107
 
108
108
  # @example Basic
109
109
  # <%= render Ariadne::BlankslateComponent.new do |c| %>
110
- # <% c.heading(tag: :h2).with_content("heading") %>
110
+ # <% c.heading(tag: :h2) { "heading" } %>
111
111
  # <% c.description { "Description"} %>
112
112
  # <% end %>
113
113
  #
@@ -117,7 +117,7 @@ module Ariadne
117
117
  # @code
118
118
  # <%= render Ariadne::BlankslateComponent.new do |c| %>
119
119
  # <% c.icon(icon: :"globe-europe-africa") %>
120
- # <% c.heading(tag: :h2).with_content("heading") %>
120
+ # <% c.heading(tag: :h2) { "heading" } %>
121
121
  # <% c.description { "Description"} %>
122
122
  # <% end %>
123
123
  #
@@ -127,7 +127,7 @@ module Ariadne
127
127
  # @code
128
128
  # <%= render Ariadne::BlankslateComponent.new do |c| %>
129
129
  # <% c.image(src: "https://github.githubassets.com/images/modules/site/features/security-icon.svg", alt: "Security - secure vault") %>
130
- # <% c.heading(tag: :h2).with_content("heading") %>
130
+ # <% c.heading(tag: :h2){ "heading" } %>
131
131
  # <% end %>
132
132
  #
133
133
  # @param tag [Symbol, String] The rendered tag name
@@ -1,4 +1,4 @@
1
1
  <%= render Ariadne::BaseButton.new(tag: @tag, type: @type, classes: @classes, attributes: @attributes) do -%>
2
- <%= icon %><%= trimmed_content %><%= counter %>
2
+ <%= icon %><%= trimmed_content %><%= counter %><%= ariadne_heroicon(icon: :"chevron-down", variant: HeroiconsHelper::Icon::VARIANT_MINI, classes: "ariadne-ml-2 ariadne--mr-1") if dropdown? %>
3
3
  <%= tooltip %>
4
4
  <% end -%>
@@ -9,6 +9,7 @@ module Ariadne
9
9
  LINK_SCHEME = :link
10
10
 
11
11
  SCHEME_CLASS_MAPPINGS = {
12
+ link: Ariadne::LinkComponent::DEFAULT_ACTIONABLE_CLASSES,
12
13
  none: "",
13
14
  default: "ariadne-text-purple-800 ariadne-bg-purple-50 hover:ariadne-bg-purple-100 ariadne-border-purple-300 focus:ariadne-ring-offset-purple-50 focus:ariadne-ring-purple-600",
14
15
  info: "ariadne-text-blue-800 ariadne-bg-blue-50 hover:ariadne-bg-blue-100 ariadne-border-blue-300 focus:ariadne-ring-offset-blue-50 focus:ariadne-ring-blue-600",
@@ -109,10 +110,10 @@ module Ariadne
109
110
  # <% end %>
110
111
  #
111
112
  # @param tag [Symbol] <%= one_of(Ariadne::BaseButton::TAG_OPTIONS) %>
112
- # @param type [Symbol] <%= one_of(Ariadne::BaseButton::TYPE_OPTIONS) %>
113
+ # @param type [Symbol] <%= one_of(Ariadne::BaseButton::VALID_TYPES) %>
113
114
  # @param scheme [Symbol] <%= one_of(Ariadne::ButtonComponent::VALID_SCHEMES) %>
114
115
  # @param size [Symbol] <%= one_of(Ariadne::BaseButton::VALID_SIZES) %>
115
- # @param type [Symbol] <%= one_of(Ariadne::BaseButton::TYPE_OPTIONS) %>
116
+ # @param dropdown [Boolean] Whether or not to render a dropdown caret.
116
117
  # @param classes [String] <%= link_to_classes_docs %>
117
118
  # @param attributes [Hash] <%= link_to_attributes_docs %>
118
119
  def initialize(
@@ -120,18 +121,19 @@ module Ariadne
120
121
  type: Ariadne::BaseButton::DEFAULT_TYPE,
121
122
  scheme: DEFAULT_SCHEME,
122
123
  size: BaseButton::DEFAULT_SIZE,
124
+ dropdown: false,
123
125
  classes: "",
124
126
  attributes: {}
125
127
  )
126
128
  @tag = tag
127
129
  @type = type
128
- @scheme = scheme
129
130
 
130
131
  @attributes = attributes
131
132
  @id = @attributes[:id]
132
133
 
133
134
  @size = fetch_or_raise(Ariadne::BaseButton::VALID_SIZES, size)
134
135
  @scheme = fetch_or_raise(VALID_SCHEMES, scheme)
136
+ @scheme = LINK_SCHEME if @tag == :a
135
137
 
136
138
  @classes = class_names(
137
139
  SCHEME_CLASS_MAPPINGS[@scheme],
@@ -139,6 +141,10 @@ module Ariadne
139
141
  )
140
142
  end
141
143
 
144
+ private def dropdown?
145
+ @dropdown
146
+ end
147
+
142
148
  private def trimmed_content
143
149
  return if content.blank?
144
150
 
@@ -1,55 +1,37 @@
1
- import {Controller} from '@hotwired/stimulus'
1
+ // import {Controller} from '@hotwired/stimulus'
2
2
 
3
- export default class CommentComponent extends Controller {
4
- static targets = ['tab', 'tabBarComponent']
3
+ // export default class CommentComponent extends Controller {
4
+ // static targets = ['tab', 'tabBarComponent']
5
5
 
6
- declare readonly commentComponentTarget: HTMLDivElement
7
- declare readonly tabBarComponentTarget: HTMLElement // technically a `nav but typescript can't find it?
8
- declare readonly tabTargets: [HTMLButtonElement]
6
+ // declare readonly commentComponentTarget: HTMLDivElement
7
+ // declare readonly tabBarComponentTarget: HTMLElement // technically a `nav but typescript can't find it?
8
+ // declare readonly tabTargets: [HTMLButtonElement]
9
9
 
10
- SELECTED_TAB_CLASSES = ['ariadne-border-indigo-500', 'ariadne-text-indigo-600']
11
- PUBLIC_BACKGROUND_COLOR = 'ariadne-bg-white'
12
- INTERNAL_BACKGROUND_COLOR = 'ariadne-bg-internal-message'
10
+ // // keep in sync with comment_component.rb
11
+ // SELECTED_TAB_CLASSES = ['ariadne-border-indigo-500', 'ariadne-text-indigo-600']
12
+ // PUBLIC_BACKGROUND_COLOR = 'ariadne-bg-white'
13
+ // INTERNAL_BACKGROUND_COLOR = 'ariadne-bg-internal-message'
13
14
 
14
- connect() {
15
- for (const tab of this.tabTargets) {
16
- if (tab.hasAttribute('selected')) {
17
- tab.classList.add(...this.SELECTED_TAB_CLASSES)
18
- }
19
- }
20
- }
15
+ // toggleTab() {
16
+ // for (const tab of this.tabTargets) {
17
+ // if (tab.hasAttribute('aria-selected')) {
18
+ // tab.classList.remove(...this.SELECTED_TAB_CLASSES)
19
+ // this.toggleBackgrounds(tab, false)
20
+ // tab.removeAttribute('aria-selected')
21
+ // } else {
22
+ // tab.setAttribute('aria-selected', 'true')
23
+ // tab.classList.add(...this.SELECTED_TAB_CLASSES)
24
+ // this.toggleBackgrounds(tab, true)
25
+ // }
26
+ // }
27
+ // }
28
+ // toggleBackgrounds(tab: HTMLButtonElement, publicComment: boolean) {
29
+ // if (publicComment) {
30
+ // this.tabBarComponentTarget.classList.add(this.PUBLIC_BACKGROUND_COLOR)
31
+ // this.tabBarComponentTarget.classList.remove(this.INTERNAL_BACKGROUND_COLOR)
21
32
 
22
- toggleTab() {
23
- for (const tab of this.tabTargets) {
24
- if (tab.hasAttribute('selected')) {
25
- tab.removeAttribute('selected')
26
- tab.classList.remove(...this.SELECTED_TAB_CLASSES)
27
- this.toggleBackgrounds(tab)
28
- } else {
29
- tab.setAttribute('selected', 'true')
30
- tab.classList.add(...this.SELECTED_TAB_CLASSES)
31
- this.toggleBackgrounds(tab)
32
- if (tab.hasAttribute('data-public')) {
33
- document.getElementById('message_public')?.setAttribute('value', 'true')
34
- } else {
35
- document.getElementById('message_public')?.setAttribute('value', 'false')
36
- }
37
- }
38
- }
39
- }
40
- toggleBackgrounds(tab: HTMLButtonElement) {
41
- if (tab.hasAttribute('selected')) {
42
- if (tab.hasAttribute('data-public')) {
43
- // this.commentComponentTarget.classList.add(this.PUBLIC_BACKGROUND_COLOR)
44
- // this.commentComponentTarget.classList.remove(this.INTERNAL_BACKGROUND_COLOR)
45
- this.tabBarComponentTarget.classList.add(this.PUBLIC_BACKGROUND_COLOR)
46
- this.tabBarComponentTarget.classList.remove(this.INTERNAL_BACKGROUND_COLOR)
47
- } else {
48
- // this.commentComponentTarget.classList.remove(this.PUBLIC_BACKGROUND_COLOR)
49
- // this.commentComponentTarget.classList.add(this.INTERNAL_BACKGROUND_COLOR)
50
- this.tabBarComponentTarget.classList.remove(this.PUBLIC_BACKGROUND_COLOR)
51
- this.tabBarComponentTarget.classList.add(this.INTERNAL_BACKGROUND_COLOR)
52
- }
53
- }
54
- }
55
- }
33
+ // this.tabBarComponentTarget.classList.remove(this.PUBLIC_BACKGROUND_COLOR)
34
+ // this.tabBarComponentTarget.classList.add(this.INTERNAL_BACKGROUND_COLOR)
35
+ // }
36
+ // }
37
+ // }
@@ -2,17 +2,39 @@
2
2
  <div class="ariadne-bg-white" data-comment-component-target="commentComponent">
3
3
  <div class="ariadne-hidden sm:ariadne-block">
4
4
  <div class="ariadne-border-b ariadne-border-gray-200">
5
+ <%= render(Ariadne::TabContainerComponent.new(sr_label: @sr_label)) do |tab_container| %>
6
+ <%= tab_container.tab(id: public_tab.id, selected: public_tab.selected, classes: public_tab.classes, attributes: public_tab.attributes) do |tab| %>
7
+ <% tab.text { @public_tab_text } %>
8
+ <% tab.panel do %>
9
+ <%= ariadne_form_with(url: @url, method: @method, classes: @classes, attributes: @attributes) do |comment_box| %>
10
+ <div class="ariadne-overflow-hidden ariadne-border-x ariadne-border-b ariadne-border-gray-300 ariadne-shadow-sm focus-within:ariadne-border-indigo-500 focus-within:ariadne-ring-1 focus-within:ariadne-ring-indigo-500">
11
+ <%= hidden_field_tag 'message_public', true %>
12
+ <%= render(Ariadne::RichTextAreaComponent.new(name: :bodytext, sr_label: "Select reply type", attributes: { required: true})) %>
13
+ <% comment_box.submit { @submit } %>
14
+ </div>
15
+ <div class="ariadne-mt-2 ariadne-flex ariadne-justify-end">
16
+ <%= submit %>
17
+ </div>
18
+ <% end %>
19
+ <% end %>
20
+ <% end %>
21
+ <%= tab_container.tab(id: internal_tab.id, selected: internal_tab.selected, classes: internal_tab.classes, attributes: internal_tab.attributes) do |tab| %>
22
+ <% tab.text { @internal_tab_text } %>
23
+ <% tab.panel do %>
24
+ <%= ariadne_form_with(url: @url, method: @method, classes: @classes, attributes: @attributes) do |comment_box| %>
25
+ <div class="ariadne-overflow-hidden ariadne-border-x ariadne-border-b ariadne-border-gray-300 ariadne-shadow-sm focus-within:ariadne-border-indigo-500 focus-within:ariadne-ring-1 focus-within:ariadne-ring-indigo-500">
26
+ <%= hidden_field_tag 'message_public', false %>
27
+ <%= render(Ariadne::RichTextAreaComponent.new(name: :bodytext, sr_label: "Select reply type", attributes: { required: true})) %>
28
+ <% comment_box.submit { @submit } %>
29
+ </div>
30
+ <div class="ariadne-mt-2 ariadne-flex ariadne-justify-end">
31
+ <%= submit %>
32
+ </div>
33
+ <% end %>
34
+ <% end %>
35
+ <% end %>
36
+ <% end %>
5
37
  </div>
6
38
  </div>
7
- <%= ariadne_form_with(url: @url, method: @method, classes: @classes, attributes: @attributes) do |comment_box| %>
8
- <div class="ariadne-overflow-hidden ariadne-border-x ariadne-border-b ariadne-border-gray-300 ariadne-shadow-sm focus-within:ariadne-border-indigo-500 focus-within:ariadne-ring-1 focus-within:ariadne-ring-indigo-500">
9
- <%= hidden_field_tag 'message_public', true %>
10
- <%= render(Ariadne::RichTextAreaComponent.new(name: :bodytext, sr_label: "Select reply type", attributes: { required: true})) %>
11
- <% comment_box.submit { @submit } %>
12
- </div>
13
- <div class="ariadne-mt-2 ariadne-flex ariadne-justify-end">
14
- <%= submit %>
15
- </div>
16
- <% end %>
17
39
  </div>
18
40
  <% end %>
@@ -2,6 +2,10 @@
2
2
 
3
3
  module Ariadne
4
4
  # Defines a submittable form for adding comments to a conversation.
5
+ #
6
+ #
7
+ # Requires JavaScript. Set `data-comment-component-selected-class` to the class name that will be applied to the
8
+ # selected tab.
5
9
  # @accessibility This component requires you to pass in a `sr_label`
6
10
  # attribute, which will be used to label the tabs for screen readers.
7
11
  class CommentComponent < Ariadne::Component
@@ -12,17 +16,21 @@ module Ariadne
12
16
 
13
17
  renders_one :public_tab, lambda { |selected: false, text:, classes: "", attributes: {}|
14
18
  attributes[:"data-comment-component-target"] ||= "tab"
15
- attributes[:"data-action"] ||= "click->comment-component#toggleTab"
16
19
  attributes[:"data-public"] = true
17
20
  @tab_idx += 1
18
- render(Ariadne::TabComponent.new(selected: selected, classes: classes, attributes: attributes)) { text }
21
+ id = attributes.fetch(:id, "public-tab-#{@tab_idx}")
22
+ @public_tab_text = text
23
+
24
+ Ariadne::TabComponent.new(selected: selected, classes: classes, id: id, with_panel: true, attributes: attributes)
19
25
  }
20
26
 
21
27
  renders_one :internal_tab, lambda { |selected: false, text:, classes: "", attributes: {}|
22
28
  attributes[:"data-comment-component-target"] ||= "tab"
23
- attributes[:"data-action"] ||= "click->comment-component#toggleTab"
24
29
  @tab_idx += 1
25
- render(Ariadne::TabComponent.new(selected: selected, classes: classes, attributes: attributes)) { text }
30
+ id = attributes.fetch(:id, "internal-tab-#{@tab_idx}")
31
+ @internal_tab_text = text
32
+
33
+ Ariadne::TabComponent.new(selected: selected, classes: classes, id: id, with_panel: true, attributes: attributes)
26
34
  }
27
35
 
28
36
  renders_one :submit, lambda { |classes: "", attributes: {}|
@@ -31,7 +39,11 @@ module Ariadne
31
39
 
32
40
  # @example Default
33
41
  #
34
- # <%= render(Ariadne::CommentComponent.new(url: "/messages", method: :post, sr_label: "Select delivery time")) { "Example" } %>
42
+ # <%= render(Ariadne::CommentComponent.new(url: "/messages", method: :post, sr_label: "Select delivery time")) do |comment| %>
43
+ # <% comment.public_tab(selected: true, text: "Reply to sender") %>
44
+ # <% comment.internal_tab(text: "Internal comment") %>
45
+ # <% comment.submit { "Send" } %>
46
+ # <% end %>
35
47
  #
36
48
  # @param url [String] The URL to take action against.
37
49
  # @param method [String] The method to use when submitting the form.
@@ -0,0 +1,4 @@
1
+ <%= render Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes) do |component| %>
2
+ <%= summary %>
3
+ <%= body %>
4
+ <% end %>