Skip to content

Commit

Permalink
fix(tailwindcss): Add Taildwind CSS generator
Browse files Browse the repository at this point in the history
  • Loading branch information
JuanVqz committed Jun 28, 2024
1 parent c080700 commit 1117a2b
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 6 deletions.
28 changes: 22 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
# SimpleForm::Theme
Short description and motivation.

## Usage
How to use my plugin.

## Installation
Add this line to your application's Gemfile:

Expand All @@ -13,12 +10,31 @@ gem 'simple_form-theme'

And then execute:
```bash
$ bundle
bundle
```

As an alternative instead of adding an additional dependency to your project,
you can copy the initializer file to your project from the GitHub repository.

Example:
```bash
cp lib/generators/simple_form/theme/templates/config/initializers/simple_form_tailwindcss.rb yourapp/config/initializers/simple_form_tailwindcss.rb
```

Or install it yourself as:
However, if you install the gem, you will get the latest updates and improvements.

## Requirements

* Make sure you have installed [simple_form](https://github.com/heartcombo/simple_form) gem.
* Make sure you have installed the decired css framework. (Installing the CSS Framework is out of the scope of this gem).
* [Tailwindcss](https://tailwindcss.com/docs/installation)

## Usage

### Install Tailwind CSS initializer

```bash
$ gem install simple_form-theme
bin/rails generate simple_form:theme:tailwind install
```

## Contributing
Expand Down
8 changes: 8 additions & 0 deletions lib/generators/simple_form/theme/tailwind/USAGE
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Description:
Install the simple form tailwindcss config file in your app.

Example:
bin/rails generate simple_form:theme:tailwind install

This will create:
config/initializers/simple_form_tailwindcss.rb
10 changes: 10 additions & 0 deletions lib/generators/simple_form/theme/tailwind/tailwind_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

class SimpleForm::Theme::TailwindGenerator < Rails::Generators::NamedBase
source_root File.expand_path('templates', __dir__)

desc 'Copy the tailwindcss initializer file for simple_form'
def copy_initializer_file
template 'config/initializers/simple_form_tailwindcss.rb', 'config/initializers/simple_form_tailwindcss.rb'
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# frozen_string_literal: true

# Use this setup block to configure all options available in SimpleForm.
SimpleForm.setup do |config|
config.wrappers :vertical_form, tag: :div, class: 'mb-4' 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: 'block mb-2 text-sm font-medium text-gray-900 dark:text-white'
b.use :input,
class: 'bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
error_class: 'bg-red-50 border-red-500 text-red-900 placeholder-red-700 focus:ring-red-500 dark:bg-gray-700 focus:border-red-500 dark:text-red-500 dark:placeholder-red-500 dark:border-red-500',
valid_class: 'bg-green-50 border-green-500 text-green-900 dark:text-green-400 placeholder-green-700 dark:placeholder-green-500 focus:ring-green-500 focus:border-green-500 dark:bg-gray-700 dark:border-green-500'
b.use :full_error, wrap_with: { tag: :p, class: 'mt-2 text-sm text-red-600 dark:text-red-600' }
b.use :hint, wrap_with: { tag: :small, class: 'text-sm text-gray-400 dark:text-gray-400' }
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: 'form-group mb-3',
error_class: 'form-group-invalid',
valid_class: 'form-group-valid' 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, class: 'ml-3 block text-sm font-medium text-gray-700'
end
b.use :input, class: 'focus:ring-indigo-500 h-4 w-4 text-sky-600 border-gray-300 mr-2',
error_class: 'is-invalid border-red-400',
valid_class: 'is-valid'
b.use :full_error, wrap_with: { tag: :p, class: 'mt-2 text-sm text-red-600 dark:text-red-600' }
b.use :hint, wrap_with: { tag: :small, class: 'text-gray-400' }
end

# vertical input for radio buttons and check boxes
# config.wrappers :vertical_check_boxes_collection, item_wrapper_class: 'form-check',
# item_label_class: 'form-check-label',
# tag: 'fieldset', class: 'form-group mb-3',
# error_class: 'form-group-invalid',
# valid_class: 'form-group-valid' 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, class: 'ml-3 block text-sm font-medium text-gray-700'
# end
# b.use :input, class: 'focus:ring-indigo-500 h-4 w-4 text-sky-600 border-gray-300 rounded mr-2',
# error_class: 'is-invalid border-red-400',
# valid_class: 'is-valid'
# b.use :full_error, wrap_with: {tag: :p, class: "mt-2 text-sm text-red-600 dark:text-red-600"}
# b.use :hint, wrap_with: { tag: :small, class: 'text-gray-400' }
# 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',
tag: :div,
class: 'form-group flex flex-row-reverse w-fit mb-3',
error_class: 'form-group-invalid',
valid_class: 'form-group-valid' do |b|
b.use :html5
b.optional :readonly
b.use :label, class: 'pt-0 mb-2'
b.wrapper :grid_wrapper, tag: :div do |ba|
ba.use :input, class: 'focus:ring-indigo-500 h-4 w-4 text-sky-600 border-gray-300 rounded mr-2',
error_class: 'is-invalid', valid_class: 'is-valid'
ba.use :full_error, wrap_with: { tag: :p, class: 'mt-2 text-sm text-red-600 dark:text-red-600' }
ba.use :hint, wrap_with: { tag: :small, class: 'text-gray-400' }
end
end

# vertical multi select
config.wrappers :vertical_multi_select, tag: :div, class: 'mb-4' do |b|
b.use :html5
b.optional :readonly
b.use :label, class: 'block mb-2 text-sm font-medium text-gray-900 dark:text-white'
b.wrapper tag: :div, class: 'flex flex-col md:flex-row gap-1 justify-between items-center' do |ba|
ba.use :input,
class: 'bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
error_class: 'bg-red-50 border-red-500 text-red-900 placeholder-red-700 focus:ring-red-500 dark:bg-gray-700 focus:border-red-500 dark:text-red-500 dark:placeholder-red-500 dark:border-red-500',
valid_class: 'bg-green-50 border-green-500 text-green-900 dark:text-green-400 placeholder-green-700 dark:placeholder-green-500 focus:ring-green-500 focus:border-green-500 dark:bg-gray-700 dark:border-green-500'
end
b.use :full_error, wrap_with: { tag: :p, class: 'mt-2 text-sm text-red-600 dark:text-red-600' }
b.use :hint, wrap_with: { tag: :small, class: 'text-gray-400' }
end

# vertical input for boolean
config.wrappers :vertical_boolean, tag: :fieldset, class: 'mb-3',
error_class: 'form-group-invalid',
valid_class: 'form-group-valid' do |b|
b.use :html5
b.optional :readonly
b.wrapper :form_check_wrapper, tag: 'div' do |bb|
bb.use :input, class: 'focus:ring-indigo-500 h-4 w-4 text-sky-600 border-gray-300 rounded mr-2',
error_class: '!border-red-500',
valid_class: 'is-valid'
bb.use :label, class: 'mb-2'
end
b.use :full_error, wrap_with: { tag: :p, class: 'mt-2 text-sm text-red-600 dark:text-red-600' }
b.use :hint, wrap_with: { tag: :small, class: 'text-gray-400' }
end

# vertical file input
config.wrappers :vertical_file, tag: :div, class: 'mb-4' do |b|
b.use :html5
b.use :placeholder
b.optional :maxlength
b.optional :minlength
b.optional :readonly
b.use :label, class: 'block mb-2 text-sm font-medium text-gray-900 dark:text-white'
b.use :input,
class: 'block w-full text-sm text-gray-900 border border-gray-300 rounded-lg cursor-pointer bg-gray-50 dark:text-gray-400 focus:outline-none dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400',
error_class: 'bg-red-50 border-red-500 text-red-900 placeholder-red-700 focus:ring-red-500 dark:bg-gray-700 focus:border-red-500 dark:text-red-500 dark:placeholder-red-500 dark:border-red-500',
valid_class: 'bg-green-50 border-green-500 text-green-900 dark:text-green-400 placeholder-green-700 dark:placeholder-green-500 focus:ring-green-500 focus:border-green-500 dark:bg-gray-700 dark:border-green-500'
b.use :full_error, wrap_with: { tag: :p, class: 'mt-2 text-sm text-red-600 dark:text-red-600' }
b.use :hint, wrap_with: { tag: :small, class: 'text-sm text-gray-400 dark:text-gray-400' }
end

# 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,
file: :vertical_file,
datetime: :vertical_multi_select,
radio_buttons: :vertical_collection,
time: :vertical_multi_select
}

# How the label text should be generated altogether with the required text.
config.label_text = ->(label, required, _explicit_label) { "#{label} #{required}" }

# CSS class for buttons
config.button_class = 'text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800'

# 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 = 'bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded'

# 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

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

# add validation classes to `input_field`
config.input_field_error_class = 'bg-red-50'
config.input_field_valid_class = 'bg-green-50'
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

require 'test_helper'
require 'generators/simple_form/theme/tailwind/tailwind_generator'

module SimpleForm::Theme
class SimpleForm::Theme::TailwindGeneratorTest < Rails::Generators::TestCase
tests SimpleForm::Theme::TailwindGenerator
destination Rails.root.join('tmp/generators')
setup :prepare_destination

test 'generator runs without errors' do
assert_nothing_raised do
run_generator ['install']
end
end
end
end

0 comments on commit 1117a2b

Please sign in to comment.