-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
/
columns.rb
161 lines (135 loc) · 4.18 KB
/
columns.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
module ActiveAdmin
module Views
# = Columns Component
#
# The Columns component allows you draw content into scalable columns. All
# you need to do is define the number of columns and the component will
# take care of the rest.
#
# == Simple Columns
#
# To display columns, use the #columns method. Within the block, call the
# #column method to create a new column.
#
# To create a two column layout:
#
# columns do
# column do
# span "Column # 1
# end
# column do
# span "Column # 2
# end
# end
#
#
# == Multiple Span Columns
#
# To make a column span multiple, pass the :span option to the column method:
#
# columns do
# column span: 2 do
# span "Column # 1
# end
# column do
# span "Column # 2
# end
# end
#
# By default, each column spans 1 column. So the above layout would have 2 columns,
# the first being 2 time bigger than the second.
#
#
# == Max and Min Column Sizes
#
# Active Admin is a fluid width layout, which means that columns are all defined
# using percentages. Sometimes this can cause issues if you don't want a column
# to shrink or expand past a certain point.
#
# To overcome this, columns include a :max_width and :min_width option.
#
# columns do
# column max_width: "200px", min_width: "100px" do
# span "Column # 1
# end
# column do
# span "Column # 2
# end
# end
#
# Now the first column will not grow bigger than 200px and will not shrink smaller
# than 100px.
class Columns < ActiveAdmin::Component
builder_method :columns
# For documentation, please take a look at Column#build
def column(*args, &block)
insert_tag Column, *args, &block
end
# Override add child to set widths
def add_child(*)
super
calculate_columns!
end
protected
# Override the closing tag to include a clear
def closing_tag
"<div style=\"clear:both;\"></div>" + super
end
def margin_size
2
end
# Calculate our columns sizes and margins
def calculate_columns!
span_count = columns_span_count
columns_count = children.size
all_margins_width = margin_size * (span_count - 1)
column_width = (100.00 - all_margins_width) / span_count
columns.each_with_index do |column, i|
is_last_column = i == (columns_count - 1)
column.set_column_styles(column_width, margin_size, is_last_column)
end
end
def columns_span_count
count = 0
columns.each do |column|
count += column.span_size
end
count
end
def columns
children.select { |child| child.is_a?(Column) }
end
end
class Column < ActiveAdmin::Component
attr_accessor :span_size, :max_width, :min_width
# @param [Hash] options An options hash for the column
#
# @option options [Integer] :span The columns this column should span
def build(options = {})
options = options.dup
@span_size = options.delete(:span) || 1
@max_width = options.delete(:max_width)
@min_width = options.delete(:min_width)
super(options)
end
def set_column_styles(column_width, margin_width, is_last_column = false)
column_with_span_width = (span_size * column_width) + ((span_size - 1) * margin_width)
styles = []
styles << "width: #{column_with_span_width}%;"
if max_width
styles << "max-width: #{safe_width(max_width)};"
end
if min_width
styles << "min-width: #{safe_width(min_width)};"
end
styles << "margin-right: #{margin_width}%;" unless is_last_column
set_attribute :style, styles.join(" ")
end
private
# Converts values without a '%' or 'px' suffix to a pixel value
def safe_width(width)
width.to_s.gsub(/\A(\d+)\z/, '\1px')
end
end
end
end