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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1 -0
- data/README.md +34 -7
- data/app/assets/tailwind/flowbite_components/engine.css +2 -0
- data/app/components/flowbite/button/outline.rb +22 -0
- data/app/components/flowbite/button/pill.rb +40 -0
- data/app/components/flowbite/button.rb +92 -0
- data/app/components/flowbite/card.rb +43 -0
- data/app/components/flowbite/input/checkbox.rb +37 -0
- data/app/components/flowbite/input/date.rb +11 -0
- data/app/components/flowbite/input/email.rb +12 -0
- data/app/components/flowbite/input/field.rb +117 -0
- data/app/components/flowbite/input/file.rb +30 -0
- data/app/components/flowbite/input/hint.rb +57 -0
- data/app/components/flowbite/input/label.rb +82 -0
- data/app/components/flowbite/input/number.rb +11 -0
- data/app/components/flowbite/input/password.rb +11 -0
- data/app/components/flowbite/input/phone.rb +11 -0
- data/app/components/flowbite/input/radio_button.rb +50 -0
- data/app/components/flowbite/input/select.rb +49 -0
- data/app/components/flowbite/input/textarea.rb +42 -0
- data/app/components/flowbite/input/url.rb +12 -0
- data/app/components/flowbite/input/validation_error.rb +11 -0
- data/app/components/flowbite/input_field/checkbox.html.erb +14 -0
- data/app/components/flowbite/input_field/checkbox.rb +49 -0
- data/app/components/flowbite/input_field/date.rb +13 -0
- data/app/components/flowbite/input_field/email.rb +13 -0
- data/app/components/flowbite/input_field/file.rb +13 -0
- data/app/components/flowbite/input_field/input_field.html.erb +8 -0
- data/app/components/flowbite/input_field/number.rb +13 -0
- data/app/components/flowbite/input_field/password.rb +13 -0
- data/app/components/flowbite/input_field/phone.rb +13 -0
- data/app/components/flowbite/input_field/radio_button.html.erb +14 -0
- data/app/components/flowbite/input_field/radio_button.rb +88 -0
- data/app/components/flowbite/input_field/select.rb +31 -0
- data/app/components/flowbite/input_field/text.rb +8 -0
- data/app/components/flowbite/input_field/textarea.rb +13 -0
- data/app/components/flowbite/input_field/url.rb +13 -0
- data/app/components/flowbite/input_field.rb +187 -0
- data/app/components/flowbite/style.rb +13 -0
- data/lib/flowbite/{view_components → components}/engine.rb +2 -2
- data/lib/flowbite/{view_components → components}/version.rb +2 -2
- data/lib/flowbite/{view_components.rb → components.rb} +3 -3
- metadata +49 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: afc7f639fa9f28b2310d7f68cd3d8939e3eaa526ba80ee028c471664597e4581
|
4
|
+
data.tar.gz: 1b4e73f0bd471b9b3d36db8aba2e614e28f5573cbf7fd214de360a985767eade
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d56824ba5b7d0c13bca6b31e4dac90a1859ec35c3c50478b90a4f67aae2cd7e7efcfb53dc29ddfcae9f4839695610ea5602e0f29b2ddd53c64a00b34562806d
|
7
|
+
data.tar.gz: efe21d27318e44196ecd0024663a143ba577ab8b2ca0a2b9e085263d4be3d7f472c22c68c5442d802c58717306a575d320325c4d9d8bb3d5f8b5e48fb444c992
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
# Flowbite
|
1
|
+
# Flowbite Components
|
2
2
|
|
3
|
-
[](https://rubygems.org/gems/flowbite-components)
|
4
|
+
[](https://github.com/substancelab/flowbite-components/actions)
|
5
5
|
|
6
6
|
Unofficial, open source implementation of [Flowbite](https://flowbite.com/) components for Rails applications, built using [ViewComponent](https://viewcomponent.org/).
|
7
7
|
|
8
|
-
Flowbite
|
8
|
+
Flowbite Components provides a comprehensive library of UI components following the Flowbite design system, implemented as Rails ViewComponents with full Tailwind CSS integration and dark mode support.
|
9
9
|
|
10
10
|
## Features
|
11
11
|
|
@@ -22,7 +22,7 @@ Flowbite ViewComponents provides a comprehensive library of UI components follow
|
|
22
22
|
Add the gem to your application's Gemfile:
|
23
23
|
|
24
24
|
```ruby
|
25
|
-
gem 'flowbite-
|
25
|
+
gem 'flowbite-components'
|
26
26
|
```
|
27
27
|
|
28
28
|
Then execute:
|
@@ -52,7 +52,7 @@ Add Flowbite to your Tailwind CSS configuration. In your `app/assets/tailwind/ap
|
|
52
52
|
```css
|
53
53
|
@import "flowbite/src/themes/default";
|
54
54
|
@plugin "flowbite/plugin";
|
55
|
-
@import "../builds/tailwind/
|
55
|
+
@import "../builds/tailwind/flowbite_components";
|
56
56
|
```
|
57
57
|
|
58
58
|
## Usage examples
|
@@ -147,6 +147,33 @@ Add Flowbite to your Tailwind CSS configuration. In your `app/assets/tailwind/ap
|
|
147
147
|
) %>
|
148
148
|
```
|
149
149
|
|
150
|
+
## How to customize components
|
151
|
+
|
152
|
+
### Add specific CSS classes
|
153
|
+
|
154
|
+
A common use case for customizing a component is to add more CSS classes when
|
155
|
+
rendering it, fx to change the size or spacing. flowbite-components is optimized
|
156
|
+
for this case and all you need to do is specify the extra classes:
|
157
|
+
|
158
|
+
```erb
|
159
|
+
<%= render(Flowbite::Card.new(class: "w-full my-8")) { "Content" } %>
|
160
|
+
```
|
161
|
+
renders
|
162
|
+
```html
|
163
|
+
<div class="... all the usual classes... w-full my-8">
|
164
|
+
```
|
165
|
+
|
166
|
+
If you want to fully replace the existing classes, you can pass an entirely new
|
167
|
+
`class` attribute via options:
|
168
|
+
|
169
|
+
```erb
|
170
|
+
<%= render(Flowbite::Card.new(options: {class: "w-full my-8"})) { "Content" } %>
|
171
|
+
```
|
172
|
+
renders
|
173
|
+
```html
|
174
|
+
<div class="w-full my-8">
|
175
|
+
```
|
176
|
+
|
150
177
|
## Available Components
|
151
178
|
|
152
179
|
### Form Components
|
@@ -223,7 +250,7 @@ This library includes Lookbook previews for all components. To view them:
|
|
223
250
|
|
224
251
|
## Contributing
|
225
252
|
|
226
|
-
Bug reports and pull requests are welcome on GitHub at [https://github.com/substancelab/flowbite-
|
253
|
+
Bug reports and pull requests are welcome on GitHub at [https://github.com/substancelab/flowbite-components](https://github.com/substancelab/flowbite-components).
|
227
254
|
|
228
255
|
### Development Guidelines
|
229
256
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Flowbite
|
4
|
+
class Button
|
5
|
+
class Outline < Flowbite::Button
|
6
|
+
class << self
|
7
|
+
# rubocop:disable Layout/LineLength
|
8
|
+
def styles
|
9
|
+
{
|
10
|
+
default: Flowbite::Style.new(
|
11
|
+
default: ["text-blue-700", "hover:text-white", "border", "border-blue-700", "hover:bg-blue-800", "focus:ring-4", "focus:outline-none", "focus:ring-blue-300", "font-medium", "rounded-lg", "text-center", "me-2", "mb-2", "dark:border-blue-500", "dark:text-blue-500", "dark:hover:text-white", "dark:hover:bg-blue-500", "dark:focus:ring-blue-800"]
|
12
|
+
),
|
13
|
+
green: Flowbite::Style.new(
|
14
|
+
default: ["text-green-700", "hover:text-white", "border", "border-green-700", "hover:bg-green-800", "focus:ring-4", "focus:outline-none", "focus:ring-green-300", "font-medium", "rounded-lg", "text-center", "me-2", "mb-2", "dark:border-green-500", "dark:text-green-500", "dark:hover:text-white", "dark:hover:bg-green-600", "dark:focus:ring-green-800"]
|
15
|
+
)
|
16
|
+
}
|
17
|
+
end
|
18
|
+
# rubocop:enable Layout/LineLength
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Flowbite
|
4
|
+
class Button
|
5
|
+
class Pill < Flowbite::Button
|
6
|
+
class << self
|
7
|
+
# rubocop:disable Layout/LineLength, Metrics/MethodLength
|
8
|
+
def styles
|
9
|
+
{
|
10
|
+
alternative: Flowbite::Style.new(
|
11
|
+
default: ["text-sm", "font-medium", "text-gray-900", "focus:outline-none", "bg-white", "rounded-full", "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"]
|
12
|
+
),
|
13
|
+
dark: Flowbite::Style.new(
|
14
|
+
default: ["text-white", "bg-gray-800", "hover:bg-gray-900", "focus:outline-none", "focus:ring-4", "focus:ring-gray-300", "font-medium", "rounded-full", "dark:bg-gray-800", "dark:hover:bg-gray-700", "dark:focus:ring-gray-700", "dark:border-gray-700"]
|
15
|
+
),
|
16
|
+
default: Flowbite::Style.new(
|
17
|
+
default: ["text-white", "bg-blue-700", "hover:bg-blue-800", "focus:outline-none", "focus:ring-4", "focus:ring-blue-300", "font-medium", "rounded-full", "text-center", "dark:bg-blue-600", "dark:hover:bg-blue-700", "dark:focus:ring-blue-800"]
|
18
|
+
),
|
19
|
+
green: Flowbite::Style.new(
|
20
|
+
default: ["text-white", "bg-green-700", "hover:bg-green-800", "focus:outline-none", "focus:ring-4", "focus:ring-green-300", "font-medium", "rounded-full", "text-center", "dark:bg-green-600", "dark:hover:bg-green-700", "dark:focus:ring-green-800"]
|
21
|
+
),
|
22
|
+
light: Flowbite::Style.new(
|
23
|
+
default: ["text-gray-900", "bg-white", "border", "border-gray-300", "focus:outline-none", "hover:bg-gray-100", "focus:ring-4", "focus:ring-gray-100", "font-medium", "rounded-full", "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"]
|
24
|
+
),
|
25
|
+
purple: Flowbite::Style.new(
|
26
|
+
default: ["text-white", "bg-purple-700", "hover:bg-purple-800", "focus:outline-none", "focus:ring-4", "focus:ring-purple-300", "font-medium", "rounded-full", "text-center", "dark:bg-purple-600", "dark:hover:bg-purple-700", "dark:focus:ring-purple-900"]
|
27
|
+
),
|
28
|
+
red: Flowbite::Style.new(
|
29
|
+
default: ["text-white", "bg-red-700", "hover:bg-red-800", "focus:outline-none", "focus:ring-4", "focus:ring-red-300", "font-medium", "rounded-full", "text-center", "dark:bg-red-600", "dark:hover:bg-red-700", "dark:focus:ring-red-900"]
|
30
|
+
),
|
31
|
+
yellow: Flowbite::Style.new(
|
32
|
+
default: ["text-white", "bg-yellow-400", "hover:bg-yellow-500", "focus:outline-none", "focus:ring-4", "focus:ring-yellow-300", "font-medium", "rounded-full", "text-center", "dark:focus:ring-yellow-900"]
|
33
|
+
)
|
34
|
+
}
|
35
|
+
end
|
36
|
+
# rubocop:enable Layout/LineLength, Metrics/MethodLength
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
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.
|
9
|
+
#
|
10
|
+
# All other parameters are optional and are passed directly to the button tag
|
11
|
+
# as HTML attributes.
|
12
|
+
class Button < ViewComponent::Base
|
13
|
+
SIZES = {
|
14
|
+
xs: ["text-xs", "px-3", "py-2"],
|
15
|
+
sm: ["text-sm", "px-3", "py-2"],
|
16
|
+
default: ["text-sm", "px-5", "py-2.5"],
|
17
|
+
lg: ["text-base", "px-5", "py-3"],
|
18
|
+
xl: ["text-base", "px-6", "py-3.5"]
|
19
|
+
}.freeze
|
20
|
+
|
21
|
+
class << self
|
22
|
+
def classes(size: :default, state: :default, style: :default)
|
23
|
+
style = styles.fetch(style)
|
24
|
+
classes = style.fetch(state)
|
25
|
+
classes + sizes.fetch(size)
|
26
|
+
end
|
27
|
+
|
28
|
+
def sizes
|
29
|
+
SIZES
|
30
|
+
end
|
31
|
+
|
32
|
+
# rubocop:disable Layout/LineLength
|
33
|
+
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
|
60
|
+
end
|
61
|
+
# rubocop:enable Layout/LineLength
|
62
|
+
end
|
63
|
+
|
64
|
+
attr_reader :button_attributes, :size, :style
|
65
|
+
|
66
|
+
def initialize(size: :default, style: :default, **button_attributes)
|
67
|
+
@size = size
|
68
|
+
@style = style
|
69
|
+
@button_attributes = button_attributes
|
70
|
+
end
|
71
|
+
|
72
|
+
def call
|
73
|
+
content_tag(
|
74
|
+
:button,
|
75
|
+
content,
|
76
|
+
**options
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def classes
|
83
|
+
self.class.classes(size: size, state: :default, style: style)
|
84
|
+
end
|
85
|
+
|
86
|
+
def options
|
87
|
+
{
|
88
|
+
class: classes
|
89
|
+
}.merge(button_attributes)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Flowbite
|
2
|
+
# Renders a card element.
|
3
|
+
#
|
4
|
+
# See https://flowbite.com/docs/components/cards/
|
5
|
+
class Card < 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
|
+
{
|
15
|
+
default: Flowbite::Style.new(
|
16
|
+
default: ["p-6", "bg-white", "border", "border-gray-200", "rounded-lg", "shadow-sm", "dark:bg-gray-800", "dark:border-gray-700"]
|
17
|
+
)
|
18
|
+
}.freeze
|
19
|
+
end
|
20
|
+
# rubocop:enable Layout/LineLength
|
21
|
+
end
|
22
|
+
|
23
|
+
def call
|
24
|
+
card_options = {}
|
25
|
+
card_options[:class] = self.class.classes + @class
|
26
|
+
|
27
|
+
content_tag(:div, card_options.merge(@options)) do
|
28
|
+
concat(content_tag(:div, content, class: "font-normal text-gray-700 dark:text-gray-400"))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# @param class [Array<String>] Additional CSS classes for the card
|
33
|
+
# container.
|
34
|
+
#
|
35
|
+
# @param options [Hash] Additional HTML options for the card container
|
36
|
+
# (e.g., custom classes, data attributes). These options are merged into
|
37
|
+
# the card's root element.
|
38
|
+
def initialize(class: [], options: {})
|
39
|
+
@class = Array(binding.local_variable_get(:class)) || []
|
40
|
+
@options = options || {}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Flowbite
|
4
|
+
module Input
|
5
|
+
# The checkbox component can be used to receive one or more selected options
|
6
|
+
# from the user in the form of a square box available in multiple styles,
|
7
|
+
# sizes, colors, and variants coded with the utility classes from Tailwind
|
8
|
+
# CSS and with support for dark mode.
|
9
|
+
#
|
10
|
+
# https://flowbite.com/docs/forms/checkbox/
|
11
|
+
class Checkbox < Field
|
12
|
+
class << self
|
13
|
+
# Checkboxes only have their default size.
|
14
|
+
def sizes
|
15
|
+
{
|
16
|
+
default: ["w-4", "h-4"]
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
# rubocop:disable Layout/LineLength
|
21
|
+
def styles
|
22
|
+
{
|
23
|
+
default: Flowbite::Style.new(
|
24
|
+
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"],
|
25
|
+
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"],
|
26
|
+
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"]
|
27
|
+
)
|
28
|
+
}.freeze
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def input_field_type
|
33
|
+
:check_box
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Flowbite
|
4
|
+
module Input
|
5
|
+
# The indivdual input component for use in forms without labels or error
|
6
|
+
# messages.
|
7
|
+
#
|
8
|
+
# Use this when you want to render an input field on its own without any
|
9
|
+
# surrounding elements, ie as a building block in more complex input
|
10
|
+
# components.
|
11
|
+
#
|
12
|
+
# To render a complete input field with labels and error messages, use
|
13
|
+
# `Flowbite::InputField` instead.
|
14
|
+
class Field < ViewComponent::Base
|
15
|
+
SIZES = {
|
16
|
+
sm: ["p-2", "text-xs"],
|
17
|
+
default: ["p-2.5", "text-sm"],
|
18
|
+
lg: ["p-4", "text-base"]
|
19
|
+
}.freeze
|
20
|
+
|
21
|
+
STATES = [
|
22
|
+
DEFAULT = :default,
|
23
|
+
DISABLED = :disabled,
|
24
|
+
ERROR = :error
|
25
|
+
].freeze
|
26
|
+
|
27
|
+
attr_reader :options, :size, :style
|
28
|
+
|
29
|
+
class << self
|
30
|
+
def classes(size: :default, state: :default, style: :default)
|
31
|
+
style = styles.fetch(style)
|
32
|
+
state_classes = style.fetch(state)
|
33
|
+
state_classes + sizes.fetch(size)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns the sizes this Field supports.
|
37
|
+
#
|
38
|
+
# This is effectively the SIZES constant, but provided as a method to
|
39
|
+
# return the constant from the current class, not the superclass.
|
40
|
+
#
|
41
|
+
# @return [Hash] A hash mapping size names to their corresponding CSS
|
42
|
+
# classes.
|
43
|
+
def sizes
|
44
|
+
const_get(:SIZES)
|
45
|
+
end
|
46
|
+
|
47
|
+
# rubocop:disable Layout/LineLength
|
48
|
+
def styles
|
49
|
+
{
|
50
|
+
default: Flowbite::Style.new(
|
51
|
+
default: ["bg-gray-50", "border", "border-gray-300", "text-gray-900", "rounded-lg", "focus:ring-blue-500", "focus:border-blue-500", "block", "w-full", "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"],
|
52
|
+
disabled: ["bg-gray-100", "border", "border-gray-300", "text-gray-900", "text-sm", "rounded-lg", "focus:ring-blue-500", "focus:border-blue-500", "block", "w-full", "p-2.5", "cursor-not-allowed", "dark:bg-gray-700", "dark:border-gray-600", "dark:placeholder-gray-400", "dark:text-gray-400", "dark:focus:ring-blue-500", "dark:focus:border-blue-500"],
|
53
|
+
error: ["bg-red-50", "border", "border-red-500", "text-red-900", "placeholder-red-700", "rounded-lg", "focus:ring-red-500", "dark:bg-gray-700", "focus:border-red-500", "block", "w-full", "dark:text-red-500", "dark:placeholder-red-500", "dark:border-red-500"]
|
54
|
+
)
|
55
|
+
}.freeze
|
56
|
+
end
|
57
|
+
# rubocop:enable Layout/LineLength
|
58
|
+
end
|
59
|
+
|
60
|
+
def initialize(attribute:, form:, disabled: false, options: {}, size: :default)
|
61
|
+
@attribute = attribute
|
62
|
+
@disabled = disabled
|
63
|
+
@form = form
|
64
|
+
@options = options || {}
|
65
|
+
@object = form.object
|
66
|
+
@size = size
|
67
|
+
end
|
68
|
+
|
69
|
+
# Returns the HTML to use for the actual input field element.
|
70
|
+
def call
|
71
|
+
@form.send(
|
72
|
+
input_field_type,
|
73
|
+
@attribute,
|
74
|
+
**input_options
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns the CSS classes to apply to the input field
|
79
|
+
def classes
|
80
|
+
self.class.classes(size: size, state: state)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Returns the name of the method used to generate HTML for the input field
|
84
|
+
def input_field_type
|
85
|
+
:text_field
|
86
|
+
end
|
87
|
+
|
88
|
+
protected
|
89
|
+
|
90
|
+
# Returns true if the field is disabled
|
91
|
+
def disabled?
|
92
|
+
!!@disabled
|
93
|
+
end
|
94
|
+
|
95
|
+
def errors?
|
96
|
+
@object.errors.include?(@attribute.intern)
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
# Returns the options argument for the input field
|
102
|
+
def input_options
|
103
|
+
{
|
104
|
+
class: classes,
|
105
|
+
disabled: disabled?
|
106
|
+
}.merge(options)
|
107
|
+
end
|
108
|
+
|
109
|
+
def state
|
110
|
+
return DISABLED if disabled?
|
111
|
+
return ERROR if errors?
|
112
|
+
|
113
|
+
DEFAULT
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Flowbite
|
4
|
+
module Input
|
5
|
+
class File < Field
|
6
|
+
SIZES = {
|
7
|
+
sm: ["text-xs"],
|
8
|
+
default: ["text-sm"],
|
9
|
+
lg: ["text-lg"]
|
10
|
+
}.freeze
|
11
|
+
|
12
|
+
# Returns the name of the method used to generate HTML for the input field
|
13
|
+
def input_field_type
|
14
|
+
:file_field
|
15
|
+
end
|
16
|
+
|
17
|
+
# rubocop:disable Layout/LineLength
|
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
|
26
|
+
end
|
27
|
+
# rubocop:enable Layout/LineLength
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Flowbite
|
4
|
+
module Input
|
5
|
+
class Hint < ViewComponent::Base
|
6
|
+
STATES = [
|
7
|
+
DEFAULT = :default
|
8
|
+
].freeze
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def classes(state: :default, style: :default)
|
12
|
+
style = styles.fetch(style)
|
13
|
+
style.fetch(state)
|
14
|
+
end
|
15
|
+
|
16
|
+
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
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def call
|
26
|
+
tag.p(
|
27
|
+
content,
|
28
|
+
class: classes,
|
29
|
+
**@options
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(attribute:, form:, options: {})
|
34
|
+
@attribute = attribute
|
35
|
+
@form = form
|
36
|
+
@options = options
|
37
|
+
@object = form.object
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns an array with the CSS classes to apply to the label element
|
41
|
+
def classes
|
42
|
+
self.class.classes(state: state)
|
43
|
+
end
|
44
|
+
|
45
|
+
protected
|
46
|
+
|
47
|
+
# Returns the state of the label.
|
48
|
+
#
|
49
|
+
# See the STATES constant for valid values.
|
50
|
+
#
|
51
|
+
# @return [Symbol] the state of the label
|
52
|
+
def state
|
53
|
+
DEFAULT
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Flowbite
|
4
|
+
module Input
|
5
|
+
# https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-label
|
6
|
+
class Label < ViewComponent::Base
|
7
|
+
STATES = [
|
8
|
+
DEFAULT = :default,
|
9
|
+
DISABLED = :disabled,
|
10
|
+
ERROR = :error
|
11
|
+
].freeze
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def classes(state: :default, style: :default)
|
15
|
+
style = styles.fetch(style)
|
16
|
+
style.fetch(state)
|
17
|
+
end
|
18
|
+
|
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
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def call
|
31
|
+
if content?
|
32
|
+
@form.label(@attribute, content, **options)
|
33
|
+
else
|
34
|
+
@form.label(@attribute, **options)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def errors?
|
39
|
+
@object.errors.include?(@attribute.intern)
|
40
|
+
end
|
41
|
+
|
42
|
+
def initialize(attribute:, form:, disabled: false, options: {})
|
43
|
+
@attribute = attribute
|
44
|
+
@disabled = disabled
|
45
|
+
@form = form
|
46
|
+
@object = form.object
|
47
|
+
@options = options
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns an array with the CSS classes to apply to the label element
|
51
|
+
def classes
|
52
|
+
self.class.classes(state: state)
|
53
|
+
end
|
54
|
+
|
55
|
+
protected
|
56
|
+
|
57
|
+
def disabled?
|
58
|
+
!!@disabled
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns the state of the label.
|
62
|
+
#
|
63
|
+
# See the STATES constant for valid values.
|
64
|
+
#
|
65
|
+
# @return [Symbol] the state of the label
|
66
|
+
def state
|
67
|
+
return DISABLED if disabled?
|
68
|
+
return ERROR if errors?
|
69
|
+
|
70
|
+
DEFAULT
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def options
|
76
|
+
{
|
77
|
+
class: classes
|
78
|
+
}.merge(@options)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|