ariadne_view_components 0.0.13 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/builds/ariadne_view_components.css +2355 -0
  3. data/app/assets/javascripts/ariadne_view_components.js +2 -2
  4. data/app/assets/javascripts/ariadne_view_components.js.map +1 -1
  5. data/app/assets/javascripts/comment-component.d.ts +1 -2
  6. data/app/assets/stylesheets/ariadne_view_components.css +1 -0
  7. data/app/assets/stylesheets/dropdown.css +46 -0
  8. data/app/assets/stylesheets/tooltip-component.css +8 -8
  9. data/app/components/ariadne/ariadne-form-with.d.ts +20 -0
  10. data/app/components/ariadne/ariadne-form-with.js +85 -0
  11. data/app/components/ariadne/ariadne-form.d.ts +22 -0
  12. data/app/components/ariadne/ariadne-form.js +84 -0
  13. data/app/components/ariadne/ariadne.d.ts +2 -0
  14. data/app/components/ariadne/ariadne.js +16 -0
  15. data/app/components/ariadne/ariadne.ts +0 -2
  16. data/app/components/ariadne/avatar_component.rb +81 -0
  17. data/app/components/ariadne/avatar_stack_component.html.erb +12 -0
  18. data/app/components/ariadne/avatar_stack_component.rb +75 -0
  19. data/app/components/ariadne/base_button.rb +13 -4
  20. data/app/components/ariadne/blankslate_component.rb +4 -4
  21. data/app/components/ariadne/body_component.rb +1 -1
  22. data/app/components/ariadne/button_component.html.erb +1 -1
  23. data/app/components/ariadne/button_component.rb +9 -3
  24. data/app/components/ariadne/clipboard-copy-component.d.ts +4 -0
  25. data/app/components/ariadne/clipboard-copy-component.js +18 -0
  26. data/app/components/ariadne/clipboard_copy_component.d.ts +4 -0
  27. data/app/components/ariadne/clipboard_copy_component.js +18 -0
  28. data/app/components/ariadne/comment-component.d.ts +0 -0
  29. data/app/components/ariadne/comment-component.js +33 -0
  30. data/app/components/ariadne/comment-component.ts +32 -50
  31. data/app/components/ariadne/comment_component.html.erb +32 -10
  32. data/app/components/ariadne/comment_component.rb +17 -5
  33. data/app/components/ariadne/component.rb +0 -2
  34. data/app/components/ariadne/details_component.html.erb +4 -0
  35. data/app/components/ariadne/details_component.rb +80 -0
  36. data/app/components/ariadne/dropdown/menu_component.html.erb +20 -0
  37. data/app/components/ariadne/dropdown/menu_component.rb +101 -0
  38. data/app/components/ariadne/dropdown/menu_component.ts +1 -0
  39. data/app/components/ariadne/dropdown_component.html.erb +8 -0
  40. data/app/components/ariadne/dropdown_component.rb +172 -0
  41. data/app/components/ariadne/flex_component.rb +1 -1
  42. data/app/components/ariadne/footer_component.html.erb +1 -1
  43. data/app/components/ariadne/header_component.rb +3 -3
  44. data/app/components/ariadne/heroicon_component.rb +6 -4
  45. data/app/components/ariadne/inline_flex_component.html.erb +1 -0
  46. data/app/components/ariadne/inline_flex_component.rb +8 -1
  47. data/app/components/ariadne/link_component.rb +2 -2
  48. data/app/components/ariadne/list_component.html.erb +2 -9
  49. data/app/components/ariadne/list_component.rb +11 -15
  50. data/app/components/ariadne/pill_component.rb +19 -5
  51. data/app/components/ariadne/rich-text-area-component.d.ts +4 -0
  52. data/app/components/ariadne/rich-text-area-component.js +27 -0
  53. data/app/components/ariadne/rich-text-area-component.ts +4 -4
  54. data/app/components/ariadne/rich_text_area_component.html.erb +1 -1
  55. data/app/components/ariadne/rich_text_area_component.rb +1 -1
  56. data/app/components/ariadne/slideover-component.d.ts +9 -0
  57. data/app/components/ariadne/slideover-component.js +20 -0
  58. data/app/components/ariadne/slideover_component.d.ts +9 -0
  59. data/app/components/ariadne/slideover_component.html.erb +1 -1
  60. data/app/components/ariadne/slideover_component.js +19 -0
  61. data/app/components/ariadne/tab-component.js +1 -0
  62. data/app/components/ariadne/tab-container-component copy.d.ts +1 -0
  63. data/app/components/ariadne/tab-container-component copy.js +23 -0
  64. data/app/components/ariadne/tab-container-component.d.ts +1 -0
  65. data/app/components/ariadne/tab-container-component.js +23 -0
  66. data/app/components/ariadne/tab-container-component.ts +21 -21
  67. data/app/components/ariadne/tab-nav-component.d.ts +9 -0
  68. data/app/components/ariadne/tab-nav-component.js +32 -0
  69. data/app/components/ariadne/tab_component.rb +4 -7
  70. data/app/components/ariadne/tab_container_component.rb +8 -2
  71. data/app/components/ariadne/tab_nav_component.html.erb +1 -1
  72. data/app/components/ariadne/tab_nav_component.rb +1 -1
  73. data/app/components/ariadne/table_nav_component.html.erb +52 -0
  74. data/app/components/ariadne/table_nav_component.rb +338 -0
  75. data/app/components/ariadne/tabs-component.d.ts +0 -0
  76. data/app/components/ariadne/tabs-component.js +1 -0
  77. data/app/components/ariadne/time-ago-component.d.ts +1 -0
  78. data/app/components/ariadne/time-ago-component.js +1 -0
  79. data/app/components/ariadne/time_ago_component.d.ts +1 -0
  80. data/app/components/ariadne/time_ago_component.js +1 -0
  81. data/app/components/ariadne/tooltip-component.d.ts +24 -0
  82. data/app/components/ariadne/tooltip-component.js +42 -0
  83. data/app/components/ariadne/tooltip_component.html.erb +1 -1
  84. data/app/components/ariadne/tooltip_component.rb +4 -4
  85. data/app/lib/ariadne/action_view_extensions/form_helper.rb +21 -7
  86. data/app/lib/ariadne/form_builder.rb +4 -4
  87. data/lib/ariadne/view_components/version.rb +1 -1
  88. data/lib/tasks/docs.rake +19 -4
  89. data/static/arguments.yml +103 -22
  90. data/static/audited_at.json +15 -8
  91. data/static/classes.yml +51 -47
  92. data/static/constants.json +180 -55
  93. data/static/statuses.json +15 -8
  94. data/tailwind.config.js +25 -1
  95. metadata +53 -9
  96. data/app/components/ariadne/main_component.rb +0 -32
  97. data/app/components/ariadne/table_component.html.erb +0 -17
  98. data/app/components/ariadne/table_component.rb +0 -281
@@ -0,0 +1,172 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ariadne
4
+ # `DropdownComponent` is a lightweight context menu for holding navigation and actions.
5
+ class DropdownComponent < Ariadne::Component
6
+ DEFAULT_TAG = :div
7
+ TAG_OPTIONS = [DEFAULT_TAG].freeze
8
+
9
+ DEFAULT_CLASSES = ""
10
+
11
+ # Required trigger for the dropdown. Has the same arguments as <%= link_to_component(Ariadne::ButtonComponent) %>,
12
+ # but it is locked as a `summary` tag.
13
+ #
14
+ # @param size [Symbol] <%= one_of(Ariadne::BaseButton::VALID_SIZES) %>
15
+ # @param type [Symbol] <%= one_of(Ariadne::BaseButton::VALID_TYPES) %>
16
+ # @param scheme [Symbol] <%= one_of(Ariadne::ButtonComponent::VALID_SCHEMES) %>
17
+ # @param classes [String] <%= link_to_classes_docs %>
18
+ # @param attributes [Hash] <%= link_to_attributes_docs %>
19
+ renders_one :button, lambda { |size: Ariadne::BaseButton::DEFAULT_SIZE, scheme: :none, classes: "", attributes: {}|
20
+ @button_classes = classes
21
+ @button_attributes = attributes
22
+ @button_attributes[:button] = true
23
+
24
+ Ariadne::ButtonComponent.new(tag: :summary, type: :button, scheme: scheme, dropdown: @with_caret, size: size, classes: classes, attributes: attributes)
25
+ }
26
+
27
+ # Required context menu for the dropdown.
28
+ #
29
+ # @param as [Symbol] When `as` is `:list`, wraps the menu in a `<ul>` with a `<li>` for each item.
30
+ # @param direction [Symbol] <%= one_of(Ariadne::Dropdown::MenuComponent::VALID_DIRECTIONS) %>
31
+ # @param header [String] Optional string to display as the header
32
+ # @param classes [String] <%= link_to_classes_docs %>
33
+ # @param attributes [Hash] <%= link_to_attributes_docs %>
34
+ renders_one :menu, "Ariadne::Dropdown::MenuComponent"
35
+ # TODO: remove *Item suffix from nested classes
36
+
37
+ # @example Default
38
+ # <%= render(Ariadne::DropdownComponent.new) do |c| %>
39
+ # <% c.button do %>
40
+ # Dropdown
41
+ # <% end %>
42
+ #
43
+ # <% c.menu do |menu| %>
44
+ # <% menu.header { "Header" } %>
45
+ # <% menu.item { "Item 1" } %>
46
+ # <% menu.item { "Item 2" } %>
47
+ # <% menu.item { "Item 3" } %>
48
+ # <% end %>
49
+ # <% end %>
50
+ #
51
+ # @example With dividers
52
+ #
53
+ # @description
54
+ # Dividers can be used to separate a group of items. They don't have any content.
55
+ # @code
56
+ # <%= render(Ariadne::DropdownComponent.new) do |c| %>
57
+ # <% c.button do %>
58
+ # Dropdown
59
+ # <% end %>
60
+ #
61
+ # <% c.menu do |menu| %>
62
+ # <% menu.header { "Header" } %>
63
+ # <%= menu.item { "Item 1" } %>
64
+ # <%= menu.item { "Item 2" } %>
65
+ # <%= menu.item(divider: true) %>
66
+ # <%= menu.item { "Item 3" } %>
67
+ # <%= menu.item { "Item 4" } %>
68
+ # <%= menu.item(divider: true) %>
69
+ # <%= menu.item { "Item 5" } %>
70
+ # <%= menu.item { "Item 6" } %>
71
+ # <% end %>
72
+ # <% end %>
73
+ #
74
+ # @example With direction
75
+ # <%= render(Ariadne::DropdownComponent.new) do |c| %>
76
+ # <% c.button do %>
77
+ # Dropdown
78
+ # <% end %>
79
+ #
80
+ # <% c.menu(direction: :s) do |menu| %>
81
+ # <% menu.header { "Header" } %>
82
+ # <%= menu.item { "Item 1" } %>
83
+ # <%= menu.item { "Item 2" } %>
84
+ # <%= menu.item { "Item 3" } %>
85
+ # <%= menu.item { "Item 4" } %>
86
+ # <% end %>
87
+ # <% end %>
88
+ #
89
+ # @example With caret
90
+ # <%= render(Ariadne::DropdownComponent.new(with_caret: true)) do |c| %>
91
+ # <% c.button do %>
92
+ # Dropdown
93
+ # <% end %>
94
+ #
95
+ # <% c.menu do |menu| %>
96
+ # <% menu.header { "Header" } %>
97
+ # <%= menu.item { "Item 1" } %>
98
+ # <%= menu.item { "Item 2" } %>
99
+ # <%= menu.item { "Item 3" } %>
100
+ # <%= menu.item { "Item 4" } %>
101
+ # <% end %>
102
+ # <% end %>
103
+ #
104
+ # @example Customizing the button
105
+ # <%= render(Ariadne::DropdownComponent.new) do |c| %>
106
+ # <% c.button(scheme: :info, size: :sm) do %>
107
+ # Dropdown
108
+ # <% end %>
109
+ #
110
+ # <% c.menu do |menu| %>
111
+ # <% menu.header { "Header" } %>
112
+ # <%= menu.item { "Item 1" } %>
113
+ # <%= menu.item { "Item 2" } %>
114
+ # <%= menu.item { "Item 3" } %>
115
+ # <%= menu.item { "Item 4" } %>
116
+ # <% end %>
117
+ # <% end %>
118
+ #
119
+ # @example Menu as list
120
+ # <%= render(Ariadne::DropdownComponent.new) do |c| %>
121
+ # <% c.button do %>
122
+ # Dropdown
123
+ # <% end %>
124
+ #
125
+ # <% c.menu(as: :list) do |menu| %>
126
+ # <% menu.header { "Header" } %>
127
+ # <% menu.item { "Item 1" } %>
128
+ # <% menu.item { "Item 2" } %>
129
+ # <% menu.item(divider: true) %>
130
+ # <% menu.item { "Item 3" } %>
131
+ # <% menu.item { "Item 4" } %>
132
+ # <% end %>
133
+ # <% end %>
134
+ #
135
+ # @example Customizing menu items
136
+ # <%= render(Ariadne::DropdownComponent.new) do |c| %>
137
+ # <% c.button do %>
138
+ # Dropdown
139
+ # <% end %>
140
+ #
141
+ # <% c.menu do |menu| %>
142
+ # <% menu.header { "Header" } %>
143
+ # <% menu.item(tag: :button) { "Item 1" } %>
144
+ # <% menu.item(classes: "ariadne-text-red-500") { "Item 2" } %>
145
+ # <% menu.item { "Item 3" } %>
146
+ # <% end %>
147
+ # <% end %>
148
+ #
149
+ # @param overlay [Symbol] <%= one_of(Ariadne::DetailsComponent::OVERLAY_MAPPINGS.keys) %>
150
+ # @param with_caret [Boolean] Whether or not a caret should be rendered in the button.
151
+ # @param classes [String] <%= link_to_classes_docs %>
152
+ # @param attributes [Hash] <%= link_to_attributes_docs %>
153
+ def initialize(overlay: :default, with_caret: false, classes: "", attributes: {})
154
+ @tag = check_incoming_tag(DEFAULT_TAG, tag)
155
+ @classes = class_names(
156
+ DEFAULT_CLASSES,
157
+ classes,
158
+ )
159
+
160
+ @attributes = attributes
161
+
162
+ @with_caret = with_caret
163
+
164
+ @overlay = overlay
165
+ @attributes[:reset] = true
166
+ end
167
+
168
+ def render?
169
+ button.present? && menu.present?
170
+ end
171
+ end
172
+ end
@@ -6,7 +6,7 @@ module Ariadne
6
6
  DEFAULT_TAG = :div
7
7
  TAG_OPTIONS = [DEFAULT_TAG].freeze
8
8
 
9
- DEFAULT_CLASSES = "flex"
9
+ DEFAULT_CLASSES = "ariadne-flex"
10
10
 
11
11
  VALID_TYPES = [:row, :column, :row_reverse, :column_reverse].freeze
12
12
 
@@ -1,6 +1,6 @@
1
1
  <%= render Ariadne::BaseComponent.new(tag: :footer, classes: @classes, attributes: @attributes) do |footer| %>
2
2
  <%= render Ariadne::ContainerComponent.new do |container| %>
3
- <p class="ariadne-mt-6 ariadne-text-sm text-slate-500 sm:ariadne-mt-0">
3
+ <p class="ariadne-mt-6 ariadne-text-sm ariadne-text-slate-500 sm:ariadne-mt-0">
4
4
  <%= content %>
5
5
  </p>
6
6
  <% end %>
@@ -3,7 +3,7 @@
3
3
  module Ariadne
4
4
  # Represents the top navigation bar on every page.
5
5
  class HeaderComponent < Ariadne::Component
6
- DEFAULT_CLASSES = "ariadne-sticky ariadne-top-0 ariadne-z-50 ariadne-px-4 ariadne-py-5 ariadne-bg-white ariadne-shadow-sm shadow-slate-900/5 ariadne-transition ariadne-duration-500"
6
+ DEFAULT_CLASSES = "ariadne-sticky ariadne-top-0 ariadne-z-50 ariadne-px-4 ariadne-pt-4 ariadne-h-16 ariadne-bg-white ariadne-shadow-sm shadow-slate-900/5 ariadne-transition ariadne-duration-500"
7
7
  # ariadne-flex ariadne-flex-wrap ariadne-items-center ariadne-justify-between ariadne-bg-white dark:ariadne-shadow-none dark:ariadne-bg-transparent
8
8
  LINK_CLASSES = "ariadne-rounded-lg ariadne-py-1 ariadne-px-2 text-slate-700 hover:bg-slate-100 hover:text-slate-900"
9
9
 
@@ -60,13 +60,13 @@ module Ariadne
60
60
  # @param href [String] The link destination.
61
61
  # @param classes [String] <%= link_to_classes_docs %>
62
62
  # @param attributes [Hash] <%= link_to_attributes_docs %>
63
- DEFAULT_SIGNUP_LINK_CLASSES = "group ariadne-inline-flex ariadne-items-center ariadne-justify-center ariadne-rounded-full ariadne-py-2 ariadne-px-4 ariadne-text-sm ariadne-font-semibold focus:ariadne-outline-none focus-visible:outline-2 focus-visible:outline-offset-2"
63
+ DEFAULT_SIGNUP_LINK_CLASSES = "group ariadne-inline-flex ariadne-items-center ariadne-justify-center ariadne-rounded-full ariadne-py-2 ariadne-px-4 ariadne-text-sm ariadne-font-semibold focus:ariadne-outline-none focus-visible:ariadne-outline-2 focus-visible:outline-offset-2"
64
64
  renders_one :signup_link, lambda { |tag: Ariadne::LinkComponent::DEFAULT_TAG, href:, classes: "", attributes: {}|
65
65
  actual_classes = class_names(DEFAULT_SIGNUP_LINK_CLASSES, classes)
66
66
  Ariadne::LinkComponent.new(tag: tag, href: href, classes: actual_classes, attributes: attributes)
67
67
  }
68
68
 
69
- DEFAULT_PROFILE_LINK_CLASSES = "group ariadne-inline-flex ariadne-items-center ariadne-justify-center ariadne-rounded-full ariadne-py-2 ariadne-px-4 ariadne-text-sm ariadne-font-semibold focus:ariadne-outline-none focus-visible:outline-2 focus-visible:outline-offset-2"
69
+ DEFAULT_PROFILE_LINK_CLASSES = "group ariadne-inline-flex ariadne-items-center ariadne-justify-center ariadne-rounded-full ariadne-py-2 ariadne-px-4 ariadne-text-sm ariadne-font-semibold focus:ariadne-outline-none focus-visible:ariadne-outline-2 focus-visible:outline-offset-2"
70
70
  renders_one :profile_link, lambda { |tag: Ariadne::LinkComponent::DEFAULT_TAG, href:, classes: "", attributes: {}|
71
71
  actual_classes = class_names(DEFAULT_PROFILE_LINK_CLASSES, classes)
72
72
  Ariadne::LinkComponent.new(tag: tag, href: href, classes: actual_classes, attributes: attributes)
@@ -11,13 +11,15 @@ module Ariadne
11
11
  include IconHelper
12
12
  include HeroiconsHelper
13
13
 
14
- SIZE_DEFAULT = :sm
15
- SIZE_MEDIUM = :md
14
+ SIZE_MICRO = :mu
15
+ SIZE_SMALL = :sm
16
+ SIZE_DEFAULT = :md
16
17
  SIZE_LARGE = :lg
17
18
 
18
19
  SIZE_MAPPINGS = {
19
- SIZE_DEFAULT => 16,
20
- SIZE_MEDIUM => 24,
20
+ SIZE_MICRO => 16,
21
+ SIZE_SMALL => 20,
22
+ SIZE_DEFAULT => 24,
21
23
  SIZE_LARGE => 128,
22
24
  }.freeze
23
25
  SIZE_OPTIONS = SIZE_MAPPINGS.keys
@@ -2,4 +2,5 @@
2
2
  <%= icon %>
3
3
  <%= item %>
4
4
  <%= text %>
5
+ <%= dropdown %>
5
6
  <% end %>
@@ -19,7 +19,7 @@ module Ariadne
19
19
  </svg>
20
20
  MSG
21
21
  STATE_CLOSED_SVG = <<~MSG
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">
22
+ <svg viewBox="0 0 24 24" width="12" height="12" class="ariadne-stroke-state-closed ariadne-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
@@ -42,12 +42,19 @@ module Ariadne
42
42
  Ariadne::BaseComponent.new(tag: :span, classes: actual_classes, attributes: attributes) { content }
43
43
  }
44
44
 
45
+ renders_one :dropdown, "Ariadne::DropdownComponent"
46
+
45
47
  # @example Default
46
48
  #
47
49
  # <%= render(Ariadne::InlineFlexComponent.new) do |c| %>
48
50
  # <% c.item { Ariadne::InlineFlexComponent::STATE_OPEN_SVG.html_safe } %>
49
51
  # <% end %>
50
52
  #
53
+ # # TODO: STATE_CLOSED_SVG colors didn't show until it was listed in an example
54
+ # <%= render(Ariadne::InlineFlexComponent.new) do |c| %>
55
+ # <% c.item { Ariadne::InlineFlexComponent::STATE_CLOSED_SVG.html_safe } %>
56
+ # <% end %>
57
+ #
51
58
  # <%= render(Ariadne::InlineFlexComponent.new) do |c| %>
52
59
  # <% c.icon(icon: :check, size: :sm, variant: HeroiconsHelper::Icon::VARIANT_SOLID) %>
53
60
  # <% c.text { "Closed" } %>
@@ -6,8 +6,8 @@ module Ariadne
6
6
  DEFAULT_TAG = :a
7
7
  TAG_OPTIONS = [DEFAULT_TAG, :span].freeze
8
8
 
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"
9
+ DEFAULT_CLASSES = "ariadne-cursor-pointer hover:ariadne-text-button-text-color focus:ariadne-outline-none focus:ariadne-ring-2 focus:ariadne-ring-offset-2 focus:ariadne-ring-purple-500"
10
+ DEFAULT_ACTIONABLE_CLASSES = "ariadne-cursor-pointer ariadne-font-semibold ariadne-underline ariadne-decoration-double"
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.
@@ -1,13 +1,6 @@
1
1
  <%= render Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes) do |list| %>
2
+ <%= content %>
2
3
  <% items.each do |item| %>
3
- <%= render Ariadne::BaseComponent.new(tag: :li, classes: item.classes, attributes: item.attributes) do %>
4
- <% if item.linked? %>
5
- <%= render Ariadne::LinkComponent.new(href: item.link[:href], classes: item.link[:classes], attributes: item.link[:attributes]) do %>
6
- <%= item.entry %>
7
- <% end %>
8
- <% else %>
9
- <%= item.entry %>
10
- <% end %>
11
- <% end %>
4
+ <%= item %>
12
5
  <% end %>
13
6
  <% end %>
@@ -13,7 +13,7 @@ module Ariadne
13
13
  # <%= render(Ariadne::ListComponent.new) do |list| %>
14
14
  # <% numbers.each do |number| %>
15
15
  # <%= list.item do |item| %>
16
- # <%= item.entry { number } %>
16
+ # <%= number %>
17
17
  # <% end %>
18
18
  # <% end %>
19
19
  # <% end %>
@@ -27,23 +27,11 @@ module Ariadne
27
27
  @attributes = attributes
28
28
  end
29
29
 
30
- def render?
31
- items.any?
32
- end
33
-
34
30
  # This component is part of `ListComponent` and should not be
35
31
  # used as a standalone component.
36
32
  class ListItem < Ariadne::Component
37
33
  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"
38
34
 
39
- DEFAULT_ENTRY_CLASSES = "hover:ariadne-text-gray-500"
40
- renders_one :entry, lambda { |classes: "", attributes: {}, &block|
41
- view_context.capture do
42
- actual_classes = class_names(DEFAULT_ENTRY_CLASSES, classes)
43
- render(Ariadne::BaseComponent.new(tag: :div, classes: actual_classes, attributes: attributes)) { block&.call }
44
- end
45
- }
46
-
47
35
  attr_reader :link, :classes, :attributes
48
36
 
49
37
  def initialize(link: {}, classes: "", attributes: {})
@@ -56,12 +44,20 @@ module Ariadne
56
44
  @selected
57
45
  end
58
46
 
59
- def linked?
47
+ private def linked?
60
48
  @link.present?
61
49
  end
62
50
 
63
51
  def call
64
- Ariadne::BaseComponent.new(tag: :div, classes: @classes, attributes: @attributes)
52
+ render(Ariadne::BaseComponent.new(tag: :li, classes: @classes, attributes: @attributes)) do
53
+ if linked?
54
+ render(Ariadne::LinkComponent.new(href: @link[:href], classes: @link[:classes], attributes: @link[:attributes])) do
55
+ content
56
+ end
57
+ else
58
+ content
59
+ end
60
+ end
65
61
  end
66
62
  end
67
63
  end
@@ -6,25 +6,39 @@ module Ariadne
6
6
  DEFAULT_TAG = :span
7
7
  TAG_OPTIONS = [DEFAULT_TAG].freeze
8
8
 
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"
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 ariadne-whitespace-nowrap"
10
10
 
11
11
  # @example Default
12
12
  #
13
- # <%= render(Ariadne::PillComponent.new(color: "FF0000")) { "Admin" } %>
13
+ # <%= render(Ariadne::PillComponent.new(color: [49, 186, 115, 1.0])) { "Admin" } %>
14
14
  #
15
15
  # @param tag [Symbol, String] The rendered tag name.
16
- # @param color [String] The hex color of the pill.
16
+ # @param color [String] The rgba color of the pill.
17
17
  # @param classes [String] <%= link_to_classes_docs %>
18
18
  # @param attributes [Hash] <%= link_to_attributes_docs %>
19
19
  def initialize(tag: DEFAULT_TAG, color:, classes: "", attributes: {})
20
20
  @tag = check_incoming_tag(DEFAULT_TAG, tag)
21
+
22
+ @red = color[0]
23
+ @green = color[1]
24
+ @blue = color[2]
25
+ @alpha = color[3]
26
+
27
+ @attributes = attributes
28
+ @attributes["style"] = "background-color: rgba(#{@red}, #{@green}, #{@blue}, #{@alpha});"
29
+ @text_color = contrast_of(@red, @green, @blue)
30
+
21
31
  @classes = class_names(
22
32
  DEFAULT_CLASSES,
23
33
  classes,
34
+ @text_color,
24
35
  )
36
+ end
25
37
 
26
- @attributes = attributes
27
- @attributes["style"] = "background-color: ##{color};"
38
+ private def contrast_of(red, green, blue)
39
+ luminance = (0.299 * red + 0.587 * green + 0.114 * blue) / 255
40
+
41
+ luminance > 0.5 ? "ariadne-text-black" : "ariadne-text-white"
28
42
  end
29
43
  end
30
44
  end
@@ -0,0 +1,4 @@
1
+ import { Controller } from '@hotwired/stimulus';
2
+ export default class RichTextArea extends Controller {
3
+ connect(): void;
4
+ }
@@ -0,0 +1,27 @@
1
+ import { Controller } from '@hotwired/stimulus';
2
+ import { Editor } from '@tiptap/core';
3
+ import { StarterKit } from '@tiptap/starter-kit';
4
+ export default class RichTextArea extends Controller {
5
+ connect() {
6
+ const editorElements = document.getElementsByClassName('tiptap-editor');
7
+ for (const editorElement of editorElements) {
8
+ new Editor({
9
+ element: editorElement,
10
+ extensions: [StarterKit],
11
+ content: '',
12
+ editorProps: {
13
+ attributes: {
14
+ class: 'ariadne-m-5 focus:ariadne-outline-none ariadne-block ariadne-w-full ariadne-resize-none ariadne-p-0 ariadne-pb-2 ariadne-border-none focus:ariadne-ring-0 sm:ariadne-text-sm'
15
+ }
16
+ }
17
+ });
18
+ const tiptapValueContainer = document.querySelector('input[data-tiptap-value-container=true]');
19
+ if (tiptapValueContainer) {
20
+ const parentForm = editorElement.closest('form');
21
+ parentForm === null || parentForm === void 0 ? void 0 : parentForm.addEventListener('submit', () => {
22
+ tiptapValueContainer.setAttribute('value', editorElement.textContent || '');
23
+ });
24
+ }
25
+ }
26
+ }
27
+ }
@@ -5,16 +5,16 @@ import {StarterKit} from '@tiptap/starter-kit'
5
5
 
6
6
  export default class RichTextArea extends Controller {
7
7
  connect() {
8
- const editorElement = document.querySelector('.tiptap-editor')
9
- if (editorElement) {
8
+ const editorElements = document.getElementsByClassName('tiptap-editor')
9
+ for (const editorElement of editorElements) {
10
10
  new Editor({
11
11
  element: editorElement,
12
12
  extensions: [StarterKit],
13
- content: 'Hello World!',
13
+ content: '',
14
14
  editorProps: {
15
15
  attributes: {
16
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'
17
+ 'ariadne-m-5 focus:ariadne-outline-none ariadne-block ariadne-w-full ariadne-resize-none ariadne-p-0 ariadne-pb-2 ariadne-border-none focus:ariadne-ring-0 sm:ariadne-text-sm'
18
18
  }
19
19
  }
20
20
  })
@@ -2,5 +2,5 @@
2
2
  <% if @has_form %>
3
3
  <input type="hidden" data-tiptap-value-container=true name="<%= @name %>" id="<%= @name %>">
4
4
  <% end %>
5
- <textarea class="tiptap-editor"></textarea>
5
+ <div class="tiptap-editor"></div>
6
6
  <% end %>
@@ -6,7 +6,7 @@ module Ariadne
6
6
  # @accessibility Add any accessibility considerations
7
7
  class RichTextAreaComponent < Ariadne::Component
8
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"
9
+ DEFAULT_CLASSES = "ariadne-block"
10
10
 
11
11
  # @example Default
12
12
  #
@@ -0,0 +1,9 @@
1
+ import { Controller } from '@hotwired/stimulus';
2
+ export default class SlideoverComponent extends Controller {
3
+ static targets: string[];
4
+ readonly expandableTarget: HTMLDivElement;
5
+ readonly expandWrapperTarget: HTMLDivElement;
6
+ readonly slidePanelTargets: [HTMLDivElement];
7
+ readonly buttonWrapperTarget: HTMLDivElement;
8
+ toggle(): void;
9
+ }
@@ -0,0 +1,20 @@
1
+ import { Controller } from '@hotwired/stimulus';
2
+ export default class SlideoverComponent extends Controller {
3
+ toggle() {
4
+ var _a;
5
+ this.expandableTarget.classList.toggle('ariadne-hidden');
6
+ this.expandWrapperTarget.classList.toggle('bg-filter-panel');
7
+ for (const slidePanel of this.slidePanelTargets) {
8
+ slidePanel.classList.toggle('ariadne-hidden');
9
+ }
10
+ this.buttonWrapperTarget.classList.toggle('bg-filter-panel');
11
+ if ((_a = document.getElementById('btnClose')) === null || _a === void 0 ? void 0 : _a.classList.contains('ariadne-hidden')) {
12
+ const formID = this.buttonWrapperTarget.getAttribute('data-slideover-component-form-id');
13
+ if (formID) {
14
+ const form = document.getElementById(formID);
15
+ form === null || form === void 0 ? void 0 : form.submit();
16
+ }
17
+ }
18
+ }
19
+ }
20
+ SlideoverComponent.targets = ['expandable', 'expandWrapper', 'slidePanel', 'buttonWrapper'];
@@ -0,0 +1,9 @@
1
+ import { Controller } from '@hotwired/stimulus';
2
+ export default class SlideoverComponent extends Controller {
3
+ static targets: string[];
4
+ readonly expandableTarget: HTMLDivElement;
5
+ readonly expandWrapperTarget: HTMLDivElement;
6
+ readonly slidePanelTargets: [HTMLDivElement];
7
+ readonly buttonWrapperTarget: HTMLDivElement;
8
+ toggle(): void;
9
+ }
@@ -1,6 +1,6 @@
1
1
  <%= render Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes) do |slideover| %>
2
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">
3
+ <div data-slideover-component-target="expandable" class="ariadne-hidden ariadne-px-3 ariadne-pb-4">
4
4
  <%= content %>
5
5
  </div>
6
6
  <div data-slideover-component-target="buttonWrapper" data-slideover-component-form-id="<%= @form_id %>" class="ariadne-relative ariadne-flex ariadne-justify-center">
@@ -0,0 +1,19 @@
1
+ import { Controller } from '@hotwired/stimulus';
2
+ export default class SlideoverComponent extends Controller {
3
+ toggle() {
4
+ var _a;
5
+ // eslint-disable-next-line no-debugger
6
+ debugger;
7
+ this.expandableTarget.classList.toggle('hidden');
8
+ this.expandWrapperTarget.classList.toggle('bg-filter-panel');
9
+ for (const slidePanel of this.slidePanelTargets) {
10
+ slidePanel.classList.toggle('hidden');
11
+ }
12
+ this.buttonWrapperTarget.classList.toggle('bg-filter-panel');
13
+ if ((_a = document.getElementById('btnClose')) === null || _a === void 0 ? void 0 : _a.classList.contains('hidden')) {
14
+ const form = this.buttonWrapperTarget.closest('form');
15
+ form === null || form === void 0 ? void 0 : form.submit();
16
+ }
17
+ }
18
+ }
19
+ SlideoverComponent.targets = ['expandable', 'expandWrapper', 'slidePanel', 'buttonWrapper'];
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1 @@
1
+ import '@github/tab-container-element';
@@ -0,0 +1,23 @@
1
+ import '@github/tab-container-element';
2
+ // // keep in sync with tab_container_component.rb
3
+ // const DEFAULT_SELECTED_CLASSES: string[] = ['ariadne-border-indigo-500', 'ariadne-text-indigo-600']
4
+ // const DEFAULT_UNSELECTED_CLASSES: string[] = [
5
+ // 'ariadne-text-gray-500',
6
+ // 'hover:ariadne-text-gray-700',
7
+ // 'hover:ariadne-border-gray-300'
8
+ // ]
9
+ for (const tabContainer of document.getElementsByTagName('tab-container')) {
10
+ tabContainer.addEventListener('tab-container-change', function (event) {
11
+ var _a;
12
+ const newPanel = event.detail.relatedTarget;
13
+ const tabContainer = newPanel.closest('tab-container');
14
+ const tabList = tabContainer.firstElementChild;
15
+ const currentTab = tabList.querySelector('[aria-selected="true"]');
16
+ const tabId = (_a = newPanel.getAttribute('id')) === null || _a === void 0 ? void 0 : _a.split('-').slice(1).join('-');
17
+ const newTab = tabList.querySelector(`#${tabId}`);
18
+ currentTab.classList.remove(...DEFAULT_SELECTED_CLASSES);
19
+ currentTab.classList.add(...DEFAULT_UNSELECTED_CLASSES);
20
+ newTab.classList.add(...DEFAULT_SELECTED_CLASSES);
21
+ newTab.classList.remove(...DEFAULT_UNSELECTED_CLASSES);
22
+ });
23
+ }
@@ -0,0 +1 @@
1
+ import '@github/tab-container-element';
@@ -0,0 +1,23 @@
1
+ import '@github/tab-container-element';
2
+ // keep in sync with tab_container_component.rb
3
+ const DEFAULT_SELECTED_CLASSES = ['ariadne-border-indigo-500', 'ariadne-text-indigo-600'];
4
+ const DEFAULT_UNSELECTED_CLASSES = [
5
+ 'ariadne-text-gray-500',
6
+ 'hover:ariadne-text-gray-700',
7
+ 'hover:ariadne-border-gray-300'
8
+ ];
9
+ for (const tabContainer of document.getElementsByTagName('tab-container')) {
10
+ tabContainer.addEventListener('tab-container-change', function (event) {
11
+ var _a;
12
+ const newPanel = event.detail.relatedTarget;
13
+ const tabContainer = newPanel.closest('tab-container');
14
+ const tabList = tabContainer.firstElementChild;
15
+ const currentTab = tabList.querySelector('[aria-selected="true"]');
16
+ const tabId = (_a = newPanel.getAttribute('id')) === null || _a === void 0 ? void 0 : _a.split('-').slice(1).join('-');
17
+ const newTab = tabList.querySelector(`#${tabId}`);
18
+ currentTab.classList.remove(...DEFAULT_SELECTED_CLASSES);
19
+ currentTab.classList.add(...DEFAULT_UNSELECTED_CLASSES);
20
+ newTab.classList.add(...DEFAULT_SELECTED_CLASSES);
21
+ newTab.classList.remove(...DEFAULT_UNSELECTED_CLASSES);
22
+ });
23
+ }