bootstrap-cells 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.gitlab-ci.yml +13 -0
- data/.rspec +2 -0
- data/.rubocop.yml +27 -0
- data/CHANGELOG +29 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +200 -0
- data/Rakefile +8 -0
- data/app/assets/javascripts/bootstrap-cells/add_many_event_listeners.js +11 -0
- data/app/assets/javascripts/bootstrap-cells/index.js +3 -0
- data/app/assets/stylesheets/_bootstrap-cells.scss +7 -0
- data/app/views/kaminari/bootstrap/_first_page.html.erb +15 -0
- data/app/views/kaminari/bootstrap/_gap.html.erb +12 -0
- data/app/views/kaminari/bootstrap/_last_page.html.erb +16 -0
- data/app/views/kaminari/bootstrap/_next_page.html.erb +16 -0
- data/app/views/kaminari/bootstrap/_page.html.erb +17 -0
- data/app/views/kaminari/bootstrap/_paginator.html.erb +32 -0
- data/app/views/kaminari/bootstrap/_prev_page.html.erb +16 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/bootstrap-cells.gemspec +36 -0
- data/lib/bootstrap-cells.rb +16 -0
- data/lib/bootstrap-cells/cells/alert/body.erb +7 -0
- data/lib/bootstrap-cells/cells/alert/show.erb +7 -0
- data/lib/bootstrap-cells/cells/alert/title.erb +9 -0
- data/lib/bootstrap-cells/cells/alert_cell.rb +39 -0
- data/lib/bootstrap-cells/cells/base_cell.rb +43 -0
- data/lib/bootstrap-cells/cells/button/show.erb +17 -0
- data/lib/bootstrap-cells/cells/button_cell.rb +41 -0
- data/lib/bootstrap-cells/cells/card/block.erb +14 -0
- data/lib/bootstrap-cells/cells/card/block_body.erb +5 -0
- data/lib/bootstrap-cells/cells/card/block_subtitle.erb +5 -0
- data/lib/bootstrap-cells/cells/card/block_text.erb +5 -0
- data/lib/bootstrap-cells/cells/card/block_title.erb +5 -0
- data/lib/bootstrap-cells/cells/card/footer.erb +9 -0
- data/lib/bootstrap-cells/cells/card/header.erb +9 -0
- data/lib/bootstrap-cells/cells/card/img_bottom.erb +9 -0
- data/lib/bootstrap-cells/cells/card/img_top.erb +9 -0
- data/lib/bootstrap-cells/cells/card/list_group.erb +9 -0
- data/lib/bootstrap-cells/cells/card/show.erb +9 -0
- data/lib/bootstrap-cells/cells/card/table.erb +9 -0
- data/lib/bootstrap-cells/cells/card_cell.rb +152 -0
- data/lib/bootstrap-cells/cells/column/td.erb +1 -0
- data/lib/bootstrap-cells/cells/column/th.erb +9 -0
- data/lib/bootstrap-cells/cells/column_cell.rb +49 -0
- data/lib/bootstrap-cells/cells/field/required_field.scss +5 -0
- data/lib/bootstrap-cells/cells/field/show.erb +15 -0
- data/lib/bootstrap-cells/cells/field_cell.rb +96 -0
- data/lib/bootstrap-cells/cells/fields_for/form.scss +12 -0
- data/lib/bootstrap-cells/cells/fields_for/form_horizontal.scss +33 -0
- data/lib/bootstrap-cells/cells/fields_for/show.erb +3 -0
- data/lib/bootstrap-cells/cells/fields_for_cell.rb +15 -0
- data/lib/bootstrap-cells/cells/kv_horizontal/show.erb +17 -0
- data/lib/bootstrap-cells/cells/kv_horizontal_cell.rb +34 -0
- data/lib/bootstrap-cells/cells/kv_vertical/show.erb +17 -0
- data/lib/bootstrap-cells/cells/kv_vertical_cell.rb +32 -0
- data/lib/bootstrap-cells/cells/modal/body.erb +9 -0
- data/lib/bootstrap-cells/cells/modal/button.erb +9 -0
- data/lib/bootstrap-cells/cells/modal/content.erb +12 -0
- data/lib/bootstrap-cells/cells/modal/footer.erb +10 -0
- data/lib/bootstrap-cells/cells/modal/header.erb +12 -0
- data/lib/bootstrap-cells/cells/modal/modal.js +15 -0
- data/lib/bootstrap-cells/cells/modal/show.erb +9 -0
- data/lib/bootstrap-cells/cells/modal_cell.rb +64 -0
- data/lib/bootstrap-cells/cells/pages/pages.scss +4 -0
- data/lib/bootstrap-cells/cells/pages/show.erb +3 -0
- data/lib/bootstrap-cells/cells/pages_cell.rb +16 -0
- data/lib/bootstrap-cells/cells/table/nubbin.scss +40 -0
- data/lib/bootstrap-cells/cells/table/show.erb +7 -0
- data/lib/bootstrap-cells/cells/table/table_sort.scss +17 -0
- data/lib/bootstrap-cells/cells/table/table_striped_nested.scss +8 -0
- data/lib/bootstrap-cells/cells/table/tbody.erb +3 -0
- data/lib/bootstrap-cells/cells/table/tbody_button_for_nested_row.erb +9 -0
- data/lib/bootstrap-cells/cells/table/tbody_final_row.erb +9 -0
- data/lib/bootstrap-cells/cells/table/tbody_first_row.erb +9 -0
- data/lib/bootstrap-cells/cells/table/tbody_nested_row.erb +6 -0
- data/lib/bootstrap-cells/cells/table/tbody_rows.erb +35 -0
- data/lib/bootstrap-cells/cells/table/thead.erb +11 -0
- data/lib/bootstrap-cells/cells/table_cell.rb +68 -0
- data/lib/bootstrap-cells/cells/tabs/show.erb +19 -0
- data/lib/bootstrap-cells/cells/tabs_cell.rb +40 -0
- data/lib/bootstrap-cells/engine.rb +9 -0
- metadata +307 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
<%# Link to the "Previous" page
|
2
|
+
- available local variables
|
3
|
+
url: url to the previous page
|
4
|
+
current_page: a page object for the currently displayed page
|
5
|
+
num_pages: total number of pages
|
6
|
+
per_page: number of items to fetch per page
|
7
|
+
remote: data-remote
|
8
|
+
-%>
|
9
|
+
<% unless current_page.first? %>
|
10
|
+
<li class="prev">
|
11
|
+
<%= link_to raw(t 'views.pagination.previous'),
|
12
|
+
url,
|
13
|
+
rel: 'prev',
|
14
|
+
remote: remote %>
|
15
|
+
</li>
|
16
|
+
<% end %>
|
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'bootstrap-cells'
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require 'irb'
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
lib = File.expand_path('../lib', __FILE__)
|
5
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'bootstrap-cells'
|
9
|
+
spec.version = '0.1.5'
|
10
|
+
spec.authors = ['Stephen Margheim']
|
11
|
+
spec.email = ['margheim@mail.med.upenn.edu']
|
12
|
+
|
13
|
+
spec.summary = 'Cells for common Bootstrap components.'
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
16
|
+
f.match(%r{^(test|spec|features|coverage)/})
|
17
|
+
end
|
18
|
+
spec.bindir = 'exe'
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.add_dependency 'cells', '~> 4.0'
|
23
|
+
spec.add_dependency 'cells-rails', '>= 0.0.8'
|
24
|
+
spec.add_dependency 'cells-erb', '>= 0.1.0'
|
25
|
+
spec.add_dependency 'kaminari', '~> 1.0'
|
26
|
+
|
27
|
+
spec.add_development_dependency 'rails', '~> 4.2'
|
28
|
+
spec.add_development_dependency 'bundler'
|
29
|
+
spec.add_development_dependency 'rake'
|
30
|
+
spec.add_development_dependency 'rspec-rails'
|
31
|
+
spec.add_development_dependency 'sqlite3'
|
32
|
+
spec.add_development_dependency 'simplecov'
|
33
|
+
spec.add_development_dependency 'simplecov-console'
|
34
|
+
spec.add_development_dependency 'rspec-cells'
|
35
|
+
spec.add_development_dependency 'capybara'
|
36
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cells'
|
4
|
+
require 'cells-rails'
|
5
|
+
require 'cells-erb'
|
6
|
+
require 'kaminari'
|
7
|
+
|
8
|
+
require 'bootstrap-cells/engine'
|
9
|
+
require 'bootstrap-cells/cells/base_cell'
|
10
|
+
|
11
|
+
Dir[BootstrapCells::Engine.root.join('lib', 'bootstrap-cells', 'cells', '**', '*.rb')].each do |cell|
|
12
|
+
require cell
|
13
|
+
end
|
14
|
+
|
15
|
+
module BootstrapCells
|
16
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AlertCell < BaseCell
|
4
|
+
private
|
5
|
+
|
6
|
+
def alert_props
|
7
|
+
defaults = {
|
8
|
+
class: c('alert',
|
9
|
+
('alert-dismissable' if options[:dismissable]),
|
10
|
+
("alert-#{options[:type]}" if options[:type]),
|
11
|
+
('border-silver' unless options[:type])),
|
12
|
+
role: 'alert',
|
13
|
+
}
|
14
|
+
merge_props(from: defaults, to: options.dig(:props, :alert))
|
15
|
+
end
|
16
|
+
|
17
|
+
def title_props
|
18
|
+
defaults = {
|
19
|
+
class: 'alert-title',
|
20
|
+
}
|
21
|
+
merge_props(from: defaults, to: options.dig(:props, :title))
|
22
|
+
end
|
23
|
+
|
24
|
+
def title_text
|
25
|
+
return nil if options.key?(:title) && !options[:title]
|
26
|
+
options[:title] || options[:type].to_s.titleize
|
27
|
+
end
|
28
|
+
|
29
|
+
def body_props
|
30
|
+
defaults = {
|
31
|
+
class: 'alert-body',
|
32
|
+
}
|
33
|
+
merge_props(from: defaults, to: options.dig(:props, :body))
|
34
|
+
end
|
35
|
+
|
36
|
+
def body_text
|
37
|
+
options[:body]
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class BaseCell < Cell::ViewModel
|
4
|
+
view_paths << "#{File.dirname(__dir__)}/cells"
|
5
|
+
|
6
|
+
def c(*class_list)
|
7
|
+
class_list.flatten.compact.uniq.map(&:to_s).map(&:strip).join(' ').strip
|
8
|
+
end
|
9
|
+
|
10
|
+
def merge_props(from:, to:)
|
11
|
+
from ||= {}
|
12
|
+
to ||= {}
|
13
|
+
from = from.deep_symbolize_keys
|
14
|
+
to = to.deep_symbolize_keys
|
15
|
+
from.deep_merge(to) { |k, o, n| k == :class ? c(n, o) : n }
|
16
|
+
end
|
17
|
+
|
18
|
+
def renderable?(option)
|
19
|
+
options[option].respond_to?(:call)
|
20
|
+
end
|
21
|
+
|
22
|
+
def render_option(option)
|
23
|
+
return nil unless renderable?(option)
|
24
|
+
options[option].call
|
25
|
+
end
|
26
|
+
|
27
|
+
def render_attribute_path(path, object)
|
28
|
+
path&.to_s&.split('.')&.inject(object, :try)&.to_s
|
29
|
+
end
|
30
|
+
|
31
|
+
def fetch_errors(object, field)
|
32
|
+
field = field.to_s
|
33
|
+
return nil unless object.try(:errors)
|
34
|
+
errors = object.errors[field]
|
35
|
+
errors = object.errors[field.remove('_id')] unless errors.any?
|
36
|
+
return nil unless errors.any?
|
37
|
+
errors.join('; ')
|
38
|
+
end
|
39
|
+
|
40
|
+
def titleized_attribute_path(attribute)
|
41
|
+
attribute.to_s.split('.').map(&:titleize).join(' ')
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<%= content_tag(tag, **button_props) do %>
|
2
|
+
<% if @options[:icon] %>
|
3
|
+
<%= content_tag(:span, class: 'flex justify-between items-center') do %>
|
4
|
+
<% if left_icon? %>
|
5
|
+
<%= content_tag(:i, nil, class: "fa fa-#{icon} mr-1") %>
|
6
|
+
<% end %>
|
7
|
+
<%= content_tag(:span, button_text) %>
|
8
|
+
<% if right_icon? %>
|
9
|
+
<%= content_tag(:i, nil, class: "fa fa-#{icon} ml-1") %>
|
10
|
+
<% end %>
|
11
|
+
<% end %>
|
12
|
+
<% else %>
|
13
|
+
<%= button_text %>
|
14
|
+
<% end %>
|
15
|
+
|
16
|
+
<%= append_text %>
|
17
|
+
<% end %>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class ButtonCell < BaseCell
|
4
|
+
private
|
5
|
+
|
6
|
+
def tag
|
7
|
+
options[:link] ? :a : :button
|
8
|
+
end
|
9
|
+
|
10
|
+
def button_props
|
11
|
+
defaults = {
|
12
|
+
class: 'btn btn-default',
|
13
|
+
(tag == :a ? :role : :type) => 'button',
|
14
|
+
}
|
15
|
+
defaults[:href] = options[:link] if tag == :a
|
16
|
+
merge_props(from: defaults, to: options.dig(:props, :button))
|
17
|
+
end
|
18
|
+
|
19
|
+
def button_text
|
20
|
+
options[:text]
|
21
|
+
end
|
22
|
+
|
23
|
+
def icon
|
24
|
+
return options[:icon] if options[:icon].is_a?(String)
|
25
|
+
return options.dig(:icon, :icon) if options[:icon].is_a?(Hash)
|
26
|
+
end
|
27
|
+
|
28
|
+
def left_icon?
|
29
|
+
return false unless options[:icon].is_a?(Hash)
|
30
|
+
options.dig(:icon, :justify).to_s == 'left'
|
31
|
+
end
|
32
|
+
|
33
|
+
def right_icon?
|
34
|
+
return true unless options[:icon].is_a?(Hash)
|
35
|
+
options.dig(:icon, :justify).to_s == 'right'
|
36
|
+
end
|
37
|
+
|
38
|
+
def append_text
|
39
|
+
options[:append]
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<% if block_props.present? %>
|
2
|
+
<%= content_tag(:div, **block_props) do %>
|
3
|
+
<% if renderable?(:block) %>
|
4
|
+
<%= render_option(:block) %>
|
5
|
+
<% elsif block_text.is_a?(String) %>
|
6
|
+
<%= block_text %>
|
7
|
+
<% else %>
|
8
|
+
<%= render :block_title %>
|
9
|
+
<%= render :block_subtitle %>
|
10
|
+
<%= render :block_body %>
|
11
|
+
<%= render :block_text %>
|
12
|
+
<% end %>
|
13
|
+
<% end %>
|
14
|
+
<% end %>
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CardCell < BaseCell
|
4
|
+
private
|
5
|
+
|
6
|
+
def card_props
|
7
|
+
defaults = {
|
8
|
+
class: 'card',
|
9
|
+
}
|
10
|
+
merge_props(from: defaults, to: options.dig(:props, :card))
|
11
|
+
end
|
12
|
+
|
13
|
+
def img_top_props
|
14
|
+
return nil unless options[:img_top] || options.dig(:props, :img_top)
|
15
|
+
defaults = {
|
16
|
+
class: 'card-img-top',
|
17
|
+
}
|
18
|
+
merge_props(from: defaults, to: options.dig(:props, :img_top))
|
19
|
+
end
|
20
|
+
|
21
|
+
def img_top_text
|
22
|
+
options[:img_top]
|
23
|
+
end
|
24
|
+
|
25
|
+
def header_props
|
26
|
+
return nil unless options[:header] || options.dig(:props, :header)
|
27
|
+
defaults = {
|
28
|
+
class: 'card-header',
|
29
|
+
}
|
30
|
+
merge_props(from: defaults, to: options.dig(:props, :header))
|
31
|
+
end
|
32
|
+
|
33
|
+
def header_text
|
34
|
+
options[:header]
|
35
|
+
end
|
36
|
+
|
37
|
+
def block_props
|
38
|
+
return nil unless options[:block] || options.dig(:props, :block)
|
39
|
+
defaults = {
|
40
|
+
class: 'card-block',
|
41
|
+
}
|
42
|
+
merge_props(from: defaults, to: options.dig(:props, :block)&.except(:title, :subtitle, :body, :text))
|
43
|
+
end
|
44
|
+
|
45
|
+
def block_text
|
46
|
+
options[:block]
|
47
|
+
end
|
48
|
+
|
49
|
+
def block_title_props
|
50
|
+
return nil unless options[:block].is_a?(Hash)
|
51
|
+
return nil unless options.dig(:block, :title) || options.dig(:props, :block, :title)
|
52
|
+
defaults = {
|
53
|
+
class: 'card-title',
|
54
|
+
}
|
55
|
+
merge_props(from: defaults, to: options.dig(:props, :block, :title))
|
56
|
+
end
|
57
|
+
|
58
|
+
def block_title_text
|
59
|
+
return nil unless options[:block].is_a? Hash
|
60
|
+
options.dig(:block, :title)
|
61
|
+
end
|
62
|
+
|
63
|
+
def block_subtitle_props
|
64
|
+
return nil unless options[:block].is_a?(Hash)
|
65
|
+
return nil unless options.dig(:block, :subtitle) || options.dig(:props, :block, :subtitle)
|
66
|
+
defaults = {
|
67
|
+
class: 'card-subtitle text-muted',
|
68
|
+
}
|
69
|
+
merge_props(from: defaults, to: options.dig(:props, :block, :subtitle))
|
70
|
+
end
|
71
|
+
|
72
|
+
def block_subtitle_text
|
73
|
+
return nil unless options[:block].is_a? Hash
|
74
|
+
options.dig(:block, :subtitle)
|
75
|
+
end
|
76
|
+
|
77
|
+
def block_text_props
|
78
|
+
return nil unless options[:block].is_a?(Hash)
|
79
|
+
return nil unless options.dig(:block, :text) || options.dig(:props, :block, :text)
|
80
|
+
defaults = {
|
81
|
+
class: 'card-text',
|
82
|
+
}
|
83
|
+
merge_props(from: defaults, to: options.dig(:props, :block, :text))
|
84
|
+
end
|
85
|
+
|
86
|
+
def block_text_text
|
87
|
+
return nil unless options[:block].is_a? Hash
|
88
|
+
options.dig(:block, :text)
|
89
|
+
end
|
90
|
+
|
91
|
+
def block_body_props
|
92
|
+
return nil unless options[:block].is_a?(Hash)
|
93
|
+
return nil unless options.dig(:block, :body) || options.dig(:props, :block, :body)
|
94
|
+
defaults = {
|
95
|
+
class: 'card-body',
|
96
|
+
}
|
97
|
+
merge_props(from: defaults, to: options.dig(:props, :block, :body))
|
98
|
+
end
|
99
|
+
|
100
|
+
def block_body_text
|
101
|
+
return nil unless options[:block].is_a? Hash
|
102
|
+
options.dig(:block, :body)
|
103
|
+
end
|
104
|
+
|
105
|
+
def table_props
|
106
|
+
return nil unless options[:table] || options.dig(:props, :table)
|
107
|
+
defaults = {
|
108
|
+
class: 'card-table',
|
109
|
+
}
|
110
|
+
merge_props(from: defaults, to: options.dig(:props, :table))
|
111
|
+
end
|
112
|
+
|
113
|
+
def table_text
|
114
|
+
options[:table]
|
115
|
+
end
|
116
|
+
|
117
|
+
def list_group_props
|
118
|
+
return nil unless options[:list_group] || options.dig(:props, :list_group)
|
119
|
+
defaults = {
|
120
|
+
class: 'card-list-group',
|
121
|
+
}
|
122
|
+
merge_props(from: defaults, to: options.dig(:props, :list_group))
|
123
|
+
end
|
124
|
+
|
125
|
+
def list_group_text
|
126
|
+
options[:list_group]
|
127
|
+
end
|
128
|
+
|
129
|
+
def footer_props
|
130
|
+
return nil unless options[:footer] || options.dig(:props, :footer)
|
131
|
+
defaults = {
|
132
|
+
class: 'card-footer',
|
133
|
+
}
|
134
|
+
merge_props(from: defaults, to: options.dig(:props, :footer))
|
135
|
+
end
|
136
|
+
|
137
|
+
def footer_text
|
138
|
+
options[:footer]
|
139
|
+
end
|
140
|
+
|
141
|
+
def img_bottom_props
|
142
|
+
return nil unless options[:img_bottom] || options.dig(:props, :img_bottom)
|
143
|
+
defaults = {
|
144
|
+
class: 'card-img-bottom',
|
145
|
+
}
|
146
|
+
merge_props(from: defaults, to: options.dig(:props, :img_bottom))
|
147
|
+
end
|
148
|
+
|
149
|
+
def img_bottom_text
|
150
|
+
options[:img_bottom]
|
151
|
+
end
|
152
|
+
end
|