flowbite-components 0.1.2 → 0.1.4
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 +35 -7
- data/README.md +39 -9
- data/app/components/flowbite/button/outline.rb +25 -10
- data/app/components/flowbite/button/pill.rb +26 -26
- data/app/components/flowbite/button.rb +33 -30
- 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 +58 -15
- data/app/components/flowbite/input/checkbox.rb +45 -7
- data/app/components/flowbite/input/field.rb +21 -12
- data/app/components/flowbite/input/file.rb +11 -9
- data/app/components/flowbite/input/hint.rb +10 -7
- data/app/components/flowbite/input/label.rb +14 -9
- data/app/components/flowbite/input/radio_button.rb +11 -9
- data/app/components/flowbite/input/select.rb +15 -6
- data/app/components/flowbite/input/textarea.rb +11 -9
- data/app/components/flowbite/input/validation_error.rb +31 -1
- data/app/components/flowbite/input_field/checkbox.html.erb +2 -4
- data/app/components/flowbite/input_field/checkbox.rb +17 -8
- data/app/components/flowbite/input_field/input_field.html.erb +1 -1
- data/app/components/flowbite/input_field/radio_button.html.erb +2 -4
- data/app/components/flowbite/input_field/radio_button.rb +14 -12
- data/app/components/flowbite/input_field/select.rb +5 -1
- data/app/components/flowbite/input_field.rb +38 -9
- data/app/components/flowbite/link.rb +41 -0
- data/app/components/flowbite/styles.rb +34 -0
- data/lib/flowbite/components/version.rb +1 -1
- metadata +5 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0013a87a4e4924d4ca2fe6f3ba8eff3f9f266be23a15b07cbddd25164d436805
|
|
4
|
+
data.tar.gz: d50dd418f1403dc2375754f4b0d295c9c2d4f1a09c0904bffce88fc76268135b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e410ab1f18d6264c18cae8e5c0322c612422e33aa4136ab99ff21e6b0564ceaeb95decd262a265d72b9029022ff76965c19eeb0438d3d295c85cd2962986a3ab
|
|
7
|
+
data.tar.gz: 168b101505fbddfc952c334cc169c1e12e5f129beb8c3f884ffd32047c0548bd22655fd03a6da3589f9ff5071c94850d727761c7aacb96b2712c09420657147c
|
data/CHANGELOG.md
CHANGED
|
@@ -7,15 +7,43 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
### Added
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
* Basic Card component
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
### Removed
|
|
14
13
|
|
|
15
|
-
### Changes
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
## [0.1.4]
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
* Flowbite::Link component to render links.
|
|
20
|
+
* Flowbite::Card now displays a title via the title argument/slot.
|
|
21
|
+
* Improved error message when an unknown style is requested.
|
|
22
|
+
* Input-elements now support forms without an object; ie forms built with `form_tag` - not `form_for` or `form_with`.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
* [BREAKING] All components now use Flowbite 4 style classes. This adds the option for easier styling, uses semantic variant names, and keeps us up to date with Flowbite proper.
|
|
27
|
+
* Extra CSS classes passed to components in the `class` argument are now added to the default classes from the component. This optimizes for minor tweaks and additions, which is likely to be the most common use case. If you need to replace all classes on the root element of the component, pass them in `options[:class]` instead.
|
|
18
28
|
|
|
19
29
|
### Removed
|
|
20
30
|
|
|
21
|
-
*
|
|
31
|
+
* [BREAKING] Color-specific styles from Flowbite::Button, ie `alternative`, `green`, `light`, `purple`, `red`, `yellow`.
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## [0.1.3]
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
|
|
38
|
+
* Options to Flowbite::InputField::Checkbox and Flowbite::Input::Checkbox that allow you to change the submitted value.
|
|
39
|
+
* Options added for Flowbite::Input::Select - :multiple and :include_blank. These can now be passed to either the input itself or Flowbite::InputField::Select
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
## [0.1.2]
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
|
|
46
|
+
* Button component (first component, wee!)
|
|
47
|
+
* Input components
|
|
48
|
+
* InputField components
|
|
49
|
+
* Basic Card component
|
data/README.md
CHANGED
|
@@ -22,7 +22,7 @@ Flowbite Components provides a comprehensive library of UI components following
|
|
|
22
22
|
Add the gem to your application's Gemfile:
|
|
23
23
|
|
|
24
24
|
```ruby
|
|
25
|
-
gem
|
|
25
|
+
gem "flowbite-components"
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
Then execute:
|
|
@@ -31,9 +31,9 @@ Then execute:
|
|
|
31
31
|
bundle install
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
###
|
|
34
|
+
### tailwindcss-rails
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
Tailwind needs to be able to look through your code in order to generate the final CSS file with the class names you actually use. To allow Tailwind to find CSS class names inside flowbite-components you need to use [tailwindcss-rails](https://github.com/rails/tailwindcss-rails) gem:
|
|
37
37
|
|
|
38
38
|
```ruby
|
|
39
39
|
gem "tailwindcss-rails", ">= 4.3.0"
|
|
@@ -44,17 +44,19 @@ gem "tailwindcss-rails", ">= 4.3.0"
|
|
|
44
44
|
Install Flowbite as an npm dependency:
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
|
-
|
|
47
|
+
yarn add flowbite
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
Add Flowbite to your Tailwind CSS configuration. In your `app/assets/tailwind/application.css`:
|
|
51
51
|
|
|
52
52
|
```css
|
|
53
|
-
@import "flowbite/src/themes/default";
|
|
54
53
|
@plugin "flowbite/plugin";
|
|
54
|
+
@import "flowbite/src/themes/default";
|
|
55
55
|
@import "../builds/tailwind/flowbite_components";
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
+
If you want to use one of the other [Flowbite themes](https://flowbite.com/docs/customize/theming/), change `@import "flowbite/src/themes/default";` accordingly.
|
|
59
|
+
|
|
58
60
|
## Usage examples
|
|
59
61
|
|
|
60
62
|
### Basic Form Field
|
|
@@ -217,6 +219,33 @@ renders
|
|
|
217
219
|
- **Outline Button**: `Flowbite::Button::Outline`
|
|
218
220
|
- **Pill Button**: `Flowbite::Button::Pill`
|
|
219
221
|
|
|
222
|
+
#### Cards
|
|
223
|
+
- **Card**: `Flowbite::Card` (default card with content and title)
|
|
224
|
+
|
|
225
|
+
#### Navigation
|
|
226
|
+
- **Link**: `Flowbite::Link` (default link styling)
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
## Principles
|
|
230
|
+
|
|
231
|
+
### CSS classes are additive
|
|
232
|
+
|
|
233
|
+
Passing classes via the `class` argument to a component adds the classes to the
|
|
234
|
+
default ones instead of replacing them.
|
|
235
|
+
|
|
236
|
+
```ruby
|
|
237
|
+
render(Component.new(class: "these are added"))
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
This makes for easier customization of components, where you don't have to
|
|
241
|
+
recreate the entire classlist, ie in order to increase sizes or add margins or
|
|
242
|
+
whatever.
|
|
243
|
+
|
|
244
|
+
If you want to replace the entire class attribute for a component, pass it as part of the `options` hash, ie
|
|
245
|
+
|
|
246
|
+
```ruby
|
|
247
|
+
render(Component.new(options: {class: "these replace the classes"}))
|
|
248
|
+
```
|
|
220
249
|
|
|
221
250
|
## Development
|
|
222
251
|
|
|
@@ -242,11 +271,12 @@ bundle exec rake install
|
|
|
242
271
|
|
|
243
272
|
### Component Previews
|
|
244
273
|
|
|
245
|
-
This library includes
|
|
274
|
+
This library includes a demo application with previews for all components. To view them:
|
|
246
275
|
|
|
247
|
-
1.
|
|
248
|
-
2. Run `
|
|
249
|
-
3.
|
|
276
|
+
1. cd demo
|
|
277
|
+
2. Run `bundle && npm install`
|
|
278
|
+
3. Run `rails server`
|
|
279
|
+
4. Visit `http://localhost:3000/rails/lookbook`
|
|
250
280
|
|
|
251
281
|
## Contributing
|
|
252
282
|
|
|
@@ -4,18 +4,33 @@ module Flowbite
|
|
|
4
4
|
class Button
|
|
5
5
|
class Outline < Flowbite::Button
|
|
6
6
|
class << self
|
|
7
|
-
# rubocop:disable Layout/LineLength
|
|
7
|
+
# rubocop:disable Layout/LineLength, Metrics/MethodLength
|
|
8
8
|
def styles
|
|
9
|
-
{
|
|
10
|
-
|
|
11
|
-
default: ["text-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
default: ["
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
Flowbite::Styles.from_hash({
|
|
10
|
+
danger: {
|
|
11
|
+
default: ["focus:outline-none", "text-danger", "bg-transparent", "box-border", "border", "border-danger", "hover:text-white", "hover:bg-danger-strong", "focus:ring-4", "focus:ring-danger-medium", "shadow-xs", "font-medium", "leading-5", "rounded-base", "text-center", "me-2", "mb-2"]
|
|
12
|
+
},
|
|
13
|
+
dark: {
|
|
14
|
+
default: ["focus:outline-none", "text-dark", "bg-transparent", "box-border", "border", "border-dark", "hover:text-white", "hover:bg-dark-strong", "focus:ring-4", "focus:ring-neutral-tertiary", "shadow-xs", "font-medium", "leading-5", "rounded-base", "text-center", "me-2", "mb-2"]
|
|
15
|
+
},
|
|
16
|
+
default: {
|
|
17
|
+
default: ["focus:outline-none", "text-brand", "bg-transparent", "box-border", "border", "border-brand", "hover:text-white", "hover:bg-brand-strong", "focus:ring-4", "focus:ring-brand-medium", "shadow-xs", "font-medium", "leading-5", "rounded-base", "text-center", "me-2", "mb-2"]
|
|
18
|
+
},
|
|
19
|
+
secondary: {
|
|
20
|
+
default: ["focus:outline-none", "text-body", "bg-transparent", "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", "text-center", "me-2", "mb-2"]
|
|
21
|
+
},
|
|
22
|
+
success: {
|
|
23
|
+
default: ["focus:outline-none", "text-success", "bg-transparent", "box-border", "border", "border-success", "hover:text-white", "hover:bg-success-strong", "focus:ring-4", "focus:ring-success-medium", "shadow-xs", "font-medium", "leading-5", "rounded-base", "text-center", "me-2", "mb-2"]
|
|
24
|
+
},
|
|
25
|
+
tertiary: {
|
|
26
|
+
default: ["focus:outline-none", "text-body", "bg-transparent", "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", "text-center", "me-2", "mb-2"]
|
|
27
|
+
},
|
|
28
|
+
warning: {
|
|
29
|
+
default: ["focus:outline-none", "text-warning", "bg-transparent", "box-border", "border", "border-warning", "hover:text-white", "hover:bg-warning-strong", "focus:ring-4", "focus:ring-warning-medium", "shadow-xs", "font-medium", "leading-5", "rounded-base", "text-center", "me-2", "mb-2"]
|
|
30
|
+
}
|
|
31
|
+
}.freeze)
|
|
17
32
|
end
|
|
18
|
-
# rubocop:enable Layout/LineLength
|
|
33
|
+
# rubocop:enable Layout/LineLength, Metrics/MethodLength
|
|
19
34
|
end
|
|
20
35
|
end
|
|
21
36
|
end
|
|
@@ -6,32 +6,32 @@ module Flowbite
|
|
|
6
6
|
class << self
|
|
7
7
|
# rubocop:disable Layout/LineLength, Metrics/MethodLength
|
|
8
8
|
def styles
|
|
9
|
-
{
|
|
10
|
-
|
|
11
|
-
default: ["
|
|
12
|
-
|
|
13
|
-
dark:
|
|
14
|
-
default: ["text-white", "bg-
|
|
15
|
-
|
|
16
|
-
default:
|
|
17
|
-
default: ["text-white", "bg-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
default: ["text-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
default: ["text-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
default: ["text-white", "bg-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
default: ["text-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
default: ["text-white", "bg-
|
|
33
|
-
|
|
34
|
-
}
|
|
9
|
+
Flowbite::Styles.from_hash({
|
|
10
|
+
danger: {
|
|
11
|
+
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-full", "text-center"]
|
|
12
|
+
},
|
|
13
|
+
dark: {
|
|
14
|
+
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-full", "text-center"]
|
|
15
|
+
},
|
|
16
|
+
default: {
|
|
17
|
+
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-full", "text-center"]
|
|
18
|
+
},
|
|
19
|
+
ghost: {
|
|
20
|
+
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-full", "text-center"]
|
|
21
|
+
},
|
|
22
|
+
secondary: {
|
|
23
|
+
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-full", "text-center"]
|
|
24
|
+
},
|
|
25
|
+
success: {
|
|
26
|
+
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-full", "text-center"]
|
|
27
|
+
},
|
|
28
|
+
tertiary: {
|
|
29
|
+
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-full", "text-center"]
|
|
30
|
+
},
|
|
31
|
+
warning: {
|
|
32
|
+
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-full", "text-center"]
|
|
33
|
+
}
|
|
34
|
+
}.freeze)
|
|
35
35
|
end
|
|
36
36
|
# rubocop:enable Layout/LineLength, Metrics/MethodLength
|
|
37
37
|
end
|
|
@@ -11,9 +11,9 @@ module Flowbite
|
|
|
11
11
|
# as HTML attributes.
|
|
12
12
|
class Button < ViewComponent::Base
|
|
13
13
|
SIZES = {
|
|
14
|
-
xs: ["text-xs", "px-3", "py-
|
|
14
|
+
xs: ["text-xs", "px-3", "py-1.5"],
|
|
15
15
|
sm: ["text-sm", "px-3", "py-2"],
|
|
16
|
-
default: ["text-sm", "px-
|
|
16
|
+
default: ["text-sm", "px-4", "py-2.5"],
|
|
17
17
|
lg: ["text-base", "px-5", "py-3"],
|
|
18
18
|
xl: ["text-base", "px-6", "py-3.5"]
|
|
19
19
|
}.freeze
|
|
@@ -31,39 +31,42 @@ module Flowbite
|
|
|
31
31
|
|
|
32
32
|
# rubocop:disable Layout/LineLength
|
|
33
33
|
def styles
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
default:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
34
|
+
Flowbite::Styles.from_hash(
|
|
35
|
+
{
|
|
36
|
+
danger: {
|
|
37
|
+
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"]
|
|
38
|
+
},
|
|
39
|
+
dark: {
|
|
40
|
+
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"]
|
|
41
|
+
},
|
|
42
|
+
default: {
|
|
43
|
+
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"]
|
|
44
|
+
},
|
|
45
|
+
ghost: {
|
|
46
|
+
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"]
|
|
47
|
+
},
|
|
48
|
+
secondary: {
|
|
49
|
+
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"]
|
|
50
|
+
},
|
|
51
|
+
success: {
|
|
52
|
+
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"]
|
|
53
|
+
},
|
|
54
|
+
tertiary: {
|
|
55
|
+
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"]
|
|
56
|
+
},
|
|
57
|
+
warning: {
|
|
58
|
+
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"]
|
|
59
|
+
}
|
|
60
|
+
}.freeze
|
|
61
|
+
)
|
|
60
62
|
end
|
|
61
63
|
# rubocop:enable Layout/LineLength
|
|
62
64
|
end
|
|
63
65
|
|
|
64
66
|
attr_reader :button_attributes, :size, :style
|
|
65
67
|
|
|
66
|
-
def initialize(size: :default, style: :default, **button_attributes)
|
|
68
|
+
def initialize(class: nil, size: :default, style: :default, **button_attributes)
|
|
69
|
+
@class = Array.wrap(binding.local_variable_get(:class))
|
|
67
70
|
@size = size
|
|
68
71
|
@style = style
|
|
69
72
|
@button_attributes = button_attributes
|
|
@@ -80,7 +83,7 @@ module Flowbite
|
|
|
80
83
|
private
|
|
81
84
|
|
|
82
85
|
def classes
|
|
83
|
-
self.class.classes(size: size, state: :default, style: style)
|
|
86
|
+
self.class.classes(size: size, state: :default, style: style) + @class
|
|
84
87
|
end
|
|
85
88
|
|
|
86
89
|
def options
|
|
@@ -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
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Flowbite
|
|
2
4
|
# Renders a card element.
|
|
3
5
|
#
|
|
4
6
|
# See https://flowbite.com/docs/components/cards/
|
|
5
7
|
class Card < ViewComponent::Base
|
|
8
|
+
renders_one :title
|
|
9
|
+
|
|
6
10
|
class << self
|
|
7
11
|
def classes(state: :default, style: :default)
|
|
8
12
|
style = styles.fetch(style)
|
|
@@ -11,33 +15,72 @@ module Flowbite
|
|
|
11
15
|
|
|
12
16
|
# rubocop:disable Layout/LineLength
|
|
13
17
|
def styles
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
default:
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
Flowbite::Styles.from_hash(
|
|
19
|
+
{
|
|
20
|
+
default: {
|
|
21
|
+
default: ["p-6", "bg-neutral-primary-soft", "border", "border-default", "rounded-base", "shadow-xs"]
|
|
22
|
+
}
|
|
23
|
+
}.freeze
|
|
24
|
+
)
|
|
19
25
|
end
|
|
20
26
|
# rubocop:enable Layout/LineLength
|
|
21
27
|
end
|
|
22
28
|
|
|
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
29
|
# @param class [Array<String>] Additional CSS classes for the card
|
|
33
30
|
# container.
|
|
34
31
|
#
|
|
35
32
|
# @param options [Hash] Additional HTML options for the card container
|
|
36
33
|
# (e.g., custom classes, data attributes). These options are merged into
|
|
37
34
|
# the card's root element.
|
|
38
|
-
|
|
35
|
+
#
|
|
36
|
+
# @param title [Hash] An optional title for the card. If provided,
|
|
37
|
+
# it will be rendered at the top of the card in a h5 tag using the
|
|
38
|
+
# Card::Title component. The hash can contain:
|
|
39
|
+
# - `content`: The text content of the title
|
|
40
|
+
# - `options`: Additional HTML options to pass to the title element
|
|
41
|
+
# Alternatively, you can use the `title` slot to provide the entire
|
|
42
|
+
# title element yourself.
|
|
43
|
+
def initialize(class: [], options: {}, title: {})
|
|
39
44
|
@class = Array(binding.local_variable_get(:class)) || []
|
|
40
45
|
@options = options || {}
|
|
46
|
+
@title = title
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
protected
|
|
50
|
+
|
|
51
|
+
def card_options
|
|
52
|
+
card_options = {}
|
|
53
|
+
card_options[:class] = self.class.classes + @class
|
|
54
|
+
card_options.merge(@options)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Returns the HTML to use for the title element if any
|
|
58
|
+
def default_title
|
|
59
|
+
component = Flowbite::Card::Title.new(**default_title_options)
|
|
60
|
+
|
|
61
|
+
if default_title_content
|
|
62
|
+
component.with_content(default_title_content)
|
|
63
|
+
else
|
|
64
|
+
component
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
render(component)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def default_title_content
|
|
71
|
+
return nil unless @title
|
|
72
|
+
|
|
73
|
+
@title[:content]
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# @return [Hash] The options to pass to the default title component
|
|
77
|
+
def default_title_options
|
|
78
|
+
title_options = @title.dup
|
|
79
|
+
title_options[:options] || {}
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def title?
|
|
83
|
+
@title.present?
|
|
41
84
|
end
|
|
42
85
|
end
|
|
43
86
|
end
|
|
@@ -9,6 +9,9 @@ module Flowbite
|
|
|
9
9
|
#
|
|
10
10
|
# https://flowbite.com/docs/forms/checkbox/
|
|
11
11
|
class Checkbox < Field
|
|
12
|
+
DEFAULT_CHECKED_VALUE = "1"
|
|
13
|
+
DEFAULT_UNCHECKED_VALUE = "0"
|
|
14
|
+
|
|
12
15
|
class << self
|
|
13
16
|
# Checkboxes only have their default size.
|
|
14
17
|
def sizes
|
|
@@ -19,19 +22,54 @@ module Flowbite
|
|
|
19
22
|
|
|
20
23
|
# rubocop:disable Layout/LineLength
|
|
21
24
|
def styles
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
default:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
+
)
|
|
29
34
|
end
|
|
30
35
|
end
|
|
31
36
|
|
|
37
|
+
# Returns the HTML to use for the actual input field element.
|
|
38
|
+
def call
|
|
39
|
+
@form.send(
|
|
40
|
+
input_field_type,
|
|
41
|
+
@attribute,
|
|
42
|
+
input_options,
|
|
43
|
+
checked_value,
|
|
44
|
+
unchecked_value
|
|
45
|
+
)
|
|
46
|
+
end
|
|
47
|
+
|
|
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)
|
|
50
|
+
@unchecked_value = unchecked_value
|
|
51
|
+
@value = value
|
|
52
|
+
end
|
|
53
|
+
|
|
32
54
|
def input_field_type
|
|
33
55
|
:check_box
|
|
34
56
|
end
|
|
57
|
+
|
|
58
|
+
# Returns the options argument for the input field
|
|
59
|
+
def input_options
|
|
60
|
+
{
|
|
61
|
+
class: classes,
|
|
62
|
+
disabled: disabled?
|
|
63
|
+
}.merge(options)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def checked_value
|
|
69
|
+
@value
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
attr_reader :unchecked_value
|
|
35
73
|
end
|
|
36
74
|
end
|
|
37
75
|
end
|