ariadne_view_components 0.0.93.1 → 0.0.94

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/README.md +13 -4
  4. data/app/assets/javascripts/ariadne_view_components.js +14 -14
  5. data/app/assets/javascripts/ariadne_view_components.js.br +0 -0
  6. data/app/assets/javascripts/ariadne_view_components.js.gz +0 -0
  7. data/app/assets/javascripts/ariadne_view_components.js.map +1 -1
  8. data/app/assets/stylesheets/ariadne_view_components.css +1 -1
  9. data/app/assets/stylesheets/ariadne_view_components.css.br +0 -0
  10. data/app/assets/stylesheets/ariadne_view_components.css.gz +0 -0
  11. data/app/components/ariadne/base_component.rb +25 -22
  12. data/app/components/ariadne/behaviors/tooltipable.rb +12 -12
  13. data/app/components/ariadne/form/checkbox/component.rb +2 -2
  14. data/app/components/ariadne/form/group/component.rb +1 -1
  15. data/app/components/ariadne/form/radio_button/component.rb +2 -2
  16. data/app/components/ariadne/form/select/component.rb +1 -1
  17. data/app/components/ariadne/form/text_field/component.html.erb +2 -2
  18. data/app/components/ariadne/form/text_field/component.rb +14 -7
  19. data/app/components/ariadne/form/toggle/component.rb +2 -2
  20. data/app/components/ariadne/form/toggle_group/component.rb +1 -1
  21. data/app/components/ariadne/form/toggle_group/option/component.rb +1 -1
  22. data/app/components/ariadne/layout/grid/component.rb +1 -1
  23. data/app/components/ariadne/layout/grid/item/component.rb +2 -2
  24. data/app/components/ariadne/layout/label_block/component.rb +1 -1
  25. data/app/components/ariadne/layout/narrow/component.rb +1 -1
  26. data/app/components/ariadne/ui/accordion/component.rb +3 -1
  27. data/app/components/ariadne/ui/accordion/item/component.html.erb +10 -10
  28. data/app/components/ariadne/ui/accordion/item/component.rb +12 -3
  29. data/app/components/ariadne/ui/avatar/component.html.erb +9 -7
  30. data/app/components/ariadne/ui/avatar/component.rb +55 -7
  31. data/app/components/ariadne/ui/badge/component.rb +35 -16
  32. data/app/components/ariadne/ui/banner/component.html.erb +23 -0
  33. data/app/components/ariadne/ui/banner/component.rb +226 -0
  34. data/app/components/ariadne/ui/banner/component.ts +46 -0
  35. data/app/components/ariadne/ui/blankslate/component.html.erb +2 -2
  36. data/app/components/ariadne/ui/blankslate/component.rb +12 -1
  37. data/app/components/ariadne/ui/button/component.rb +35 -24
  38. data/app/components/ariadne/ui/card/body/component.rb +1 -1
  39. data/app/components/ariadne/ui/card/component.rb +11 -7
  40. data/app/components/ariadne/ui/card/footer/component.rb +1 -1
  41. data/app/components/ariadne/ui/card/header/component.html.erb +2 -2
  42. data/app/components/ariadne/ui/card/header/component.rb +25 -16
  43. data/app/components/ariadne/ui/clipboard_copy/component.html.erb +1 -0
  44. data/app/components/ariadne/ui/clipboard_copy/component.rb +17 -21
  45. data/app/components/ariadne/ui/clipboard_copy/component.ts +15 -0
  46. data/app/components/ariadne/ui/color_dot/component.html.erb +5 -5
  47. data/app/components/ariadne/ui/color_dot/component.rb +19 -4
  48. data/app/components/ariadne/ui/combobox/component.html.erb +1 -1
  49. data/app/components/ariadne/ui/combobox/component.rb +54 -23
  50. data/app/components/ariadne/ui/combobox/component.ts +2 -0
  51. data/app/components/ariadne/ui/dialog/body/component.html.erb +3 -0
  52. data/app/components/ariadne/ui/dialog/body/component.rb +28 -0
  53. data/app/components/ariadne/ui/dialog/component.html.erb +25 -24
  54. data/app/components/ariadne/ui/dialog/component.rb +87 -18
  55. data/app/components/ariadne/ui/dialog/component.ts +5 -1
  56. data/app/components/ariadne/ui/dialog/footer/component.html.erb +3 -0
  57. data/app/components/ariadne/ui/dialog/footer/component.rb +34 -0
  58. data/app/components/ariadne/ui/heroicon/component.rb +21 -21
  59. data/app/components/ariadne/ui/image/component.rb +11 -23
  60. data/app/components/ariadne/ui/link/component.html.erb +1 -3
  61. data/app/components/ariadne/ui/link/component.rb +17 -4
  62. data/app/components/ariadne/ui/list/component.html.erb +5 -9
  63. data/app/components/ariadne/ui/list/component.rb +31 -7
  64. data/app/components/ariadne/ui/list/item/component.rb +6 -5
  65. data/app/components/ariadne/ui/pagination/component.rb +1 -2
  66. data/app/components/ariadne/ui/popover/component.html.erb +1 -1
  67. data/app/components/ariadne/ui/popover/component.rb +31 -26
  68. data/app/components/ariadne/ui/relative_time/component.html.erb +1 -0
  69. data/app/components/ariadne/ui/{time_ago → relative_time}/component.rb +15 -15
  70. data/app/components/ariadne/ui/{time_ago → relative_time}/component.ts +1 -1
  71. data/app/components/ariadne/ui/shortcut/component.html.erb +0 -1
  72. data/app/components/ariadne/ui/shortcut/component.rb +31 -5
  73. data/app/components/ariadne/ui/shortcut/component.ts +1 -1
  74. data/app/components/ariadne/ui/skeleton/component.rb +2 -8
  75. data/app/components/ariadne/ui/stats_panel/component.html.erb +3 -3
  76. data/app/components/ariadne/ui/stats_panel/component.rb +25 -1
  77. data/app/components/ariadne/ui/stats_panel/item/component.html.erb +3 -3
  78. data/app/components/ariadne/ui/stats_panel/item/component.rb +6 -6
  79. data/app/components/ariadne/ui/table/cell/component.rb +1 -1
  80. data/app/components/ariadne/ui/table/row/component.rb +1 -1
  81. data/app/components/ariadne/ui/typography/component.rb +3 -1
  82. data/app/frontend/controllers/tooltip_controller.ts +8 -3
  83. data/app/frontend/stylesheets/ariadne_view_components.css +1 -0
  84. data/app/frontend/stylesheets/theme.css +88 -0
  85. data/app/frontend/utils/createController.ts +9 -0
  86. data/app/helpers/ariadne/color_helper.rb +158 -0
  87. data/app/helpers/ariadne/form_helper.rb +1 -0
  88. data/app/helpers/ariadne/size_helper.rb +7 -0
  89. data/app/lib/ariadne/attributes_helper.rb +4 -4
  90. data/app/lib/ariadne/view_component/style_variants.rb +1 -1
  91. data/app/lib/ariadne/view_helper.rb +0 -6
  92. data/lib/ariadne/accessibility.rb +64 -0
  93. data/lib/ariadne/forms/dsl/form_object.rb +5 -1
  94. data/lib/ariadne/forms/dsl/input.rb +1 -1
  95. data/lib/ariadne/static/generate_arguments.rb +54 -0
  96. data/lib/ariadne/static/generate_audited_at.rb +17 -0
  97. data/lib/ariadne/static/generate_constants.rb +19 -0
  98. data/lib/ariadne/static/generate_previews.rb +53 -0
  99. data/lib/ariadne/static/generate_statuses.rb +17 -0
  100. data/lib/ariadne/static/generate_structure.rb +279 -0
  101. data/lib/ariadne/static.rb +68 -0
  102. data/lib/ariadne/view_components/constants.rb +2 -2
  103. data/lib/ariadne/view_components/version.rb +1 -1
  104. data/lib/ariadne/view_components.rb +0 -51
  105. data/lib/ariadne/yard/component_manifest.rb +81 -81
  106. data/lib/ariadne/yard/component_ref.rb +1 -1
  107. data/lib/ariadne/yard/docs_helper.rb +24 -16
  108. data/lib/ariadne/yard/dry_initializer/common_handler.rb +103 -0
  109. data/lib/ariadne/yard/dry_initializer/option_handler.rb +38 -0
  110. data/lib/ariadne/yard/dry_initializer/param_handler.rb +57 -0
  111. data/lib/ariadne/yard/registry.rb +2 -5
  112. data/lib/ariadne/yard/{info_arch_docs_helper.rb → structure_docs_helper.rb} +5 -5
  113. data/lib/ariadne/yard.rb +20 -8
  114. data/lib/rubocop/config/default.yml +0 -3
  115. metadata +34 -37
  116. data/app/components/ariadne/behaviors/captionable.rb +0 -55
  117. data/app/components/ariadne/turbo/frame/component.html.erb +0 -3
  118. data/app/components/ariadne/turbo/frame/component.rb +0 -16
  119. data/app/components/ariadne/turbo/stream_action/component.html.erb +0 -4
  120. data/app/components/ariadne/turbo/stream_action/component.rb +0 -25
  121. data/app/components/ariadne/ui/data_table/component.html.erb +0 -1
  122. data/app/components/ariadne/ui/data_table/component.rb +0 -11
  123. data/app/components/ariadne/ui/flash/component.html.erb +0 -18
  124. data/app/components/ariadne/ui/flash/component.rb +0 -151
  125. data/app/components/ariadne/ui/flash/component.ts +0 -56
  126. data/app/components/ariadne/ui/overlay/component.html.erb +0 -12
  127. data/app/components/ariadne/ui/overlay/component.rb +0 -54
  128. data/app/components/ariadne/ui/overlay/component.ts +0 -92
  129. data/app/components/ariadne/ui/time_ago/component.html.erb +0 -1
  130. data/lib/ariadne/view_components/commands.rb +0 -90
  131. data/lib/ariadne/view_components/statuses.rb +0 -14
  132. data/lib/ariadne/view_components/upstream.rb +0 -19
  133. data/lib/ariadne/yard/lookbook_pages_backend.rb +0 -235
  134. data/lib/rubocop/cop/ariadne/no_tag_memoize.rb +0 -44
  135. data/static/arguments.yml +0 -879
  136. data/static/assets/view-components.svg +0 -18
  137. data/static/classes.yml +0 -211
  138. data/static/constants.json +0 -743
  139. data/static/statuses.json +0 -58
  140. data/static/tailwindcss.yml +0 -727
  141. /data/app/components/ariadne/ui/{time_ago → relative_time}/en.yml +0 -0
@@ -13,10 +13,10 @@
13
13
  input? ? :input : :textarea,
14
14
  input? ? nil : html_attrs[:value],
15
15
  name: @name,
16
- class: Ariadne::ViewComponents.tailwind_merger.merge([html_attrs[:class], style(with_leading_item: leading_visual ? :yes : :no)]),
16
+ class: merge_tailwind_classes([html_attrs[:class], style(with_leading_item: leading_visual ? :yes : :no)]),
17
17
  type: @type,
18
18
  **html_attrs.except(:class)
19
- ) %>
19
+ ) %>
20
20
  <% if @validation_message %>
21
21
  <%= render(Primer::BaseComponent.new(tag: :div, **@validation_arguments)) do %>
22
22
  <span class="FormControl-inlineValidation--visual"><%= render(Primer::Beta::Octicon.new(icon: :"alert-fill", size: :xsmall, aria: { hidden: true })) %></span>
@@ -3,6 +3,14 @@
3
3
  module Ariadne
4
4
  module Form
5
5
  module TextField
6
+ # Text fields are single-line text inputs rendered as `<input type="text">` in HTML.
7
+ #
8
+ # @form_usage
9
+ # class ExampleForm < ApplicationForm
10
+ # form do |example_form|
11
+ # example_form.text_field(attributes)
12
+ # end
13
+ # end
6
14
  class Component < Ariadne::Form::BaseInputComponent
7
15
  option :name
8
16
  option :label
@@ -16,15 +24,15 @@ module Ariadne
16
24
  }
17
25
  # renders_one :trailing_visual, BaseComponent::ACCEPT_ANYTHING
18
26
 
19
- option :theme, default: proc { :primary }
20
- option :size, default: proc { :base }
21
- option :width, default: proc { :narrow }
27
+ option :theme, default: -> { :primary }
28
+ option :size, default: -> { :base }
29
+ option :width, default: -> { :narrow }
22
30
 
23
31
  option :label_classes, default: -> { "" }
24
32
  option :label_arguments, default: -> { {} }
25
33
 
26
34
  accepts_html_attributes do |html_attrs|
27
- html_attrs[:class] = Ariadne::ViewComponents.tailwind_merger.merge([style(theme:, size:, width:), html_attrs[:class]].join(" "))
35
+ html_attrs[:class] = merge_tailwind_classes([style(theme:, size:, width:), html_attrs[:class]].join(" "))
28
36
 
29
37
  html_attrs
30
38
  end
@@ -38,7 +46,7 @@ module Ariadne
38
46
  end
39
47
 
40
48
  def label_styles
41
- Ariadne::ViewComponents.tailwind_merger.merge([style(:label), label_classes].join(" "))
49
+ merge_tailwind_classes([style(:label), label_classes].join(" "))
42
50
  end
43
51
 
44
52
  style do
@@ -53,9 +61,8 @@ module Ariadne
53
61
  "dark:disabled:ariadne-text-zinc-600",
54
62
  "disabled:ariadne-cursor-not-allowed",
55
63
 
56
- "ariadne-bg-foreground",
64
+ "ariadne-bg-slate-50",
57
65
  "dark:ariadne-bg-foreground-dark",
58
- "dark:ariadne-bg-zinc-900",
59
66
  ]
60
67
  end
61
68
 
@@ -22,7 +22,7 @@ module Ariadne
22
22
  option :enabled, default: proc { true }
23
23
 
24
24
  accepts_html_attributes do |html_attrs|
25
- html_attrs[:class] = Ariadne::ViewComponents.tailwind_merger.merge(["ariadne-sr-only ariadne-peer", html_attrs[:class]].join(" "))
25
+ html_attrs[:class] = merge_tailwind_classes(["ariadne-sr-only ariadne-peer", html_attrs[:class]].join(" "))
26
26
 
27
27
  if @checked
28
28
  html_attrs[:checked] = @checked
@@ -40,7 +40,7 @@ module Ariadne
40
40
  end
41
41
 
42
42
  def before_render
43
- @label_id = ::Ariadne::ViewHelper.generate_id
43
+ @label_id = Ariadne::BaseComponent.generate_id
44
44
 
45
45
  if @form_url.present?
46
46
  csrf_token = view_context.form_authenticity_token(
@@ -12,7 +12,7 @@ module Ariadne
12
12
  }
13
13
 
14
14
  accepts_html_attributes do |html_attrs|
15
- html_attrs[:class] = Ariadne::ViewComponents.tailwind_merger.merge([style, html_attrs[:class]].join(" "))
15
+ html_attrs[:class] = merge_tailwind_classes([style, html_attrs[:class]].join(" "))
16
16
  end
17
17
 
18
18
  style do
@@ -13,7 +13,7 @@ module Ariadne
13
13
  option :checked, default: proc { false }
14
14
 
15
15
  accepts_html_attributes do |html_attrs|
16
- html_attrs[:class] = Ariadne::ViewComponents.tailwind_merger.merge([style(:tab), html_attrs[:class]].join(" "))
16
+ html_attrs[:class] = merge_tailwind_classes([style(:tab), html_attrs[:class]].join(" "))
17
17
  end
18
18
 
19
19
  def input_type
@@ -8,7 +8,7 @@ module Ariadne
8
8
  renders_many :items, Ariadne::Layout::Grid::Item::Component
9
9
 
10
10
  accepts_html_attributes do |html_attrs|
11
- html_attrs[:class] = Ariadne::ViewComponents.tailwind_merger.merge([style(:grid), html_attrs[:class]].join(" "))
11
+ html_attrs[:class] = merge_tailwind_classes([style(:grid), html_attrs[:class]].join(" "))
12
12
  end
13
13
 
14
14
  style :grid do
@@ -6,10 +6,10 @@ module Ariadne
6
6
  module Grid
7
7
  module Item
8
8
  class Component < Ariadne::BaseComponent
9
- option :type, default: proc { :base }
9
+ option :type, default: -> { :base }
10
10
 
11
11
  accepts_html_attributes do |html_attrs|
12
- html_attrs[:class] = Ariadne::ViewComponents.tailwind_merger.merge([style(:item), html_attrs[:class]].join(" "))
12
+ html_attrs[:class] = merge_tailwind_classes([style(:item), html_attrs[:class]].join(" "))
13
13
  end
14
14
 
15
15
  def blank?
@@ -21,7 +21,7 @@ module Ariadne
21
21
  options[:theme] ||= :none
22
22
  options[:html_attrs] ||= {}
23
23
 
24
- options[:html_attrs][:class] = Ariadne::ViewComponents.tailwind_merger.merge([style(:trailing_visual), options[:html_attrs][:class] || ""].join(" "))
24
+ options[:html_attrs][:class] = merge_tailwind_classes([style(:trailing_visual), options[:html_attrs][:class] || ""].join(" "))
25
25
 
26
26
  Ariadne::UI::Button::Component.new(**options)
27
27
  },
@@ -8,7 +8,7 @@ module Ariadne
8
8
  renders_one :footer, Ariadne::BaseComponent::ACCEPT_ANYTHING
9
9
 
10
10
  accepts_html_attributes do |html_attrs|
11
- html_attrs[:class] = Ariadne::ViewComponents.tailwind_merger.merge([style(:container), html_attrs[:class]].join(" "))
11
+ html_attrs[:class] = merge_tailwind_classes([style(:container), html_attrs[:class]].join(" "))
12
12
  end
13
13
 
14
14
  style(:container) do
@@ -4,11 +4,13 @@
4
4
  module Ariadne
5
5
  module UI
6
6
  module Accordion
7
+ # A vertically stacked set of interactive headings that each reveal a section of content.
7
8
  class Component < Ariadne::BaseComponent
9
+ # Represent the item stored within the accordion.
8
10
  renders_many :items, Ariadne::UI::Accordion::Item::Component
9
11
 
10
12
  accepts_html_attributes do |html_attrs|
11
- html_attrs[:class] = Ariadne::ViewComponents.tailwind_merger.merge([style, html_attrs[:class]].join(" "))
13
+ html_attrs[:class] = merge_tailwind_classes([style, html_attrs[:class]].join(" "))
12
14
  end
13
15
 
14
16
  style do
@@ -1,15 +1,15 @@
1
1
  <div class="<%= style(:item) %>" data-controller="<%= Ariadne::UI::Accordion::Component.stimulus_name %>">
2
- <button type="button" class="<%= html_attrs[:class] %>" <%= html_attributes %> data-<%= stimulus_name %>-state-value="closed" data-action="click-><%= Ariadne::UI::Accordion::Component.stimulus_name %>#toggle">
2
+ <button type="button" class="<%= html_attrs[:class] %>" <%= html_attributes %>>
3
3
  <%= text %>
4
4
  <div data-<%= Ariadne::UI::Accordion::Component.stimulus_name %>-target="icon">
5
- <% if heroicon? %>
6
- <%= heroicon %>
7
- <% else %>
8
- <%= render Ariadne::UI::Heroicon::Component.new(icon: "chevron-down", size: :sm, variant: :solid, html_attrs: { class: "ariadne-transition-transform ariadne-duration-200 ariadne-opacity-50" }) %>
9
- <% end %>
10
- </div>
11
- </button>
12
- <div class="<%= style(:content) %>" data-<%= Ariadne::UI::Accordion::Component.stimulus_name %>-target="content">
13
- <%= content %>
5
+ <% if heroicon? %>
6
+ <%= heroicon %>
7
+ <% else %>
8
+ <%= render Ariadne::UI::Heroicon::Component.new(icon: "chevron-down", size: :sm, variant: :solid, html_attrs: { class: "ariadne-transition-transform ariadne-duration-200 ariadne-opacity-50" }) %>
9
+ <% end %>
14
10
  </div>
11
+ </button>
12
+ <div class="<%= style(:content) %>" data-<%= Ariadne::UI::Accordion::Component.stimulus_name %>-target="content">
13
+ <%= content %>
14
+ </div>
15
15
  </div>
@@ -4,15 +4,24 @@ module Ariadne
4
4
  module UI
5
5
  module Accordion
6
6
  module Item
7
+ # The item stored within the accordion.
7
8
  class Component < Ariadne::BaseComponent
9
+ # @param [String] text The of the accordion item.
8
10
  option :text
9
11
 
12
+ # Trailing visual at the left of the badge text.
13
+ #
14
+ # @param options [Hash] Same arguments as <%= link_to_component(Ariadne::UI::Heroicon::Component) %>.
10
15
  renders_one :heroicon, Ariadne::UI::Heroicon::Component
11
16
 
12
17
  accepts_html_attributes do |html_attrs|
13
- html_attrs[:class] = Ariadne::ViewComponents.tailwind_merger.merge([style(:trigger), html_attrs[:class]].join(" "))
14
- html_attrs[:data] ||= {}
15
- html_attrs[:data] = {}.merge(html_attrs[:data])
18
+ html_attrs[:class] = merge_tailwind_classes([style(:trigger), html_attrs[:class]].join(" "))
19
+
20
+ component_data_attrs = {
21
+ "#{stimulus_name}-state-value": "closed",
22
+ action: "click->#{stimulus_name}#toggle",
23
+ }
24
+ html_attrs[:data] = merge_data_attributes(html_attrs, component_data_attrs)
16
25
  end
17
26
 
18
27
  style(:item) do
@@ -1,7 +1,9 @@
1
- <% if src %>
2
- <img src="<%= src %>" title="<%= title %>" class="<%= style(size:, circle:, has_src: src.present?) %>">
3
- <% else %>
4
- <div title="<%= title %>" class="<%= style(size:, circle:, has_src: src.present?) %>">
5
- <%= placeholder_text %>
6
- </div>
7
- <% end %>
1
+ <span>
2
+ <% if src %>
3
+ <%= render Ariadne::UI::Image::Component.new(src:, alt:, size:, html_attrs: ) %>
4
+ <% else %>
5
+ <span class="<%= html_attrs[:class] %>" <%= html_attributes %>>
6
+ <%= placeholder_text %>
7
+ </span>
8
+ <% end %>
9
+ </span>
@@ -4,17 +4,46 @@
4
4
  module Ariadne
5
5
  module UI
6
6
  module Avatar
7
+ # A component that can represent a user or entity with an image or initials.
8
+ #
9
+ # @accessibility
10
+ # Images should have text alternatives that describe the information or function represented.
11
+ # If the avatar functions as a link, provide alt text that helps convey the function. For instance,
12
+ # if `Avatar` is a link to a user profile, the alt attribute should be `@kittenuser profile`
13
+ # rather than `@kittenuser`.
14
+ # [Learn more about best image practices (WAI Images)](https://www.w3.org/WAI/tutorials/images/)
7
15
  class Component < Ariadne::BaseComponent
8
- option :title, default: proc { "" }
16
+ # @param [String] initials The text to show if no `src` is provided.
17
+ option :text, optional: true
18
+ # @param [String] src The avatar's URL.
9
19
  option :src, optional: true
10
- option :size, default: proc { :base }
11
- option :circle, default: proc { false }
20
+ # @param [String] size The avatar's alt text.
21
+ option :alt, optional: true
22
+ # @param [String] size (Ariadne::UI::Badge::DEFAULT_SIZE) The avatar's size. <%= one_of(Ariadne::SizeHelper::VALID_SIZES) %>
23
+ option :size, default: proc { :md }
24
+
25
+ DEFAULT_SHAPE = :circle
26
+ SHAPE_OPTIONS = [DEFAULT_SHAPE, :square].freeze
27
+ # @param [Symbol] shape Shape of the avatar. <%= one_of(Ariadne::UI::Avatar::Component::SHAPE_OPTIONS) %>
28
+ option :shape, default: proc { DEFAULT_SHAPE }
12
29
 
13
30
  attr_reader :placeholder_text
14
31
 
32
+ accepts_html_attributes do |html_attrs|
33
+ html_attrs[:class] = merge_tailwind_classes([style(size:, shape:, has_src: src.present?), html_attrs[:class]].join(" "))
34
+ end
35
+
15
36
  style do
16
37
  base do
17
- "select-none object-cover"
38
+ [
39
+ "ariadne-select-none",
40
+ "ariadne-object-cover",
41
+ "ariadne-outline",
42
+ "ariadne-outline-1",
43
+ "-ariadne-outline-offset-1",
44
+ "ariadne-outline-black/20",
45
+ "dark:ariadne-outline-white/20",
46
+ ]
18
47
  end
19
48
 
20
49
  variants do
@@ -25,9 +54,20 @@ module Ariadne
25
54
  lg { ["ariadne-size-10", "ariadne-text-lg", "ariadne-rounded-lg"] }
26
55
  xl { ["ariadne-size-12", "ariadne-text-xl", "ariadne-rounded-xl"] }
27
56
  end
28
- circle do
29
- yes { "!ariadne-rounded-full" }
57
+
58
+ shape do
59
+ square do
60
+ []
61
+ end
62
+
63
+ circle do
64
+ [
65
+ "ariadne-rounded-full",
66
+ "*:ariadne-rounded-full",
67
+ ]
68
+ end
30
69
  end
70
+
31
71
  has_src do
32
72
  no do
33
73
  [
@@ -45,8 +85,16 @@ module Ariadne
45
85
  end
46
86
 
47
87
  def before_render
88
+ validate!
89
+
90
+ # One char long or two
48
91
  len = [:xs, :sm, :md].include?(size) ? 0 : 1
49
- @placeholder_text = (title || "").strip.split[0..len].map { |word| word.capitalize[0] }.join
92
+ @placeholder_text = (text || "").strip.split[0..len].map { |word| word.capitalize[0] }.join
93
+ end
94
+
95
+ private def validate!
96
+ raise ArgumentError, "Must provide either `text` or `src`" if @text.blank? && @src.blank?
97
+ raise ArgumentError, "Must provide only `text` or `src`, not both" if @text.present? && @src.present?
50
98
  end
51
99
  end
52
100
  end
@@ -4,9 +4,19 @@
4
4
  module Ariadne
5
5
  module UI
6
6
  module Badge
7
+ # Use the Badge component to highlight important information.
7
8
  class Component < Ariadne::BaseComponent
9
+ DEFAULT_SIZE = :md
10
+ DEFAULT_COLOR = :none
11
+
12
+ # @param [String] text The text within the badge.
8
13
  option :text, default: proc { nil }
9
- option :size, default: proc { :md }
14
+
15
+ # @param [Symbol] size (Ariadne::UI::Badge::DEFAULT_SIZE) The size of the badge. <%= one_of(Ariadne::SizeHelper::VALID_SIZES) %>
16
+ option :size, default: proc { DEFAULT_SIZE }
17
+
18
+ # @param [Symbol] color (Ariadne::ColorHelper::DEFAULT_COLOR) The color of the badge. <%= one_of(Ariadne::ColorHelper::VALID_COLORS.keys) %>
19
+ option :color, default: proc { DEFAULT_COLOR }
10
20
 
11
21
  # Leading visuals appear to the left of the badge text.
12
22
  #
@@ -14,23 +24,22 @@ module Ariadne
14
24
  #
15
25
  # - `leading_visual_heroicon` for a <%= link_to_component(Ariadne::UI::Heroicon::Component) %>.
16
26
  # - `leading_visual_color_dot` for a <%= link_to_component(Ariadne::UI::ColorDot::Component) %>.
27
+ #
28
+ # @param options [Hash] Same arguments as <%= link_to_component(Ariadne::UI::Heroicon::Component) %> and <%= link_to_component(Ariadne::UI::ColorDot::Component) %>.
17
29
  renders_one :leading_visual, types: {
18
- heroicon: lambda { |**options|
19
- options[:size] = size
20
- Ariadne::UI::Heroicon::Component.new(**options)
21
- },
22
- color_dot: lambda { |**options|
23
- options[:size] = size # Use the same size as the badge
24
- Ariadne::UI::ColorDot::Component.new(**options)
25
- },
30
+ heroicon: Ariadne::UI::Heroicon::Component,
31
+ color_dot: Ariadne::UI::ColorDot::Component,
26
32
  }
27
33
 
28
34
  include Ariadne::Behaviors::Tooltipable
29
35
 
30
- # must be dont here rather than within an `accepts_html_attributes` block
31
- # because the padding class is dependent on the slot's existence, which isn't known until now
36
+ accepts_html_attributes do |html_attrs|
37
+ end
38
+
39
+ # must be done here rather than within an `accepts_html_attributes` block
40
+ # because the padding class is dependent on the `with_leading_item` slot's existence, which isn't known until now
32
41
  def before_render
33
- html_attrs[:class] = Ariadne::ViewComponents.tailwind_merger.merge([style(size:, with_leading_item: leading_visual ? :yes : :no), html_attrs[:class]].join(" "))
42
+ html_attrs[:class] = merge_tailwind_classes([style(size:, color:, with_leading_item: leading_visual ? :yes : :no), html_attrs[:class]].join(" "))
34
43
  end
35
44
 
36
45
  style do
@@ -38,7 +47,7 @@ module Ariadne
38
47
  [
39
48
  "ariadne-truncate",
40
49
  "ariadne-max-w-full",
41
- "ariadne-border-0.5",
50
+ "ariadne-border",
42
51
  "ariadne-border-solid",
43
52
  "ariadne-border-black/10",
44
53
  "dark:ariadne-border-white/10",
@@ -56,15 +65,25 @@ module Ariadne
56
65
  end
57
66
 
58
67
  variants do
68
+ extend Ariadne::ColorHelper
69
+ include_colors!
70
+
59
71
  with_leading_item do
60
72
  yes { "ariadne-inline-flex ariadne-items-center" }
61
73
  no { "ariadne-inline-block" }
62
74
  end
63
75
 
76
+ theme do
77
+ outline { "ariadne-bg-transparent ariadne-text-blue-400 ariadne-border-blue-400" }
78
+ ghost { "ariadne-bg-blue-400 ariadne-text-white ariadne-border-blue-400" }
79
+ end
80
+
64
81
  size do
65
- xs { "ariadne-leading-5 ariadne-text-xs ariadne-rounded-md" }
66
- sm { "ariadne-leading-6 ariadne-text-sm ariadne-rounded-lg" }
67
- md { "ariadne-leading-7 ariadne-text-base ariadne-rounded-xl" }
82
+ xs { "ariadne-text-xs ariadne-leading-3" }
83
+ sm { "ariadne-text-xs ariadne-leading-4" }
84
+ md { "ariadne-text-base ariadne-leading-5" }
85
+ lg { "ariadne-text-lg ariadne-leading-6" }
86
+ xl { "ariadne-text-xl ariadne-leading-8" }
68
87
  end
69
88
  end
70
89
 
@@ -0,0 +1,23 @@
1
+ <div class="<%= html_attrs[:class] %>" <%= html_attributes %>>
2
+ <section aria-labelledby="<%= @header_id %>" class="ariadne-p-4">
3
+ <div class="ariadne-flex ariadne-items-center">
4
+ <div class="ariadne-flex-shrink-0 <%= style(:text, scheme:) %>">
5
+ <%= render heroicon_or_default %>
6
+ </div>
7
+ <div class="ariadne-ml-3 ariadne-w-0 ariadne-flex-1 ariadne-pt-0.5 <%= style(:text, scheme:) %>">
8
+ <p id="<%= @header_id %>" class="ariadne-text-sm ariadne-font-semibold" data-<%= Ariadne::UI::Banner::Component.stimulus_name %>-target="title"><%= title %></p>
9
+ <p class="ariadne-mt-1 ariadne-text-sm" data-<%= Ariadne::UI::Banner::Component.stimulus_name %>-target="message"><%= content %></p>
10
+ </div>
11
+ <% if action %>
12
+ <div class="ariadne-flex">
13
+ <%= action %>
14
+ </div>
15
+ <% end %>
16
+ <div class="ariadne-ml-4 ariadne-flex ariadne-flex-shrink-0 ">
17
+ <% if @dismissible %>
18
+ <%= render Ariadne::UI::Button::Component.new(scheme: :nude, html_attrs: { class: style(:dismissable, scheme:), aria: { label: dismiss_label }, data: { action: "click->#{stimulus_name}#dismiss" } }).as_icon(icon: "x-mark", variant: :outline) %>
19
+ <% end %>
20
+ </div>
21
+ </div>
22
+ </section>
23
+ </div>