ndr_ui 4.1.2 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/app/assets/fonts/bootstrap-icons.woff +0 -0
- data/app/assets/fonts/bootstrap-icons.woff2 +0 -0
- data/app/assets/javascripts/ndr_ui/index.js +1 -0
- data/app/assets/stylesheets/ndr_ui/bootstrap-icons.scss +2090 -0
- data/app/assets/stylesheets/ndr_ui/index.scss +5 -3
- data/app/builders/ndr_ui/bootstrap/datepicker.rb +4 -4
- data/app/builders/ndr_ui/bootstrap/form_control_class.rb +2 -2
- data/app/builders/ndr_ui/bootstrap/inline_errors_and_warnings.rb +2 -2
- data/app/builders/ndr_ui/bootstrap/input_group_addons.rb +4 -10
- data/app/builders/ndr_ui/bootstrap/readonly.rb +12 -12
- data/app/builders/ndr_ui/bootstrap_builder.rb +32 -25
- data/app/helpers/ndr_ui/bootstrap/{accordion.rb → accordion_helper.rb} +49 -16
- data/app/helpers/ndr_ui/bootstrap/breadcrumbs_helper.rb +4 -4
- data/app/helpers/ndr_ui/bootstrap/card_helper.rb +94 -0
- data/app/helpers/ndr_ui/bootstrap/dropdown_helper.rb +16 -13
- data/app/helpers/ndr_ui/bootstrap/modal_helper.rb +15 -13
- data/app/helpers/ndr_ui/bootstrap_helper.rb +68 -64
- data/app/helpers/ndr_ui/css_helper.rb +1 -4
- data/lib/ndr_ui/engine.rb +2 -1
- data/lib/ndr_ui/version.rb +1 -1
- metadata +50 -19
- data/app/helpers/ndr_ui/bootstrap/panel_helper.rb +0 -87
@@ -1,7 +1,9 @@
|
|
1
|
-
// "bootstrap-sprockets" must be imported before "bootstrap" and "bootstrap/variables"
|
2
|
-
@import "bootstrap-sprockets";
|
3
1
|
@import "bootstrap";
|
4
2
|
|
3
|
+
//NOTE: font-dir: "." and "./assets" works, "./fonts" doesn't. may vary between systems
|
4
|
+
$bootstrap-icons-font-dir: ".";
|
5
|
+
@import "bootstrap-icons";
|
6
|
+
|
5
7
|
// Fieldsets don't behave properly with Bootstrap in Firefox
|
6
8
|
// https://stackoverflow.com/questions/17408815/fieldset-resizes-wrong-appears-to-have-unremovable-min-width-min-content/17863685#17863685
|
7
9
|
@-moz-document url-prefix() {
|
@@ -12,7 +14,7 @@
|
|
12
14
|
|
13
15
|
// for input fields with input-addons, remove background and border when the form is readonly.
|
14
16
|
.input-group {
|
15
|
-
.form-control-
|
17
|
+
.form-control-plaintext + .input-group-text {
|
16
18
|
background: none;
|
17
19
|
border:0;
|
18
20
|
}
|
@@ -14,11 +14,11 @@ module NdrUi
|
|
14
14
|
# # => <div class="input-group date" data-provide="datepicker" data-date-end-date="0d">
|
15
15
|
# <input class="form-control" type="text"
|
16
16
|
# name="post[last_updated]" id="post_last_updated" />
|
17
|
-
# <span aria-hidden="true" class="input-group-
|
17
|
+
# <span aria-hidden="true" class="input-group-text">
|
18
18
|
# <span class="glyphicon glyphicon-calendar"></span>
|
19
19
|
# </span>
|
20
20
|
# </div>
|
21
|
-
# <span class="
|
21
|
+
# <span class="form-text" data-feedback-for="post_last_updated">
|
22
22
|
# <span class="text-danger"></span><span class="text-warning"></span>
|
23
23
|
# </span>
|
24
24
|
#
|
@@ -37,7 +37,7 @@ module NdrUi
|
|
37
37
|
|
38
38
|
# This method returns the date input-group and inline errors and warnings.
|
39
39
|
# The errors and warnings are appended after the group to avoid messing up the
|
40
|
-
# input-group-
|
40
|
+
# input-group-text calendar icon.
|
41
41
|
def date_input_group(method, options)
|
42
42
|
data = { provide: 'datepicker' }
|
43
43
|
data[:'date-end-date'] = '0d' if options.delete(:no_future)
|
@@ -50,7 +50,7 @@ module NdrUi
|
|
50
50
|
html +
|
51
51
|
@template.content_tag(:span,
|
52
52
|
@template.bootstrap_icon_tag(:calendar),
|
53
|
-
'aria-hidden': 'true', class: 'input-group-
|
53
|
+
'aria-hidden': 'true', class: 'input-group-text')
|
54
54
|
end + errors
|
55
55
|
end
|
56
56
|
end
|
@@ -23,7 +23,7 @@ module NdrUi
|
|
23
23
|
module FormControlClass
|
24
24
|
def self.add_form_control_class(method_name)
|
25
25
|
define_method(method_name) do |label, *args, &proc|
|
26
|
-
options = css_class_options_merge(args.extract_options!, %w
|
26
|
+
options = css_class_options_merge(args.extract_options!, %w[form-control])
|
27
27
|
super(label, *(args << options), &proc)
|
28
28
|
end
|
29
29
|
end
|
@@ -35,7 +35,7 @@ module NdrUi
|
|
35
35
|
options ||= {}
|
36
36
|
html_options ||= {}
|
37
37
|
|
38
|
-
html_options = css_class_options_merge(html_options, %w
|
38
|
+
html_options = css_class_options_merge(html_options, %w[form-control form-select])
|
39
39
|
super(label, choices, options, html_options, &proc)
|
40
40
|
end
|
41
41
|
end
|
@@ -2,7 +2,7 @@ module NdrUi
|
|
2
2
|
module Bootstrap
|
3
3
|
# Allows us to display errors and warnings in a bootstrap-friendly way
|
4
4
|
module InlineErrorsAndWarnings
|
5
|
-
# Tag::Base subclass for generating bootstrap span.
|
5
|
+
# Tag::Base subclass for generating bootstrap span.form-text.
|
6
6
|
# Allows us to use generate the tag_id properly.
|
7
7
|
class HelpBlock < ActionView::Helpers::Tags::Base
|
8
8
|
def render(&block)
|
@@ -13,7 +13,7 @@ module NdrUi
|
|
13
13
|
add_default_name_and_id(@options.fetch('html', {}))
|
14
14
|
end
|
15
15
|
|
16
|
-
options = { class: '
|
16
|
+
options = { class: 'form-text', data: { feedback_for: feedback_for } }
|
17
17
|
content_tag(:span, @template_object.capture(&block), options)
|
18
18
|
end
|
19
19
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module NdrUi
|
2
2
|
module Bootstrap
|
3
|
-
# Provides form builder method for Bootstrap input-group-
|
3
|
+
# Provides form builder method for Bootstrap input-group-text
|
4
4
|
module InputGroupAddons
|
5
5
|
# Identical signature to ActionView::Helpers::FormBuilder#text_field, but adds
|
6
6
|
# <tt>:prepend</tt> and <tt>:append</tt> options to prepend and append text to
|
@@ -12,17 +12,11 @@ module NdrUi
|
|
12
12
|
append = options.delete('append')
|
13
13
|
|
14
14
|
return super if prepend.blank? && append.blank?
|
15
|
-
div_content = []
|
16
|
-
|
17
|
-
unless prepend.blank?
|
18
|
-
div_content << @template.content_tag(:span, prepend, class: 'input-group-addon')
|
19
|
-
end
|
20
15
|
|
16
|
+
div_content = []
|
17
|
+
div_content << @template.content_tag(:span, prepend, class: 'input-group-text') if prepend.present?
|
21
18
|
div_content << text_field_without_inline_errors(method, options)
|
22
|
-
|
23
|
-
unless append.blank?
|
24
|
-
div_content << @template.content_tag(:span, append, class: 'input-group-addon')
|
25
|
-
end
|
19
|
+
div_content << @template.content_tag(:span, append, class: 'input-group-text') if append.present?
|
26
20
|
|
27
21
|
@template.content_tag(:div, @template.safe_join(div_content), class: 'input-group')
|
28
22
|
end
|
@@ -7,7 +7,7 @@ module NdrUi
|
|
7
7
|
# Most helpers have a similar signature, so can be iterated over and
|
8
8
|
# enhanced. The reminaining minority have to be manually re-defined.
|
9
9
|
module Readonly
|
10
|
-
def self.included(base)
|
10
|
+
def self.included(base) # rubocop:disable Metrics/MethodLength
|
11
11
|
# These have different signatures, or aren't affected by `readonly`:
|
12
12
|
not_affected = %i[label fields_for]
|
13
13
|
needs_custom = %i[radio_button file_field hidden_field textarea] +
|
@@ -18,12 +18,12 @@ module NdrUi
|
|
18
18
|
# def text_field(method, options = {}, *rest)
|
19
19
|
# return super unless readonly?
|
20
20
|
# readonly_value = options.symbolize_keys.fetch(:readonly_value, object.send(method))
|
21
|
-
# @template.content_tag(:p, readonly_value, class: 'form-control-
|
21
|
+
# @template.content_tag(:p, readonly_value, class: 'form-control-plaintext')
|
22
22
|
# end
|
23
23
|
def #{selector}(method, options = {}, *rest)
|
24
24
|
return super unless readonly?
|
25
25
|
readonly_value = options.symbolize_keys.fetch(:readonly_value, object.send(method))
|
26
|
-
@template.content_tag(:p, readonly_value, class: 'form-control-
|
26
|
+
@template.content_tag(:p, readonly_value, class: 'form-control-plaintext')
|
27
27
|
end
|
28
28
|
ENDEVAL
|
29
29
|
end
|
@@ -33,12 +33,12 @@ module NdrUi
|
|
33
33
|
# def text_area(method, options = {}, *rest)
|
34
34
|
# return super unless readonly?
|
35
35
|
# readonly_value = options.symbolize_keys.fetch(:readonly_value, object.send(method))
|
36
|
-
# @template.simple_format(readonly_value, class: 'form-control-
|
36
|
+
# @template.simple_format(readonly_value, class: 'form-control-plaintext')
|
37
37
|
# end
|
38
38
|
def #{selector}(method, options = {}, *rest)
|
39
39
|
return super unless readonly?
|
40
40
|
readonly_value = options.symbolize_keys.fetch(:readonly_value, object.send(method))
|
41
|
-
@template.simple_format(readonly_value, class: 'form-control-
|
41
|
+
@template.simple_format(readonly_value, class: 'form-control-plaintext')
|
42
42
|
end
|
43
43
|
ENDEVAL
|
44
44
|
end
|
@@ -48,12 +48,12 @@ module NdrUi
|
|
48
48
|
# def select(method, _something, options = {}, *rest)
|
49
49
|
# return super unless readonly?
|
50
50
|
# readonly_value = options.symbolize_keys.fetch(:readonly_value, object.send(method))
|
51
|
-
# @template.content_tag(:p, readonly_value, class: 'form-control-
|
51
|
+
# @template.content_tag(:p, readonly_value, class: 'form-control-plaintext')
|
52
52
|
# end
|
53
53
|
def #{selector}(method, _something, options = {}, *rest)
|
54
54
|
return super unless readonly?
|
55
55
|
readonly_value = options.symbolize_keys.fetch(:readonly_value, object.send(method))
|
56
|
-
@template.content_tag(:p, readonly_value, class: 'form-control-
|
56
|
+
@template.content_tag(:p, readonly_value, class: 'form-control-plaintext')
|
57
57
|
end
|
58
58
|
ENDEVAL
|
59
59
|
end
|
@@ -63,12 +63,12 @@ module NdrUi
|
|
63
63
|
# def collection_select(method, collection, value_method, text_method, options = {}, *rest)
|
64
64
|
# return super unless readonly?
|
65
65
|
# readonly_value = options.symbolize_keys.fetch(:readonly_value, object.send(method))
|
66
|
-
# @template.content_tag(:p, readonly_value, class: 'form-control-
|
66
|
+
# @template.content_tag(:p, readonly_value, class: 'form-control-plaintext')
|
67
67
|
# end
|
68
68
|
def #{selector}(method, collection, value_method, text_method, options = {}, *rest)
|
69
69
|
return super unless readonly?
|
70
70
|
readonly_value = options.symbolize_keys.fetch(:readonly_value, object.send(method))
|
71
|
-
@template.content_tag(:p, readonly_value, class: 'form-control-
|
71
|
+
@template.content_tag(:p, readonly_value, class: 'form-control-plaintext')
|
72
72
|
end
|
73
73
|
ENDEVAL
|
74
74
|
end
|
@@ -78,21 +78,21 @@ module NdrUi
|
|
78
78
|
def grouped_collection_select(method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {})
|
79
79
|
return super unless readonly?
|
80
80
|
readonly_value = options.symbolize_keys.fetch(:readonly_value, object.send(method))
|
81
|
-
@template.content_tag(:p, readonly_value, class: 'form-control-
|
81
|
+
@template.content_tag(:p, readonly_value, class: 'form-control-plaintext')
|
82
82
|
end
|
83
83
|
|
84
84
|
# radio_button takes another intermediate argument:
|
85
85
|
def radio_button(method, tag_value, options = {})
|
86
86
|
return super unless readonly?
|
87
87
|
readonly_value = options.symbolize_keys.fetch(:readonly_value, object.send(method))
|
88
|
-
@template.content_tag(:p, readonly_value, class: 'form-control-
|
88
|
+
@template.content_tag(:p, readonly_value, class: 'form-control-plaintext')
|
89
89
|
end
|
90
90
|
|
91
91
|
# For file_field, the readonly value defaults to nil:
|
92
92
|
def file_field(method, options = {})
|
93
93
|
return super unless readonly?
|
94
94
|
readonly_value = options.symbolize_keys[:readonly_value]
|
95
|
-
@template.content_tag(:p, readonly_value, class: 'form-control-
|
95
|
+
@template.content_tag(:p, readonly_value, class: 'form-control-plaintext')
|
96
96
|
end
|
97
97
|
|
98
98
|
# Hidden fields should be suppressed when the form is readonly:
|
@@ -50,7 +50,7 @@ module NdrUi
|
|
50
50
|
|
51
51
|
# <%= form.control_group(:title, 'Demo', {:class => "col-md-6"}, {:id => 'some_id'}, "# Controls go here") %>
|
52
52
|
# # => <div class="form-group col-md-6">
|
53
|
-
# <label
|
53
|
+
# <label class="form-label" for="post_title">Demo</label>
|
54
54
|
# <div id="some_id">
|
55
55
|
# # Controls go here
|
56
56
|
# </div>
|
@@ -63,37 +63,44 @@ module NdrUi
|
|
63
63
|
# <% end %>
|
64
64
|
#
|
65
65
|
def control_group(methods, text = nil, options = {}, control_options = {}, controls = '', &block)
|
66
|
-
if block_given?
|
67
|
-
return control_group(methods, text, options, control_options, @template.capture(&block))
|
68
|
-
else
|
69
|
-
methods = [methods].compact unless methods.is_a?(Array)
|
66
|
+
return control_group(methods, text, options, control_options, @template.capture(&block)) if block_given?
|
70
67
|
|
71
|
-
|
72
|
-
label_classes << "col-md-#{label_columns}" if horizontal_mode
|
73
|
-
label_options = {class: label_classes.join(' ')}
|
74
|
-
label_options[:tooltip] = options.delete(:tooltip)
|
75
|
-
label_html = if methods.present?
|
76
|
-
label(methods.first, text, label_options)
|
77
|
-
else
|
78
|
-
@template.content_tag(:span, text, class: label_classes.join(' '))
|
79
|
-
end
|
68
|
+
methods = [methods].compact unless methods.is_a?(Array)
|
80
69
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
70
|
+
label_classes = if horizontal_mode
|
71
|
+
"col-form-label col-#{label_columns} text-end"
|
72
|
+
else
|
73
|
+
'form-label'
|
74
|
+
end
|
75
|
+
label_options = {
|
76
|
+
class: label_classes,
|
77
|
+
tooltip: options.delete(:tooltip)
|
78
|
+
}
|
79
|
+
label_html = if methods.present?
|
80
|
+
label(methods.first, text, label_options)
|
81
|
+
else
|
82
|
+
@template.content_tag(:span, text, class: label_classes)
|
83
|
+
end
|
87
84
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
85
|
+
control_options = css_class_options_merge(control_options) do |control_classes|
|
86
|
+
# Only add a col-md-N class if none already specified
|
87
|
+
if horizontal_mode && control_classes.none? { |css_class| css_class.start_with?('col-') }
|
88
|
+
control_classes << "col-#{12 - label_columns}"
|
89
|
+
end
|
92
90
|
end
|
91
|
+
|
92
|
+
@template.content_tag(:div,
|
93
|
+
label_html +
|
94
|
+
@template.content_tag(:div, controls, control_options),
|
95
|
+
control_group_options(methods, options))
|
93
96
|
end
|
94
97
|
|
95
98
|
def control_group_options(methods, options)
|
96
|
-
|
99
|
+
# .form-group has been deprecated in Bootstrap
|
100
|
+
# however, we keep this class to do the global margin setting
|
101
|
+
default_classes = %w[form-group]
|
102
|
+
default_classes << 'row' if horizontal_mode
|
103
|
+
css_class_options_merge(options, default_classes) do |group_classes|
|
97
104
|
if object && methods.present?
|
98
105
|
if methods.any? { |method| object.errors[method].present? }
|
99
106
|
group_classes << 'has-error'
|
@@ -1,5 +1,34 @@
|
|
1
1
|
module NdrUi
|
2
2
|
module Bootstrap
|
3
|
+
# This provides bootstrap accordion helper methods
|
4
|
+
module AccordionHelper
|
5
|
+
# Creates an accordion wrapper and creates a new NdrUi::Bootstrap::Accordion instance
|
6
|
+
# Creates an plain or nested bootstrap accordion along with bootstrap_accordion_group
|
7
|
+
# method at NdrUi::Bootstrap::Accordion class.
|
8
|
+
#
|
9
|
+
# ==== Signatures
|
10
|
+
#
|
11
|
+
# bootstrap_accordion_tag(dom_id) do |accordion|
|
12
|
+
# #content for accordion items
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# ==== Examples
|
16
|
+
#
|
17
|
+
# <%= bootstrap_accordion_group :fruit do |fruit_accordion| %>
|
18
|
+
# <% end %>
|
19
|
+
# # => <div id="fruit" class="accordion"></div>
|
20
|
+
def bootstrap_accordion_tag(dom_id, options = {}, &_block)
|
21
|
+
return unless block_given?
|
22
|
+
|
23
|
+
options.stringify_keys!
|
24
|
+
accordion = ::NdrUi::Bootstrap::Accordion.new(dom_id, self)
|
25
|
+
seamless = options['seamless']
|
26
|
+
content_tag(:div, id: accordion.dom_id.to_s, class: "accordion#{' accordion-flush' if seamless}") do
|
27
|
+
yield(accordion)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
3
32
|
# Creates a plain or nested bootstrap accordion along with bootstrap_accordion_tag helper
|
4
33
|
# method.
|
5
34
|
# Produce the inner html code of an accordion item.
|
@@ -35,7 +64,7 @@ module NdrUi
|
|
35
64
|
# <div id="fruit" class="accordion">
|
36
65
|
# <div class="panel panel-default">
|
37
66
|
# <div class="panel-heading">
|
38
|
-
# <a href="#fruit_1" data-parent="#fruit" data-toggle="collapse">Apple</a>
|
67
|
+
# <a href="#fruit_1" data-bs-parent="#fruit" data-bs-toggle="collapse">Apple</a>
|
39
68
|
# </div>
|
40
69
|
# <div class="panel-collapse collapse" id="fruit_1">
|
41
70
|
# <div class="panel-body">
|
@@ -45,7 +74,7 @@ module NdrUi
|
|
45
74
|
# </div>
|
46
75
|
# <div class="panel panel-default">
|
47
76
|
# <div class="panel-heading">
|
48
|
-
# <a href="#fruit_2" data-parent="#fruit" data-toggle="collapse">Orange</a>
|
77
|
+
# <a href="#fruit_2" data-bs-parent="#fruit" data-bs-toggle="collapse">Orange</a>
|
49
78
|
# </div>
|
50
79
|
# <div class="panel-collapse collapse in" id="fruit_2">
|
51
80
|
# <div class="panel-body">
|
@@ -58,6 +87,7 @@ module NdrUi
|
|
58
87
|
class Accordion
|
59
88
|
attr_accessor :dom_id, :index
|
60
89
|
|
90
|
+
# rubocop:disable Rails/HelperInstanceVariable
|
61
91
|
def initialize(accordion_id, template)
|
62
92
|
@dom_id = accordion_id
|
63
93
|
@template = template
|
@@ -66,13 +96,14 @@ module NdrUi
|
|
66
96
|
|
67
97
|
def bootstrap_accordion_group(heading, options = {}, &block)
|
68
98
|
return unless block_given?
|
99
|
+
|
69
100
|
options.stringify_keys!
|
70
|
-
seamless = options['seamless']
|
71
101
|
@index += 1
|
72
|
-
content = @template.
|
73
|
-
|
74
|
-
|
75
|
-
|
102
|
+
content = @template.content_tag('div', class: 'accordion-body') do
|
103
|
+
@template.capture(&block)
|
104
|
+
end
|
105
|
+
@template.content_tag('div', class: 'accordion-item') do
|
106
|
+
accordion_header_tag(heading, options['open']) + accordion_collapse_tag(content, options['open'])
|
76
107
|
end
|
77
108
|
end
|
78
109
|
|
@@ -82,21 +113,23 @@ module NdrUi
|
|
82
113
|
"#{@dom_id}_#{@index}"
|
83
114
|
end
|
84
115
|
|
85
|
-
def
|
86
|
-
@template.content_tag('
|
87
|
-
@template.
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
116
|
+
def accordion_header_tag(heading, open_by_default)
|
117
|
+
@template.content_tag('h2', class: 'accordion-header') do
|
118
|
+
@template.button_tag(heading,
|
119
|
+
class: "accordion-button#{' collapsed' unless open_by_default}",
|
120
|
+
type: :button,
|
121
|
+
'data-bs-toggle': 'collapse',
|
122
|
+
'data-bs-target': "##{group_id}")
|
92
123
|
end
|
93
124
|
end
|
94
125
|
|
95
|
-
def
|
126
|
+
def accordion_collapse_tag(content, open_by_default)
|
96
127
|
@template.content_tag('div', content,
|
97
128
|
id: group_id,
|
98
|
-
class: "
|
129
|
+
class: "accordion-collapse collapse#{' show' if open_by_default}",
|
130
|
+
'data-bs-parent': "##{@dom_id}")
|
99
131
|
end
|
132
|
+
# rubocop:enable Rails/HelperInstanceVariable
|
100
133
|
end
|
101
134
|
end
|
102
135
|
end
|
@@ -13,11 +13,11 @@ module NdrUi
|
|
13
13
|
# <%= bootstrap_breadcrumbs([
|
14
14
|
# bootstrap_breadcrumb("Fruits", "#fruits")
|
15
15
|
# ]) %>
|
16
|
-
# # => <ol class="breadcrumb">
|
16
|
+
# # => <ol class="breadcrumb bg-body-tertiary p-2">
|
17
17
|
# <li class="active"><a href="#fruits">Fruits</a></li>
|
18
18
|
# </ol>
|
19
19
|
def bootstrap_breadcrumbs(breadcrumbs)
|
20
|
-
content_tag('ol', safe_join(breadcrumbs), class: 'breadcrumb')
|
20
|
+
content_tag('ol', safe_join(breadcrumbs), class: 'breadcrumb bg-body-tertiary p-2')
|
21
21
|
end
|
22
22
|
|
23
23
|
# Creates a bootstrap breadcrumb.
|
@@ -29,11 +29,11 @@ module NdrUi
|
|
29
29
|
# ==== Examples
|
30
30
|
#
|
31
31
|
# <%= bootstrap_breadcrumb("Fruits", "#fruits", true) %>
|
32
|
-
# # => <li class="active"><a href="#fruits">Fruits</a></li>
|
32
|
+
# # => <li class="breadcrumb-item active"><a href="#fruits">Fruits</a></li>
|
33
33
|
def bootstrap_breadcrumb(title, linkto, active = false)
|
34
34
|
content_tag('li',
|
35
35
|
link_to(title, linkto),
|
36
|
-
|
36
|
+
{ class: "breadcrumb-item#{active ? ' active' : ''}" })
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module NdrUi
|
2
|
+
module Bootstrap
|
3
|
+
# This provides accordion
|
4
|
+
module CardHelper
|
5
|
+
include CssHelper
|
6
|
+
|
7
|
+
CARD_TYPES = %w[primary secondary success danger warning info light dark].freeze
|
8
|
+
|
9
|
+
# Creates a bootstrap card wrapper. the heading is wrapped in a card-header.
|
10
|
+
# The content is not wrapped in a card-body to enable seamless tables and lists.
|
11
|
+
#
|
12
|
+
# ==== Signatures
|
13
|
+
#
|
14
|
+
# bootstrap_card_tag(heading, options = {}) do
|
15
|
+
# #content for card
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# ==== Examples
|
19
|
+
#
|
20
|
+
# <%= bootstrap_card_tag 'Apples', type: :warning, id: 'fruit' do %>
|
21
|
+
# Check it out!!
|
22
|
+
# <% end %>
|
23
|
+
# # => <div id="fruit" class="card mb-3 text-bg-warning">
|
24
|
+
# <div class="card-header d-flex">
|
25
|
+
# <h4 class="card-title">Apples</h4>
|
26
|
+
# <div class="ms-auto"></div>
|
27
|
+
# </div>
|
28
|
+
# Check it out!!
|
29
|
+
# </div>
|
30
|
+
def bootstrap_card_tag(heading, controls = nil, options = {}, &block)
|
31
|
+
return unless block_given?
|
32
|
+
|
33
|
+
options.stringify_keys!
|
34
|
+
classes = %w[card mb-3]
|
35
|
+
classes << "bg-#{options.delete('type')}-subtle" if CARD_TYPES.include?(options['type'].to_s)
|
36
|
+
options = css_class_options_merge(options, classes)
|
37
|
+
|
38
|
+
header = content_tag(:div, class: "card-header#{' d-flex' if controls.present?}") do
|
39
|
+
concat content_tag(:h4, heading, class: 'card-title')
|
40
|
+
concat content_tag(:div, controls, class: 'ms-auto') if controls.present?
|
41
|
+
end
|
42
|
+
|
43
|
+
content_tag(:div, header + capture(&block), options)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Creates a simple bootstrap card body.
|
47
|
+
#
|
48
|
+
# ==== Signatures
|
49
|
+
#
|
50
|
+
# bootstrap_card_body_tag do
|
51
|
+
# #content for card body
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# ==== Examples
|
55
|
+
#
|
56
|
+
# <%= bootstrap_card_body_tag do %>
|
57
|
+
# Check it out!!
|
58
|
+
# <% end %>
|
59
|
+
# # => <div class="card-body">Check it out!!</div>
|
60
|
+
def bootstrap_card_body_tag(&block)
|
61
|
+
return unless block_given?
|
62
|
+
|
63
|
+
content_tag(:div, capture(&block), class: 'card-body')
|
64
|
+
end
|
65
|
+
|
66
|
+
# Creates a bootstrap card wrapper. the heading is wrapped in a card-header.
|
67
|
+
# The content is wrapped in a ul.list-group to enable seamless lists.
|
68
|
+
# It doesn't support controls (controls = nil).
|
69
|
+
def bootstrap_card_list(title, options = {}, &block)
|
70
|
+
bootstrap_card_tag(title, nil, options) do
|
71
|
+
content_tag(:div, capture(&block), class: 'list-group list-group-flush')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Bootstrap v4 dropped Wells for Card component
|
76
|
+
# create a wrapper for Wells - a Card without heading
|
77
|
+
def bootstrap_well_tag(options = {}, &block)
|
78
|
+
return unless block_given?
|
79
|
+
|
80
|
+
options.stringify_keys!
|
81
|
+
classes = %w[card mb-3]
|
82
|
+
classes << (CARD_TYPES.include?(options['type'].to_s) ? "bg-#{options.delete('type')}-subtle" : 'text-bg-light')
|
83
|
+
classes += options['class'].to_s.split if options['class'].present?
|
84
|
+
options['class'] = classes.uniq.join(' ')
|
85
|
+
|
86
|
+
content_tag(:div, options) do
|
87
|
+
bootstrap_card_body_tag do
|
88
|
+
capture(&block)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -17,18 +17,22 @@ module NdrUi
|
|
17
17
|
# See the Rails documentation for details of the options and examples
|
18
18
|
#
|
19
19
|
def bootstrap_list_link_to(*args, &block)
|
20
|
-
if block_given?
|
21
|
-
return bootstrap_list_link_to(capture(&block), (args.first || {}), args.second)
|
22
|
-
end
|
20
|
+
return bootstrap_list_link_to(capture(&block), (args.first || {}), args.second) if block_given?
|
23
21
|
|
24
22
|
name = args.first
|
25
23
|
options = args.second || {}
|
26
|
-
html_options = args.third
|
27
|
-
li_options = {}
|
24
|
+
html_options = args.third || {}
|
28
25
|
|
29
|
-
|
26
|
+
klass = html_options[:class].to_s.split
|
27
|
+
klass << if html_options.delete(:mode).to_s == 'nav'
|
28
|
+
'nav-link'
|
29
|
+
else
|
30
|
+
'dropdown-item'
|
31
|
+
end
|
32
|
+
klass << 'active' if current_page?(options)
|
33
|
+
html_options[:class] = klass.join(' ')
|
30
34
|
|
31
|
-
content_tag(:li, link_to(name, options, html_options)
|
35
|
+
content_tag(:li, link_to(name, options, html_options))
|
32
36
|
end
|
33
37
|
|
34
38
|
# Creates a Boostrap list header.
|
@@ -42,8 +46,8 @@ module NdrUi
|
|
42
46
|
# <%= bootstrap_list_header_tag("Apples") %>
|
43
47
|
# # => <li class="dropdown-header">Apples</li>
|
44
48
|
def bootstrap_list_header_tag(name, options = {})
|
45
|
-
options[:class] = (options[:class].to_s.split
|
46
|
-
content_tag(:li, name,
|
49
|
+
options[:class] = (options[:class].to_s.split + ['dropdown-header']).join(' ')
|
50
|
+
content_tag(:li, content_tag(:h6, name, options))
|
47
51
|
end
|
48
52
|
|
49
53
|
# Creates a Boostrap list divider.
|
@@ -55,10 +59,9 @@ module NdrUi
|
|
55
59
|
# ==== Examples
|
56
60
|
#
|
57
61
|
# <%= bootstrap_list_divider_tag %>
|
58
|
-
# # => <li class="divider"></li>
|
59
|
-
def bootstrap_list_divider_tag
|
60
|
-
|
61
|
-
content_tag(:li, '', { role: 'presentation' }.merge(options))
|
62
|
+
# # => <li><hr class="dropdown-divider"></li>
|
63
|
+
def bootstrap_list_divider_tag
|
64
|
+
content_tag(:li, content_tag(:hr, '', class: 'dropdown-divider'))
|
62
65
|
end
|
63
66
|
end
|
64
67
|
end
|