fluxbit_view_components 0.2.0 → 0.4.0

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 (173) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -0
  3. data/app/assets/javascripts/fluxbit_view_components/assigner_controller.js +49 -0
  4. data/app/assets/javascripts/fluxbit_view_components/auto_submit_controller.js +39 -0
  5. data/app/assets/javascripts/fluxbit_view_components/drawer_controller.js +135 -0
  6. data/app/assets/javascripts/fluxbit_view_components/index.js +56 -0
  7. data/app/assets/javascripts/fluxbit_view_components/method_link_controller.js +143 -0
  8. data/app/assets/javascripts/fluxbit_view_components/modal_controller.js +118 -0
  9. data/app/assets/javascripts/fluxbit_view_components/password_controller.js +170 -0
  10. data/app/assets/javascripts/fluxbit_view_components/progress_controller.js +374 -0
  11. data/app/assets/javascripts/fluxbit_view_components/row_click_controller.js +32 -0
  12. data/app/assets/javascripts/fluxbit_view_components/select_all_controller.js +122 -0
  13. data/app/assets/javascripts/fluxbit_view_components/spinner_percent_controller.js +174 -0
  14. data/app/assets/javascripts/fluxbit_view_components/theme_button_controller.js +90 -0
  15. data/app/assets/javascripts/fluxbit_view_components.js +1175 -0
  16. data/app/components/fluxbit/accordion_component.rb +125 -0
  17. data/app/components/fluxbit/alert_component.rb +8 -8
  18. data/app/components/fluxbit/avatar_component.rb +11 -12
  19. data/app/components/fluxbit/avatar_group_component.rb +1 -1
  20. data/app/components/fluxbit/badge_component.rb +8 -7
  21. data/app/components/fluxbit/banner_component.rb +139 -0
  22. data/app/components/fluxbit/bottom_navigation_component.rb +437 -0
  23. data/app/components/fluxbit/breadcrumb_component.rb +66 -0
  24. data/app/components/fluxbit/button_component.rb +39 -11
  25. data/app/components/fluxbit/button_group_component.rb +1 -1
  26. data/app/components/fluxbit/card_component.rb +26 -23
  27. data/app/components/fluxbit/carousel_component.rb +154 -0
  28. data/app/components/fluxbit/component.rb +24 -3
  29. data/app/components/fluxbit/drawer_component.html.erb +30 -0
  30. data/app/components/fluxbit/drawer_component.rb +125 -0
  31. data/app/components/fluxbit/dropdown_component.rb +41 -0
  32. data/app/components/fluxbit/dropdown_item_component.rb +68 -0
  33. data/app/components/fluxbit/flex_component.rb +1 -1
  34. data/app/components/fluxbit/form/check_box_component.rb +56 -0
  35. data/app/components/fluxbit/form/component.rb +27 -26
  36. data/app/components/fluxbit/form/dropzone_component.html.erb +39 -0
  37. data/app/components/fluxbit/form/dropzone_component.rb +39 -0
  38. data/app/components/fluxbit/form/field_component.rb +28 -0
  39. data/app/components/fluxbit/form/form_builder_component.rb +1 -1
  40. data/app/components/fluxbit/form/{helper_text_component.rb → help_text_component.rb} +9 -4
  41. data/app/components/fluxbit/form/label_component.rb +40 -30
  42. data/app/components/fluxbit/form/password_component.rb +247 -0
  43. data/app/components/fluxbit/form/radio_group_button_component.rb +126 -0
  44. data/app/components/fluxbit/form/range_component.rb +52 -0
  45. data/app/components/fluxbit/form/select_component.rb +185 -0
  46. data/app/components/fluxbit/form/text_field_component.rb +185 -0
  47. data/app/components/fluxbit/form/toggle_component.html.erb +23 -0
  48. data/app/components/fluxbit/form/toggle_component.rb +81 -0
  49. data/app/components/fluxbit/form/upload_image_component.html.erb +50 -0
  50. data/app/components/fluxbit/form/upload_image_component.rb +61 -0
  51. data/app/components/fluxbit/gravatar_component.rb +7 -0
  52. data/app/components/fluxbit/icon_helpers.rb +167 -0
  53. data/app/components/fluxbit/link_component.rb +42 -0
  54. data/app/components/fluxbit/modal_component.rb +28 -31
  55. data/app/components/fluxbit/pagination_component.rb +206 -0
  56. data/app/components/fluxbit/popover_component.rb +14 -14
  57. data/app/components/fluxbit/progress_component.rb +196 -0
  58. data/app/components/fluxbit/skeleton_component.rb +237 -0
  59. data/app/components/fluxbit/speed_dial_action_component.html.erb +30 -0
  60. data/app/components/fluxbit/speed_dial_action_component.rb +59 -0
  61. data/app/components/fluxbit/speed_dial_component.html.erb +33 -0
  62. data/app/components/fluxbit/speed_dial_component.rb +73 -0
  63. data/app/components/fluxbit/spinner_component.rb +71 -0
  64. data/app/components/fluxbit/spinner_percent_component.rb +174 -0
  65. data/app/components/fluxbit/stepper_component.rb +223 -0
  66. data/app/components/fluxbit/tab_component.rb +44 -25
  67. data/app/components/fluxbit/table_component.rb +186 -0
  68. data/app/components/fluxbit/table_group_component.rb +28 -0
  69. data/app/components/fluxbit/theme_button_component.rb +64 -0
  70. data/app/components/fluxbit/timeline_component.rb +63 -0
  71. data/app/components/fluxbit/timeline_item_component.html.erb +64 -0
  72. data/app/components/fluxbit/timeline_item_component.rb +78 -0
  73. data/app/components/fluxbit/tooltip_component.rb +2 -2
  74. data/app/helpers/fluxbit/components_helper.rb +93 -51
  75. data/app/helpers/fluxbit/form_builder.rb +136 -0
  76. data/app/helpers/fluxbit/view_helper.rb +71 -0
  77. data/config/locales/en.yml +37 -4
  78. data/config/locales/pt-BR.yml +36 -0
  79. data/lib/fluxbit/config/accordion_component.rb +73 -0
  80. data/lib/fluxbit/config/avatar_component.rb +11 -11
  81. data/lib/fluxbit/config/badge_component.rb +14 -11
  82. data/lib/fluxbit/config/banner_component.rb +60 -0
  83. data/lib/fluxbit/config/bottom_navigation_component.rb +74 -0
  84. data/lib/fluxbit/config/breadcrumb_component.rb +24 -0
  85. data/lib/fluxbit/config/button_component.rb +6 -4
  86. data/lib/fluxbit/config/card_component.rb +23 -12
  87. data/lib/fluxbit/config/carousel_component.rb +33 -0
  88. data/lib/fluxbit/config/drawer_component.rb +48 -0
  89. data/lib/fluxbit/config/dropdown_component.rb +29 -0
  90. data/lib/fluxbit/config/form/check_box_component.rb +19 -0
  91. data/lib/fluxbit/config/form/dropzone_component.rb +20 -0
  92. data/lib/fluxbit/config/form/{helper_text_component.rb → help_text_component.rb} +2 -2
  93. data/lib/fluxbit/config/form/label_component.rb +31 -0
  94. data/lib/fluxbit/config/form/password_component.rb +19 -0
  95. data/lib/fluxbit/config/form/radio_group_button_component.rb +24 -0
  96. data/lib/fluxbit/config/form/range_component.rb +15 -0
  97. data/lib/fluxbit/config/form/text_field_component.rb +76 -0
  98. data/lib/fluxbit/config/form/toggle_component.rb +79 -0
  99. data/lib/fluxbit/config/link_component.rb +24 -0
  100. data/lib/fluxbit/config/modal_component.rb +1 -1
  101. data/lib/fluxbit/config/pagination_component.rb +31 -0
  102. data/lib/fluxbit/config/popover_component.rb +1 -1
  103. data/lib/fluxbit/config/progress_component.rb +63 -0
  104. data/lib/fluxbit/config/skeleton_component.rb +82 -0
  105. data/lib/fluxbit/config/speed_dial_component.rb +50 -0
  106. data/lib/fluxbit/config/spinner_component.rb +30 -0
  107. data/lib/fluxbit/config/spinner_percent_component.rb +61 -0
  108. data/lib/fluxbit/config/stepper_component.rb +299 -0
  109. data/lib/fluxbit/config/tab_component.rb +6 -0
  110. data/lib/fluxbit/config/table_component.rb +75 -0
  111. data/lib/fluxbit/config/theme_button_component.rb +19 -0
  112. data/lib/fluxbit/config/timeline_component.rb +77 -0
  113. data/lib/fluxbit/view_components/engine.rb +11 -3
  114. data/lib/fluxbit/view_components/version.rb +1 -1
  115. data/lib/fluxbit/view_components.rb +27 -1
  116. data/lib/generators/fluxbit/devise_views_generator.rb +116 -0
  117. data/lib/generators/fluxbit/pagy_generator.rb +39 -0
  118. data/lib/generators/fluxbit/scaffold_generator.rb +165 -0
  119. data/lib/generators/fluxbit/templates/_alert.html.erb.tt +1 -0
  120. data/lib/generators/fluxbit/templates/_flash.html.erb.tt +15 -0
  121. data/lib/generators/fluxbit/templates/_form.html.erb.tt +38 -0
  122. data/lib/generators/fluxbit/templates/_metadata.html.erb.tt +44 -0
  123. data/lib/generators/fluxbit/templates/controller.rb.tt +406 -0
  124. data/lib/generators/fluxbit/templates/create.turbo_stream.erb.tt +7 -0
  125. data/lib/generators/fluxbit/templates/destroy.turbo_stream.erb.tt +3 -0
  126. data/lib/generators/fluxbit/templates/destroy_all.turbo_stream.erb.tt +9 -0
  127. data/lib/generators/fluxbit/templates/devise_views/confirmations/new.html.erb +11 -0
  128. data/lib/generators/fluxbit/templates/devise_views/layouts/devise.html.erb +64 -0
  129. data/lib/generators/fluxbit/templates/devise_views/mailer/confirmation_instructions.html.erb +5 -0
  130. data/lib/generators/fluxbit/templates/devise_views/mailer/email_changed.html.erb +7 -0
  131. data/lib/generators/fluxbit/templates/devise_views/mailer/password_changed.html.erb +3 -0
  132. data/lib/generators/fluxbit/templates/devise_views/mailer/reset_password_instructions.html.erb +8 -0
  133. data/lib/generators/fluxbit/templates/devise_views/mailer/unlock_instructions.html.erb +7 -0
  134. data/lib/generators/fluxbit/templates/devise_views/passwords/edit.html.erb +29 -0
  135. data/lib/generators/fluxbit/templates/devise_views/passwords/new.html.erb +11 -0
  136. data/lib/generators/fluxbit/templates/devise_views/registrations/edit.html.erb +43 -0
  137. data/lib/generators/fluxbit/templates/devise_views/registrations/new.html.erb +34 -0
  138. data/lib/generators/fluxbit/templates/devise_views/sessions/new.html.erb +15 -0
  139. data/lib/generators/fluxbit/templates/devise_views/shared/_error_messages.html.erb +14 -0
  140. data/lib/generators/fluxbit/templates/devise_views/shared/_links.html.erb +25 -0
  141. data/lib/generators/fluxbit/templates/devise_views/unlocks/new.html.erb +11 -0
  142. data/lib/generators/fluxbit/templates/edit.html.erb.tt +47 -0
  143. data/lib/generators/fluxbit/templates/fluxbit_pagy.css +27 -0
  144. data/lib/generators/fluxbit/templates/i18n.en.yml.tt +121 -0
  145. data/lib/generators/fluxbit/templates/i18n.pt-BR.yml.tt +121 -0
  146. data/lib/generators/fluxbit/templates/index.html.erb.tt +254 -0
  147. data/lib/generators/fluxbit/templates/index.json.jbuilder.tt +33 -0
  148. data/lib/generators/fluxbit/templates/new.html.erb.tt +47 -0
  149. data/lib/generators/fluxbit/templates/partial.html.erb.tt +61 -0
  150. data/lib/generators/fluxbit/templates/policy.rb.tt +36 -0
  151. data/lib/generators/fluxbit/templates/send_alert_via_drawer.erb.tt +10 -0
  152. data/lib/generators/fluxbit/templates/show.html.erb.tt +44 -0
  153. data/lib/generators/fluxbit/templates/show.json.jbuilder.tt +6 -0
  154. data/lib/generators/fluxbit/templates/update.turbo_stream.erb.tt +10 -0
  155. data/lib/generators/fluxbit/templates/update_all.turbo_stream.erb.tt +20 -0
  156. data/lib/install/install.rb +61 -3
  157. metadata +127 -35
  158. data/LICENSE.txt +0 -20
  159. data/app/components/fluxbit/form/checkbox_input_component.rb +0 -61
  160. data/app/components/fluxbit/form/datepicker_component.rb +0 -7
  161. data/app/components/fluxbit/form/radio_input_component.rb +0 -21
  162. data/app/components/fluxbit/form/range_input_component.rb +0 -51
  163. data/app/components/fluxbit/form/select_free_input_component.rb +0 -77
  164. data/app/components/fluxbit/form/select_input_component.rb +0 -21
  165. data/app/components/fluxbit/form/spacer_input_component.rb +0 -12
  166. data/app/components/fluxbit/form/text_input_component.rb +0 -225
  167. data/app/components/fluxbit/form/textarea_input_component.rb +0 -57
  168. data/app/components/fluxbit/form/toggle_input_component.rb +0 -166
  169. data/app/components/fluxbit/form/upload_image_input_component.html.erb +0 -48
  170. data/app/components/fluxbit/form/upload_image_input_component.rb +0 -61
  171. data/app/components/fluxbit/form/upload_input_component.html.erb +0 -12
  172. data/app/components/fluxbit/form/upload_input_component.rb +0 -47
  173. data/app/helpers/fluxbit/classes_helper.rb +0 -9
@@ -0,0 +1,33 @@
1
+ <% singular = file_name.singularize; plural = file_name.pluralize -%>
2
+ # app/views/<%= plural %>/index.json.jbuilder
3
+ json.<%= plural %> @<%= plural %> do |<%= singular %>|
4
+ json.id <%= singular %>.id
5
+ <% attributes.each do |att|
6
+ name = att.name
7
+ next if att.type.to_s == 'password_digest' # handle password fields separately
8
+ -%>
9
+ json.<%= name %> <%= singular %>.<%= name %>
10
+ <% end -%>
11
+ json.created_at <%= singular %>.created_at
12
+ json.updated_at <%= singular %>.updated_at
13
+ json.url <%= path_prefix %><%= singular %>_url(<%= singular %>, format: :json)
14
+ end
15
+
16
+ json.pagination do
17
+ json.current_page @pagy.page
18
+ json.total_pages @pagy.pages
19
+ json.total_count @pagy.count
20
+ json.per_page @pagy.limit
21
+ json.next_page @pagy.next
22
+ json.prev_page @pagy.prev
23
+ end
24
+
25
+ json.filters do
26
+ json.search @q
27
+ <% attributes
28
+ .select { |a| %i[integer decimal text string].include?(a.type) }
29
+ .each do |att|
30
+ -%>
31
+ json.<%= att.name %> @<%= att.name %>
32
+ <% end -%>
33
+ end
@@ -0,0 +1,47 @@
1
+ <% singular = file_name.singularize; plural = file_name.pluralize -%>
2
+ <% if options[:ui] == "drawer" -%>
3
+ <% if options[:turbo] -%>
4
+ <%% if turbo_frame_request? %>
5
+ <turbo-frame id="drawer">
6
+ <%%= fx_drawer(id: "new-drawer", placement: :right, sizing: :xl, data: {controller: "fx-drawer"}) do |drawer| %>
7
+ <%% drawer.with_header { t("<%= plural %>.titles.new") } %>
8
+ <%%= render "form", <%= singular %>: @<%= singular %> %>
9
+ <%% end %>
10
+ <script>document.dispatchEvent(new CustomEvent("showDrawer:new-drawer"));</script>
11
+ </turbo-frame>
12
+ <%% else %>
13
+ <%%= fx_heading(class: "m-4", size: 2) { t("<%= plural %>.titles.new") } %>
14
+ <%%= fx_card(class: "m-4") do |card| %>
15
+ <%% card.with_section do %>
16
+ <%%= render "form", <%= singular %>: @<%= singular %> %>
17
+ <%% end %>
18
+ <%% end %>
19
+ <%% end %>
20
+ <% end -%>
21
+ <% elsif options[:ui] == "modal" -%>
22
+ <% if options[:turbo] -%>
23
+ <%% if turbo_frame_request? %>
24
+ <turbo-frame id="modal">
25
+ <%%= fx_modal(id: "new-modal", size: :xl, data: {controller: "fx-modal"}) do |modal| %>
26
+ <%% modal.with_header { t("<%= plural %>.titles.new") } %>
27
+ <%%= render "form", <%= singular %>: @<%= singular %> %>
28
+ <%% end %>
29
+ <script>document.dispatchEvent(new CustomEvent("showModal:new-modal"));</script>
30
+ </turbo-frame>
31
+ <%% else %>
32
+ <%%= fx_heading(class: "m-4", size: 2) { t("<%= plural %>.titles.new") } %>
33
+ <%%= fx_card(class: "m-4") do |card| %>
34
+ <%% card.with_section do %>
35
+ <%%= render "form", <%= singular %>: @<%= singular %> %>
36
+ <%% end %>
37
+ <%% end %>
38
+ <%% end %>
39
+ <% end -%>
40
+ <% else -%>
41
+ <%%= fx_heading(class: "m-4", size: 2) { t("<%= plural %>.titles.new") } %>
42
+ <%%= fx_card(class: "m-4") do |card| %>
43
+ <%% card.with_section do %>
44
+ <%%= render "form", <%= singular %>: @<%= singular %> %>
45
+ <%% end %>
46
+ <%% end %>
47
+ <% end -%>
@@ -0,0 +1,61 @@
1
+ <% singular = file_name.singularize; plural = file_name.pluralize -%>
2
+ <%%= fx_table(striped: true, only_rows: true, hover: true) do |table| %>
3
+ <%% <%= plural %>.each do |<%= singular %>| %>
4
+ <%% table.with_row(
5
+ id: dom_id(<%= singular %>),
6
+ class: "cursor-pointer hover:bg-gray-50",
7
+ title: <%= %{t("#{plural}.helpers.click_to_edit")} %>,
8
+ <% if options[:turbo] && options[:ui] != "none" -%>data: {
9
+ controller: "fx-row-click",
10
+ fx_row_click_url_value: edit_<%= path_prefix %><%= singular %>_path(<%= singular %>),
11
+ fx_row_click_frame_value: "<%= options[:ui] == "modal" ? "modal" : "drawer" %>"
12
+ }<% end -%>) do |row| %>
13
+ <%% row.with_cell(width: "1%") { fx_checkbox(id: dom_id(<%= singular %>, "select"), value: <%= singular %>.id, name: "<%= singular %>_ids[]", data: { "fx-select-all-target": "select" }) } %>
14
+
15
+ <% attributes.reject { |attr| attr.type == :password_digest }.first(5).each do |attr|
16
+ attr_name = attr.name
17
+ attr_type = attr.type -%>
18
+
19
+ <% if attr_type == :boolean -%>
20
+ <%% row.with_cell(width: "1%", class: "text-center") do %>
21
+ <%%= link_to "#",
22
+ class: "inline-flex items-center justify-center w-full h-full",
23
+ data: {
24
+ controller: "fx-method-link",
25
+ fx_method_link_method_value: "patch",
26
+ fx_method_link_url_value: <%= path_prefix %><%= singular %>_path(<%= singular %>),
27
+ fx_method_link_params_value: { <%= singular %>: { <%= attr_name %>: !<%= singular %>.<%= attr_name %> } }
28
+ },
29
+ title: <%= %{t("#{plural}.helpers.click_to_change_#{attr_name}")} %> do %>
30
+ <%%= anyicon(
31
+ "heroicons_solid:#{<%= singular %>.<%= attr_name %>? ? 'check-circle' : 'x-circle'}",
32
+ class: "size-5 #{<%= singular %>.<%= attr_name %>? ? 'text-green-600' : 'text-red-600'}") %>
33
+ <%% end %>
34
+ <%% end %>
35
+ <% else -%>
36
+ <%% row.with_cell { <%= singular %>.<%= attr_name %>.to_s } %>
37
+ <% end -%>
38
+ <% end -%>
39
+
40
+ <%% row.with_cell(width: "1%") do %>
41
+ <%%= fx_button color: :danger_outline,
42
+ onclick: "event.preventDefault();",
43
+ data: {
44
+ href: <%= path_prefix %><%= singular %>_path(<%= singular %>),
45
+ controller: "fx-assigner",
46
+ fx_assigner_change_param: {
47
+ "#confirm-deletion-button" => {
48
+ "data-fx-method-link-url-value" => <%= path_prefix %><%= singular %>_path(<%= singular %>),
49
+ }
50
+ }.to_json,
51
+ fx_assigner_prevent_default_param: "true",
52
+ action: "fx-assigner#assign",
53
+ "modal-target": "confirm-deletion-modal",
54
+ "modal-toggle": "confirm-deletion-modal"
55
+ }, remove_class: "w-full" do %>
56
+ <%%= anyicon("heroicons_solid:trash", class: "size-4") %>
57
+ <%% end %>
58
+ <%% end %>
59
+ <%% end %>
60
+ <%% end %>
61
+ <%% end %>
@@ -0,0 +1,36 @@
1
+ class <%= file_name.singularize.camelize %>Policy < ApplicationPolicy
2
+ def index?
3
+ true
4
+ end
5
+
6
+ def show?
7
+ true
8
+ end
9
+
10
+ def create?
11
+ true
12
+ end
13
+
14
+ def update?
15
+ true
16
+ end
17
+
18
+ def destroy?
19
+ false
20
+ end
21
+
22
+ def update_all?
23
+ update?
24
+ end
25
+
26
+ def destroy_all?
27
+ destroy?
28
+ end
29
+
30
+ class Scope < ApplicationPolicy::Scope
31
+ # NOTE: Be explicit about which records you allow access to!
32
+ def resolve
33
+ scope.all
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,10 @@
1
+ <turbo-frame id="drawer">
2
+ <script>
3
+ alertsContainer = document.getElementById("notice");
4
+ if (alertsContainer) {
5
+ const alertElement = document.createElement("div");
6
+ alertElement.innerHTML = `<%%= j fx_alert(color: color) { sanitize(message.to_s, tags: [], attributes: []) } %>`;
7
+ alertsContainer.appendChild(alertElement);
8
+ }
9
+ </script>
10
+ </turbo-frame>
@@ -0,0 +1,44 @@
1
+ <% singular = file_name.singularize; plural = file_name.pluralize -%>
2
+ <p id="notice"><%%= notice %></p>
3
+
4
+ <%%= fx_heading(class: "m-4", size: 2) { t("<%= plural %>.titles.show") } %>
5
+
6
+ <%%= fx_card(class: "m-4") do |card| %>
7
+ <%% card.with_section do %>
8
+ <div class="grid gap-4 sm:grid-cols-2">
9
+
10
+ <% attributes.reject { |attr| attr.type == :password_digest }.each do |attr| -%>
11
+ <% attr_name = attr.name -%>
12
+ <% if attr.type == :boolean -%>
13
+ <div>
14
+ <p class="text-xs uppercase tracking-wide text-gray-500"><%%= t("<%= plural %>.fields.<%= attr_name %>") %></p>
15
+ <%%= fx_badge(pill: true, color: @<%= singular %>.<%= attr_name %>? ? :success_bordered : :danger_bordered) { t(@<%= singular %>.<%= attr_name %>?, scope: "<%= plural %>.values.<%= attr_name %>") } %>
16
+ </div>
17
+ <% elsif attr.type == :text -%>
18
+ <div class="sm:col-span-2">
19
+ <p class="text-xs uppercase tracking-wide text-gray-500"><%%= t("<%= plural %>.fields.<%= attr_name %>") %></p>
20
+ <p class="mt-1 leading-relaxed text-gray-700 whitespace-pre-line"><%%= @<%= singular %>.<%= attr_name %> || t("<%= plural %>.values.no_value") %></p>
21
+ </div>
22
+ <% else -%>
23
+ <div>
24
+ <p class="text-xs uppercase tracking-wide text-gray-500"><%%= t("<%= plural %>.fields.<%= attr_name %>") %></p>
25
+ <p class="mt-1 font-medium text-gray-900"><%%= @<%= singular %>.<%= attr_name %> || t("<%= plural %>.values.no_value") %></p>
26
+ </div>
27
+ <% end -%>
28
+ <% end -%>
29
+ </div>
30
+
31
+ <%%= render "metadata", <%= singular %>: @<%= singular %> %>
32
+ <%% end %>
33
+ <%% end %>
34
+
35
+ <div class="m-4 flex gap-2">
36
+ <%%= fx_button as: :a, href: edit_<%= path_prefix %><%= singular %>_path(@<%= singular %>), data: { turbo_frame: "drawer" }, remove_class: "w-full", class: "p-2 px-4" do %>
37
+ <%%= anyicon("heroicons_solid:pencil", class: "size-4") %>
38
+ <span class="pl-2"><%%= t("<%= plural %>.actions.edit") %></span>
39
+ <%% end %>
40
+ <%%= fx_button as: :a, href: <%= path_prefix %><%= plural %>_path, remove_class: "w-full", class: "p-2 px-4" do %>
41
+ <%%= anyicon("heroicons_solid:arrow-left", class: "size-4") %>
42
+ <span class="pl-2"><%%= t("<%= plural %>.actions.back") %></span>
43
+ <%% end %>
44
+ </div>
@@ -0,0 +1,6 @@
1
+ <% singular = file_name.singularize; plural = file_name.pluralize -%>
2
+ # app/views/<%= plural %>s/show.json.jbuilder
3
+ json.extract! @<%= singular %>, <%= attributes.reject { |a|
4
+ a.type.to_s == "password_digest" }.map { |a|
5
+ ":#{a.name}" }.join(', ') %>, :created_at, :updated_at
6
+ json.url <%= path_prefix %><%= singular %>_url(@<%= singular %>, format: :json)
@@ -0,0 +1,10 @@
1
+ <% singular = file_name.singularize; plural = file_name.pluralize -%>
2
+ <%% if @<%= singular %>.errors.any? %>
3
+ <%%# On failure: re-render the form (with errors still in drawer) %>
4
+ <%%= turbo_stream.replace "<%= singular %>_form", partial: "<%= namespace_path %>/<%= plural %>/form", locals: { <%= plural %>: [@<%= singular %>] } %>
5
+ <%% else %>
6
+ <%%# On success: replace the existing row, clear drawer, and show notice %>
7
+ <%%= turbo_stream.replace dom_id(@<%= singular %>), partial: "<%= namespace_path %>/<%= plural %>/<%= plural %>", locals: { <%= plural %>: [@<%= singular %>] } %>
8
+ <%%= turbo_stream.update "drawer", "" %>
9
+ <%%= turbo_stream.append "notice", fx_alert(with_content: @message, color: :success) %>
10
+ <%% end %>
@@ -0,0 +1,20 @@
1
+ <% singular = file_name.singularize; plural = file_name.pluralize -%>
2
+ <%% if @errors.empty? %>
3
+ <%%# On success: replace the existing row, clear drawer, and show notice %>
4
+ <%% @<%= plural %>.each do |<%= singular %>| %>
5
+ <%%= turbo_stream.replace dom_id(<%= singular %>),
6
+ partial: "<%= namespace_path %>/<%= plural %>/<%= plural %>",
7
+ locals: { <%= plural %>: [<%= singular %>] } %>
8
+ <%% end %>
9
+ <%% end %>
10
+ <%%= turbo_stream.append "notice" do %>
11
+ <%%= fx_alert(color: @errors.any? ? :danger : :success) { @message } %>
12
+ <%% end %>
13
+ <%%= turbo_stream.after "notice" do %>
14
+ <script id="temp-script-<%= Time.current.to_i %>">
15
+ (function() {
16
+ document.getElementById("dropdownActionButton").classList.add("hidden");
17
+ document.currentScript.remove();
18
+ })();
19
+ </script>
20
+ <%% end %>
@@ -1,12 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- gem_path = Gem.loaded_specs['fluxbit_view_components'].full_gem_path
3
+ gem_path = Gem.loaded_specs["fluxbit_view_components"].full_gem_path
4
4
  template_path = File.join(gem_path, "lib/fluxbit/templates/tailwind.config.js.template")
5
5
  darkmode_path = File.join(gem_path, "lib/fluxbit/templates/darkmode.js.template")
6
6
  layout_path = Rails.root.join("app/views/layouts/application.html.erb")
7
7
  importmap_binstub = Rails.root.join("bin/importmap")
8
8
  importmap_config = Rails.root.join("config/importmap.rb")
9
9
  stimulus_path = Rails.root.join("app/javascript/controllers/index.js")
10
+ application_js_path = Rails.root.join("app/javascript/application.js")
10
11
  package_json_path = Rails.root.join("package.json")
11
12
  tailwind_config_path = Rails.root.join("tailwind.config.js")
12
13
  stylesheets_path = Rails.root.join("app/assets/stylesheets/application.tailwind.css")
@@ -25,6 +26,12 @@ system "#{RbConfig.ruby} ./bin/rails tailwindcss:install"
25
26
  say.call "- Installing Flowbite via npm..."
26
27
  system "npm install flowbite --save"
27
28
 
29
+ say.call "- Installing Fluxbit ViewComponents JavaScript package via npm..."
30
+ system "npm install fluxbit_view_components --save"
31
+
32
+ say.call "- Installing flowbite-datepicker via npm..."
33
+ system "npm install flowbite-datepicker --save"
34
+
28
35
  say.call "- Copying tailwind.config.js from template..."
29
36
  if File.exist?(template_path)
30
37
  FileUtils.cp(template_path, tailwind_config_path)
@@ -37,12 +44,63 @@ if stylesheets_path.exist?
37
44
  say.call "- Updating CSS with Flowbite imports..."
38
45
  content = File.read(stylesheets_path)
39
46
  content.prepend("@import \"flowbite/src/themes/default\";\n")
40
- content << "\n@plugin \"flowbite/plugin\";\n@source \"../../../node_modules/flowbite\";\n@config \"../../../tailwind.config.js\";\n"
47
+ content << "\n@plugin \"flowbite/plugin\";\n@source \"../../../node_modules/flowbite\";\n@config \"../../../tailwind.config.js\";\n@custom-variant dark (&:where(.dark, .dark *));\n\n"
41
48
  File.write(stylesheets_path, content)
42
49
  else
43
50
  say.call "⚠️ Couldn't find application.tailwind.css, skipping CSS modifications", :red
44
51
  end
45
52
 
53
+ if application_js_path.exist?
54
+ say.call "- Updating application.js with Fluxbit imports..."
55
+ app_js_content = File.read(application_js_path)
56
+
57
+ unless app_js_content.include?("flowbite/dist/flowbite.turbo.js")
58
+ # Find the line with "./controllers" import and add before it
59
+ if app_js_content.include?("./controllers")
60
+ gsub_file application_js_path.to_s, 'import "./controllers"',
61
+ 'import "flowbite/dist/flowbite.turbo.js"' + "\n" +
62
+ 'import "flowbite-datepicker"' + "\n" +
63
+ 'import "./controllers"' + "\n" +
64
+ 'import "fluxbit-view-components"'
65
+ say.call " Added Flowbite and Fluxbit imports to application.js"
66
+ else
67
+ say.call " ⚠️ Couldn't find './controllers' import in application.js", :red
68
+ say.call " Add these lines manually:", :red
69
+ say.call ' import "flowbite/dist/flowbite.turbo.js"', :red
70
+ say.call ' import "flowbite-datepicker"', :red
71
+ say.call ' import "fluxbit-view-components"', :red
72
+ end
73
+ else
74
+ say.call " Flowbite imports already exist in application.js, skipping..."
75
+ end
76
+ else
77
+ say.call "⚠️ Couldn't find application.js, skipping JavaScript modifications", :red
78
+ say.call " Add these lines to your application.js:", :red
79
+ say.call ' import "flowbite/dist/flowbite.turbo.js"', :red
80
+ say.call ' import "flowbite-datepicker"', :red
81
+ say.call ' import "fluxbit-view-components"', :red
82
+ end
83
+
84
+ if stimulus_path.exist?
85
+ say.call "- Updating controllers/index.js with Fluxbit controllers..."
86
+ controllers_content = File.read(stimulus_path)
87
+
88
+ unless controllers_content.include?("registerFluxbitControllers")
89
+ # Add the Fluxbit controller registration at the end
90
+ controllers_content << "\nimport { registerFluxbitControllers } from \"fluxbit-view-components\"\n"
91
+ controllers_content << "registerFluxbitControllers(Stimulus)\n"
92
+ File.write(stimulus_path, controllers_content)
93
+ say.call " Added Fluxbit controller registration to controllers/index.js"
94
+ else
95
+ say.call " Fluxbit controllers already registered, skipping..."
96
+ end
97
+ else
98
+ say.call "⚠️ Couldn't find controllers/index.js, skipping Stimulus controller setup", :red
99
+ say.call " Add these lines to your controllers/index.js:", :red
100
+ say.call ' import { registerFluxbitControllers } from "fluxbit-view-components"', :red
101
+ say.call ' registerFluxbitControllers(Stimulus)', :red
102
+ end
103
+
46
104
  if layout_path.exist?
47
105
  say.call "- Updating layout to include Fluxbit styles..."
48
106
 
@@ -59,7 +117,7 @@ if layout_path.exist?
59
117
 
60
118
 
61
119
  if layout_content.include?("<body")
62
- # gsub_file layout_path.to_s, "<html", "<html class=\"<%= fluxbit_html_classes %>\""
120
+ # gsub_file layout_path.to_s, "<html", "<html class=\"<%= fx_html_class %>\""
63
121
  gsub_file layout_path.to_s, "<body>", "<body class=\"<%= fx_body_class %>\">"
64
122
  else
65
123
  say.call "<body> tag is not found in application layout.", :red
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluxbit_view_components
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arthur Molina
@@ -127,80 +127,132 @@ dependencies:
127
127
  - - ">="
128
128
  - !ruby/object:Gem::Version
129
129
  version: '0'
130
- - !ruby/object:Gem::Dependency
131
- name: kamal
132
- requirement: !ruby/object:Gem::Requirement
133
- requirements:
134
- - - ">="
135
- - !ruby/object:Gem::Version
136
- version: '0'
137
- type: :development
138
- prerelease: false
139
- version_requirements: !ruby/object:Gem::Requirement
140
- requirements:
141
- - - ">="
142
- - !ruby/object:Gem::Version
143
- version: '0'
144
130
  email:
145
131
  - arthurmolina@gmail.com
146
132
  executables: []
147
133
  extensions: []
148
134
  extra_rdoc_files: []
149
135
  files:
150
- - LICENSE.txt
151
136
  - README.md
137
+ - app/assets/javascripts/fluxbit_view_components.js
138
+ - app/assets/javascripts/fluxbit_view_components/assigner_controller.js
139
+ - app/assets/javascripts/fluxbit_view_components/auto_submit_controller.js
140
+ - app/assets/javascripts/fluxbit_view_components/drawer_controller.js
141
+ - app/assets/javascripts/fluxbit_view_components/index.js
142
+ - app/assets/javascripts/fluxbit_view_components/method_link_controller.js
143
+ - app/assets/javascripts/fluxbit_view_components/modal_controller.js
144
+ - app/assets/javascripts/fluxbit_view_components/password_controller.js
145
+ - app/assets/javascripts/fluxbit_view_components/progress_controller.js
146
+ - app/assets/javascripts/fluxbit_view_components/row_click_controller.js
147
+ - app/assets/javascripts/fluxbit_view_components/select_all_controller.js
148
+ - app/assets/javascripts/fluxbit_view_components/spinner_percent_controller.js
149
+ - app/assets/javascripts/fluxbit_view_components/theme_button_controller.js
150
+ - app/components/fluxbit/accordion_component.rb
152
151
  - app/components/fluxbit/alert_component.rb
153
152
  - app/components/fluxbit/avatar_component.rb
154
153
  - app/components/fluxbit/avatar_group_component.rb
155
154
  - app/components/fluxbit/badge_component.rb
155
+ - app/components/fluxbit/banner_component.rb
156
+ - app/components/fluxbit/bottom_navigation_component.rb
157
+ - app/components/fluxbit/breadcrumb_component.rb
156
158
  - app/components/fluxbit/button_component.rb
157
159
  - app/components/fluxbit/button_group_component.rb
158
160
  - app/components/fluxbit/card_component.rb
161
+ - app/components/fluxbit/carousel_component.rb
159
162
  - app/components/fluxbit/component.rb
163
+ - app/components/fluxbit/drawer_component.html.erb
164
+ - app/components/fluxbit/drawer_component.rb
165
+ - app/components/fluxbit/dropdown_component.rb
166
+ - app/components/fluxbit/dropdown_item_component.rb
160
167
  - app/components/fluxbit/flex_component.rb
161
- - app/components/fluxbit/form/checkbox_input_component.rb
168
+ - app/components/fluxbit/form/check_box_component.rb
162
169
  - app/components/fluxbit/form/component.rb
163
- - app/components/fluxbit/form/datepicker_component.rb
170
+ - app/components/fluxbit/form/dropzone_component.html.erb
171
+ - app/components/fluxbit/form/dropzone_component.rb
172
+ - app/components/fluxbit/form/field_component.rb
164
173
  - app/components/fluxbit/form/form_builder_component.rb
165
- - app/components/fluxbit/form/helper_text_component.rb
174
+ - app/components/fluxbit/form/help_text_component.rb
166
175
  - app/components/fluxbit/form/label_component.rb
167
- - app/components/fluxbit/form/radio_input_component.rb
168
- - app/components/fluxbit/form/range_input_component.rb
169
- - app/components/fluxbit/form/select_free_input_component.rb
170
- - app/components/fluxbit/form/select_input_component.rb
171
- - app/components/fluxbit/form/spacer_input_component.rb
172
- - app/components/fluxbit/form/text_input_component.rb
173
- - app/components/fluxbit/form/textarea_input_component.rb
174
- - app/components/fluxbit/form/toggle_input_component.rb
175
- - app/components/fluxbit/form/upload_image_input_component.html.erb
176
- - app/components/fluxbit/form/upload_image_input_component.rb
177
- - app/components/fluxbit/form/upload_input_component.html.erb
178
- - app/components/fluxbit/form/upload_input_component.rb
176
+ - app/components/fluxbit/form/password_component.rb
177
+ - app/components/fluxbit/form/radio_group_button_component.rb
178
+ - app/components/fluxbit/form/range_component.rb
179
+ - app/components/fluxbit/form/select_component.rb
180
+ - app/components/fluxbit/form/text_field_component.rb
181
+ - app/components/fluxbit/form/toggle_component.html.erb
182
+ - app/components/fluxbit/form/toggle_component.rb
183
+ - app/components/fluxbit/form/upload_image_component.html.erb
184
+ - app/components/fluxbit/form/upload_image_component.rb
179
185
  - app/components/fluxbit/gravatar_component.rb
180
186
  - app/components/fluxbit/heading_component.rb
187
+ - app/components/fluxbit/icon_helpers.rb
188
+ - app/components/fluxbit/link_component.rb
181
189
  - app/components/fluxbit/modal_component.rb
190
+ - app/components/fluxbit/pagination_component.rb
182
191
  - app/components/fluxbit/popover_component.rb
192
+ - app/components/fluxbit/progress_component.rb
193
+ - app/components/fluxbit/skeleton_component.rb
194
+ - app/components/fluxbit/speed_dial_action_component.html.erb
195
+ - app/components/fluxbit/speed_dial_action_component.rb
196
+ - app/components/fluxbit/speed_dial_component.html.erb
197
+ - app/components/fluxbit/speed_dial_component.rb
198
+ - app/components/fluxbit/spinner_component.rb
199
+ - app/components/fluxbit/spinner_percent_component.rb
200
+ - app/components/fluxbit/stepper_component.rb
183
201
  - app/components/fluxbit/tab_component.rb
202
+ - app/components/fluxbit/table_component.rb
203
+ - app/components/fluxbit/table_group_component.rb
184
204
  - app/components/fluxbit/text_component.rb
205
+ - app/components/fluxbit/theme_button_component.rb
206
+ - app/components/fluxbit/timeline_component.rb
207
+ - app/components/fluxbit/timeline_item_component.html.erb
208
+ - app/components/fluxbit/timeline_item_component.rb
185
209
  - app/components/fluxbit/tooltip_component.rb
186
- - app/helpers/fluxbit/classes_helper.rb
187
210
  - app/helpers/fluxbit/components_helper.rb
211
+ - app/helpers/fluxbit/form_builder.rb
212
+ - app/helpers/fluxbit/view_helper.rb
188
213
  - config/deploy.yml
189
214
  - config/locales/en.yml
215
+ - config/locales/pt-BR.yml
216
+ - lib/fluxbit/config/accordion_component.rb
190
217
  - lib/fluxbit/config/alert_component.rb
191
218
  - lib/fluxbit/config/avatar_component.rb
192
219
  - lib/fluxbit/config/badge_component.rb
220
+ - lib/fluxbit/config/banner_component.rb
221
+ - lib/fluxbit/config/bottom_navigation_component.rb
222
+ - lib/fluxbit/config/breadcrumb_component.rb
193
223
  - lib/fluxbit/config/button_component.rb
194
224
  - lib/fluxbit/config/card_component.rb
225
+ - lib/fluxbit/config/carousel_component.rb
226
+ - lib/fluxbit/config/drawer_component.rb
227
+ - lib/fluxbit/config/dropdown_component.rb
195
228
  - lib/fluxbit/config/flex_component.rb
196
- - lib/fluxbit/config/form/helper_text_component.rb
229
+ - lib/fluxbit/config/form/check_box_component.rb
230
+ - lib/fluxbit/config/form/dropzone_component.rb
231
+ - lib/fluxbit/config/form/help_text_component.rb
232
+ - lib/fluxbit/config/form/label_component.rb
233
+ - lib/fluxbit/config/form/password_component.rb
234
+ - lib/fluxbit/config/form/radio_group_button_component.rb
235
+ - lib/fluxbit/config/form/range_component.rb
236
+ - lib/fluxbit/config/form/text_field_component.rb
237
+ - lib/fluxbit/config/form/toggle_component.rb
197
238
  - lib/fluxbit/config/gravatar_component.rb
198
239
  - lib/fluxbit/config/heading_component.rb
240
+ - lib/fluxbit/config/link_component.rb
199
241
  - lib/fluxbit/config/modal_component.rb
242
+ - lib/fluxbit/config/pagination_component.rb
200
243
  - lib/fluxbit/config/paragraph_component.rb
201
244
  - lib/fluxbit/config/popover_component.rb
245
+ - lib/fluxbit/config/progress_component.rb
246
+ - lib/fluxbit/config/skeleton_component.rb
247
+ - lib/fluxbit/config/speed_dial_component.rb
248
+ - lib/fluxbit/config/spinner_component.rb
249
+ - lib/fluxbit/config/spinner_percent_component.rb
250
+ - lib/fluxbit/config/stepper_component.rb
202
251
  - lib/fluxbit/config/tab_component.rb
252
+ - lib/fluxbit/config/table_component.rb
203
253
  - lib/fluxbit/config/text_component.rb
254
+ - lib/fluxbit/config/theme_button_component.rb
255
+ - lib/fluxbit/config/timeline_component.rb
204
256
  - lib/fluxbit/config/tooltip_component.rb
205
257
  - lib/fluxbit/templates/darkmode.js.template
206
258
  - lib/fluxbit/templates/tailwind.config.js.template
@@ -208,9 +260,49 @@ files:
208
260
  - lib/fluxbit/view_components/engine.rb
209
261
  - lib/fluxbit/view_components/version.rb
210
262
  - lib/fluxbit_view_components.rb
263
+ - lib/generators/fluxbit/devise_views_generator.rb
264
+ - lib/generators/fluxbit/pagy_generator.rb
265
+ - lib/generators/fluxbit/scaffold_generator.rb
266
+ - lib/generators/fluxbit/templates/_alert.html.erb.tt
267
+ - lib/generators/fluxbit/templates/_flash.html.erb.tt
268
+ - lib/generators/fluxbit/templates/_form.html.erb.tt
269
+ - lib/generators/fluxbit/templates/_metadata.html.erb.tt
270
+ - lib/generators/fluxbit/templates/controller.rb.tt
271
+ - lib/generators/fluxbit/templates/create.turbo_stream.erb.tt
272
+ - lib/generators/fluxbit/templates/destroy.turbo_stream.erb.tt
273
+ - lib/generators/fluxbit/templates/destroy_all.turbo_stream.erb.tt
274
+ - lib/generators/fluxbit/templates/devise_views/confirmations/new.html.erb
275
+ - lib/generators/fluxbit/templates/devise_views/layouts/devise.html.erb
276
+ - lib/generators/fluxbit/templates/devise_views/mailer/confirmation_instructions.html.erb
277
+ - lib/generators/fluxbit/templates/devise_views/mailer/email_changed.html.erb
278
+ - lib/generators/fluxbit/templates/devise_views/mailer/password_changed.html.erb
279
+ - lib/generators/fluxbit/templates/devise_views/mailer/reset_password_instructions.html.erb
280
+ - lib/generators/fluxbit/templates/devise_views/mailer/unlock_instructions.html.erb
281
+ - lib/generators/fluxbit/templates/devise_views/passwords/edit.html.erb
282
+ - lib/generators/fluxbit/templates/devise_views/passwords/new.html.erb
283
+ - lib/generators/fluxbit/templates/devise_views/registrations/edit.html.erb
284
+ - lib/generators/fluxbit/templates/devise_views/registrations/new.html.erb
285
+ - lib/generators/fluxbit/templates/devise_views/sessions/new.html.erb
286
+ - lib/generators/fluxbit/templates/devise_views/shared/_error_messages.html.erb
287
+ - lib/generators/fluxbit/templates/devise_views/shared/_links.html.erb
288
+ - lib/generators/fluxbit/templates/devise_views/unlocks/new.html.erb
289
+ - lib/generators/fluxbit/templates/edit.html.erb.tt
290
+ - lib/generators/fluxbit/templates/fluxbit_pagy.css
291
+ - lib/generators/fluxbit/templates/i18n.en.yml.tt
292
+ - lib/generators/fluxbit/templates/i18n.pt-BR.yml.tt
293
+ - lib/generators/fluxbit/templates/index.html.erb.tt
294
+ - lib/generators/fluxbit/templates/index.json.jbuilder.tt
295
+ - lib/generators/fluxbit/templates/new.html.erb.tt
296
+ - lib/generators/fluxbit/templates/partial.html.erb.tt
297
+ - lib/generators/fluxbit/templates/policy.rb.tt
298
+ - lib/generators/fluxbit/templates/send_alert_via_drawer.erb.tt
299
+ - lib/generators/fluxbit/templates/show.html.erb.tt
300
+ - lib/generators/fluxbit/templates/show.json.jbuilder.tt
301
+ - lib/generators/fluxbit/templates/update.turbo_stream.erb.tt
302
+ - lib/generators/fluxbit/templates/update_all.turbo_stream.erb.tt
211
303
  - lib/install/install.rb
212
304
  - lib/tasks/fluxbit_view_components_tasks.rake
213
- homepage: https://github.com/baoagency/fluxbit-view-components
305
+ homepage: https://github.com/arthurmolina/fluxbit_view_components
214
306
  licenses:
215
307
  - MIT
216
308
  metadata:
@@ -231,5 +323,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
231
323
  requirements: []
232
324
  rubygems_version: 3.6.7
233
325
  specification_version: 4
234
- summary: ViewComponents for Fluxbit Design System
326
+ summary: ViewComponents based on Flowbite Design System
235
327
  test_files: []
data/LICENSE.txt DELETED
@@ -1,20 +0,0 @@
1
- Copyright 2021 Dan Gamble
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.