はじめに
以前タグを扱うことがあり、そこでの対処法を備忘録として記載しておきます。
内容としては、本来CSSでやる部分をrubyでやってみようという興味範囲の記事となります
問題点
背景色のみを設定していたため、色合いによっては見えない等が発生していました
改修内容
今回から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
全体的なソース
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
%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)
完成図
まとめ(前回との比較)
変更前(呼び出し元)
タグ
= 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)
さいごに
色の反転に関してはCSSでやる方法(むしろこっちが一般的?)もありますが、今回はrubyでやってみたいなーという気持ちからやってみました。
また、view_componentを使い始めたのですが、個人的にとても使いやすいと思います。
前回daisyUIのbadgeを利用していましたが、微妙にデザインが汚かったので、今回はtailwindで作成しました。
(まとめの比較画像を拡大してみてもらったら分かるかと思います)