Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

Rails: Tailwind CSSをカスタムフォームビルダーで使う(翻訳)

概要

元サイトの許諾を得て翻訳・公開いたします。

日本語タイトルは内容に即したものにしました。

参考: §7 フォームビルダーをカスタマイズする -- Action View フォームヘルパー - Railsガイド

Rails: フォーム作成にTailwind CSSを使う(翻訳)

Railsのフォームビルダーは、さまざまなフォームを手軽に構築できる優秀なインターフェイスを提供してくれます。しかし、Tailwind CSSを使っている多くのRails開発者が抱えがちな悩みは、text_fieldtext_areacheck_boxesのスタイルを結局どう設定すればいいのかというものです。解決策はいくつか考えられます。

  • 1. Tailwindのクラスをすべてコピーして使う。
  • 2. Tailwindの@applyディレクティブを使って(素の)クラスをフォームのinputフィールドなどに追加する。
  • 3. フィールド種別ごとに(ViewComponentで)カスタムコンポーネントを使う。

オプション2は再利用もしやすく変更も適用も簡単なので、私が長年使い続けてきたソリューションでした。
しかし、私が次のSaaSを手掛けたときに、カスタムフォームビルダーを使うという新しいオプションを検討してみました。

🔗 Railsのフォームビルダーとは

RailsのFormBuilderは、HTMLフォームを生成・処理するための構造化された方法を提供し、モデルオブジェクトとその属性に自動的に関連付けられるフォームフィールドを作成できます。私はフォームビルダーを多用しています!

🔗 基本的なカスタムフォームビルダーを作成する

Action Viewのフォームビルダーを独自に作成するには、以下のようにActionView::Helpers::FormBuilderを継承したサブクラスを作成します。

最も基本的なバージョンは以下のような感じになります。

class CustomFormBuilder < ActionView::Helpers::FormBuilder
  def text_field(attribute, options = {})
    super(attribute, options.merge(class: "px-2 py-1 text-gray-900 bg-gray-50 rounded"))
  end

  # def password_field(attribute, options = {});end
  # def email_field(attribute, options = {});end
  # def file_field(attribute, options = {});end
  # def url_field(attribute, options = {});end
end

これを見れば、フォームビルダーを書くときに、フォームでサポートされているすべてのフィールド種別ごとに必要なTailwindCSSクラスをどのように追加すればよいかはおわかりだと思います。
最も一般的なフィールド種別は、text_fieldpassword_fieldemail_fieldfile_fieldurl_fieldです。

新しいフォームビルダーはさまざまな方法で活用できます。
特定のフォームだけで使う場合は以下のように書きます。

<%= form_with model: @user, builder: CustomFormBuilder do |form| %>
  <%= form.text_field :name %>
<% end %>

すべてのフォームに適用したい場合は、ApplicationControllerに以下を追加します。

default_form_builder CustomFormBuilder

上の例をレンダリングすると以下のようになります。

<input type="text" name="user[name]" class="px-2 py-1 text-gray-900 rounded bg-gray-50" id="user_name">

🔗 Rails Designerをインクルードする

Rails Designer のUIコンポーネントライブラリにはカスタムFormBuilderも含まれているため、余計な手間をかけずに美しいフォームフィールドを作成できます。

text_fieldpassword_fieldなどの一般的なフィールド種別をすべてサポートしているだけでなく、collection_selectcollection_radio_buttonsもサポートしています。

また、このUIコンポーネントライブラリにはスマートインプット(Smart Inputs)という機能もあります。 simple_formなどのgemを使ったことがある方にはおなじみの機能です。<%= form.input :name %>と書くだけで、以下のようにラベルとラッピングdiv要素を含む適切なフィールドヘルパーが自動的にレンダリングされます。

<div class="w-full mt-4">
  <label class="text-gray-700" for="user_title">Title</label>

  <input class="w-full px-2 py-1 text-sm text-gray-900 rounded bg-gray-50" type="text" name="user[title]" id="user_title">
</div>

また、<%= form.input :email %>と書けばemail_fieldを、<%= form.input :password %>と書けばpassword_fieldを適切なフィールド種別で正しくレンダリングしてくれます。

この機能を支えているのは、Rails DesignerのFormLabelComponentFieldComponentです。

詳しくはRails DesignerのフォームビルダードキュメントRails UIコンポーネントライブラリをぜひチェックしてみてください(チームの皆さんや自分自身へのクリスマスプレゼントにもどうぞ🎅)。

関連記事

Rails: Tailwind + Stimulusで2FA/OTP/SMS認証用の6桁フィールドを作る(翻訳)

Railsフロントエンド: ViewComponent+Tailwind CSS+Hotwireの便利技8つ(翻訳)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。