4
1

はじめに

以前タグを扱うことがあり、そこでの対処法を備忘録として記載しておきます。
内容としては、本来CSSでやる部分をrubyでやってみようという興味範囲の記事となります

問題点

背景色のみを設定していたため、色合いによっては見えない等が発生していました
image.png

改修内容

今回からview_componentを利用するようにしました

送られてくる配色レコードは、「#ffffff」のような形だったので、下の記事を参考に分解するメソッドを構築
https://qiita.com/t_fujise/items/be13f5288d4423e56a64

    def rgb_color
      @color.delete('#').each_char.each_slice(2).map { |a| a.join.to_i(16) }
    end

フォント色は背景色に応じて黒と白を適応させるため、以下のページを参考に計算式を利用させていただきました
http://www.asahi-net.or.jp/~gx4s-kmgi/page04.html

  def font_color
    brightness = ((rgb_color[0] * 299) + (rgb_color[1] * 587) + (rgb_color[2] * 114)) / 1000
    if brightness < 128
      '#ffffff'
    else
      '#000000'
    end
  end

レコードに意図しない値が入った時の対策として、RGBの値が0の場合、強制的にタグ色が黒になる様にしました

  def bg_color
    if rgb_color[0].zero? && rgb_color[1].zero? && rgb_color[2].zero?
      '#000000'
    else
      @color
    end
  end

最後にタグ色が白の場合、全体色が白だったので境界線が見づらくなると思い、線を引くようにクラスに追加するようにしました

  def add_class
    return unless rgb_color[0] == 255 && rgb_color[1] == 255 && rgb_color[2] == 255

    'outline outline-offset-1 outline-1'
  end

全体的なソース

tag_component.rb
class Admin::Common::TagComponent < ViewComponent::Base
  def initialize(text:, color:)
    @color = color
    @text = text
  end

  def font_color
    brightness = ((rgb_color[0] * 299) + (rgb_color[1] * 587) + (rgb_color[2] * 114)) / 1000
    if brightness < 128
      '#ffffff'
    else
      '#000000'
    end
  end

  def bg_color
    if rgb_color[0].zero? && rgb_color[1].zero? && rgb_color[2].zero?
      '#000000'
    else
      @color
    end
  end

  def add_class
    return unless rgb_color[0] == 255 && rgb_color[1] == 255 && rgb_color[2] == 255

    'outline outline-offset-1 outline-1'
  end

  private

    def rgb_color
      @color.delete('#').each_char.each_slice(2).map { |a| a.join.to_i(16) }
    end
end
tag_component.html.haml
%span.inline-block.rounded-xl.px-2.mx-2{style: "background-color: #{bg_color}; color: #{font_color}", class: add_class}
  = @text

呼び出し側

    タグ
    .flex.items-center
      = f.collection_check_boxes :tag_ids, MasterTag.use_in_e_learning, :id, :name do |tag|
        = tag.label do
          .flex.items-center.m-1
            = tag.check_box(class: 'checkbox rounded')
            = render Admin::Common::TagComponent.new(text: tag.text, color: tag.object.color_code)

完成図

image.png

まとめ(前回との比較)

変更前(呼び出し元)

    タグ
    = content_tag(:dev, class: 'flex items-center') do
      = f.collection_check_boxes :tag_ids, MasterTag.all, :id, :name do |tag|
        = tag.label do
          = content_tag(:dev, class: 'flex items-center m-1') do
            = tag.check_box(class: 'checkbox rounded')
            = content_tag(:dev, tag.text, class: 'badge badge-lg', style: "background-color: #{tag.object.color_code}")

変更後(呼び出し元)

    タグ
    .flex.items-center
      = f.collection_check_boxes :tag_ids, MasterTag.all, :id, :name do |tag|
        = tag.label do
          .flex.items-center.m-1
            = tag.check_box(class: 'checkbox rounded')
            = render Admin::Common::TagComponent.new(text: tag.text, color: tag.object.color_code)

変更前(デザイン)
image.png
変更後(デザイン)
image.png

さいごに

色の反転に関してはCSSでやる方法(むしろこっちが一般的?)もありますが、今回はrubyでやってみたいなーという気持ちからやってみました。
また、view_componentを使い始めたのですが、個人的にとても使いやすいと思います。
前回daisyUIのbadgeを利用していましたが、微妙にデザインが汚かったので、今回はtailwindで作成しました。
(まとめの比較画像を拡大してみてもらったら分かるかと思います)

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1