flowbite-components 0.1.3 → 0.2.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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -4
  3. data/README.md +56 -8
  4. data/app/components/flowbite/breadcrumb/home_icon.rb +28 -0
  5. data/app/components/flowbite/breadcrumb/item/current.rb +35 -0
  6. data/app/components/flowbite/breadcrumb/item/first.rb +37 -0
  7. data/app/components/flowbite/breadcrumb/item.rb +50 -0
  8. data/app/components/flowbite/breadcrumb/separator_icon.rb +34 -0
  9. data/app/components/flowbite/breadcrumb.rb +54 -0
  10. data/app/components/flowbite/button/outline.rb +25 -10
  11. data/app/components/flowbite/button/pill.rb +26 -26
  12. data/app/components/flowbite/button.rb +39 -35
  13. data/app/components/flowbite/card/card.html.erb +7 -0
  14. data/app/components/flowbite/card/title.rb +39 -0
  15. data/app/components/flowbite/card.rb +71 -16
  16. data/app/components/flowbite/input/checkbox.rb +13 -11
  17. data/app/components/flowbite/input/date.rb +2 -2
  18. data/app/components/flowbite/input/date_time.rb +11 -0
  19. data/app/components/flowbite/input/email.rb +2 -2
  20. data/app/components/flowbite/input/file.rb +13 -11
  21. data/app/components/flowbite/input/hint.rb +16 -8
  22. data/app/components/flowbite/input/label.rb +15 -10
  23. data/app/components/flowbite/input/number.rb +2 -2
  24. data/app/components/flowbite/input/password.rb +2 -2
  25. data/app/components/flowbite/input/phone.rb +2 -2
  26. data/app/components/flowbite/input/radio_button.rb +13 -11
  27. data/app/components/flowbite/input/select.rb +7 -7
  28. data/app/components/flowbite/input/textarea.rb +13 -11
  29. data/app/components/flowbite/input/url.rb +2 -2
  30. data/app/components/flowbite/input/validation_error.rb +32 -2
  31. data/app/components/flowbite/input.rb +155 -0
  32. data/app/components/flowbite/input_field/checkbox.html.erb +2 -4
  33. data/app/components/flowbite/input_field/checkbox.rb +8 -4
  34. data/app/components/flowbite/input_field/date_time.rb +13 -0
  35. data/app/components/flowbite/input_field/input_field.html.erb +2 -2
  36. data/app/components/flowbite/input_field/radio_button.html.erb +2 -4
  37. data/app/components/flowbite/input_field/radio_button.rb +19 -21
  38. data/app/components/flowbite/input_field.rb +117 -49
  39. data/app/components/flowbite/link.rb +43 -0
  40. data/app/components/flowbite/styles.rb +34 -0
  41. data/app/components/flowbite/toast/icon.html.erb +5 -0
  42. data/app/components/flowbite/toast/icon.rb +57 -0
  43. data/app/components/flowbite/toast/toast.html.erb +40 -0
  44. data/app/components/flowbite/toast.rb +37 -0
  45. data/lib/flowbite/components/version.rb +1 -1
  46. data/lib/yard/flowbite_viewcomponent.rb +24 -0
  47. metadata +37 -5
  48. data/app/components/flowbite/input/field.rb +0 -117
@@ -1,19 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Flowbite
4
- # Renders a HTML button element.
5
- #
6
- # See https://flowbite.com/docs/components/buttons/
7
- #
8
- # @param label [String] The text to display on the button.
4
+ # Renders a HTML button element. See https://flowbite.com/docs/components/buttons/
9
5
  #
10
6
  # All other parameters are optional and are passed directly to the button tag
11
7
  # as HTML attributes.
8
+ #
9
+ # @example Basic usage
10
+ # <%= render Flowbite::Button.new { "Click me" } %>
11
+ #
12
+ # @lookbook_embed ButtonPreview
12
13
  class Button < ViewComponent::Base
13
14
  SIZES = {
14
- xs: ["text-xs", "px-3", "py-2"],
15
+ xs: ["text-xs", "px-3", "py-1.5"],
15
16
  sm: ["text-sm", "px-3", "py-2"],
16
- default: ["text-sm", "px-5", "py-2.5"],
17
+ default: ["text-sm", "px-4", "py-2.5"],
17
18
  lg: ["text-base", "px-5", "py-3"],
18
19
  xl: ["text-base", "px-6", "py-3.5"]
19
20
  }.freeze
@@ -31,39 +32,42 @@ module Flowbite
31
32
 
32
33
  # rubocop:disable Layout/LineLength
33
34
  def styles
34
- {
35
- alternative: Flowbite::Style.new(
36
- default: ["font-medium", "text-gray-900", "focus:outline-none", "bg-white", "rounded-lg", "border", "border-gray-200", "hover:bg-gray-100", "hover:text-blue-700", "focus:z-10", "focus:ring-4", "focus:ring-gray-100", "dark:focus:ring-gray-700", "dark:bg-gray-800", "dark:text-gray-400", "dark:border-gray-600", "dark:hover:text-white", "dark:hover:bg-gray-700"]
37
- ),
38
- dark: Flowbite::Style.new(
39
- default: ["text-white", "bg-gray-800", "hover:bg-gray-900", "focus:ring-4", "focus:ring-gray-300", "font-medium", "rounded-lg", "dark:bg-gray-800", "dark:hover:bg-gray-700", "dark:focus:ring-gray-700", "dark:border-gray-700"]
40
- ),
41
- default: Flowbite::Style.new(
42
- default: ["text-white", "bg-blue-700", "hover:bg-blue-800", "focus:ring-4", "focus:ring-blue-300", "font-medium", "rounded-lg", "dark:bg-blue-600", "dark:hover:bg-blue-700", "focus:outline-none", "dark:focus:ring-blue-800"]
43
- ),
44
- green: Flowbite::Style.new(
45
- default: ["focus:outline-none", "text-white", "bg-green-700", "hover:bg-green-800", "focus:ring-4", "focus:ring-green-300", "font-medium", "rounded-lg", "dark:bg-green-600", "dark:hover:bg-green-700", "dark:focus:ring-green-800"]
46
- ),
47
- light: Flowbite::Style.new(
48
- default: ["text-gray-900", "bg-white", "border", "border-gray-300", "hover:bg-gray-100", "focus:ring-4", "focus:ring-gray-100", "font-medium", "rounded-lg", "dark:bg-gray-800", "dark:text-white", "dark:border-gray-600", "dark:hover:bg-gray-700", "dark:hover:border-gray-600", "dark:focus:ring-gray-700"]
49
- ),
50
- purple: Flowbite::Style.new(
51
- default: ["focus:outline-none", "text-white", "bg-purple-700", "hover:bg-purple-800", "focus:ring-4", "focus:ring-purple-300", "font-medium", "rounded-lg", "dark:bg-purple-600", "dark:hover:bg-purple-700", "dark:focus:ring-purple-900"]
52
- ),
53
- red: Flowbite::Style.new(
54
- default: ["focus:outline-none", "text-white", "bg-red-700", "hover:bg-red-800", "focus:ring-4", "focus:ring-red-300", "font-medium", "rounded-lg", "dark:bg-red-600", "dark:hover:bg-red-700", "dark:focus:ring-red-900"]
55
- ),
56
- yellow: Flowbite::Style.new(
57
- default: ["focus:outline-none", "text-white", "bg-yellow-400", "hover:bg-yellow-500", "focus:ring-4", "focus:ring-yellow-300", "font-medium", "rounded-lg", "dark:focus:ring-yellow-900"]
58
- )
59
- }.freeze
35
+ Flowbite::Styles.from_hash(
36
+ {
37
+ danger: {
38
+ default: ["focus:outline-none", "text-white", "bg-danger", "box-border", "border", "border-transparent", "hover:bg-danger-strong", "focus:ring-4", "focus:ring-danger-medium", "shadow-xs", "font-medium", "leading-5", "rounded-base"]
39
+ },
40
+ dark: {
41
+ default: ["focus:outline-none", "text-white", "bg-dark", "box-border", "border", "border-transparent", "hover:bg-dark-strong", "focus:ring-4", "focus:ring-neutral-tertiary", "shadow-xs", "font-medium", "leading-5", "rounded-base"]
42
+ },
43
+ default: {
44
+ default: ["focus:outline-none", "text-white", "bg-brand", "box-border", "border", "border-transparent", "hover:bg-brand-strong", "focus:ring-4", "focus:ring-brand-medium", "shadow-xs", "font-medium", "leading-5", "rounded-base"]
45
+ },
46
+ ghost: {
47
+ default: ["focus:outline-none", "text-heading", "bg-transparent", "box-border", "border", "border-transparent", "hover:bg-neutral-secondary-medium", "focus:ring-4", "focus:ring-neutral-tertiary", "font-medium", "leading-5", "rounded-base"]
48
+ },
49
+ secondary: {
50
+ default: ["focus:outline-none", "text-body", "bg-neutral-secondary-medium", "box-border", "border", "border-default-medium", "hover:bg-neutral-tertiary-medium", "focus:ring-4", "focus:ring-neutral-tertiary", "shadow-xs", "font-medium", "leading-5", "rounded-base"]
51
+ },
52
+ success: {
53
+ default: ["focus:outline-none", "text-white", "bg-success", "box-border", "border", "border-transparent", "hover:bg-success-strong", "focus:ring-4", "focus:ring-success-medium", "shadow-xs", "font-medium", "leading-5", "rounded-base"]
54
+ },
55
+ tertiary: {
56
+ default: ["focus:outline-none", "text-body", "bg-neutral-primary-soft", "box-border", "border", "border-default", "hover:bg-neutral-secondary-medium", "focus:ring-4", "focus:ring-neutral-tertiary-soft", "shadow-xs", "font-medium", "leading-5", "rounded-base"]
57
+ },
58
+ warning: {
59
+ default: ["focus:outline-none", "text-white", "bg-warning", "box-border", "border", "border-transparent", "hover:bg-warning-strong", "focus:ring-4", "focus:ring-warning-medium", "shadow-xs", "font-medium", "leading-5", "rounded-base"]
60
+ }
61
+ }.freeze
62
+ )
60
63
  end
61
64
  # rubocop:enable Layout/LineLength
62
65
  end
63
66
 
64
67
  attr_reader :button_attributes, :size, :style
65
68
 
66
- def initialize(size: :default, style: :default, **button_attributes)
69
+ def initialize(class: nil, size: :default, style: :default, **button_attributes)
70
+ @class = Array.wrap(binding.local_variable_get(:class))
67
71
  @size = size
68
72
  @style = style
69
73
  @button_attributes = button_attributes
@@ -80,7 +84,7 @@ module Flowbite
80
84
  private
81
85
 
82
86
  def classes
83
- self.class.classes(size: size, state: :default, style: style)
87
+ self.class.classes(size: size, state: :default, style: style) + @class
84
88
  end
85
89
 
86
90
  def options
@@ -0,0 +1,7 @@
1
+ <%= content_tag(:div, card_options) do %>
2
+ <%= title %>
3
+
4
+ <% if content.present? %>
5
+ <div class="font-normal text-body"><%= content %></div>
6
+ <% end %>
7
+ <% end %>
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ class Card
5
+ # Renders the title of a card element.
6
+ class Title < ViewComponent::Base
7
+ class << self
8
+ def classes(state: :default, style: :default)
9
+ style = styles.fetch(style)
10
+ style.fetch(state)
11
+ end
12
+
13
+ # rubocop:disable Layout/LineLength
14
+ def styles
15
+ Flowbite::Styles.from_hash(
16
+ {
17
+ default: {
18
+ default: ["mb-2", "text-2xl", "font-semibold", "tracking-tight", "text-heading"]
19
+ }
20
+ }.freeze
21
+ )
22
+ end
23
+ # rubocop:enable Layout/LineLength
24
+ end
25
+
26
+ def call
27
+ title_options = {
28
+ class: self.class.classes
29
+ }.merge(@options)
30
+
31
+ content_tag(:h5, content, **title_options)
32
+ end
33
+
34
+ def initialize(**options)
35
+ @options = options || {}
36
+ end
37
+ end
38
+ end
39
+ end
@@ -3,8 +3,24 @@
3
3
  module Flowbite
4
4
  # Renders a card element.
5
5
  #
6
- # See https://flowbite.com/docs/components/cards/
6
+ # To render a title in the card, use the title argument or the title slot.
7
+ #
8
+ # @example Using the title slot
9
+ # <%= render(Flowbite::Card.new) do |card| %>
10
+ # <% card.with_title do %>
11
+ # <div><%= parent_category.name %></div>
12
+ # <%= render(Flowbite::Card::Title.new) { category.name } %>
13
+ # <% end %>
14
+ # <% end %>
15
+ #
16
+ # @viewcomponent_slot [Flowbite::Card::Title] title The title of the card,
17
+ # rendered at the top. Use +with_title+ to set custom content.
18
+ #
19
+ # @see https://flowbite.com/docs/components/cards/
20
+ # @lookbook_embed CardPreview
7
21
  class Card < ViewComponent::Base
22
+ renders_one :title
23
+
8
24
  class << self
9
25
  def classes(state: :default, style: :default)
10
26
  style = styles.fetch(style)
@@ -13,33 +29,72 @@ module Flowbite
13
29
 
14
30
  # rubocop:disable Layout/LineLength
15
31
  def styles
16
- {
17
- default: Flowbite::Style.new(
18
- default: ["p-6", "bg-white", "border", "border-gray-200", "rounded-lg", "shadow-sm", "dark:bg-gray-800", "dark:border-gray-700"]
19
- )
20
- }.freeze
32
+ Flowbite::Styles.from_hash(
33
+ {
34
+ default: {
35
+ default: ["p-6", "bg-neutral-primary-soft", "border", "border-default", "rounded-base", "shadow-xs"]
36
+ }
37
+ }.freeze
38
+ )
21
39
  end
22
40
  # rubocop:enable Layout/LineLength
23
41
  end
24
42
 
25
- def call
26
- card_options = {}
27
- card_options[:class] = self.class.classes + @class
28
-
29
- content_tag(:div, card_options.merge(@options)) do
30
- concat(content_tag(:div, content, class: "font-normal text-gray-700 dark:text-gray-400"))
31
- end
32
- end
33
-
34
43
  # @param class [Array<String>] Additional CSS classes for the card
35
44
  # container.
36
45
  #
37
46
  # @param options [Hash] Additional HTML options for the card container
38
47
  # (e.g., custom classes, data attributes). These options are merged into
39
48
  # the card's root element.
40
- def initialize(class: [], options: {})
49
+ #
50
+ # @param title [Hash] An optional title for the card. If provided,
51
+ # it will be rendered at the top of the card in a h5 tag using the
52
+ # Card::Title component. The hash can contain:
53
+ # - `content`: The text content of the title
54
+ # - `options`: Additional HTML options to pass to the title element
55
+ # Alternatively, you can use the `title` slot to provide the entire
56
+ # title element yourself.
57
+ def initialize(class: [], options: {}, title: {})
41
58
  @class = Array(binding.local_variable_get(:class)) || []
42
59
  @options = options || {}
60
+ @title = title
61
+ end
62
+
63
+ protected
64
+
65
+ def card_options
66
+ card_options = {}
67
+ card_options[:class] = self.class.classes + @class
68
+ card_options.merge(@options)
69
+ end
70
+
71
+ # Returns the HTML to use for the title element if any
72
+ def default_title
73
+ component = Flowbite::Card::Title.new(**default_title_options)
74
+
75
+ if default_title_content
76
+ component.with_content(default_title_content)
77
+ else
78
+ component
79
+ end
80
+
81
+ render(component)
82
+ end
83
+
84
+ def default_title_content
85
+ return nil unless @title
86
+
87
+ @title[:content]
88
+ end
89
+
90
+ # @return [Hash] The options to pass to the default title component
91
+ def default_title_options
92
+ title_options = @title.dup
93
+ title_options[:options] || {}
94
+ end
95
+
96
+ def title?
97
+ @title.present?
43
98
  end
44
99
  end
45
100
  end
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Flowbite
4
- module Input
4
+ class Input
5
5
  # The checkbox component can be used to receive one or more selected options
6
6
  # from the user in the form of a square box available in multiple styles,
7
7
  # sizes, colors, and variants coded with the utility classes from Tailwind
8
8
  # CSS and with support for dark mode.
9
9
  #
10
10
  # https://flowbite.com/docs/forms/checkbox/
11
- class Checkbox < Field
11
+ class Checkbox < Input
12
12
  DEFAULT_CHECKED_VALUE = "1"
13
13
  DEFAULT_UNCHECKED_VALUE = "0"
14
14
 
@@ -22,13 +22,15 @@ module Flowbite
22
22
 
23
23
  # rubocop:disable Layout/LineLength
24
24
  def styles
25
- {
26
- default: Flowbite::Style.new(
27
- default: ["text-blue-600", "bg-gray-100", "border-gray-300", "rounded-sm", "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"],
28
- disabled: ["text-blue-600", "bg-gray-100", "border-gray-300", "rounded-sm", "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"],
29
- error: ["text-red-600", "bg-red-50", "border-red-500", "rounded-sm", "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"]
30
- )
31
- }.freeze
25
+ Flowbite::Styles.from_hash(
26
+ {
27
+ default: {
28
+ default: ["text-brand", "bg-neutral-secondary-medium", "border-default-medium", "rounded-sm", "focus:ring-brand", "focus:ring-2"],
29
+ disabled: ["text-brand", "bg-neutral-secondary-medium", "border-default-medium", "rounded-sm", "focus:ring-brand", "focus:ring-2", "cursor-not-allowed"],
30
+ error: ["text-danger", "bg-danger-soft", "border-danger-subtle", "rounded-sm", "focus:ring-danger", "focus:ring-2"]
31
+ }
32
+ }.freeze
33
+ )
32
34
  end
33
35
  end
34
36
 
@@ -43,8 +45,8 @@ module Flowbite
43
45
  )
44
46
  end
45
47
 
46
- def initialize(attribute:, form:, disabled: false, options: {}, size: :default, unchecked_value: DEFAULT_UNCHECKED_VALUE, value: DEFAULT_CHECKED_VALUE)
47
- super(attribute: attribute, form: form, disabled: disabled, options: options, size: size)
48
+ def initialize(attribute:, form:, class: nil, disabled: false, options: {}, size: :default, unchecked_value: DEFAULT_UNCHECKED_VALUE, value: DEFAULT_CHECKED_VALUE)
49
+ super(attribute: attribute, class: binding.local_variable_get(:class), form: form, disabled: disabled, options: options, size: size)
48
50
  @unchecked_value = unchecked_value
49
51
  @value = value
50
52
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Flowbite
4
- module Input
5
- class Date < Field
4
+ class Input
5
+ class Date < Input
6
6
  def input_field_type
7
7
  :date_field
8
8
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ class Input
5
+ class DateTime < Input
6
+ def input_field_type
7
+ :datetime_field
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Flowbite
4
- module Input
5
- class Email < Field
4
+ class Input
5
+ class Email < Input
6
6
  # Returns the name of the method used to generate HTML for the input field
7
7
  def input_field_type
8
8
  :email_field
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Flowbite
4
- module Input
5
- class File < Field
4
+ class Input
5
+ class File < Input
6
6
  SIZES = {
7
- sm: ["text-xs"],
7
+ sm: ["text-sm"],
8
8
  default: ["text-sm"],
9
- lg: ["text-lg"]
9
+ lg: ["text-base"]
10
10
  }.freeze
11
11
 
12
12
  # Returns the name of the method used to generate HTML for the input field
@@ -16,13 +16,15 @@ module Flowbite
16
16
 
17
17
  # rubocop:disable Layout/LineLength
18
18
  def self.styles
19
- {
20
- default: Flowbite::Style.new(
21
- default: ["block", "w-full", "text-gray-900", "border", "border-gray-300", "rounded-lg", "cursor-pointer", "bg-gray-50", "focus:outline-none", "dark:text-gray-400", "dark:bg-gray-700", "dark:border-gray-600"],
22
- disabled: ["block", "w-full", "text-gray-400", "border", "border-gray-300", "rounded-lg", "cursor-not-allowed", "bg-gray-100", "dark:text-gray-500", "dark:bg-gray-600", "dark:border-gray-500"],
23
- error: ["block", "w-full", "text-red-900", "border", "border-red-500", "rounded-lg", "cursor-pointer", "bg-red-50", "focus:outline-none", "dark:text-red-400", "dark:bg-gray-700", "dark:border-red-500"]
24
- )
25
- }.freeze
19
+ Flowbite::Styles.from_hash(
20
+ {
21
+ default: {
22
+ default: ["block", "w-full", "text-heading", "border", "border-default-medium", "rounded-base", "cursor-pointer", "bg-neutral-secondary-medium", "focus:outline-none"],
23
+ disabled: ["block", "w-full", "text-fg-disabled", "border", "border-default-medium", "rounded-base", "cursor-not-allowed", "bg-neutral-secondary-medium"],
24
+ error: ["block", "w-full", "text-fg-danger-strong", "border", "border-danger-subtle", "rounded-base", "cursor-pointer", "bg-danger-soft", "focus:outline-none"]
25
+ }
26
+ }.freeze
27
+ )
26
28
  end
27
29
  # rubocop:enable Layout/LineLength
28
30
  end
@@ -1,7 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Flowbite
4
- module Input
4
+ class Input
5
+ # A hint element for input fields.
6
+ #
7
+ # Provides additional context or instructions for the user.
8
+ #
9
+ # See https://flowbite.com/docs/forms/input-field/#helper-text
5
10
  class Hint < ViewComponent::Base
6
11
  STATES = [
7
12
  DEFAULT = :default
@@ -14,11 +19,13 @@ module Flowbite
14
19
  end
15
20
 
16
21
  def styles
17
- {
18
- default: Flowbite::Style.new(
19
- default: ["mt-2", "text-sm", "text-gray-500", "dark:text-gray-400"]
20
- )
21
- }.freeze
22
+ Flowbite::Styles.from_hash(
23
+ {
24
+ default: {
25
+ default: ["mt-2.5", "text-sm", "text-body"]
26
+ }
27
+ }.freeze
28
+ )
22
29
  end
23
30
  end
24
31
 
@@ -30,8 +37,9 @@ module Flowbite
30
37
  )
31
38
  end
32
39
 
33
- def initialize(attribute:, form:, options: {})
40
+ def initialize(attribute:, form:, class: nil, options: {})
34
41
  @attribute = attribute
42
+ @class = Array.wrap(binding.local_variable_get(:class))
35
43
  @form = form
36
44
  @options = options
37
45
  @object = form.object
@@ -39,7 +47,7 @@ module Flowbite
39
47
 
40
48
  # Returns an array with the CSS classes to apply to the label element
41
49
  def classes
42
- self.class.classes(state: state)
50
+ self.class.classes(state: state) + @class
43
51
  end
44
52
 
45
53
  protected
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Flowbite
4
- module Input
4
+ class Input
5
5
  # https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-label
6
6
  class Label < ViewComponent::Base
7
7
  STATES = [
@@ -17,13 +17,15 @@ module Flowbite
17
17
  end
18
18
 
19
19
  def styles
20
- {
21
- default: Flowbite::Style.new(
22
- default: ["block", "mb-2", "text-sm", "font-medium", "text-gray-900", "dark:text-white"],
23
- disabled: ["block", "mb-2", "text-sm", "font-medium", "text-gray-400", "dark:text-gray-500"],
24
- error: ["block", "mb-2", "text-sm", "font-medium", "text-red-700", "dark:text-red-500"]
25
- )
26
- }.freeze
20
+ Flowbite::Styles.from_hash(
21
+ {
22
+ default: {
23
+ default: ["block", "mb-2.5", "text-sm", "font-medium", "text-heading"],
24
+ disabled: ["block", "mb-2.5", "text-sm", "font-medium", "text-fg-disabled"],
25
+ error: ["block", "mb-2.5", "text-sm", "font-medium", "text-fg-danger-strong"]
26
+ }
27
+ }.freeze
28
+ )
27
29
  end
28
30
  end
29
31
 
@@ -36,11 +38,14 @@ module Flowbite
36
38
  end
37
39
 
38
40
  def errors?
41
+ return false unless @object
42
+
39
43
  @object.errors.include?(@attribute.intern)
40
44
  end
41
45
 
42
- def initialize(attribute:, form:, disabled: false, options: {})
46
+ def initialize(attribute:, form:, class: nil, disabled: false, options: {})
43
47
  @attribute = attribute
48
+ @class = Array.wrap(binding.local_variable_get(:class))
44
49
  @disabled = disabled
45
50
  @form = form
46
51
  @object = form.object
@@ -49,7 +54,7 @@ module Flowbite
49
54
 
50
55
  # Returns an array with the CSS classes to apply to the label element
51
56
  def classes
52
- self.class.classes(state: state)
57
+ self.class.classes(state: state) + @class
53
58
  end
54
59
 
55
60
  protected
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Flowbite
4
- module Input
5
- class Number < Field
4
+ class Input
5
+ class Number < Input
6
6
  def input_field_type
7
7
  :number_field
8
8
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Flowbite
4
- module Input
5
- class Password < Field
4
+ class Input
5
+ class Password < Input
6
6
  def input_field_type
7
7
  :password_field
8
8
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Flowbite
4
- module Input
5
- class Phone < Field
4
+ class Input
5
+ class Phone < Input
6
6
  def input_field_type
7
7
  :phone_field
8
8
  end
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Flowbite
4
- module Input
4
+ class Input
5
5
  # The radio button component can be used to allow the user to choose a
6
6
  # single option from one or more available options.
7
7
  #
8
8
  # https://flowbite.com/docs/forms/radio/
9
- class RadioButton < Field
9
+ class RadioButton < Input
10
10
  class << self
11
11
  # Radio buttons only have their default size.
12
12
  def sizes
@@ -17,13 +17,15 @@ module Flowbite
17
17
 
18
18
  # rubocop:disable Layout/LineLength
19
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
20
+ Flowbite::Styles.from_hash(
21
+ {
22
+ default: {
23
+ default: ["text-brand", "bg-neutral-secondary-medium", "border-default-medium", "focus:ring-brand", "focus:ring-2"],
24
+ disabled: ["text-brand", "bg-neutral-secondary-medium", "border-default-medium", "focus:ring-brand", "focus:ring-2", "cursor-not-allowed"],
25
+ error: ["text-danger", "bg-danger-soft", "border-danger-subtle", "focus:ring-danger", "focus:ring-2"]
26
+ }
27
+ }.freeze
28
+ )
27
29
  end
28
30
  end
29
31
 
@@ -37,8 +39,8 @@ module Flowbite
37
39
  )
38
40
  end
39
41
 
40
- def initialize(attribute:, form:, value:, disabled: false, options: {})
41
- super(attribute: attribute, disabled: disabled, form: form, options: options)
42
+ def initialize(attribute:, form:, value:, class: nil, disabled: false, options: {})
43
+ super(attribute: attribute, class: binding.local_variable_get(:class), disabled: disabled, form: form, options: options)
42
44
  @value = value
43
45
  end
44
46
 
@@ -1,21 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Flowbite
4
- module Input
4
+ class Input
5
5
  # The `Select` component renders a select input field for use in forms.
6
6
  #
7
7
  # https://flowbite.com/docs/forms/select/
8
8
  #
9
9
  # Wraps `ActionView::Helpers::FormOptionsHelper#select`: https://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-select
10
- class Select < Field
10
+ class Select < Input
11
11
  SIZES = {
12
- sm: ["p-2", "text-xs"],
13
- default: ["p-2.5", "text-sm"],
14
- lg: ["px-4", "py-3", "text-base"]
12
+ sm: ["px-2.5", "py-2", "text-sm"],
13
+ default: ["px-3", "py-2.5", "text-sm"],
14
+ lg: ["px-3.5", "py-3", "text-base"]
15
15
  }.freeze
16
16
 
17
- def initialize(form:, attribute:, collection: [], disabled: false, include_blank: false, multiple: false, options: {}, size: :default)
18
- super(form: form, attribute: attribute, disabled: disabled, options: options, size: size)
17
+ def initialize(form:, attribute:, class: nil, collection: [], disabled: false, include_blank: false, multiple: false, options: {}, size: :default)
18
+ super(form: form, attribute: attribute, class: binding.local_variable_get(:class), disabled: disabled, options: options, size: size)
19
19
  @collection = collection
20
20
  @include_blank = include_blank
21
21
  @multiple = multiple