Full Code of heartcombo/simple_form for AI

main 55bec8024c3b cached
122 files
438.9 KB
115.7k tokens
590 symbols
1 requests
Download .txt
Showing preview only (471K chars total). Download the full file or copy to clipboard to get everything.
Repository: heartcombo/simple_form
Branch: main
Commit: 55bec8024c3b
Files: 122
Total size: 438.9 KB

Directory structure:
gitextract_7k1r7n03/

├── .github/
│   ├── code-scanning.yml
│   └── workflows/
│       └── test.yml
├── .gitignore
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Gemfile
├── ISSUE_TEMPLATE.md
├── MIT-LICENSE
├── README.md
├── Rakefile
├── bin/
│   └── test
├── gemfiles/
│   ├── Gemfile-rails-7-0
│   ├── Gemfile-rails-7-1
│   ├── Gemfile-rails-7-2
│   ├── Gemfile-rails-8-0
│   └── Gemfile-rails-main
├── lib/
│   ├── generators/
│   │   └── simple_form/
│   │       ├── USAGE
│   │       ├── install_generator.rb
│   │       └── templates/
│   │           ├── README
│   │           ├── _form.html.erb
│   │           ├── _form.html.haml
│   │           ├── _form.html.slim
│   │           └── config/
│   │               ├── initializers/
│   │               │   ├── simple_form.rb
│   │               │   ├── simple_form_bootstrap.rb
│   │               │   └── simple_form_foundation.rb
│   │               └── locales/
│   │                   └── simple_form.en.yml
│   ├── simple_form/
│   │   ├── action_view_extensions/
│   │   │   ├── builder.rb
│   │   │   └── form_helper.rb
│   │   ├── components/
│   │   │   ├── errors.rb
│   │   │   ├── hints.rb
│   │   │   ├── html5.rb
│   │   │   ├── label_input.rb
│   │   │   ├── labels.rb
│   │   │   ├── maxlength.rb
│   │   │   ├── min_max.rb
│   │   │   ├── minlength.rb
│   │   │   ├── pattern.rb
│   │   │   ├── placeholders.rb
│   │   │   └── readonly.rb
│   │   ├── components.rb
│   │   ├── error_notification.rb
│   │   ├── form_builder.rb
│   │   ├── helpers/
│   │   │   ├── autofocus.rb
│   │   │   ├── disabled.rb
│   │   │   ├── readonly.rb
│   │   │   ├── required.rb
│   │   │   └── validators.rb
│   │   ├── helpers.rb
│   │   ├── inputs/
│   │   │   ├── base.rb
│   │   │   ├── block_input.rb
│   │   │   ├── boolean_input.rb
│   │   │   ├── collection_check_boxes_input.rb
│   │   │   ├── collection_input.rb
│   │   │   ├── collection_radio_buttons_input.rb
│   │   │   ├── collection_select_input.rb
│   │   │   ├── color_input.rb
│   │   │   ├── date_time_input.rb
│   │   │   ├── file_input.rb
│   │   │   ├── grouped_collection_select_input.rb
│   │   │   ├── hidden_input.rb
│   │   │   ├── numeric_input.rb
│   │   │   ├── password_input.rb
│   │   │   ├── priority_input.rb
│   │   │   ├── range_input.rb
│   │   │   ├── rich_text_area_input.rb
│   │   │   ├── string_input.rb
│   │   │   ├── text_input.rb
│   │   │   └── weekday_input.rb
│   │   ├── inputs.rb
│   │   ├── map_type.rb
│   │   ├── railtie.rb
│   │   ├── tags.rb
│   │   ├── version.rb
│   │   ├── wrappers/
│   │   │   ├── builder.rb
│   │   │   ├── leaf.rb
│   │   │   ├── many.rb
│   │   │   ├── root.rb
│   │   │   └── single.rb
│   │   └── wrappers.rb
│   └── simple_form.rb
├── simple_form.gemspec
└── test/
    ├── action_view_extensions/
    │   ├── builder_test.rb
    │   └── form_helper_test.rb
    ├── components/
    │   ├── custom_components_test.rb
    │   └── label_test.rb
    ├── form_builder/
    │   ├── association_test.rb
    │   ├── button_test.rb
    │   ├── error_notification_test.rb
    │   ├── error_test.rb
    │   ├── general_test.rb
    │   ├── hint_test.rb
    │   ├── input_field_test.rb
    │   ├── label_test.rb
    │   └── wrapper_test.rb
    ├── generators/
    │   └── simple_form_generator_test.rb
    ├── inputs/
    │   ├── boolean_input_test.rb
    │   ├── collection_check_boxes_input_test.rb
    │   ├── collection_radio_buttons_input_test.rb
    │   ├── collection_select_input_test.rb
    │   ├── color_input_test.rb
    │   ├── country_input_test.rb
    │   ├── datetime_input_test.rb
    │   ├── disabled_test.rb
    │   ├── discovery_test.rb
    │   ├── file_input_test.rb
    │   ├── general_test.rb
    │   ├── grouped_collection_select_input_test.rb
    │   ├── hidden_input_test.rb
    │   ├── numeric_input_test.rb
    │   ├── readonly_test.rb
    │   ├── required_test.rb
    │   ├── rich_text_area_input_test.rb
    │   ├── string_input_test.rb
    │   ├── text_input_test.rb
    │   ├── time_zone_input_test.rb
    │   └── weekday_input_test.rb
    ├── simple_form_test.rb
    ├── support/
    │   ├── discovery_inputs.rb
    │   ├── misc_helpers.rb
    │   ├── mock_controller.rb
    │   └── models.rb
    └── test_helper.rb

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/code-scanning.yml
================================================
paths-ignore:
  - test/**


================================================
FILE: .github/workflows/test.yml
================================================
name: Test

permissions:
  contents: read
on:
  push:
    branches:
      - main
  pull_request:
  workflow_dispatch:
jobs:
  test:
    strategy:
      fail-fast: false
      matrix:
        gemfile:
          - Gemfile
          - gemfiles/Gemfile-rails-main
          - gemfiles/Gemfile-rails-8-0
          - gemfiles/Gemfile-rails-7-2
          - gemfiles/Gemfile-rails-7-1
          - gemfiles/Gemfile-rails-7-0
        ruby:
          - '4.0'
          - '3.4'
          - '3.3'
          - '3.2'
          - '3.1'
          - '3.0'
          - '2.7'
        exclude:
          - gemfile: Gemfile
            ruby: '3.1'
          - gemfile: Gemfile
            ruby: '3.0'
          - gemfile: Gemfile
            ruby: '2.7'
          - gemfile: gemfiles/Gemfile-rails-main
            ruby: '3.2'
          - gemfile: gemfiles/Gemfile-rails-main
            ruby: '3.1'
          - gemfile: gemfiles/Gemfile-rails-main
            ruby: '3.0'
          - gemfile: gemfiles/Gemfile-rails-main
            ruby: '2.7'
          - gemfile: gemfiles/Gemfile-rails-8-0
            ruby: '3.1'
          - gemfile: gemfiles/Gemfile-rails-8-0
            ruby: '3.0'
          - gemfile: gemfiles/Gemfile-rails-8-0
            ruby: '2.7'
          - gemfile: gemfiles/Gemfile-rails-7-2
            ruby: '3.0'
          - gemfile: gemfiles/Gemfile-rails-7-2
            ruby: '2.7'
    runs-on: ubuntu-latest
    env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
      BUNDLE_GEMFILE: ${{ matrix.gemfile }}
    steps:
      - uses: actions/checkout@v4
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby }}
          bundler-cache: true # runs bundle install and caches installed gems automatically
      - run: bundle exec rake


================================================
FILE: .gitignore
================================================
.bundle/
pkg/
rdoc/
gemfiles/*.lock
/.idea/


================================================
FILE: CHANGELOG.md
================================================
## 5.4.1

* Ruby 4.0 support (no changes required)
* Support procs on validators for minlength/maxlength, and improve validators logic across the board to match Rails [#1859](https://github.com/heartcombo/simple_form/pull/1859)

## 5.4.0

* Add support for Ruby 3.4 and Rails 7.2/8.0/8.1. (no changes required)
* Drop support for Rails < 7 and Ruby < 2.7.
* Add `weekday` input. [#1846](https://github.com/heartcombo/simple_form/pull/1846)
* Remove redundant `aria-required` attribute for required fields. [#1823](https://github.com/heartcombo/simple_form/pull/1823)
* Integrate `:rich_text_area` with placeholders [#1842](https://github.com/heartcombo/simple_form/pull/1842)
* Fix encrypted attributes improperly casted (later fixed in Rails) [#1836](https://github.com/heartcombo/simple_form/pull/1836)
* Pass `base` object to `human_attribute_name` in labels [#1812](https://github.com/heartcombo/simple_form/pull/1812)

## 5.3.1

* Revert "Speed up input mapping lookup by avoiding rescuing exceptions" from v5.3.0, it caused a regression on dev/test environments with custom inputs.
* Try a slightly different approach to input lookups, without relying on regexp, to see if that helps with performance as originally intended.
* Add support to Ruby 3.3. (no changes required.)

## 5.3.0

* Add support for Rails 7.1. (no meaningful changes required.)
* Add `SimpleForm.deprecator` to integrate with new application deprecators in Rails 7.1.
* Remove test files from the gem package. [@orien](https://github.com/orien)
* Speed up input mapping lookup by avoiding rescuing exceptions. [@meanphil](https://github.com/meanphil) [@kriom](https://github.com/kriom) [@egeek](https://github.com/egeek)

## 5.2.0

* Add support for Rails 7.0 and Ruby 3.1/3.2 (no changes required)
* Fix escaping issue on boolean input with `include_hidden: false` and custom wrapper.
* Update Bootstrap install generator version 5. [@mhw](https://github.com/mhw)
* Accept proc as `group_method` for grouped collection select
* Honor `include_hidden` option on inline boolean inputs [@yboulkaid](https://github.com/yboulkaid)
* Fix deprecation error when using country_select input.

## 5.1.0

* Remove `I18nCache` module entirely. It was added complexity for very little gain in some translations, and caused extra trouble upgrading to Ruby 3. If you need that level of caching consider looking into I18n caching as a whole.
* Add support for Ruby 3.0, drop support for Ruby < 2.5.
* Add support for Rails 6.1, drop support for Rails < 5.2.
* Move CI to GitHub Actions.

## 5.0.3

### Bug fix
* Fix for ActiveStorage::Attached::Many. [@enriquez](https://github.com/enriquez)

## 5.0.2

### Enhancements
* Remove instruction to use form-inline class. [@goalaleo](https://github.com/goalaleo)
* Added RichTextAreaInput for ActionText. [itsterry](https://github.com/itsterry)
* Skip valid_class check if no class defined. [TALlama](https://github.com/TALlama)

### Bug fix
* Fix 'aria-required' field generated by prompt. [@CarlosAlbertoSantos](https://github.com/CarlosAlbertoSantos)

## 5.0.1

### Bug fix
* Replace `_url` with `remote_url` when trying to guess file inputs [@tegon](https://github.com/tegon). This has the side-effect of changing carrierwave's support from `0.2.1` to `0.2.2`.

## 5.0.0

### Enhancements
* Set multiple attribute for grouped selects also. [@ollym](https://github.com/ollym)
* Removes or renames label classes. [Abduvakilov](https://github.com/Abduvakilov)
* Support to label custom classes for inline collections. [@feliperenan](https://github.com/feliperenan)
* Update bootstrap generator template to match v4.3.x. [@m5o](https://github.com/m5o)
* Allow "required" attribute in generated select elements of PriorityInput. [@mcountis](https://github.com/mcountis)

### Bug fix
* Do not call `#send` in form object to check whether the attribute is a file input. [@tegon](https://github.com/tegon)

## Deprecations
* The config `SimpleForm.file_methods` is deprecated and it has no effect. Simple Form now supports automatically discover of file inputs for the following Gems: activestorage, carrierwave, paperclip, refile and shrine. If you are using a custom method that is not from one of the supported Gems, please change your forms to pass the input type explicitly:

```erb
 <%= form.input :avatar, as: :file %>
 ```

See http://blog.plataformatec.com.br/2019/09/incorrect-access-control-in-simple-form-cve-2019-16676 for more information.

## 4.1.0

### Enhancements
* Guess input type more carefully. [@sringling](https://github.com/sringling)
* Allow custom error on forms without model. [@victorperez](https://github.com/victorperez)
* Do not support Ruby < 2.3 anymore. [@gssbzn](https://github.com/gssbzn)
* Add color input type. [@gssbzn](https://github.com/gssbzn)

### Bug fix
* Improve disabled option to input_field. [@betelgeuse](https://github.com/betelgeuse)
* Memoize `input_html_classes` in `SimpleForm::Inputs::Base`. [@RigoTheDev](https://github.com/RigoTheDev)
* Fix column type citext HTML5 input type bug. [@brucew](https://github.com/brucew)
* Use form attribute in the nested boolean hidden field when it is given. [@feliperenan](https://github.com/feliperenan)

## 4.0.1

### Bug fix
* Do not support Rails 4 anymore. [@rafaelfranca](https://github.com/rafaelfranca)
* Add missing comma. [@vill](https://github.com/vill)

## 4.0.0

### Enhancements
* Add bootstrap v4.1 generator template. [@m5o](https://github.com/m5o)
* Add Rails 5.2 support. [@gobijan](https://github.com/gobijan)
* Add API to register custom components.[@feliperenan](https://github.com/feliperenan)
* Allow custom errors classes to inputs.[@feliperenan](https://github.com/feliperenan)
* Remove support from Rails 4.0, 4.1 and 4.2. [@feliperenan](https://github.com/feliperenan)
* Add support for citext, hstore, json & jsonb column types. [@swrobel](https://github.com/swrobel)
* Add :valid_class on input wrapper when value is present and valid [@aeberlin](https://github.com/aeberlin), [@m5o](https://github.com/m5o)
* Allow :valid_class to inputs when value is present and valid. [@m5o](https://github.com/m5o)
* Allow validation classes on input_field. [@feliperenan](https://github.com/feliperenan)
* Add basic ActiveStorage support. [@murb](https://github.com/murb)

### Bug fix
* Fix horizontal form label position, from right to text-right. [@cavpollo](https://github.com/cavpollo)
* Add base error display alongside existing errors. [@bluefalcon26](https://github.com/bluefalcon26)
* Silent deprecation warning for placeholder_text. [@moofkit](https://github.com/moofkit)
* Use custom i18n scope for label required html. [@tvdeyen](https://github.com/tvdeyen)

## 3.5.1

### Enhancements
* Exclude hidden field when unchecked_value: false. [@fschwahn](https://github.com/fschwahn)
* Add frozen_string_literal magic comment to several files. [@oniofchaos](https://github.com/oniofchaos)
* Try convert @object to model in case we got decorated object [@timurvafin](https://github.com/timurvafin)
- From now, if you are using some object that inherits from `SimpleDelegator`, you must implement
  `def to_model; self; end`. Otherwise, *Simple Form* will convert the decorated object to the model
  since `SimpleDelegator` will delegate it to the model.
* Code cleanup [@Fornacula](https://github.com/Fornacula)

### Bug fix
* Fix error when the scope from association has parameter. [@feliperenan](https://github.com/feliperenan)
* Only call `where` on associations when they respond to it. [@anicholson](https://github.com/anicholson)
* require 'action_pack' before using it. [@etagwerker](https://github.com/etagwerker)
* Check if Rails.env is defined. [@etagwerker](https://github.com/etagwerker)
* Fix minlength. [@mameier](https://github.com/mameier)
* Make errors_on_attribute return [] when not present. [@redrick](https://github.com/redrick)
* Fix boolean inputs in nested style for label non-string. [@feliperenan](https://github.com/feliperenan)

## 3.5.0

* Updated gem dependency to support Rails 5.1.x.

## 3.4.0

* Removed Ruby 2.4.0 `Integer` unification deprecation warning.
* Removed EOL Ruby 1.9.3 from the build matrix.
* Added `minlength` component.
* `boolean_label_class` can be set on a per-input basis.

## 3.3.1

### Bug fix

* Fix support for symbols when looking up types with `ActiveModel::Type`.

## 3.3.0

### enhancements
  * Add the `aria-invalid` attribute on inputs with errors.
  * Added support for the new `ActiveModel::Type` API over Active Record's
    column objects.

### bug fix
  * Fix `merge_wrapper_options` to correctly merge options with duplicated keys. [@herminiotorres](https://github.com/herminiotorres)
  Closes [#1278](https://github.com/heartcombo/simple_form/issues/1278).

## 3.2.1

### enhancements
  * Updated gem dependency to support Rails 5.0.x.

## 3.2.0

### bug fix
  * Improve performance of input generation by disabling support for `_html` translations. This reverts the feature introduced on the 3.1.0 branch

## 3.1.1

### enhancements
  * Add the `disabled_class` to the label when the input is disabled. [@rhodrid](https://github.com/rhodrid)

### bug fix
  * Make it possible to override `required` value that was previously set in the wrapper. [@nashby](https://github.com/nashby)

  * `date/time/datetime` inputs now correctly generate the label `for` attribute when
  HTML5 compatibility is explicitly enabled. [@ericsullivan](https://github.com/ericsullivan)

  * The datetime, date, and time inputs now have a nice format by default on bootstrap.
  [@ulissesalmeida](https://github.com/ulissesalmeida) [@eltonchrls](https://github.com/eltonchrls)

  * Now it is possible to set custom input mappings for collections.

  Example:

  ```ruby
    # On configuration:
    config.input_mappings = { /gender$/ => :check_boxes }

    # On form:
    f.input :gender, collection: [:male, :female]
  ```
  [strangeworks](https://github.com/strangeworks)

## 3.1.0

### enhancements
  * Update foundation generator to version 5. [@jorge-d](https://github.com/jorge-d)
  * Add mapping to `uuid` columns.
  * Add custom namespaces for custom inputs feature. [@vala](https://github.com/vala)
  * Add `:unless_blank` option to the wrapper API. [@IanVaughan](https://github.com/IanVaughan)
  * Add support to html markup in the I18n options. [@laurocaetano](https://github.com/laurocaetano)
  * Add the `full_error` component. [@laurocaetano](https://github.com/laurocaetano)
  * Add support to `scope` to be used on associations. [@laurocaetano](https://github.com/laurocaetano)
  * Execute the association `condition` in the object context. [@laurocaetano](https://github.com/laurocaetano)
  * Check if the given association responds to `order` before calling it. [@laurocaetano](https://github.com/laurocaetano)
  * Add Bootstrap 3 initializer template.
  * For radio or checkbox collection always use `:item_wrapper_tag` to wrap the content and add `label` when using `boolean_style` with `:nested` [@kassio](https://github.com/kassio) and [@erichkist](https://github.com/erichkist)
  * `input_field` uses the same wrapper as input but only with attribute components. [@nashby](https://github.com/nashby)
  * Add wrapper mapping per form basis [@rcillo](https://github.com/rcillo) and [@bernardoamc](https://github.com/bernardoamc)
  * Add `for` attribute to `label` when collections are rendered as radio or checkbox [@erichkist](https://github.com/erichkist), [@ulissesalmeida](https://github.com/ulissesalmeida) and [@fabioyamate](https://github.com/fabioyamate)
  * Add `include_default_input_wrapper_class` config [@luizcosta](https://github.com/luizcosta)
  * Map `datetime`, `date` and `time` input types to their respective HTML5 input tags
  when the `:html5` is set to `true` [@volmer](https://github.com/volmer)
  * Add `boolean_label_class` config.
  * Add `:html` option to include additional attributes on custom wrappers [@remofritzsche](https://github.com/remofritzsche) and [@ulissesalmeida](https://github.com/ulissesalmeida)
  * Make possible to use the Wrappers API to define attributes for the components.
  See https://github.com/heartcombo/simple_form/pull/997 for more information.
  * Put a whitespace before the `inline_label` options of boolean input if it is present.
  * Add support to configure the `label_text` proc at the wrapper level. [@NOX73](https://github.com/NOX73)
  * `label_text` proc now receive three arguments (label, request, and if the label was explicit). [@timscott](https://github.com/timscott)
  * Add I18n support to `:include_blank` and `:prompt` when `:translate` is used as value. [@haines](https://github.com/heartcombo/simple_form/pull/616)
  * Add support to define custom error messages for the attributes.
  * Add support to change the I18n scope to be used in Simple Form. [@nielsbuus](https://github.com/nielsbuus)
  * The default form class can now be overridden with `html: { :class }`. [@rmm5t](https://github.com/rmm5t)

### bug fix
  * Fix `full_error` when the attribute is an association. [@mvdamme](https://github.com/jorge-d)
  * Fix support to `:namespace` and `:index` options for nested check boxes and radio buttons when the attribute is an association.
  * Collection input that uses automatic collection translation properly sets checked values.
  Closes [#971](https://github.com/heartcombo/simple_form/issues/971) [@nashby](https://github.com/nashby)
  * Collection input generates `required` attribute if it has `prompt` option. [@nashby](https://github.com/nashby)
  * Grouped collection uses the first non-empty object to detect label and value methods.

## deprecation
  * Methods on custom inputs now accept a required argument with the wrapper options.
  See https://github.com/heartcombo/simple_form/pull/997 for more information.
  * SimpleForm.form_class is deprecated in favor of SimpleForm.default_form_class.
  Future versions of Simple Form will not generate `simple_form` class for the form
  element.
  See https://github.com/heartcombo/simple_form/pull/1109 for more information.

Please check [v3.0](https://github.com/heartcombo/simple_form/blob/v3.0/CHANGELOG.md) for previous changes.


================================================
FILE: CONTRIBUTING.md
================================================
## Contributing

1. If you have any questions about Simple Form, search the
[Wiki](https://github.com/heartcombo/simple_form/wiki)
or [Stack Overflow](http://stackoverflow.com/questions/tagged/simple_form).
Do not post questions here.

2. If you find a security bug, **DO NOT** submit an issue here.
Please send an e-mail to [heartcombo@googlegroups.com](mailto:heartcombo@googlegroups.com)
instead.

3. Do a small search on the issues tracker before submitting your issue to
see if it was already reported or fixed. In case it was not, create your report
including Rails and Simple Form versions. If you are getting exceptions, please
include the full backtrace.

That's it! The more information you give, the more easy it becomes for us to
track it down and fix it. Ideal scenario would be adding the issue to Simple Form
test suite or to a sample application.

Thanks!


================================================
FILE: Gemfile
================================================
source "https://rubygems.org"

gemspec

gem "activemodel", "~> 8.1.0"
gem "actionpack", "~> 8.1.0"
gem "railties", "~> 8.1.0"


================================================
FILE: ISSUE_TEMPLATE.md
================================================
## Precheck

- Do not use the issues tracker for help or support, try Stack Overflow.
- For bugs, do a quick search and make sure the bug has not yet been reported
- If you found a security bug, do not report it through GitHub. Please send an e-mail to heartcombo@googlegroups.com instead.
- Finally, be nice and have fun!

## Environment

- Ruby **[version]**
- Rails **[version]**
- Simple Form **[version]**

## Current behavior

Include code samples, errors, steps to reproduce the error and stacktraces if appropriate.

Will be even more helpful if you provide a sample application or a test case that reproduces the error.

## Expected behavior


================================================
FILE: MIT-LICENSE
================================================
Copyright (c) 2020-CURRENT Rafael França, Carlos Antonio da Silva
Copyright (c) 2009-2019 Plataformatec

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
![Simple Form Logo](https://raw.github.com/heartcombo/simple_form/main/simple_form.png)

[![Gem Version](https://badge.fury.io/rb/simple_form.svg)](https://badge.fury.io/rb/simple_form)

Rails forms made easy.

**Simple Form** aims to be as flexible as possible while helping you with powerful components to create
your forms. The basic goal of **Simple Form** is to not touch your way of defining the layout, letting
you find the better design for your eyes. Most of the DSL was inherited from Formtastic,
which we are thankful for and should make you feel right at home.

INFO: This README refers to **Simple Form** 5.0. For older releases, check the related branch for your version.

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
## Table of Contents

- [Installation](#installation)
  - [Bootstrap](#bootstrap-5)
  - [Zurb Foundation 5](#zurb-foundation-5)
  - [Country Select](#country-select)
- [Usage](#usage)
  - [Stripping away all wrapper divs](#stripping-away-all-wrapper-divs)
  - [Collections](#collections)
  - [Priority](#priority)
  - [Associations](#associations)
  - [Buttons](#buttons)
  - [Wrapping Rails Form Helpers](#wrapping-rails-form-helpers)
  - [Extra helpers](#extra-helpers)
    - [Simple Fields For](#simple-fields-for)
    - [Collection Radio Buttons](#collection-radio-buttons)
    - [Collection Check Boxes](#collection-check-boxes)
- [Available input types and defaults for each column type](#available-input-types-and-defaults-for-each-column-type)
- [Custom inputs](#custom-inputs)
- [Custom form builder](#custom-form-builder)
- [I18n](#i18n)
- [Configuration](#configuration)
  - [The wrappers API](#the-wrappers-api)
- [Custom Components](#custom-components)
- [HTML 5 Notice](#html-5-notice)
  - [Using non Active Record objects](#using-non-active-record-objects)
- [Information](#information)
  - [RDocs](#rdocs)
  - [Supported Ruby / Rails versions](#supported-ruby--rails-versions)
  - [Bug reports](#bug-reports)
- [Maintainers](#maintainers)
- [License](#license)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## Installation

Add it to your Gemfile:

```ruby
gem 'simple_form'
```

Run the following command to install it:

```console
bundle install
```

Run the generator:

```console
rails generate simple_form:install
```

### Bootstrap 5

**Simple Form** can be easily integrated with [Bootstrap 5](https://getbootstrap.com/).
Use the `bootstrap` option in the install generator, like this:

```console
rails generate simple_form:install --bootstrap
```

This will add an initializer that configures **Simple Form** wrappers for
Bootstrap 5's [form controls](https://getbootstrap.com/docs/5.0/forms/overview/).
You have to be sure that you added a copy of the [Bootstrap](https://getbootstrap.com/)
assets on your application.

For more information see the generator output, our
[example application code](https://github.com/heartcombo/simple_form-bootstrap).

### Zurb Foundation 5

To generate wrappers that are compatible with [Zurb Foundation 5](https://get.foundation/sites/docs-v5/), pass
the `foundation` option to the generator, like this:

```console
rails generate simple_form:install --foundation
```

Please note that the Foundation wrapper does not support the `:hint` option by default. In order to
enable hints, please uncomment the appropriate line in `config/initializers/simple_form_foundation.rb`.
You will need to provide your own CSS styles for hints.

Please see the [instructions on how to install Foundation in a Rails app](https://get.foundation/sites/docs-v5/applications.html).

### Country Select

If you want to use the country select, you will need the
[country_select gem](https://rubygems.org/gems/country_select), add it to your Gemfile:

```ruby
gem 'country_select'
```

If you don't want to use the gem you can easily override this behaviour by mapping the
country inputs to something else, with a line like this in your `simple_form.rb` initializer:

```ruby
config.input_mappings = { /country/ => :string }
```

## Usage

**Simple Form** was designed to be customized as you need to. Basically it's a stack of components that
are invoked to create a complete html input for you, which by default contains label, hints, errors
and the input itself. It does not aim to create a lot of different logic from the default Rails
form helpers, as they do a great job by themselves. Instead, **Simple Form** acts as a DSL and just
maps your input type (retrieved from the column definition in the database) to a specific helper method.

To start using **Simple Form** you just have to use the helper it provides:

```erb
<%= simple_form_for @user do |f| %>
  <%= f.input :username %>
  <%= f.input :password %>
  <%= f.button :submit %>
<% end %>
```

This will generate an entire form with labels for user name and password as well, and render errors
by default when you render the form with invalid data (after submitting for example).

You can overwrite the default label by passing it to the input method. You can also add a hint,
an error, or even a placeholder. For boolean inputs, you can add an inline label as well:

```erb
<%= simple_form_for @user do |f| %>
  <%= f.input :username, label: 'Your username please', error: 'Username is mandatory, please specify one' %>
  <%= f.input :password, hint: 'No special characters.' %>
  <%= f.input :email, placeholder: 'user@domain.com' %>
  <%= f.input :remember_me, inline_label: 'Yes, remember me' %>
  <%= f.button :submit %>
<% end %>
```

In some cases you may want to disable labels, hints or errors. Or you may want to configure the html
of any of them:

```erb
<%= simple_form_for @user do |f| %>
  <%= f.input :username, label_html: { class: 'my_class' }, hint_html: { class: 'hint_class' } %>
  <%= f.input :password, hint: false, error_html: { id: 'password_error' } %>
  <%= f.input :password_confirmation, label: false %>
  <%= f.button :submit %>
<% end %>
```

It is also possible to pass any html attribute straight to the input, by using the `:input_html`
option, for instance:

```erb
<%= simple_form_for @user do |f| %>
  <%= f.input :username, input_html: { class: 'special' } %>
  <%= f.input :password, input_html: { maxlength: 20 } %>
  <%= f.input :remember_me, input_html: { value: '1' } %>
  <%= f.button :submit %>
<% end %>
```

If you want to pass the same options to all inputs in the form (for example, a default class),
you can use the `:defaults` option in `simple_form_for`. Specific options in `input` call will
overwrite the defaults:

```erb
<%= simple_form_for @user, defaults: { input_html: { class: 'default_class' } } do |f| %>
  <%= f.input :username, input_html: { class: 'special' } %>
  <%= f.input :password, input_html: { maxlength: 20 } %>
  <%= f.input :remember_me, input_html: { value: '1' } %>
  <%= f.button :submit %>
<% end %>
```

Since **Simple Form** generates a wrapper div around your label and input by default, you can pass
any html attribute to that wrapper as well using the `:wrapper_html` option, like so:

```erb
<%= simple_form_for @user do |f| %>
  <%= f.input :username, wrapper_html: { class: 'username' } %>
  <%= f.input :password, wrapper_html: { id: 'password' } %>
  <%= f.input :remember_me, wrapper_html: { class: 'options' } %>
  <%= f.button :submit %>
<% end %>
```

Required fields are marked with an * prepended to their labels.

By default all inputs are required. When the form object includes `ActiveModel::Validations`
(which, for example, happens with Active Record models), fields are required only when there is `presence` validation.
Otherwise, **Simple Form** will mark fields as optional. For performance reasons, this
detection is skipped on validations that make use of conditional options, such as `:if` and `:unless`.

And of course, the `required` property of any input can be overwritten as needed:

```erb
<%= simple_form_for @user do |f| %>
  <%= f.input :name, required: false %>
  <%= f.input :username %>
  <%= f.input :password %>
  <%= f.button :submit %>
<% end %>
```

By default, **Simple Form** will look at the column type in the database and use an
appropriate input for the column. For example, a column created with type
`:text` in the database will use a `textarea` input by default. See the section
[Available input types and defaults for each column
type](https://github.com/heartcombo/simple_form#available-input-types-and-defaults-for-each-column-type)
for a complete list of defaults.

**Simple Form** also lets you overwrite the default input type it creates:

```erb
<%= simple_form_for @user do |f| %>
  <%= f.input :username %>
  <%= f.input :password %>
  <%= f.input :description, as: :text %>
  <%= f.input :accepts,     as: :radio_buttons %>
  <%= f.button :submit %>
<% end %>
```

So instead of a checkbox for the *accepts* attribute, you'll have a pair of radio buttons with yes/no
labels and a textarea instead of a text field for the description. You can also render boolean
attributes using `as: :select` to show a dropdown.

It is also possible to give the `:disabled` option to **Simple Form**, and it'll automatically mark
the wrapper as disabled with a CSS class, so you can style labels, hints and other components inside
the wrapper as well:

```erb
<%= simple_form_for @user do |f| %>
  <%= f.input :username, disabled: true, hint: 'You cannot change your username.' %>
  <%= f.button :submit %>
<% end %>
```

**Simple Form** inputs accept the same options as their corresponding input type helper in Rails:

```erb
<%= simple_form_for @user do |f| %>
  <%= f.input :date_of_birth, as: :date, start_year: Date.today.year - 90,
                              end_year: Date.today.year - 12, discard_day: true,
                              order: [:month, :year] %>
  <%= f.input :accepts, as: :boolean, checked_value: 'positive', unchecked_value: 'negative' %>
  <%= f.button :submit %>
<% end %>
```

By default, **Simple Form** generates a hidden field to handle the un-checked case for boolean fields.
Passing `unchecked_value: false` in the options for boolean fields will cause this hidden field to be omitted,
following the convention in Rails. You can also specify `include_hidden: false` to skip the hidden field:

```erb
<%= simple_form_for @user do |f| %>
  <%= f.input :just_the_checked_case, as: :boolean, include_hidden: false %>
  <%= f.button :submit %>
<% end %>
```

**Simple Form** also allows you to use label, hint, input_field, error and full_error helpers
(please take a look at the rdocs for each method for more info):

```erb
<%= simple_form_for @user do |f| %>
  <%= f.label :username %>
  <%= f.input_field :username %>
  <%= f.hint 'No special characters, please!' %>
  <%= f.error :username, id: 'user_name_error' %>
  <%= f.full_error :token %>
  <%= f.submit 'Save' %>
<% end %>
```

Any extra option passed to these methods will be rendered as html option.

### Stripping away all wrapper divs

**Simple Form** also allows you to strip away all the div wrappers around the `<input>` field that is
generated with the usual `f.input`.
The easiest way to achieve this is to use `f.input_field`.

Example:

```ruby
simple_form_for @user do |f|
  f.input_field :name
  f.input_field :remember_me, as: :boolean
end
```

```html
<form>
  ...
  <input class="string required" id="user_name" maxlength="255" name="user[name]" size="255" type="text">
  <input name="user[remember_me]" type="hidden" value="0">
  <label class="checkbox">
    <input class="boolean optional" id="user_published" name="user[remember_me]" type="checkbox" value="1">
  </label>
</form>
```

For check boxes and radio buttons you can remove the label changing `boolean_style` from default value `:nested` to `:inline`.

Example:

```ruby
simple_form_for @user do |f|
  f.input_field :name
  f.input_field :remember_me, as: :boolean, boolean_style: :inline
end
```

```html
<form>
  ...
  <input class="string required" id="user_name" maxlength="255" name="user[name]" size="255" type="text">
  <input name="user[remember_me]" type="hidden" value="0">
  <input class="boolean optional" id="user_remember_me" name="user[remember_me]" type="checkbox" value="1">
</form>
```

To view the actual RDocs for this, check them out here - https://rubydoc.info/github/heartcombo/simple_form/main/SimpleForm/FormBuilder:input_field

### Collections

And what if you want to create a select containing the age from 18 to 60 in your form? You can do it
overriding the `:collection` option:

```erb
<%= simple_form_for @user do |f| %>
  <%= f.input :user %>
  <%= f.input :age, collection: 18..60 %>
  <%= f.button :submit %>
<% end %>
```

Collections can be arrays or ranges, and when a `:collection` is given the `:select` input will be
rendered by default, so we don't need to pass the `as: :select` option. Other types of collection
are `:radio_buttons` and `:check_boxes`. Those are added by **Simple Form** to Rails set of form
helpers (read Extra Helpers section below for more information).

Collection inputs accept two other options beside collections:

* *label_method* => the label method to be applied to the collection to retrieve the label (use this
  instead of the `text_method` option in `collection_select`)

* *value_method* => the value method to be applied to the collection to retrieve the value

Those methods are useful to manipulate the given collection. Both of these options also accept
lambda/procs in case you want to calculate the value or label in a special way eg. custom
translation. You can also define a `to_label` method on your model as **Simple Form** will search for
and use `:to_label` as a `:label_method` first if it is found.

By default, **Simple Form** will use the first item from an array as the label and the second one as the value.
If you want to change this behavior you must make it explicit, like this:

```erb
<%= simple_form_for @user do |f| %>
  <%= f.input :gender, as: :radio_buttons, collection: [['0', 'female'], ['1', 'male']], label_method: :second, value_method: :first %>
<% end %>
```

All other options given are sent straight to the underlying Rails helper(s): [`collection_select`](https://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select), [`collection_check_boxes`](https://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_check_boxes), [`collection_radio_buttons`](https://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_radio_buttons). For example, you can pass `prompt` and `selected` as:

```ruby
f.input :age, collection: 18..60, prompt: "Select your age", selected: 21
```

It may also be useful to explicitly pass a value to the optional `:selected` like above, especially if passing a collection of nested objects.

It is also possible to create grouped collection selects, that will use the html *optgroup* tags, like this:

```ruby
f.input :country_id, collection: @continents, as: :grouped_select, group_method: :countries
```

Grouped collection inputs accept the same `:label_method` and `:value_method` options, which will be
used to retrieve label/value attributes for the `option` tags. Besides that, you can give:

* *group_method* => the method to be called on the given collection to generate the options for
  each group (required)

* *group_label_method* => the label method to be applied on the given collection to retrieve the label
  for the _optgroup_ (**Simple Form** will attempt to guess the best one the same way it does with
  `:label_method`)

### Priority

**Simple Form** also supports `:time_zone` and `:country`. When using such helpers, you can give
`:priority` as an option to select which time zones and/or countries should be given higher priority:

```ruby
f.input :residence_country, priority: [ "Brazil" ]
f.input :time_zone, priority: /US/
```

Those values can also be configured with a default value to be used on the site through the
`SimpleForm.country_priority` and `SimpleForm.time_zone_priority` helpers.

Note: While using `country_select` if you want to restrict to only a subset of countries for a specific
drop down then you may use the `:collection` option:

```ruby
f.input :shipping_country, priority: [ "Brazil" ], collection: [ "Australia", "Brazil", "New Zealand"]
```

### Associations

To deal with associations, **Simple Form** can generate select inputs, a series of radios buttons or checkboxes.
Lets see how it works: imagine you have a user model that belongs to a company and `has_and_belongs_to_many`
roles. The structure would be something like:

```ruby
class User < ActiveRecord::Base
  belongs_to :company
  has_and_belongs_to_many :roles
end

class Company < ActiveRecord::Base
  has_many :users
end

class Role < ActiveRecord::Base
  has_and_belongs_to_many :users
end
```

Now we have the user form:

```erb
<%= simple_form_for @user do |f| %>
  <%= f.input :name %>
  <%= f.association :company %>
  <%= f.association :roles %>
  <%= f.button :submit %>
<% end %>
```

Simple enough, right? This is going to render a `:select` input for choosing the `:company`, and another
`:select` input with `:multiple` option for the `:roles`. You can, of course, change it to use radio
buttons and checkboxes as well:

```ruby
f.association :company, as: :radio_buttons
f.association :roles,   as: :check_boxes
```

The association helper just invokes `input` under the hood, so all options available to `:select`,
`:radio_buttons` and `:check_boxes` are also available to association. Additionally, you can specify
the collection by hand, all together with the prompt:

```ruby
f.association :company, collection: Company.active.order(:name), prompt: "Choose a Company"
```

In case you want to declare different labels and values:

```ruby
f.association :company, label_method: :company_name, value_method: :id, include_blank: false
```

Please note that the association helper is currently only tested with Active Record. It currently
does not work well with Mongoid and depending on the ORM you're using your mileage may vary.

### Buttons

All web forms need buttons, right? **Simple Form** wraps them in the DSL, acting like a proxy:

```erb
<%= simple_form_for @user do |f| %>
  <%= f.input :name %>
  <%= f.button :submit %>
<% end %>
```

The above will simply call submit. You choose to use it or not, it's just a question of taste.

The button method also accepts optional parameters, that are delegated to the underlying submit call:

```erb
<%= f.button :submit, "Custom Button Text", class: "my-button" %>
```

To create a `<button>` element, use the following syntax:

```erb
<%= f.button :button, "Custom Button Text" %>

<%= f.button :button do %>
  Custom Button Text
<% end %>
```

### Wrapping Rails Form Helpers

Say you wanted to use a rails form helper but still wrap it in **Simple Form** goodness? You can, by
calling input with a block like so:

```erb
<%= f.input :role do %>
  <%= f.select :role, Role.all.map { |r| [r.name, r.id, { class: r.company.id }] }, include_blank: true %>
<% end %>
```

In the above example, we're taking advantage of Rails 3's select method that allows us to pass in a
hash of additional attributes for each option.

### Extra helpers

**Simple Form** also comes with some extra helpers you can use inside rails default forms without relying
on `simple_form_for` helper. They are listed below.

#### Simple Fields For

Wrapper to use **Simple Form** inside a default rails form. It works in the same way that the `fields_for`
Rails helper, but change the builder to use the `SimpleForm::FormBuilder`.

```ruby
form_for @user do |f|
  f.simple_fields_for :posts do |posts_form|
    # Here you have all simple_form methods available
    posts_form.input :title
  end
end
```

#### Collection Radio Buttons

Creates a collection of radio inputs with labels associated (same API as `collection_select`):

```ruby
form_for @user do |f|
  f.collection_radio_buttons :options, [[true, 'Yes'], [false, 'No']], :first, :last
end
```

```html
<input id="user_options_true" name="user[options]" type="radio" value="true" />
<label class="collection_radio_buttons" for="user_options_true">Yes</label>
<input id="user_options_false" name="user[options]" type="radio" value="false" />
<label class="collection_radio_buttons" for="user_options_false">No</label>
```

#### Collection Check Boxes

Creates a collection of checkboxes with labels associated (same API as `collection_select`):

```ruby
form_for @user do |f|
  f.collection_check_boxes :options, [[true, 'Yes'], [false, 'No']], :first, :last
end
```

```html
<input name="user[options][]" type="hidden" value="" />
<input id="user_options_true" name="user[options][]" type="checkbox" value="true" />
<label class="collection_check_box" for="user_options_true">Yes</label>
<input name="user[options][]" type="hidden" value="" />
<input id="user_options_false" name="user[options][]" type="checkbox" value="false" />
<label class="collection_check_box" for="user_options_false">No</label>
```

To use this with associations in your model, you can do the following:

```ruby
form_for @user do |f|
  f.collection_check_boxes :role_ids, Role.all, :id, :name # using :roles here is not going to work.
end
```

To add a CSS class to the label item, you can use the `item_label_class` option:

```ruby
f.collection_check_boxes :role_ids, Role.all, :id, :name, item_label_class: 'my-custom-class'
```

## Available input types and defaults for each column type

The following table shows the html element you will get for each attribute
according to its database definition. These defaults can be changed by
specifying the helper method in the column `Mapping` as the `as:` option.

Mapping         | Generated HTML Element               | Database Column Type
--------------- |--------------------------------------|---------------------
`boolean`       | `input[type=checkbox]`               | `boolean`
`string`        | `input[type=text]`                   | `string`
`citext`        | `input[type=text]`                   | `citext`
`email`         | `input[type=email]`                  | `string` with `name =~ /email/`
`url`           | `input[type=url]`                    | `string` with `name =~ /url/`
`tel`           | `input[type=tel]`                    | `string` with `name =~ /phone/`
`password`      | `input[type=password]`               | `string` with `name =~ /password/`
`search`        | `input[type=search]`                 | -
`uuid`          | `input[type=text]`                   | `uuid`
`color`         | `input[type=color]`                  | `string`
`text`          | `textarea`                           | `text`
`hstore`        | `textarea`                           | `hstore`
`json`          | `textarea`                           | `json`
`jsonb`         | `textarea`                           | `jsonb`
`file`          | `input[type=file]`                   | `string` responding to file methods
`hidden`        | `input[type=hidden]`                 | -
`integer`       | `input[type=number]`                 | `integer`
`float`         | `input[type=number]`                 | `float`
`decimal`       | `input[type=number]`                 | `decimal`
`range`         | `input[type=range]`                  | -
`datetime`      | `datetime select`                    | `datetime/timestamp`
`date`          | `date select`                        | `date`
`time`          | `time select`                        | `time`
`weekday`       | `select` (weekdays as options)       | -
`select`        | `select`                             | `belongs_to`/`has_many`/`has_and_belongs_to_many` associations
`radio_buttons` | collection of `input[type=radio]`    | `belongs_to` associations
`check_boxes`   | collection of `input[type=checkbox]` | `has_many`/`has_and_belongs_to_many` associations
`country`       | `select` (countries as options)      | `string` with `name =~ /country/`
`time_zone`     | `select` (timezones as options)      | `string` with `name =~ /time_zone/`
`rich_text_area`| `trix-editor`                        | -

## Custom inputs

It is very easy to add custom inputs to **Simple Form**. For instance, if you want to add a custom input
that extends the string one, you just need to add this file:

```ruby
# app/inputs/currency_input.rb
class CurrencyInput < SimpleForm::Inputs::Base
  def input(wrapper_options)
    merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)

    "$ #{@builder.text_field(attribute_name, merged_input_options)}".html_safe
  end
end
```

And use it in your views:

```ruby
f.input :money, as: :currency
```
Note, you may have to create the `app/inputs/` directory and restart your webserver.

You can also redefine existing **Simple Form** inputs by creating a new class with the same name. For
instance, if you want to wrap date/time/datetime in a div, you can do:

```ruby
# app/inputs/date_time_input.rb
class DateTimeInput < SimpleForm::Inputs::DateTimeInput
  def input(wrapper_options)
    template.content_tag(:div, super)
  end
end
```

Or if you want to add a class to all the select fields you can do:

```ruby
# app/inputs/collection_select_input.rb
class CollectionSelectInput < SimpleForm::Inputs::CollectionSelectInput
  def input_html_classes
    super.push('chosen')
  end
end
```

If needed, you can namespace your custom inputs in a module and tell **Simple Form** to look for
their definitions in this module. This can avoid conflicts with other form libraries (like Formtastic) that look up
the global context to find inputs definition too.

```ruby
# app/inputs/custom_inputs/numeric_input
module CustomInputs
  class NumericInput < SimpleForm::Inputs::NumericInput
    def input_html_classes
      super.push('no-spinner')
    end
  end
end
```

And in the **SimpleForm** initializer :

```ruby
# config/simple_form.rb
config.custom_inputs_namespaces << "CustomInputs"
```

## Custom form builder

You can create a custom form builder that uses **Simple Form**.

Create a helper method that calls `simple_form_for` with a custom builder:

```ruby
def custom_form_for(object, *args, &block)
  options = args.extract_options!
  simple_form_for(object, *(args << options.merge(builder: CustomFormBuilder)), &block)
end
```

Create a form builder class that inherits from `SimpleForm::FormBuilder`.

```ruby
class CustomFormBuilder < SimpleForm::FormBuilder
  def input(attribute_name, options = {}, &block)
    super(attribute_name, options.merge(label: false), &block)
  end
end
```

## I18n

**Simple Form** uses all power of I18n API to lookup labels, hints, prompts and placeholders. To customize your
forms you can create a locale file like this:

```yaml
en:
  simple_form:
    labels:
      user:
        username: 'User name'
        password: 'Password'
    hints:
      user:
        username: 'User name to sign in.'
        password: 'No special characters, please.'
    placeholders:
      user:
        username: 'Your username'
        password: '****'
    include_blanks:
      user:
        age: 'Rather not say'
    prompts:
      user:
        role: 'Select your role'
```

And your forms will use this information to render the components for you.

**Simple Form** also lets you be more specific, separating lookups through actions.
Let's say you want a different label for new and edit actions, the locale file would
be something like:

```yaml
en:
  simple_form:
    labels:
      user:
        username: 'User name'
        password: 'Password'
        edit:
          username: 'Change user name'
          password: 'Change password'
```

This way **Simple Form** will figure out the right translation for you, based on the action being
rendered. And to be a little bit DRYer with your locale file, you can specify defaults for all
models under the 'defaults' key:

```yaml
en:
  simple_form:
    labels:
      defaults:
        username: 'User name'
        password: 'Password'
        new:
          username: 'Choose a user name'
    hints:
      defaults:
        username: 'User name to sign in.'
        password: 'No special characters, please.'
    placeholders:
      defaults:
        username: 'Your username'
        password: '****'
```

**Simple Form** will always look for a default attribute translation under the "defaults" key if no
specific is found inside the model key.

In addition, **Simple Form** will fallback to default `human_attribute_name` from Rails when no other
translation is found for labels. Finally, you can also overwrite any label, hint or placeholder
inside your view, just by passing the option manually. This way the I18n lookup will be skipped.

For `:prompt` and `:include_blank` the I18n lookup is optional and to enable it is necessary to pass
`:translate` as value.

```ruby
f.input :role, prompt: :translate
```

**Simple Form** also has support for translating options in collection helpers. For instance, given a
User with a `:role` attribute, you might want to create a select box showing translated labels
that would post either `:admin` or `:editor` as value. With **Simple Form** you could create an input
like this:

```ruby
f.input :role, collection: [:admin, :editor]
```

And **Simple Form** will try a lookup like this in your locale file, to find the right labels to show:

```yaml
en:
  simple_form:
    options:
      user:
        role:
          admin: 'Administrator'
          editor: 'Editor'
```

You can also use the `defaults` key as you would do with labels, hints and placeholders. It is
important to notice that **Simple Form** will only do the lookup for options if you give a collection
composed of symbols only. This is to avoid constant lookups to I18n.

It's also possible to translate buttons, using Rails' built-in I18n support:

```yaml
en:
  helpers:
    submit:
      user:
        create: "Add %{model}"
        update: "Save Changes"
```

There are other options that can be configured through I18n API, such as required text and boolean.
Be sure to check our locale file or the one copied to your application after you run
`rails generate simple_form:install`.

It should be noted that translations for labels, hints and placeholders for a namespaced model, e.g.
`Admin::User`, should be placed under `admin_user`, not under `admin/user`. This is different from
how translations for namespaced model and attribute names are defined:

```yaml
en:
  activerecord:
    models:
        admin/user: User
    attributes:
        admin/user:
            name: Name
```

They should be placed under `admin/user`. Form labels, hints and placeholders for those attributes,
though, should be placed under `admin_user`:

```yaml
en:
  simple_form:
    labels:
        admin_user:
            name: Name
```

This difference exists because **Simple Form** relies on `object_name` provided by Rails'
FormBuilder to determine the translation path for a given object instead of `i18n_key` from the
object itself. Thus, similarly, if a form for an `Admin::User` object is defined by calling
`simple_form_for @admin_user, as: :some_user`, **Simple Form** will look for translations
under `some_user` instead of `admin_user`.

When translating `simple_fields_for` attributes be sure to use the same name you pass to it, e.g. `simple_fields_for :posts` should be placed under `posts` not `post`:

```yaml
en:
  simple_form:
    labels:
      posts:
        title: 'Post title'
    hints:
      posts:
        title: 'A good title'
    placeholders:
      posts:
        title: 'Once upon a time...'
```

## Configuration

**Simple Form** has several configuration options. You can read and change them in the initializer
created by **Simple Form**, so if you haven't executed the command below yet, please do:

`rails generate simple_form:install`

### The wrappers API

With **Simple Form** you can configure how your components will be rendered using the wrappers API.
The syntax looks like this:

```ruby
config.wrappers tag: :div, class: :input,
                error_class: :field_with_errors,
                valid_class: :field_without_errors do |b|

  # Form extensions
  b.use :html5
  b.optional :pattern
  b.use :maxlength
  b.use :placeholder
  b.use :readonly

  # Form components
  b.use :label_input
  b.use :hint,  wrap_with: { tag: :span, class: :hint }
  b.use :error, wrap_with: { tag: :span, class: :error }
end
```

The _Form components_ will generate the form tags like labels, inputs, hints or errors contents.
The available components are:

```ruby
:label         # The <label> tag alone
:input         # The <input> tag alone
:label_input   # The <label> and the <input> tags
:hint          # The hint for the input
:error         # The error for the input
```

The _Form extensions_ are used to generate some attributes or perform some lookups on the model to
add extra information to your components.

You can create new _Form components_ using the wrappers API as in the following example:

```ruby
config.wrappers do |b|
  b.use :placeholder
  b.use :label_input
  b.wrapper tag: :div, class: 'separator' do |component|
    component.use :hint,  wrap_with: { tag: :span, class: :hint }
    component.use :error, wrap_with: { tag: :span, class: :error }
  end
end
```

this will wrap the hint and error components within a `div` tag using the class `'separator'`.

You can customize _Form components_ passing options to them:

```ruby
config.wrappers do |b|
  b.use :label_input, class: 'label-input-class', error_class: 'is-invalid', valid_class: 'is-valid'
end
```

This sets the input and label classes to `'label-input-class'` and will set the class `'is-invalid'`
if the input has errors and `'is-valid'` if the input is valid.

If you want to customize the custom _Form components_ on demand you can give it a name like this:

```ruby
config.wrappers do |b|
  b.use :placeholder
  b.use :label_input
  b.wrapper :my_wrapper, tag: :div, class: 'separator', html: { id: 'my_wrapper_id' } do |component|
    component.use :hint,  wrap_with: { tag: :span, class: :hint }
    component.use :error, wrap_with: { tag: :span, class: :error }
  end
end
```

and now you can pass options to your `input` calls to customize the `:my_wrapper` _Form component_.

```ruby
# Completely turns off the custom wrapper
f.input :name, my_wrapper: false

# Configure the html
f.input :name, my_wrapper_html: { id: 'special_id' }

# Configure the tag
f.input :name, my_wrapper_tag: :p
```

You can also define more than one wrapper and pick one to render in a specific form or input.
To define another wrapper you have to give it a name, as the follow:

```ruby
config.wrappers :small do |b|
  b.use :placeholder
  b.use :label_input
end
```

and use it in this way:

```ruby
# Specifying to whole form
simple_form_for @user, wrapper: :small do |f|
  f.input :name
end

# Specifying to one input
simple_form_for @user do |f|
  f.input :name, wrapper: :small
end
```

**Simple Form** also allows you to use optional elements. For instance, let's suppose you want to use
hints or placeholders, but you don't want them to be generated automatically. You can set their
default values to `false` or use the `optional` method. Is preferable to use the `optional` syntax:

```ruby
config.wrappers placeholder: false do |b|
  b.use :placeholder
  b.use :label_input
  b.wrapper tag: :div, class: 'separator' do |component|
    component.optional :hint, wrap_with: { tag: :span, class: :hint }
    component.use :error, wrap_with: { tag: :span, class: :error }
  end
end
```

By setting it as `optional`, a hint will only be generated when `hint: true` is explicitly used.
The same for placeholder.

It is also possible to give the option `:unless_blank` to the wrapper if you want to render it only
when the content is present.

```ruby
  b.wrapper tag: :span, class: 'hint', unless_blank: true do |component|
    component.optional :hint
  end
```

## Custom Components

When you use custom wrappers, you might also be looking for a way to add custom components to your
wrapper. The default components are:

```ruby
:label         # The <label> tag alone
:input         # The <input> tag alone
:label_input   # The <label> and the <input> tags
:hint          # The hint for the input
:error         # The error for the input
```

A custom component might be interesting for you if your views look something like this:

```erb
<%= simple_form_for @blog do |f| %>
  <div class="row">
    <div class="span1 number">
      1
    </div>
    <div class="span8">
      <%= f.input :title %>
    </div>
  </div>
  <div class="row">
    <div class="span1 number">
      2
    </div>
    <div class="span8">
      <%= f.input :body, as: :text %>
    </div>
  </div>
<% end %>
```

A cleaner method to create your views would be:

```erb
<%= simple_form_for @blog, wrapper: :with_numbers do |f| %>
  <%= f.input :title, number: 1 %>
  <%= f.input :body, as: :text, number: 2 %>
<% end %>
```

To use the number option on the input, first, tells to Simple Form the place where the components
will be:

``` ruby
# config/initializers/simple_form.rb
Dir[Rails.root.join('lib/components/**/*.rb')].each { |f| require f }
```

Create a new component within the path specified above:

```ruby
# lib/components/numbers_component.rb
module NumbersComponent
  # To avoid deprecation warning, you need to make the wrapper_options explicit
  # even when they won't be used.
  def number(wrapper_options = nil)
    @number ||= begin
      options[:number].to_s.html_safe if options[:number].present?
    end
  end
end

SimpleForm.include_component(NumbersComponent)
```

Finally, add a new wrapper to the config/initializers/simple_form.rb file:

```ruby
config.wrappers :with_numbers, tag: 'div', class: 'row', error_class: 'error' do |b|
  b.use :html5
  b.use :number, wrap_with: { tag: 'div', class: 'span1 number' }
  b.wrapper tag: 'div', class: 'span8' do |ba|
    ba.use :placeholder
    ba.use :label
    ba.use :input
    ba.use :error, wrap_with: { tag: 'span', class: 'help-inline' }
    ba.use :hint,  wrap_with: { tag: 'p', class: 'help-block' }
  end
end
```

## HTML 5 Notice

By default, **Simple Form** will generate input field types and attributes that are supported in HTML5,
but are considered invalid HTML for older document types such as HTML4 or XHTML1.0. The HTML5
extensions include the new field types such as email, number, search, url, tel, and the new
attributes such as required, autofocus, maxlength, min, max, step.

Most browsers will not care, but some of the newer ones - in particular Chrome 10+ - use the
required attribute to force a value into an input and will prevent form submission without it.
Depending on the design of the application this may or may not be desired. In many cases it can
break existing UI's.

It is possible to disable all HTML 5 extensions in **Simple Form** by removing the `html5`
component from the wrapper used to render the inputs.

For example, change:

```ruby
config.wrappers tag: :div do |b|
  b.use :html5

  b.use :label_input
end
```

To:

```ruby
config.wrappers tag: :div do |b|
  b.use :label_input
end
```

If you want to have all other HTML 5 features, such as the new field types, you can disable only
the browser validation:

```ruby
SimpleForm.browser_validations = false # default is true
```

This option adds a new `novalidate` property to the form, instructing it to skip all HTML 5
validation. The inputs will still be generated with the required and other attributes, that might
help you to use some generic javascript validation.

You can also add `novalidate` to a specific form by setting the option on the form itself:

```erb
<%= simple_form_for(resource, html: { novalidate: true }) do |form| %>
```

Please notice that none of the configurations above will disable the `placeholder` component,
which is an HTML 5 feature. We believe most of the newest browsers are handling this attribute
just fine, and if they aren't, any plugin you use would take care of applying the placeholder.
In any case, you can disable it if you really want to, by removing the placeholder component
from the components list in the **Simple Form** configuration file.

HTML 5 date / time inputs are not generated by **Simple Form** by default, so using `date`,
`time` or `datetime` will all generate select boxes using normal Rails helpers. We believe
browsers are not totally ready for these yet, but you can easily opt-in on a per-input basis
by passing the html5 option:

```erb
<%= f.input :expires_at, as: :date, html5: true %>
```

## Using non Active Record objects

There are few ways to build forms with objects that don't inherit from Active Record, as
follows:

You can include the module `ActiveModel::Model`.

```ruby
class User
  include ActiveModel::Model

  attr_accessor :id, :name
end
```

If you are using Presenters or Decorators that inherit from `SimpleDelegator` you can delegate
it to the model.

```ruby
class UserPresenter < SimpleDelegator
  # Without that, Simple Form will consider the user model as the object.
  def to_model
    self
  end
end
```

You can define all methods required by the helpers.

```ruby
class User
  extend ActiveModel::Naming

  attr_accessor :id, :name

  def to_model
    self
  end

  def to_key
    id
  end

  def persisted?
    false
  end
end
```

To have SimpleForm infer the attributes' types, you can provide
`#has_attribute?` and `#type_for_attribute` methods.
The later should return an object that responds to `#type`
with the attribute type. This is useful for generating
the correct input types (eg: checkboxes for booleans).

```ruby
class User < Struct.new(:id, :name, :age, :registered)
  def to_model
    self
  end

  def model_name
    OpenStruct.new(param_key: "user")
  end

  def to_key
    id
  end

  def persisted?
    id.present?
  end

  def has_attribute?(attr_name)
    %w(id name age registered).include?(attr_name.to_s)
  end

  def type_for_attribute(attr_name)
    case attr_name.to_s
      when "id" then OpenStruct.new(type: :integer)
      when "name" then OpenStruct.new(type: :string)
      when "age" then OpenStruct.new(type: :integer)
      when "registered" then OpenStruct.new(type: :boolean)
    end
  end
end
```

If your object doesn't implement those methods, you must make explicit it when you are
building the form

```ruby
class User
  attr_accessor :id, :name

  # The only method required to use the f.submit helper.
  def persisted?
    false
  end
end
```

```erb
<%= simple_form_for(@user, as: :user, method: :post, url: users_path) do |f| %>
  <%= f.input :name %>
  <%= f.submit 'New user' %>
<% end %>
```

## Information

### RDocs

You can view the **Simple Form** documentation in RDoc format here:

https://rubydoc.info/github/heartcombo/simple_form/main/frames

### Supported Ruby / Rails versions

We intend to maintain support for all Ruby / Rails versions that haven't reached end-of-life.

For more information about specific versions please check [Ruby](https://www.ruby-lang.org/en/downloads/branches/)
and [Rails](https://guides.rubyonrails.org/maintenance_policy.html) maintenance policies, and our test matrix.

### Bug reports

If you discover any bugs, feel free to create an issue on GitHub. Please add as much information as
possible to help us in fixing the potential bug. We also encourage you to help even more by forking and
sending us a pull request.

https://github.com/heartcombo/simple_form/issues

If you have discovered a security related bug, please do NOT use the GitHub issue tracker. Send an e-mail to heartcombo.oss@gmail.com.

## License

MIT License.
Copyright 2020-CURRENT Rafael França, Carlos Antonio da Silva.
Copyright 2009-2019 Plataformatec.

The Simple Form logo is licensed under [Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License](https://creativecommons.org/licenses/by-nc-nd/4.0/).


================================================
FILE: Rakefile
================================================
# encoding: UTF-8

require 'bundler/gem_tasks'

require 'rake/testtask'

desc 'Default: run unit tests.'
task default: :test

desc 'Test the simple_form plugin.'
Rake::TestTask.new(:test) do |t|
  t.libs << 'lib'
  t.libs << 'test'
  t.pattern = 'test/**/*_test.rb'
  t.verbose = true
end

begin
  require 'rdoc/task'
  desc 'Generate documentation for the simple_form plugin.'
  RDoc::Task.new(:rdoc) do |rdoc|
    rdoc.rdoc_dir = 'rdoc'
    rdoc.title    = 'SimpleForm'
    rdoc.options << '--line-numbers'
    rdoc.rdoc_files.include('README.md')
    rdoc.rdoc_files.include('lib/**/*.rb')
  end
rescue LoadError
  puts 'RDoc::Task is not supported on this platform'
end


================================================
FILE: bin/test
================================================
#!/usr/bin/env ruby
$: << File.expand_path(File.expand_path('../../test', __FILE__))

require 'bundler/setup'
require 'rails/test_unit/runner'
require 'rails/test_unit/reporter'

Rails::TestUnitReporter.executable = 'bin/test'

Rails::TestUnit::Runner.parse_options(ARGV)
Rails::TestUnit::Runner.run(ARGV)


================================================
FILE: gemfiles/Gemfile-rails-7-0
================================================
source "https://rubygems.org"

gemspec path: ".."

gem "activemodel", "~> 7.0.0"
gem "actionpack", "~> 7.0.0"
gem "railties", "~> 7.0.0"


================================================
FILE: gemfiles/Gemfile-rails-7-1
================================================
source "https://rubygems.org"

gemspec path: ".."

gem "activemodel", "~> 7.1.0"
gem "actionpack", "~> 7.1.0"
gem "railties", "~> 7.1.0"


================================================
FILE: gemfiles/Gemfile-rails-7-2
================================================
source "https://rubygems.org"

gemspec path: ".."

gem "activemodel", "~> 7.2.0"
gem "actionpack", "~> 7.2.0"
gem "railties", "~> 7.2.0"


================================================
FILE: gemfiles/Gemfile-rails-8-0
================================================
source "https://rubygems.org"

gemspec path: ".."

gem "activemodel", "~> 8.0.0"
gem "actionpack", "~> 8.0.0"
gem "railties", "~> 8.0.0"


================================================
FILE: gemfiles/Gemfile-rails-main
================================================
source "https://rubygems.org"

gemspec path: ".."

gem "railties", github: "rails/rails", branch: "main"
gem "activemodel", github: "rails/rails", branch: "main"
gem "actionpack", github: "rails/rails", branch: "main"
gem "tzinfo"


================================================
FILE: lib/generators/simple_form/USAGE
================================================
To copy a SimpleForm initializer to your Rails App, with some configuration values, just do:

    rails generate simple_form:install


================================================
FILE: lib/generators/simple_form/install_generator.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Generators
    class InstallGenerator < Rails::Generators::Base
      desc "Copy SimpleForm default files"
      source_root File.expand_path('../templates', __FILE__)
      class_option :template_engine, desc: 'Template engine to be invoked (erb, haml or slim).'
      class_option :bootstrap, type: :boolean, desc: 'Add the Bootstrap 5 wrappers to the SimpleForm initializer.'
      class_option :foundation, type: :boolean, desc: 'Add the Zurb Foundation 5 wrappers to the SimpleForm initializer.'

      def info_bootstrap
        return if options.bootstrap? || options.foundation?
        puts "SimpleForm supports Bootstrap 5 and Zurb Foundation 5. If you want "\
          "a configuration that is compatible with one of these frameworks, then please " \
          "re-run this generator with --bootstrap or --foundation as an option."
      end

      def copy_config
        template "config/initializers/simple_form.rb"

        if options[:bootstrap]
          template "config/initializers/simple_form_bootstrap.rb"
        elsif options[:foundation]
          template "config/initializers/simple_form_foundation.rb"
        end

        directory 'config/locales'
      end

      def copy_scaffold_template
        engine = options[:template_engine]
        copy_file "_form.html.#{engine}", "lib/templates/#{engine}/scaffold/_form.html.#{engine}"
      end

      def show_readme
        if behavior == :invoke && options.bootstrap?
          readme "README"
        end
      end
    end
  end
end


================================================
FILE: lib/generators/simple_form/templates/README
================================================
===============================================================================

  Be sure to have a copy of the Bootstrap stylesheet available on your
  application, you can get it on http://getbootstrap.com/.

  For usage examples and documentation, see the example app:

    https://github.com/heartcombo/simple_form-bootstrap

===============================================================================


================================================
FILE: lib/generators/simple_form/templates/_form.html.erb
================================================
<%# frozen_string_literal: true %>
<%%= simple_form_for(@<%= singular_table_name %>) do |f| %>
  <%%= f.error_notification %>
  <%%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>

  <div class="form-inputs">
  <%- attributes.each do |attribute| -%>
    <%%= f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> %>
  <%- end -%>
  </div>

  <div class="form-actions">
    <%%= f.button :submit %>
  </div>
<%% end %>


================================================
FILE: lib/generators/simple_form/templates/_form.html.haml
================================================
-# frozen_string_literal: true
= simple_form_for(@<%= singular_table_name %>) do |f|
  = f.error_notification
  = f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present?

  .form-inputs
  <%- attributes.each do |attribute| -%>
    = f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %>
  <%- end -%>

  .form-actions
    = f.button :submit


================================================
FILE: lib/generators/simple_form/templates/_form.html.slim
================================================
= simple_form_for(@<%= singular_table_name %>) do |f|
  = f.error_notification
  = f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present?

  .form-inputs
<%- attributes.each do |attribute| -%>
    = f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %>
<%- end -%>

  .form-actions
    = f.button :submit


================================================
FILE: lib/generators/simple_form/templates/config/initializers/simple_form.rb
================================================
# frozen_string_literal: true
#
# Uncomment this and change the path if necessary to include your own
# components.
# See https://github.com/heartcombo/simple_form#custom-components to know
# more about custom components.
# Dir[Rails.root.join('lib/components/**/*.rb')].each { |f| require f }
#
# Use this setup block to configure all options available in SimpleForm.
SimpleForm.setup do |config|
  # Wrappers are used by the form builder to generate a
  # complete input. You can remove any component from the
  # wrapper, change the order or even add your own to the
  # stack. The options given below are used to wrap the
  # whole input.
  config.wrappers :default, class: :input,
    hint_class: :field_with_hint, error_class: :field_with_errors, valid_class: :field_without_errors do |b|
    ## Extensions enabled by default
    # Any of these extensions can be disabled for a
    # given input by passing: `f.input EXTENSION_NAME => false`.
    # You can make any of these extensions optional by
    # renaming `b.use` to `b.optional`.

    # Determines whether to use HTML5 (:email, :url, ...)
    # and required attributes
    b.use :html5

    # Calculates placeholders automatically from I18n
    # You can also pass a string as f.input placeholder: "Placeholder"
    b.use :placeholder

    ## Optional extensions
    # They are disabled unless you pass `f.input EXTENSION_NAME => true`
    # to the input. If so, they will retrieve the values from the model
    # if any exists. If you want to enable any of those
    # extensions by default, you can change `b.optional` to `b.use`.

    # Calculates maxlength from length validations for string inputs
    # and/or database column lengths
    b.optional :maxlength

    # Calculate minlength from length validations for string inputs
    b.optional :minlength

    # Calculates pattern from format validations for string inputs
    b.optional :pattern

    # Calculates min and max from length validations for numeric inputs
    b.optional :min_max

    # Calculates readonly automatically from readonly attributes
    b.optional :readonly

    ## Inputs
    # b.use :input, class: 'input', error_class: 'is-invalid', valid_class: 'is-valid'
    b.use :label_input
    b.use :hint,  wrap_with: { tag: :span, class: :hint }
    b.use :error, wrap_with: { tag: :span, class: :error }

    ## full_messages_for
    # If you want to display the full error message for the attribute, you can
    # use the component :full_error, like:
    #
    # b.use :full_error, wrap_with: { tag: :span, class: :error }
  end

  # The default wrapper to be used by the FormBuilder.
  config.default_wrapper = :default

  # Define the way to render check boxes / radio buttons with labels.
  # Defaults to :nested for bootstrap config.
  #   inline: input + label
  #   nested: label > input
  config.boolean_style = :nested

  # Default class for buttons
  config.button_class = 'btn'

  # Method used to tidy up errors. Specify any Rails Array method.
  # :first lists the first message for each field.
  # Use :to_sentence to list all errors for each field.
  # config.error_method = :first

  # Default tag used for error notification helper.
  config.error_notification_tag = :div

  # CSS class to add for error notification helper.
  config.error_notification_class = 'error_notification'

  # Series of attempts to detect a default label method for collection.
  # config.collection_label_methods = [ :to_label, :name, :title, :to_s ]

  # Series of attempts to detect a default value method for collection.
  # config.collection_value_methods = [ :id, :to_s ]

  # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none.
  # config.collection_wrapper_tag = nil

  # You can define the class to use on all collection wrappers. Defaulting to none.
  # config.collection_wrapper_class = nil

  # You can wrap each item in a collection of radio/check boxes with a tag,
  # defaulting to :span.
  # config.item_wrapper_tag = :span

  # You can define a class to use in all item wrappers. Defaulting to none.
  # config.item_wrapper_class = nil

  # How the label text should be generated altogether with the required text.
  # config.label_text = lambda { |label, required, explicit_label| "#{required} #{label}" }

  # You can define the class to use on all labels. Default is nil.
  # config.label_class = nil

  # You can define the default class to be used on forms. Can be overridden
  # with `html: { :class }`. Defaulting to none.
  # config.default_form_class = nil

  # You can define which elements should obtain additional classes
  # config.generate_additional_classes_for = [:wrapper, :label, :input]

  # Whether attributes are required by default (or not). Default is true.
  # config.required_by_default = true

  # Tell browsers whether to use the native HTML5 validations (novalidate form option).
  # These validations are enabled in SimpleForm's internal config but disabled by default
  # in this configuration, which is recommended due to some quirks from different browsers.
  # To stop SimpleForm from generating the novalidate option, enabling the HTML5 validations,
  # change this configuration to true.
  config.browser_validations = false

  # Custom mappings for input types. This should be a hash containing a regexp
  # to match as key, and the input type that will be used when the field name
  # matches the regexp as value.
  # config.input_mappings = { /count/ => :integer }

  # Custom wrappers for input types. This should be a hash containing an input
  # type as key and the wrapper that will be used for all inputs with specified type.
  # config.wrapper_mappings = { string: :prepend }

  # Namespaces where SimpleForm should look for custom input classes that
  # override default inputs.
  # config.custom_inputs_namespaces << "CustomInputs"

  # Default priority for time_zone inputs.
  # config.time_zone_priority = nil

  # Default priority for country inputs.
  # config.country_priority = nil

  # When false, do not use translations for labels.
  # config.translate_labels = true

  # Automatically discover new inputs in Rails' autoload path.
  # config.inputs_discovery = true

  # Cache SimpleForm inputs discovery
  # config.cache_discovery = !Rails.env.development?

  # Default class for inputs
  # config.input_class = nil

  # Define the default class of the input wrapper of the boolean input.
  config.boolean_label_class = 'checkbox'

  # Defines if the default input wrapper class should be included in radio
  # collection wrappers.
  # config.include_default_input_wrapper_class = true

  # Defines which i18n scope will be used in Simple Form.
  # config.i18n_scope = 'simple_form'

  # Defines validation classes to the input_field. By default it's nil.
  # config.input_field_valid_class = 'is-valid'
  # config.input_field_error_class = 'is-invalid'
end


================================================
FILE: lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb
================================================
# frozen_string_literal: true

# These defaults are defined and maintained by the community at
# https://github.com/heartcombo/simple_form-bootstrap
# Please submit feedback, changes and tests only there.

# Uncomment this and change the path if necessary to include your own
# components.
# See https://github.com/heartcombo/simple_form#custom-components
# to know more about custom components.
# Dir[Rails.root.join('lib/components/**/*.rb')].each { |f| require f }

# Use this setup block to configure all options available in SimpleForm.
SimpleForm.setup do |config|
  # Default class for buttons
  config.button_class = 'btn'

  # Define the default class of the input wrapper of the boolean input.
  config.boolean_label_class = 'form-check-label'

  # How the label text should be generated altogether with the required text.
  config.label_text = lambda { |label, required, explicit_label| "#{label} #{required}" }

  # Define the way to render check boxes / radio buttons with labels.
  config.boolean_style = :inline

  # You can wrap each item in a collection of radio/check boxes with a tag
  config.item_wrapper_tag = :div

  # Defines if the default input wrapper class should be included in radio
  # collection wrappers.
  config.include_default_input_wrapper_class = false

  # CSS class to add for error notification helper.
  config.error_notification_class = 'alert alert-danger'

  # Method used to tidy up errors. Specify any Rails Array method.
  # :first lists the first message for each field.
  # :to_sentence to list all errors for each field.
  config.error_method = :to_sentence

  # add validation classes to `input_field`
  config.input_field_error_class = 'is-invalid'
  config.input_field_valid_class = 'is-valid'


  # vertical forms
  #
  # vertical default_wrapper
  config.wrappers :vertical_form, class: 'mb-3' do |b|
    b.use :html5
    b.use :placeholder
    b.optional :maxlength
    b.optional :minlength
    b.optional :pattern
    b.optional :min_max
    b.optional :readonly
    b.use :label, class: 'form-label'
    b.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'
    b.use :full_error, wrap_with: { class: 'invalid-feedback' }
    b.use :hint, wrap_with: { class: 'form-text' }
  end

  # vertical input for boolean
  config.wrappers :vertical_boolean, tag: 'fieldset', class: 'mb-3' do |b|
    b.use :html5
    b.optional :readonly
    b.wrapper :form_check_wrapper, class: 'form-check' do |bb|
      bb.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
      bb.use :label, class: 'form-check-label'
      bb.use :full_error, wrap_with: { class: 'invalid-feedback' }
      bb.use :hint, wrap_with: { class: 'form-text' }
    end
  end

  # vertical input for radio buttons and check boxes
  config.wrappers :vertical_collection, item_wrapper_class: 'form-check', item_label_class: 'form-check-label', tag: 'fieldset', class: 'mb-3' do |b|
    b.use :html5
    b.optional :readonly
    b.wrapper :legend_tag, tag: 'legend', class: 'col-form-label pt-0' do |ba|
      ba.use :label_text
    end
    b.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
    b.use :full_error, wrap_with: { class: 'invalid-feedback d-block' }
    b.use :hint, wrap_with: { class: 'form-text' }
  end

  # vertical input for inline radio buttons and check boxes
  config.wrappers :vertical_collection_inline, item_wrapper_class: 'form-check form-check-inline', item_label_class: 'form-check-label', tag: 'fieldset', class: 'mb-3' do |b|
    b.use :html5
    b.optional :readonly
    b.wrapper :legend_tag, tag: 'legend', class: 'col-form-label pt-0' do |ba|
      ba.use :label_text
    end
    b.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
    b.use :full_error, wrap_with: { class: 'invalid-feedback d-block' }
    b.use :hint, wrap_with: { class: 'form-text' }
  end

  # vertical file input
  config.wrappers :vertical_file, class: 'mb-3' do |b|
    b.use :html5
    b.use :placeholder
    b.optional :maxlength
    b.optional :minlength
    b.optional :readonly
    b.use :label, class: 'form-label'
    b.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'
    b.use :full_error, wrap_with: { class: 'invalid-feedback' }
    b.use :hint, wrap_with: { class: 'form-text' }
  end

  # vertical select input
  config.wrappers :vertical_select, class: 'mb-3' do |b|
    b.use :html5
    b.optional :readonly
    b.use :label, class: 'form-label'
    b.use :input, class: 'form-select', error_class: 'is-invalid', valid_class: 'is-valid'
    b.use :full_error, wrap_with: { class: 'invalid-feedback' }
    b.use :hint, wrap_with: { class: 'form-text' }
  end

  # vertical multi select
  config.wrappers :vertical_multi_select, class: 'mb-3' do |b|
    b.use :html5
    b.optional :readonly
    b.use :label, class: 'form-label'
    b.wrapper class: 'd-flex flex-row justify-content-between align-items-center' do |ba|
      ba.use :input, class: 'form-select mx-1', error_class: 'is-invalid', valid_class: 'is-valid'
    end
    b.use :full_error, wrap_with: { class: 'invalid-feedback d-block' }
    b.use :hint, wrap_with: { class: 'form-text' }
  end

  # vertical range input
  config.wrappers :vertical_range, class: 'mb-3' do |b|
    b.use :html5
    b.use :placeholder
    b.optional :readonly
    b.optional :step
    b.use :label, class: 'form-label'
    b.use :input, class: 'form-range', error_class: 'is-invalid', valid_class: 'is-valid'
    b.use :full_error, wrap_with: { class: 'invalid-feedback' }
    b.use :hint, wrap_with: { class: 'form-text' }
  end


  # horizontal forms
  #
  # horizontal default_wrapper
  config.wrappers :horizontal_form, class: 'row mb-3' do |b|
    b.use :html5
    b.use :placeholder
    b.optional :maxlength
    b.optional :minlength
    b.optional :pattern
    b.optional :min_max
    b.optional :readonly
    b.use :label, class: 'col-sm-3 col-form-label'
    b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|
      ba.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'
      ba.use :full_error, wrap_with: { class: 'invalid-feedback' }
      ba.use :hint, wrap_with: { class: 'form-text' }
    end
  end

  # horizontal input for boolean
  config.wrappers :horizontal_boolean, class: 'row mb-3' do |b|
    b.use :html5
    b.optional :readonly
    b.wrapper :grid_wrapper, class: 'col-sm-9 offset-sm-3' do |wr|
      wr.wrapper :form_check_wrapper, class: 'form-check' do |bb|
        bb.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
        bb.use :label, class: 'form-check-label'
        bb.use :full_error, wrap_with: { class: 'invalid-feedback' }
        bb.use :hint, wrap_with: { class: 'form-text' }
      end
    end
  end

  # horizontal input for radio buttons and check boxes
  config.wrappers :horizontal_collection, item_wrapper_class: 'form-check', item_label_class: 'form-check-label', class: 'row mb-3' do |b|
    b.use :html5
    b.optional :readonly
    b.use :label, class: 'col-sm-3 col-form-label pt-0'
    b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|
      ba.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
      ba.use :full_error, wrap_with: { class: 'invalid-feedback d-block' }
      ba.use :hint, wrap_with: { class: 'form-text' }
    end
  end

  # horizontal input for inline radio buttons and check boxes
  config.wrappers :horizontal_collection_inline, item_wrapper_class: 'form-check form-check-inline', item_label_class: 'form-check-label', class: 'row mb-3' do |b|
    b.use :html5
    b.optional :readonly
    b.use :label, class: 'col-sm-3 col-form-label pt-0'
    b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|
      ba.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
      ba.use :full_error, wrap_with: { class: 'invalid-feedback d-block' }
      ba.use :hint, wrap_with: { class: 'form-text' }
    end
  end

  # horizontal file input
  config.wrappers :horizontal_file, class: 'row mb-3' do |b|
    b.use :html5
    b.use :placeholder
    b.optional :maxlength
    b.optional :minlength
    b.optional :readonly
    b.use :label, class: 'col-sm-3 col-form-label'
    b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|
      ba.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'
      ba.use :full_error, wrap_with: { class: 'invalid-feedback' }
      ba.use :hint, wrap_with: { class: 'form-text' }
    end
  end

  # horizontal select input
  config.wrappers :horizontal_select, class: 'row mb-3' do |b|
    b.use :html5
    b.optional :readonly
    b.use :label, class: 'col-sm-3 col-form-label'
    b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|
      ba.use :input, class: 'form-select', error_class: 'is-invalid', valid_class: 'is-valid'
      ba.use :full_error, wrap_with: { class: 'invalid-feedback' }
      ba.use :hint, wrap_with: { class: 'form-text' }
    end
  end

  # horizontal multi select
  config.wrappers :horizontal_multi_select, class: 'row mb-3' do |b|
    b.use :html5
    b.optional :readonly
    b.use :label, class: 'col-sm-3 col-form-label'
    b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|
      ba.wrapper class: 'd-flex flex-row justify-content-between align-items-center' do |bb|
        bb.use :input, class: 'form-select mx-1', error_class: 'is-invalid', valid_class: 'is-valid'
      end
      ba.use :full_error, wrap_with: { class: 'invalid-feedback d-block' }
      ba.use :hint, wrap_with: { class: 'form-text' }
    end
  end

  # horizontal range input
  config.wrappers :horizontal_range, class: 'row mb-3' do |b|
    b.use :html5
    b.use :placeholder
    b.optional :readonly
    b.optional :step
    b.use :label, class: 'col-sm-3 col-form-label pt-0'
    b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|
      ba.use :input, class: 'form-range', error_class: 'is-invalid', valid_class: 'is-valid'
      ba.use :full_error, wrap_with: { class: 'invalid-feedback' }
      ba.use :hint, wrap_with: { class: 'form-text' }
    end
  end


  # inline forms
  #
  # inline default_wrapper
  config.wrappers :inline_form, class: 'col-12' do |b|
    b.use :html5
    b.use :placeholder
    b.optional :maxlength
    b.optional :minlength
    b.optional :pattern
    b.optional :min_max
    b.optional :readonly
    b.use :label, class: 'visually-hidden'

    b.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'
    b.use :error, wrap_with: { class: 'invalid-feedback' }
    b.optional :hint, wrap_with: { class: 'form-text' }
  end

  # inline input for boolean
  config.wrappers :inline_boolean, class: 'col-12' do |b|
    b.use :html5
    b.optional :readonly
    b.wrapper :form_check_wrapper, class: 'form-check' do |bb|
      bb.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
      bb.use :label, class: 'form-check-label'
      bb.use :error, wrap_with: { class: 'invalid-feedback' }
      bb.optional :hint, wrap_with: { class: 'form-text' }
    end
  end


  # bootstrap custom forms
  #
  # custom input switch for boolean
  config.wrappers :custom_boolean_switch, class: 'mb-3' do |b|
    b.use :html5
    b.optional :readonly
    b.wrapper :form_check_wrapper, tag: 'div', class: 'form-check form-switch' do |bb|
      bb.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
      bb.use :label, class: 'form-check-label'
      bb.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback' }
      bb.use :hint, wrap_with: { class: 'form-text' }
    end
  end


  # Input Group - custom component
  # see example app and config at https://github.com/heartcombo/simple_form-bootstrap
  config.wrappers :input_group, class: 'mb-3' do |b|
    b.use :html5
    b.use :placeholder
    b.optional :maxlength
    b.optional :minlength
    b.optional :pattern
    b.optional :min_max
    b.optional :readonly
    b.use :label, class: 'form-label'
    b.wrapper :input_group_tag, class: 'input-group' do |ba|
      ba.optional :prepend
      ba.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'
      ba.optional :append
      ba.use :full_error, wrap_with: { class: 'invalid-feedback' }
    end
    b.use :hint, wrap_with: { class: 'form-text' }
  end


  # Floating Labels form
  #
  # floating labels default_wrapper
  config.wrappers :floating_labels_form, class: 'form-floating mb-3' do |b|
    b.use :html5
    b.use :placeholder
    b.optional :maxlength
    b.optional :minlength
    b.optional :pattern
    b.optional :min_max
    b.optional :readonly
    b.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'
    b.use :label
    b.use :full_error, wrap_with: { class: 'invalid-feedback' }
    b.use :hint, wrap_with: { class: 'form-text' }
  end

  # custom multi select
  config.wrappers :floating_labels_select, class: 'form-floating mb-3' do |b|
    b.use :html5
    b.optional :readonly
    b.use :input, class: 'form-select', error_class: 'is-invalid', valid_class: 'is-valid'
    b.use :label
    b.use :full_error, wrap_with: { class: 'invalid-feedback' }
    b.use :hint, wrap_with: { class: 'form-text' }
  end


  # The default wrapper to be used by the FormBuilder.
  config.default_wrapper = :vertical_form

  # Custom wrappers for input types. This should be a hash containing an input
  # type as key and the wrapper that will be used for all inputs with specified type.
  config.wrapper_mappings = {
    boolean:       :vertical_boolean,
    check_boxes:   :vertical_collection,
    date:          :vertical_multi_select,
    datetime:      :vertical_multi_select,
    file:          :vertical_file,
    radio_buttons: :vertical_collection,
    range:         :vertical_range,
    time:          :vertical_multi_select,
    select:        :vertical_select
  }
end


================================================
FILE: lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb
================================================
# frozen_string_literal: true
#
# Uncomment this and change the path if necessary to include your own
# components.
# See https://github.com/heartcombo/simple_form#custom-components to know
# more about custom components.
# Dir[Rails.root.join('lib/components/**/*.rb')].each { |f| require f }
#
# Use this setup block to configure all options available in SimpleForm.
SimpleForm.setup do |config|
  # Don't forget to edit this file to adapt it to your needs (specially
  # all the grid-related classes)
  #
  # Please note that hints are commented out by default since Foundation
  # doesn't provide styles for hints. You will need to provide your own CSS styles for hints.
  # Uncomment them to enable hints.

  config.wrappers :vertical_form, class: :input, hint_class: :field_with_hint, error_class: :error, valid_class: :valid do |b|
    b.use :html5
    b.use :placeholder
    b.optional :maxlength
    b.optional :minlength
    b.optional :pattern
    b.optional :min_max
    b.optional :readonly
    b.use :label_input
    b.use :error, wrap_with: { tag: :small, class: :error }

    # b.use :hint,  wrap_with: { tag: :span, class: :hint }
  end

  config.wrappers :horizontal_form, tag: 'div', class: 'row', hint_class: :field_with_hint, error_class: :error, valid_class: :valid do |b|
    b.use :html5
    b.use :placeholder
    b.optional :maxlength
    b.optional :minlength
    b.optional :pattern
    b.optional :min_max
    b.optional :readonly

    b.wrapper :label_wrapper, tag: :div, class: 'small-3 columns' do |ba|
      ba.use :label, class: 'text-right inline'
    end

    b.wrapper :right_input_wrapper, tag: :div, class: 'small-9 columns' do |ba|
      ba.use :input
      ba.use :error, wrap_with: { tag: :small, class: :error }
      # ba.use :hint,  wrap_with: { tag: :span, class: :hint }
    end
  end

  config.wrappers :horizontal_radio_and_checkboxes, tag: 'div', class: 'row' do |b|
    b.use :html5
    b.optional :readonly

    b.wrapper :container_wrapper, tag: 'div', class: 'small-offset-3 small-9 columns' do |ba|
      ba.wrapper tag: 'label', class: 'checkbox' do |bb|
        bb.use :input
        bb.use :label_text
      end

      ba.use :error, wrap_with: { tag: :small, class: :error }
      # ba.use :hint,  wrap_with: { tag: :span, class: :hint }
    end
  end

  # Foundation does not provide a way to handle inline forms
  # This wrapper can be used to create an inline form
  # by hiding that labels on every screen sizes ('hidden-for-small-up').
  #
  # Note that you need to adapt this wrapper to your needs. If you need a 4
  # columns form then change the wrapper class to 'small-3', if you need
  # only two use 'small-6' and so on.
  config.wrappers :inline_form, tag: 'div', class: 'column small-4', hint_class: :field_with_hint, error_class: :error, valid_class: :valid do |b|
    b.use :html5
    b.use :placeholder
    b.optional :maxlength
    b.optional :minlength
    b.optional :pattern
    b.optional :min_max
    b.optional :readonly

    b.use :label, class: 'hidden-for-small-up'
    b.use :input

    b.use :error, wrap_with: { tag: :small, class: :error }
    # b.use :hint,  wrap_with: { tag: :span, class: :hint }
  end

  # Examples of use:
  # - wrapper_html: {class: 'row'}, custom_wrapper_html: {class: 'column small-12'}
  # - custom_wrapper_html: {class: 'column small-3 end'}
  config.wrappers :customizable_wrapper, tag: 'div', error_class: :error, valid_class: :valid do |b|
    b.use :html5
    b.optional :readonly

    b.wrapper :custom_wrapper, tag: :div do |ba|
      ba.use :label_input
    end

    b.use :error, wrap_with: { tag: :small, class: :error }
    # b.use :hint,  wrap_with: { tag: :span, class: :hint }
  end

  # CSS class for buttons
  config.button_class = 'button'

  # Set this to div to make the checkbox and radio properly work
  # otherwise simple_form adds a label tag instead of a div around
  # the nested label
  config.item_wrapper_tag = :div

  # CSS class to add for error notification helper.
  config.error_notification_class = 'alert-box alert'

  # The default wrapper to be used by the FormBuilder.
  config.default_wrapper = :vertical_form

  # Defines validation classes to the input_field. By default it's nil.
  # config.input_field_valid_class = 'is-valid'
  # config.input_field_error_class = 'is-invalid'
end


================================================
FILE: lib/generators/simple_form/templates/config/locales/simple_form.en.yml
================================================
en:
  simple_form:
    "yes": 'Yes'
    "no": 'No'
    required:
      text: 'required'
      mark: '*'
      # You can uncomment the line below if you need to overwrite the whole required html.
      # When using html, text and mark won't be used.
      # html: '<abbr title="required">*</abbr>'
    error_notification:
      default_message: "Please review the problems below:"
    # Examples
    # labels:
    #   defaults:
    #     password: 'Password'
    #   user:
    #     new:
    #       email: 'E-mail to sign in.'
    #     edit:
    #       email: 'E-mail.'
    # hints:
    #   defaults:
    #     username: 'User name to sign in.'
    #     password: 'No special characters, please.'
    # include_blanks:
    #   defaults:
    #     age: 'Rather not say'
    # prompts:
    #   defaults:
    #     age: 'Select your age'


================================================
FILE: lib/simple_form/action_view_extensions/builder.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module ActionViewExtensions
    # A collection of methods required by simple_form but added to rails default form.
    # This means that you can use such methods outside simple_form context.
    module Builder

      # Wrapper for using SimpleForm inside a default rails form.
      # Example:
      #
      #   form_for @user do |f|
      #     f.simple_fields_for :posts do |posts_form|
      #       # Here you have all simple_form methods available
      #       posts_form.input :title
      #     end
      #   end
      def simple_fields_for(*args, &block)
        options = args.extract_options!
        options[:wrapper] = self.options[:wrapper] if options[:wrapper].nil?
        options[:defaults] ||= self.options[:defaults]
        options[:wrapper_mappings] ||= self.options[:wrapper_mappings]

        if self.class < ActionView::Helpers::FormBuilder
          options[:builder] ||= self.class
        else
          options[:builder] ||= SimpleForm::FormBuilder
        end
        fields_for(*args, options, &block)
      end
    end
  end
end

module ActionView::Helpers
  class FormBuilder
    include SimpleForm::ActionViewExtensions::Builder
  end
end


================================================
FILE: lib/simple_form/action_view_extensions/form_helper.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module ActionViewExtensions
    # This module creates SimpleForm wrappers around default form_for and fields_for.
    #
    # Example:
    #
    #   simple_form_for @user do |f|
    #     f.input :name, hint: 'My hint'
    #   end
    #
    module FormHelper

      def simple_form_for(record, options = {}, &block)
        options[:builder] ||= SimpleForm::FormBuilder
        options[:html] ||= {}
        unless options[:html].key?(:novalidate)
          options[:html][:novalidate] = !SimpleForm.browser_validations
        end
        if options[:html].key?(:class)
          options[:html][:class] = [SimpleForm.form_class, options[:html][:class]].compact
        else
          options[:html][:class] = [SimpleForm.form_class, SimpleForm.default_form_class, simple_form_css_class(record, options)].compact
        end

        with_simple_form_field_error_proc do
          form_for(record, options, &block)
        end
      end

      def simple_fields_for(record_name, record_object = nil, options = {}, &block)
        options, record_object = record_object, nil if record_object.is_a?(Hash) && record_object.extractable_options?
        options[:builder] ||= SimpleForm::FormBuilder

        with_simple_form_field_error_proc do
          fields_for(record_name, record_object, options, &block)
        end
      end

      private

      def with_simple_form_field_error_proc
        default_field_error_proc = ::ActionView::Base.field_error_proc
        begin
          ::ActionView::Base.field_error_proc = SimpleForm.field_error_proc
          yield
        ensure
          ::ActionView::Base.field_error_proc = default_field_error_proc
        end
      end

      def simple_form_css_class(record, options)
        html_options = options[:html]
        as = options[:as]

        if html_options.key?(:class)
          html_options[:class]
        elsif record.is_a?(String) || record.is_a?(Symbol)
          as || record
        else
          record = record.last if record.is_a?(Array)
          action = record.respond_to?(:persisted?) && record.persisted? ? :edit : :new
          as ? "#{action}_#{as}" : dom_class(record, action)
        end
      end
    end
  end
end

ActiveSupport.on_load(:action_view) do
  include SimpleForm::ActionViewExtensions::FormHelper
end


================================================
FILE: lib/simple_form/components/errors.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Components
    module Errors
      def error(wrapper_options = nil)
        error_text if has_errors?
      end

      def full_error(wrapper_options = nil)
        full_error_text if options[:error] != false && has_errors?
      end

      def has_errors?
        object_with_errors? || !object && has_custom_error?
      end

      def has_value?
        object && object.respond_to?(attribute_name) && object.send(attribute_name).present?
      end

      def valid?
        !has_errors? && has_value?
      end

      protected

      def error_text
        text = has_custom_error? ? options[:error] : errors.send(error_method)

        "#{html_escape(options[:error_prefix])} #{html_escape(text)}".lstrip.html_safe
      end

      def full_error_text
        has_custom_error? ? options[:error] : full_errors.send(error_method)
      end

      def object_with_errors?
        object && object.respond_to?(:errors) && errors.present?
      end

      def error_method
        options[:error_method] || SimpleForm.error_method
      end

      def errors
        @errors ||= (errors_on_attribute + errors_on_association).compact
      end

      def full_errors
        @full_errors ||= (full_errors_on_attribute + full_errors_on_association).compact
      end

      def errors_on_attribute
        object.errors[attribute_name] || []
      end

      def full_errors_on_attribute
        object.errors.full_messages_for(attribute_name)
      end

      def errors_on_association
        reflection ? object.errors[reflection.name] : []
      end

      def full_errors_on_association
        reflection ? object.errors.full_messages_for(reflection.name) : []
      end

      def has_custom_error?
        options[:error].is_a?(String)
      end
    end
  end
end


================================================
FILE: lib/simple_form/components/hints.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Components
    # Needs to be enabled in order to do automatic lookups.
    module Hints
      def hint(wrapper_options = nil)
        @hint ||= begin
          hint = options[:hint]

          if hint.is_a?(String)
            html_escape(hint)
          else
            content = translate_from_namespace(:hints)
            content.html_safe if content
          end
        end
      end

      def has_hint?
        options[:hint] != false && hint.present?
      end
    end
  end
end


================================================
FILE: lib/simple_form/components/html5.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Components
    module HTML5
      def initialize(*)
        @html5 = false
      end

      def html5(wrapper_options = nil)
        @html5 = true

        input_html_options[:required]        = input_html_required_option
        input_html_options[:'aria-invalid']  = has_errors? || nil
        nil
      end

      def html5?
        @html5
      end

      def input_html_required_option
        !options[:required].nil? ? required_field? : has_required?
      end

      def has_required?
        # We need to check browser_validations because
        # some browsers are still checking required even
        # if novalidate was given.
        required_field? && SimpleForm.browser_validations
      end
    end
  end
end


================================================
FILE: lib/simple_form/components/label_input.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Components
    module LabelInput
      extend ActiveSupport::Concern

      included do
        include SimpleForm::Components::Labels
      end

      def label_input(wrapper_options = nil)
        if options[:label] == false
          deprecated_component(:input, wrapper_options)
        else
          deprecated_component(:label, wrapper_options) + deprecated_component(:input, wrapper_options)
        end
      end

      private

      def deprecated_component(namespace, wrapper_options)
        method = method(namespace)

        if method.arity.zero?
          SimpleForm.deprecator.warn(SimpleForm::CUSTOM_INPUT_DEPRECATION_WARN % { name: namespace })

          method.call
        else
          method.call(wrapper_options)
        end
      end
    end
  end
end


================================================
FILE: lib/simple_form/components/labels.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Components
    module Labels
      extend ActiveSupport::Concern

      module ClassMethods #:nodoc:
        def translate_required_html
          I18n.t(:"required.html", scope: i18n_scope, default:
            %(<abbr title="#{translate_required_text}">#{translate_required_mark}</abbr>)
          )
        end

        def translate_required_text
          I18n.t(:"required.text", scope: i18n_scope, default: 'required')
        end

        def translate_required_mark
          I18n.t(:"required.mark", scope: i18n_scope, default: '*')
        end

        private

        def i18n_scope
          SimpleForm.i18n_scope
        end
      end

      def label(wrapper_options = nil)
        label_options = merge_wrapper_options(label_html_options, wrapper_options)

        if generate_label_for_attribute?
          @builder.label(label_target, label_text, label_options)
        else
          template.label_tag(nil, label_text, label_options)
        end
      end

      def label_text(wrapper_options = nil)
        label_text = options[:label_text] || SimpleForm.label_text
        label_text.call(html_escape(raw_label_text), required_label_text, options[:label].present?).strip.html_safe
      end

      def label_target
        attribute_name
      end

      def label_html_options
        label_html_classes = SimpleForm.additional_classes_for(:label) {
          [input_type, required_class, disabled_class, SimpleForm.label_class].compact
        }

        label_options = html_options_for(:label, label_html_classes)
        if options.key?(:input_html) && options[:input_html].key?(:id)
          label_options[:for] = options[:input_html][:id]
        end

        label_options
      end

      protected

      def raw_label_text #:nodoc:
        options[:label] || label_translation
      end

      # Default required text when attribute is required.
      def required_label_text #:nodoc:
        required_field? ? self.class.translate_required_html.dup : ''
      end

      # First check labels translation and then human attribute name.
      def label_translation #:nodoc:
        if SimpleForm.translate_labels && (translated_label = translate_from_namespace(:labels))
          translated_label
        elsif object.class.respond_to?(:human_attribute_name)
          object.class.human_attribute_name(reflection_or_attribute_name.to_s, { base: object })
        else
          attribute_name.to_s.humanize
        end
      end

      def generate_label_for_attribute?
        true
      end
    end
  end
end


================================================
FILE: lib/simple_form/components/maxlength.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Components
    # Needs to be enabled in order to do automatic lookups.
    module Maxlength
      def maxlength(wrapper_options = nil)
        input_html_options[:maxlength] ||= maximum_length_from_validation || limit
        nil
      end

      private

      def maximum_length_from_validation
        maxlength = options[:maxlength]
        if maxlength.is_a?(String) || maxlength.is_a?(Integer)
          maxlength
        else
          length_validator = find_length_validator
          maximum_length_value_from(length_validator)
        end
      end

      def find_length_validator
        find_validator(:length)
      end

      def maximum_length_value_from(length_validator)
        if length_validator
          value = length_validator.options[:is] || length_validator.options[:maximum]
          resolve_validator_value(value)
        end
      end
    end
  end
end


================================================
FILE: lib/simple_form/components/min_max.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Components
    module MinMax
      def min_max(wrapper_options = nil)
        if numeric_validator = find_numericality_validator
          validator_options = numeric_validator.options
          input_html_options[:min] ||= minimum_value(validator_options)
          input_html_options[:max] ||= maximum_value(validator_options)
        end
        nil
      end

      private

      def integer?
        input_type == :integer
      end

      def minimum_value(validator_options)
        if integer? && validator_options.key?(:greater_than)
          resolve_validator_value(validator_options[:greater_than]) + 1
        else
          resolve_validator_value(validator_options[:greater_than_or_equal_to])
        end
      end

      def maximum_value(validator_options)
        if integer? && validator_options.key?(:less_than)
          resolve_validator_value(validator_options[:less_than]) - 1
        else
          resolve_validator_value(validator_options[:less_than_or_equal_to])
        end
      end

      def find_numericality_validator
        find_validator(:numericality)
      end
    end
  end
end


================================================
FILE: lib/simple_form/components/minlength.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Components
    # Needs to be enabled in order to do automatic lookups.
    module Minlength
      def minlength(wrapper_options = nil)
        input_html_options[:minlength] ||= minimum_length_from_validation
        nil
      end

      private

      def minimum_length_from_validation
        minlength = options[:minlength]
        if minlength.is_a?(String) || minlength.is_a?(Integer)
          minlength
        else
          length_validator = find_length_validator
          minimum_length_value_from(length_validator)
        end
      end

      def find_length_validator
        find_validator(:length)
      end

      def minimum_length_value_from(length_validator)
        if length_validator
          value = length_validator.options[:is] || length_validator.options[:minimum]
          resolve_validator_value(value)
        end
      end
    end
  end
end


================================================
FILE: lib/simple_form/components/pattern.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Components
    # Needs to be enabled in order to do automatic lookups.
    module Pattern
      def pattern(wrapper_options = nil)
        input_html_options[:pattern] ||= pattern_source
        nil
      end

      private

      def pattern_source
        pattern = options[:pattern]
        if pattern.is_a?(String)
          pattern
        elsif (pattern_validator = find_pattern_validator) && (with = pattern_validator.options[:with])
          resolve_validator_value(with).source
        end
      end

      def find_pattern_validator
        find_validator(:format)
      end
    end
  end
end


================================================
FILE: lib/simple_form/components/placeholders.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Components
    # Needs to be enabled in order to do automatic lookups.
    module Placeholders
      def placeholder(wrapper_options = nil)
        input_html_options[:placeholder] ||= placeholder_text
        nil
      end

      def placeholder_text(wrapper_options = nil)
        placeholder = options[:placeholder]
        placeholder.is_a?(String) ? placeholder : translate_from_namespace(:placeholders)
      end
    end
  end
end


================================================
FILE: lib/simple_form/components/readonly.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Components
    # Needs to be enabled in order to do automatic lookups.
    module Readonly
      def readonly(wrapper_options = nil)
        if readonly_attribute? && !has_readonly?
          input_html_options[:readonly] ||= true
          input_html_classes << :readonly
        end
        nil
      end

      private

      def readonly_attribute?
        object.class.respond_to?(:readonly_attributes) &&
          object.persisted? &&
          object.class.readonly_attributes.include?(attribute_name.to_s)
      end
    end
  end
end


================================================
FILE: lib/simple_form/components.rb
================================================
# frozen_string_literal: true
module SimpleForm
  # Components are a special type of helpers that can work on their own.
  # For example, by using a component, it will automatically change the
  # output under given circumstances without user input. For example,
  # the disabled helper always need a disabled: true option given
  # to the input in order to be enabled. On the other hand, things like
  # hints can generate output automatically by doing I18n lookups.
  module Components
    extend ActiveSupport::Autoload

    autoload :Errors
    autoload :Hints
    autoload :HTML5
    autoload :LabelInput
    autoload :Labels
    autoload :MinMax
    autoload :Maxlength
    autoload :Minlength
    autoload :Pattern
    autoload :Placeholders
    autoload :Readonly
  end
end


================================================
FILE: lib/simple_form/error_notification.rb
================================================
# frozen_string_literal: true
module SimpleForm
  class ErrorNotification
    delegate :object, :object_name, :template, to: :@builder

    def initialize(builder, options)
      @builder = builder
      @message = options.delete(:message)
      @options = options
    end

    def render
      if has_errors?
        template.content_tag(error_notification_tag, error_message, html_options)
      end
    end

    protected

    def errors
      object.errors
    end

    def has_errors?
      object && object.respond_to?(:errors) && errors.present?
    end

    def error_message
      (@message || translate_error_notification).html_safe
    end

    def error_notification_tag
      SimpleForm.error_notification_tag
    end

    def html_options
      @options[:class] = "#{SimpleForm.error_notification_class} #{@options[:class]}".strip
      @options
    end

    def translate_error_notification
      lookups = []
      lookups << :"#{object_name}"
      lookups << :default_message
      lookups << "Please review the problems below:"
      I18n.t(lookups.shift, scope: :"simple_form.error_notification", default: lookups)
    end
  end
end


================================================
FILE: lib/simple_form/form_builder.rb
================================================
# frozen_string_literal: true
require 'active_support/core_ext/object/deep_dup'
require 'simple_form/map_type'
require 'simple_form/tags'

module SimpleForm
  class FormBuilder < ActionView::Helpers::FormBuilder
    attr_reader :template, :object_name, :object, :wrapper

    # When action is create or update, we still should use new and edit
    ACTIONS = {
      'create' => 'new',
      'update' => 'edit'
    }

    ATTRIBUTE_COMPONENTS = %i[html5 min_max maxlength minlength placeholder pattern readonly]

    extend MapType
    include SimpleForm::Inputs

    map_type :text, :hstore, :json, :jsonb,                        to: SimpleForm::Inputs::TextInput
    map_type :file,                                                to: SimpleForm::Inputs::FileInput
    map_type :string, :email, :search, :tel, :url, :uuid, :citext, to: SimpleForm::Inputs::StringInput
    map_type :password,                                            to: SimpleForm::Inputs::PasswordInput
    map_type :integer, :decimal, :float,                           to: SimpleForm::Inputs::NumericInput
    map_type :range,                                               to: SimpleForm::Inputs::RangeInput
    map_type :check_boxes,                                         to: SimpleForm::Inputs::CollectionCheckBoxesInput
    map_type :radio_buttons,                                       to: SimpleForm::Inputs::CollectionRadioButtonsInput
    map_type :rich_text_area,                                      to: SimpleForm::Inputs::RichTextAreaInput
    map_type :select,                                              to: SimpleForm::Inputs::CollectionSelectInput
    map_type :grouped_select,                                      to: SimpleForm::Inputs::GroupedCollectionSelectInput
    map_type :date, :time, :datetime,                              to: SimpleForm::Inputs::DateTimeInput
    map_type :country, :time_zone,                                 to: SimpleForm::Inputs::PriorityInput
    map_type :boolean,                                             to: SimpleForm::Inputs::BooleanInput
    map_type :hidden,                                              to: SimpleForm::Inputs::HiddenInput

    def self.discovery_cache
      @discovery_cache ||= {}
    end

    def initialize(*) #:nodoc:
      super
      @object   = convert_to_model(@object)
      @defaults = options[:defaults]
      @wrapper  = SimpleForm.wrapper(options[:wrapper] || SimpleForm.default_wrapper)
    end

    # Basic input helper, combines all components in the stack to generate
    # input html based on options the user define and some guesses through
    # database column information. By default a call to input will generate
    # label + input + hint (when defined) + errors (when exists), and all can
    # be configured inside a wrapper html.
    #
    # If a block is given, the contents of the block will replace the input
    # field that would otherwise be generated automatically. The content will
    # be given a label and wrapper div to make it consistent with the other
    # elements in the form.
    #
    # == Examples
    #
    #   # Imagine @user has error "can't be blank" on name
    #   simple_form_for @user do |f|
    #     f.input :name, hint: 'My hint'
    #   end
    #
    # This is the output html (only the input portion, not the form):
    #
    #     <label class="string required" for="user_name">
    #       <abbr title="required">*</abbr> Super User Name!
    #     </label>
    #     <input class="string required" id="user_name" maxlength="100"
    #        name="user[name]" type="text" value="Carlos" />
    #     <span class="hint">My hint</span>
    #     <span class="error">can't be blank</span>
    #
    # Each database type will render a default input, based on some mappings and
    # heuristic to determine which is the best option.
    #
    # You have some options for the input to enable/disable some functions:
    #
    #   as: allows you to define the input type you want, for instance you
    #          can use it to generate a text field for a date column.
    #
    #   required: defines whether this attribute is required or not. True
    #               by default.
    #
    # The fact SimpleForm is built in components allow the interface to be unified.
    # So, for instance, if you need to disable :hint for a given input, you can pass
    # hint: false. The same works for :error, :label and :wrapper.
    #
    # Besides the html for any component can be changed. So, if you want to change
    # the label html you just need to give a hash to :label_html. To configure the
    # input html, supply :input_html instead and so on.
    #
    # == Options
    #
    # Some inputs, as datetime, time and select allow you to give extra options, like
    # prompt and/or include blank. Such options are given in plainly:
    #
    #    f.input :created_at, include_blank: true
    #
    # == Collection
    #
    # When playing with collections (:radio_buttons, :check_boxes and :select
    # inputs), you have three extra options:
    #
    #   collection: use to determine the collection to generate the radio or select
    #
    #   label_method: the method to apply on the array collection to get the label
    #
    #   value_method: the method to apply on the array collection to get the value
    #
    # == Priority
    #
    # Some inputs, as :time_zone and :country accepts a :priority option. If none is
    # given SimpleForm.time_zone_priority and SimpleForm.country_priority are used respectively.
    #
    def input(attribute_name, options = {}, &block)
      options = @defaults.deep_dup.deep_merge(options) if @defaults

      input   = find_input(attribute_name, options, &block)
      wrapper = find_wrapper(input.input_type, options)

      wrapper.render input
    end
    alias :attribute :input

    # Creates a input tag for the given attribute. All the given options
    # are sent as :input_html.
    #
    # == Examples
    #
    #   simple_form_for @user do |f|
    #     f.input_field :name
    #   end
    #
    # This is the output html (only the input portion, not the form):
    #
    #     <input class="string required" id="user_name" maxlength="100"
    #        name="user[name]" type="text" value="Carlos" />
    #
    # It also support validation classes once it is configured.
    #
    #   # config/initializers/simple_form.rb
    #   SimpleForm.setup do |config|
    #     config.input_field_valid_class = 'is-valid'
    #     config.input_field_error_class = 'is-invalid'
    #   end
    #
    #   simple_form_for @user do |f|
    #     f.input_field :name
    #   end
    #
    # When the validation happens, the input will be rendered with
    # the class configured according to the validation:
    #
    # - when the input is valid:
    #
    #     <input class="is-valid string required" id="user_name" value="Carlos" />
    #
    # - when the input is invalid:
    #
    #     <input class="is-invalid string required" id="user_name" value="" />
    #
    def input_field(attribute_name, options = {})
      components = (wrapper.components.map(&:namespace) & ATTRIBUTE_COMPONENTS)

      options = options.dup
      options[:input_html] = options.except(:as, :boolean_style, :collection, :disabled, :label_method, :value_method, :prompt, *components)
      options = @defaults.deep_dup.deep_merge(options) if @defaults

      input      = find_input(attribute_name, options)
      wrapper    = find_wrapper(input.input_type, options)
      components = build_input_field_components(components.push(:input))

      SimpleForm::Wrappers::Root.new(components, wrapper.options.merge(wrapper: false)).render input
    end

    # Helper for dealing with association selects/radios, generating the
    # collection automatically. It's just a wrapper to input, so all options
    # supported in input are also supported by association. Some extra options
    # can also be given:
    #
    # == Examples
    #
    #   simple_form_for @user do |f|
    #     f.association :company          # Company.all
    #   end
    #
    #   f.association :company, collection: Company.all(order: 'name')
    #   # Same as using :order option, but overriding collection
    #
    # == Block
    #
    # When a block is given, association simple behaves as a proxy to
    # simple_fields_for:
    #
    #   f.association :company do |c|
    #     c.input :name
    #     c.input :type
    #   end
    #
    # From the options above, only :collection can also be supplied.
    #
    # Please note that the association helper is currently only tested with Active Record. Depending on the ORM you are using your mileage may vary.
    #
    def association(association, options = {}, &block)
      options = options.dup

      return simple_fields_for(*[association,
        options.delete(:collection), options].compact, &block) if block_given?

      raise ArgumentError, "Association cannot be used in forms not associated with an object" unless @object

      reflection = find_association_reflection(association)
      raise "Association #{association.inspect} not found" unless reflection

      options[:as] ||= :select
      options[:collection] ||= fetch_association_collection(reflection, options)

      attribute = build_association_attribute(reflection, association, options)

      input(attribute, options.merge(reflection: reflection))
    end

    # Creates a button:
    #
    #   form_for @user do |f|
    #     f.button :submit
    #   end
    #
    # It just acts as a proxy to method name given. We also alias original Rails
    # button implementation (3.2 forward (to delegate to the original when
    # calling `f.button :button`.
    #
    alias_method :button_button, :button
    def button(type, *args, &block)
      options = args.extract_options!.dup
      options[:class] = [SimpleForm.button_class, options[:class]].compact
      args << options
      if respond_to?(:"#{type}_button")
        send(:"#{type}_button", *args, &block)
      else
        send(type, *args, &block)
      end
    end

    # Creates an error tag based on the given attribute, only when the attribute
    # contains errors. All the given options are sent as :error_html.
    #
    # == Examples
    #
    #    f.error :name
    #    f.error :name, id: "cool_error"
    #
    def error(attribute_name, options = {})
      options = options.dup

      options[:error_html] = options.except(:error_tag, :error_prefix, :error_method)
      column      = find_attribute_column(attribute_name)
      input_type  = default_input_type(attribute_name, column, options)
      wrapper.find(:error).
        render(SimpleForm::Inputs::Base.new(self, attribute_name, column, input_type, options))
    end

    # Return the error but also considering its name. This is used
    # when errors for a hidden field need to be shown.
    #
    # == Examples
    #
    #    f.full_error :token #=> <span class="error">Token is invalid</span>
    #
    def full_error(attribute_name, options = {})
      options = options.dup

      options[:error_prefix] ||= if object.class.respond_to?(:human_attribute_name)
        object.class.human_attribute_name(attribute_name.to_s, { base: object })
      else
        attribute_name.to_s.humanize
      end

      error(attribute_name, options)
    end

    # Creates a hint tag for the given attribute. Accepts a symbol indicating
    # an attribute for I18n lookup or a string. All the given options are sent
    # as :hint_html.
    #
    # == Examples
    #
    #    f.hint :name # Do I18n lookup
    #    f.hint :name, id: "cool_hint"
    #    f.hint "Don't forget to accept this"
    #
    def hint(attribute_name, options = {})
      options = options.dup

      options[:hint_html] = options.except(:hint_tag, :hint)
      if attribute_name.is_a?(String)
        options[:hint] = attribute_name
        attribute_name, column, input_type = nil, nil, nil
      else
        column      = find_attribute_column(attribute_name)
        input_type  = default_input_type(attribute_name, column, options)
      end

      wrapper.find(:hint).
        render(SimpleForm::Inputs::Base.new(self, attribute_name, column, input_type, options))
    end

    # Creates a default label tag for the given attribute. You can give a label
    # through the :label option or using i18n. All the given options are sent
    # as :label_html.
    #
    # == Examples
    #
    #    f.label :name                     # Do I18n lookup
    #    f.label :name, "Name"             # Same behavior as Rails, do not add required tag
    #    f.label :name, label: "Name"      # Same as above, but adds required tag
    #
    #    f.label :name, required: false
    #    f.label :name, id: "cool_label"
    #
    def label(attribute_name, *args)
      return super if args.first.is_a?(String) || block_given?

      options = args.extract_options!.dup
      options[:label_html] = options.except(:label, :label_text, :required, :as)

      column      = find_attribute_column(attribute_name)
      input_type  = default_input_type(attribute_name, column, options)
      SimpleForm::Inputs::Base.new(self, attribute_name, column, input_type, options).label
    end

    # Creates an error notification message that only appears when the form object
    # has some error. You can give a specific message with the :message option,
    # otherwise it will look for a message using I18n. All other options given are
    # passed straight as html options to the html tag.
    #
    # == Examples
    #
    #    f.error_notification
    #    f.error_notification message: 'Something went wrong'
    #    f.error_notification id: 'user_error_message', class: 'form_error'
    #
    def error_notification(options = {})
      SimpleForm::ErrorNotification.new(self, options).render
    end

    # Create a collection of radio inputs for the attribute. Basically this
    # helper will create a radio input associated with a label for each
    # text/value option in the collection, using value_method and text_method
    # to convert these text/value. You can give a symbol or a proc to both
    # value_method and text_method, that will be evaluated for each item in
    # the collection.
    #
    # == Examples
    #
    #   form_for @user do |f|
    #     f.collection_radio_buttons :options, [[true, 'Yes'] ,[false, 'No']], :first, :last
    #   end
    #
    #   <input id="user_options_true" name="user[options]" type="radio" value="true" />
    #   <label class="collection_radio_buttons" for="user_options_true">Yes</label>
    #   <input id="user_options_false" name="user[options]" type="radio" value="false" />
    #   <label class="collection_radio_buttons" for="user_options_false">No</label>
    #
    # It is also possible to give a block that should generate the radio +
    # label. To wrap the radio with the label, for instance:
    #
    #   form_for @user do |f|
    #     f.collection_radio_buttons(
    #       :options, [[true, 'Yes'] ,[false, 'No']], :first, :last
    #     ) do |b|
    #       b.label { b.radio_button + b.text }
    #     end
    #   end
    #
    # == Options
    #
    # Collection radio accepts some extra options:
    #
    #   * checked  => the value that should be checked initially.
    #
    #   * disabled => the value or values that should be disabled. Accepts a single
    #                 item or an array of items.
    #
    #   * collection_wrapper_tag   => the tag to wrap the entire collection.
    #
    #   * collection_wrapper_class => the CSS class to use for collection_wrapper_tag
    #
    #   * item_wrapper_tag         => the tag to wrap each item in the collection.
    #
    #   * item_wrapper_class       => the CSS class to use for item_wrapper_tag
    #
    #   * a block                  => to generate the label + radio or any other component.
    def collection_radio_buttons(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
      SimpleForm::Tags::CollectionRadioButtons.new(@object_name, method, @template, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options)).render(&block)
    end

    # Creates a collection of check boxes for each item in the collection,
    # associated with a clickable label. Use value_method and text_method to
    # convert items in the collection for use as text/value in check boxes.
    # You can give a symbol or a proc to both value_method and text_method,
    # that will be evaluated for each item in the collection.
    #
    # == Examples
    #
    #   form_for @user do |f|
    #     f.collection_check_boxes :options, [[true, 'Yes'] ,[false, 'No']], :first, :last
    #   end
    #
    #   <input name="user[options][]" type="hidden" value="" />
    #   <input id="user_options_true" name="user[options][]" type="checkbox" value="true" />
    #   <label class="collection_check_boxes" for="user_options_true">Yes</label>
    #   <input name="user[options][]" type="hidden" value="" />
    #   <input id="user_options_false" name="user[options][]" type="checkbox" value="false" />
    #   <label class="collection_check_boxes" for="user_options_false">No</label>
    #
    # It is also possible to give a block that should generate the check box +
    # label. To wrap the check box with the label, for instance:
    #
    #   form_for @user do |f|
    #     f.collection_check_boxes(
    #       :options, [[true, 'Yes'] ,[false, 'No']], :first, :last
    #     ) do |b|
    #       b.label { b.check_box + b.text }
    #     end
    #   end
    #
    # == Options
    #
    # Collection check box accepts some extra options:
    #
    #   * checked  => the value or values that should be checked initially. Accepts
    #                 a single item or an array of items. It overrides existing associations.
    #
    #   * disabled => the value or values that should be disabled. Accepts a single
    #                 item or an array of items.
    #
    #   * collection_wrapper_tag   => the tag to wrap the entire collection.
    #
    #   * collection_wrapper_class => the CSS class to use for collection_wrapper_tag. This option
    #                                 is ignored if the :collection_wrapper_tag option is blank.
    #
    #   * item_wrapper_tag         => the tag to wrap each item in the collection.
    #
    #   * item_wrapper_class       => the CSS class to use for item_wrapper_tag
    #
    #   * a block                  => to generate the label + check box or any other component.
    def collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
      SimpleForm::Tags::CollectionCheckBoxes.new(@object_name, method, @template, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options)).render(&block)
    end

    # Extract the model names from the object_name mess, ignoring numeric and
    # explicit child indexes.
    #
    # Example:
    #
    # route[blocks_attributes][0][blocks_learning_object_attributes][1][foo_attributes]
    # ["route", "blocks", "blocks_learning_object", "foo"]
    #
    def lookup_model_names #:nodoc:
      @lookup_model_names ||= begin
        child_index = options[:child_index]
        names = object_name.to_s.scan(/(?!\d)\w+/).flatten
        names.delete(child_index) if child_index
        names.each { |name| name.gsub!('_attributes', '') }
        names.freeze
      end
    end

    # The action to be used in lookup.
    def lookup_action #:nodoc:
      @lookup_action ||= begin
        action = template.controller && template.controller.action_name
        return unless action
        action = action.to_s
        ACTIONS[action] || action
      end
    end

    private

    def fetch_association_collection(reflection, options)
      options.fetch(:collection) do
        relation = reflection.klass.all

        if reflection.respond_to?(:scope) && reflection.scope
          if reflection.scope.parameters.any?
            relation = reflection.klass.instance_exec(object, &reflection.scope)
          else
            relation = reflection.klass.instance_exec(&reflection.scope)
          end
        else
          order = reflection.options[:order]
          conditions = reflection.options[:conditions]
          conditions = object.instance_exec(&conditions) if conditions.respond_to?(:call)

          relation = relation.where(conditions) if relation.respond_to?(:where) && conditions.present?
          relation = relation.order(order) if relation.respond_to?(:order)
        end

        relation
      end
    end

    def build_association_attribute(reflection, association, options)
      case reflection.macro
      when :belongs_to
        (reflection.respond_to?(:options) && reflection.options[:foreign_key]) || :"#{reflection.name}_id"
      when :has_one
        raise ArgumentError, ":has_one associations are not supported by f.association"
      else
        if options[:as] == :select || options[:as] == :grouped_select
          html_options = options[:input_html] ||= {}
          html_options[:multiple] = true unless html_options.key?(:multiple)
        end

        # Force the association to be preloaded for performance.
        if options[:preload] != false && object.respond_to?(association)
          target = object.send(association)
          target.to_a if target.respond_to?(:to_a)
        end

        :"#{reflection.name.to_s.singularize}_ids"
      end
    end

    # Find an input based on the attribute name.
    def find_input(attribute_name, options = {}, &block)
      column     = find_attribute_column(attribute_name)
      input_type = default_input_type(attribute_name, column, options)

      if block_given?
        SimpleForm::Inputs::BlockInput.new(self, attribute_name, column, input_type, options, &block)
      else
        find_mapping(input_type).new(self, attribute_name, column, input_type, options)
      end
    end

    # Attempt to guess the better input type given the defined options. By
    # default always fallback to the user :as option, or to a :select when a
    # collection is given.
    def default_input_type(attribute_name, column, options)
      return options[:as].to_sym if options[:as]
      custom_type = find_custom_type(attribute_name.to_s) and return custom_type
      return :select             if options[:collection]

      input_type = column.try(:type)
      case input_type
      when :timestamp
        :datetime
      when :string, :citext, nil
        case attribute_name.to_s
        when /(?:\b|\W|_)password(?:\b|\W|_)/  then :password
        when /(?:\b|\W|_)time_zone(?:\b|\W|_)/ then :time_zone
        when /(?:\b|\W|_)country(?:\b|\W|_)/   then :country
        when /(?:\b|\W|_)email(?:\b|\W|_)/     then :email
        when /(?:\b|\W|_)phone(?:\b|\W|_)/     then :tel
        when /(?:\b|\W|_)url(?:\b|\W|_)/       then :url
        else
          file_method?(attribute_name) ? :file : (input_type || :string)
        end
      else
        input_type
      end
    end

    def find_custom_type(attribute_name)
      SimpleForm.input_mappings.find { |match, type|
        attribute_name =~ match
      }.try(:last) if SimpleForm.input_mappings
    end

    # Internal: Try to discover whether an attribute corresponds to a file or not.
    #
    # Most upload Gems add some kind of attributes to the ActiveRecord's model they are included in.
    # This method tries to guess if an attribute belongs to some of these Gems by checking the presence
    # of their methods using `#respond_to?`.
    #
    # Note: This does not support multiple file upload inputs, as this is very application-specific.
    #
    # The order here was chosen based on the popularity of Gems:
    #
    # - `#{attribute_name}_attachment` - ActiveStorage >= `5.2` and Refile >= `0.2.0` <= `0.4.0`
    # - `remote_#{attribute_name}_url` - Refile >= `0.3.0` and CarrierWave >= `0.2.2`
    # - `#{attribute_name}_attacher` - Refile >= `0.4.0` and Shrine >= `0.9.0`
    # - `#{attribute_name}_file_name` - Paperclip ~> `2.0` (added for backwards compatibility)
    #
    # Returns a Boolean.
    def file_method?(attribute_name)
      @object.respond_to?("#{attribute_name}_attachment") ||
        @object.respond_to?("#{attribute_name}_attachments") ||
        @object.respond_to?("remote_#{attribute_name}_url") ||
        @object.respond_to?("#{attribute_name}_attacher") ||
        @object.respond_to?("#{attribute_name}_file_name")
    end

    def find_attribute_column(attribute_name)
      if @object.respond_to?(:type_for_attribute) && @object.has_attribute?(attribute_name)
        detected_type = @object.type_for_attribute(attribute_name.to_s)

        # Some attributes like ActiveRecord::Encryption::EncryptedAttribute are detected
        # as different type, in that case we need to use the original type
        detected_type.respond_to?(:cast_type) ? detected_type.cast_type : detected_type
      elsif @object.respond_to?(:column_for_attribute) && @object.has_attribute?(attribute_name)
        @object.column_for_attribute(attribute_name)
      end
    end

    def find_association_reflection(association)
      if @object.class.respond_to?(:reflect_on_association)
        @object.class.reflect_on_association(association)
      end
    end

    # Attempts to find a mapping. It follows the following rules:
    #
    # 1) It tries to find a registered mapping, if succeeds:
    #    a) Try to find an alternative with the same name in the Object scope
    #    b) Or use the found mapping
    # 2) If not, fallbacks to #{input_type}Input
    # 3) If not, fallbacks to SimpleForm::Inputs::#{input_type}Input
    def find_mapping(input_type)
      discovery_cache[input_type] ||=
        if mapping = self.class.mappings[input_type]
          mapping_override(mapping) || mapping
        else
          camelized = "#{input_type.to_s.camelize}Input"
          attempt_mapping_with_custom_namespace(camelized) ||
            attempt_mapping(camelized, Object) ||
            attempt_mapping(camelized, self.class) ||
            raise("No input found for #{input_type}")
        end
    end

    # Attempts to find a wrapper mapping. It follows the following rules:
    #
    # 1) It tries to find a wrapper for the current form
    # 2) If not, it tries to find a config
    def find_wrapper_mapping(input_type)
      if options[:wrapper_mappings] && options[:wrapper_mappings][input_type]
        options[:wrapper_mappings][input_type]
      else
        SimpleForm.wrapper_mappings && SimpleForm.wrapper_mappings[input_type]
      end
    end

    def find_wrapper(input_type, options)
      if name = options[:wrapper] || find_wrapper_mapping(input_type)
        name.respond_to?(:render) ? name : SimpleForm.wrapper(name)
      else
        wrapper
      end
    end

    # If cache_discovery is enabled, use the class level cache that persists
    # between requests, otherwise use the instance one.
    def discovery_cache
      if SimpleForm.cache_discovery
        self.class.discovery_cache
      else
        @discovery_cache ||= {}
      end
    end

    def mapping_override(klass)
      name = klass.name
      if name =~ /^SimpleForm::Inputs/
        input_name = name.split("::").last
        attempt_mapping_with_custom_namespace(input_name) ||
          attempt_mapping(input_name, Object)
      end
    end

    def attempt_mapping(mapping, at)
      return if SimpleForm.inputs_discovery == false && at == Object

      begin
        at.const_get(mapping)
      rescue NameError => e
        raise unless e.message.include?(mapping)
      end
    end

    def attempt_mapping_with_custom_namespace(input_name)
      SimpleForm.custom_inputs_namespaces.each do |namespace|
        if (mapping = attempt_mapping(input_name, namespace.constantize))
          return mapping
        end
      end

      nil
    end

    def build_input_field_components(components)
      components.map do |component|
        if component == :input
          SimpleForm::Wrappers::Leaf.new(component, build_input_field_options)
        else
          SimpleForm::Wrappers::Leaf.new(component)
        end
      end
    end

    def build_input_field_options
      input_field_options = {}
      valid_class         = SimpleForm.input_field_valid_class
      error_class         = SimpleForm.input_field_error_class

      if error_class.present?
        input_field_options[:error_class] = error_class
      end

      if valid_class.present?
        input_field_options[:valid_class] = valid_class
      end

      input_field_options
    end
  end
end


================================================
FILE: lib/simple_form/helpers/autofocus.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Helpers
    module Autofocus
      private

      def has_autofocus?
        options[:autofocus] == true
      end
    end
  end
end


================================================
FILE: lib/simple_form/helpers/disabled.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Helpers
    module Disabled
      private

      def has_disabled?
        options[:disabled] == true
      end

      def disabled_class
        :disabled if has_disabled?
      end
    end
  end
end


================================================
FILE: lib/simple_form/helpers/readonly.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Helpers
    module Readonly
      private

      def readonly_class
        :readonly if has_readonly?
      end

      def has_readonly?
        options[:readonly] == true
      end
    end
  end
end


================================================
FILE: lib/simple_form/helpers/required.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Helpers
    module Required
      private

      def required_field?
        @required
      end

      def calculate_required
        if !options[:required].nil?
          options[:required]
        elsif has_validators?
          required_by_validators?
        else
          required_by_default?
        end
      end

      def required_by_validators?
        (attribute_validators + reflection_validators).any? { |v| v.kind == :presence && valid_validator?(v) }
      end

      def required_by_default?
        SimpleForm.required_by_default
      end

      # Do not use has_required? because we want to add the class
      # regardless of the required option.
      def required_class
        required_field? ? :required : :optional
      end
    end
  end
end


================================================
FILE: lib/simple_form/helpers/validators.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Helpers
    module Validators
      def has_validators?
        @has_validators ||= attribute_name && object.class.respond_to?(:validators_on)
      end

      private

      def attribute_validators
        object.class.validators_on(attribute_name)
      end

      def reflection_validators
        reflection ? object.class.validators_on(reflection.name) : []
      end

      def valid_validator?(validator)
        !conditional_validators?(validator) && action_validator_match?(validator)
      end

      def conditional_validators?(validator)
        validator.options.include?(:if) || validator.options.include?(:unless)
      end

      def action_validator_match?(validator)
        return true unless validator.options.include?(:on)

        case validator.options[:on]
        when :save
          true
        when :create
          !object.persisted?
        when :update
          object.persisted?
        end
      end

      def find_validator(kind)
        attribute_validators.find { |v| v.kind == kind } if has_validators?
      end

      # Implements `ActiveModel::Validations::ResolveValue`, introduced by Rails 7.1.
      # https://github.com/rails/rails/blob/v7.1.0/activemodel/lib/active_model/validations/resolve_value.rb
      def resolve_validator_value(value)
        case value
        when Proc
          if value.arity == 0
            value.call
          else
            value.call(object)
          end
        when Symbol
          object.send(value)
        else
          if value.respond_to?(:call)
            value.call(object)
          else
            value
          end
        end
      end
    end
  end
end


================================================
FILE: lib/simple_form/helpers.rb
================================================
# frozen_string_literal: true
module SimpleForm
  # Helpers are made of several helpers that cannot be turned on automatically.
  # For instance, disabled cannot be turned on automatically, it requires the
  # user to explicitly pass the option disabled: true so it may work.
  module Helpers
    autoload :Autofocus,  'simple_form/helpers/autofocus'
    autoload :Disabled,   'simple_form/helpers/disabled'
    autoload :Readonly,   'simple_form/helpers/readonly'
    autoload :Required,   'simple_form/helpers/required'
    autoload :Validators, 'simple_form/helpers/validators'
  end
end


================================================
FILE: lib/simple_form/inputs/base.rb
================================================
# frozen_string_literal: true
require 'active_support/core_ext/string/output_safety'
require 'action_view/helpers'

module SimpleForm
  module Inputs
    class Base
      include ERB::Util
      include ActionView::Helpers::TranslationHelper

      include SimpleForm::Helpers::Autofocus
      include SimpleForm::Helpers::Disabled
      include SimpleForm::Helpers::Readonly
      include SimpleForm::Helpers::Required
      include SimpleForm::Helpers::Validators

      include SimpleForm::Components::Errors
      include SimpleForm::Components::Hints
      include SimpleForm::Components::HTML5
      include SimpleForm::Components::LabelInput
      include SimpleForm::Components::Maxlength
      include SimpleForm::Components::Minlength
      include SimpleForm::Components::MinMax
      include SimpleForm::Components::Pattern
      include SimpleForm::Components::Placeholders
      include SimpleForm::Components::Readonly

      attr_reader :attribute_name, :column, :input_type, :reflection,
                  :options, :input_html_options, :input_html_classes, :html_classes

      delegate :template, :object, :object_name, :lookup_model_names, :lookup_action, to: :@builder

      class_attribute :default_options
      self.default_options = {}

      def self.enable(*keys)
        options = self.default_options.dup
        keys.each { |key| options.delete(key) }
        self.default_options = options
      end

      def self.disable(*keys)
        options = self.default_options.dup
        keys.each { |key| options[key] = false }
        self.default_options = options
      end

      # Always enabled.
      enable :hint

      # Usually disabled, needs to be enabled explicitly passing true as option.
      disable :maxlength, :minlength, :placeholder, :pattern, :min_max

      def initialize(builder, attribute_name, column, input_type, options = {})
        super

        options         = options.dup
        @builder        = builder
        @attribute_name = attribute_name
        @column         = column
        @input_type     = input_type
        @reflection     = options.delete(:reflection)
        @options        = options.reverse_merge!(self.class.default_options)
        @required       = calculate_required

        # Notice that html_options_for receives a reference to input_html_classes.
        # This means that classes added dynamically to input_html_classes will
        # still propagate to input_html_options.
        @html_classes = SimpleForm.additional_classes_for(:input) { additional_classes }

        @input_html_classes = @html_classes.dup

        input_html_classes = self.input_html_classes

        if SimpleForm.input_class && input_html_classes.any?
          input_html_classes << SimpleForm.input_class
        end

        @input_html_options = html_options_for(:input, input_html_classes).tap do |o|
          o[:readonly]  = true if has_readonly?
          o[:disabled]  = true if has_disabled?
          o[:autofocus] = true if has_autofocus?
        end
      end

      def input(wrapper_options = nil)
        raise NotImplementedError
      end

      def input_options
        options
      end

      def additional_classes
        @additional_classes ||= [input_type, required_class, readonly_class, disabled_class].compact
      end

      def input_class
        "#{lookup_model_names.join('_')}_#{reflection_or_attribute_name}"
      end

      private

      def limit
        if column
          decimal_or_float? ? decimal_limit : column_limit
        end
      end

      def column_limit
        column.limit
      end

      # Add one for decimal point
      def decimal_limit
        column_limit && (column_limit + 1)
      end

      def decimal_or_float?
        column.type == :float || column.type == :decimal
      end

      def nested_boolean_style?
        options.fetch(:boolean_style, SimpleForm.boolean_style) == :nested
      end

      # Find reflection name when available, otherwise use attribute
      def reflection_or_attribute_name
        @reflection_or_attribute_name ||= reflection ? reflection.name : attribute_name
      end

      # Retrieve options for the given namespace from the options hash
      def html_options_for(namespace, css_classes)
        html_options = options[:"#{namespace}_html"]
        html_options = html_options ? html_options.dup : {}
        css_classes << html_options[:class] if html_options.key?(:class)
        html_options[:class] = css_classes unless css_classes.empty?
        html_options
      end

      # Lookup translations for the given namespace using I18n, based on object name,
      # actual action and attribute name. Lookup priority as follows:
      #
      #   simple_form.{namespace}.{model}.{action}.{attribute}
      #   simple_form.{namespace}.{model}.{attribute}
      #   simple_form.{namespace}.defaults.{attribute}
      #
      #  Namespace is used for :labels and :hints.
      #
      #  Model is the actual object name, for a @user object you'll have :user.
      #  Action is the action being rendered, usually :new or :edit.
      #  And attribute is the attribute itself, :name for example.
      #
      #  The lookup for nested attributes is also done in a nested format using
      #  both model and nested object names, such as follow:
      #
      #   simple_form.{namespace}.{model}.{nested}.{action}.{attribute}
      #   simple_form.{namespace}.{model}.{nested}.{attribute}
      #   simple_form.{namespace}.{nested}.{action}.{attribute}
      #   simple_form.{namespace}.{nested}.{attribute}
      #   simple_form.{namespace}.defaults.{attribute}
      #
      #  Example:
      #
      #    simple_form:
      #      labels:
      #        user:
      #          new:
      #            email: 'E-mail para efetuar o sign in.'
      #          edit:
      #            email: 'E-mail.'
      #
      #  Take a look at our locale example file.
      def translate_from_namespace(namespace, default = '')
        model_names = lookup_model_names.dup
        lookups     = []

        while !model_names.empty?
          joined_model_names = model_names.join(".")
          model_names.shift

          lookups << :"#{joined_model_names}.#{lookup_action}.#{reflection_or_attribute_name}"
          lookups << :"#{joined_model_names}.#{reflection_or_attribute_name}"
        end
        lookups << :"defaults.#{lookup_action}.#{reflection_or_attribute_name}"
        lookups << :"defaults.#{reflection_or_attribute_name}"
        lookups << default

        I18n.t(lookups.shift, scope: :"#{i18n_scope}.#{namespace}", default: lookups).presence
      end

      def merge_wrapper_options(options, wrapper_options)
        if wrapper_options
          wrapper_options = set_input_classes(wrapper_options)

          wrapper_options.merge(options) do |key, oldval, newval|
            case key.to_s
            when "class"
              Array(oldval) + Array(newval)
            when "data", "aria"
              oldval.merge(newval)
            else
              newval
            end
          end
        else
          options
        end
      end

      def set_input_classes(wrapper_options)
        wrapper_options = wrapper_options.dup
        error_class     = wrapper_options.delete(:error_class)
        valid_class     = wrapper_options.delete(:valid_class)

        if error_class.present? && has_errors?
          wrapper_options[:class] = "#{wrapper_options[:class]} #{error_class}"
        end

        if valid_class.present? && valid?
          wrapper_options[:class] = "#{wrapper_options[:class]} #{valid_class}"
        end

        wrapper_options
      end

      def i18n_scope
        SimpleForm.i18n_scope
      end
    end
  end
end


================================================
FILE: lib/simple_form/inputs/block_input.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Inputs
    class BlockInput < Base
      def initialize(*args, &block)
        super
        @block = block
      end

      def input(wrapper_options = nil)
        template.capture(&@block)
      end
    end
  end
end


================================================
FILE: lib/simple_form/inputs/boolean_input.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Inputs
    class BooleanInput < Base
      def input(wrapper_options = nil)
        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)

        if nested_boolean_style?
          build_hidden_field_for_checkbox +
            template.label_tag(nil, class: boolean_label_class) {
              build_check_box_without_hidden_field(merged_input_options) +
                inline_label
            }
        else
          if include_hidden?
            build_check_box(unchecked_value, merged_input_options)
          else
            build_check_box_without_hidden_field(merged_input_options)
          end
        end
      end

      def label_input(wrapper_options = nil)
        if options[:label] == false || inline_label?
          input(wrapper_options)
        elsif nested_boolean_style?
          html_options = label_html_options.dup
          html_options[:class] ||= []
          html_options[:class].push(boolean_label_class) if boolean_label_class

          merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)

          build_hidden_field_for_checkbox +
            @builder.label(label_target, html_options) {
              build_check_box_without_hidden_field(merged_input_options) + label_text
            }
        else
          input(wrapper_options) + label(wrapper_options)
        end
      end

      private

      def boolean_label_class
        options[:boolean_label_class] || SimpleForm.boolean_label_class
      end

      # Build a checkbox tag using default unchecked value. This allows us to
      # reuse the method for nested boolean style, but with no unchecked value,
      # which won't generate the hidden checkbox. This is the default functionality
      # in Rails > 3.2.1, and is backported in SimpleForm AV helpers.
      def build_check_box(unchecked_value, options)
        @builder.check_box(attribute_name, options, checked_value, unchecked_value)
      end

      # Build a checkbox without generating the hidden field. See
      # #build_hidden_field_for_checkbox for more info.
      def build_check_box_without_hidden_field(options)
        build_check_box(nil, options)
      end

      # Create a hidden field for the current checkbox, so we can simulate Rails
      # functionality with hidden + checkbox, but under a nested context, where
      # we need the hidden field to be *outside* the label (otherwise it
      # generates invalid html - html5 only).
      def build_hidden_field_for_checkbox
        return "".html_safe if !include_hidden? || !unchecked_value
        options = { value: unchecked_value, id: nil, disabled: input_html_options[:disabled] }
        options[:name] = input_html_options[:name] if input_html_options.key?(:name)
        options[:form] = input_html_options[:form] if input_html_options.key?(:form)

        @builder.hidden_field(attribute_name, options)
      end

      def inline_label?
        nested_boolean_style? && options[:inline_label]
      end

      def inline_label
        inline_option = options[:inline_label]

        if inline_option
          label = inline_option == true ? label_text : html_escape(inline_option)
          " #{label}".html_safe
        end
      end

      # Booleans are not required by default because in most of the cases
      # it makes no sense marking them as required. The only exception is
      # Terms of Use usually presented at most sites sign up screen.
      def required_by_default?
        false
      end

      def include_hidden?
        options.fetch(:include_hidden, true)
      end

      def checked_value
        options.fetch(:checked_value, '1')
      end

      def unchecked_value
        options.fetch(:unchecked_value, '0')
      end
    end
  end
end


================================================
FILE: lib/simple_form/inputs/collection_check_boxes_input.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Inputs
    class CollectionCheckBoxesInput < CollectionRadioButtonsInput
      protected

      # Checkbox components do not use the required html tag.
      # More info: https://github.com/heartcombo/simple_form/issues/340#issuecomment-2871956
      def has_required?
        false
      end

      def build_nested_boolean_style_item_tag(collection_builder)
        collection_builder.check_box + collection_builder.text.to_s
      end

      def item_wrapper_class
        "checkbox"
      end
    end
  end
end


================================================
FILE: lib/simple_form/inputs/collection_input.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Inputs
    class CollectionInput < Base
      BASIC_OBJECT_CLASSES = [String, Integer, Float, NilClass, Symbol, TrueClass, FalseClass]
      BASIC_OBJECT_CLASSES.push(Fixnum, Bignum) unless 1.class == Integer

      # Default boolean collection for use with selects/radios when no
      # collection is given. Always fallback to this boolean collection.
      # Texts can be translated using i18n in "simple_form.yes" and
      # "simple_form.no" keys. See the example locale file.
      def self.boolean_collection
        [ [I18n.t(:"simple_form.yes", default: 'Yes'), true],
          [I18n.t(:"simple_form.no", default: 'No'), false] ]
      end

      def input(wrapper_options = nil)
        raise NotImplementedError,
          "input should be implemented by classes inheriting from CollectionInput"
      end

      def input_options
        options = super

        options[:include_blank] = true unless skip_include_blank?
        translate_option options, :prompt
        translate_option options, :include_blank

        options
      end

      private

      def collection
        @collection ||= begin
          collection = options.delete(:collection) || self.class.boolean_collection
          collection.respond_to?(:call) ? collection.call : collection.to_a
        end
      end

      def has_required?
        super && (input_options[:include_blank] || input_options[:prompt].present? || multiple?)
      end

      # Check if :include_blank must be included by default.
      def skip_include_blank?
        (options.keys & %i[prompt include_blank default selected]).any? || multiple?
      end

      def multiple?
        !!options[:input_html].try(:[], :multiple)
      end

      # Detect the right method to find the label and value for a collection.
      # If no label or value method are defined, will attempt to find them based
      # on default label and value methods that can be configured through
      # SimpleForm.collection_label_methods and
      # SimpleForm.collection_value_methods.
      def detect_collection_methods
        label, value = options.delete(:label_method), options.delete(:value_method)

        unless label && value
          common_method_for = detect_common_display_methods
          label ||= common_method_for[:label]
          value ||= common_method_for[:value]
        end

        [label, value]
      end

      def detect_common_display_methods(collection_classes = detect_collection_classes)
        collection_translated = translate_collection if collection_classes == [Symbol]

        if collection_translated || collection_classes.include?(Array)
          { label: :first, value: :second }
        elsif collection_includes_basic_objects?(collection_classes)
          { label: :to_s, value: :to_s }
        else
          detect_method_from_class(collection_classes)
        end
      end

      def detect_method_from_class(collection_classes)
        sample = collection.first || collection.last

        { label: SimpleForm.collection_label_methods.find { |m| sample.respond_to?(m) },
          value: SimpleForm.collection_value_methods.find { |m| sample.respond_to?(m) } }
      end

      def detect_collection_classes(some_collection = collection)
        some_collection.map(&:class).uniq
      end

      def collection_includes_basic_objects?(collection_classes)
        (collection_classes & BASIC_OBJECT_CLASSES).any?
      end

      def translate_collection
        if translated_collection = translate_from_namespace(:options)
          @collection = collection.map do |key|
            html_key = "#{key}_html".to_sym

            if translated_collection[html_key]
              [translated_collection[html_key].html_safe || key, key.to_s]
            else
              [translated_collection[key] || key, key.to_s]
            end
          end
          true
        end
      end

      def translate_option(options, key)
        if options[key] == :translate
          namespace = key.to_s.pluralize

          options[key] = translate_from_namespace(namespace, true)
        end
      end
    end
  end
end


================================================
FILE: lib/simple_form/inputs/collection_radio_buttons_input.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Inputs
    class CollectionRadioButtonsInput < CollectionInput
      def input(wrapper_options = nil)
        label_method, value_method = detect_collection_methods

        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)

        @builder.send(:"collection_#{input_type}",
          attribute_name, collection, value_method, label_method,
          input_options, merged_input_options,
          &collection_block_for_nested_boolean_style
        )
      end

      def input_options
        options = super
        apply_default_collection_options!(options)
        options
      end

      protected

      def apply_default_collection_options!(options)
        options[:item_wrapper_tag] ||= options.fetch(:item_wrapper_tag, SimpleForm.item_wrapper_tag)
        options[:item_wrapper_class] = [
          item_wrapper_class, options[:item_wrapper_class], SimpleForm.item_wrapper_class
        ].compact.presence if SimpleForm.include_default_input_wrapper_class

        options[:collection_wrapper_tag] ||= options.fetch(:collection_wrapper_tag, SimpleForm.collection_wrapper_tag)
        options[:collection_wrapper_class] = [
          options[:collection_wrapper_class], SimpleForm.collection_wrapper_class
        ].compact.presence
      end

      def collection_block_for_nested_boolean_style
        return unless nested_boolean_style?

        proc { |builder| build_nested_boolean_style_item_tag(builder) }
      end

      def build_nested_boolean_style_item_tag(collection_builder)
        collection_builder.radio_button + collection_builder.text.to_s
      end

      def item_wrapper_class
        "radio"
      end

      # Do not attempt to generate label[for] attributes by default, unless an
      # explicit html option is given. This avoids generating labels pointing to
      # non existent fields.
      def generate_label_for_attribute?
        false
      end
    end
  end
end


================================================
FILE: lib/simple_form/inputs/collection_select_input.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Inputs
    class CollectionSelectInput < CollectionInput
      def input(wrapper_options = nil)
        label_method, value_method = detect_collection_methods

        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)

        @builder.collection_select(
          attribute_name, collection, value_method, label_method,
          input_options, merged_input_options
        )
      end
    end
  end
end


================================================
FILE: lib/simple_form/inputs/color_input.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Inputs
    class ColorInput < Base
      def input(wrapper_options = nil)
        input_html_options[:type] ||= "color" if html5?

        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)

        @builder.text_field(attribute_name, merged_input_options)
      end
    end
  end
end


================================================
FILE: lib/simple_form/inputs/date_time_input.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Inputs
    class DateTimeInput < Base
      def input(wrapper_options = nil)
        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)

        if use_html5_inputs?
          @builder.send(:"#{input_type}_field", attribute_name, merged_input_options)
        else
          @builder.send(:"#{input_type}_select", attribute_name, input_options, merged_input_options)
        end
      end

      private

      def label_target
        if use_html5_inputs?
          attribute_name
        else
          position = case input_type
          when :date, :datetime
            date_order = input_options[:order] || I18n.t('date.order')
            date_order.first.to_sym
          else
            :hour
          end

          position = ActionView::Helpers::DateTimeSelector::POSITION[position]
          "#{attribute_name}_#{position}i"
        end
      end

      def use_html5_inputs?
        input_options[:html5]
      end
    end
  end
end


================================================
FILE: lib/simple_form/inputs/file_input.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Inputs
    class FileInput < Base
      def input(wrapper_options = nil)
        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)

        @builder.file_field(attribute_name, merged_input_options)
      end
    end
  end
end


================================================
FILE: lib/simple_form/inputs/grouped_collection_select_input.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Inputs
    class GroupedCollectionSelectInput < CollectionInput
      def input(wrapper_options = nil)
        label_method, value_method = detect_collection_methods

        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)

        @builder.grouped_collection_select(attribute_name, grouped_collection,
                      group_method, group_label_method, value_method, label_method,
                      input_options, merged_input_options)
      end

      private

      def grouped_collection
        @grouped_collection ||= begin
          grouped_collection = options.delete(:collection)
          grouped_collection.respond_to?(:call) ? grouped_collection.call : grouped_collection.to_a
        end
      end

      # Sample collection
      def collection
        @collection ||= grouped_collection.map { |collection| group_method.respond_to?(:call) ? group_method.call(collection) : collection.try(:send, group_method) }.detect(&:present?) || []
      end

      def group_method
        @group_method ||= options.delete(:group_method)
      end

      def group_label_method
        label = options.delete(:group_label_method)

        unless label
          common_method_for = detect_common_display_methods(detect_collection_classes(grouped_collection))
          label = common_method_for[:label]
        end

        label
      end

      def detect_method_from_class(collection_classes)
        return {} if collection_classes.empty?

        sample = collection_classes.first

        { label: SimpleForm.collection_label_methods.find { |m| sample.instance_methods.include?(m) },
          value: SimpleForm.collection_value_methods.find { |m| sample.instance_methods.include?(m) } }
      end
    end
  end
end


================================================
FILE: lib/simple_form/inputs/hidden_input.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Inputs
    class HiddenInput < Base
      disable :label, :errors, :hint, :required

      def input(wrapper_options = nil)
        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)

        @builder.hidden_field(attribute_name, merged_input_options)
      end

      private

      def required_class
        nil
      end
    end
  end
end


================================================
FILE: lib/simple_form/inputs/numeric_input.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Inputs
    class NumericInput < Base
      enable :placeholder, :min_max

      def input(wrapper_options = nil)
        input_html_classes.unshift("numeric")
        if html5?
          input_html_options[:type] ||= "number"
          input_html_options[:step] ||= integer? ? 1 : "any"
        end

        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)

        @builder.text_field(attribute_name, merged_input_options)
      end
    end
  end
end


================================================
FILE: lib/simple_form/inputs/password_input.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Inputs
    class PasswordInput < Base
      enable :placeholder, :maxlength, :minlength

      def input(wrapper_options = nil)
        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)

        @builder.password_field(attribute_name, merged_input_options)
      end
    end
  end
end


================================================
FILE: lib/simple_form/inputs/priority_input.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Inputs
    class PriorityInput < CollectionSelectInput
      def input(wrapper_options = nil)
        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)

        send(:"#{input_type}_input", merged_input_options)
      end

      def input_priority
        options[:priority] || SimpleForm.send(:"#{input_type}_priority")
      end

      protected

      def country_input(merged_input_options)
        @builder.send(:country_select,
                      attribute_name,
                      input_options.merge(priority_countries: input_priority),
                      merged_input_options)
      end

      def time_zone_input(merged_input_options)
        @builder.send(:time_zone_select,
                      attribute_name,
                      input_priority,
                      input_options,
                      merged_input_options)
      end

      def skip_include_blank?
        super || input_priority.present?
      end
    end
  end
end


================================================
FILE: lib/simple_form/inputs/range_input.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Inputs
    class RangeInput < NumericInput
      def input(wrapper_options = nil)
        if html5?
          input_html_options[:type] ||= "range"
          input_html_options[:step] ||= 1
        end

        super
      end
    end
  end
end


================================================
FILE: lib/simple_form/inputs/rich_text_area_input.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Inputs
    class RichTextAreaInput < Base
      enable :placeholder

      def input(wrapper_options = nil)
        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)

        @builder.rich_text_area(attribute_name, merged_input_options)
      end
    end
  end
end


================================================
FILE: lib/simple_form/inputs/string_input.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Inputs
    class StringInput < Base
      enable :placeholder, :maxlength, :minlength, :pattern

      def input(wrapper_options = nil)
        unless string?
          input_html_classes.unshift("string")
          input_html_options[:type] ||= input_type if html5?
        end

        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)

        @builder.text_field(attribute_name, merged_input_options)
      end

      private

      def string?
        input_type == :string || input_type == :citext
      end
    end
  end
end


================================================
FILE: lib/simple_form/inputs/text_input.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Inputs
    class TextInput < Base
      enable :placeholder, :maxlength, :minlength

      def input(wrapper_options = nil)
        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)

        @builder.text_area(attribute_name, merged_input_options)
      end
    end
  end
end


================================================
FILE: lib/simple_form/inputs/weekday_input.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Inputs
    class WeekdayInput < CollectionSelectInput
      enable :placeholder

      def input(wrapper_options = nil)
        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)

        @builder.weekday_select(attribute_name, input_options, merged_input_options)
      end
    end
  end
end


================================================
FILE: lib/simple_form/inputs.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Inputs
    extend ActiveSupport::Autoload

    autoload :Base
    autoload :BlockInput
    autoload :BooleanInput
    autoload :CollectionCheckBoxesInput
    autoload :CollectionInput
    autoload :CollectionRadioButtonsInput
    autoload :CollectionSelectInput
    autoload :ColorInput
    autoload :DateTimeInput
    autoload :FileInput
    autoload :GroupedCollectionSelectInput
    autoload :HiddenInput
    autoload :NumericInput
    autoload :PasswordInput
    autoload :PriorityInput
    autoload :RangeInput
    autoload :RichTextAreaInput
    autoload :StringInput
    autoload :TextInput
    autoload :WeekdayInput
  end
end


================================================
FILE: lib/simple_form/map_type.rb
================================================
# frozen_string_literal: true
require 'active_support/core_ext/class/attribute'

module SimpleForm
  module MapType
    def self.extended(base)
      base.class_attribute :mappings
      base.mappings = {}
    end

    def map_type(*types)
      map_to = types.extract_options![:to]
      raise ArgumentError, "You need to give :to as option to map_type" unless map_to
      self.mappings = mappings.merge types.each_with_object({}) { |t, m| m[t] = map_to }
    end
  end
end


================================================
FILE: lib/simple_form/railtie.rb
================================================
# frozen_string_literal: true
require 'rails/railtie'

module SimpleForm
  class Railtie < Rails::Railtie
    config.eager_load_namespaces << SimpleForm

    config.after_initialize do
      unless SimpleForm.configured?
        warn '[Simple Form] Simple Form is not configured in the application and will use the default values.' +
          ' Use `rails generate simple_form:install` to generate the Simple Form configuration.'
      end
    end

    initializer "simple_form.deprecator" do |app|
      app.deprecators[:simple_form] = SimpleForm.deprecator if app.respond_to?(:deprecators)
    end
  end
end


================================================
FILE: lib/simple_form/tags.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Tags
    module CollectionExtensions
      private

      def render_collection
        item_wrapper_tag   = @options.fetch(:item_wrapper_tag, :span)
        item_wrapper_class = @options[:item_wrapper_class]

        @collection.map do |item|
          value = value_for_collection(item, @value_method)
          text  = value_for_collection(item, @text_method)
          default_html_options = default_html_options_for_collection(item, value)
          additional_html_options = option_html_attributes(item)

          rendered_item = yield item, value, text, default_html_options.merge(additional_html_options)

          if @options.fetch(:boolean_style, SimpleForm.boolean_style) == :nested
            label_options = default_html_options.slice(:index, :namespace)
            label_options['class'] = @options[:item_label_class]
            rendered_item = @template_object.label(@object_name, sanitize_attribute_name(value), rendered_item, label_options)
          end

          item_wrapper_tag ? @template_object.content_tag(item_wrapper_tag, rendered_item, class: item_wrapper_class) : rendered_item
        end.join.html_safe
      end

      def wrap_rendered_collection(collection)
        wrapper_tag = @options[:collection_wrapper_tag]

        if wrapper_tag
          wrapper_class = @options[:collection_wrapper_class]
          @template_object.content_tag(wrapper_tag, collection, class: wrapper_class)
        else
          collection
        end
      end
    end

    class CollectionRadioButtons < ActionView::Helpers::Tags::CollectionRadioButtons
      include CollectionExtensions

      def render
        wrap_rendered_collection(super)
      end

      private

      def render_component(builder)
        label_class = "#{@options[:item_label_class]} collection_radio_buttons".strip

        builder.radio_button + builder.label(class: label_class)
      end
    end

    class CollectionCheckBoxes < ActionView::Helpers::Tags::CollectionCheckBoxes
      include CollectionExtensions

      def render
        wrap_rendered_collection(super)
      end

      private

      def render_component(builder)
        label_class = "#{@options[:item_label_class]} collection_check_boxes".strip

        builder.check_box + builder.label(class: label_class)
      end
    end
  end
end


================================================
FILE: lib/simple_form/version.rb
================================================
# frozen_string_literal: true
module SimpleForm
  VERSION = "5.4.1".freeze
end


================================================
FILE: lib/simple_form/wrappers/builder.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Wrappers
    # Provides the builder syntax for components. The builder provides
    # three methods `use`, `optional` and `wrapper` and they allow the following invocations:
    #
    #     config.wrappers do |b|
    #       # Use a single component
    #       b.use :html5
    #
    #       # Use the component, but do not automatically lookup. It will only be triggered when
    #       # :placeholder is explicitly set.
    #       b.optional :placeholder
    #
    #       # Use a component with specific wrapper options
    #       b.use :error, wrap_with: { tag: "span", class: "error" }
    #
    #       # Use a set of components by wrapping them in a tag+class.
    #       b.wrapper tag: "div", class: "another" do |ba|
    #         ba.use :label
    #         ba.use :input
    #       end
    #
    #       # Use a set of components by wrapping them in a tag+class.
    #       # This wrapper is identified by :label_input, which means it can
    #       # be turned off on demand with `f.input :name, label_input: false`
    #       b.wrapper :label_input, tag: "div", class: "another" do |ba|
    #         ba.use :label
    #         ba.use :input
    #       end
    #     end
    #
    # The builder also accepts default options at the root level. This is usually
    # used if you want a component to be disabled by default:
    #
    #     config.wrappers hint: false do |b|
    #       b.use :hint
    #       b.use :label_input
    #     end
    #
    # In the example above, hint defaults to false, which means it won't automatically
    # do the lookup anymore. It will only be triggered when :hint is explicitly set.
    class Builder
      def initialize(options)
        @options    = options
        @components = []
      end

      def use(name, options = {})
        if options && wrapper = options[:wrap_with]
          @components << Single.new(name, wrapper, options.except(:wrap_with))
        else
          @components << Leaf.new(name, options)
        end
      end

      def optional(name, options = {}, &block)
        @options[name] = false
        use(name, options)
      end

      def wrapper(name, options = nil)
        if block_given?
          name, options = nil, name if name.is_a?(Hash)
          builder = self.class.new(@options)
          options ||= {}
          options[:tag] = :div if options[:tag].nil?
          yield builder
          @components << Many.new(name, builder.to_a, options)
        else
          raise ArgumentError, "A block is required as argument to wrapper"
        end
      end

      def to_a
        @components
      end
    end
  end
end


================================================
FILE: lib/simple_form/wrappers/leaf.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Wrappers
    class Leaf
      attr_reader :namespace

      def initialize(namespace, options = {})
        @namespace = namespace
        @options = options
      end

      def render(input)
        method = input.method(@namespace)

        if method.arity.zero?
          SimpleForm.deprecator.warn(SimpleForm::CUSTOM_INPUT_DEPRECATION_WARN % { name: @namespace })

          method.call
        else
          method.call(@options)
        end
      end

      def find(name)
        self if @namespace == name
      end
    end
  end
end


================================================
FILE: lib/simple_form/wrappers/many.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Wrappers
    # A wrapper is an object that holds several components and render them.
    # A component may be any object that responds to `render`.
    # This API allows inputs/components to be easily wrapped, removing the
    # need to modify the code only to wrap input in an extra tag.
    #
    # `Many` represents a wrapper around several components at the same time.
    # It may optionally receive a namespace, allowing it to be configured
    # on demand on input generation.
    class Many
      attr_reader :namespace, :defaults, :components

      def initialize(namespace, components, defaults = {})
        @namespace  = namespace
        @components = components
        @defaults   = defaults
        @defaults[:tag]   = :div unless @defaults.key?(:tag)
        @defaults[:class] = Array(@defaults[:class])
      end

      def render(input)
        content = "".html_safe
        options = input.options

        components.each do |component|
          next if options[component.namespace] == false
          rendered = component.render(input)
          content.safe_concat rendered.to_s if rendered
        end

        wrap(input, options, content)
      end

      def find(name)
        return self if namespace == name

        @components.each do |c|
          if c.is_a?(Symbol)
            return nil if c == namespace
          elsif value = c.find(name)
            return value
          end
        end

        nil
      end

      private

      def wrap(input, options, content)
        return content if options[namespace] == false
        return if defaults[:unless_blank] && content.empty?

        tag = (namespace && options[:"#{namespace}_tag"]) || @defaults[:tag]
        return content unless tag

        klass = html_classes(input, options)
        opts  = html_options(options)
        opts[:class] = (klass << opts[:class]).join(' ').strip unless klass.empty?
        input.template.content_tag(tag, content, opts)
      end

      def html_options(options)
        (@defaults[:html] || {}).merge(options[:"#{namespace}_html"] || {})
      end

      def html_classes(input, options)
        @defaults[:class].dup
      end
    end
  end
end


================================================
FILE: lib/simple_form/wrappers/root.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Wrappers
    # `Root` is the root wrapper for all components. It is special cased to
    # always have a namespace and to add special html classes.
    class Root < Many
      attr_reader :options

      def initialize(*args)
        super(:wrapper, *args)
        @options = @defaults.except(:tag, :class, :error_class, :hint_class)
      end

      def render(input)
        input.options.reverse_merge!(@options)
        super
      end

      # Provide a fallback if name cannot be found.
      def find(name)
        super || SimpleForm::Wrappers::Many.new(name, [Leaf.new(name)])
      end

      private

      def html_classes(input, options)
        css = options[:wrapper_class] ? Array(options[:wrapper_class]) : @defaults[:class]
        css += SimpleForm.additional_classes_for(:wrapper) do
          input.additional_classes + [input.input_class]
        end
        css << html_class(:error_class, options) { input.has_errors? }
        css << html_class(:hint_class, options) { input.has_hint? }
        css << html_class(:valid_class, options) { input.valid? }
        css.compact
      end

      def html_class(key, options)
        css = (options[:"wrapper_#{key}"] || @defaults[key])
        css if css && yield
      end
    end
  end
end


================================================
FILE: lib/simple_form/wrappers/single.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Wrappers
    # `Single` is an optimization for a wrapper that has only one component.
    class Single < Many
      def initialize(name, wrapper_options = {}, options = {})
        @component = Leaf.new(name, options)

        super(name, [@component], wrapper_options)
      end

      def render(input)
        options = input.options
        if options[namespace] != false
          content = @component.render(input)
          wrap(input, options, content) if content
        end
      end

      private

      def html_options(options)
        %i[label input].include?(namespace) ? {} : super
      end
    end
  end
end


================================================
FILE: lib/simple_form/wrappers.rb
================================================
# frozen_string_literal: true
module SimpleForm
  module Wrappers
    autoload :Builder, 'simple_form/wrappers/builder'
    autoload :Many,    'simple_form/wrappers/many'
    autoload :Root,    'simple_form/wrappers/root'
    autoload :Single,  'simple_form/wrappers/single'
    autoload :Leaf,    'simple_form/wrappers/leaf'
  end
end


================================================
FILE: lib/simple_form.rb
================================================
# frozen_string_literal: true
require 'action_view'
require 'action_pack'
require 'simple_form/action_view_extensions/form_helper'
require 'simple_form/action_view_extensions/builder'
require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/hash/reverse_merge'

module SimpleForm
  extend ActiveSupport::Autoload

  autoload :Helpers
  autoload :Wrappers

  eager_autoload do
    autoload :Components
    autoload :ErrorNotification
    autoload :FormBuilder
    autoload :Inputs
  end

  def self.eager_load!
    super
    SimpleForm::Inputs.eager_load!
    SimpleForm::Components.eager_load!
  end

  CUSTOM_INPUT_DEPRECATION_WARN = <<-WARN
%{name} method now accepts a `wrapper_options` argument. The method definition without the argument is deprecated and will be removed in the next Simple Form version. Change your code from:

    def %{name}

to

    def %{name}(wrapper_options)

See https://github.com/heartcombo/simple_form/pull/997 for more information.
  WARN

  FILE_METHODS_DEPRECATION_WARN = <<-WARN
[SIMPLE_FORM] SimpleForm.file_methods is deprecated and has no effect.

Since version 5, Simple Form now supports automatically discover of file inputs for the following Gems: activestorage, carrierwave, paperclip, refile and shrine.
If you are using a custom method that is not from one of the supported Gems, please change your forms to pass the input type explicitly:

    <%= form.input :avatar, as: :file %>

See http://blog.plataformatec.com.br/2019/09/incorrect-access-control-in-simple-form-cve-2019-16676 for more information.
  WARN

  @@configured = false

  def self.configured? #:nodoc:
    @@configured
  end

  def self.deprecator
    @deprecator ||= ActiveSupport::Deprecation.new("5.3", "SimpleForm")
  end

  ## CONFIGURATION OPTIONS

  # Method used to tidy up errors.
  mattr_accessor :error_method
  @@error_method = :first

  # Default tag used for error notification helper.
  mattr_accessor :error_notification_tag
  @@error_notification_tag = :p

  # CSS class to add for error notification helper.
  mattr_accessor :error_notification_class
  @@error_notification_class = :error_notification

  # Series of attempts to detect a default label method for collection.
  mattr_accessor :collection_label_methods
  @@collection_label_methods = %i[to_label name title to_s]

  # Series of attempts to detect a default value method for collection.
  mattr_accessor :collection_value_methods
  @@collection_value_methods = %i[id to_s]

  # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none.
  mattr_accessor :collection_wrapper_tag
  @@collection_wrapper_tag = nil

  # You can define the class to use on all collection wrappers, defaulting to none.
  mattr_accessor :collection_wrapper_class
  @@collection_wrapper_class = nil

  # You can wrap each item in a collection of radio/check boxes with a tag,
  # defaulting to span. Please note that when using :boolean_style = :nested,
  # SimpleForm will force this option to be a :label.
  mattr_accessor :item_wrapper_tag
  @@item_wrapper_tag = :span

  # You can define the class to use on all item wrappers, defaulting to none.
  mattr_accessor :item_wrapper_class
  @@item_wrapper_class = nil

  # How the label text should be generated altogether with the required text.
  mattr_accessor :label_text
  @@label_text = ->(label, required, explicit_label) { "#{required} #{label}" }

  # You can define the class to be used on all labels. Defaults to none.
  mattr_accessor :label_class
  @@label_class = nil

  # Define the way to render check boxes / radio buttons with labels.
  #   inline: input + label (default)
  #   nested: label > input
  mattr_accessor :boolean_style
  @@boolean_style = :inline

  # DEPRECATED: You can define the class to be used on all forms. Default is
  # simple_form.
  mattr_reader :form_class
  @@form_class = :simple_form

  # You can define the default class to be used on all forms. Can be overridden
  # with `html: { :class }`. Defaults to none.
  mattr_accessor :default_form_class
  @@default_form_class = nil

  # You can define which elements should obtain additional classes.
  mattr_accessor :generate_additional_classes_for
  @@generate_additional_classes_for = %i[wrapper label input]

  # Whether attributes are required by default or not.
  mattr_accessor :required_by_default
  @@required_by_default = true

  # Tell browsers whether to use default HTML5 validations (novalidate option).
  mattr_accessor :browser_validations
  @@browser_validations = true

  # Custom mappings for input types. This should be a hash containing a regexp
  # to match as key, and the input type that will be used when the field name
  # matches the regexp as value, such as { /count/ => :integer }.
  mattr_accessor :input_mappings
  @@input_mappings = nil

  # Custom wrappers for input types. This should be a hash containing an input
  # type as key and the wrapper that will be used for all inputs with specified type.
  # e.g { string: :string_wrapper, boolean: :boolean_wrapper }
  # You can also set a wrapper mapping per form basis.
  # e.g simple_form_for(@foo, wrapper_mappings: { check_boxes: :bootstrap_checkbox })
  mattr_accessor :wrapper_mappings
  @@wrapper_mappings = nil

  # Namespaces where SimpleForm should look for custom input classes that override
  # default inputs. Namespaces are given as string to allow lazy loading inputs.
  # e.g. config.custom_inputs_namespaces << "CustomInputs"
  #      will try to find CustomInputs::NumericInput when an :integer
  #      field is called.
  mattr_accessor :custom_inputs_namespaces
  @@custom_inputs_namespaces = []

  # Default priority for time_zone inputs.
  mattr_accessor :time_zone_priority
  @@time_zone_priority = nil

  # Default priority for country inputs.
 
Download .txt
gitextract_7k1r7n03/

├── .github/
│   ├── code-scanning.yml
│   └── workflows/
│       └── test.yml
├── .gitignore
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Gemfile
├── ISSUE_TEMPLATE.md
├── MIT-LICENSE
├── README.md
├── Rakefile
├── bin/
│   └── test
├── gemfiles/
│   ├── Gemfile-rails-7-0
│   ├── Gemfile-rails-7-1
│   ├── Gemfile-rails-7-2
│   ├── Gemfile-rails-8-0
│   └── Gemfile-rails-main
├── lib/
│   ├── generators/
│   │   └── simple_form/
│   │       ├── USAGE
│   │       ├── install_generator.rb
│   │       └── templates/
│   │           ├── README
│   │           ├── _form.html.erb
│   │           ├── _form.html.haml
│   │           ├── _form.html.slim
│   │           └── config/
│   │               ├── initializers/
│   │               │   ├── simple_form.rb
│   │               │   ├── simple_form_bootstrap.rb
│   │               │   └── simple_form_foundation.rb
│   │               └── locales/
│   │                   └── simple_form.en.yml
│   ├── simple_form/
│   │   ├── action_view_extensions/
│   │   │   ├── builder.rb
│   │   │   └── form_helper.rb
│   │   ├── components/
│   │   │   ├── errors.rb
│   │   │   ├── hints.rb
│   │   │   ├── html5.rb
│   │   │   ├── label_input.rb
│   │   │   ├── labels.rb
│   │   │   ├── maxlength.rb
│   │   │   ├── min_max.rb
│   │   │   ├── minlength.rb
│   │   │   ├── pattern.rb
│   │   │   ├── placeholders.rb
│   │   │   └── readonly.rb
│   │   ├── components.rb
│   │   ├── error_notification.rb
│   │   ├── form_builder.rb
│   │   ├── helpers/
│   │   │   ├── autofocus.rb
│   │   │   ├── disabled.rb
│   │   │   ├── readonly.rb
│   │   │   ├── required.rb
│   │   │   └── validators.rb
│   │   ├── helpers.rb
│   │   ├── inputs/
│   │   │   ├── base.rb
│   │   │   ├── block_input.rb
│   │   │   ├── boolean_input.rb
│   │   │   ├── collection_check_boxes_input.rb
│   │   │   ├── collection_input.rb
│   │   │   ├── collection_radio_buttons_input.rb
│   │   │   ├── collection_select_input.rb
│   │   │   ├── color_input.rb
│   │   │   ├── date_time_input.rb
│   │   │   ├── file_input.rb
│   │   │   ├── grouped_collection_select_input.rb
│   │   │   ├── hidden_input.rb
│   │   │   ├── numeric_input.rb
│   │   │   ├── password_input.rb
│   │   │   ├── priority_input.rb
│   │   │   ├── range_input.rb
│   │   │   ├── rich_text_area_input.rb
│   │   │   ├── string_input.rb
│   │   │   ├── text_input.rb
│   │   │   └── weekday_input.rb
│   │   ├── inputs.rb
│   │   ├── map_type.rb
│   │   ├── railtie.rb
│   │   ├── tags.rb
│   │   ├── version.rb
│   │   ├── wrappers/
│   │   │   ├── builder.rb
│   │   │   ├── leaf.rb
│   │   │   ├── many.rb
│   │   │   ├── root.rb
│   │   │   └── single.rb
│   │   └── wrappers.rb
│   └── simple_form.rb
├── simple_form.gemspec
└── test/
    ├── action_view_extensions/
    │   ├── builder_test.rb
    │   └── form_helper_test.rb
    ├── components/
    │   ├── custom_components_test.rb
    │   └── label_test.rb
    ├── form_builder/
    │   ├── association_test.rb
    │   ├── button_test.rb
    │   ├── error_notification_test.rb
    │   ├── error_test.rb
    │   ├── general_test.rb
    │   ├── hint_test.rb
    │   ├── input_field_test.rb
    │   ├── label_test.rb
    │   └── wrapper_test.rb
    ├── generators/
    │   └── simple_form_generator_test.rb
    ├── inputs/
    │   ├── boolean_input_test.rb
    │   ├── collection_check_boxes_input_test.rb
    │   ├── collection_radio_buttons_input_test.rb
    │   ├── collection_select_input_test.rb
    │   ├── color_input_test.rb
    │   ├── country_input_test.rb
    │   ├── datetime_input_test.rb
    │   ├── disabled_test.rb
    │   ├── discovery_test.rb
    │   ├── file_input_test.rb
    │   ├── general_test.rb
    │   ├── grouped_collection_select_input_test.rb
    │   ├── hidden_input_test.rb
    │   ├── numeric_input_test.rb
    │   ├── readonly_test.rb
    │   ├── required_test.rb
    │   ├── rich_text_area_input_test.rb
    │   ├── string_input_test.rb
    │   ├── text_input_test.rb
    │   ├── time_zone_input_test.rb
    │   └── weekday_input_test.rb
    ├── simple_form_test.rb
    ├── support/
    │   ├── discovery_inputs.rb
    │   ├── misc_helpers.rb
    │   ├── mock_controller.rb
    │   └── models.rb
    └── test_helper.rb
Download .txt
SYMBOL INDEX (590 symbols across 96 files)

FILE: lib/generators/simple_form/install_generator.rb
  type SimpleForm (line 2) | module SimpleForm
    type Generators (line 3) | module Generators
      class InstallGenerator (line 4) | class InstallGenerator < Rails::Generators::Base
        method info_bootstrap (line 11) | def info_bootstrap
        method copy_config (line 18) | def copy_config
        method copy_scaffold_template (line 30) | def copy_scaffold_template
        method show_readme (line 35) | def show_readme

FILE: lib/simple_form.rb
  type SimpleForm (line 10) | module SimpleForm
    function eager_load! (line 23) | def self.eager_load!
    function configured? (line 54) | def self.configured? #:nodoc:
    function deprecator (line 58) | def self.deprecator
    function wrapper (line 221) | def self.wrapper(name)
    class WrapperNotFound (line 226) | class WrapperNotFound < StandardError
    function wrappers (line 231) | def self.wrappers(*args, &block)
    function build (line 242) | def self.build(options = {})
    function additional_classes_for (line 264) | def self.additional_classes_for(component)
    function default_input_size= (line 270) | def self.default_input_size=(*)
    function form_class= (line 274) | def self.form_class=(value)
    function file_methods= (line 279) | def self.file_methods=(file_methods)
    function file_methods (line 284) | def self.file_methods
    function setup (line 291) | def self.setup
    function include_component (line 331) | def self.include_component(component)

FILE: lib/simple_form/action_view_extensions/builder.rb
  type SimpleForm (line 2) | module SimpleForm
    type ActionViewExtensions (line 3) | module ActionViewExtensions
      type Builder (line 6) | module Builder
        function simple_fields_for (line 17) | def simple_fields_for(*args, &block)
  type ActionView::Helpers (line 34) | module ActionView::Helpers
    class FormBuilder (line 35) | class FormBuilder

FILE: lib/simple_form/action_view_extensions/form_helper.rb
  type SimpleForm (line 2) | module SimpleForm
    type ActionViewExtensions (line 3) | module ActionViewExtensions
      type FormHelper (line 12) | module FormHelper
        function simple_form_for (line 14) | def simple_form_for(record, options = {}, &block)
        function simple_fields_for (line 31) | def simple_fields_for(record_name, record_object = nil, options = ...
        function with_simple_form_field_error_proc (line 42) | def with_simple_form_field_error_proc
        function simple_form_css_class (line 52) | def simple_form_css_class(record, options)

FILE: lib/simple_form/components.rb
  type SimpleForm (line 2) | module SimpleForm
    type Components (line 9) | module Components

FILE: lib/simple_form/components/errors.rb
  type SimpleForm (line 2) | module SimpleForm
    type Components (line 3) | module Components
      type Errors (line 4) | module Errors
        function error (line 5) | def error(wrapper_options = nil)
        function full_error (line 9) | def full_error(wrapper_options = nil)
        function has_errors? (line 13) | def has_errors?
        function has_value? (line 17) | def has_value?
        function valid? (line 21) | def valid?
        function error_text (line 27) | def error_text
        function full_error_text (line 33) | def full_error_text
        function object_with_errors? (line 37) | def object_with_errors?
        function error_method (line 41) | def error_method
        function errors (line 45) | def errors
        function full_errors (line 49) | def full_errors
        function errors_on_attribute (line 53) | def errors_on_attribute
        function full_errors_on_attribute (line 57) | def full_errors_on_attribute
        function errors_on_association (line 61) | def errors_on_association
        function full_errors_on_association (line 65) | def full_errors_on_association
        function has_custom_error? (line 69) | def has_custom_error?

FILE: lib/simple_form/components/hints.rb
  type SimpleForm (line 2) | module SimpleForm
    type Components (line 3) | module Components
      type Hints (line 5) | module Hints
        function hint (line 6) | def hint(wrapper_options = nil)
        function has_hint? (line 19) | def has_hint?

FILE: lib/simple_form/components/html5.rb
  type SimpleForm (line 2) | module SimpleForm
    type Components (line 3) | module Components
      type HTML5 (line 4) | module HTML5
        function initialize (line 5) | def initialize(*)
        function html5 (line 9) | def html5(wrapper_options = nil)
        function html5? (line 17) | def html5?
        function input_html_required_option (line 21) | def input_html_required_option
        function has_required? (line 25) | def has_required?

FILE: lib/simple_form/components/label_input.rb
  type SimpleForm (line 2) | module SimpleForm
    type Components (line 3) | module Components
      type LabelInput (line 4) | module LabelInput
        function label_input (line 11) | def label_input(wrapper_options = nil)
        function deprecated_component (line 21) | def deprecated_component(namespace, wrapper_options)

FILE: lib/simple_form/components/labels.rb
  type SimpleForm (line 2) | module SimpleForm
    type Components (line 3) | module Components
      type Labels (line 4) | module Labels
        type ClassMethods (line 7) | module ClassMethods #:nodoc:
          function translate_required_html (line 8) | def translate_required_html
          function translate_required_text (line 14) | def translate_required_text
          function translate_required_mark (line 18) | def translate_required_mark
          function i18n_scope (line 24) | def i18n_scope
        function label (line 29) | def label(wrapper_options = nil)
        function label_text (line 39) | def label_text(wrapper_options = nil)
        function label_target (line 44) | def label_target
        function label_html_options (line 48) | def label_html_options
        function raw_label_text (line 63) | def raw_label_text #:nodoc:
        function required_label_text (line 68) | def required_label_text #:nodoc:
        function label_translation (line 73) | def label_translation #:nodoc:
        function generate_label_for_attribute? (line 83) | def generate_label_for_attribute?

FILE: lib/simple_form/components/maxlength.rb
  type SimpleForm (line 2) | module SimpleForm
    type Components (line 3) | module Components
      type Maxlength (line 5) | module Maxlength
        function maxlength (line 6) | def maxlength(wrapper_options = nil)
        function maximum_length_from_validation (line 13) | def maximum_length_from_validation
        function find_length_validator (line 23) | def find_length_validator
        function maximum_length_value_from (line 27) | def maximum_length_value_from(length_validator)

FILE: lib/simple_form/components/min_max.rb
  type SimpleForm (line 2) | module SimpleForm
    type Components (line 3) | module Components
      type MinMax (line 4) | module MinMax
        function min_max (line 5) | def min_max(wrapper_options = nil)
        function integer? (line 16) | def integer?
        function minimum_value (line 20) | def minimum_value(validator_options)
        function maximum_value (line 28) | def maximum_value(validator_options)
        function find_numericality_validator (line 36) | def find_numericality_validator

FILE: lib/simple_form/components/minlength.rb
  type SimpleForm (line 2) | module SimpleForm
    type Components (line 3) | module Components
      type Minlength (line 5) | module Minlength
        function minlength (line 6) | def minlength(wrapper_options = nil)
        function minimum_length_from_validation (line 13) | def minimum_length_from_validation
        function find_length_validator (line 23) | def find_length_validator
        function minimum_length_value_from (line 27) | def minimum_length_value_from(length_validator)

FILE: lib/simple_form/components/pattern.rb
  type SimpleForm (line 2) | module SimpleForm
    type Components (line 3) | module Components
      type Pattern (line 5) | module Pattern
        function pattern (line 6) | def pattern(wrapper_options = nil)
        function pattern_source (line 13) | def pattern_source
        function find_pattern_validator (line 22) | def find_pattern_validator

FILE: lib/simple_form/components/placeholders.rb
  type SimpleForm (line 2) | module SimpleForm
    type Components (line 3) | module Components
      type Placeholders (line 5) | module Placeholders
        function placeholder (line 6) | def placeholder(wrapper_options = nil)
        function placeholder_text (line 11) | def placeholder_text(wrapper_options = nil)

FILE: lib/simple_form/components/readonly.rb
  type SimpleForm (line 2) | module SimpleForm
    type Components (line 3) | module Components
      type Readonly (line 5) | module Readonly
        function readonly (line 6) | def readonly(wrapper_options = nil)
        function readonly_attribute? (line 16) | def readonly_attribute?

FILE: lib/simple_form/error_notification.rb
  type SimpleForm (line 2) | module SimpleForm
    class ErrorNotification (line 3) | class ErrorNotification
      method initialize (line 6) | def initialize(builder, options)
      method render (line 12) | def render
      method errors (line 20) | def errors
      method has_errors? (line 24) | def has_errors?
      method error_message (line 28) | def error_message
      method error_notification_tag (line 32) | def error_notification_tag
      method html_options (line 36) | def html_options
      method translate_error_notification (line 41) | def translate_error_notification

FILE: lib/simple_form/form_builder.rb
  type SimpleForm (line 6) | module SimpleForm
    class FormBuilder (line 7) | class FormBuilder < ActionView::Helpers::FormBuilder
      method discovery_cache (line 37) | def self.discovery_cache
      method initialize (line 41) | def initialize(*) #:nodoc:
      method input (line 118) | def input(attribute_name, options = {}, &block)
      method input_field (line 165) | def input_field(attribute_name, options = {})
      method association (line 207) | def association(association, options = {}, &block)
      method button (line 237) | def button(type, *args, &block)
      method error (line 256) | def error(attribute_name, options = {})
      method full_error (line 273) | def full_error(attribute_name, options = {})
      method hint (line 295) | def hint(attribute_name, options = {})
      method label (line 324) | def label(attribute_name, *args)
      method error_notification (line 346) | def error_notification(options = {})
      method collection_radio_buttons (line 397) | def collection_radio_buttons(method, collection, value_method, text_...
      method collection_check_boxes (line 451) | def collection_check_boxes(method, collection, value_method, text_me...
      method lookup_model_names (line 463) | def lookup_model_names #:nodoc:
      method lookup_action (line 474) | def lookup_action #:nodoc:
      method fetch_association_collection (line 485) | def fetch_association_collection(reflection, options)
      method build_association_attribute (line 508) | def build_association_attribute(reflection, association, options)
      method find_input (line 531) | def find_input(attribute_name, options = {}, &block)
      method default_input_type (line 545) | def default_input_type(attribute_name, column, options)
      method find_custom_type (line 570) | def find_custom_type(attribute_name)
      method file_method? (line 592) | def file_method?(attribute_name)
      method find_attribute_column (line 600) | def find_attribute_column(attribute_name)
      method find_association_reflection (line 612) | def find_association_reflection(association)
      method find_mapping (line 625) | def find_mapping(input_type)
      method find_wrapper_mapping (line 642) | def find_wrapper_mapping(input_type)
      method find_wrapper (line 650) | def find_wrapper(input_type, options)
      method discovery_cache (line 660) | def discovery_cache
      method mapping_override (line 668) | def mapping_override(klass)
      method attempt_mapping (line 677) | def attempt_mapping(mapping, at)
      method attempt_mapping_with_custom_namespace (line 687) | def attempt_mapping_with_custom_namespace(input_name)
      method build_input_field_components (line 697) | def build_input_field_components(components)
      method build_input_field_options (line 707) | def build_input_field_options

FILE: lib/simple_form/helpers.rb
  type SimpleForm (line 2) | module SimpleForm
    type Helpers (line 6) | module Helpers

FILE: lib/simple_form/helpers/autofocus.rb
  type SimpleForm (line 2) | module SimpleForm
    type Helpers (line 3) | module Helpers
      type Autofocus (line 4) | module Autofocus
        function has_autofocus? (line 7) | def has_autofocus?

FILE: lib/simple_form/helpers/disabled.rb
  type SimpleForm (line 2) | module SimpleForm
    type Helpers (line 3) | module Helpers
      type Disabled (line 4) | module Disabled
        function has_disabled? (line 7) | def has_disabled?
        function disabled_class (line 11) | def disabled_class

FILE: lib/simple_form/helpers/readonly.rb
  type SimpleForm (line 2) | module SimpleForm
    type Helpers (line 3) | module Helpers
      type Readonly (line 4) | module Readonly
        function readonly_class (line 7) | def readonly_class
        function has_readonly? (line 11) | def has_readonly?

FILE: lib/simple_form/helpers/required.rb
  type SimpleForm (line 2) | module SimpleForm
    type Helpers (line 3) | module Helpers
      type Required (line 4) | module Required
        function required_field? (line 7) | def required_field?
        function calculate_required (line 11) | def calculate_required
        function required_by_validators? (line 21) | def required_by_validators?
        function required_by_default? (line 25) | def required_by_default?
        function required_class (line 31) | def required_class

FILE: lib/simple_form/helpers/validators.rb
  type SimpleForm (line 2) | module SimpleForm
    type Helpers (line 3) | module Helpers
      type Validators (line 4) | module Validators
        function has_validators? (line 5) | def has_validators?
        function attribute_validators (line 11) | def attribute_validators
        function reflection_validators (line 15) | def reflection_validators
        function valid_validator? (line 19) | def valid_validator?(validator)
        function conditional_validators? (line 23) | def conditional_validators?(validator)
        function action_validator_match? (line 27) | def action_validator_match?(validator)
        function find_validator (line 40) | def find_validator(kind)
        function resolve_validator_value (line 46) | def resolve_validator_value(value)

FILE: lib/simple_form/inputs.rb
  type SimpleForm (line 2) | module SimpleForm
    type Inputs (line 3) | module Inputs

FILE: lib/simple_form/inputs/base.rb
  type SimpleForm (line 5) | module SimpleForm
    type Inputs (line 6) | module Inputs
      class Base (line 7) | class Base
        method enable (line 36) | def self.enable(*keys)
        method disable (line 42) | def self.disable(*keys)
        method initialize (line 54) | def initialize(builder, attribute_name, column, input_type, option...
        method input (line 86) | def input(wrapper_options = nil)
        method input_options (line 90) | def input_options
        method additional_classes (line 94) | def additional_classes
        method input_class (line 98) | def input_class
        method limit (line 104) | def limit
        method column_limit (line 110) | def column_limit
        method decimal_limit (line 115) | def decimal_limit
        method decimal_or_float? (line 119) | def decimal_or_float?
        method nested_boolean_style? (line 123) | def nested_boolean_style?
        method reflection_or_attribute_name (line 128) | def reflection_or_attribute_name
        method html_options_for (line 133) | def html_options_for(namespace, css_classes)
        method translate_from_namespace (line 174) | def translate_from_namespace(namespace, default = '')
        method merge_wrapper_options (line 192) | def merge_wrapper_options(options, wrapper_options)
        method set_input_classes (line 211) | def set_input_classes(wrapper_options)
        method i18n_scope (line 227) | def i18n_scope

FILE: lib/simple_form/inputs/block_input.rb
  type SimpleForm (line 2) | module SimpleForm
    type Inputs (line 3) | module Inputs
      class BlockInput (line 4) | class BlockInput < Base
        method initialize (line 5) | def initialize(*args, &block)
        method input (line 10) | def input(wrapper_options = nil)

FILE: lib/simple_form/inputs/boolean_input.rb
  type SimpleForm (line 2) | module SimpleForm
    type Inputs (line 3) | module Inputs
      class BooleanInput (line 4) | class BooleanInput < Base
        method input (line 5) | def input(wrapper_options = nil)
        method label_input (line 23) | def label_input(wrapper_options = nil)
        method boolean_label_class (line 44) | def boolean_label_class
        method build_check_box (line 52) | def build_check_box(unchecked_value, options)
        method build_check_box_without_hidden_field (line 58) | def build_check_box_without_hidden_field(options)
        method build_hidden_field_for_checkbox (line 66) | def build_hidden_field_for_checkbox
        method inline_label? (line 75) | def inline_label?
        method inline_label (line 79) | def inline_label
        method required_by_default? (line 91) | def required_by_default?
        method include_hidden? (line 95) | def include_hidden?
        method checked_value (line 99) | def checked_value
        method unchecked_value (line 103) | def unchecked_value

FILE: lib/simple_form/inputs/collection_check_boxes_input.rb
  type SimpleForm (line 2) | module SimpleForm
    type Inputs (line 3) | module Inputs
      class CollectionCheckBoxesInput (line 4) | class CollectionCheckBoxesInput < CollectionRadioButtonsInput
        method has_required? (line 9) | def has_required?
        method build_nested_boolean_style_item_tag (line 13) | def build_nested_boolean_style_item_tag(collection_builder)
        method item_wrapper_class (line 17) | def item_wrapper_class

FILE: lib/simple_form/inputs/collection_input.rb
  type SimpleForm (line 2) | module SimpleForm
    type Inputs (line 3) | module Inputs
      class CollectionInput (line 4) | class CollectionInput < Base
        method boolean_collection (line 12) | def self.boolean_collection
        method input (line 17) | def input(wrapper_options = nil)
        method input_options (line 22) | def input_options
        method collection (line 34) | def collection
        method has_required? (line 41) | def has_required?
        method skip_include_blank? (line 46) | def skip_include_blank?
        method multiple? (line 50) | def multiple?
        method detect_collection_methods (line 59) | def detect_collection_methods
        method detect_common_display_methods (line 71) | def detect_common_display_methods(collection_classes = detect_coll...
        method detect_method_from_class (line 83) | def detect_method_from_class(collection_classes)
        method detect_collection_classes (line 90) | def detect_collection_classes(some_collection = collection)
        method collection_includes_basic_objects? (line 94) | def collection_includes_basic_objects?(collection_classes)
        method translate_collection (line 98) | def translate_collection
        method translate_option (line 113) | def translate_option(options, key)

FILE: lib/simple_form/inputs/collection_radio_buttons_input.rb
  type SimpleForm (line 2) | module SimpleForm
    type Inputs (line 3) | module Inputs
      class CollectionRadioButtonsInput (line 4) | class CollectionRadioButtonsInput < CollectionInput
        method input (line 5) | def input(wrapper_options = nil)
        method input_options (line 17) | def input_options
        method apply_default_collection_options! (line 25) | def apply_default_collection_options!(options)
        method collection_block_for_nested_boolean_style (line 37) | def collection_block_for_nested_boolean_style
        method build_nested_boolean_style_item_tag (line 43) | def build_nested_boolean_style_item_tag(collection_builder)
        method item_wrapper_class (line 47) | def item_wrapper_class
        method generate_label_for_attribute? (line 54) | def generate_label_for_attribute?

FILE: lib/simple_form/inputs/collection_select_input.rb
  type SimpleForm (line 2) | module SimpleForm
    type Inputs (line 3) | module Inputs
      class CollectionSelectInput (line 4) | class CollectionSelectInput < CollectionInput
        method input (line 5) | def input(wrapper_options = nil)

FILE: lib/simple_form/inputs/color_input.rb
  type SimpleForm (line 2) | module SimpleForm
    type Inputs (line 3) | module Inputs
      class ColorInput (line 4) | class ColorInput < Base
        method input (line 5) | def input(wrapper_options = nil)

FILE: lib/simple_form/inputs/date_time_input.rb
  type SimpleForm (line 2) | module SimpleForm
    type Inputs (line 3) | module Inputs
      class DateTimeInput (line 4) | class DateTimeInput < Base
        method input (line 5) | def input(wrapper_options = nil)
        method label_target (line 17) | def label_target
        method use_html5_inputs? (line 34) | def use_html5_inputs?

FILE: lib/simple_form/inputs/file_input.rb
  type SimpleForm (line 2) | module SimpleForm
    type Inputs (line 3) | module Inputs
      class FileInput (line 4) | class FileInput < Base
        method input (line 5) | def input(wrapper_options = nil)

FILE: lib/simple_form/inputs/grouped_collection_select_input.rb
  type SimpleForm (line 2) | module SimpleForm
    type Inputs (line 3) | module Inputs
      class GroupedCollectionSelectInput (line 4) | class GroupedCollectionSelectInput < CollectionInput
        method input (line 5) | def input(wrapper_options = nil)
        method grouped_collection (line 17) | def grouped_collection
        method collection (line 25) | def collection
        method group_method (line 29) | def group_method
        method group_label_method (line 33) | def group_label_method
        method detect_method_from_class (line 44) | def detect_method_from_class(collection_classes)

FILE: lib/simple_form/inputs/hidden_input.rb
  type SimpleForm (line 2) | module SimpleForm
    type Inputs (line 3) | module Inputs
      class HiddenInput (line 4) | class HiddenInput < Base
        method input (line 7) | def input(wrapper_options = nil)
        method required_class (line 15) | def required_class

FILE: lib/simple_form/inputs/numeric_input.rb
  type SimpleForm (line 2) | module SimpleForm
    type Inputs (line 3) | module Inputs
      class NumericInput (line 4) | class NumericInput < Base
        method input (line 7) | def input(wrapper_options = nil)

FILE: lib/simple_form/inputs/password_input.rb
  type SimpleForm (line 2) | module SimpleForm
    type Inputs (line 3) | module Inputs
      class PasswordInput (line 4) | class PasswordInput < Base
        method input (line 7) | def input(wrapper_options = nil)

FILE: lib/simple_form/inputs/priority_input.rb
  type SimpleForm (line 2) | module SimpleForm
    type Inputs (line 3) | module Inputs
      class PriorityInput (line 4) | class PriorityInput < CollectionSelectInput
        method input (line 5) | def input(wrapper_options = nil)
        method input_priority (line 11) | def input_priority
        method country_input (line 17) | def country_input(merged_input_options)
        method time_zone_input (line 24) | def time_zone_input(merged_input_options)
        method skip_include_blank? (line 32) | def skip_include_blank?

FILE: lib/simple_form/inputs/range_input.rb
  type SimpleForm (line 2) | module SimpleForm
    type Inputs (line 3) | module Inputs
      class RangeInput (line 4) | class RangeInput < NumericInput
        method input (line 5) | def input(wrapper_options = nil)

FILE: lib/simple_form/inputs/rich_text_area_input.rb
  type SimpleForm (line 2) | module SimpleForm
    type Inputs (line 3) | module Inputs
      class RichTextAreaInput (line 4) | class RichTextAreaInput < Base
        method input (line 7) | def input(wrapper_options = nil)

FILE: lib/simple_form/inputs/string_input.rb
  type SimpleForm (line 2) | module SimpleForm
    type Inputs (line 3) | module Inputs
      class StringInput (line 4) | class StringInput < Base
        method input (line 7) | def input(wrapper_options = nil)
        method string? (line 20) | def string?

FILE: lib/simple_form/inputs/text_input.rb
  type SimpleForm (line 2) | module SimpleForm
    type Inputs (line 3) | module Inputs
      class TextInput (line 4) | class TextInput < Base
        method input (line 7) | def input(wrapper_options = nil)

FILE: lib/simple_form/inputs/weekday_input.rb
  type SimpleForm (line 2) | module SimpleForm
    type Inputs (line 3) | module Inputs
      class WeekdayInput (line 4) | class WeekdayInput < CollectionSelectInput
        method input (line 7) | def input(wrapper_options = nil)

FILE: lib/simple_form/map_type.rb
  type SimpleForm (line 4) | module SimpleForm
    type MapType (line 5) | module MapType
      function extended (line 6) | def self.extended(base)
      function map_type (line 11) | def map_type(*types)

FILE: lib/simple_form/railtie.rb
  type SimpleForm (line 4) | module SimpleForm
    class Railtie (line 5) | class Railtie < Rails::Railtie

FILE: lib/simple_form/tags.rb
  type SimpleForm (line 2) | module SimpleForm
    type Tags (line 3) | module Tags
      type CollectionExtensions (line 4) | module CollectionExtensions
        function render_collection (line 7) | def render_collection
        function wrap_rendered_collection (line 29) | def wrap_rendered_collection(collection)
      class CollectionRadioButtons (line 41) | class CollectionRadioButtons < ActionView::Helpers::Tags::Collection...
        method render (line 44) | def render
        method render_component (line 50) | def render_component(builder)
      class CollectionCheckBoxes (line 57) | class CollectionCheckBoxes < ActionView::Helpers::Tags::CollectionCh...
        method render (line 60) | def render
        method render_component (line 66) | def render_component(builder)

FILE: lib/simple_form/version.rb
  type SimpleForm (line 2) | module SimpleForm

FILE: lib/simple_form/wrappers.rb
  type SimpleForm (line 2) | module SimpleForm
    type Wrappers (line 3) | module Wrappers

FILE: lib/simple_form/wrappers/builder.rb
  type SimpleForm (line 2) | module SimpleForm
    type Wrappers (line 3) | module Wrappers
      class Builder (line 43) | class Builder
        method initialize (line 44) | def initialize(options)
        method use (line 49) | def use(name, options = {})
        method optional (line 57) | def optional(name, options = {}, &block)
        method wrapper (line 62) | def wrapper(name, options = nil)
        method to_a (line 75) | def to_a

FILE: lib/simple_form/wrappers/leaf.rb
  type SimpleForm (line 2) | module SimpleForm
    type Wrappers (line 3) | module Wrappers
      class Leaf (line 4) | class Leaf
        method initialize (line 7) | def initialize(namespace, options = {})
        method render (line 12) | def render(input)
        method find (line 24) | def find(name)

FILE: lib/simple_form/wrappers/many.rb
  type SimpleForm (line 2) | module SimpleForm
    type Wrappers (line 3) | module Wrappers
      class Many (line 12) | class Many
        method initialize (line 15) | def initialize(namespace, components, defaults = {})
        method render (line 23) | def render(input)
        method find (line 36) | def find(name)
        method wrap (line 52) | def wrap(input, options, content)
        method html_options (line 65) | def html_options(options)
        method html_classes (line 69) | def html_classes(input, options)

FILE: lib/simple_form/wrappers/root.rb
  type SimpleForm (line 2) | module SimpleForm
    type Wrappers (line 3) | module Wrappers
      class Root (line 6) | class Root < Many
        method initialize (line 9) | def initialize(*args)
        method render (line 14) | def render(input)
        method find (line 20) | def find(name)
        method html_classes (line 26) | def html_classes(input, options)
        method html_class (line 37) | def html_class(key, options)

FILE: lib/simple_form/wrappers/single.rb
  type SimpleForm (line 2) | module SimpleForm
    type Wrappers (line 3) | module Wrappers
      class Single (line 5) | class Single < Many
        method initialize (line 6) | def initialize(name, wrapper_options = {}, options = {})
        method render (line 12) | def render(input)
        method html_options (line 22) | def html_options(options)

FILE: test/action_view_extensions/builder_test.rb
  class BuilderTest (line 4) | class BuilderTest < ActionView::TestCase
    method with_custom_form_for (line 5) | def with_custom_form_for(object, *args, &block)
    method with_collection_radio_buttons (line 12) | def with_collection_radio_buttons(object, attribute, collection, value...
    method with_collection_check_boxes (line 18) | def with_collection_check_boxes(object, attribute, collection, value_m...

FILE: test/action_view_extensions/form_helper_test.rb
  class FormHelperTest (line 4) | class FormHelperTest < ActionView::TestCase
    method swap_field_error_proc (line 165) | def swap_field_error_proc(expected_error_proc = -> {})

FILE: test/components/custom_components_test.rb
  type Numbers (line 6) | module Numbers
    function number (line 7) | def number(wrapper_options = nil)
  type InputGroup (line 13) | module InputGroup
    function prepend (line 14) | def prepend(wrapper_options = nil)
    function append (line 19) | def append(wrapper_options = nil)
  class CustomComponentsTest (line 25) | class CustomComponentsTest < ActionView::TestCase

FILE: test/components/label_test.rb
  class IsolatedLabelTest (line 6) | class IsolatedLabelTest < ActionView::TestCase
    method with_label_for (line 7) | def with_label_for(object, attribute_name, type, options = {})
    method action_name (line 60) | def @controller.action_name; nil; end

FILE: test/form_builder/association_test.rb
  class AssociationTest (line 5) | class AssociationTest < ActionView::TestCase
    method with_association_for (line 6) | def with_association_for(object, *args)

FILE: test/form_builder/button_test.rb
  class ButtonTest (line 5) | class ButtonTest < ActionView::TestCase
    method with_button_for (line 6) | def with_button_for(object, *args)

FILE: test/form_builder/error_notification_test.rb
  class ErrorNotificationTest (line 6) | class ErrorNotificationTest < ActionView::TestCase
    method with_error_notification_for (line 7) | def with_error_notification_for(object, options = {}, &block)

FILE: test/form_builder/error_test.rb
  class ErrorTest (line 5) | class ErrorTest < ActionView::TestCase
    method with_error_for (line 6) | def with_error_for(object, *args)
    method with_full_error_for (line 12) | def with_full_error_for(object, *args)

FILE: test/form_builder/general_test.rb
  class FormBuilderTest (line 5) | class FormBuilderTest < ActionView::TestCase
    method with_custom_form_for (line 6) | def with_custom_form_for(object, *args, &block)

FILE: test/form_builder/hint_test.rb
  class HintTest (line 5) | class HintTest < ActionView::TestCase
    method with_hint_for (line 6) | def with_hint_for(object, *args)

FILE: test/form_builder/input_field_test.rb
  class InputFieldTest (line 5) | class InputFieldTest < ActionView::TestCase

FILE: test/form_builder/label_test.rb
  class LabelTest (line 5) | class LabelTest < ActionView::TestCase
    method with_label_for (line 6) | def with_label_for(object, *args, &block)

FILE: test/form_builder/wrapper_test.rb
  class WrapperTest (line 4) | class WrapperTest < ActionView::TestCase

FILE: test/generators/simple_form_generator_test.rb
  class SimpleFormGeneratorTest (line 4) | class SimpleFormGeneratorTest < Rails::Generators::TestCase

FILE: test/inputs/boolean_input_test.rb
  class BooleanInputTest (line 5) | class BooleanInputTest < ActionView::TestCase

FILE: test/inputs/collection_check_boxes_input_test.rb
  class CollectionCheckBoxesInputTest (line 5) | class CollectionCheckBoxesInputTest < ActionView::TestCase

FILE: test/inputs/collection_radio_buttons_input_test.rb
  class CollectionRadioButtonsInputTest (line 5) | class CollectionRadioButtonsInputTest < ActionView::TestCase

FILE: test/inputs/collection_select_input_test.rb
  class CollectionSelectInputTest (line 5) | class CollectionSelectInputTest < ActionView::TestCase

FILE: test/inputs/color_input_test.rb
  class ColorInputTest (line 5) | class ColorInputTest < ActionView::TestCase

FILE: test/inputs/country_input_test.rb
  class CountryInputTest (line 5) | class CountryInputTest < ActionView::TestCase

FILE: test/inputs/datetime_input_test.rb
  class DateTimeInputWithHtml5Test (line 6) | class DateTimeInputWithHtml5Test < ActionView::TestCase
  class DateTimeInputWithoutHtml5Test (line 50) | class DateTimeInputWithoutHtml5Test < ActionView::TestCase

FILE: test/inputs/disabled_test.rb
  class DisabledTest (line 4) | class DisabledTest < ActionView::TestCase

FILE: test/inputs/discovery_test.rb
  class DiscoveryTest (line 4) | class DiscoveryTest < ActionView::TestCase
    method discovery (line 6) | def discovery(value = false)

FILE: test/inputs/file_input_test.rb
  class FileInputTest (line 5) | class FileInputTest < ActionView::TestCase

FILE: test/inputs/general_test.rb
  class InputTest (line 5) | class InputTest < ActionView::TestCase

FILE: test/inputs/grouped_collection_select_input_test.rb
  class GroupedCollectionSelectInputTest (line 5) | class GroupedCollectionSelectInputTest < ActionView::TestCase

FILE: test/inputs/hidden_input_test.rb
  class HiddenInputTest (line 5) | class HiddenInputTest < ActionView::TestCase

FILE: test/inputs/numeric_input_test.rb
  class NumericInputTest (line 5) | class NumericInputTest < ActionView::TestCase

FILE: test/inputs/readonly_test.rb
  class ReadonlyTest (line 4) | class ReadonlyTest < ActionView::TestCase

FILE: test/inputs/required_test.rb
  class RequiredTest (line 4) | class RequiredTest < ActionView::TestCase

FILE: test/inputs/rich_text_area_input_test.rb
  class RichTextAreaInputTest (line 5) | class RichTextAreaInputTest < ActionView::TestCase

FILE: test/inputs/string_input_test.rb
  class StringInputTest (line 5) | class StringInputTest < ActionView::TestCase

FILE: test/inputs/text_input_test.rb
  class TextInputTest (line 5) | class TextInputTest < ActionView::TestCase

FILE: test/inputs/time_zone_input_test.rb
  class TimeZoneInputTest (line 5) | class TimeZoneInputTest < ActionView::TestCase

FILE: test/inputs/weekday_input_test.rb
  class WeekdayInputTest (line 5) | class WeekdayInputTest < ActionView::TestCase

FILE: test/simple_form_test.rb
  class SimpleFormTest (line 4) | class SimpleFormTest < ActiveSupport::TestCase

FILE: test/support/discovery_inputs.rb
  class StringInput (line 2) | class StringInput < SimpleForm::Inputs::StringInput
    method input (line 3) | def input(wrapper_options = nil)
  class NumericInput (line 8) | class NumericInput < SimpleForm::Inputs::NumericInput
    method input (line 9) | def input(wrapper_options = nil)
  class CustomizedInput (line 14) | class CustomizedInput < SimpleForm::Inputs::StringInput
    method input (line 15) | def input(wrapper_options = nil)
    method input_method (line 19) | def input_method
  class DeprecatedInput (line 24) | class DeprecatedInput < SimpleForm::Inputs::StringInput
    method input (line 25) | def input
    method input_method (line 29) | def input_method
  class CollectionSelectInput (line 34) | class CollectionSelectInput < SimpleForm::Inputs::CollectionSelectInput
    method input_html_classes (line 35) | def input_html_classes
  class FileInput (line 40) | class FileInput < SimpleForm::Inputs::FileInput
    method input_html_classes (line 41) | def input_html_classes
  type CustomInputs (line 47) | module CustomInputs
    class CustomizedInput (line 48) | class CustomizedInput < SimpleForm::Inputs::StringInput
      method input_html_classes (line 49) | def input_html_classes
    class PasswordInput (line 54) | class PasswordInput < SimpleForm::Inputs::PasswordInput
      method input_html_classes (line 55) | def input_html_classes
    class NumericInput (line 60) | class NumericInput < SimpleForm::Inputs::PasswordInput
      method input_html_classes (line 61) | def input_html_classes

FILE: test/support/misc_helpers.rb
  type MiscHelpers (line 2) | module MiscHelpers
    function store_translations (line 3) | def store_translations(locale, translations, &block)
    function assert_no_select (line 11) | def assert_no_select(selector, value = nil)
    function swap (line 15) | def swap(object, new_values)
    function stub_any_instance (line 28) | def stub_any_instance(klass, method, value)
    function swap_wrapper (line 50) | def swap_wrapper(name = :default, wrapper = custom_wrapper)
    function custom_wrapper (line 58) | def custom_wrapper
    function custom_wrapper_with_wrapped_optional_component (line 72) | def custom_wrapper_with_wrapped_optional_component
    function custom_wrapper_with_unless_blank (line 80) | def custom_wrapper_with_unless_blank
    function custom_wrapper_with_input_class (line 88) | def custom_wrapper_with_input_class
    function custom_wrapper_with_input_data_modal (line 95) | def custom_wrapper_with_input_data_modal
    function custom_wrapper_with_input_aria_modal (line 102) | def custom_wrapper_with_input_aria_modal
    function custom_wrapper_with_label_class (line 109) | def custom_wrapper_with_label_class
    function custom_wrapper_with_input_attributes (line 116) | def custom_wrapper_with_input_attributes
    function custom_wrapper_with_label_input_class (line 122) | def custom_wrapper_with_label_input_class
    function custom_wrapper_with_wrapped_input (line 128) | def custom_wrapper_with_wrapped_input
    function custom_wrapper_with_wrapped_label (line 137) | def custom_wrapper_with_wrapped_label
    function custom_wrapper_without_top_level (line 146) | def custom_wrapper_without_top_level
    function custom_wrapper_without_class (line 154) | def custom_wrapper_without_class
    function custom_wrapper_with_label_html_option (line 160) | def custom_wrapper_with_label_html_option
    function custom_wrapper_with_wrapped_label_input (line 166) | def custom_wrapper_with_wrapped_label_input
    function custom_wrapper_with_additional_attributes (line 172) | def custom_wrapper_with_additional_attributes
    function custom_wrapper_with_full_error (line 178) | def custom_wrapper_with_full_error
    function custom_wrapper_with_label_text (line 184) | def custom_wrapper_with_label_text
    function custom_wrapper_with_custom_label_component (line 190) | def custom_wrapper_with_custom_label_component
    function custom_wrapper_with_html5_components (line 196) | def custom_wrapper_with_html5_components
    function custom_wrapper_with_required_input (line 202) | def custom_wrapper_with_required_input
    function custom_wrapper_with_input_error_class (line 209) | def custom_wrapper_with_input_error_class
    function custom_wrapper_with_input_valid_class (line 216) | def custom_wrapper_with_input_valid_class(valid_class: :field_without_...
    function custom_form_for (line 223) | def custom_form_for(object, *args, &block)
    function custom_mapping_form_for (line 227) | def custom_mapping_form_for(object, *args, &block)
    function with_concat_form_for (line 231) | def with_concat_form_for(*args, &block)
    function with_concat_fields_for (line 235) | def with_concat_fields_for(*args, &block)
    function with_concat_custom_form_for (line 239) | def with_concat_custom_form_for(*args, &block)
    function with_concat_custom_mapping_form_for (line 243) | def with_concat_custom_mapping_form_for(*args, &block)
    function with_form_for (line 247) | def with_form_for(object, *args, &block)
    function with_input_for (line 253) | def with_input_for(object, attribute_name, type, options = {})
    function with_input_field_for (line 259) | def with_input_field_for(object, *args)
  class CustomFormBuilder (line 266) | class CustomFormBuilder < SimpleForm::FormBuilder
    method input (line 267) | def input(attribute_name, *args, &block)
  class CustomMapTypeFormBuilder (line 272) | class CustomMapTypeFormBuilder < SimpleForm::FormBuilder

FILE: test/support/mock_controller.rb
  class MockController (line 2) | class MockController
    method _routes (line 5) | def _routes
    method action_name (line 9) | def action_name
    method url_for (line 13) | def url_for(*)
    method url_options (line 17) | def url_options
    method polymorphic_mappings (line 21) | def polymorphic_mappings(*); {}; end
    method hash_for_user_path (line 23) | def hash_for_user_path(*); end
    method hash_for_validating_user_path (line 25) | def hash_for_validating_user_path(*); end
    method hash_for_other_validating_user_path (line 27) | def hash_for_other_validating_user_path(*); end
    method hash_for_users_path (line 29) | def hash_for_users_path(*); end

FILE: test/support/models.rb
  function where (line 10) | def where(conditions = nil)
  function order (line 14) | def order(conditions = nil)
  function to_model (line 23) | def to_model
  function where (line 32) | def self.where(conditions = nil)
  function all (line 40) | def self.all
  function _relation (line 53) | def self._relation
  function all (line 57) | def self.all
  function persisted? (line 61) | def persisted?
  function all (line 70) | def self.all
  function persisted? (line 74) | def persisted?
  class Tag (line 79) | class Tag < Company
    method group_method (line 80) | def group_method
  class User (line 87) | class User
    method build (line 100) | def self.build(extra_attributes = {})
    method initialize (line 111) | def initialize(options = {})
    method new_record! (line 118) | def new_record!
    method persisted? (line 122) | def persisted?
    method company_attributes= (line 126) | def company_attributes=(*)
    method tags_attributes= (line 129) | def tags_attributes=(*)
    method column_for_attribute (line 132) | def column_for_attribute(attribute)
    class ::ActiveModel::Type::Text (line 160) | class ::ActiveModel::Type::Text < ActiveModel::Type::String
      method type (line 161) | def type; :text; end
    method type_for_attribute (line 165) | def type_for_attribute(attribute)
    method has_attribute? (line 194) | def has_attribute?(attribute)
    method human_attribute_name (line 205) | def self.human_attribute_name(attribute, options = {})
    method reflect_on_association (line 220) | def self.reflect_on_association(association)
    method errors (line 243) | def errors
    method readonly_attributes (line 256) | def self.readonly_attributes
  class ValidatingUser (line 261) | class ValidatingUser < User
    method min_amount (line 294) | def min_amount
    method max_amount (line 298) | def max_amount
    method min_attempts (line 302) | def min_attempts
    method max_attempts (line 306) | def max_attempts
  class OtherValidatingUser (line 311) | class OtherValidatingUser < User
  class HashBackedAuthor (line 331) | class HashBackedAuthor < Hash
    method persisted? (line 335) | def persisted?; false; end
    method name (line 337) | def name
  class UserNumber1And2 (line 342) | class UserNumber1And2 < User
  class UserWithAttachment (line 345) | class UserWithAttachment < User
    method avatar_attachment (line 346) | def avatar_attachment
    method avatars_attachments (line 350) | def avatars_attachments
    method remote_cover_url (line 354) | def remote_cover_url
    method profile_image_attacher (line 358) | def profile_image_attacher
    method portrait_file_name (line 362) | def portrait_file_name

FILE: test/test_helper.rb
  type Rails (line 13) | module Rails
    function env (line 14) | def self.env
  class ActionView::TestCase (line 40) | class ActionView::TestCase
    method set_controller (line 49) | def set_controller
    method setup_users (line 53) | def setup_users(extra_attributes = {})
    method protect_against_forgery? (line 74) | def protect_against_forgery?
    method user_path (line 78) | def user_path(*args)
    method company_user_path (line 82) | def company_user_path(*args)
Condensed preview — 122 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (472K chars).
[
  {
    "path": ".github/code-scanning.yml",
    "chars": 26,
    "preview": "paths-ignore:\n  - test/**\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 1796,
    "preview": "name: Test\n\npermissions:\n  contents: read\non:\n  push:\n    branches:\n      - main\n  pull_request:\n  workflow_dispatch:\njo"
  },
  {
    "path": ".gitignore",
    "chars": 44,
    "preview": ".bundle/\npkg/\nrdoc/\ngemfiles/*.lock\n/.idea/\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 14169,
    "preview": "## 5.4.1\n\n* Ruby 4.0 support (no changes required)\n* Support procs on validators for minlength/maxlength, and improve va"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 872,
    "preview": "## Contributing\n\n1. If you have any questions about Simple Form, search the\n[Wiki](https://github.com/heartcombo/simple_"
  },
  {
    "path": "Gemfile",
    "chars": 126,
    "preview": "source \"https://rubygems.org\"\n\ngemspec\n\ngem \"activemodel\", \"~> 8.1.0\"\ngem \"actionpack\", \"~> 8.1.0\"\ngem \"railties\", \"~> 8"
  },
  {
    "path": "ISSUE_TEMPLATE.md",
    "chars": 651,
    "preview": "## Precheck\n\n- Do not use the issues tracker for help or support, try Stack Overflow.\n- For bugs, do a quick search and "
  },
  {
    "path": "MIT-LICENSE",
    "chars": 1128,
    "preview": "Copyright (c) 2020-CURRENT Rafael França, Carlos Antonio da Silva\nCopyright (c) 2009-2019 Plataformatec\n\nPermission is h"
  },
  {
    "path": "README.md",
    "chars": 44019,
    "preview": "![Simple Form Logo](https://raw.github.com/heartcombo/simple_form/main/simple_form.png)\n\n[![Gem Version](https://badge.f"
  },
  {
    "path": "Rakefile",
    "chars": 674,
    "preview": "# encoding: UTF-8\n\nrequire 'bundler/gem_tasks'\n\nrequire 'rake/testtask'\n\ndesc 'Default: run unit tests.'\ntask default: :"
  },
  {
    "path": "bin/test",
    "chars": 306,
    "preview": "#!/usr/bin/env ruby\n$: << File.expand_path(File.expand_path('../../test', __FILE__))\n\nrequire 'bundler/setup'\nrequire 'r"
  },
  {
    "path": "gemfiles/Gemfile-rails-7-0",
    "chars": 137,
    "preview": "source \"https://rubygems.org\"\n\ngemspec path: \"..\"\n\ngem \"activemodel\", \"~> 7.0.0\"\ngem \"actionpack\", \"~> 7.0.0\"\ngem \"railt"
  },
  {
    "path": "gemfiles/Gemfile-rails-7-1",
    "chars": 137,
    "preview": "source \"https://rubygems.org\"\n\ngemspec path: \"..\"\n\ngem \"activemodel\", \"~> 7.1.0\"\ngem \"actionpack\", \"~> 7.1.0\"\ngem \"railt"
  },
  {
    "path": "gemfiles/Gemfile-rails-7-2",
    "chars": 137,
    "preview": "source \"https://rubygems.org\"\n\ngemspec path: \"..\"\n\ngem \"activemodel\", \"~> 7.2.0\"\ngem \"actionpack\", \"~> 7.2.0\"\ngem \"railt"
  },
  {
    "path": "gemfiles/Gemfile-rails-8-0",
    "chars": 137,
    "preview": "source \"https://rubygems.org\"\n\ngemspec path: \"..\"\n\ngem \"activemodel\", \"~> 8.0.0\"\ngem \"actionpack\", \"~> 8.0.0\"\ngem \"railt"
  },
  {
    "path": "gemfiles/Gemfile-rails-main",
    "chars": 231,
    "preview": "source \"https://rubygems.org\"\n\ngemspec path: \"..\"\n\ngem \"railties\", github: \"rails/rails\", branch: \"main\"\ngem \"activemode"
  },
  {
    "path": "lib/generators/simple_form/USAGE",
    "chars": 133,
    "preview": "To copy a SimpleForm initializer to your Rails App, with some configuration values, just do:\n\n    rails generate simple_"
  },
  {
    "path": "lib/generators/simple_form/install_generator.rb",
    "chars": 1573,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Generators\n    class InstallGenerator < Rails::Generators::Base"
  },
  {
    "path": "lib/generators/simple_form/templates/README",
    "chars": 411,
    "preview": "===============================================================================\n\n  Be sure to have a copy of the Bootstr"
  },
  {
    "path": "lib/generators/simple_form/templates/_form.html.erb",
    "chars": 497,
    "preview": "<%# frozen_string_literal: true %>\n<%%= simple_form_for(@<%= singular_table_name %>) do |f| %>\n  <%%= f.error_notificati"
  },
  {
    "path": "lib/generators/simple_form/templates/_form.html.haml",
    "chars": 408,
    "preview": "-# frozen_string_literal: true\n= simple_form_for(@<%= singular_table_name %>) do |f|\n  = f.error_notification\n  = f.erro"
  },
  {
    "path": "lib/generators/simple_form/templates/_form.html.slim",
    "chars": 373,
    "preview": "= simple_form_for(@<%= singular_table_name %>) do |f|\n  = f.error_notification\n  = f.error_notification message: f.objec"
  },
  {
    "path": "lib/generators/simple_form/templates/config/initializers/simple_form.rb",
    "chars": 6905,
    "preview": "# frozen_string_literal: true\n#\n# Uncomment this and change the path if necessary to include your own\n# components.\n# Se"
  },
  {
    "path": "lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb",
    "chars": 14068,
    "preview": "# frozen_string_literal: true\n\n# These defaults are defined and maintained by the community at\n# https://github.com/hear"
  },
  {
    "path": "lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb",
    "chars": 4339,
    "preview": "# frozen_string_literal: true\n#\n# Uncomment this and change the path if necessary to include your own\n# components.\n# Se"
  },
  {
    "path": "lib/generators/simple_form/templates/config/locales/simple_form.en.yml",
    "chars": 838,
    "preview": "en:\n  simple_form:\n    \"yes\": 'Yes'\n    \"no\": 'No'\n    required:\n      text: 'required'\n      mark: '*'\n      # You can "
  },
  {
    "path": "lib/simple_form/action_view_extensions/builder.rb",
    "chars": 1222,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module ActionViewExtensions\n    # A collection of methods required by "
  },
  {
    "path": "lib/simple_form/action_view_extensions/form_helper.rb",
    "chars": 2345,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module ActionViewExtensions\n    # This module creates SimpleForm wrapp"
  },
  {
    "path": "lib/simple_form/components/errors.rb",
    "chars": 1829,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    module Errors\n      def error(wrapper_options = "
  },
  {
    "path": "lib/simple_form/components/hints.rb",
    "chars": 547,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    # Needs to be enabled in order to do automatic l"
  },
  {
    "path": "lib/simple_form/components/html5.rb",
    "chars": 783,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    module HTML5\n      def initialize(*)\n        @ht"
  },
  {
    "path": "lib/simple_form/components/label_input.rb",
    "chars": 837,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    module LabelInput\n      extend ActiveSupport::Co"
  },
  {
    "path": "lib/simple_form/components/labels.rb",
    "chars": 2605,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    module Labels\n      extend ActiveSupport::Concer"
  },
  {
    "path": "lib/simple_form/components/maxlength.rb",
    "chars": 942,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    # Needs to be enabled in order to do automatic l"
  },
  {
    "path": "lib/simple_form/components/min_max.rb",
    "chars": 1176,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    module MinMax\n      def min_max(wrapper_options "
  },
  {
    "path": "lib/simple_form/components/minlength.rb",
    "chars": 933,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    # Needs to be enabled in order to do automatic l"
  },
  {
    "path": "lib/simple_form/components/pattern.rb",
    "chars": 661,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    # Needs to be enabled in order to do automatic l"
  },
  {
    "path": "lib/simple_form/components/placeholders.rb",
    "chars": 494,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    # Needs to be enabled in order to do automatic l"
  },
  {
    "path": "lib/simple_form/components/readonly.rb",
    "chars": 600,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    # Needs to be enabled in order to do automatic l"
  },
  {
    "path": "lib/simple_form/components.rb",
    "chars": 782,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  # Components are a special type of helpers that can work on their own."
  },
  {
    "path": "lib/simple_form/error_notification.rb",
    "chars": 1153,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  class ErrorNotification\n    delegate :object, :object_name, :template,"
  },
  {
    "path": "lib/simple_form/form_builder.rb",
    "chars": 28692,
    "preview": "# frozen_string_literal: true\nrequire 'active_support/core_ext/object/deep_dup'\nrequire 'simple_form/map_type'\nrequire '"
  },
  {
    "path": "lib/simple_form/helpers/autofocus.rb",
    "chars": 190,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Helpers\n    module Autofocus\n      private\n\n      def has_autof"
  },
  {
    "path": "lib/simple_form/helpers/disabled.rb",
    "chars": 258,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Helpers\n    module Disabled\n      private\n\n      def has_disabl"
  },
  {
    "path": "lib/simple_form/helpers/readonly.rb",
    "chars": 258,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Helpers\n    module Readonly\n      private\n\n      def readonly_c"
  },
  {
    "path": "lib/simple_form/helpers/required.rb",
    "chars": 827,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Helpers\n    module Required\n      private\n\n      def required_f"
  },
  {
    "path": "lib/simple_form/helpers/validators.rb",
    "chars": 1717,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Helpers\n    module Validators\n      def has_validators?\n       "
  },
  {
    "path": "lib/simple_form/helpers.rb",
    "chars": 591,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  # Helpers are made of several helpers that cannot be turned on automat"
  },
  {
    "path": "lib/simple_form/inputs/base.rb",
    "chars": 7752,
    "preview": "# frozen_string_literal: true\nrequire 'active_support/core_ext/string/output_safety'\nrequire 'action_view/helpers'\n\nmodu"
  },
  {
    "path": "lib/simple_form/inputs/block_input.rb",
    "chars": 277,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class BlockInput < Base\n      def initialize(*args, "
  },
  {
    "path": "lib/simple_form/inputs/boolean_input.rb",
    "chars": 3831,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class BooleanInput < Base\n      def input(wrapper_op"
  },
  {
    "path": "lib/simple_form/inputs/collection_check_boxes_input.rb",
    "chars": 572,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class CollectionCheckBoxesInput < CollectionRadioBut"
  },
  {
    "path": "lib/simple_form/inputs/collection_input.rb",
    "chars": 4168,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class CollectionInput < Base\n      BASIC_OBJECT_CLAS"
  },
  {
    "path": "lib/simple_form/inputs/collection_radio_buttons_input.rb",
    "chars": 1999,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class CollectionRadioButtonsInput < CollectionInput\n"
  },
  {
    "path": "lib/simple_form/inputs/collection_select_input.rb",
    "chars": 494,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class CollectionSelectInput < CollectionInput\n      "
  },
  {
    "path": "lib/simple_form/inputs/color_input.rb",
    "chars": 373,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class ColorInput < Base\n      def input(wrapper_opti"
  },
  {
    "path": "lib/simple_form/inputs/date_time_input.rb",
    "chars": 1038,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class DateTimeInput < Base\n      def input(wrapper_o"
  },
  {
    "path": "lib/simple_form/inputs/file_input.rb",
    "chars": 315,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class FileInput < Base\n      def input(wrapper_optio"
  },
  {
    "path": "lib/simple_form/inputs/grouped_collection_select_input.rb",
    "chars": 1824,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class GroupedCollectionSelectInput < CollectionInput"
  },
  {
    "path": "lib/simple_form/inputs/hidden_input.rb",
    "chars": 431,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class HiddenInput < Base\n      disable :label, :erro"
  },
  {
    "path": "lib/simple_form/inputs/numeric_input.rb",
    "chars": 542,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class NumericInput < Base\n      enable :placeholder,"
  },
  {
    "path": "lib/simple_form/inputs/password_input.rb",
    "chars": 374,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class PasswordInput < Base\n      enable :placeholder"
  },
  {
    "path": "lib/simple_form/inputs/priority_input.rb",
    "chars": 1051,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class PriorityInput < CollectionSelectInput\n      de"
  },
  {
    "path": "lib/simple_form/inputs/range_input.rb",
    "chars": 302,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class RangeInput < NumericInput\n      def input(wrap"
  },
  {
    "path": "lib/simple_form/inputs/rich_text_area_input.rb",
    "chars": 354,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class RichTextAreaInput < Base\n      enable :placeho"
  },
  {
    "path": "lib/simple_form/inputs/string_input.rb",
    "chars": 621,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class StringInput < Base\n      enable :placeholder, "
  },
  {
    "path": "lib/simple_form/inputs/text_input.rb",
    "chars": 365,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class TextInput < Base\n      enable :placeholder, :m"
  },
  {
    "path": "lib/simple_form/inputs/weekday_input.rb",
    "chars": 381,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class WeekdayInput < CollectionSelectInput\n      ena"
  },
  {
    "path": "lib/simple_form/inputs.rb",
    "chars": 692,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    extend ActiveSupport::Autoload\n\n    autoload :Base\n "
  },
  {
    "path": "lib/simple_form/map_type.rb",
    "chars": 476,
    "preview": "# frozen_string_literal: true\nrequire 'active_support/core_ext/class/attribute'\n\nmodule SimpleForm\n  module MapType\n    "
  },
  {
    "path": "lib/simple_form/railtie.rb",
    "chars": 611,
    "preview": "# frozen_string_literal: true\nrequire 'rails/railtie'\n\nmodule SimpleForm\n  class Railtie < Rails::Railtie\n    config.eag"
  },
  {
    "path": "lib/simple_form/tags.rb",
    "chars": 2369,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Tags\n    module CollectionExtensions\n      private\n\n      def r"
  },
  {
    "path": "lib/simple_form/version.rb",
    "chars": 79,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  VERSION = \"5.4.1\".freeze\nend\n"
  },
  {
    "path": "lib/simple_form/wrappers/builder.rb",
    "chars": 2684,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Wrappers\n    # Provides the builder syntax for components. The "
  },
  {
    "path": "lib/simple_form/wrappers/leaf.rb",
    "chars": 601,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Wrappers\n    class Leaf\n      attr_reader :namespace\n\n      def"
  },
  {
    "path": "lib/simple_form/wrappers/many.rb",
    "chars": 2243,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Wrappers\n    # A wrapper is an object that holds several compon"
  },
  {
    "path": "lib/simple_form/wrappers/root.rb",
    "chars": 1318,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Wrappers\n    # `Root` is the root wrapper for all components. I"
  },
  {
    "path": "lib/simple_form/wrappers/single.rb",
    "chars": 684,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Wrappers\n    # `Single` is an optimization for a wrapper that h"
  },
  {
    "path": "lib/simple_form/wrappers.rb",
    "chars": 336,
    "preview": "# frozen_string_literal: true\nmodule SimpleForm\n  module Wrappers\n    autoload :Builder, 'simple_form/wrappers/builder'\n"
  },
  {
    "path": "lib/simple_form.rb",
    "chars": 11300,
    "preview": "# frozen_string_literal: true\nrequire 'action_view'\nrequire 'action_pack'\nrequire 'simple_form/action_view_extensions/fo"
  },
  {
    "path": "simple_form.gemspec",
    "chars": 1429,
    "preview": "# -*- encoding: utf-8 -*-\n$:.push File.expand_path(\"../lib\", __FILE__)\nrequire \"simple_form/version\"\n\nGem::Specification"
  },
  {
    "path": "test/action_view_extensions/builder_test.rb",
    "chars": 26151,
    "preview": "# frozen_string_literal: true\nrequire 'test_helper'\n\nclass BuilderTest < ActionView::TestCase\n  def with_custom_form_for"
  },
  {
    "path": "test/action_view_extensions/form_helper_test.rb",
    "chars": 5529,
    "preview": "# frozen_string_literal: true\nrequire 'test_helper'\n\nclass FormHelperTest < ActionView::TestCase\n\n  test 'SimpleForm for"
  },
  {
    "path": "test/components/custom_components_test.rb",
    "chars": 1882,
    "preview": "# frozen_string_literal: true\n\nrequire 'test_helper'\n\n# Module that represents a custom component.\nmodule Numbers\n  def "
  },
  {
    "path": "test/components/label_test.rb",
    "chars": 12926,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\n# Isolated tests for label without triggering f.l"
  },
  {
    "path": "test/form_builder/association_test.rb",
    "chars": 9764,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass AssociationTest < ActionView::TestCase\n  de"
  },
  {
    "path": "test/form_builder/button_test.rb",
    "chars": 1503,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass ButtonTest < ActionView::TestCase\n  def wit"
  },
  {
    "path": "test/form_builder/error_notification_test.rb",
    "chars": 3075,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\n# Tests for f.error_notification\nclass ErrorNotif"
  },
  {
    "path": "test/form_builder/error_test.rb",
    "chars": 9732,
    "preview": "# frozen_string_literal: true\nrequire 'test_helper'\n\n# Tests for f.error and f.full_error\nclass ErrorTest < ActionView::"
  },
  {
    "path": "test/form_builder/general_test.rb",
    "chars": 19327,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass FormBuilderTest < ActionView::TestCase\n  de"
  },
  {
    "path": "test/form_builder/hint_test.rb",
    "chars": 4828,
    "preview": "# frozen_string_literal: true\nrequire 'test_helper'\n\n# Tests for f.hint\nclass HintTest < ActionView::TestCase\n  def with"
  },
  {
    "path": "test/form_builder/input_field_test.rb",
    "chars": 6330,
    "preview": "# frozen_string_literal: true\nrequire 'test_helper'\n\n# Tests for f.input_field\nclass InputFieldTest < ActionView::TestCa"
  },
  {
    "path": "test/form_builder/label_test.rb",
    "chars": 4888,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass LabelTest < ActionView::TestCase\n  def with"
  },
  {
    "path": "test/form_builder/wrapper_test.rb",
    "chars": 13274,
    "preview": "# frozen_string_literal: true\nrequire 'test_helper'\n\nclass WrapperTest < ActionView::TestCase\n  test 'wrapper does not h"
  },
  {
    "path": "test/generators/simple_form_generator_test.rb",
    "chars": 1715,
    "preview": "# frozen_string_literal: true\nrequire 'test_helper'\n\nclass SimpleFormGeneratorTest < Rails::Generators::TestCase\n  tests"
  },
  {
    "path": "test/inputs/boolean_input_test.rb",
    "chars": 10361,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass BooleanInputTest < ActionView::TestCase\n  t"
  },
  {
    "path": "test/inputs/collection_check_boxes_input_test.rb",
    "chars": 12403,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass CollectionCheckBoxesInputTest < ActionView:"
  },
  {
    "path": "test/inputs/collection_radio_buttons_input_test.rb",
    "chars": 17708,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass CollectionRadioButtonsInputTest < ActionVie"
  },
  {
    "path": "test/inputs/collection_select_input_test.rb",
    "chars": 15644,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass CollectionSelectInputTest < ActionView::Tes"
  },
  {
    "path": "test/inputs/color_input_test.rb",
    "chars": 264,
    "preview": "# frozen_string_literal: true\n\nrequire 'test_helper'\n\nclass ColorInputTest < ActionView::TestCase\n  test 'input generate"
  },
  {
    "path": "test/inputs/country_input_test.rb",
    "chars": 1324,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass CountryInputTest < ActionView::TestCase\n  C"
  },
  {
    "path": "test/inputs/datetime_input_test.rb",
    "chars": 6255,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\n# Tests for datetime, date and time inputs when H"
  },
  {
    "path": "test/inputs/disabled_test.rb",
    "chars": 3501,
    "preview": "# frozen_string_literal: true\nrequire 'test_helper'\n\nclass DisabledTest < ActionView::TestCase\n  test 'string input is d"
  },
  {
    "path": "test/inputs/discovery_test.rb",
    "chars": 4583,
    "preview": "# frozen_string_literal: true\nrequire 'test_helper'\n\nclass DiscoveryTest < ActionView::TestCase\n  # Setup new inputs and"
  },
  {
    "path": "test/inputs/file_input_test.rb",
    "chars": 514,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass FileInputTest < ActionView::TestCase\n  test"
  },
  {
    "path": "test/inputs/general_test.rb",
    "chars": 4968,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass InputTest < ActionView::TestCase\n  test 'in"
  },
  {
    "path": "test/inputs/grouped_collection_select_input_test.rb",
    "chars": 6406,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass GroupedCollectionSelectInputTest < ActionVi"
  },
  {
    "path": "test/inputs/hidden_input_test.rb",
    "chars": 951,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass HiddenInputTest < ActionView::TestCase\n  te"
  },
  {
    "path": "test/inputs/numeric_input_test.rb",
    "chars": 6153,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass NumericInputTest < ActionView::TestCase\n  t"
  },
  {
    "path": "test/inputs/readonly_test.rb",
    "chars": 4052,
    "preview": "# frozen_string_literal: true\nrequire 'test_helper'\n\nclass ReadonlyTest < ActionView::TestCase\n  test 'string input gene"
  },
  {
    "path": "test/inputs/required_test.rb",
    "chars": 6138,
    "preview": "# frozen_string_literal: true\nrequire 'test_helper'\n\nclass RequiredTest < ActionView::TestCase\n  # REQUIRED AND PRESENCE"
  },
  {
    "path": "test/inputs/rich_text_area_input_test.rb",
    "chars": 525,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass RichTextAreaInputTest < ActionView::TestCas"
  },
  {
    "path": "test/inputs/string_input_test.rb",
    "chars": 6189,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass StringInputTest < ActionView::TestCase\n  te"
  },
  {
    "path": "test/inputs/text_input_test.rb",
    "chars": 1505,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass TextInputTest < ActionView::TestCase\n  test"
  },
  {
    "path": "test/inputs/time_zone_input_test.rb",
    "chars": 1140,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass TimeZoneInputTest < ActionView::TestCase\n  "
  },
  {
    "path": "test/inputs/weekday_input_test.rb",
    "chars": 487,
    "preview": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass WeekdayInputTest < ActionView::TestCase\n  t"
  },
  {
    "path": "test/simple_form_test.rb",
    "chars": 404,
    "preview": "# frozen_string_literal: true\nrequire 'test_helper'\n\nclass SimpleFormTest < ActiveSupport::TestCase\n  test 'setup block "
  },
  {
    "path": "test/support/discovery_inputs.rb",
    "chars": 1432,
    "preview": "# frozen_string_literal: true\nclass StringInput < SimpleForm::Inputs::StringInput\n  def input(wrapper_options = nil)\n   "
  },
  {
    "path": "test/support/misc_helpers.rb",
    "chars": 7767,
    "preview": "# frozen_string_literal: true\nmodule MiscHelpers\n  def store_translations(locale, translations, &block)\n    I18n.backend"
  },
  {
    "path": "test/support/mock_controller.rb",
    "chars": 476,
    "preview": "# frozen_string_literal: true\nclass MockController\n  attr_writer :action_name\n\n  def _routes\n    self\n  end\n\n  def actio"
  },
  {
    "path": "test/support/models.rb",
    "chars": 9747,
    "preview": "# frozen_string_literal: true\nAssociation = Struct.new(:klass, :name, :macro, :scope, :options)\n\nColumn = Struct.new(:na"
  },
  {
    "path": "test/test_helper.rb",
    "chars": 2141,
    "preview": "# frozen_string_literal: true\nrequire 'minitest/autorun'\n\nrequire 'active_model'\nrequire 'action_controller'\nrequire 'ac"
  }
]

About this extraction

This page contains the full source code of the heartcombo/simple_form GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 122 files (438.9 KB), approximately 115.7k tokens, and a symbol index with 590 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!