Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Changed

* [BREAKING] The API of Flowbite::InputField::RadioButton now follows the same structure as the other components for hints. Instead of passing a String (`hint: "This is the hint"`) you now have to pass a Hash that's passed along to the Hint component (i.e. `hint: {content: "This is the hint"}`), allowing you to customize other options (eg HTML attributes like class) as well.
* [BREAKING] Flowbite::Input::Field has been renamed to Flowbite::Input. All individual input components now use that as their superclass. This matches the class hierarchy of Flowbite::InputField::* classes better and allows Flowbite::Input to automagically appear in the documentation.

### Fixed

Expand Down
152 changes: 152 additions & 0 deletions app/components/flowbite/input.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# frozen_string_literal: true

module Flowbite
# The individual input form element used in forms - without labels, error
# messages, hints, etc.
#
# Use this when you want to render an input field on its own without any
# surrounding elements, i.e. as a building block in more complex input
# components.
#
# To render a complete input field with labels and error messages, use
# {Flowbite::InputField} instead.
#
# By default this renders a text input field. To render other types of input
# fields, use one of the subclasses, such as {Flowbite::Input::Checkbox} or
# {Flowbite::Input::Textarea}.
class Input < ViewComponent::Base
SIZES = {
sm: ["px-2.5", "py-2", "text-sm"],
default: ["px-3", "py-2.5", "text-sm"],
lg: ["px-3.5", "py-3", "text-base"]
}.freeze

STATES = [
DEFAULT = :default,
DISABLED = :disabled,
ERROR = :error
].freeze

attr_reader :options, :size, :style

class << self
# @return [Array<String>] The CSS classes to apply to the input field
# given the specified +size+, +state+, and +style+.
def classes(size: :default, state: :default, style: :default)
style = styles.fetch(style)
state_classes = style.fetch(state)
state_classes + sizes.fetch(size)
end

# Returns the sizes this Input supports.
#
# This is effectively the {SIZES} constant, but provided as a method to
# return the constant from the current class, not the superclass.
#
# @return [Hash] A hash mapping size names to their corresponding CSS
# classes.
def sizes
const_get(:SIZES)
end

# @return [Flowbite::Styles] The available styles for this input field.
def styles
# rubocop:disable Layout/LineLength
Flowbite::Styles.from_hash(
{
default: {
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"],
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"],
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"]
}
}.freeze
)
# rubocop:enable Layout/LineLength
end
end

# @param attribute [Symbol] The attribute on the form's object this input
# field is for.
#
# @param form [ActionView::Helpers::FormBuilder] The form builder this
# input field is part of.
#
# @param class [String, Array<String>] Additional CSS classes to apply to
# the input field.
#
# @param disabled [Boolean] Whether the input field should be disabled.
#
# @param options [Hash] Additional HTML attributes to pass to the input
# field. For example, you can use this to set placeholder text by
# passing +options: {placeholder: "Enter your name"}+
#
# @param size [Symbol] The size of the input field. Can be one of +:sm+,
# +:default+, or +:lg+.
def initialize(attribute:, form:, class: nil, disabled: false, options: {}, size: :default)
@attribute = attribute
@class = Array.wrap(binding.local_variable_get(:class))
@disabled = disabled
@form = form
@options = options || {}
@object = form.object
@size = size
end

# Returns the HTML to use for the actual input field element.
def call
@form.send(
input_field_type,
@attribute,
**input_options
)
end

# Returns the CSS classes to apply to the input field
#
# @return [Array<String>] An array of CSS classes.
def classes
self.class.classes(size: size, state: state) + @class
end

# Returns the name of the method used to generate HTML for the input field
#
# @return [Symbol] The form helper method name to call on +form+.
def input_field_type
:text_field
end

protected

# @return [Boolean] Returns true if the field is disabled
def disabled?
!!@disabled
end

# Returns true if the object has errors. Returns false if there is no
# object.
#
# @return [Boolean] true if there are errors, false otherwise.
def errors?
return false unless @object

@object.errors.include?(@attribute.intern)
end

private

# Returns the options argument for the input field
def input_options
{
class: classes,
disabled: disabled?
}.merge(options)
end

def state
return DISABLED if disabled?
return ERROR if errors?

DEFAULT
end
end
end
4 changes: 2 additions & 2 deletions app/components/flowbite/input/checkbox.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# frozen_string_literal: true

module Flowbite
module Input
class Input
# The checkbox component can be used to receive one or more selected options
# from the user in the form of a square box available in multiple styles,
# sizes, colors, and variants coded with the utility classes from Tailwind
# CSS and with support for dark mode.
#
# https://flowbite.com/docs/forms/checkbox/
class Checkbox < Field
class Checkbox < Input
DEFAULT_CHECKED_VALUE = "1"
DEFAULT_UNCHECKED_VALUE = "0"

Expand Down
4 changes: 2 additions & 2 deletions app/components/flowbite/input/date.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# frozen_string_literal: true

module Flowbite
module Input
class Date < Field
class Input
class Date < Input
def input_field_type
:date_field
end
Expand Down
4 changes: 2 additions & 2 deletions app/components/flowbite/input/date_time.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# frozen_string_literal: true

module Flowbite
module Input
class DateTime < Field
class Input
class DateTime < Input
def input_field_type
:datetime_field
end
Expand Down
4 changes: 2 additions & 2 deletions app/components/flowbite/input/email.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# frozen_string_literal: true

module Flowbite
module Input
class Email < Field
class Input
class Email < Input
# Returns the name of the method used to generate HTML for the input field
def input_field_type
:email_field
Expand Down
154 changes: 0 additions & 154 deletions app/components/flowbite/input/field.rb

This file was deleted.

4 changes: 2 additions & 2 deletions app/components/flowbite/input/file.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# frozen_string_literal: true

module Flowbite
module Input
class File < Field
class Input
class File < Input
SIZES = {
sm: ["text-sm"],
default: ["text-sm"],
Expand Down
2 changes: 1 addition & 1 deletion app/components/flowbite/input/hint.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

module Flowbite
module Input
class Input
# A hint element for input fields.
#
# Provides additional context or instructions for the user.
Expand Down
2 changes: 1 addition & 1 deletion app/components/flowbite/input/label.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

module Flowbite
module Input
class Input
# https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-label
class Label < ViewComponent::Base
STATES = [
Expand Down
Loading