ndr_ui 4.1.2 → 5.0.0
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 +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
|