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
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Fluxbit::Form::CheckboxInputComponent < Fluxbit::Form::Component
4
- # rubocop: disable Layout/LineLength
5
- cattr_accessor :styles do
6
- {
7
- checkbox: "rounded-sm",
8
- base: "w-4 h-4 text-blue-600 bg-slate-100 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-slate-700 dark:border-slate-600",
9
- label: {
10
- with_helper: "font-medium text-slate-900 dark:text-slate-300",
11
- base: "ml-2 text-sm font-medium text-slate-900 dark:text-slate-300"
12
- },
13
- input_div: "flex items-center h-5",
14
- helper_div: "ml-2 text-sm",
15
- no_helper_div: "flex items-center"
16
- }
17
- end
18
- # rubocop: enable Layout/LineLength
19
-
20
- def initialize(form: nil, field: nil, label: nil, helper_text: nil, helper_popover: nil,
21
- helper_popover_placement: "right", **props)
22
- super
23
- @form = form
24
- @field = field
25
- @object = form&.object
26
- @props = props
27
- @label = label_value(label, @object, field, id)
28
- @helper_text = define_helper_text(helper_text, @object, field)
29
- @helper_popover = define_helper_popover(helper_popover, @object, field)
30
- @helper_popover_placement = helper_popover_placement
31
-
32
- @props[:type] = @props[:type].to_s.in?(%w[checkbox radio]) ? @props[:type].to_s : "checkbox"
33
- add(class: styles[:checkbox], to: @props, first_element: true) if @props[:type] == "checkbox"
34
- add(class: styles[:base], to: @props, first_element: true)
35
- end
36
-
37
- def input
38
- if @form.nil?
39
- content_tag :input, content, @props
40
- else
41
- @form.text_field(@field, **@props)
42
- end
43
- end
44
-
45
- def call
46
- if @helper_text
47
- content_tag :div, { class: "flex" } do
48
- concat content_tag(:div, input, { class: styles[:input_div] })
49
- concat content_tag(:div, { class: styles[:helper_div] }) do
50
- concat label
51
- concat helper_text
52
- end
53
- end
54
- else
55
- content_tag :div, { class: styles[:no_helper_div] } do
56
- concat input
57
- concat label
58
- end
59
- end
60
- end
61
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Fluxbit::Form::DatepickerComponent < Fluxbit::Form::Component
4
- cattr_accessor :styles
5
-
6
- def call; end
7
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Fluxbit::Form::RadioInputComponent < Fluxbit::Form::Component
4
- def initialize(**kwargs, &block)
5
- super
6
- kwargs[:type] = :radio
7
-
8
- @component_klass = "Fluxbit::Form::CheckboxInputComponent".constantize
9
- @kwargs = kwargs
10
- @block = block
11
- end
12
-
13
- def call
14
- if @kwargs[:with_content]
15
- content = @kwargs.delete(:with_content)
16
- render(@component_klass.new(**@kwargs).with_content(content), &@block)
17
- else
18
- render(@component_klass.new(**@kwargs), &@block)
19
- end
20
- end
21
- end
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Fluxbit::Form::RangeInputComponent < Fluxbit::Form::Component
4
- cattr_accessor :styles do
5
- {
6
- base: "w-full bg-slate-200 rounded-lg appearance-none cursor-pointer dark:bg-slate-700",
7
- sizes: {
8
- sm: "h-1 range-sm",
9
- md: "h-2",
10
- lg: "h-3 range-lg"
11
- }
12
- }
13
- end
14
-
15
- def initialize(form: nil, field: nil, sizing: :md, label: nil, helper_text: nil, helper_popover: nil,
16
- helper_popover_placement: "right", **props)
17
- super
18
- @form = form
19
- @field = field
20
- @object = form&.object
21
- @sizing = sizing.in?(styles[:sizes].keys) ? sizing : :md
22
- @props = props
23
- @label = label_value(label, @object, field, id)
24
- @helper_text = define_helper_text(helper_text, @object, field)
25
- @helper_popover = define_helper_popover(helper_popover, @object, field)
26
- @helper_popover_placement = helper_popover_placement
27
- @props[:type] = "range"
28
-
29
- add(class: styles[:sizes][@sizing], to: @props, first_element: true)
30
- add(class: styles[:base], to: @props, first_element: true)
31
- end
32
-
33
- def id
34
- return @id ||= (0...30).map { ("a".."z").to_a[rand(26)] }.join if @props[:id].nil? && @form.nil?
35
- return @props[:id] unless @props[:id].nil?
36
-
37
- "#{@form.object_name}_#{@field}"
38
- end
39
-
40
- def range
41
- if @form.nil?
42
- content_tag :input, content, @props
43
- else
44
- @form.text_field(@field, **@props)
45
- end
46
- end
47
-
48
- def call
49
- safe_join([ label, range, helper_text ])
50
- end
51
- end
@@ -1,77 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Fluxbit::Form::SelectFreeInputComponent < Fluxbit::Form::Component
4
- def initialize(free_option: "Specify...", **kwargs, &block)
5
- super
6
-
7
- @kwargs = kwargs
8
- @block = block
9
- @free_option = free_option
10
- end
11
-
12
- def call
13
- if @kwargs[:with_content]
14
- content = @kwargs.delete(:with_content)
15
- content_tag :div do
16
- concat render(Fluxbit::Form::SelectInputComponent.new(**select_params).with_content(content), &@block)
17
- concat render(Fluxbit::Form::TextInputComponent.new(**text_params).with_content(content), &@block)
18
- end
19
- else
20
- content_tag :div do
21
- concat render(Fluxbit::Form::SelectInputComponent.new(**select_params), &@block)
22
- concat render(Fluxbit::Form::TextInputComponent.new(**text_params), &@block)
23
- end
24
- end
25
- end
26
-
27
- private
28
-
29
- def select_params
30
- @kwargs[:options].push @free_option
31
- @kwargs.merge(
32
- {
33
- class: (corresponding_options? ? "" : "hidden").to_s,
34
- onchange: "
35
- const select = this.selectedOptions[0];
36
- const input = this.parentElement.querySelector('div > input');
37
- const input_div = this.parentElement.querySelector('div');
38
- if(select.value == '#{@free_option}') {
39
- input.value = ''
40
- this.classList.add('hidden');
41
- input_div.classList.remove('hidden');
42
- } else {
43
- input.value = select.value;
44
- }
45
- "
46
- }
47
- )
48
- end
49
-
50
- def text_params
51
- @kwargs.merge(
52
- {
53
- label: false,
54
- helper_popover: false,
55
- helper_text: false,
56
- right_icon: "heroicons_solid:x-mark:cursor-pointer",
57
- right_icon_props: {
58
- onclick: "
59
- this.parentElement.classList.add('hidden');
60
- this.parentElement.querySelector('input').value='';
61
- this.parentElement.parentElement.querySelector('select').classList.remove('hidden');
62
- this.parentElement.parentElement.querySelector('select').selectedIndex = null;
63
- "
64
- },
65
- div_props: { class: (corresponding_options? ? "hidden" : "").to_s }
66
- }
67
- )
68
- end
69
-
70
- def corresponding_options?
71
- value.blank? || @kwargs[:options].include?(value)
72
- end
73
-
74
- def value
75
- @kwargs[:value] || @kwargs[:form]&.object&[@kwargs[:field]]
76
- end
77
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Fluxbit::Form::SelectInputComponent < Fluxbit::Form::Component
4
- def initialize(**kwargs, &block)
5
- super
6
- kwargs[:type] = :select
7
-
8
- @component_klass = "Fluxbit::Form::TextInputComponent".constantize
9
- @kwargs = kwargs
10
- @block = block
11
- end
12
-
13
- def call
14
- if @kwargs[:with_content]
15
- content = @kwargs.delete(:with_content)
16
- render(@component_klass.new(**@kwargs).with_content(content), &@block)
17
- else
18
- render(@component_klass.new(**@kwargs), &@block)
19
- end
20
- end
21
- end
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Fluxbit::Form::SpacerInputComponent < Fluxbit::Component
4
- def initialize(with_content: "", **_args)
5
- super
6
- @with_content = with_content
7
- end
8
-
9
- def call
10
- content || @with_content
11
- end
12
- end
@@ -1,225 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- #
4
- # @param
5
- # form: The form to create a input element
6
- # options: {
7
- # size: :large, :base, :small,
8
- # label: nil | 'Label',
9
- # placeholder: nil | 'placeholder',
10
- # validators: [:required]
11
- # required: true | false | message,
12
- # }
13
- #
14
- # Validators can be predefined or customized:
15
- # [:required, :min_length, :max_length, :min_value, :max_value,
16
- # { type: :regexp, regex: /dd/, success: '', failure: ''},
17
- # ]
18
- #
19
- class Fluxbit::Form::TextInputComponent < Fluxbit::Form::Component
20
- # rubocop: disable Layout/LineLength, Metrics/BlockLength
21
- cattr_accessor :styles do
22
- {
23
- default: "mt-1 block w-full border disabled:cursor-not-allowed disabled:opacity-50 disabled:text-slate-900 disabled:dark:text-slate-400 disabled:bg-slate-100 disabled:dark:bg-slate-700",
24
- text: {
25
- default: "text-slate-900 dark:text-white",
26
- success: "text-green-900",
27
- failure: "text-red-900",
28
- info: "text-cyan-900",
29
- warning: "text-yellow-900"
30
- },
31
- ring: {
32
- default: "focus:ring-blue-500 dark:focus:ring-blue-500",
33
- success: "focus:ring-green-500",
34
- failure: "focus:ring-red-500",
35
- info: "focus:ring-cyan-500",
36
- warning: "focus:ring-yellow-500"
37
- },
38
- bg: {
39
- default: "bg-slate-50 dark:bg-slate-700",
40
- success: "bg-green-50 dark:bg-green-100",
41
- failure: "bg-red-50 dark:bg-red-100",
42
- info: "bg-cyan-50 dark:bg-cyan-100",
43
- warning: "bg-yellow-50 dark:bg-yellow-100"
44
- },
45
- placeholder: {
46
- default: "dark:placeholder-slate-400",
47
- success: "placeholder-green-700",
48
- failure: "placeholder-red-700",
49
- info: "placeholder-cyan-700",
50
- warning: "placeholder-yellow-700"
51
- },
52
- border: {
53
- default: "border-slate-300 focus:border-blue-500 dark:border-slate-600 dark:focus:border-blue-500",
54
- success: "border-green-500 focus:border-green-500 dark:border-green-400",
55
- failure: "border-red-500 focus:border-red-500 dark:border-red-400",
56
- info: "border-cyan-500 focus:border-cyan-500 dark:border-cyan-400",
57
- warning: "border-yellow-500 focus:border-yellow-500 dark:border-yellow-400"
58
- },
59
- shadow: "shadow-xs dark:shadow-xs-light",
60
- icon: "pl-10",
61
- right_icon: "pr-10",
62
- sizing: {
63
- md: "p-2.5 text-sm rounded-lg",
64
- lg: "p-4 sm:text-md rounded-lg",
65
- sm: "p-2 rounded-lg sm:text-xs",
66
- md_addon: "p-2.5 rounded-none rounded-r-lg flex-1 min-w-0 text-sm"
67
- },
68
- additional_icons: {
69
- class: {
70
- default: "mt-1 w-4 h-4 text-slate-500 dark:text-slate-400",
71
- success: "mt-1 w-4 h-4 text-green-500 dark:text-green-400",
72
- failure: "mt-1 w-4 h-4 text-red-500 dark:text-red-400",
73
- info: "mt-1 w-4 h-4 text-cyan-500 dark:text-cyan-400",
74
- warning: "mt-1 w-4 h-4 text-yellow-500 dark:text-yellow-400"
75
- },
76
- icon: "absolute inset-y-0 left-0 flex items-center pl-3",
77
- right_icon: "absolute inset-y-0 right-0 flex items-center pr-3",
78
- addon: {
79
- default: "mt-1 inline-flex items-center px-3 text-sm text-slate-900 bg-slate-200 border border-r-0 border-slate-300 rounded-l-md dark:bg-slate-600 dark:text-slate-400 dark:border-slate-600",
80
- success: "mt-1 inline-flex items-center px-3 text-sm text-green-900 bg-green-200 border border-r-0 border-green-300 rounded-l-md dark:bg-green-600 dark:text-green-400 dark:border-green-600",
81
- failure: "mt-1 inline-flex items-center px-3 text-sm text-red-900 bg-red-200 border border-r-0 border-red-300 rounded-l-md dark:bg-red-600 dark:text-red-400 dark:border-red-600",
82
- info: "mt-1 inline-flex items-center px-3 text-sm text-cyan-900 bg-cyan-200 border border-r-0 border-cyan-300 rounded-l-md dark:bg-cyan-600 dark:text-cyan-400 dark:border-cyan-600",
83
- warning: "mt-1 inline-flex items-center px-3 text-sm text-yellow-900 bg-yellow-200 border border-r-0 border-yellow-300 rounded-l-md dark:bg-yellow-600 dark:text-yellow-400 dark:border-yellow-600"
84
- }
85
- }
86
- }
87
- end
88
- # rubocop: enable Layout/LineLength, Metrics/BlockLength
89
-
90
- def initialize(form: nil, field: nil, id: nil, shadow: false, type: "text", helper_text: nil,
91
- helper_popover: nil, helper_popover_placement: "right", icon: nil,
92
- right_icon: nil, addon: nil, color: nil, label: nil, sizing: :md, i18n: nil, options: [],
93
- validators: [], div_props: {}, icon_props: {}, right_icon_props: {}, addon_props: {}, **props)
94
- super
95
- @form = form
96
- @object = form&.object
97
- @field = field
98
- @id = id
99
- @shadow = shadow
100
- @type = valid_input_type(type)
101
- @helper_text = define_helper_text(helper_text, @object, field)
102
- @helper_popover = define_helper_popover(helper_popover, @object, field)
103
- @helper_popover_placement = helper_popover_placement
104
- @icon = icon
105
- @right_icon = right_icon
106
- @addon = addon
107
- @color = valid_color(color)
108
- @label = label_value(label, @object, field, id)
109
- @sizing = sizing_with_addon(sizing, addon)
110
- @validators = validators
111
- @props = props.merge(type: @type)
112
- @options = options
113
- @sizing = :md_addon if addon
114
- @div_props = div_props
115
- @icon_props = icon_props
116
- @right_icon_props = right_icon_props
117
- @addon_props = addon_props
118
-
119
- declare_classes
120
- end
121
-
122
- def call
123
- safe_join [ label, icon_container, helper_text ]
124
- end
125
-
126
- private
127
-
128
- def valid_input_type(type)
129
- %w[email password number search time date datetime-local select].include?(type.to_s) ? type.to_s : "text"
130
- end
131
-
132
- def valid_color(color)
133
- return color if styles[:bg].key?(color)
134
- return :failure if errors.present?
135
-
136
- :default
137
- end
138
-
139
- def sizing_with_addon(sizing, addon)
140
- return :md_addon if addon
141
-
142
- sizing.in?(%i[md sm lg]) ? sizing : :md
143
- end
144
-
145
- def declare_classes
146
- add to: @props,
147
- first_element: true,
148
- class: [
149
- styles[:default],
150
- (@props.key?(:readonly) || @props.key?(:disabled) ? styles[:text][@color] : ""),
151
- styles[:ring][@color],
152
- styles[:bg][@color],
153
- styles[:placeholder][@color],
154
- styles[:border][@color],
155
- styles[:sizing][@sizing],
156
- (@shadow ? styles[:shadow] : ""),
157
- (@right_icon ? styles[:right_icon] : ""),
158
- (@icon ? styles[:icon] : "")
159
- ].join(" ")
160
- end
161
-
162
- def icon(icon_v, tag: :div, props: nil)
163
- return "" if icon_v.blank?
164
-
165
- content_tag(
166
- tag,
167
- anyicon(
168
- icon: icon_v,
169
- class: styles[:additional_icons][:class][@color]
170
- ),
171
- **props
172
- )
173
- end
174
-
175
- def create_icon
176
- add class: styles[:additional_icons][:icon], to: @icon_props
177
- add(class: "pointer-events-none", to: @icon_props) unless events?(@icon_props)
178
- icon(@icon, props: @icon_props)
179
- end
180
-
181
- def create_addon
182
- add class: styles[:additional_icons][:addon][@color], to: @addon_props
183
- icon(@addon, tag: :span, props: @addon_props)
184
- end
185
-
186
- def create_right_icon
187
- add class: styles[:additional_icons][:right_icon], to: @right_icon_props
188
- add(class: "pointer-events-none", to: @right_icon_props) unless events?(@right_icon_props)
189
- icon(@right_icon, props: @right_icon_props)
190
- end
191
-
192
- def events?(props)
193
- props.keys.intersection(
194
- %i[onclick onsubmit onchange onkeydown onkeyup onkeypress href]
195
- ).present?
196
- end
197
-
198
- def input
199
- return content_tag :input, content, @props if @form.nil?
200
-
201
- if @type == "select"
202
- @props[:prompt] = @props[:placeholder] if @props[:placeholder]
203
- return @form.select(@field, @options || [], {}, @props)
204
- end
205
-
206
- @form.text_field(@field, **@props)
207
- end
208
-
209
- def icon_container_with_addon
210
- add class: "flex", to: @div_props
211
- content_tag :div, safe_join([ create_addon, create_right_icon, input ]), @div_props
212
- end
213
-
214
- def icon_container_without_addon
215
- add class: "relative w-full", to: @div_props
216
- content_tag :div, safe_join([ create_icon, create_right_icon, input ]), @div_props
217
- end
218
-
219
- def icon_container
220
- return input if @icon.nil? && @right_icon.nil? && @addon.nil?
221
- return icon_container_with_addon unless @addon.nil?
222
-
223
- icon_container_without_addon
224
- end
225
- end
@@ -1,57 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Fluxbit::Form::TextareaInputComponent < Fluxbit::Form::Component
4
- # rubocop: disable Layout/LineLength
5
- cattr_accessor :styles do
6
- {
7
- base: "mt-1 block w-full rounded-lg border disabled:cursor-not-allowed disabled:opacity-50 text-sm",
8
- bg: {
9
- default: "bg-slate-50 border-slate-300 text-slate-900 focus:border-blue-500 focus:ring-blue-500 dark:border-slate-600 dark:bg-slate-700 dark:text-white dark:placeholder-slate-400 dark:focus:border-blue-500 dark:focus:ring-blue-500",
10
- success: "border-green-500 bg-green-50 text-green-900 placeholder-green-700 focus:border-green-500 focus:ring-green-500 dark:border-green-400 dark:bg-green-100 dark:focus:border-green-500 dark:focus:ring-green-500",
11
- failure: "border-red-500 bg-red-50 text-red-900 placeholder-red-700 focus:border-red-500 focus:ring-red-500 dark:border-red-400 dark:bg-red-100 dark:focus:border-red-500 dark:focus:ring-red-500",
12
- info: "border-cyan-500 bg-cyan-50 text-cyan-900 placeholder-cyan-700 focus:border-cyan-500 focus:ring-cyan-500 dark:border-cyan-400 dark:bg-cyan-100 dark:focus:border-cyan-500 dark:focus:ring-cyan-500",
13
- warning: "border-yellow-500 bg-yellow-50 text-yellow-900 placeholder-yellow-700 focus:border-yellow-500 focus:ring-yellow-500 dark:border-yellow-400 dark:bg-yellow-100 dark:focus:border-yellow-500 dark:focus:ring-yellow-500"
14
- },
15
- shadow: "shadow-xs dark:shadow-xs-light"
16
- }
17
- end
18
- # rubocop: enable Layout/LineLength
19
-
20
- def initialize(form: nil, field: nil, color: nil, label: nil, helper_text: nil, helper_popover: nil,
21
- helper_popover_placement: "right", shadow: false, **props)
22
- super
23
- @form = form
24
- @object = form&.object
25
- @field = field
26
- @shadow = shadow
27
- @color = valid_color(color)
28
- @props = props
29
- @label = label_value(label, @object, field, id)
30
- @helper_text = define_helper_text(helper_text, @object, field)
31
- @helper_popover = define_helper_popover(helper_popover, @object, field)
32
- @helper_popover_placement = helper_popover_placement
33
-
34
- add(class: styles[:shadow], to: @props, first_element: true) if shadow
35
- add(class: styles[:bg][@color], to: @props, first_element: true)
36
- add(class: styles[:base], to: @props, first_element: true)
37
- end
38
-
39
- def valid_color(color)
40
- return color if styles[:bg].key?(color)
41
- return :failure if errors.present?
42
-
43
- :default
44
- end
45
-
46
- def textarea
47
- if @form.nil?
48
- content_tag :textarea, content, @props
49
- else
50
- @form.text_area(@field, **@props)
51
- end
52
- end
53
-
54
- def call
55
- safe_join([ label, textarea, helper_text ])
56
- end
57
- end