bootstrap4_helper 0.0.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ # @root
2
+ #
3
+ #
4
+ module Bootstrap4Helper
5
+ # @description
6
+ #
7
+ #
8
+ class CardGroup < CardGrouping
9
+ # @description
10
+ # -
11
+ #
12
+ def to_s
13
+ content_tag :div, id: @id, class: "card-group #{@class}", data: @data do
14
+ @content.call(self)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,35 @@
1
+ # @root
2
+ #
3
+ #
4
+ module Bootstrap4Helper
5
+ # @description
6
+ #
7
+ #
8
+ class CardGrouping < Component
9
+ # @description
10
+ # - Used to initialize a new Card Group.
11
+ #
12
+ # @param [Class] template
13
+ # @param [Hash] opts
14
+ # @return [Card]
15
+ #
16
+ def initialize(template, opts = {}, &block)
17
+ super(template)
18
+
19
+ @id = opts.fetch(:id, '')
20
+ @class = opts.fetch(:class, '')
21
+ @data = opts.fetch(:data, nil)
22
+ @content = block || proc { '' }
23
+ end
24
+
25
+ # @description
26
+ # - Builds a `Card` for the grouping class.
27
+ #
28
+ # @param [Hash] opts
29
+ # @return [Card]
30
+ #
31
+ def card(opts = {}, &block)
32
+ Card.new(@template, opts, &block)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,110 @@
1
+ # @root
2
+ #
3
+ #
4
+ module Bootstrap4Helper
5
+ # @description
6
+ # - This super class is meant to contain commonly used methods that
7
+ # all sub classes can leverage.
8
+ #
9
+ # @note
10
+ # - Every component that inherits from this class, needs to call the parent
11
+ # initialization method! In order to properly render erb blocks within the
12
+ # proper context, we need the template. The only way to get this, is to pass
13
+ # in the template.
14
+ #
15
+ # @note
16
+ # - the `context` mentioned above, refers to the context of `@template` and
17
+ # not to be confused with `@context` that can be found in the sub classes.
18
+ # `@context` refers to the Bootstrap class context of the component.
19
+ #
20
+ class Component
21
+ # @description
22
+ # - Used to ensure that the helpers always have the propert context for
23
+ # rendering and bindings.
24
+ #
25
+ # @param [Class] template - the context of the bindings
26
+ #
27
+ def initialize(template)
28
+ @template = template
29
+ end
30
+
31
+ # @description
32
+ # - Used to pass all context of content_tag to the template. This ensures
33
+ # proper template binding of variables and methods!
34
+ #
35
+ # @return [String]
36
+ #
37
+ def content_tag(
38
+ name,
39
+ content_or_options_with_block = nil,
40
+ options = nil,
41
+ escape = true,
42
+ &block
43
+ )
44
+ @template.content_tag(
45
+ name,
46
+ content_or_options_with_block,
47
+ options,
48
+ escape,
49
+ &block
50
+ )
51
+ end
52
+
53
+ # @description
54
+ # -
55
+ #
56
+ def capture(*args)
57
+ @template.capture(*args)
58
+ end
59
+
60
+ # @description
61
+ # - Used to pass all concat references to the template. This ensures proper
62
+ # binding. Concat adds a String to the template Output buffer. Useful when
63
+ # trying to add a String with no block.
64
+ #
65
+ # @params [String] text
66
+ #
67
+ def concat(text)
68
+ @template.concat(text)
69
+ end
70
+
71
+ # @description
72
+ # - Used to parse method arguments. If the first argument is
73
+ # a Hash, then it is assumed that the user left off the bootstrap
74
+ # contectual class. So we will assign it to `secondary` and
75
+ # return the Hash to be used as options.
76
+ #
77
+ # @params [Hash|NilClass|String|Symbol] *args
78
+ # @return [Array]
79
+ #
80
+ def parse_arguments(*args)
81
+ first, second = *args
82
+ case first
83
+ when Hash, NilClass
84
+ ['secondary', first || second]
85
+ when Symbol, String
86
+ [first, second]
87
+ end
88
+ end
89
+
90
+ # @description
91
+ # - Used to generate a (hopefully) unique ID for DOM elements. Used as a
92
+ # fallback if the user doesn't specify one.
93
+ #
94
+ # @return [String]
95
+ #
96
+ def uuid
97
+ (0...10).map { rand(65..90).chr }.join
98
+ end
99
+
100
+ # @description
101
+ # - Used to get config settings inside of components quicker.
102
+ #
103
+ # @param [Symbol] setting
104
+ # @return [Mixed]
105
+ #
106
+ def config(setting, fallback)
107
+ Bootstrap4Helper.config.send(setting) || fallback
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,36 @@
1
+ # @root
2
+ #
3
+ #
4
+ module Bootstrap4Helper
5
+ # @description
6
+ #
7
+ #
8
+ class Configuration
9
+ DEFAULT_SETTINGS = {
10
+ autoload_in_views: true,
11
+ card_title: :h5,
12
+ card_text: :p,
13
+ accordion_header: :h5,
14
+ badge: :span
15
+ }.freeze
16
+
17
+ attr_accessor(*DEFAULT_SETTINGS.keys)
18
+
19
+ # @description
20
+ # -
21
+ #
22
+ # @params [Hash] args
23
+ # @return [ClassName]
24
+ #
25
+ def initialize(_args = {})
26
+ DEFAULT_SETTINGS.each { |key, value| instance_variable_set("@#{key}", value) }
27
+ end
28
+
29
+ # @description
30
+ # - Simple predicate method
31
+ #
32
+ def autoload_in_views?
33
+ @autoload_in_views
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,30 @@
1
+ # @root
2
+ #
3
+ #
4
+ module Bootstrap4Helper
5
+ # @description
6
+ # - Simple class for storing constants
7
+ #
8
+ class Constants
9
+ COMPONENTS = %i[
10
+ component
11
+ alert
12
+ accordion
13
+ accordion_group
14
+ badge
15
+ card
16
+ card_grouping
17
+ card_group
18
+ card_deck
19
+ card_column
20
+ configuration
21
+ dropdown
22
+ dropdown/menu
23
+ modal
24
+ nav
25
+ spinner
26
+ tab
27
+ tab/content
28
+ ].freeze
29
+ end
30
+ end
@@ -0,0 +1,92 @@
1
+ # @root
2
+ #
3
+ #
4
+ module Bootstrap4Helper
5
+ # @description
6
+ #
7
+ #
8
+ class Dropdown < Component
9
+ # @description
10
+ # -
11
+ #
12
+ # @param [ActionView] template
13
+ # @param [Symbol|String] type
14
+ # @param [Hash] opts
15
+ # @param [Hash]
16
+ #
17
+ def initialize(template, type = :dropdown, opts = {}, &block)
18
+ super(template)
19
+
20
+ @type = type
21
+ @id = opts.fetch(:id, uuid)
22
+ @class = opts.fetch(:class, '')
23
+ @data = opts.fetch(:data, {})
24
+ @content = block || proc { '' }
25
+ end
26
+
27
+ # @description
28
+ # - Used to generate a button for the dropdown. The buttons default as just
29
+ # a button that opens the coresponding dropdown menu. The `split: true` option
30
+ # make the button just the arrow indicator that open the menu.
31
+ #
32
+ # @param [Symbol] context
33
+ # @param [Hash] opts
34
+ # @return [String]
35
+ #
36
+ def button(context = :primary, opts = {})
37
+ split = opts.fetch(:split, false)
38
+ id = opts.fetch(:id, nil)
39
+ klass = opts.fetch(:class, '')
40
+ data = opts.fetch(:data, {}).merge(toggle: 'dropdown')
41
+ extra = split ? 'dropdown-toggle-split' : ''
42
+
43
+ content_tag(
44
+ :button,
45
+ id: id,
46
+ type: 'button',
47
+ class: "dropdown-toggle btn btn-#{context} #{klass} #{extra}",
48
+ data: data,
49
+ aria: { haspopup: true, expanded: false }
50
+ ) do
51
+ split ? content_tag(:span, 'Toggle Dropdwon', class: 'sr-only') : yield
52
+ end
53
+ end
54
+
55
+ # @description
56
+ # - Used to create a new `Dropdown::Menu`
57
+ #
58
+ # @param [Hash] opts
59
+ # @return [Dropdown::Menu]
60
+ #
61
+ def menu(opts = {}, &block)
62
+ Menu.new(@template, opts, &block)
63
+ end
64
+
65
+ # @description
66
+ # -
67
+ #
68
+ def to_s
69
+ content_tag :div, id: @id, class: "#{container_class} #{@class}", data: @data do
70
+ @content.call(self)
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ # @description
77
+ # - Returns the container class for the dropdown component.
78
+ #
79
+ # @return [String]
80
+ #
81
+ def container_class
82
+ case @type
83
+ when :dropdown
84
+ 'dropdown'
85
+ when :group
86
+ 'btn-group'
87
+ else
88
+ ''
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,123 @@
1
+ # @root
2
+ #
3
+ #
4
+ module Bootstrap4Helper
5
+ class Dropdown
6
+ # @description
7
+ #
8
+ #
9
+ class Menu < Component
10
+ # @description
11
+ # -
12
+ #
13
+ # @param [ActionView] template
14
+ # @param [Hash] opts
15
+ # @param [Hash]
16
+ #
17
+ def initialize(template, opts = {}, &block)
18
+ super(template)
19
+
20
+ @id = opts.fetch(:id, uuid)
21
+ @class = opts.fetch(:class, '')
22
+ @data = opts.fetch(:data, {})
23
+ @content = block || proc { '' }
24
+ end
25
+
26
+ # @description
27
+ # - Use this method when the `item`, `link` in the item in the menu is nothing
28
+ # more than a hyperlink.
29
+ #
30
+ def link(name = nil, options = nil, html_options = nil, &block)
31
+ html_options = (html_options || {}).merge(class: 'dropdown-item')
32
+
33
+ @template.link_to(name, options, html_options, &block)
34
+ end
35
+
36
+ # @description
37
+ # - Use this method when you are using the item in the menu as trigger for tab
38
+ # content.
39
+ #
40
+ # @param [Symbol|String] target
41
+ # @param [Hash] opts
42
+ #
43
+ def item(target, opts = {})
44
+ id = opts.fetch(:id, nil)
45
+ klass = opts.fetch(:class, '')
46
+ data = opts.fetch(:data, {}).merge(toggle: 'tab')
47
+ aria = opts.fetch(:aria, {})
48
+
49
+ content_tag(
50
+ :a,
51
+ id: id,
52
+ class: "dropdown-item #{klass}",
53
+ href: "##{target}",
54
+ aria: aria,
55
+ data: data
56
+ ) do
57
+ block_given? ? yield : target.to_s.titleize
58
+ end
59
+ end
60
+
61
+ # @description
62
+ # - Builds a Text component
63
+ #
64
+ # @param [Symbol|String] text
65
+ # @param [Hash] opts
66
+ #
67
+ def text(text, opts = {}, &block)
68
+ build_sub_component :span, text, 'item-text', opts, &block
69
+ end
70
+
71
+ # @description
72
+ # - Builds a Header component
73
+ #
74
+ # @param [Symbol|String] text
75
+ # @param [Hash] opts
76
+ #
77
+ def header(text, opts = {}, &block)
78
+ build_sub_component :h6, text, 'header', opts, &block
79
+ end
80
+
81
+ # @description
82
+ # - Builds a divider element
83
+ #
84
+ def divider
85
+ content_tag :div, '', class: 'dropdown-divider'
86
+ end
87
+
88
+ # @description
89
+ # -
90
+ #
91
+ def to_s
92
+ content_tag :div, id: @id, class: "dropdown-menu #{@class}", data: @data do
93
+ @content.call(self)
94
+ end
95
+ end
96
+
97
+ private
98
+
99
+ # @description
100
+ # - Used to build specific components.
101
+ #
102
+ # @param [Symbol] tag
103
+ # @param [Symbol|String] text
104
+ # @param [Symbol|String] type
105
+ # @param [Hash] opts
106
+ #
107
+ def build_sub_component(tag, text, type, opts)
108
+ id = opts.fetch(:id, nil)
109
+ klass = opts.fetch(:class, '')
110
+ data = opts.fetch(:data, {})
111
+
112
+ content_tag(
113
+ tag,
114
+ id: id,
115
+ class: "dropdown-#{type} #{klass}",
116
+ data: data
117
+ ) do
118
+ block_given? ? yield : text || ''
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end