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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -4
- data/README.md +56 -8
- data/app/components/flowbite/breadcrumb/home_icon.rb +28 -0
- data/app/components/flowbite/breadcrumb/item/current.rb +35 -0
- data/app/components/flowbite/breadcrumb/item/first.rb +37 -0
- data/app/components/flowbite/breadcrumb/item.rb +50 -0
- data/app/components/flowbite/breadcrumb/separator_icon.rb +34 -0
- data/app/components/flowbite/breadcrumb.rb +54 -0
- data/app/components/flowbite/button/outline.rb +25 -10
- data/app/components/flowbite/button/pill.rb +26 -26
- data/app/components/flowbite/button.rb +39 -35
- data/app/components/flowbite/card/card.html.erb +7 -0
- data/app/components/flowbite/card/title.rb +39 -0
- data/app/components/flowbite/card.rb +71 -16
- data/app/components/flowbite/input/checkbox.rb +13 -11
- data/app/components/flowbite/input/date.rb +2 -2
- data/app/components/flowbite/input/date_time.rb +11 -0
- data/app/components/flowbite/input/email.rb +2 -2
- data/app/components/flowbite/input/file.rb +13 -11
- data/app/components/flowbite/input/hint.rb +16 -8
- data/app/components/flowbite/input/label.rb +15 -10
- data/app/components/flowbite/input/number.rb +2 -2
- data/app/components/flowbite/input/password.rb +2 -2
- data/app/components/flowbite/input/phone.rb +2 -2
- data/app/components/flowbite/input/radio_button.rb +13 -11
- data/app/components/flowbite/input/select.rb +7 -7
- data/app/components/flowbite/input/textarea.rb +13 -11
- data/app/components/flowbite/input/url.rb +2 -2
- data/app/components/flowbite/input/validation_error.rb +32 -2
- data/app/components/flowbite/input.rb +155 -0
- data/app/components/flowbite/input_field/checkbox.html.erb +2 -4
- data/app/components/flowbite/input_field/checkbox.rb +8 -4
- data/app/components/flowbite/input_field/date_time.rb +13 -0
- data/app/components/flowbite/input_field/input_field.html.erb +2 -2
- data/app/components/flowbite/input_field/radio_button.html.erb +2 -4
- data/app/components/flowbite/input_field/radio_button.rb +19 -21
- data/app/components/flowbite/input_field.rb +117 -49
- data/app/components/flowbite/link.rb +43 -0
- data/app/components/flowbite/styles.rb +34 -0
- data/app/components/flowbite/toast/icon.html.erb +5 -0
- data/app/components/flowbite/toast/icon.rb +57 -0
- data/app/components/flowbite/toast/toast.html.erb +40 -0
- data/app/components/flowbite/toast.rb +37 -0
- data/lib/flowbite/components/version.rb +1 -1
- data/lib/yard/flowbite_viewcomponent.rb +24 -0
- metadata +37 -5
- data/app/components/flowbite/input/field.rb +0 -117
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Flowbite
|
|
4
|
-
|
|
5
|
-
class Textarea <
|
|
4
|
+
class Input
|
|
5
|
+
class Textarea < Input
|
|
6
6
|
class << self
|
|
7
7
|
# rubocop:disable Layout/LineLength
|
|
8
8
|
def styles
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
default:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
Flowbite::Styles.from_hash(
|
|
10
|
+
{
|
|
11
|
+
default: {
|
|
12
|
+
default: ["block", "w-full", "text-heading", "bg-neutral-secondary-medium", "rounded-base", "border", "border-default-medium", "focus:ring-brand", "focus:border-brand", "shadow-xs", "placeholder:text-body"],
|
|
13
|
+
disabled: ["block", "w-full", "bg-neutral-secondary-medium", "rounded-base", "border", "border-default-medium", "text-fg-disabled", "cursor-not-allowed", "shadow-xs", "placeholder:text-fg-disabled"],
|
|
14
|
+
error: ["block", "w-full", "bg-danger-soft", "border", "border-danger-subtle", "text-fg-danger-strong", "placeholder:text-fg-danger-strong", "rounded-base", "focus:ring-danger", "focus:border-danger", "shadow-xs"]
|
|
15
|
+
}
|
|
16
|
+
}.freeze
|
|
17
|
+
)
|
|
16
18
|
end
|
|
17
|
-
# rubocop:enable Layout/LineLength
|
|
18
19
|
end
|
|
20
|
+
# rubocop:enable Layout/LineLength
|
|
19
21
|
|
|
20
22
|
# Returns the HTML to use for the actual input field element.
|
|
21
23
|
def call
|
|
@@ -30,7 +32,7 @@ module Flowbite
|
|
|
30
32
|
|
|
31
33
|
# Returns the CSS classes to apply to the input field
|
|
32
34
|
def classes
|
|
33
|
-
self.class.classes(size: size, state: state)
|
|
35
|
+
self.class.classes(size: size, state: state) + @class
|
|
34
36
|
end
|
|
35
37
|
|
|
36
38
|
# Returns the name of the method used to generate HTML for the input field
|
|
@@ -1,10 +1,40 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Flowbite
|
|
4
|
-
|
|
4
|
+
class Input
|
|
5
5
|
class ValidationError < ViewComponent::Base
|
|
6
|
+
class << self
|
|
7
|
+
def classes(state: :default, style: :default)
|
|
8
|
+
style = styles.fetch(style)
|
|
9
|
+
style.fetch(state)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# rubocop:disable Layout/LineLength
|
|
13
|
+
def styles
|
|
14
|
+
Flowbite::Styles.from_hash(
|
|
15
|
+
{
|
|
16
|
+
default: {
|
|
17
|
+
default: ["mt-2", "text-sm", "text-red-600", "dark:text-red-500"]
|
|
18
|
+
}
|
|
19
|
+
}.freeze
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
# rubocop:enable Layout/LineLength
|
|
23
|
+
end
|
|
24
|
+
|
|
6
25
|
def call
|
|
7
|
-
tag.p(content, class:
|
|
26
|
+
tag.p(content, class: classes)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def initialize(class: nil)
|
|
30
|
+
@class = Array.wrap(binding.local_variable_get(:class))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
protected
|
|
34
|
+
|
|
35
|
+
# Returns the CSS classes to apply to the validation error
|
|
36
|
+
def classes
|
|
37
|
+
self.class.classes + @class
|
|
8
38
|
end
|
|
9
39
|
end
|
|
10
40
|
end
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Flowbite
|
|
4
|
+
# The individual input form element used in forms - without labels, error
|
|
5
|
+
# messages, hints, etc.
|
|
6
|
+
#
|
|
7
|
+
# Use this when you want to render an input field on its own without any
|
|
8
|
+
# surrounding elements, i.e. as a building block in more complex input
|
|
9
|
+
# components. To render a complete input field with labels and error messages,
|
|
10
|
+
# use {Flowbite::InputField} instead.
|
|
11
|
+
#
|
|
12
|
+
# By default this renders a text input field. To render other types of input
|
|
13
|
+
# fields, use one of the subclasses, such as {Flowbite::Input::Checkbox} or
|
|
14
|
+
# {Flowbite::Input::Textarea}.
|
|
15
|
+
#
|
|
16
|
+
# @example Usage
|
|
17
|
+
# <%= render(Flowbite::Input::Email.new(attribute: :email, form: form)) %>
|
|
18
|
+
#
|
|
19
|
+
# @lookbook_embed InputPreview
|
|
20
|
+
class Input < ViewComponent::Base
|
|
21
|
+
SIZES = {
|
|
22
|
+
sm: ["px-2.5", "py-2", "text-sm"],
|
|
23
|
+
default: ["px-3", "py-2.5", "text-sm"],
|
|
24
|
+
lg: ["px-3.5", "py-3", "text-base"]
|
|
25
|
+
}.freeze
|
|
26
|
+
|
|
27
|
+
STATES = [
|
|
28
|
+
DEFAULT = :default,
|
|
29
|
+
DISABLED = :disabled,
|
|
30
|
+
ERROR = :error
|
|
31
|
+
].freeze
|
|
32
|
+
|
|
33
|
+
attr_reader :options, :size, :style
|
|
34
|
+
|
|
35
|
+
class << self
|
|
36
|
+
# @return [Array<String>] The CSS classes to apply to the input field
|
|
37
|
+
# given the specified +size+, +state+, and +style+.
|
|
38
|
+
def classes(size: :default, state: :default, style: :default)
|
|
39
|
+
style = styles.fetch(style)
|
|
40
|
+
state_classes = style.fetch(state)
|
|
41
|
+
state_classes + sizes.fetch(size)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Returns the sizes this Input supports.
|
|
45
|
+
#
|
|
46
|
+
# This is effectively the {SIZES} constant, but provided as a method to
|
|
47
|
+
# return the constant from the current class, not the superclass.
|
|
48
|
+
#
|
|
49
|
+
# @return [Hash] A hash mapping size names to their corresponding CSS
|
|
50
|
+
# classes.
|
|
51
|
+
def sizes
|
|
52
|
+
const_get(:SIZES)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @return [Flowbite::Styles] The available styles for this input field.
|
|
56
|
+
def styles
|
|
57
|
+
# rubocop:disable Layout/LineLength
|
|
58
|
+
Flowbite::Styles.from_hash(
|
|
59
|
+
{
|
|
60
|
+
default: {
|
|
61
|
+
default: ["bg-neutral-secondary-medium", "border", "border-default-medium", "text-heading", "rounded-base", "focus:ring-brand", "focus:border-brand", "block", "w-full", "shadow-xs", "placeholder:text-body"],
|
|
62
|
+
disabled: ["bg-neutral-secondary-medium", "border", "border-default-medium", "text-fg-disabled", "rounded-base", "focus:ring-brand", "focus:border-brand", "block", "w-full", "shadow-xs", "cursor-not-allowed", "placeholder:text-fg-disabled"],
|
|
63
|
+
error: ["bg-danger-soft", "border", "border-danger-subtle", "text-fg-danger-strong", "rounded-base", "focus:ring-danger", "focus:border-danger", "block", "w-full", "shadow-xs", "placeholder:text-fg-danger-strong"]
|
|
64
|
+
}
|
|
65
|
+
}.freeze
|
|
66
|
+
)
|
|
67
|
+
# rubocop:enable Layout/LineLength
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# @param attribute [Symbol] The attribute on the form's object this input
|
|
72
|
+
# field is for.
|
|
73
|
+
#
|
|
74
|
+
# @param form [ActionView::Helpers::FormBuilder] The form builder this
|
|
75
|
+
# input field is part of.
|
|
76
|
+
#
|
|
77
|
+
# @param class [String, Array<String>] Additional CSS classes to apply to
|
|
78
|
+
# the input field.
|
|
79
|
+
#
|
|
80
|
+
# @param disabled [Boolean] Whether the input field should be disabled.
|
|
81
|
+
#
|
|
82
|
+
# @param options [Hash] Additional HTML attributes to pass to the input
|
|
83
|
+
# field. For example, you can use this to set placeholder text by
|
|
84
|
+
# passing +options: {placeholder: "Enter your name"}+
|
|
85
|
+
#
|
|
86
|
+
# @param size [Symbol] The size of the input field. Can be one of +:sm+,
|
|
87
|
+
# +:default+, or +:lg+.
|
|
88
|
+
def initialize(attribute:, form:, class: nil, disabled: false, options: {}, size: :default)
|
|
89
|
+
@attribute = attribute
|
|
90
|
+
@class = Array.wrap(binding.local_variable_get(:class))
|
|
91
|
+
@disabled = disabled
|
|
92
|
+
@form = form
|
|
93
|
+
@options = options || {}
|
|
94
|
+
@object = form.object
|
|
95
|
+
@size = size
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Returns the HTML to use for the actual input field element.
|
|
99
|
+
def call
|
|
100
|
+
@form.send(
|
|
101
|
+
input_field_type,
|
|
102
|
+
@attribute,
|
|
103
|
+
**input_options
|
|
104
|
+
)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Returns the CSS classes to apply to the input field
|
|
108
|
+
#
|
|
109
|
+
# @return [Array<String>] An array of CSS classes.
|
|
110
|
+
def classes
|
|
111
|
+
self.class.classes(size: size, state: state) + @class
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Returns the name of the method used to generate HTML for the input field
|
|
115
|
+
#
|
|
116
|
+
# @return [Symbol] The form helper method name to call on +form+.
|
|
117
|
+
def input_field_type
|
|
118
|
+
:text_field
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
protected
|
|
122
|
+
|
|
123
|
+
# @return [Boolean] Returns true if the field is disabled
|
|
124
|
+
def disabled?
|
|
125
|
+
!!@disabled
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Returns true if the object has errors. Returns false if there is no
|
|
129
|
+
# object.
|
|
130
|
+
#
|
|
131
|
+
# @return [Boolean] true if there are errors, false otherwise.
|
|
132
|
+
def errors?
|
|
133
|
+
return false unless @object
|
|
134
|
+
|
|
135
|
+
@object.errors.include?(@attribute.intern)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
private
|
|
139
|
+
|
|
140
|
+
# Returns the options argument for the input field
|
|
141
|
+
def input_options
|
|
142
|
+
{
|
|
143
|
+
class: classes,
|
|
144
|
+
disabled: disabled?
|
|
145
|
+
}.merge(options)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def state
|
|
149
|
+
return DISABLED if disabled?
|
|
150
|
+
return ERROR if errors?
|
|
151
|
+
|
|
152
|
+
DEFAULT
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
@@ -5,6 +5,10 @@ module Flowbite
|
|
|
5
5
|
class Checkbox < InputField
|
|
6
6
|
protected
|
|
7
7
|
|
|
8
|
+
def default_container_classes
|
|
9
|
+
["flex"]
|
|
10
|
+
end
|
|
11
|
+
|
|
8
12
|
def default_hint_options
|
|
9
13
|
return {} unless @hint
|
|
10
14
|
|
|
@@ -29,9 +33,9 @@ module Flowbite
|
|
|
29
33
|
|
|
30
34
|
def hint_classes
|
|
31
35
|
if disabled?
|
|
32
|
-
"text-xs font-normal text-
|
|
36
|
+
"text-xs font-normal text-fg-disabled"
|
|
33
37
|
else
|
|
34
|
-
"text-xs font-normal text-
|
|
38
|
+
"text-xs font-normal text-body"
|
|
35
39
|
end
|
|
36
40
|
end
|
|
37
41
|
|
|
@@ -44,9 +48,9 @@ module Flowbite
|
|
|
44
48
|
|
|
45
49
|
def label_classes
|
|
46
50
|
if disabled?
|
|
47
|
-
"font-medium text-
|
|
51
|
+
"font-medium text-fg-disabled"
|
|
48
52
|
else
|
|
49
|
-
"font-medium text-
|
|
53
|
+
"font-medium text-heading"
|
|
50
54
|
end
|
|
51
55
|
end
|
|
52
56
|
end
|
|
@@ -3,13 +3,17 @@
|
|
|
3
3
|
module Flowbite
|
|
4
4
|
class InputField
|
|
5
5
|
class RadioButton < InputField
|
|
6
|
-
def initialize(attribute:, form:, value:, disabled: false, hint: nil, input: {}, label: {})
|
|
7
|
-
super(attribute: attribute, form: form, disabled: disabled, hint: hint, input: input, label: label)
|
|
6
|
+
def initialize(attribute:, form:, value:, class: nil, disabled: false, hint: nil, input: {}, label: {}, options: {})
|
|
7
|
+
super(attribute: attribute, class: binding.local_variable_get(:class), form: form, disabled: disabled, hint: hint, input: input, label: label, options: options)
|
|
8
8
|
@value = value
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
protected
|
|
12
12
|
|
|
13
|
+
def default_container_classes
|
|
14
|
+
["flex"]
|
|
15
|
+
end
|
|
16
|
+
|
|
13
17
|
def default_input
|
|
14
18
|
args = {
|
|
15
19
|
attribute: @attribute,
|
|
@@ -22,6 +26,15 @@ module Flowbite
|
|
|
22
26
|
input_component.new(**args)
|
|
23
27
|
end
|
|
24
28
|
|
|
29
|
+
def default_hint_options
|
|
30
|
+
return {} unless @hint
|
|
31
|
+
|
|
32
|
+
{
|
|
33
|
+
class: hint_classes,
|
|
34
|
+
id: id_for_hint_element
|
|
35
|
+
}.merge(@hint[:options] || {})
|
|
36
|
+
end
|
|
37
|
+
|
|
25
38
|
# Returns options for the default label element. This includes CSS classes
|
|
26
39
|
# since they are specific to RadioButton labels (and Checkbox ones).
|
|
27
40
|
def default_label_options
|
|
@@ -33,21 +46,6 @@ module Flowbite
|
|
|
33
46
|
})
|
|
34
47
|
end
|
|
35
48
|
|
|
36
|
-
# Returns the HTML to use for the hint element if any
|
|
37
|
-
def hint
|
|
38
|
-
return unless hint?
|
|
39
|
-
|
|
40
|
-
component = Flowbite::Input::Hint.new(
|
|
41
|
-
attribute: @attribute,
|
|
42
|
-
form: @form,
|
|
43
|
-
options: {
|
|
44
|
-
class: hint_classes,
|
|
45
|
-
id: id_for_hint_element
|
|
46
|
-
}
|
|
47
|
-
).with_content(@hint)
|
|
48
|
-
render(component)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
49
|
def input_component
|
|
52
50
|
::Flowbite::Input::RadioButton
|
|
53
51
|
end
|
|
@@ -56,9 +54,9 @@ module Flowbite
|
|
|
56
54
|
|
|
57
55
|
def hint_classes
|
|
58
56
|
if disabled?
|
|
59
|
-
"text-xs font-normal text-
|
|
57
|
+
"text-xs font-normal text-fg-disabled"
|
|
60
58
|
else
|
|
61
|
-
"text-xs font-normal text-
|
|
59
|
+
"text-xs font-normal text-body"
|
|
62
60
|
end
|
|
63
61
|
end
|
|
64
62
|
|
|
@@ -76,9 +74,9 @@ module Flowbite
|
|
|
76
74
|
|
|
77
75
|
def label_classes
|
|
78
76
|
if disabled?
|
|
79
|
-
"font-medium text-
|
|
77
|
+
"font-medium text-fg-disabled"
|
|
80
78
|
else
|
|
81
|
-
"font-medium text-
|
|
79
|
+
"font-medium text-heading"
|
|
82
80
|
end
|
|
83
81
|
end
|
|
84
82
|
end
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Flowbite
|
|
4
|
-
# A form element for
|
|
5
|
-
# messages, helper text and whatever else is needed for a user
|
|
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,81 +13,143 @@ 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
|
|
17
|
-
#
|
|
16
|
+
# different input types, like {Flowbite::InputField::Text},
|
|
17
|
+
# {Flowbite::InputField::Email}, etc.
|
|
18
18
|
#
|
|
19
|
-
#
|
|
19
|
+
# To render an input without labels or error messages etc, see
|
|
20
|
+
# {Flowbite::Input} instead and one of its subclasses.
|
|
20
21
|
#
|
|
21
|
-
# @
|
|
22
|
-
#
|
|
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
|
-
# @
|
|
25
|
-
#
|
|
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
|
-
#
|
|
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
|
-
# @
|
|
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
|
|
67
68
|
renders_one :label
|
|
68
69
|
|
|
69
70
|
# Returns the errors for attribute
|
|
71
|
+
#
|
|
72
|
+
# @return [Array<String>] An array of error messages for the attribute.
|
|
70
73
|
def errors
|
|
74
|
+
return [] unless @object
|
|
75
|
+
|
|
71
76
|
@object.errors[@attribute] || []
|
|
72
77
|
end
|
|
73
78
|
|
|
74
|
-
|
|
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+.
|
|
118
|
+
def initialize(attribute:, form:, class: nil, disabled: false, hint: nil, input: {}, label: {}, options: {}, size: :default)
|
|
75
119
|
@attribute = attribute
|
|
120
|
+
@class = Array.wrap(binding.local_variable_get(:class))
|
|
76
121
|
@disabled = disabled
|
|
77
122
|
@form = form
|
|
78
123
|
@hint = hint
|
|
79
124
|
@input = input
|
|
80
125
|
@label = label
|
|
81
126
|
@object = form.object
|
|
127
|
+
@options = options || {}
|
|
82
128
|
@size = size
|
|
83
129
|
end
|
|
84
130
|
|
|
85
131
|
def input_component
|
|
86
|
-
::Flowbite::Input
|
|
132
|
+
::Flowbite::Input
|
|
87
133
|
end
|
|
88
134
|
|
|
89
135
|
protected
|
|
90
136
|
|
|
137
|
+
def classes
|
|
138
|
+
if @options[:class]
|
|
139
|
+
Array.wrap(@options[:class])
|
|
140
|
+
else
|
|
141
|
+
[default_container_classes, @class].flatten.compact
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def container_options
|
|
146
|
+
@options.merge({class: classes.join(" ")})
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def default_container_classes
|
|
150
|
+
[]
|
|
151
|
+
end
|
|
152
|
+
|
|
91
153
|
# Returns the HTML to use for the hint element if any
|
|
92
154
|
def default_hint
|
|
93
155
|
return unless hint?
|
|
@@ -171,7 +233,13 @@ module Flowbite
|
|
|
171
233
|
end
|
|
172
234
|
|
|
173
235
|
def id_for_hint_element
|
|
174
|
-
|
|
236
|
+
[
|
|
237
|
+
@form.object_name,
|
|
238
|
+
@attribute,
|
|
239
|
+
"hint"
|
|
240
|
+
]
|
|
241
|
+
.compact_blank
|
|
242
|
+
.join("_")
|
|
175
243
|
end
|
|
176
244
|
|
|
177
245
|
# @return [Hash] The keyword arguments for the input component.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Flowbite
|
|
4
|
+
# The link component can be used to set hyperlinks from one page to another or
|
|
5
|
+
# to an external website when clicking on an inline text item, button, or card
|
|
6
|
+
#
|
|
7
|
+
# Use this component to add default styles to an inline link element.
|
|
8
|
+
#
|
|
9
|
+
# @lookbook_embed LinkPreview
|
|
10
|
+
class Link < ViewComponent::Base
|
|
11
|
+
attr_reader :href, :options
|
|
12
|
+
|
|
13
|
+
class << self
|
|
14
|
+
def classes
|
|
15
|
+
["font-medium", "text-fg-brand", "hover:underline"]
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Initialize the Link component.
|
|
20
|
+
#
|
|
21
|
+
# @param href What to link to. This can be a String or anything else that
|
|
22
|
+
# `link_to` supports. See `ActionView::Helpers::UrlHelper#link_to` for more
|
|
23
|
+
# details.
|
|
24
|
+
#
|
|
25
|
+
# @param options [Hash] Additional HTML options for the link element
|
|
26
|
+
def initialize(href:, class: nil, **options)
|
|
27
|
+
super()
|
|
28
|
+
@class = Array.wrap(binding.local_variable_get(:class))
|
|
29
|
+
@href = href
|
|
30
|
+
@options = options
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def call
|
|
34
|
+
link_to(content, href, {class: classes}.merge(options))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def classes
|
|
40
|
+
self.class.classes + @class
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|