ariadne_view_components 0.0.6 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +28 -0
  3. data/README.md +5 -1
  4. data/app/assets/javascripts/ariadne-form-with.d.ts +20 -0
  5. data/app/assets/javascripts/ariadne-form.d.ts +22 -0
  6. data/app/assets/javascripts/ariadne.d.ts +1 -1
  7. data/app/assets/javascripts/ariadne_view_components.js +7 -1
  8. data/app/assets/javascripts/ariadne_view_components.js.map +1 -1
  9. data/app/assets/javascripts/comment-component.d.ts +13 -0
  10. data/app/assets/javascripts/rich-text-area-component.d.ts +4 -0
  11. data/app/{components/ariadne/time_ago_component.d.ts → assets/javascripts/time-ago-component.d.ts} +0 -0
  12. data/app/assets/stylesheets/{application.ariadne_view_components.css → ariadne_view_components.css} +1 -0
  13. data/app/assets/stylesheets/prosemirror.css +323 -0
  14. data/app/components/ariadne/ariadne-form.ts +96 -0
  15. data/app/components/ariadne/ariadne.ts +8 -1
  16. data/app/components/ariadne/base_button.rb +6 -7
  17. data/app/components/ariadne/base_component.rb +13 -131
  18. data/app/components/ariadne/blankslate_component.html.erb +5 -5
  19. data/app/components/ariadne/blankslate_component.rb +4 -9
  20. data/app/components/ariadne/body_component.rb +1 -1
  21. data/app/components/ariadne/button_component.rb +7 -6
  22. data/app/components/ariadne/clipboard_copy_component.html.erb +3 -2
  23. data/app/components/ariadne/comment-component.ts +55 -0
  24. data/app/components/ariadne/comment_component.html.erb +17 -20
  25. data/app/components/ariadne/comment_component.rb +29 -17
  26. data/app/components/ariadne/component.rb +4 -4
  27. data/app/components/ariadne/container_component.rb +1 -1
  28. data/app/components/ariadne/counter_component.rb +4 -4
  29. data/app/components/ariadne/flash_component.html.erb +12 -12
  30. data/app/components/ariadne/flash_component.rb +16 -16
  31. data/app/components/ariadne/flex_component.rb +5 -7
  32. data/app/components/ariadne/footer_component.html.erb +1 -1
  33. data/app/components/ariadne/footer_component.rb +1 -1
  34. data/app/components/ariadne/grid_component.html.erb +4 -4
  35. data/app/components/ariadne/grid_component.rb +9 -9
  36. data/app/components/ariadne/header_component.html.erb +7 -7
  37. data/app/components/ariadne/header_component.rb +8 -8
  38. data/app/components/ariadne/heading_component.rb +3 -3
  39. data/app/components/ariadne/heroicon_component.rb +4 -4
  40. data/app/components/ariadne/inline_flex_component.rb +7 -7
  41. data/app/components/ariadne/link_component.rb +2 -2
  42. data/app/components/ariadne/list_component.rb +6 -5
  43. data/app/components/ariadne/narrow_container_component.html.erb +3 -0
  44. data/app/components/ariadne/narrow_container_component.rb +30 -0
  45. data/app/components/ariadne/panel_bar_component.html.erb +20 -0
  46. data/app/components/ariadne/panel_bar_component.rb +79 -0
  47. data/app/components/ariadne/pill_component.rb +2 -2
  48. data/app/components/ariadne/rich-text-area-component.ts +32 -0
  49. data/app/components/ariadne/rich_text_area_component.html.erb +6 -0
  50. data/app/components/ariadne/rich_text_area_component.rb +35 -0
  51. data/app/components/ariadne/slideover-component.ts +3 -3
  52. data/app/components/ariadne/slideover_component.html.erb +3 -3
  53. data/app/components/ariadne/slideover_component.rb +1 -1
  54. data/app/components/ariadne/tab_bar_component.html.erb +3 -0
  55. data/app/components/ariadne/tab_bar_component.rb +45 -0
  56. data/app/components/ariadne/tab_component.html.erb +7 -0
  57. data/app/components/ariadne/tab_component.rb +43 -0
  58. data/app/components/ariadne/{time_ago_component.ts → time-ago-component.ts} +0 -0
  59. data/app/components/ariadne/time_ago_component.rb +2 -2
  60. data/app/components/ariadne/timeline_component.html.erb +6 -6
  61. data/app/components/ariadne/tooltip-component.ts +3 -3
  62. data/app/components/ariadne/tooltip_component.html.erb +1 -1
  63. data/app/components/ariadne/tooltip_component.rb +1 -1
  64. data/app/lib/ariadne/action_view_extensions/form_helper.rb +4 -1
  65. data/app/lib/ariadne/fetch_or_fallback_helper.rb +3 -1
  66. data/app/lib/ariadne/form_builder.rb +10 -10
  67. data/app/lib/ariadne/icon_helper.rb +1 -1
  68. data/exe/tailwindcss +21 -0
  69. data/lib/ariadne/view_components/commands.rb +90 -0
  70. data/lib/ariadne/view_components/engine.rb +41 -4
  71. data/lib/ariadne/view_components/upstream.rb +20 -0
  72. data/lib/ariadne/view_components/version.rb +1 -1
  73. data/lib/ariadne/view_components.rb +1 -1
  74. data/lib/rubocop/config/default.yml +0 -6
  75. data/lib/rubocop/cop/ariadne/no_tag_memoize.rb +1 -0
  76. data/lib/tasks/ariadne_view_components.rake +2 -1
  77. data/lib/tasks/build.rake +30 -0
  78. data/lib/tasks/docs.rake +6 -1
  79. data/static/arguments.yml +99 -4
  80. data/static/audited_at.json +8 -2
  81. data/static/classes.yml +195 -181
  82. data/static/constants.json +112 -72
  83. data/static/statuses.json +8 -2
  84. data/tailwind.config.js +65 -0
  85. metadata +38 -36
  86. data/app/assets/builds/ariadne_view_components.css +0 -1874
  87. data/app/components/ariadne/ariadne.d.ts +0 -1
  88. data/app/components/ariadne/ariadne.js +0 -9
  89. data/app/components/ariadne/clipboard-copy-component.d.ts +0 -4
  90. data/app/components/ariadne/clipboard-copy-component.js +0 -18
  91. data/app/components/ariadne/clipboard_copy_component.d.ts +0 -4
  92. data/app/components/ariadne/clipboard_copy_component.js +0 -18
  93. data/app/components/ariadne/slideover-component.d.ts +0 -9
  94. data/app/components/ariadne/slideover-component.js +0 -20
  95. data/app/components/ariadne/slideover_component.d.ts +0 -9
  96. data/app/components/ariadne/slideover_component.js +0 -19
  97. data/app/components/ariadne/time_ago_component.js +0 -1
  98. data/app/components/ariadne/tooltip-component.d.ts +0 -24
  99. data/app/components/ariadne/tooltip-component.js +0 -42
  100. data/lib/ariadne/classify/utilities.rb +0 -199
  101. data/lib/ariadne/classify/utilities.yml +0 -1817
  102. data/lib/ariadne/classify/validation.rb +0 -18
  103. data/lib/ariadne/classify.rb +0 -124
  104. data/lib/rubocop/cop/ariadne/ariadne_heroicon.rb +0 -252
  105. data/lib/rubocop/cop/ariadne/component_name_migration.rb +0 -35
  106. data/lib/rubocop/cop/ariadne/system_argument_instead_of_class.rb +0 -57
  107. data/lib/tasks/utilities.rake +0 -121
@@ -6,7 +6,7 @@ module Ariadne
6
6
  # `Heroicon` renders an <%= link_to_heroicons %> with <%= link_to_attributes_docs %>.
7
7
  # `Heroicon` can also be rendered with the `heroicon` helper.
8
8
  class HeroiconComponent < Ariadne::Component
9
- DEFAULT_TEXT_CLASSES = "pl-2"
9
+ DEFAULT_TEXT_CLASSES = "ariadne-pl-2"
10
10
 
11
11
  include IconHelper
12
12
  include HeroiconsHelper
@@ -57,7 +57,7 @@ module Ariadne
57
57
  variant: HeroiconsHelper::Icon::VARIANT_OUTLINE, },
58
58
  { name: "trash",
59
59
  variant: HeroiconsHelper::Icon::VARIANT_OUTLINE, },
60
- { name: "x",
60
+ { name: "x-mark",
61
61
  variant: HeroiconsHelper::Icon::VARIANT_OUTLINE, },
62
62
  ].freeze
63
63
 
@@ -74,7 +74,7 @@ module Ariadne
74
74
  # @param tag [Symbol, String] The rendered tag name
75
75
  # @param classes [String] <%= link_to_classes_docs %>
76
76
  # @param icon [Symbol, String] Name of <%= link_to_heroicons %> to use.
77
- # @param variant [String] <%= one_of(HeroiconsHelper::Icon::VARIANTS, sort: false) %>
77
+ # @param variant [String] <%= one_of(HeroiconsHelper::Icon::VALID_VARIANTS, sort: false) %>
78
78
  # @param size [Symbol] <%= one_of(Ariadne::HeroiconComponent::SIZE_MAPPINGS, sort: false) %>
79
79
  # @param attributes [Hash] <%= link_to_attributes_docs %>
80
80
  # @param text_classes [String] <%= link_to_classes_docs %>
@@ -106,7 +106,7 @@ module Ariadne
106
106
  width: @attributes[:width],
107
107
  }
108
108
 
109
- @icon = heroicon(icon, variant: variant, **attributes) # rubocop:disable Ariadne/AriadneHeroicon
109
+ @icon = heroicon(icon, variant: variant, **attributes)
110
110
 
111
111
  @classes = class_names(
112
112
  @icon.attributes[:class],
@@ -9,24 +9,24 @@ module Ariadne
9
9
  # present a static list of SVG images (and can be embedded in buttons or shown alone).
10
10
  class InlineFlexComponent < Ariadne::Component
11
11
  DEFAULT_TAG = :span
12
- DEFAULT_CLASSES = "inline-flex items-baseline"
12
+ DEFAULT_CLASSES = "ariadne-inline-flex ariadne-items-baseline"
13
13
 
14
14
  STATE_OPTIONS = [:closed, :open].freeze
15
15
 
16
16
  STATE_OPEN_SVG = <<~MSG
17
- <svg viewBox="0 0 24 24" width="12" height="12" class="stroke-state-open" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
17
+ <svg viewBox="0 0 24 24" width="12" height="12" class="ariadne-stroke-state-open" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
18
18
  <circle cx="12" cy="12" r="10"></circle>
19
19
  </svg>
20
20
  MSG
21
21
  STATE_CLOSED_SVG = <<~MSG
22
- <svg viewBox="0 0 24 24" width="12" height="12" class="stroke-state-closed fill-state-closed " stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
22
+ <svg viewBox="0 0 24 24" width="12" height="12" class="ariadne-stroke-state-closed fill-state-closed " stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
23
23
  <circle cx="12" cy="12" r="10"></circle>
24
24
  </svg>
25
25
  MSG
26
26
 
27
- DEFAULT_TEXT_OPEN_CLASSES = "text-state-open"
28
- DEFAULT_TEXT_CLOSED_CLASSES = "text-state-closed"
29
- DEFAULT_TEXT_CLASSES = "pl-2 text-sm font-medium text-gray-900"
27
+ DEFAULT_TEXT_OPEN_CLASSES = "ariadne-text-state-open"
28
+ DEFAULT_TEXT_CLOSED_CLASSES = "ariadne-text-state-closed"
29
+ DEFAULT_TEXT_CLASSES = "ariadne-pl-2 ariadne-text-sm ariadne-font-medium ariadne-text-gray-900"
30
30
  renders_one :icon, lambda { |tag: :svg, icon:, variant:, size: Ariadne::HeroiconComponent::SIZE_DEFAULT, classes: "", attributes: {}, text_classes: "", text_attributes: {}|
31
31
  actual_text_classes = class_names(DEFAULT_TEXT_CLASSES, text_classes)
32
32
  Ariadne::HeroiconComponent.new(tag: tag, icon: icon, variant: variant, size: size, classes: classes, attributes: attributes, text_classes: actual_text_classes, text_attributes: text_attributes) { content }
@@ -36,7 +36,7 @@ module Ariadne
36
36
  Ariadne::BaseComponent.new(tag: :span, classes: classes, attributes: attributes) { content }
37
37
  }
38
38
 
39
- DEFAULT_LABEL_CLASSES = "pl-2 text-sm font-medium text-gray-900"
39
+ DEFAULT_LABEL_CLASSES = "ariadne-pl-2 ariadne-text-sm ariadne-font-medium ariadne-text-gray-900"
40
40
  renders_one :text, lambda { |classes: "", attributes: {}|
41
41
  actual_classes = class_names(DEFAULT_LABEL_CLASSES, classes)
42
42
  Ariadne::BaseComponent.new(tag: :span, classes: actual_classes, attributes: attributes) { content }
@@ -6,8 +6,8 @@ module Ariadne
6
6
  DEFAULT_TAG = :a
7
7
  TAG_OPTIONS = [DEFAULT_TAG, :span].freeze
8
8
 
9
- DEFAULT_CLASSES = "cursor-pointer"
10
- DEFAULT_ACTIONABLE_CLASSES = " cursor-pointer underline decoration-double font-semibold hover:text-button-text-color focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-500"
9
+ DEFAULT_CLASSES = "ariadne-cursor-pointer"
10
+ DEFAULT_ACTIONABLE_CLASSES = " ariadne-cursor-pointer ariadne-underline ariadne-decoration-double ariadne-font-semibold hover:ariadne-text-button-text-color focus:ariadne-outline-none focus:ariadne-ring-2 focus:ariadne-ring-offset-2 focus:ariadne-ring-purple-500"
11
11
 
12
12
  # `Tooltip` that appears on mouse hover or keyboard focus over the button. Use tooltips sparingly and as a last resort.
13
13
  # **Important:** This tooltip defaults to `type: :description`. In a few scenarios, `type: :label` may be more appropriate.
@@ -3,9 +3,10 @@
3
3
  module Ariadne
4
4
  # `List` is used to show a list of items in a vertical format.
5
5
  class ListComponent < Ariadne::Component
6
- DEFAULT_UL_CLASSES = "divide-y divide-gray-300"
6
+ DEFAULT_TAG = :ul
7
+ DEFAULT_UL_CLASSES = "ariadne-divide-y ariadne-divide-gray-300"
7
8
 
8
- renders_many :items, "Item"
9
+ renders_many :items, "ListItem"
9
10
 
10
11
  # @example Basic
11
12
  # <% numbers = [1, 2, 3] %>
@@ -21,7 +22,7 @@ module Ariadne
21
22
  # @param classes [String] <%= link_to_classes_docs %>
22
23
  # @param attributes [Hash] <%= link_to_attributes_docs %>
23
24
  def initialize(classes: "", attributes: {})
24
- @tag = :ul
25
+ @tag = DEFAULT_TAG
25
26
  @classes = class_names(DEFAULT_UL_CLASSES, classes)
26
27
  @attributes = attributes
27
28
  end
@@ -32,8 +33,8 @@ module Ariadne
32
33
 
33
34
  # This component is part of `ListComponent` and should not be
34
35
  # used as a standalone component.
35
- class Item < Ariadne::Component
36
- DEFAULT_ITEM_CLASSES = "relative p-1.5 focus:ring-2 focus:ring-offset-2 focus:ring-purple-500 hover:bg-button-hover-color"
36
+ class ListItem < Ariadne::Component
37
+ DEFAULT_ITEM_CLASSES = "ariadne-relative ariadne-p-1.5 focus:ariadne-ring-2 focus:ariadne-ring-offset-2 focus:ariadne-ring-purple-500 hover:ariadne-bg-button-hover-color"
37
38
 
38
39
  renders_one :entry, lambda { |static_content = nil, &block|
39
40
  next static_content if static_content.present?
@@ -0,0 +1,3 @@
1
+ <%= render Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes) do |component| %>
2
+ <%= content %>
3
+ <% end %>
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ariadne
4
+ # Add a general description of component here
5
+ # Add additional usage considerations or best practices that may aid the user to use the component correctly.
6
+ # @accessibility Add any accessibility considerations
7
+ class NarrowContainerComponent < Ariadne::Component
8
+ DEFAULT_TAG = :div
9
+ TAG_OPTIONS = [DEFAULT_TAG].freeze
10
+
11
+ DEFAULT_CLASSES = "ariadne-max-w-7xl ariadne-mx-auto ariadne-py-12 ariadne-px-4 sm:ariadne-px-6 lg:ariadne-py-16 lg:ariadne-px-8"
12
+
13
+ # @example Default
14
+ # <%= render(Ariadne::NarrowContainerComponent.new) do |container| %>
15
+ # <%= render(Ariadne::ButtonComponent.new) { "Click me!" } %>
16
+ # <% end %>
17
+ #
18
+ # @param classes [String] <%= link_to_classes_docs %>
19
+ # @param attributes [Hash] <%= link_to_attributes_docs %>
20
+ def initialize(classes: "", attributes: {})
21
+ @tag = :div
22
+ @classes = class_names(
23
+ DEFAULT_CLASSES,
24
+ classes
25
+ )
26
+
27
+ @attributes = attributes
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,20 @@
1
+ <%= render Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes) do |list| %>
2
+ <% panels.each_with_index do |panel, idx| %>
3
+ <%= render Ariadne::BaseComponent.new(tag: :li, classes: panel.classes, attributes: panel.attributes) do %>
4
+ <%= render Ariadne::BaseComponent.new(tag: :div, classes: Ariadne::PanelBarComponent::PanelItem::DEFAULT_WRAPPER_CLASSES) do %>
5
+ <span class="ariadne-px-6 ariadne-py-4 ariadne-flex ariadne-items-center ariadne-text-sm ariadne-font-medium">
6
+ <%= panel.icon %>
7
+ <span class="ariadne-ml-4 ariadne-text-sm ariadne-font-medium ariadne-text-gray-900"><%= panel.label %></span>
8
+ <!-- Arrow separator for lg screens and up -->
9
+ <% if idx + 1 < panels.size %>
10
+ <div class="md:ariadne-block ariadne-hidden ariadne-absolute ariadne-top-0 ariadne-right-0 ariadne-h-full ariadne-w-5" aria-hidden="true">
11
+ <svg class="ariadne-h-full ariadne-w-full ariadne-text-gray-300" viewBox="0 0 22 80" fill="none" preserveAspectRatio="none">
12
+ <path d="M0 -2L20 40L0 82" vector-effect="non-scaling-stroke" stroke="currentcolor" stroke-linejoin="round"></path>
13
+ </svg>
14
+ </div>
15
+ <% end %>
16
+ </span>
17
+ <% end %>
18
+ <% end %>
19
+ <% end %>
20
+ <% end %>
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ariadne
4
+ # Add a general description of component here
5
+ # Add additional usage considerations or best practices that may aid the user to use the component correctly.
6
+ # @accessibility Add any accessibility considerations
7
+ class PanelBarComponent < Ariadne::Component
8
+ DEFAULT_TAG = :ol
9
+ TAG_OPTIONS = [DEFAULT_TAG].freeze
10
+
11
+ DEFAULT_CLASSES = "ariadne-border ariadne-border-gray-300 ariadne-rounded-md ariadne-divide-y ariadne-divide-gray-300 md:ariadne-flex md:ariadne-divide-y-0"
12
+
13
+ renders_many :panels, "PanelItem"
14
+
15
+ # @example Default
16
+ #
17
+ # <%= render(Ariadne::PanelBarComponent.new) { "Example" } %>
18
+ #
19
+ # @param tag [Symbol, String] The rendered tag name.
20
+ # @param classes [String] <%= link_to_classes_docs %>
21
+ # @param attributes [Hash] <%= link_to_attributes_docs %>
22
+ def initialize(classes: "", attributes: {})
23
+ @tag = DEFAULT_TAG
24
+ @classes = class_names(
25
+ DEFAULT_CLASSES,
26
+ classes
27
+ )
28
+
29
+ @attributes = attributes
30
+ @attributes[:role] ||= "list"
31
+ end
32
+
33
+ # def render?
34
+ # items.any?
35
+ # end
36
+
37
+ # This component is part of `PanelBarComponent` and should not be
38
+ # used as a standalone component.
39
+ class PanelItem < Ariadne::Component
40
+ DEFAULT_ITEM_CLASSES = "ariadne-relative md:ariadne-flex-1 md:ariadne-flex"
41
+ DEFAULT_WRAPPER_CLASSES = "group ariadne-flex ariadne-items-center ariadne-w-full"
42
+
43
+ renders_one :icon, lambda { |static_content = nil, &block|
44
+ next static_content if static_content.present?
45
+
46
+ view_context.capture { block&.call }
47
+ }
48
+
49
+ renders_one :label, lambda { |static_content = nil, &block|
50
+ next static_content if static_content.present?
51
+
52
+ view_context.capture { block&.call }
53
+ }
54
+
55
+ attr_reader :link, :classes, :attributes
56
+
57
+ def initialize(link: {}, classes: "", attributes: {})
58
+ @link = link
59
+ if @link.present?
60
+ @link["classes"] = class_names(DEFAULT_WRAPPER_CLASSES, @link["classes"])
61
+ end
62
+ @classes = class_names(DEFAULT_ITEM_CLASSES, classes)
63
+ @attributes = attributes
64
+ end
65
+
66
+ def selected?
67
+ @selected
68
+ end
69
+
70
+ def linked?
71
+ @link.present?
72
+ end
73
+
74
+ def call
75
+ Ariadne::BaseComponent.new(tag: :div, classes: @classes, attributes: @attributes)
76
+ end
77
+ end
78
+ end
79
+ end
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ariadne
4
- # Creates a rounded label that resembles a medicine pill.
4
+ # Creates a ariadne-rounded label that resembles a medicine pill.
5
5
  class PillComponent < Ariadne::Component
6
6
  DEFAULT_TAG = :span
7
7
  TAG_OPTIONS = [DEFAULT_TAG].freeze
8
8
 
9
- DEFAULT_CLASSES = "flex-shrink-0 inline-block px-2 py-0.5 text-xs font-medium rounded-full"
9
+ DEFAULT_CLASSES = "ariadne-flex-shrink-0 ariadne-inline-block ariadne-px-2 ariadne-py-0.5 ariadne-text-xs ariadne-font-medium ariadne-rounded-full"
10
10
 
11
11
  # @example Default
12
12
  #
@@ -0,0 +1,32 @@
1
+ import {Controller} from '@hotwired/stimulus'
2
+
3
+ import {Editor} from '@tiptap/core'
4
+ import {StarterKit} from '@tiptap/starter-kit'
5
+
6
+ export default class RichTextArea extends Controller {
7
+ connect() {
8
+ const editorElement = document.querySelector('.tiptap-editor')
9
+ if (editorElement) {
10
+ new Editor({
11
+ element: editorElement,
12
+ extensions: [StarterKit],
13
+ content: 'Hello World!',
14
+ editorProps: {
15
+ attributes: {
16
+ class:
17
+ 'ariadne-prose ariadne-prose-sm sm:ariadne-prose lg:ariadne-prose-lg xl:ariadne-prose-2xl ariadne-m-5 focus:ariadne-outline-none'
18
+ }
19
+ }
20
+ })
21
+
22
+ const tiptapValueContainer = document.querySelector('input[data-tiptap-value-container=true]')
23
+ if (tiptapValueContainer) {
24
+ const parentForm = editorElement.closest('form')
25
+
26
+ parentForm?.addEventListener('submit', () => {
27
+ tiptapValueContainer.setAttribute('value', editorElement.textContent || '')
28
+ })
29
+ }
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,6 @@
1
+ <%= render(Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes)) do %>
2
+ <% if @has_form %>
3
+ <input type="hidden" data-tiptap-value-container=true name="<%= @name %>" id="<%= @name %>" />
4
+ <% end %>
5
+ <textarea class="tiptap-editor"></textarea>
6
+ <% end %>
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ariadne
4
+ # Add a general description of component here
5
+ # Add additional usage considerations or best practices that may aid the user to use the component correctly.
6
+ # @accessibility Add any accessibility considerations
7
+ class RichTextAreaComponent < Ariadne::Component
8
+ DEFAULT_TAG = :div
9
+ DEFAULT_CLASSES = "ariadne-block ariadne-w-full ariadne-border-0 ariadne-py-3 focus:ariadne-ring-0 sm:ariadne-text-sm"
10
+
11
+ # @example Default
12
+ #
13
+ # <%= render(Ariadne::RichTextAreaComponent.new(name: "bodytext", sr_label: "Enter message contents")) { "Example" } %>
14
+ #
15
+ # @param name [Symbol] Identifies the form/param name for this rich text area.
16
+ # @param sr_label [String] A label to introduce these tabs for screen readers.
17
+ # @param has_form [Boolean] Indicates whether this component is wrapped in a form.
18
+ # @param classes [String] <%= link_to_classes_docs %>
19
+ # @param attributes [Hash] <%= link_to_attributes_docs %>
20
+ def initialize(name:, sr_label:, has_form: true, classes: "", attributes: {})
21
+ @tag = DEFAULT_TAG
22
+ @name = name
23
+ @sr_label = sr_label
24
+ @has_form = has_form
25
+
26
+ @classes = class_names(
27
+ DEFAULT_CLASSES,
28
+ classes
29
+ )
30
+ @attributes = attributes
31
+ @attributes[:"data-controller"] = "rich-text-area-component"
32
+ @attributes[:"data-has-form"] = true if @has_form
33
+ end
34
+ end
35
+ end
@@ -9,13 +9,13 @@ export default class SlideoverComponent extends Controller {
9
9
  declare readonly buttonWrapperTarget: HTMLDivElement
10
10
 
11
11
  toggle() {
12
- this.expandableTarget.classList.toggle('hidden')
12
+ this.expandableTarget.classList.toggle('ariadne-hidden')
13
13
  this.expandWrapperTarget.classList.toggle('bg-filter-panel')
14
14
  for (const slidePanel of this.slidePanelTargets) {
15
- slidePanel.classList.toggle('hidden')
15
+ slidePanel.classList.toggle('ariadne-hidden')
16
16
  }
17
17
  this.buttonWrapperTarget.classList.toggle('bg-filter-panel')
18
- if (document.getElementById('btnClose')?.classList.contains('hidden')) {
18
+ if (document.getElementById('btnClose')?.classList.contains('ariadne-hidden')) {
19
19
  const formID = this.buttonWrapperTarget.getAttribute('data-slideover-component-form-id')
20
20
  if (formID) {
21
21
  const form = <HTMLFormElement>document.getElementById(formID)
@@ -1,9 +1,9 @@
1
1
  <%= render Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes) do |slideover| %>
2
- <div data-slideover-component-target="expandWrapper" class="flex flex-col z-10">
3
- <div data-slideover-component-target="expandable" class="hidden bg-filter-panel px-3 pb-4">
2
+ <div data-slideover-component-target="expandWrapper" class="ariadne-flex ariadne-flex-col ariadne-z-10">
3
+ <div data-slideover-component-target="expandable" class="ariadne-hidden bg-filter-panel ariadne-px-3 ariadne-pb-4">
4
4
  <%= content %>
5
5
  </div>
6
- <div data-slideover-component-target="buttonWrapper" data-slideover-component-form-id="<%= @form_id %>" class="relative flex justify-center">
6
+ <div data-slideover-component-target="buttonWrapper" data-slideover-component-form-id="<%= @form_id %>" class="ariadne-relative ariadne-flex ariadne-justify-center">
7
7
  <%= open_button %>
8
8
  <%= close_button %>
9
9
  </div>
@@ -14,7 +14,7 @@ module Ariadne
14
14
 
15
15
  DEFAULT_CLASSES = ""
16
16
 
17
- DEFAULT_BUTTON_CLASSES = "inline-flex items-center shadow-sm px-4 py-1.5 pb-2 text-sm leading-5 font-medium rounded-full " + Ariadne::ButtonComponent::SCHEME_CLASS_MAPPINGS[:default]
17
+ DEFAULT_BUTTON_CLASSES = "ariadne-inline-flex ariadne-items-center ariadne-shadow-sm ariadne-px-4 ariadne-py-1.5 ariadne-pb-2 ariadne-text-sm ariadne-leading-5 ariadne-font-medium ariadne-rounded-full " + Ariadne::ButtonComponent::SCHEME_CLASS_MAPPINGS[:default]
18
18
  renders_one :open_button, lambda { |label:, classes: "", attributes: {}, text_classes: ""|
19
19
  actual_classes = class_names(DEFAULT_BUTTON_CLASSES, classes)
20
20
 
@@ -0,0 +1,3 @@
1
+ <%= render Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes) do |component| %>
2
+ <%= content %>
3
+ <% end %>
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ariadne
4
+ # A container for a row of tags.
5
+ # @accessibility This component requires you to pass in a `sr_label`
6
+ # attribute, which will be used to label the tabs for screen readers.
7
+ class TabBarComponent < Ariadne::Component
8
+ DEFAULT_TAG = :nav
9
+ TAG_OPTIONS = [DEFAULT_TAG].freeze
10
+
11
+ DEFAULT_CLASSES = "ariadne--mb-px ariadne-flex ariadne-space-x-8 ariadne-bg-transparent"
12
+
13
+ # Tabs to be rendered. For more information, refer to <%= link_to_component(Ariadne::TabComponent) %>.
14
+ #
15
+ # @param selected [Boolean] Whether the tab is selected.
16
+ # @param classes [String] <%= link_to_classes_docs %>
17
+ # @param attributes [Hash] <%= link_to_attributes_docs %>
18
+ renders_many :tabs, lambda { |selected: false, classes: "", attributes: {}|
19
+ Ariadne::TabComponent.new(
20
+ selected: selected,
21
+ classes: classes,
22
+ attributes: attributes
23
+ )
24
+ }
25
+
26
+ # @example Default
27
+ #
28
+ # <%= render(Ariadne::TabBarComponent.new(sr_label: "Navigation tabs")) { "Example" } %>
29
+ #
30
+ # @param tag [Symbol, String] The rendered tag name.
31
+ # @param sr_label [String] A label to introduce these tabs for screen readers.
32
+ # @param classes [String] <%= link_to_classes_docs %>
33
+ # @param attributes [Hash] <%= link_to_attributes_docs %>
34
+ def initialize(tag: DEFAULT_TAG, sr_label:, classes: "", attributes: {})
35
+ @tag = check_incoming_tag(DEFAULT_TAG, tag)
36
+ @classes = class_names(
37
+ DEFAULT_CLASSES,
38
+ classes
39
+ )
40
+ @sr_label = sr_label
41
+ @attributes = attributes
42
+ @attributes[:"aria-label"] ||= "Tabs"
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,7 @@
1
+ <%= render(Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes)) do |component| %>
2
+ <% if text.present? %>
3
+ <%= text %>
4
+ <% else %>
5
+ <%= content %>
6
+ <% end %>
7
+ <% end %>
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ariadne
4
+ # Represents a sequence of tabs which, when clicked, swap between panel contents.
5
+ class TabComponent < Ariadne::Component
6
+ DEFAULT_TAG = :button
7
+ TAG_OPTIONS = [DEFAULT_TAG].freeze
8
+
9
+ # The Tab's text.
10
+ #
11
+ # @param kwargs [Hash] The same arguments as <%= link_to_component(Ariadne::Text) %>.
12
+ renders_one :text, Ariadne::Text
13
+
14
+ attr_reader :selected
15
+
16
+ DEFAULT_CLASSES = "ariadne-border-gray-300 ariadne-border ariadne-shadow ariadne-py-5 ariadne-px-5 ariadne-rounded-md"
17
+
18
+ BASE_TAB_CLASSES = "ariadne-whitespace-nowrap ariadne-py-4 ariadne-px-1 ariadne-border-b-2 ariadne-font-medium ariadne-text-sm"
19
+
20
+ # @example Default
21
+ #
22
+ # <%= render(Ariadne::TabComponent.new) { "Example" } %>
23
+ #
24
+ # @param tag [Symbol, String] The rendered tag name.
25
+ # @param selected [Boolean] Whether the tab is selected or not.
26
+ # @param classes [String] <%= link_to_classes_docs %>
27
+ # @param attributes [Hash] <%= link_to_attributes_docs %>
28
+ def initialize(tag: DEFAULT_TAG, selected: false, classes: "", attributes: {})
29
+ @tag = check_incoming_tag(DEFAULT_TAG, tag)
30
+ @classes = class_names(
31
+ DEFAULT_CLASSES,
32
+ classes
33
+ )
34
+
35
+ @attributes = attributes
36
+ @attributes[:id] ||= "tabs-tab-#{@tab_idx}"
37
+ @attributes[:"aria-controls"] = "tabs-panel-#{@tab_idx}"
38
+ @attributes[:"aria-current"] = "page" if selected
39
+ @attributes[:selected] = selected
40
+ @classes = class_names(BASE_TAB_CLASSES, classes)
41
+ end
42
+ end
43
+ end
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ariadne
4
- # Displays a time relative to how long ago it was. This component requires JavaScript.
4
+ # Displays a time ariadne-relative to how long ago it was. This component requires JavaScript.
5
5
  class TimeAgoComponent < Ariadne::Component
6
6
  DEFAULT_TAG = :"time-ago"
7
7
  TAG_OPTIONS = [DEFAULT_TAG].freeze
8
8
 
9
- DEFAULT_CLASSES = "whitespace-nowrap"
9
+ DEFAULT_CLASSES = "ariadne-whitespace-nowrap"
10
10
 
11
11
  # @example Default
12
12
  #
@@ -1,13 +1,13 @@
1
1
  <%= render Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes) do %>
2
2
  <div>
3
- <div class="divide-y divide-gray-200">
4
- <div class="pb-4">
5
- <h2 id="activity-title" class="text-lg font-medium text-gray-900">Timeline</h2>
3
+ <div class="ariadne-divide-y ariadne-divide-gray-200">
4
+ <div class="ariadne-pb-4">
5
+ <h2 id="activity-title" class="ariadne-text-lg ariadne-font-medium ariadne-text-gray-900">Timeline</h2>
6
6
  </div>
7
- <div class="pt-6">
7
+ <div class="ariadne-pt-6">
8
8
  <!-- Activity feed-->
9
- <div class="flow-root">
10
- <ul role="list" class="-mb-8">
9
+ <div class="ariadne-flow-root">
10
+ <ul role="list" class="ariadne--mb-8">
11
11
  <% items.each do %>
12
12
  <%= items %>
13
13
  <% end %>
@@ -40,7 +40,7 @@ export default class TooltipComponent extends Controller {
40
40
 
41
41
  show() {
42
42
  this.tooltipTarget.setAttribute('data-tooltip-show', '')
43
- this.tooltipTarget.classList.remove('invisible')
43
+ this.tooltipTarget.classList.remove('ariadne-invisible')
44
44
 
45
45
  // We need to tell Popper to update the tooltip position
46
46
  // after we show the tooltip, otherwise it will be incorrect
@@ -50,8 +50,8 @@ export default class TooltipComponent extends Controller {
50
50
 
51
51
  hide() {
52
52
  this.tooltipTarget.removeAttribute('data-tooltip-show')
53
- this.tooltipTarget.classList.add('invisible')
53
+ this.tooltipTarget.classList.add('ariadne-invisible')
54
54
 
55
- this.dispatch('hidden', {detail: {trigger: this.triggerTarget, tooltip: this.tooltipTarget}})
55
+ this.dispatch('ariadne-hidden', {detail: {trigger: this.triggerTarget, tooltip: this.tooltipTarget}})
56
56
  }
57
57
  }
@@ -1,4 +1,4 @@
1
1
  <%= render Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes) do %>
2
2
  <span><%= @text %></span>
3
- <span class="tooltip-arrow absolute block" data-popper-arrow></span>
3
+ <span class="tooltip-arrow ariadne-absolute ariadne-block" data-popper-arrow></span>
4
4
  <% end %>
@@ -28,7 +28,7 @@ module Ariadne
28
28
  DEFAULT_PLACEMENT = :top
29
29
  VALID_PLACEMENTS = [DEFAULT_PLACEMENT, :right, :bottom, :left].freeze
30
30
 
31
- DEFAULT_CLASSES = "invisible absolute bg-slate-900 text-white font-semibold max-w-xs py-1 px-2 rounded z-max"
31
+ DEFAULT_CLASSES = "ariadne-invisible ariadne-absolute ariadne-bg-slate-900 ariadne-text-white ariadne-font-semibold ariadne-max-w-xs ariadne-py-1 ariadne-px-2 ariadne-rounded z-max"
32
32
 
33
33
  DATA_CONTROLLER = "tooltip-component"
34
34
  DATA_ACTION = "mouseover->tooltip-component#show mouseout->tooltip-component#hide"
@@ -12,7 +12,10 @@ module Ariadne
12
12
  options[:builder] ||= Ariadne::FormBuilder
13
13
  options[:html] ||= {}
14
14
  options = options.merge(attributes)
15
- form_with(model: model, scope: scope, url: url, format: format, **options, &block)
15
+ data = {
16
+ controller: "ariadne-form",
17
+ }
18
+ form_with(model: model, scope: scope, url: url, format: format, data: data, **options, &block)
16
19
  end
17
20
  end
18
21
  end
@@ -25,7 +25,9 @@ module Ariadne
25
25
  TRUE_OR_FALSE = [true, false].freeze
26
26
 
27
27
  def fetch_or_raise(allowed_values, given_value)
28
- raise ArgumentError, "allowed_values must be an array; it was #{allowed_values.class}" unless allowed_values.is_a?(Array)
28
+ if !allowed_values.is_a?(Array) && !allowed_values.is_a?(Set)
29
+ raise ArgumentError, "allowed_values must be an array or a set; it was #{allowed_values.class}"
30
+ end
29
31
 
30
32
  if allowed_values.include?(given_value)
31
33
  given_value