bootstrap-cells 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|