flowbite-components 0.1.0 → 0.1.2

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -0
  3. data/README.md +34 -7
  4. data/app/assets/tailwind/flowbite_components/engine.css +2 -0
  5. data/app/components/flowbite/button/outline.rb +22 -0
  6. data/app/components/flowbite/button/pill.rb +40 -0
  7. data/app/components/flowbite/button.rb +92 -0
  8. data/app/components/flowbite/card.rb +43 -0
  9. data/app/components/flowbite/input/checkbox.rb +37 -0
  10. data/app/components/flowbite/input/date.rb +11 -0
  11. data/app/components/flowbite/input/email.rb +12 -0
  12. data/app/components/flowbite/input/field.rb +117 -0
  13. data/app/components/flowbite/input/file.rb +30 -0
  14. data/app/components/flowbite/input/hint.rb +57 -0
  15. data/app/components/flowbite/input/label.rb +82 -0
  16. data/app/components/flowbite/input/number.rb +11 -0
  17. data/app/components/flowbite/input/password.rb +11 -0
  18. data/app/components/flowbite/input/phone.rb +11 -0
  19. data/app/components/flowbite/input/radio_button.rb +50 -0
  20. data/app/components/flowbite/input/select.rb +49 -0
  21. data/app/components/flowbite/input/textarea.rb +42 -0
  22. data/app/components/flowbite/input/url.rb +12 -0
  23. data/app/components/flowbite/input/validation_error.rb +11 -0
  24. data/app/components/flowbite/input_field/checkbox.html.erb +14 -0
  25. data/app/components/flowbite/input_field/checkbox.rb +49 -0
  26. data/app/components/flowbite/input_field/date.rb +13 -0
  27. data/app/components/flowbite/input_field/email.rb +13 -0
  28. data/app/components/flowbite/input_field/file.rb +13 -0
  29. data/app/components/flowbite/input_field/input_field.html.erb +8 -0
  30. data/app/components/flowbite/input_field/number.rb +13 -0
  31. data/app/components/flowbite/input_field/password.rb +13 -0
  32. data/app/components/flowbite/input_field/phone.rb +13 -0
  33. data/app/components/flowbite/input_field/radio_button.html.erb +14 -0
  34. data/app/components/flowbite/input_field/radio_button.rb +88 -0
  35. data/app/components/flowbite/input_field/select.rb +31 -0
  36. data/app/components/flowbite/input_field/text.rb +8 -0
  37. data/app/components/flowbite/input_field/textarea.rb +13 -0
  38. data/app/components/flowbite/input_field/url.rb +13 -0
  39. data/app/components/flowbite/input_field.rb +187 -0
  40. data/app/components/flowbite/style.rb +13 -0
  41. data/lib/flowbite/{view_components → components}/engine.rb +2 -2
  42. data/lib/flowbite/{view_components → components}/version.rb +2 -2
  43. data/lib/flowbite/{view_components.rb → components.rb} +3 -3
  44. metadata +49 -10
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ module Input
5
+ class Password < Field
6
+ def input_field_type
7
+ :password_field
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ module Input
5
+ class Phone < Field
6
+ def input_field_type
7
+ :phone_field
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ module Input
5
+ # The radio button component can be used to allow the user to choose a
6
+ # single option from one or more available options.
7
+ #
8
+ # https://flowbite.com/docs/forms/radio/
9
+ class RadioButton < Field
10
+ class << self
11
+ # Radio buttons only have their default size.
12
+ def sizes
13
+ {
14
+ default: ["w-4", "h-4"]
15
+ }
16
+ end
17
+
18
+ # rubocop:disable Layout/LineLength
19
+ def styles
20
+ {
21
+ default: Flowbite::Style.new(
22
+ default: ["text-blue-600", "bg-gray-100", "border-gray-300", "focus:ring-blue-500", "dark:focus:ring-blue-600", "dark:ring-offset-gray-800", "focus:ring-2", "dark:bg-gray-700", "dark:border-gray-600"],
23
+ disabled: ["text-blue-600", "bg-gray-100", "border-gray-300", "focus:ring-blue-500", "dark:focus:ring-blue-600", "dark:ring-offset-gray-800", "focus:ring-2", "dark:bg-gray-700", "dark:border-gray-600"],
24
+ error: ["text-red-600", "bg-red-50", "border-red-500", "focus:ring-red-500", "dark:focus:ring-red-600", "dark:ring-offset-gray-800", "focus:ring-2", "dark:bg-gray-700", "dark:border-red-500"]
25
+ )
26
+ }.freeze
27
+ end
28
+ end
29
+
30
+ # Returns the HTML to use for the actual input field element.
31
+ def call
32
+ @form.send(
33
+ input_field_type,
34
+ @attribute,
35
+ @value,
36
+ **input_options
37
+ )
38
+ end
39
+
40
+ def initialize(attribute:, form:, value:, disabled: false, options: {})
41
+ super(attribute: attribute, disabled: disabled, form: form, options: options)
42
+ @value = value
43
+ end
44
+
45
+ def input_field_type
46
+ :radio_button
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ module Input
5
+ # The `Select` component renders a select input field for use in forms.
6
+ #
7
+ # https://flowbite.com/docs/forms/select/
8
+ #
9
+ # Wraps `ActionView::Helpers::FormOptionsHelper#select`: https://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-select
10
+ class Select < Field
11
+ SIZES = {
12
+ sm: ["p-2", "text-xs"],
13
+ default: ["p-2.5", "text-sm"],
14
+ lg: ["px-4", "py-3", "text-base"]
15
+ }.freeze
16
+
17
+ def initialize(form:, attribute:, collection: [], disabled: false, options: {}, size: :default)
18
+ super(form: form, attribute: attribute, disabled: disabled, options: options, size: size)
19
+ @collection = collection
20
+ end
21
+
22
+ # Returns the HTML to use for the actual input field element.
23
+ def call
24
+ @form.send(
25
+ input_field_type,
26
+ @attribute,
27
+ @collection,
28
+ {},
29
+ html_options
30
+ )
31
+ end
32
+
33
+ # Returns the name of the method used to generate HTML for the input field
34
+ def input_field_type
35
+ :select
36
+ end
37
+
38
+ private
39
+
40
+ # Returns the html_options argument for the select method
41
+ def html_options
42
+ {
43
+ class: classes,
44
+ disabled: disabled?
45
+ }.merge(options)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ module Input
5
+ class Textarea < Field
6
+ class << self
7
+ # rubocop:disable Layout/LineLength
8
+ def styles
9
+ {
10
+ default: Flowbite::Style.new(
11
+ default: ["block", "w-full", "text-gray-900", "bg-gray-50", "rounded-lg", "border", "border-gray-300", "focus:ring-blue-500", "focus:border-blue-500", "dark:bg-gray-700", "dark:border-gray-600", "dark:placeholder-gray-400", "dark:text-white", "dark:focus:ring-blue-500", "dark:focus:border-blue-500"],
12
+ disabled: ["block", "w-full", "bg-gray-100", "rounded-lg", "border", "border-gray-300", "text-gray-900", "cursor-not-allowed"],
13
+ error: ["block", "w-full", "bg-red-50", "border", "border-red-500", "text-red-900", "placeholder-red-700", "rounded-lg", "focus:ring-red-500", "focus:border-red-500", "dark:bg-gray-700", "dark:text-red-500", "dark:placeholder-red-500", "dark:border-red-500"]
14
+ )
15
+ }.freeze
16
+ end
17
+ # rubocop:enable Layout/LineLength
18
+ end
19
+
20
+ # Returns the HTML to use for the actual input field element.
21
+ def call
22
+ @form.send(
23
+ input_field_type,
24
+ @attribute,
25
+ **input_options
26
+ )
27
+ end
28
+
29
+ protected
30
+
31
+ # Returns the CSS classes to apply to the input field
32
+ def classes
33
+ self.class.classes(size: size, state: state)
34
+ end
35
+
36
+ # Returns the name of the method used to generate HTML for the input field
37
+ def input_field_type
38
+ :text_area
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ module Input
5
+ class Url < Field
6
+ # Returns the name of the method used to generate HTML for the input field
7
+ def input_field_type
8
+ :url_field
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ module Input
5
+ class ValidationError < ViewComponent::Base
6
+ def call
7
+ tag.p(content, class: "mt-2 text-sm text-red-600 dark:text-red-500")
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ <div class="flex">
2
+ <div class="flex items-center h-5">
3
+ <%= input %>
4
+ </div>
5
+
6
+ <div class="ms-2 text-sm">
7
+ <%= label %>
8
+ <%= hint %>
9
+ </div>
10
+
11
+ <% errors.each do |error| %>
12
+ <%= render(Flowbite::Input::ValidationError.new) { error.upcase_first } %>
13
+ <% end %>
14
+ </div>
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ class InputField
5
+ class Checkbox < InputField
6
+ protected
7
+
8
+ def input_component
9
+ ::Flowbite::Input::Checkbox
10
+ end
11
+
12
+ protected
13
+
14
+ def default_hint_options
15
+ return {} unless @hint
16
+
17
+ {
18
+ class: hint_classes,
19
+ id: id_for_hint_element
20
+ }.merge(@hint[:options] || {})
21
+ end
22
+
23
+ def default_label_options
24
+ options = super
25
+ options[:options] ||= {}
26
+ options[:options][:class] = options.dig(:options, :class) || label_classes
27
+ options
28
+ end
29
+
30
+ private
31
+
32
+ def hint_classes
33
+ if disabled?
34
+ "text-xs font-normal text-gray-400 dark:text-gray-500"
35
+ else
36
+ "text-xs font-normal text-gray-500 dark:text-gray-300"
37
+ end
38
+ end
39
+
40
+ def label_classes
41
+ if disabled?
42
+ "font-medium text-gray-400 dark:text-gray-500"
43
+ else
44
+ "font-medium text-gray-900 dark:text-gray-300"
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ class InputField
5
+ class Date < InputField
6
+ protected
7
+
8
+ def input_component
9
+ ::Flowbite::Input::Date
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ class InputField
5
+ class Email < InputField
6
+ protected
7
+
8
+ def input_component
9
+ ::Flowbite::Input::Email
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ class InputField
5
+ class File < InputField
6
+ protected
7
+
8
+ def input_component
9
+ ::Flowbite::Input::File
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ <div>
2
+ <%= label %>
3
+ <%= input %>
4
+ <%= hint %>
5
+ <% errors.each do |error| %>
6
+ <%= render(Flowbite::Input::ValidationError.new) { error.upcase_first } %>
7
+ <% end %>
8
+ </div>
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ class InputField
5
+ class Number < InputField
6
+ protected
7
+
8
+ def input_component
9
+ ::Flowbite::Input::Number
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ class InputField
5
+ class Password < InputField
6
+ protected
7
+
8
+ def input_component
9
+ ::Flowbite::Input::Password
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ class InputField
5
+ class Phone < InputField
6
+ protected
7
+
8
+ def input_component
9
+ ::Flowbite::Input::Phone
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ <div class="flex">
2
+ <div class="flex items-center h-5">
3
+ <%= input %>
4
+ </div>
5
+
6
+ <div class="ms-2 text-sm">
7
+ <%= label %>
8
+ <%= hint %>
9
+ </div>
10
+
11
+ <% errors.each do |error| %>
12
+ <%= render(Flowbite::Input::ValidationError.new) { error.upcase_first } %>
13
+ <% end %>
14
+ </div>
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ class InputField
5
+ class RadioButton < InputField
6
+ protected
7
+
8
+ def initialize(attribute:, form:, value:, disabled: false, hint: nil, input: {}, label: {})
9
+ super(attribute: attribute, form: form, disabled: disabled, hint: hint, input: input, label: label)
10
+ @value = value
11
+ end
12
+
13
+ def input_component
14
+ ::Flowbite::Input::RadioButton
15
+ end
16
+
17
+ protected
18
+
19
+ def default_input
20
+ args = {
21
+ attribute: @attribute,
22
+ disabled: disabled?,
23
+ form: @form,
24
+ options: default_input_options.merge(@input[:options] || {}),
25
+ value: @value
26
+ }
27
+
28
+ input_component.new(**args)
29
+ end
30
+
31
+ # Returns options for the default label element. This includes CSS classes
32
+ # since they are specific to RadioButton labels (and Checkbox ones).
33
+ def default_label_options
34
+ super.merge({
35
+ options: {
36
+ class: label_classes,
37
+ for: id_for_input_element
38
+ }
39
+ })
40
+ end
41
+
42
+ # Returns the HTML to use for the hint element if any
43
+ def hint
44
+ return unless hint?
45
+
46
+ component = Flowbite::Input::Hint.new(
47
+ attribute: @attribute,
48
+ form: @form,
49
+ options: {
50
+ class: hint_classes,
51
+ id: id_for_hint_element
52
+ }
53
+ ).with_content(@hint)
54
+ render(component)
55
+ end
56
+
57
+ private
58
+
59
+ def hint_classes
60
+ if disabled?
61
+ "text-xs font-normal text-gray-400 dark:text-gray-500"
62
+ else
63
+ "text-xs font-normal text-gray-500 dark:text-gray-300"
64
+ end
65
+ end
66
+
67
+ def id_for_input_element
68
+ [
69
+ @form.object_name,
70
+ @attribute,
71
+ @value
72
+ ].join("_")
73
+ end
74
+
75
+ def id_for_hint_element
76
+ [id_for_input_element, "hint"].join("_")
77
+ end
78
+
79
+ def label_classes
80
+ if disabled?
81
+ "font-medium text-gray-400 dark:text-gray-500"
82
+ else
83
+ "font-medium text-gray-900 dark:text-gray-300"
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ class InputField
5
+ class Select < InputField
6
+ def initialize(attribute:, form:, collection: [], disabled: false, hint: nil, input: {}, label: {}, size: :default)
7
+ super(attribute: attribute, disabled: disabled, form: form, hint: hint, input: input, label: label, size: size)
8
+ @collection = collection
9
+ end
10
+
11
+ def input
12
+ render(
13
+ input_component.new(
14
+ attribute: @attribute,
15
+ collection: @collection,
16
+ disabled: @disabled,
17
+ form: @form,
18
+ options: input_options,
19
+ size: @size
20
+ )
21
+ )
22
+ end
23
+
24
+ private
25
+
26
+ def input_component
27
+ ::Flowbite::Input::Select
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ class InputField
5
+ class Text < InputField
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ class InputField
5
+ class Textarea < InputField
6
+ protected
7
+
8
+ def input_component
9
+ ::Flowbite::Input::Textarea
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ class InputField
5
+ class Url < InputField
6
+ protected
7
+
8
+ def input_component
9
+ ::Flowbite::Input::Url
10
+ end
11
+ end
12
+ end
13
+ end