Skip to content

Instantly share code, notes, and snippets.

@dkniffin
Created June 25, 2021 14:58
Show Gist options
  • Save dkniffin/b16e44ff1519b01782124878ff1d2082 to your computer and use it in GitHub Desktop.
Save dkniffin/b16e44ff1519b01782124878ff1d2082 to your computer and use it in GitHub Desktop.
LayoutComponent
section[*section_attributes]
.container[*container_attributes]
.row
- columns.each_with_index do |column, i|
div[class=column_classes(column, i)]
= column
# frozen_string_literal: true
class LayoutComponent < BaseComponent
include ActiveModel::Validations
LAYOUT_DEFINITIONS = {
"12" => [{ xs: 12 }],
"10" => [{ xs: 12, md: 10, md_offset: 1 }],
"8" => [{ xs: 12, md: 8, md_offset: 2 }],
"6/6" => [{ xs: 12, md: 6 }, { xs: 12, md: 6 }],
"3/9" => [{ xs: 12, md: 3 }, { xs: 12, md: 9 }],
"9/3" => [{ xs: 12, md: 9 }, { xs: 12, md: 3 }],
"4/8" => [{ xs: 12, md: 4 }, { xs: 12, md: 8 }],
"8/4" => [{ xs: 12, md: 8 }, { xs: 12, md: 4 }],
"3/6/3" => [{ xs: 12, md: 3 }, { xs: 12, md: 6 }, { xs: 12, md: 3 }],
"custom" => []
}.freeze
validates :layout, inclusion: { in: LAYOUT_DEFINITIONS.keys }
validate :column_count_matches
attr_reader :layout, :section_attributes, :container_attributes
renders_many :columns
def initialize(layout:, section_attributes: {}, container_attributes: {})
@layout = layout
@section_attributes = section_attributes
@container_attributes = container_attributes
end
def column_classes(column, i)
classes = []
defaults = LAYOUT_DEFINITIONS[layout][i] || {}
column_args = column.args || {}
[:xs, :sm, :md, :lg].each do |size|
num = column_args[size] || defaults[size]
if num
classes << "col-#{size}-#{num}"
end
offset_key = "#{size}_offset".to_sym
offset = column_args[offset_key] || defaults[offset_key]
if offset
classes << "col-#{size}-offset-#{offset}"
end
end
class_names(*classes.push(column_args[:classes]))
end
private
def column_count_matches
return if layout == "custom"
if columns.count != LAYOUT_DEFINITIONS[layout].length
errors.add(:base, "The number of column slots must equal the number of columns supported by the layout")
end
end
end
= render LayoutComponent.new(layout: "12") do |l|
= l.column
span #{lorem_ipsum}
= render LayoutComponent.new(layout: "3/9") do |l|
= l.column
span #{lorem_ipsum}
= l.column
span #{lorem_ipsum}
= render LayoutComponent.new(layout: "3/6/3") do |l|
= l.column
span #{lorem_ipsum}
= l.column
span #{lorem_ipsum}
= l.column
span #{lorem_ipsum}
= render LayoutComponent.new(layout: "3/9") do |l|
= l.column(classes: "col-md-push-9")
span Column 1
= l.column(classes: "col-md-pull-3")
span Column 2
= render LayoutComponent.new(layout: "custom") do |l|
= l.column(xs: 12, sm: 6, md: 3, md_offset: 0, lg: 12)
span #{lorem_ipsum}
= l.column(xs: 12, sm: 6, md: 3, md_offset: 0, lg: 6)
span #{lorem_ipsum}
= l.column(xs: 12, sm: 10, sm_offset: 1, md: 6, md_offset: 0, lg: 6)
span #{lorem_ipsum}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment