-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5351 from nebulab/waiting-for-dev/admin/text_area…
…_component [Admin] Add text_area component
- Loading branch information
Showing
11 changed files
with
400 additions
and
96 deletions.
There are no files selected for viewing
65 changes: 65 additions & 0 deletions
65
admin/app/components/solidus_admin/ui/forms/guidance/component.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# frozen_string_literal: true | ||
|
||
# @api private | ||
class SolidusAdmin::UI::Forms::Guidance::Component < SolidusAdmin::BaseComponent | ||
def initialize(field:, form:, hint:, errors:) | ||
@field = field | ||
@form = form | ||
@hint = hint | ||
@errors = errors || @form.object&.errors || raise(ArgumentError, <<~MSG | ||
When the form builder is not bound to a model instance, you must pass an | ||
errors Hash (`{ field_name: [errors] }`) to the component. | ||
MSG | ||
) | ||
end | ||
|
||
def call | ||
return "" unless needed? | ||
|
||
tag.div(class: "mt-2") do | ||
hint_tag + error_tag | ||
end | ||
end | ||
|
||
def hint_tag | ||
return "".html_safe unless @hint | ||
|
||
tag.p(id: hint_id, class: "body-tiny text-gray-500 peer-disabled:text-gray-300") do | ||
@hint | ||
end | ||
end | ||
|
||
def hint_id | ||
"#{prefix}_hint" | ||
end | ||
|
||
def error_tag | ||
return "".html_safe unless errors? | ||
|
||
tag.p(id: error_id, class: "body-tiny text-red-400") do | ||
@errors[@field].map do |error| | ||
tag.span(class: "block") { error.capitalize } | ||
end.reduce(&:+) | ||
end | ||
end | ||
|
||
def errors? | ||
@errors[@field].present? | ||
end | ||
|
||
def error_id | ||
"#{prefix}_error" | ||
end | ||
|
||
def prefix | ||
"#{@form.object_name}_#{@field}" | ||
end | ||
|
||
def aria_describedby | ||
"#{hint_id if @hint} #{error_id if errors?}" | ||
end | ||
|
||
def needed? | ||
@hint || errors? | ||
end | ||
end |
13 changes: 13 additions & 0 deletions
13
admin/app/components/solidus_admin/ui/forms/label/component.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# frozen_string_literal: true | ||
|
||
# @api private | ||
class SolidusAdmin::UI::Forms::Label::Component < SolidusAdmin::BaseComponent | ||
def initialize(field:, form:) | ||
@field = field | ||
@form = form | ||
end | ||
|
||
def call | ||
@form.label(@field, class: "block mb-0.5 body-tiny-bold") | ||
end | ||
end |
109 changes: 109 additions & 0 deletions
109
admin/app/components/solidus_admin/ui/forms/text_area/component.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
# frozen_string_literal: true | ||
|
||
class SolidusAdmin::UI::Forms::TextArea::Component < SolidusAdmin::BaseComponent | ||
SIZES = { | ||
s: %w[h-20 body-small], | ||
m: %w[h-28 body-small], | ||
l: %w[h-36 body-text] | ||
}.freeze | ||
|
||
# @param field [Symbol] the name of the field. Usually a model attribute. | ||
# @param form [ActionView::Helpers::FormBuilder] the form builder instance. | ||
# @param size [Symbol] the size of the field: `:s`, `:m` or `:l`. | ||
# @param hint [String, null] helper text to display below the field. | ||
# @param errors [Hash, nil] a Hash of errors for the field. If `nil` and the | ||
# form is bound to a model instance, the component will automatically fetch | ||
# the errors from the model. | ||
# @param attributes [Hash] additional HTML attributes to add to the field. | ||
# @raise [ArgumentError] when the form builder is not bound to a model | ||
# instance and no `errors` Hash is passed to the component. | ||
def initialize( | ||
field:, | ||
form:, | ||
size: :m, | ||
hint: nil, | ||
errors: nil, | ||
label_component: component("ui/forms/label"), | ||
guidance_component: component("ui/forms/guidance"), | ||
**attributes | ||
) | ||
@field = field | ||
@form = form | ||
@size = size | ||
@hint = hint | ||
@attributes = attributes | ||
@errors = errors | ||
@label_component = label_component | ||
@guidance_component = guidance_component | ||
end | ||
|
||
def call | ||
guidance = @guidance_component.new( | ||
field: @field, | ||
form: @form, | ||
hint: @hint, | ||
errors: @errors | ||
) | ||
|
||
tag.div(class: "mb-6") do | ||
label_tag + field_tag(guidance) + guidance_tag(guidance) | ||
end | ||
end | ||
|
||
def field_tag(guidance) | ||
@form.text_area( | ||
@field, | ||
class: field_classes(guidance), | ||
**field_aria_describedby_attribute(guidance), | ||
**field_error_attributes(guidance), | ||
**@attributes.except(:class) | ||
) | ||
end | ||
|
||
def field_classes(guidance) | ||
%w[ | ||
peer | ||
block px-3 py-4 w-full | ||
text-black | ||
bg-white border border-gray-300 rounded-sm | ||
hover:border-gray-500 | ||
placeholder:text-gray-400 | ||
focus:border-gray-500 focus:shadow-[0_0_0_2px_#bbb] focus-visible:outline-none | ||
disabled:bg-gray-50 disabled:text-gray-300 | ||
] + field_size_classes + field_error_classes(guidance) + Array(@attributes[:class]).compact | ||
end | ||
|
||
def field_size_classes | ||
SIZES.fetch(@size) | ||
end | ||
|
||
def field_aria_describedby_attribute(guidance) | ||
return {} unless guidance.needed? | ||
|
||
{ | ||
"aria-describedby": guidance.aria_describedby | ||
} | ||
end | ||
|
||
def field_error_classes(guidance) | ||
return [] unless guidance.errors? | ||
|
||
%w[border-red-400 text-red-400] | ||
end | ||
|
||
def field_error_attributes(guidance) | ||
return {} unless guidance.errors? | ||
|
||
{ | ||
"aria-invalid": true | ||
} | ||
end | ||
|
||
def label_tag | ||
render @label_component.new(field: @field, form: @form) | ||
end | ||
|
||
def guidance_tag(guidance) | ||
render guidance | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.