flowbite-components 0.1.4 → 0.3.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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +28 -4
  3. data/README.md +23 -4
  4. data/app/components/flowbite/badge/badge.html.erb +4 -0
  5. data/app/components/flowbite/badge/dot.rb +45 -0
  6. data/app/components/flowbite/badge/pill.rb +40 -0
  7. data/app/components/flowbite/badge.rb +116 -0
  8. data/app/components/flowbite/breadcrumb/home_icon.rb +28 -0
  9. data/app/components/flowbite/breadcrumb/item/current.rb +35 -0
  10. data/app/components/flowbite/breadcrumb/item/first.rb +37 -0
  11. data/app/components/flowbite/breadcrumb/item.rb +50 -0
  12. data/app/components/flowbite/breadcrumb/separator_icon.rb +34 -0
  13. data/app/components/flowbite/breadcrumb.rb +54 -0
  14. data/app/components/flowbite/button.rb +6 -5
  15. data/app/components/flowbite/card.rb +15 -1
  16. data/app/components/flowbite/input/checkbox.rb +2 -2
  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 +2 -2
  21. data/app/components/flowbite/input/hint.rb +6 -1
  22. data/app/components/flowbite/input/label.rb +1 -1
  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 +2 -2
  27. data/app/components/flowbite/input/select.rb +2 -2
  28. data/app/components/flowbite/input/textarea.rb +2 -2
  29. data/app/components/flowbite/input/url.rb +2 -2
  30. data/app/components/flowbite/input/validation_error.rb +1 -1
  31. data/app/components/flowbite/input.rb +155 -0
  32. data/app/components/flowbite/input_field/checkbox.rb +7 -7
  33. data/app/components/flowbite/input_field/date_time.rb +13 -0
  34. data/app/components/flowbite/input_field/input_field.html.erb +2 -2
  35. data/app/components/flowbite/input_field/radio_button.rb +9 -15
  36. data/app/components/flowbite/input_field/select.rb +1 -1
  37. data/app/components/flowbite/input_field.rb +120 -69
  38. data/app/components/flowbite/link.rb +2 -0
  39. data/app/components/flowbite/sidebar/item.rb +68 -0
  40. data/app/components/flowbite/sidebar/navigation.rb +62 -0
  41. data/app/components/flowbite/sidebar.rb +62 -0
  42. data/app/components/flowbite/toast/icon.html.erb +5 -0
  43. data/app/components/flowbite/toast/icon.rb +57 -0
  44. data/app/components/flowbite/toast/toast.html.erb +40 -0
  45. data/app/components/flowbite/toast.rb +37 -0
  46. data/lib/flowbite/components/version.rb +1 -1
  47. data/lib/yard/flowbite_viewcomponent.rb +24 -0
  48. metadata +40 -5
  49. data/app/components/flowbite/input/field.rb +0 -126
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Flowbite
4
- # A form element for a single field, containing label, input field, error
5
- # messages, helper text and whatever else is needed for a user friendly input
6
- # experience.
4
+ # A fully fledged form element for an attribute containing label, input field,
5
+ # error messages, helper text and whatever else is needed for a user-friendly
6
+ # input experience.
7
7
  #
8
8
  # @see https://flowbite.com/docs/forms/input-field/
9
9
  #
@@ -13,54 +13,55 @@ module Flowbite
13
13
  # more.
14
14
  #
15
15
  # Usually you'd use one of the subclasses of this class which implement the
16
- # different input types, like `Flowbite::InputField::Text`,
17
- # `Flowbite::InputField::Email`, etc.
16
+ # different input types, like {Flowbite::InputField::Text},
17
+ # {Flowbite::InputField::Email}, etc.
18
18
  #
19
- # Expects 2 arguments:
19
+ # To render an input without labels or error messages etc, see
20
+ # {Flowbite::Input} instead and one of its subclasses.
20
21
  #
21
- # @param attribute [Symbol] The name of the attribute to render in this input
22
- # field.
22
+ # @example Basic usage
23
+ # <% form_for @person do |form| %>
24
+ # <%= render(
25
+ # Flowbite::InputField::Number.new(
26
+ # attribute: :name,
27
+ # form: form
28
+ # )
29
+ # ) %>
30
+ # <% end %>
23
31
  #
24
- # @param form [ActionView::Helpers::FormBuilder] The form builder object that
25
- # will be used to generate the input field.
32
+ # @example Kitchen sink
33
+ # <% form_for @person do |form| %>
34
+ # <%= render(
35
+ # Flowbite::InputField::Number.new(
36
+ # attribute: :name,
37
+ # class: ["mb-4", "w-full"],
38
+ # disabled: true,
39
+ # form: form,
40
+ # hint: {
41
+ # content: "Please enter your full name.",
42
+ # options: {id: "name-helper-text"}
43
+ # },
44
+ # input: {
45
+ # options: {placeholder: "All of your names here"}
46
+ # },
47
+ # label: {
48
+ # content: "Full name",
49
+ # options: {class: ["mb-2", "font-medium"]}
50
+ # },
51
+ # options: {data: {controller: "form-field"}},
52
+ # size: :lg
53
+ # )
54
+ # ) %>
55
+ # <% end %>
26
56
  #
27
- # Supports additional arguments:
57
+ # @viewcomponent_slot [Flowbite::Input::Hint] hint Helper text displayed
58
+ # below the input field to provide additional context or instructions.
59
+ # @viewcomponent_slot [Flowbite::Input] input The input element itself.
60
+ # Usually auto-generated based on the input type subclass.
61
+ # @viewcomponent_slot [Flowbite::Input::Label] label The label for the input
62
+ # field, rendered above the input element.
28
63
  #
29
- # @param hint [String] A hint to display below the input field, providing
30
- # additional context or instructions for the user. This is optional. See
31
- # https://flowbite.com/docs/forms/input-field/#helper-text
32
- #
33
- # @param label [Hash] A hash with options for the label. These are passed to
34
- # Flowbite::Input::Label, see that for details. Can contain:
35
- # - `content`: The content of the label. If not provided, the label will
36
- # default to the attribute name.
37
- # - `options`: A hash of additional options to pass to the label component.
38
- # This can be used to set the class, for example.
39
- #
40
- # @param disabled [Boolean] Whether the input field should be disabled.
41
- # Defaults to `false`.
42
- #
43
- # @param input [Hash] A hash with options for the default input component.
44
- # These are passed to the input components constructor, so see whatever
45
- # component is being used for details. Can contain:
46
- # - `options`: Additional HTML attributes to pass to the input element.
47
- #
48
- # @param size [Symbol] The size of the input field. Can be one of `:sm`,
49
- # `:md`, or `:lg`. Defaults to `:md`.
50
- #
51
- # Sample usage
52
- #
53
- # <% form_for @person do |form| %>
54
- # <%= render(
55
- # Flowbite::InputField::Number.new(
56
- # :attribute => :name,
57
- # :form => form
58
- # )
59
- # ) %>
60
- # <% end %>
61
- #
62
- # To render an input without labels or error messages etc, use
63
- # `Flowbite::Input::Field` instead.
64
+ # @lookbook_embed InputFieldPreview
64
65
  class InputField < ViewComponent::Base
65
66
  renders_one :hint
66
67
  renders_one :input
@@ -75,6 +76,45 @@ module Flowbite
75
76
  @object.errors[@attribute] || []
76
77
  end
77
78
 
79
+ # @param attribute [Symbol] The name of the attribute to render in this
80
+ # input field.
81
+ #
82
+ # @param form [ActionView::Helpers::FormBuilder] The form builder object that
83
+ # will be used to generate the input field.
84
+ #
85
+ # @param class [String, Array<String>] Additional CSS classes to apply to
86
+ # the input field container, i.e. the outermost element. To add classes to
87
+ # individual components of the InputField, use the +input+, +label+ and
88
+ # +hint+ arguments.
89
+ #
90
+ # @param disabled [Boolean] Whether the input field should be disabled.
91
+ #
92
+ # @param hint [Hash] A hint to display below the input field, providing
93
+ # additional context or instructions for the user. If provided, this Hash
94
+ # is passed to the {Flowbite::Input::Hint} constructor.
95
+ # @option hint [String] content The content of the hint element.
96
+ # @option hint [Hash] options Additional options to pass to the hint
97
+ # component. This can be used to set the class, for example.
98
+ #
99
+ # @param input [Hash] A hash with options for the input component.
100
+ # These are passed to the input component's constructor, see the
101
+ # documentation for whatever input component is being used.
102
+ # See {Flowbite::Input}.
103
+ # @option input [Hash] options Additional HTML attributes to pass to
104
+ # the input element.
105
+ #
106
+ # @param label [Hash] A hash with options for the label element. If
107
+ # provided, this Hash is passed to the {Flowbite::Input::Label}
108
+ # constructor.
109
+ # @option label [String] content The content of the label element.
110
+ # @option label [Hash] options Additional options to pass to the label
111
+ # component. This can be used to set the class, for example.
112
+ #
113
+ # @param options [Hash] Additional HTML attributes to pass to the input
114
+ # field container element.
115
+ #
116
+ # @param size [Symbol] The size of the input field. Can be one of +:sm+,
117
+ # +:default+, or +:lg+.
78
118
  def initialize(attribute:, form:, class: nil, disabled: false, hint: nil, input: {}, label: {}, options: {}, size: :default)
79
119
  @attribute = attribute
80
120
  @class = Array.wrap(binding.local_variable_get(:class))
@@ -89,7 +129,7 @@ module Flowbite
89
129
  end
90
130
 
91
131
  def input_component
92
- ::Flowbite::Input::Field
132
+ ::Flowbite::Input
93
133
  end
94
134
 
95
135
  protected
@@ -102,6 +142,10 @@ module Flowbite
102
142
  end
103
143
  end
104
144
 
145
+ def container_options
146
+ @options.merge({class: classes.join(" ")})
147
+ end
148
+
105
149
  def default_container_classes
106
150
  []
107
151
  end
@@ -111,11 +155,19 @@ module Flowbite
111
155
  return unless hint?
112
156
 
113
157
  component = Flowbite::Input::Hint.new(
158
+ **default_hint_arguments
159
+ ).with_content(default_hint_content)
160
+ render(component)
161
+ end
162
+
163
+ # @return [Hash] The keyword arguments for the hint component.
164
+ def default_hint_arguments
165
+ {
114
166
  attribute: @attribute,
167
+ class: @hint[:class],
115
168
  form: @form,
116
169
  options: default_hint_options
117
- ).with_content(default_hint_content)
118
- render(component)
170
+ }
119
171
  end
120
172
 
121
173
  def default_hint_content
@@ -136,23 +188,37 @@ module Flowbite
136
188
  }.merge(@hint[:options] || {})
137
189
  end
138
190
 
191
+ # Returns the HTML to use for the default input element.
192
+ def default_input
193
+ render(input_component.new(**default_input_arguments))
194
+ end
195
+
196
+ # @return [Hash] The keyword arguments for the default input component.
197
+ def default_input_arguments
198
+ {
199
+ attribute: @attribute,
200
+ class: @input[:class],
201
+ disabled: @disabled,
202
+ form: @form,
203
+ options: default_input_options,
204
+ size: @size
205
+ }
206
+ end
207
+
139
208
  # Returns a Hash with the default attributes to apply to the input element.
140
209
  #
141
210
  # The default attributes can be overriden by passing the `input[options]`
142
211
  # argument to the constructor.
143
212
  def default_input_options
144
- if hint?
213
+ options = if hint?
145
214
  {
146
215
  "aria-describedby": id_for_hint_element
147
216
  }
148
217
  else
149
218
  {}
150
219
  end
151
- end
152
220
 
153
- # Returns the HTML to use for the default input element.
154
- def default_input
155
- render(input_component.new(**input_arguments))
221
+ options.merge(@input[:options] || {})
156
222
  end
157
223
 
158
224
  def default_label
@@ -197,20 +263,5 @@ module Flowbite
197
263
  .compact_blank
198
264
  .join("_")
199
265
  end
200
-
201
- # @return [Hash] The keyword arguments for the input component.
202
- def input_arguments
203
- {
204
- attribute: @attribute,
205
- disabled: @disabled,
206
- form: @form,
207
- options: input_options,
208
- size: @size
209
- }
210
- end
211
-
212
- def input_options
213
- default_input_options.merge(@input[:options] || {})
214
- end
215
266
  end
216
267
  end
@@ -5,6 +5,8 @@ module Flowbite
5
5
  # to an external website when clicking on an inline text item, button, or card
6
6
  #
7
7
  # Use this component to add default styles to an inline link element.
8
+ #
9
+ # @lookbook_embed LinkPreview
8
10
  class Link < ViewComponent::Base
9
11
  attr_reader :href, :options
10
12
 
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ class Sidebar
5
+ # Renders a sidebar navigation item.
6
+ #
7
+ # Each item renders as a list item containing a link. Optionally, an icon
8
+ # can be provided using the +icon+ slot, which will be displayed before the
9
+ # label text.
10
+ #
11
+ # @example Basic item
12
+ # <%= render Flowbite::Sidebar::Item.new(href: "/dashboard") { "Dashboard" } %>
13
+ #
14
+ # @example Item with icon
15
+ # <%= render(Flowbite::Sidebar::Item.new(href: "/dashboard")) do |item| %>
16
+ # <% item.with_icon do %>
17
+ # <svg class="w-5 h-5" ...>...</svg>
18
+ # <% end %>
19
+ # Dashboard
20
+ # <% end %>
21
+ #
22
+ # @viewcomponent_slot icon An optional icon displayed before the label text.
23
+ class Item < ViewComponent::Base
24
+ renders_one :icon
25
+
26
+ attr_reader :href, :options
27
+
28
+ class << self
29
+ def classes
30
+ [
31
+ "flex", "items-center", "px-2", "py-1.5", "text-body",
32
+ "rounded-base", "hover:bg-neutral-tertiary", "hover:text-fg-brand", "group"
33
+ ]
34
+ end
35
+ end
36
+
37
+ # @param class [Array<String>] Additional CSS classes for the link element.
38
+ # @param href [String] The URL for the navigation link.
39
+ # @param options [Hash] Additional HTML attributes for the link element.
40
+ def initialize(href:, class: nil, **options)
41
+ super()
42
+ @class = Array.wrap(binding.local_variable_get(:class))
43
+ @href = href
44
+ @options = options
45
+ end
46
+
47
+ def call
48
+ content_tag(:li) do
49
+ link_options = {class: link_classes}.merge(options)
50
+ content_tag(:a, href: href, **link_options) do
51
+ concat(icon) if icon?
52
+ concat(content_tag(:span, content, class: label_classes))
53
+ end
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ def label_classes
60
+ "ms-3" if icon?
61
+ end
62
+
63
+ def link_classes
64
+ self.class.classes + @class
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ class Sidebar
5
+ # Renders the navigation list for a sidebar.
6
+ #
7
+ # This component renders a +<ul>+ with navigation items. It can be used
8
+ # inside a {Flowbite::Sidebar} for a fixed-position sidebar, or standalone
9
+ # in any layout that needs sidebar-style navigation.
10
+ #
11
+ # @example Inside a Sidebar
12
+ # <%= render(Flowbite::Sidebar.new) do %>
13
+ # <%= render(Flowbite::Sidebar::Navigation.new) do |nav| %>
14
+ # <% nav.with_item do %>
15
+ # <%= render(Flowbite::Sidebar::Item.new(href: "/")) { "Home" } %>
16
+ # <% end %>
17
+ # <% end %>
18
+ # <% end %>
19
+ #
20
+ # @example Standalone
21
+ # <%= render(Flowbite::Sidebar::Navigation.new) do |nav| %>
22
+ # <% nav.with_item do %>
23
+ # <%= render(Flowbite::Sidebar::Item.new(href: "/")) { "Home" } %>
24
+ # <% end %>
25
+ # <% end %>
26
+ class Navigation < ViewComponent::Base
27
+ renders_many :items
28
+
29
+ class << self
30
+ def classes
31
+ ["space-y-2", "font-medium"]
32
+ end
33
+ end
34
+
35
+ # @param class [Array<String>] Additional CSS classes for the list element.
36
+ # @param options [Hash] Additional HTML options for the list element.
37
+ def initialize(class: nil, **options)
38
+ super()
39
+ @class = Array.wrap(binding.local_variable_get(:class))
40
+ @options = options
41
+ end
42
+
43
+ def call
44
+ content_tag(:ul, list_options) do
45
+ items.each do |item|
46
+ concat(item)
47
+ end
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def list_classes
54
+ self.class.classes + @class
55
+ end
56
+
57
+ def list_options
58
+ {class: list_classes}.merge(@options)
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ # Renders a fixed-position sidebar container.
5
+ #
6
+ # Use {Flowbite::Sidebar} as the outer shell and
7
+ # {Flowbite::Sidebar::Navigation} inside it to render the list of
8
+ # {Flowbite::Sidebar::Item}s.
9
+ #
10
+ # @example Usage
11
+ # <%= render(Flowbite::Sidebar.new) do %>
12
+ # <%= render(Flowbite::Sidebar::Navigation.new) do |nav| %>
13
+ # <% nav.with_item do %>
14
+ # <%= render(Flowbite::Sidebar::Item.new(href: "/dashboard")) { "Dashboard" } %>
15
+ # <% end %>
16
+ # <% end %>
17
+ # <% end %>
18
+ #
19
+ # @see https://flowbite.com/docs/components/sidebar/
20
+ # @lookbook_embed SidebarPreview
21
+ class Sidebar < ViewComponent::Base
22
+ class << self
23
+ def classes
24
+ [
25
+ "fixed", "top-0", "left-0", "z-40", "w-64", "h-screen",
26
+ "transition-transform", "-translate-x-full", "sm:translate-x-0"
27
+ ]
28
+ end
29
+ end
30
+
31
+ # @param class [Array<String>] Additional CSS classes for the sidebar
32
+ # container.
33
+ # @param options [Hash] Additional HTML options for the sidebar container.
34
+ def initialize(class: nil, **options)
35
+ super()
36
+ @class = Array.wrap(binding.local_variable_get(:class))
37
+ @options = options
38
+ end
39
+
40
+ def call
41
+ content_tag(:aside, aside_options) do
42
+ content_tag(:div, class: wrapper_classes) do
43
+ content
44
+ end
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def aside_classes
51
+ self.class.classes + @class
52
+ end
53
+
54
+ def aside_options
55
+ {class: aside_classes, "aria-label": "Sidebar"}.merge(@options)
56
+ end
57
+
58
+ def wrapper_classes
59
+ ["h-full", "px-3", "py-4", "overflow-y-auto", "bg-neutral-primary-soft"]
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,5 @@
1
+ <div class="<%= container_classes.join(" ") %>">
2
+ <svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
3
+ <path d="<%= svg_path %>"/>
4
+ </svg>
5
+ </div>
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ class Toast
5
+ # Renders an icon for a toast notification.
6
+ #
7
+ # @param style [Symbol] The color style of the icon (:default, :success, :danger, :warning).
8
+ class Icon < ViewComponent::Base
9
+ class << self
10
+ def classes(style: :default)
11
+ styles.fetch(style).fetch(:classes)
12
+ end
13
+
14
+ def svg_path(style: :default)
15
+ styles.fetch(style).fetch(:svg_path)
16
+ end
17
+
18
+ # rubocop:disable Layout/LineLength
19
+ def styles
20
+ {
21
+ default: {
22
+ classes: ["inline-flex", "items-center", "justify-center", "shrink-0", "w-8", "h-8", "text-blue-500", "bg-blue-100", "rounded-lg", "dark:bg-blue-800", "dark:text-blue-200"],
23
+ svg_path: "M15.147 15.085a7.159 7.159 0 0 1-6.189 3.307A6.713 6.713 0 0 1 3.1 15.444c-2.679-4.513.287-8.737.888-9.548A4.373 4.373 0 0 0 5 1.608c1.287.953 6.445 3.218 5.537 10.5 1.5-1.122 2.706-3.01 2.853-6.14 1.433 1.049 3.993 5.395 1.757 9.117Z"
24
+ },
25
+ success: {
26
+ classes: ["inline-flex", "items-center", "justify-center", "shrink-0", "w-8", "h-8", "text-green-500", "bg-green-100", "rounded-lg", "dark:bg-green-800", "dark:text-green-200"],
27
+ svg_path: "M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5Zm3.707 8.207-4 4a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L9 10.586l3.293-3.293a1 1 0 0 1 1.414 1.414Z"
28
+ },
29
+ danger: {
30
+ classes: ["inline-flex", "items-center", "justify-center", "shrink-0", "w-8", "h-8", "text-red-500", "bg-red-100", "rounded-lg", "dark:bg-red-800", "dark:text-red-200"],
31
+ svg_path: "M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5Zm3.707 11.793a1 1 0 1 1-1.414 1.414L10 11.414l-2.293 2.293a1 1 0 0 1-1.414-1.414L8.586 10 6.293 7.707a1 1 0 0 1 1.414-1.414L10 8.586l2.293-2.293a1 1 0 0 1 1.414 1.414L11.414 10l2.293 2.293Z"
32
+ },
33
+ warning: {
34
+ classes: ["inline-flex", "items-center", "justify-center", "shrink-0", "w-8", "h-8", "text-orange-500", "bg-orange-100", "rounded-lg", "dark:bg-orange-700", "dark:text-orange-200"],
35
+ svg_path: "M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM10 15a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm1-4a1 1 0 0 1-2 0V6a1 1 0 0 1 2 0v5Z"
36
+ }
37
+ }.freeze
38
+ end
39
+ # rubocop:enable Layout/LineLength
40
+ end
41
+
42
+ attr_reader :style
43
+
44
+ def initialize(style: :default)
45
+ @style = style
46
+ end
47
+
48
+ def container_classes
49
+ self.class.classes(style: style)
50
+ end
51
+
52
+ def svg_path
53
+ self.class.svg_path(style: style)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,40 @@
1
+ <%= tag.div(
2
+ class: container_classes.join(" "),
3
+ role: "alert",
4
+ **options,
5
+ ) do %>
6
+ <%= render Flowbite::Toast::Icon.new(style: style) %>
7
+
8
+ <div class="ms-3 text-sm font-normal"><%= message %></div>
9
+
10
+ <% if dismissible %>
11
+ <%# Styles from https://flowbite.com/docs/components/toast/#default-toast %>
12
+ <button
13
+ type="button"
14
+ class="
15
+ ms-auto flex items-center justify-center text-body
16
+ hover:text-heading bg-transparent box-border border
17
+ border-transparent hover:bg-neutral-secondary-medium focus:ring-4
18
+ focus:ring-neutral-tertiary font-medium leading-5 rounded text-sm
19
+ h-8 w-8 focus:outline-none
20
+ "
21
+ aria-label="Close"
22
+ >
23
+ <svg
24
+ class="w-3 h-3"
25
+ aria-hidden="true"
26
+ xmlns="http://www.w3.org/2000/svg"
27
+ fill="none"
28
+ viewBox="0 0 14 14"
29
+ >
30
+ <path
31
+ stroke="currentColor"
32
+ stroke-linecap="round"
33
+ stroke-linejoin="round"
34
+ stroke-width="2"
35
+ d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"
36
+ />
37
+ </svg>
38
+ </button>
39
+ <% end %>
40
+ <% end %>
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flowbite
4
+ # Renders a toast notification element.
5
+ #
6
+ # @example Usage
7
+ # <%= render(Flowbite::Toast.new(message: "Something has happened!")) %>
8
+ #
9
+ # @see https://flowbite.com/docs/components/toast/
10
+ # @lookbook_embed ToastPreview
11
+ class Toast < ViewComponent::Base
12
+ class << self
13
+ def classes
14
+ ["flex", "items-center", "w-full", "max-w-xs", "p-4", "text-body", "bg-neutral-primary-soft", "rounded-base", "shadow-xs", "border", "border-default"]
15
+ end
16
+ end
17
+
18
+ attr_reader :dismissible, :message, :options, :style
19
+
20
+ # @param class [Array<String>] Additional CSS classes for the toast container.
21
+ # @param dismissible [Boolean] Whether the toast can be dismissed (default: true).
22
+ # @param message [String] The message to display in the toast.
23
+ # @param options [Hash] Additional HTML options for the toast container.
24
+ # @param style [Symbol] The color style of the toast (:default, :success, :danger, :warning).
25
+ def initialize(message:, dismissible: true, style: :default, class: nil, **options)
26
+ @message = message
27
+ @style = style
28
+ @dismissible = dismissible
29
+ @class = Array.wrap(binding.local_variable_get(:class))
30
+ @options = options
31
+ end
32
+
33
+ def container_classes
34
+ self.class.classes + @class
35
+ end
36
+ end
37
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Flowbite
4
4
  module Components
5
- VERSION = "0.1.4"
5
+ VERSION = "0.3.0"
6
6
  end
7
7
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ # YARD plugin for documenting ViewComponent slots
4
+ #
5
+ # This plugin adds a @viewcomponent_slot tag that can be used to document
6
+ # slots defined with renders_one and renders_many in ViewComponent classes.
7
+ #
8
+ # Usage:
9
+ # # @viewcomponent_slot [Flowbite::Card::Title] title The title of the card
10
+ # renders_one :title
11
+ #
12
+ # # @viewcomponent_slot [Flowbite::Breadcrumb::Item] items The breadcrumb items
13
+ # renders_many :items
14
+ #
15
+ # The tag accepts:
16
+ # - Types (optional): The component class(es) that can be rendered in the slot
17
+ # - Name (required): The slot name (matching the symbol passed to renders_one/renders_many)
18
+ # - Description (optional): A description of what the slot is for
19
+
20
+ YARD::Tags::Library.define_tag(
21
+ "ViewComponent Slot",
22
+ :viewcomponent_slot,
23
+ :with_types_and_name
24
+ )